int fakeidentd_main(int argc, char **argv) { enum { OPT_foreground = 0x1, OPT_inetd = 0x2, OPT_inetdwait = 0x4, OPT_fiw = 0x7, OPT_bindaddr = 0x8, }; const char *bind_address = NULL; unsigned opt; int fd; opt = getopt32(argv, "fiwb:", &bind_address); strcpy(bogouser, "nobody"); if (argv[optind]) strncpy(bogouser, argv[optind], sizeof(bogouser)); /* Daemonize if no -f and no -i and no -w */ if (!(opt & OPT_fiw)); bb_daemonize_or_rexec(0, argv); /* Where to log in inetd modes? "Classic" inetd * probably has its stderr /dev/null'ed (we need log to syslog?), * but daemontools-like utilities usually expect that children * log to stderr. I like daemontools more. Go their way. * (Or maybe we need yet another option "log to syslog") */ if (!(opt & OPT_fiw) /* || (opt & OPT_syslog) */) { openlog(applet_name, 0, LOG_DAEMON); logmode = LOGMODE_SYSLOG; } if (opt & OPT_inetd) { inetd_mode(); return 0; } /* Ignore closed connections when writing */ signal(SIGPIPE, SIG_IGN); fd = 0; if (!(opt & OPT_inetdwait)) { fd = create_and_bind_stream_or_die(bind_address, bb_lookup_port("identd", "tcp", 113)); xlisten(fd, 5); } isrv_run(fd, new_peer, do_rd, /*do_wr:*/ NULL, do_timeout, TIMEOUT, (opt & OPT_inetdwait) ? TIMEOUT : 0); return 0; }
int xbind_connect(const len_and_sockaddr *lsa, const char *ip) { int fd; /*Start of MNT 2008-10-13 14:40 for 传输超时检测 by z65940*/ g_TimeoutCnt = ATP_CONNECT_TIMEOUT_D; // 每个命令的超时检测 /*End of MNT 2008-10-13 14:40 for by z65940*/ #if 0 /*Added by yehuisheng00183935@20110806 修改IPv6链路地址访问问题--使用链路地址时,必须指定参数"sin6_scope_id"*/ if ( AF_INET6 == lsa->u.sa.sa_family ) { if (IN6_IS_ADDR_LINKLOCAL(&(((struct sockaddr_in6 *)(&(lsa->u.sa)))->sin6_addr))) { ((struct sockaddr_in6 *)(&(lsa->u.sa)))->sin6_scope_id = if_nametoindex("br0"); } } /*Added by yehuisheng00183935@20110806 修改IPv6链路地址访问问题--使用链路地址时,必须指定参数"sin6_scope_id"*/ #endif if (NULL == ip) { // No bind, the same as xconnect_stream fd = xconnect_stream(lsa); /*Start of MNT 2008-10-13 14:40 for 传输超时检测 by z65940*/ g_TimeoutCnt = -1; /*End of MNT 2008-10-13 14:40 for by z65940*/ return fd; } // Bind to specified local interface //fd = create_and_bind_stream_or_die(ip, get_nport(&(lsa->u.sa))); fd = create_and_bind_stream_or_die(ip, 0); xconnect(fd, &(lsa->u.sa), lsa->len); /*Start of MNT 2008-10-13 14:40 for 传输超时检测 by z65940*/ g_TimeoutCnt = -1; /*End of MNT 2008-10-13 14:40 for by z65940*/ return fd; }
int fakeidentd_main(int argc, char **argv) { int fd; pid_t pid; /* FD_ZERO(&G.readfds); - in bss, already zeroed */ FD_SET(0, &G.readfds); /* handle -b <ip> parameter */ getopt32(argc, argv, "b:", &bind_ip_address); /* handle optional REPLY STRING */ if (optind < argc) G.identuser = argv[optind]; else G.identuser = "******"; writepid(); signal(SIGTERM, handlexitsigs); signal(SIGINT, handlexitsigs); signal(SIGQUIT, handlexitsigs); signal(SIGHUP, SIG_IGN); signal(SIGPIPE, SIG_IGN); /* ignore closed connections when writing */ fd = create_and_bind_stream_or_die(bind_ip_address, bb_lookup_port("identd", "tcp", 113)); xlisten(fd, 5); pid = fork(); if (pid < 0) bb_perror_msg_and_die("fork"); if (pid != 0) /* parent */ exit(0); /* child */ setsid(); movefd(fd, 0); while (fd) close(fd--); openlog(applet_name, 0, LOG_DAEMON); logmode = LOGMODE_SYSLOG; /* main loop where we process all events and never exit */ while (1) { fd_set rfds = G.readfds; struct timeval tv = { 15, 0 }; int i; int tim = time(NULL); select(G.conncnt + FCS, &rfds, NULL, NULL, G.conncnt? &tv: NULL); for (i = G.conncnt - 1; i >= 0; i--) { int s = i + FCS; if (FD_ISSET(s, &rfds)) { char *buf = conns[i].buf; unsigned len = conns[i].len; unsigned l; l = read(s, buf + len, sizeof(conns[0].buf) - len); if (l > 0) { if (checkInput(buf, len, l)) { reply(s, buf); goto deleteconn; } else if (len + l >= sizeof(conns[0].buf)) { replyError(s, "X-INVALID-REQUEST"); goto deleteconn; } else { conns[i].len += l; } } else { goto deleteconn; } conns[i].lasttime = tim; continue; deleteconn: deleteConn(s); } else { /* implement as time_after() in linux kernel sources ... */ if (conns[i].lasttime + MAXIDLETIME <= tim) { replyError(s, "X-TIMEOUT"); deleteConn(s); } } } if (FD_ISSET(0, &rfds)) { int s = accept(0, NULL, 0); if (s < 0) { if (errno != EINTR) bb_perror_msg("accept"); } else { if (G.conncnt == MAXCONNS) i = closeOldest(); else i = G.conncnt++; movefd(s, i + FCS); /* move if not already there */ FD_SET(i + FCS, &G.readfds); conns[i].len = 0; conns[i].lasttime = time(NULL); } } } /* end of while (1) */ return 0; }