Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/networking/inetd.c
- Timestamp:
- Jan 1, 2014, 12:47:38 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.2/mindi-busybox/networking/inetd.c
r2725 r3232 155 155 */ 156 156 157 //usage:#define inetd_trivial_usage 158 //usage: "[-fe] [-q N] [-R N] [CONFFILE]" 159 //usage:#define inetd_full_usage "\n\n" 160 //usage: "Listen for network connections and launch programs\n" 161 //usage: "\n -f Run in foreground" 162 //usage: "\n -e Log to stderr" 163 //usage: "\n -q N Socket listen queue (default: 128)" 164 //usage: "\n -R N Pause services after N connects/min" 165 //usage: "\n (default: 0 - disabled)" 166 157 167 #include <syslog.h> 168 #include <sys/resource.h> /* setrlimit */ 169 #include <sys/socket.h> /* un.h may need this */ 158 170 #include <sys/un.h> 159 171 … … 161 173 162 174 #if ENABLE_FEATURE_INETD_RPC 163 #include <rpc/rpc.h> 164 #include <rpc/pmap_clnt.h> 175 # if defined(__UCLIBC__) && ! defined(__UCLIBC_HAS_RPC__) 176 # error "You need to build uClibc with UCLIBC_HAS_RPC for NFS support" 177 # endif 178 # include <rpc/rpc.h> 179 # include <rpc/pmap_clnt.h> 165 180 #endif 166 181 … … 171 186 #define ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN 0 172 187 #endif 173 174 #define _PATH_INETDPID "/var/run/inetd.pid"175 188 176 189 #define CNT_INTERVAL 60 /* servers in CNT_INTERVAL sec. */ … … 345 358 } while (0) 346 359 360 #if 1 361 # define dbg(...) ((void)0) 362 #else 363 # define dbg(...) \ 364 do { \ 365 int dbg_fd = open("inetd_debug.log", O_WRONLY | O_CREAT | O_APPEND, 0666); \ 366 if (dbg_fd >= 0) { \ 367 fdprintf(dbg_fd, "%d: ", getpid()); \ 368 fdprintf(dbg_fd, __VA_ARGS__); \ 369 close(dbg_fd); \ 370 } \ 371 } while (0) 372 #endif 373 347 374 static void maybe_close(int fd) 348 375 { 349 if (fd >= 0) 376 if (fd >= 0) { 350 377 close(fd); 378 dbg("closed fd:%d\n", fd); 379 } 351 380 } 352 381 … … 452 481 if (fd >= 0) { 453 482 FD_CLR(fd, &allsock); 483 dbg("stopped listening on fd:%d\n", fd); 454 484 maxsock = -1; 485 dbg("maxsock:%d\n", maxsock); 455 486 } 456 487 } … … 460 491 if (fd >= 0) { 461 492 FD_SET(fd, &allsock); 493 dbg("started listening on fd:%d\n", fd); 462 494 if (maxsock >= 0 && fd > maxsock) { 463 495 prev_maxsock = maxsock = fd; 496 dbg("maxsock:%d\n", maxsock); 464 497 if ((rlim_t)fd > rlim_ofile_cur - FD_MARGIN) 465 498 bump_nofile(); … … 480 513 fd++; 481 514 } 515 dbg("recalculated maxsock:%d\n", maxsock); 482 516 prev_maxsock = maxsock; 483 517 if ((rlim_t)maxsock > rlim_ofile_cur - FD_MARGIN) … … 502 536 /* zero out the port for all RPC services; let bind() 503 537 * find one. */ 504 set_nport( sep->se_lsa, 0);538 set_nport(&sep->se_lsa->u.sa, 0); 505 539 506 540 /* for RPC services, attempt to use a reserved port … … 537 571 return; 538 572 } 539 if (sep->se_socktype == SOCK_STREAM) 573 574 if (sep->se_socktype == SOCK_STREAM) { 540 575 listen(fd, global_queuelen); 576 dbg("new sep->se_fd:%d (stream)\n", fd); 577 } else { 578 dbg("new sep->se_fd:%d (!stream)\n", fd); 579 } 541 580 542 581 add_fd_to_set(fd); … … 960 999 if (LONE_CHAR(sep->se_local_hostname, '*')) { 961 1000 lsa = xzalloc_lsa(sep->se_family); 962 set_nport( lsa, port);1001 set_nport(&lsa->u.sa, port); 963 1002 } else { 964 1003 lsa = host_and_af2sockaddr(sep->se_local_hostname, … … 1000 1039 block_CHLD_HUP_ALRM(&omask); 1001 1040 sepp = &serv_list; 1002 while ((sep = *sepp) ) {1041 while ((sep = *sepp) != NULL) { 1003 1042 if (sep->se_checked) { 1004 1043 sepp = &sep->se_next; … … 1092 1131 close(sep->se_fd); 1093 1132 } 1094 remove_pidfile( _PATH_INETDPID);1133 remove_pidfile(CONFIG_PID_FILE_PATH "/inetd.pid"); 1095 1134 exit(EXIT_SUCCESS); 1096 1135 } … … 1141 1180 } 1142 1181 1143 write_pidfile( _PATH_INETDPID);1182 write_pidfile(CONFIG_PID_FILE_PATH "/inetd.pid"); 1144 1183 1145 1184 /* never fails under Linux (except if you pass it bad arguments) */ … … 1154 1193 sigaddset(&sa.sa_mask, SIGCHLD); 1155 1194 sigaddset(&sa.sa_mask, SIGHUP); 1195 //FIXME: explain why no SA_RESTART 1196 //FIXME: retry_network_setup is unsafe to run in signal handler (many reasons)! 1156 1197 sa.sa_handler = retry_network_setup; 1157 1198 sigaction_set(SIGALRM, &sa); 1199 //FIXME: reread_config_file is unsafe to run in signal handler(many reasons)! 1158 1200 sa.sa_handler = reread_config_file; 1159 1201 sigaction_set(SIGHUP, &sa); 1202 //FIXME: reap_child is unsafe to run in signal handler (uses stdio)! 1160 1203 sa.sa_handler = reap_child; 1161 1204 sigaction_set(SIGCHLD, &sa); 1205 //FIXME: clean_up_and_exit is unsafe to run in signal handler (uses stdio)! 1162 1206 sa.sa_handler = clean_up_and_exit; 1163 1207 sigaction_set(SIGTERM, &sa); … … 1189 1233 continue; 1190 1234 } 1235 dbg("ready_fd_cnt:%d\n", ready_fd_cnt); 1191 1236 1192 1237 for (sep = serv_list; ready_fd_cnt && sep; sep = sep->se_next) { … … 1194 1239 continue; 1195 1240 1241 dbg("ready fd:%d\n", sep->se_fd); 1196 1242 ready_fd_cnt--; 1197 1243 ctrl = sep->se_fd; … … 1201 1247 if (sep->se_socktype == SOCK_STREAM) { 1202 1248 ctrl = accepted_fd = accept(sep->se_fd, NULL, NULL); 1249 dbg("accepted_fd:%d\n", accepted_fd); 1203 1250 if (ctrl < 0) { 1204 1251 if (errno != EINTR) … … 1221 1268 * Parent must create and use new socket instead. */ 1222 1269 new_udp_fd = socket(sep->se_family, SOCK_DGRAM, 0); 1270 dbg("new_udp_fd:%d\n", new_udp_fd); 1223 1271 if (new_udp_fd < 0) { /* error: eat packet, forget about it */ 1224 1272 udp_err: … … 1227 1275 } 1228 1276 setsockopt_reuseaddr(new_udp_fd); 1229 /* TODO: better do bind after vfork in parent,1277 /* TODO: better do bind after fork in parent, 1230 1278 * so that we don't have two wildcard bound sockets 1231 1279 * even for a brief moment? */ 1232 1280 if (bind(new_udp_fd, &sep->se_lsa->u.sa, sep->se_lsa->len) < 0) { 1281 dbg("bind(new_udp_fd) failed\n"); 1233 1282 close(new_udp_fd); 1234 1283 goto udp_err; 1235 1284 } 1285 dbg("bind(new_udp_fd) succeeded\n"); 1236 1286 } 1237 1287 } … … 1261 1311 rearm_alarm(); /* will revive it in RETRYTIME sec */ 1262 1312 restore_sigmask(&omask); 1313 maybe_close(new_udp_fd); 1263 1314 maybe_close(accepted_fd); 1264 1315 continue; /* -> check next fd in fd set */ … … 1281 1332 sleep(1); 1282 1333 restore_sigmask(&omask); 1334 maybe_close(new_udp_fd); 1283 1335 maybe_close(accepted_fd); 1284 1336 continue; /* -> check next fd in fd set */ … … 1287 1339 pid--; /* -1: "we did fork and we are child" */ 1288 1340 } 1289 /* if pid == 0 here, we never forked*/1341 /* if pid == 0 here, we didn't fork */ 1290 1342 1291 1343 if (pid > 0) { /* parent */ 1292 1344 if (sep->se_wait) { 1293 /* tcp wait: we passed listeningsocket to child,1345 /* wait: we passed socket to child, 1294 1346 * will wait for child to terminate */ 1295 1347 sep->se_wait = pid; … … 1300 1352 * we created and will use new, unconnected one */ 1301 1353 xmove_fd(new_udp_fd, sep->se_fd); 1354 dbg("moved new_udp_fd:%d to sep->se_fd:%d\n", new_udp_fd, sep->se_fd); 1302 1355 } 1303 1356 restore_sigmask(&omask); … … 1306 1359 } 1307 1360 1308 /* we are either child or didn't vfork at all */1361 /* we are either child or didn't fork at all */ 1309 1362 #ifdef INETD_BUILTINS_ENABLED 1310 1363 if (sep->se_builtin) { 1311 if (pid) { /* "pid" is -1: we did vfork */1364 if (pid) { /* "pid" is -1: we did fork */ 1312 1365 close(sep->se_fd); /* listening socket */ 1366 dbg("closed sep->se_fd:%d\n", sep->se_fd); 1313 1367 logmode = LOGMODE_NONE; /* make xwrite etc silent */ 1314 1368 } … … 1318 1372 else 1319 1373 sep->se_builtin->bi_dgram_fn(ctrl, sep); 1320 if (pid) /* we did vfork */1374 if (pid) /* we did fork */ 1321 1375 _exit(EXIT_FAILURE); 1322 1376 maybe_close(accepted_fd); … … 1328 1382 /* "nowait" udp */ 1329 1383 if (new_udp_fd >= 0) { 1330 len_and_sockaddr *lsa = xzalloc_lsa(sep->se_family); 1384 len_and_sockaddr *lsa; 1385 int r; 1386 1387 close(new_udp_fd); 1388 dbg("closed new_udp_fd:%d\n", new_udp_fd); 1389 lsa = xzalloc_lsa(sep->se_family); 1331 1390 /* peek at the packet and remember peer addr */ 1332 intr = recvfrom(ctrl, NULL, 0, MSG_PEEK|MSG_DONTWAIT,1391 r = recvfrom(ctrl, NULL, 0, MSG_PEEK|MSG_DONTWAIT, 1333 1392 &lsa->u.sa, &lsa->len); 1334 1393 if (r < 0) … … 1338 1397 * and bare write()/send() will work on it */ 1339 1398 connect(ctrl, &lsa->u.sa, lsa->len); 1399 dbg("connected ctrl:%d to remote peer\n", ctrl); 1340 1400 free(lsa); 1341 1401 } … … 1355 1415 goto do_exit1; 1356 1416 } 1357 if (pwd->pw_uid ) {1417 if (pwd->pw_uid != 0) { 1358 1418 if (sep->se_group) 1359 1419 pwd->pw_gid = grp->gr_gid; … … 1374 1434 xmove_fd(ctrl, STDIN_FILENO); 1375 1435 xdup2(STDIN_FILENO, STDOUT_FILENO); 1436 dbg("moved ctrl:%d to fd 0,1[,2]\n", ctrl); 1376 1437 /* manpages of inetd I managed to find either say 1377 1438 * that stderr is also redirected to the network, … … 1386 1447 sigaction_set(SIGPIPE, &saved_pipe_handler); 1387 1448 restore_sigmask(&omask); 1449 dbg("execing:'%s'\n", sep->se_program); 1388 1450 BB_EXECVP(sep->se_program, sep->se_argv); 1389 1451 bb_perror_msg("can't execute '%s'", sep->se_program);
Note:
See TracChangeset
for help on using the changeset viewer.