⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inetd.c

📁 netkit-base-0.17.tar.gz linux嵌入式开发使用!
💻 C
📖 第 1 页 / 共 2 页
字号:
		 * much a mess of the internal state.		 */		for (i=getdtablesize()-1; i>=64; i--) close(i);		return;	}	/*	 * At this point we're committed to restarting.	 * Note that we have to close everything before execing the new	 * inetd, or it won't be able to listen on the ports we've got	 * bound.	 */	for (i=getdtablesize()-1; i>2; i--) {		shutdown(i,2);		close(i);	}	/* should we try argv[0] first? probably not */	tmpargv1 = argv;	/* grr */	/*tmpargv2 = (char **)tmpargv1;*/	memcpy(&tmpargv2, &tmpargv1, sizeof(tmpargv1));	mysleep(10);	execv(_PATH_INETD, tmpargv2);	/* Should this be EMERG? */	closelog();	openlog("inetd", LOG_PID, LOG_DAEMON);	syslog(LOG_ALERT, "Restart attempt failed.");	syslog(LOG_ALERT, "Recommend manually restarting inetd ASAP.");	/* this may help restore us to a semi-operable state */	{		const char *tmp = configfile;		configfile = "/dev/null";		config(0);		configfile = tmp;		config(0);	}}intmain(int argc, char *argv[], char *envp[]){	int ch;	int nodaemon=0;	gid_t gid;	char *progname;	gid = getgid();	setgroups(1, &gid);	/*	 * Note that Linux, unlike 4.4BSD, needs to clobber the	 * environment space for setproctitle. If the total size	 * of the argv and envp strings isn't enough, you won't	 * see anything. In fact, it may not even show "inetd", only	 * "ine" or "in". There's nothing that can be done about this,	 * except run inetd with the full pathname and some long 	 * environment variables, or hack 4.4BSD-style setproctitle	 * support into Linux.	 * 	 * Note that the setproctitle implementation copies the environment,	 * so child processes won't be sent trash.	 *	 * Also note that we only setproctitle() in child processes, so	 * our progname pointer and the like remain valid.	 */	initsetproctitle(argc, argv, envp);	/*	 * This must come _after_ initsetproctitle.	 */	discard_stupid_environment();		progname = strrchr(argv[0], '/');	if (progname == NULL) {		progname = argv[0];	}	else {		progname++;	}	while ((ch = getopt(argc, argv, "diq:")) != EOF)		switch(ch) {		case 'd':			debug = nodaemon = 1;			options |= SO_DEBUG;			got_dflag = 1;			break;		case 'i':			nodaemon = 1;			got_iflag = 1;			break;		case 'q':		        global_queuelen = atoi(optarg);			if (global_queuelen < 8) global_queuelen=8;			got_qflag = 1;			break;		case '?':		default:			fprintf(stderr, "usage: %s [-di] [-q len] [conf]",				progname);			exit(1);		}	argc -= optind;	argv += optind;	if (argc > 0) {		configfile = argv[0];		got_conf = 1;	}	if (nodaemon == 0) {		daemon(0, 0);	}	else if (debug == 0) {		/*		 * If nodaemon mode, but not debug mode, run in our own		 * session. Init might have done this for us if we're being 		 * spawned from init... but it might not have.		 */		setsid();	}	openlog(progname, LOG_PID | LOG_NOWAIT, LOG_DAEMON);	logpid();#ifdef RLIMIT_NOFILE	rlim_ofile_cur = DEFAULT_FILE_LIMIT;	if (getrlimit(RLIMIT_NOFILE, &rlim_ofile) < 0) {		syslog(LOG_ERR, "getrlimit: %m");	} else if (rlim_ofile.rlim_cur != RLIM_INFINITY) {		rlim_ofile_cur = rlim_ofile.rlim_cur;	}#endif	config(0);	sig_init();	mainloop();	/* Not reachable */	return 0;}voidreapchild(int signum){	int status;	pid_t pid;	register struct servtab *sep;	const char *name;	char tmp[64];	(void)signum;	while ((pid = wait3(&status, WNOHANG, NULL)) > 0) {		if (debug) {			fprintf(stderr, "pid %d, exit status %x\n", pid, 				status);		}		sep = find_service_by_pid(pid);		if (sep==NULL) {			snprintf(tmp, sizeof(tmp), "pid %d", (int)pid);			name = tmp;		}		else {			snprintf(tmp, sizeof(tmp), "%s (pid %d)", 				 sep->se_server, (int)pid);			name = tmp;		}		if (WIFEXITED(status) && WEXITSTATUS(status)) {			syslog(LOG_WARNING, "%s: exit status %d", name,			       WEXITSTATUS(status));		}		else if (WIFSIGNALED(status)) {			syslog(LOG_WARNING, "%s: exit signal %d", name,			       WTERMSIG(status));		}		if (sep!=NULL) {			sep->se_wait = 1;			FD_SET(sep->se_fd, &allsock);			nsock++;			if (debug) {				fprintf(stderr, "restored %s, fd %d\n",					sep->se_service, sep->se_fd);			}		}	}}voidretry(int signum){	(void)signum;	timingout = 0;	restart_services();}voidgoaway(int signum){	register struct servtab *sep;	(void)signum;	for (sep = servtab; sep; sep = sep->se_next) {		if (sep->se_fd == -1)			continue;		switch (sep->se_family) {		case AF_UNIX:			(void)unlink(sep->se_service);			break;		case AF_INET:			if (sep->se_wait == 1 && isrpcservice(sep))				unregister_rpc(sep);			break;		}		(void)close(sep->se_fd);	}	(void)unlink(_PATH_INETDPID);	exit(0);}voidcloseit(struct servtab *sep){	FD_CLR(sep->se_fd, &allsock);	nsock--;	(void) close(sep->se_fd);	sep->se_fd = -1;}voidsetup(struct servtab *sep){	int on = 1;	if ((sep->se_fd = socket(sep->se_family, sep->se_socktype, 0)) < 0) {		syslog(LOG_ERR, "%s: socket: %m", service_name(sep),		    sep->se_service, sep->se_proto);		if (errno == EMFILE) {			syslog(LOG_ALERT, 			       "Out of files! Attempting restart...");			attempt_to_restart();		}		return;	}#define	turnon(fd, opt) \setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on))	if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG) &&	    turnon(sep->se_fd, SO_DEBUG) < 0)		syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m");	if (turnon(sep->se_fd, SO_REUSEADDR) < 0)		syslog(LOG_ERR, "setsockopt (SO_REUSEADDR): %m");#undef turnon	if (bind(sep->se_fd, &sep->se_ctrladdr, sep->se_ctrladdr_size) < 0) {		syslog(LOG_ERR, "%s: bind: %m", service_name(sep),		    sep->se_service, sep->se_proto);		(void) close(sep->se_fd);		sep->se_fd = -1;		if (!timingout) {			timingout = 1;			alarm(RETRYTIME);		}		return;	}	if (sep->se_socktype == SOCK_STREAM)		listen(sep->se_fd, global_queuelen);	if (sep->se_family == AF_UNIX) {		/* 		 * Ignore any error, on the grounds that chmod on a socket		 * might not be possible on some systems.		 *		 * XXX in the long run there should be a config option for		 * the mode. And owner/group, too.		 */		chmod(sep->se_ctrladdr_un.sun_path, 0666);	}	FD_SET(sep->se_fd, &allsock);	nsock++;	if (sep->se_fd > maxsock) {		maxsock = sep->se_fd;		if (maxsock > rlim_ofile_cur - FD_MARGIN)			bump_nofile();	}}voidregister_rpc(struct servtab *sep){#ifdef RPC/*	size_t m; */	socklen_t m;	int i;	struct sockaddr_in sn;	struct protoent *pp;	if ((pp = getprotobyname(sep->se_proto+4)) == NULL) {		syslog(LOG_ERR, "%s: getproto: %m",		    sep->se_proto);		return;	}	m = sizeof(sn);	if (getsockname(sep->se_fd, (struct sockaddr *)&sn, &m) < 0) {		syslog(LOG_ERR, "%s: getsockname: %m", service_name(sep),		    sep->se_service, sep->se_proto);		return;	}	for (i = sep->se_rpcversl; i <= sep->se_rpcversh; i++) {		if (debug)			fprintf(stderr, "pmap_set: %u %u %u %u\n",				sep->se_rpcprog, i, 				pp->p_proto, ntohs(sn.sin_port));		(void)pmap_unset(sep->se_rpcprog, i);		if (!pmap_set(sep->se_rpcprog, i, pp->p_proto, ntohs(sn.sin_port)))			syslog(LOG_ERR, "pmap_set: %u %u %u %u: %m",			       sep->se_rpcprog, i, 			       pp->p_proto, ntohs(sn.sin_port));	}#endif /* RPC */}voidunregister_rpc(struct servtab *sep){#ifdef RPC	int n;	for (n = sep->se_rpcversl; n <= sep->se_rpcversh; n++) {		if (debug)			fprintf(stderr, "pmap_unset(%u, %u)\n",				sep->se_rpcprog, n);		if (!pmap_unset(sep->se_rpcprog, n))			syslog(LOG_ERR, "pmap_unset(%u, %u)\n",				sep->se_rpcprog, n);	}#endif /* RPC */}struct servtab *enter(struct servtab *cp){	register struct servtab *sep;	sep = domalloc(sizeof(*sep));	*sep = *cp;	sep->se_fd = -1;	sep->se_rpcprog = -1;	sep->se_next = servtab;	servtab = sep;	return (sep);}//static char *skip(char **);//static char *nextline(FILE *);static voidlogpid(void){	FILE *fp;	if ((fp = fopen(_PATH_INETDPID, "w")) != NULL) {		fprintf(fp, "%u\n", getpid());		(void)fclose(fp);	}}static intbump_nofile(void){#ifdef RLIMIT_NOFILE#define FD_CHUNK	32	struct rlimit rl;	if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {		syslog(LOG_ERR, "getrlimit: %m");		return -1;	}	rl.rlim_cur = MIN(rl.rlim_max, rl.rlim_cur + FD_CHUNK);	if (rl.rlim_cur <= rlim_ofile_cur) {		syslog(LOG_ERR,			"bump_nofile: cannot extend file limit, max = %d",			rl.rlim_cur);		return -1;	}	if (setrlimit(RLIMIT_NOFILE, &rl) < 0) {		syslog(LOG_ERR, "setrlimit: %m");		return -1;	}	rlim_ofile_cur = rl.rlim_cur;	return 0;#else	syslog(LOG_ERR, "bump_nofile: cannot extend file limit");	return -1;#endif}#ifdef MULOGdolog(sep, ctrl)	struct servtab *sep;	int		ctrl;{	struct sockaddr		sa;	struct sockaddr_in	*sin = (struct sockaddr_in *)&sa;	int			len = sizeof(sa);	struct hostent		*hp;	char			*host, *dp, buf[BUFSIZ], *rfc931_name();	int			connected = 1;	if (sep->se_family != AF_INET)		return;	if (getpeername(ctrl, &sa, &len) < 0) {		if (errno != ENOTCONN) {			syslog(LOG_ERR, "getpeername: %m");			return;		}		if (recvfrom(ctrl, buf, sizeof(buf), MSG_PEEK, &sa, &len) < 0) {			syslog(LOG_ERR, "recvfrom: %m");			return;		}		connected = 0;	}	if (sa.sa_family != AF_INET) {		syslog(LOG_ERR, "unexpected address family %u", sa.sa_family);		return;	}	hp = gethostbyaddr((char *) &sin->sin_addr.s_addr,				sizeof (sin->sin_addr.s_addr), AF_INET);	host = hp?hp->h_name:inet_ntoa(sin->sin_addr);	switch (sep->se_log & ~MULOG_RFC931) {	case 0:		return;	case 1:		if (curdom == NULL || *curdom == '\0')			break;		dp = host + strlen(host) - strlen(curdom);		if (dp < host)			break;		if (debug)			fprintf(stderr, "check \"%s\" against curdom \"%s\"\n",					host, curdom);		if (strcasecmp(dp, curdom) == 0)			return;		break;	case 2:	default:		break;	}	openlog("", LOG_NOWAIT, MULOG);	if (connected && (sep->se_log & MULOG_RFC931))		syslog(LOG_INFO, "%s@%s wants %s",				rfc931_name(sin, ctrl), host, sep->se_service);	else		syslog(LOG_INFO, "%s wants %s",				host, sep->se_service);}/* * From tcp_log by *  Wietse Venema, Eindhoven University of Technology, The Netherlands. */#if 0static char sccsid[] = "@(#) rfc931.c 1.3 92/08/31 22:54:46";#endif#include <setjmp.h>#define	RFC931_PORT	113		/* Semi-well-known port */#define	TIMEOUT		4#define	TIMEOUT2	10static sigjmp_buf timebuf;/* timeout - handle timeouts */static void timeout(sig)int     sig;{	siglongjmp(timebuf, sig);}/* rfc931_name - return remote user name */char *rfc931_name(struct sockaddr_in *there, int ctrl){	/* "there" is remote link information */	struct sockaddr_in here;	/* local link information */	struct sockaddr_in sin;		/* for talking to RFC931 daemon */	int		length;	int		s;	unsigned	remote;	unsigned	local;	static char	user[256];		/* XXX */	char		buf[256];	char		*cp;	char		*result = "USER_UNKNOWN";	int		len;	/* Find out local port number of our stdin. */	length = sizeof(here);	if (getsockname(ctrl, (struct sockaddr *) &here, &length) == -1) {		syslog(LOG_ERR, "getsockname: %m");		return (result);	}	/* Set up timer so we won't get stuck. */	if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {		syslog(LOG_ERR, "socket: %m");		return (result);	}	sin = here;	sin.sin_port = htons(0);	if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) == -1) {		syslog(LOG_ERR, "bind: %m");		close(s);		return (result);	}	signal(SIGALRM, timeout);	if (sigsetjmp(timebuf)) {		close(s);			/* not: fclose(fp) */		return (result);	}	alarm(TIMEOUT);	/* Connect to the RFC931 daemon. */	sin = *there;	sin.sin_port = htons(RFC931_PORT);	if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == -1) {		close(s);		alarm(0);		return (result);	}	/* Query the RFC 931 server. Would 13-byte writes ever be broken up? */	snprintf(buf, sizeof(buf), "%u,%u\r\n", 		 ntohs(there->sin_port), ntohs(here.sin_port));	for (len = 0, cp = buf; len < strlen(buf); ) {		int	n;		if ((n = write(s, cp, strlen(buf) - len)) == -1) {			close(s);			alarm(0);			return (result);		}		cp += n;		len += n;	}	/* Read response */	for (cp = buf; cp < buf + sizeof(buf) - 1; ) {		char	c;		if (read(s, &c, 1) != 1) {			close(s);			alarm(0);			return (result);		}		if (c == '\n')			break;		*cp++ = c;	}	*cp = '\0';	if (sscanf(buf, "%u , %u : USERID :%*[^:]:%255s", &remote, &local, user) == 3		&& ntohs(there->sin_port) == remote		&& ntohs(here.sin_port) == local) {		/* Strip trailing carriage return. */		if (cp = strchr(user, '\r'))			*cp = 0;		result = user;	}	alarm(0);	close(s);	return (result);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -