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

📄 inetd.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		return;	}	if (sep->se_socktype == SOCK_STREAM)		listen(sep->se_fd, 10);	FD_SET(sep->se_fd, &allsock);	nsock++;	if (sep->se_fd > maxsock)		maxsock = sep->se_fd;	if (debug) {		fprintf(stderr, "registered %s on %d\n",			sep->se_server, sep->se_fd);	}}/* * Finish with a service and its socket. */voidclose_sep(sep)	struct servtab *sep;{	if (sep->se_fd >= 0) {		nsock--;		FD_CLR(sep->se_fd, &allsock);		(void) close(sep->se_fd);		sep->se_fd = -1;	}	sep->se_count = 0;	/*	 * Don't keep the pid of this running deamon: when reapchild()	 * reaps this pid, it would erroneously increment nsock.	 */	if (sep->se_wait > 1)		sep->se_wait = 1;}struct servtab *enter(cp)	struct servtab *cp;{	struct servtab *sep;	long omask;	sep = (struct servtab *)malloc(sizeof (*sep));	if (sep == (struct servtab *)0) {		syslog(LOG_ERR, "Out of memory.");		exit(-1);	}	*sep = *cp;	sep->se_fd = -1;	omask = sigblock(SIGBLOCK);	sep->se_next = servtab;	servtab = sep;	sigsetmask(omask);	return (sep);}FILE	*fconfig = NULL;struct	servtab serv;char	line[LINE_MAX];intsetconfig(){	if (fconfig != NULL) {		fseek(fconfig, 0L, SEEK_SET);		return (1);	}	fconfig = fopen(CONFIG, "r");	return (fconfig != NULL);}voidendconfig(){	if (fconfig) {		(void) fclose(fconfig);		fconfig = NULL;	}}struct servtab *getconfigent(){	struct servtab *sep = &serv;	int argc;	char *cp, *arg;	static char TCPMUX_TOKEN[] = "tcpmux/";#define MUX_LEN		(sizeof(TCPMUX_TOKEN)-1)more:	while ((cp = nextline(fconfig)) && (*cp == '#' || *cp == '\0'))		;	if (cp == NULL)		return ((struct servtab *)0);	/*	 * clear the static buffer, since some fields (se_ctrladdr,	 * for example) don't get initialized here.	 */	memset((caddr_t)sep, 0, sizeof *sep);	arg = skip(&cp);	if (cp == NULL) {		/* got an empty line containing just blanks/tabs. */		goto more;	}	if (strncmp(arg, TCPMUX_TOKEN, MUX_LEN) == 0) {		char *c = arg + MUX_LEN;		if (*c == '+') {			sep->se_type = MUXPLUS_TYPE;			c++;		} else			sep->se_type = MUX_TYPE;		sep->se_service = newstr(c);	} else {		sep->se_service = newstr(arg);		sep->se_type = NORM_TYPE;	}	arg = sskip(&cp);	if (strcmp(arg, "stream") == 0)		sep->se_socktype = SOCK_STREAM;	else if (strcmp(arg, "dgram") == 0)		sep->se_socktype = SOCK_DGRAM;	else if (strcmp(arg, "rdm") == 0)		sep->se_socktype = SOCK_RDM;	else if (strcmp(arg, "seqpacket") == 0)		sep->se_socktype = SOCK_SEQPACKET;	else if (strcmp(arg, "raw") == 0)		sep->se_socktype = SOCK_RAW;	else		sep->se_socktype = -1;	sep->se_proto = newstr(sskip(&cp));	arg = sskip(&cp);	sep->se_wait = strcmp(arg, "wait") == 0;	if (ISMUX(sep)) {		/*		 * Silently enforce "nowait" for TCPMUX services since		 * they don't have an assigned port to listen on.		 */		sep->se_wait = 0;		if (strcmp(sep->se_proto, "tcp")) {			syslog(LOG_ERR, 				"%s: bad protocol for tcpmux service %s",				CONFIG, sep->se_service);			goto more;		}		if (sep->se_socktype != SOCK_STREAM) {			syslog(LOG_ERR, 				"%s: bad socket type for tcpmux service %s",				CONFIG, sep->se_service);			goto more;		}	}	sep->se_user = newstr(sskip(&cp));	sep->se_server = newstr(sskip(&cp));	if (strcmp(sep->se_server, "internal") == 0) {		struct biltin *bi;		for (bi = biltins; bi->bi_service; bi++)			if (bi->bi_socktype == sep->se_socktype &&			    strcmp(bi->bi_service, sep->se_service) == 0)				break;		if (bi->bi_service == 0) {			syslog(LOG_ERR, "internal service %s unknown",				sep->se_service);			goto more;		}		sep->se_bi = bi;		sep->se_wait = bi->bi_wait;	} else		sep->se_bi = NULL;	argc = 0;	for (arg = skip(&cp); cp; arg = skip(&cp))		if (argc < MAXARGV)			sep->se_argv[argc++] = newstr(arg);	while (argc <= MAXARGV)		sep->se_argv[argc++] = NULL;	return (sep);}voidfreeconfig(cp)	struct servtab *cp;{	int i;	if (cp->se_service)		free(cp->se_service);	if (cp->se_proto)		free(cp->se_proto);	if (cp->se_user)		free(cp->se_user);	if (cp->se_server)		free(cp->se_server);	for (i = 0; i < MAXARGV; i++)		if (cp->se_argv[i])			free(cp->se_argv[i]);}/* * Safe skip - if skip returns null, log a syntax error in the * configuration file and exit. */char *sskip(cpp)	char **cpp;{	char *cp;	cp = skip(cpp);	if (cp == NULL) {		syslog(LOG_ERR, "%s: syntax error", CONFIG);		exit(-1);	}	return (cp);}char *skip(cpp)	char **cpp;{	char *cp = *cpp;	char *start;again:	while (*cp == ' ' || *cp == '\t')		cp++;	if (*cp == '\0') {		int c;		c = getc(fconfig);		(void) ungetc(c, fconfig);		if (c == ' ' || c == '\t')			if (cp = nextline(fconfig))				goto again;		*cpp = (char *)0;		return ((char *)0);	}	start = cp;	while (*cp && *cp != ' ' && *cp != '\t')		cp++;	if (*cp != '\0')		*cp++ = '\0';	*cpp = cp;	return (start);}char *nextline(fd)	FILE *fd;{	char *cp;	if (fgets(line, sizeof (line), fd) == NULL)		return ((char *)0);	cp = strchr(line, '\n');	if (cp)		*cp = '\0';	return (line);}char *newstr(cp)	char *cp;{	if (cp = strdup(cp ? cp : ""))		return (cp);	syslog(LOG_ERR, "strdup: %m");	exit(-1);}voidsetproctitle(a, s)	char *a;	int s;{	int size;	char *cp;	struct sockaddr_in sin;	char buf[80];	cp = Argv[0];	size = sizeof(sin);	if (getpeername(s, (struct sockaddr *)&sin, &size) == 0)		(void) sprintf(buf, "-%s [%s]", a, inet_ntoa(sin.sin_addr)); 	else		(void) sprintf(buf, "-%s", a); 	strncpy(cp, buf, LastArg - cp);	cp += strlen(cp);	while (cp < LastArg)		*cp++ = ' ';}/* * Internet services provided internally by inetd: */#define	BUFSIZE	8192/* ARGSUSED */voidecho_stream(s, sep)		/* Echo service -- echo data back */	int s;	struct servtab *sep;{	char buffer[BUFSIZE];	int i;	setproctitle(sep->se_service, s);	while ((i = read(s, buffer, sizeof(buffer))) > 0 &&	    write(s, buffer, i) > 0)		;	exit(0);}/* ARGSUSED */voidecho_dg(s, sep)			/* Echo service -- echo data back */	int s;	struct servtab *sep;{	char buffer[BUFSIZE];	int i, size;	struct sockaddr sa;	size = sizeof(sa);	if ((i = recvfrom(s, buffer, sizeof(buffer), 0, &sa, &size)) < 0)		return;	(void) sendto(s, buffer, i, 0, &sa, sizeof(sa));}/* ARGSUSED */voiddiscard_stream(s, sep)		/* Discard service -- ignore data */	int s;	struct servtab *sep;{	int ret;	char buffer[BUFSIZE];	setproctitle(sep->se_service, s);	while (1) {		while ((ret = read(s, buffer, sizeof(buffer))) > 0)			;		if (ret == 0 || errno != EINTR)			break;	}	exit(0);}/* ARGSUSED */voiddiscard_dg(s, sep)		/* Discard service -- ignore data */	int s;	struct servtab *sep;{	char buffer[BUFSIZE];	(void) read(s, buffer, sizeof(buffer));}#include <ctype.h>#define LINESIZ 72char ring[128];char *endring;voidinitring(){	int i;	endring = ring;	for (i = 0; i <= 128; ++i)		if (isprint(i))			*endring++ = i;}/* ARGSUSED */voidchargen_stream(s, sep)		/* Character generator */	int s;	struct servtab *sep;{	int len;	char *rs, text[LINESIZ+2];	setproctitle(sep->se_service, s);	if (!endring) {		initring();		rs = ring;	}	text[LINESIZ] = '\r';	text[LINESIZ + 1] = '\n';	for (rs = ring;;) {		if ((len = endring - rs) >= LINESIZ)			memmove(text, rs, LINESIZ);		else {			memmove(text, rs, len);			memmove(text + len, ring, LINESIZ - len);		}		if (++rs == endring)			rs = ring;		if (write(s, text, sizeof(text)) != sizeof(text))			break;	}	exit(0);}/* ARGSUSED */voidchargen_dg(s, sep)		/* Character generator */	int s;	struct servtab *sep;{	struct sockaddr sa;	static char *rs;	int len, size;	char text[LINESIZ+2];	if (endring == 0) {		initring();		rs = ring;	}	size = sizeof(sa);	if (recvfrom(s, text, sizeof(text), 0, &sa, &size) < 0)		return;	if ((len = endring - rs) >= LINESIZ)		memmove(text, rs, LINESIZ);	else {		memmove(text, rs, len);		memmove(text + len, ring, LINESIZ - len);	}	if (++rs == endring)		rs = ring;	text[LINESIZ] = '\r';	text[LINESIZ + 1] = '\n';	(void) sendto(s, text, sizeof(text), 0, &sa, sizeof(sa));}/* * Return a machine readable date and time, in the form of the * number of seconds since midnight, Jan 1, 1900.  Since gettimeofday * returns the number of seconds since midnight, Jan 1, 1970, * we must add 2208988800 seconds to this figure to make up for * some seventy years Bell Labs was asleep. */longmachtime(){	struct timeval tv;	if (gettimeofday(&tv, (struct timezone *)0) < 0) {		if (debug)			fprintf(stderr, "Unable to get time of day\n");		return (0L);	}#define	OFFSET ((u_long)25567 * 24*60*60)	return (htonl((long)(tv.tv_sec + OFFSET)));#undef OFFSET}/* ARGSUSED */voidmachtime_stream(s, sep)	int s;	struct servtab *sep;{	long result;	result = machtime();	(void) write(s, (char *) &result, sizeof(result));}/* ARGSUSED */voidmachtime_dg(s, sep)	int s;	struct servtab *sep;{	long result;	struct sockaddr sa;	int size;	size = sizeof(sa);	if (recvfrom(s, (char *)&result, sizeof(result), 0, &sa, &size) < 0)		return;	result = machtime();	(void) sendto(s, (char *) &result, sizeof(result), 0, &sa, sizeof(sa));}/* ARGSUSED */voiddaytime_stream(s, sep)		/* Return human-readable time of day */	int s;	struct servtab *sep;{	char buffer[256];	time_t clock;	clock = time((time_t *) 0);	(void) sprintf(buffer, "%.24s\r\n", ctime(&clock));	(void) write(s, buffer, strlen(buffer));}/* ARGSUSED */voiddaytime_dg(s, sep)		/* Return human-readable time of day */	int s;	struct servtab *sep;{	char buffer[256];	time_t clock;	struct sockaddr sa;	int size;	clock = time((time_t *) 0);	size = sizeof(sa);	if (recvfrom(s, buffer, sizeof(buffer), 0, &sa, &size) < 0)		return;	(void) sprintf(buffer, "%.24s\r\n", ctime(&clock));	(void) sendto(s, buffer, strlen(buffer), 0, &sa, sizeof(sa));}/* * print_service: *	Dump relevant information to stderr */voidprint_service(action, sep)	char *action;	struct servtab *sep;{	fprintf(stderr,	    "%s: %s proto=%s, wait=%d, user=%s builtin=%x server=%s\n",	    action, sep->se_service, sep->se_proto,	    sep->se_wait, sep->se_user, (int)sep->se_bi, sep->se_server);}/* *  Based on TCPMUX.C by Mark K. Lottor November 1988 *  sri-nic::ps:<mkl>tcpmux.c */static int		/* # of characters upto \r,\n or \0 */getline(fd, buf, len)	int fd;	char *buf;	int len;{	int count = 0, n;	do {		n = read(fd, buf, len-count);		if (n == 0)			return (count);		if (n < 0)			return (-1);		while (--n >= 0) {			if (*buf == '\r' || *buf == '\n' || *buf == '\0')				return (count);			count++;			buf++;		}	} while (count < len);	return (count);}#define MAX_SERV_LEN	(256+2)		/* 2 bytes for \r\n */#define strwrite(fd, buf)	(void) write(fd, buf, sizeof(buf)-1)struct servtab *tcpmux(s)	int s;{	struct servtab *sep;	char service[MAX_SERV_LEN+1];	int len;	/* Get requested service name */	if ((len = getline(s, service, MAX_SERV_LEN)) < 0) {		strwrite(s, "-Error reading service name\r\n");		return (NULL);	}	service[len] = '\0';	if (debug)		fprintf(stderr, "tcpmux: someone wants %s\n", service);	/*	 * Help is a required command, and lists available services,	 * one per line.	 */	if (!strcasecmp(service, "help")) {		for (sep = servtab; sep; sep = sep->se_next) {			if (!ISMUX(sep))				continue;			(void)write(s,sep->se_service,strlen(sep->se_service));			strwrite(s, "\r\n");		}		return (NULL);	}	/* Try matching a service in inetd.conf with the request */	for (sep = servtab; sep; sep = sep->se_next) {		if (!ISMUX(sep))			continue;		if (!strcasecmp(service, sep->se_service)) {			if (ISMUXPLUS(sep)) {				strwrite(s, "+Go\r\n");			}			return (sep);		}	}	strwrite(s, "-Service not available\r\n");	return (NULL);}

⌨️ 快捷键说明

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