Example #1
0
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;
}
Example #2
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;
}
Example #3
0
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;
}