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

📄 servtab.c

📁 netkit-base-0.17.tar.gz linux嵌入式开发使用!
💻 C
📖 第 1 页 / 共 2 页
字号:
			s = strchr(sep->se_service, '/');			if (!s) return "No RPC version";			*s++ = 0;			sep->se_rpcversl = strtol(s, &t, 0);			if (t==s) return "Invalid RPC version";			if (*t=='-') {				s = t+1;				sep->se_rpcversh = strtol(s, &t, 0);				if (t==s) return "Invalid RPC high version";			}			else {				sep->se_rpcversh = sep->se_rpcversl;			}#else			return "No support for RPC services compiled in";#endif		}	}	s = strchr(fields[3], '.');	if (s) {		*s++ = 0;		sep->se_max = atoi(s);	}	else {		sep->se_max = TOOMANY;	}	sep->se_wait = !strcmp(fields[3], "wait");	free(fields[3]);	s = strchr(fields[4], '.');	if (s) {		*s++ = 0;		sep->se_group = s;	}	else {		sep->se_group = NULL;	}	sep->se_user = fields[4];	sep->se_server = fields[5];	if (!strcmp(fields[5], "internal")) {		sep->se_bi = find_builtin(sep->se_socktype, sep->se_service);		if (sep->se_bi==NULL) {			return "Invalid internal service";		}		sep->se_wait = sep->se_bi->bi_wait;	}	else {		sep->se_bi = NULL;	}	/* The rest are argv[]. */ 	for (i=6; i<nfields; i++) {		sep->se_argv[i-6] = fields[i];	}	/* Most programs core if argv[0] is null. */	if (!sep->se_argv[0]) {		sep->se_argv[0] = dostrdup(sep->se_server);	}	return NULL;}staticconst char *nexttoken(void){	static char linebuf[256];	char *s;	/*	 * Hack: linebuf[0-1] is not read into; it is always "Q ". This permits	 * us to initialize strtok so that it will return the first word on	 * the line on the _next_ call if we so choose.	 */	linebuf[0] = 'Q';	linebuf[1] = ' ';	s = strtok(NULL, " \t\n");	if (s!=NULL) return s;	do {		if (fgets(linebuf+2, sizeof(linebuf)-2, fconfig)==NULL) {			return NULL;		}	} while (linebuf[2]=='#');	if (!strchr(" \t", linebuf[2])) {		/* Not a continuation line - send back EOL */		strtok(linebuf, " \t\n");  /* returns Q */		return "";	}	s = strtok(linebuf+2, " \t\n");	if (!s) return ""; /* empty line -> send EOL */	return s;}staticvoidloadconfigfile(void (*sendents)(struct servtab *)){	/* 6 fields plus argv, but the last entry of argv[] must remain null */	char *fields[MAXARGV+6-1];	int nfields=0;	int warned=0;	const char *s;	int eof=0;	struct servtab assm; /* assemble entries into here */	char junk[4];	/*	 * Insure strtok() will start at EOL.	 */	junk[0] = 'Q' ;	junk[1] = 0;		strtok(junk, " \t\n");		while (!eof) {		s = nexttoken();		if (!s&& nfields<1) {			eof = 1;		}		else if (!s || (!*s && nfields>0)) {			const char *errmsg;			errmsg = assemble_entry(&assm, nfields, fields);			if (errmsg) {				syslog(LOG_WARNING, "Bad config for %s: %s"				       " (skipped)", fields[0], errmsg);			}			else {				sendents(&assm);			}                        if (!s) {	                	eof = 1;	                        }	                else {				nfields = 0;			       	warned = 0;			}		}		else if (!*s) {			/* blank line */		}		else if (nfields < MAXARGV+6) {			fields[nfields++] = dostrdup(s);		}		else if (!warned) {			syslog(LOG_WARNING, "%s: too many arguments, max %d",			       fields[0], MAXARGV);			warned = 1;		}	}}#endif/********* config loading ****************************************/static intsetconfig(void){	if (fconfig != NULL) {		fseek(fconfig, 0L, SEEK_SET);		return (1);	}	fconfig = fopen(configfile, "r");	return (fconfig != NULL);}static voidendconfig(void){	if (fconfig) {		(void) fclose(fconfig);		fconfig = NULL;	}}static voidfreeconfig(struct servtab *cp){	int i;	if (cp->se_service)		free(cp->se_service);	cp->se_service = NULL;	cp->se_address = NULL;  /* points into se_service */	if (cp->se_proto)		free(cp->se_proto);	cp->se_proto = NULL;	if (cp->se_user)		free(cp->se_user);	cp->se_user = NULL;	cp->se_group = NULL;  /* points into se_user */	if (cp->se_server)		free(cp->se_server);	cp->se_server = NULL;	for (i = 0; i < MAXARGV; i++) {		if (cp->se_argv[i])			free(cp->se_argv[i]);		cp->se_argv[i] = NULL;	}}/* * print_service: *	Dump relevant information to stderr */static voidprint_service(const char *action, struct servtab *sep){	if (isrpcservice(sep))		fprintf(stderr,		    "%s: %s rpcprog=%d, rpcvers = %d/%d, proto=%s, wait.max=%d.%d, user.group=%s.%s builtin=%lx server=%s\n",		    action, sep->se_service,		    sep->se_rpcprog, sep->se_rpcversh, sep->se_rpcversl, sep->se_proto,		    sep->se_wait, sep->se_max, sep->se_user, sep->se_group,		    (unsigned long)sep->se_bi, sep->se_server);	else		fprintf(stderr,		    "%s: %s proto=%s, wait.max=%d.%d, user.group=%s.%s builtin=%lx server=%s\n",		    action, sep->se_service, sep->se_proto,		    sep->se_wait, sep->se_max, sep->se_user, sep->se_group,		    (unsigned long)sep->se_bi, sep->se_server);}staticvoidloadconfigent(struct servtab *cp){	struct servtab *sep;	unsigned n;	/*	 * dholland 7/14/1997: always use the canonical service 	 * name to protect against silly configs that list a 	 * service twice under different aliases. This has been	 * observed in the wild thanks to Slackware... 	 * Note: this is a patch, not a fix. The real fix is	 * to key the table by port and protocol, not service name	 * and protocol.	 */	if (cp->se_family==AF_INET && !isrpcservice(cp)) {		u_short port = htons(atoi(cp->se_service));				if (!port) {			struct servent *sp;			sp = getservbyname(cp->se_service,					   cp->se_proto);			if (sp != NULL) { /* bogus services are caught later */				if (strcmp(cp->se_service, sp->s_name)) {					/*					 * Ugh. Since se_address points into					 * se_service, we need to copy both					 * together. Ew.					 */					char *tmp, *tmp2 = NULL;					const char *addr = cp->se_address;					size_t len = strlen(sp->s_name)+1;					if (addr==NULL) addr = "";					len += strlen(addr)+1;					tmp = domalloc(len);					strcpy(tmp, cp->se_service);					if (cp->se_address) {						tmp2 = tmp+strlen(tmp)+1;						strcpy(tmp2, cp->se_address);					}					free(cp->se_service);					cp->se_service = tmp;					cp->se_address = tmp2;				}			}		}	}	/* End silly patch */	sep = find_same_service(cp);	if (sep != NULL) {		int i;				if (sep->se_checked) {			syslog(LOG_WARNING, 			       "extra conf for service %s (skipped)\n",			       service_name(sep));			return;		}		#define SWAP(type, a, b) {type c=(type)a; (type)a=(type)b; (type)b=(type)c;}		/*		 * sep->se_wait may be holding the pid of a daemon		 * that we're waiting for.  If so, don't overwrite		 * it unless the config file explicitly says don't 		 * wait.		 */		if (cp->se_bi == 0 && (sep->se_wait == 1 || cp->se_wait == 0))			sep->se_wait = cp->se_wait;		if (cp->se_max != sep->se_max)			SWAP(int, cp->se_max, sep->se_max);		if (cp->se_user)			SWAP(char *, sep->se_user, cp->se_user);		if (cp->se_group)			SWAP(char *, sep->se_group, cp->se_group);		if (cp->se_server)			SWAP(char *, sep->se_server, cp->se_server);		if (cp->se_address) {			/* must swap se_service; se_address points into it */			SWAP(char *, sep->se_service, cp->se_service);			SWAP(char *, sep->se_address, cp->se_address);		}		for (i = 0; i < MAXARGV; i++)			SWAP(char *, sep->se_argv[i], cp->se_argv[i]);#undef SWAP		if (isrpcservice(sep))			unregister_rpc(sep);		sep->se_rpcversl = cp->se_rpcversl;		sep->se_rpcversh = cp->se_rpcversh;		freeconfig(cp);		if (debug) {			print_service("REDO", sep);		}	}	else {		sep = enter(cp);		if (debug)			print_service("ADD ", sep);	}	sep->se_checked = 1;		switch (sep->se_family) {	case AF_UNIX:		if (sep->se_fd != -1)			break;		(void)unlink(sep->se_service);		n = strlen(sep->se_service);		if (n > sizeof(sep->se_ctrladdr_un.sun_path) - 1) 			n = sizeof(sep->se_ctrladdr_un.sun_path) - 1;		strncpy(sep->se_ctrladdr_un.sun_path, 			sep->se_service, n);		sep->se_ctrladdr_un.sun_path[n] = 0;		sep->se_ctrladdr_un.sun_family = AF_UNIX;		sep->se_ctrladdr_size = n +			sizeof sep->se_ctrladdr_un.sun_family;		setup(sep);		break;	case AF_INET:		sep->se_ctrladdr_in.sin_family = AF_INET;		sep->se_ctrladdr_size = sizeof sep->se_ctrladdr_in;		if (isrpcservice(sep)) {			struct rpcent *rp;						sep->se_rpcprog = atoi(sep->se_service);			if (sep->se_rpcprog == 0) {				rp = getrpcbyname(sep->se_service);				if (rp == 0) {					syslog(LOG_ERR,					       "%s: unknown service",					       sep->se_service);					return;				}				sep->se_rpcprog = rp->r_number;			}			if (sep->se_fd == -1)				setup(sep);			if (sep->se_fd != -1)				register_rpc(sep);		} 		else {			u_short port = htons(atoi(sep->se_service));						if (!port) {				struct servent *sp;				sp = getservbyname(sep->se_service,						   sep->se_proto);				if (sp == 0) {					syslog(LOG_ERR,					       "%s: unknown service",					       service_name(sep));					return;				}				port = sp->s_port;			}			if (port != sep->se_ctrladdr_in.sin_port) {				sep->se_ctrladdr_in.sin_port = port;				if (sep->se_fd != -1) {					closeit(sep);				}			}			if (sep->se_fd == -1)				setup(sep);		}	}}voidconfig(int signum){	register struct servtab *sep, **sepp;	(void)signum;	if (!setconfig()) {		syslog(LOG_ERR, "%s: %m", configfile);		return;	}	for (sep = servtab; sep; sep = sep->se_next)		sep->se_checked = 0;#if 0 /* old version */	while ((cp = getconfigent())!=NULL) {		loadconfigent(cp);	}#else	loadconfigfile(loadconfigent);#endif	endconfig();	/*	 * Purge anything not looked at above.	 */	sepp = &servtab;	while ((sep = *sepp) != NULL) {		if (sep->se_checked) {			sepp = &sep->se_next;			continue;		}		*sepp = sep->se_next;		if (sep->se_fd != -1) {			closeit(sep);		}		if (isrpcservice(sep))			unregister_rpc(sep);		if (sep->se_family == AF_UNIX)			(void)unlink(sep->se_service);		if (debug)			print_service("FREE", sep);		freeconfig(sep);		free((char *)sep);	}}/********* SIGALRM handler ******************************/voidrestart_services(void){	struct servtab *sep;	for (sep = servtab; sep; sep = sep->se_next) {		if (sep->se_fd == -1) {			switch (sep->se_family) {			case AF_UNIX:			case AF_INET:				setup(sep);				if (sep->se_fd != -1 && isrpcservice(sep))					register_rpc(sep);				break;			}		}	}}

⌨️ 快捷键说明

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