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

📄 listen.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
			sprintf(scratch, nlsunknown, svc_code_p);			logmessage(scratch);			nls_reply(NLSUNKNOWN, scratch);		}	}  else		error(E_BAD_FORMAT, CONTINUE);	/* if we're still here, server didn't get exec'ed	*/	return(-1);}/* * nls_chkmsg:	validate message and return fields to caller. *		returns: TRUE == good format *			 FALSE== bad format */nls_chkmsg(bp, size, lowp, highp, svc_code_p)char *bp, *svc_code_p;int size, *lowp, *highp;{	/* first, make sure bp is null terminated */	if ((*(bp + size - 1)) != (char)0)		return(0);	/* scanf returns number of "matched and assigned items"	*/	return(sscanf(bp, "%*4c:%3d:%3d:%s", lowp, highp, svc_code_p) == 3);}/* * nls_reply:	send the "service request response message" *		when appropriate.  (Valid if running version 2 or greater). *		Must use write(2) since unknown modules may be pushed. * *		Message format: *		protocol_verion_# : message_code_# : message_text */static char *srrpprot = "%d:%d:%s";nls_reply(code, text)register code;register char *text;{	char scratch[256];	/* Nlsversion = -1 for login service */	if (Nlsversion >= 2)  {		DEBUG((7, "nls_reply: sending response message"));		sprintf(scratch, srrpprot, Nlsversion, code, text);		t_snd(0, scratch, strlen(scratch)+1, 0);	}}/* * common code to  start a server process (for any service) * if optional argv is given, info comes from o_argv, else pointer * to dbf struct is used.  In either case, first argument in argv is * full pathname of server. Before exec-ing the server, the caller's * logical address, opt and udata are addded to the environment.  */start_server(netfd, dbp, o_argv, call)int netfd;register dbf_t *dbp;register char **o_argv;struct t_call *call;{	char *path;	char **argvp;	extern char **environ;	extern struct passwd *getpwnam();	extern void endpwent();	extern struct group *getgrgid();	register struct passwd *pwdp;	struct group *grpp;	char msgbuf[256];	register dbf_t *wdbp = dbp;	/*	 * o_argv is set during SMB service setup only, in	 * which case dbp is NULL.	 */	if (o_argv) {		argvp = o_argv;		if ((wdbp = getdbfentry(DBF_SMB_CODE)) == NULL) {			/* this shouldn't happen because at this point we've			   already found it once */			logmessage("SMB message, missing data base entry");			exit(2); /* server, don't log */		}	}	else		argvp = mkdbfargv(dbp);	path = *argvp;	/* set up stdout and stderr before pushing optional modules */	(void) close(1);	(void) close(2);	if (dup(0) != 1 || dup(0) != 2) {		logmessage("Dup of fd 0 failed");		exit(2); /* server, don't log */	}	sprintf(msgbuf,"Starting server (%s)",path);	nls_reply(NLSSTART, msgbuf);	logmessage(msgbuf);	/* after pushmod, tli calls are questionable?		*/	if (dbp && pushmod(netfd, dbp->dbf_modules)) {		logmessage("Can't push server's modules: exit");		exit(2); /* server, don't log */	}	rst_signals();	if (wdbp == NULL) {		logmessage("No database entry");		exit(2); /* server, don't log */	}/*	if ((pwdp = getpwnam(wdbp->dbf_id)) == NULL) {		sprintf(msgbuf, "Missing or bad passwd entry for <%s>", wdbp->dbf_id);		logmessage(msgbuf);		exit(2); */ /* server, don't log *//*	}	if (setgid(pwdp->pw_gid)) {		if ((grpp = getgrgid(pwdp->pw_gid)) == NULL) {			sprintf(msgbuf, "No group entry for %d", pwdp->pw_gid);			logmessage(msgbuf);			exit(2); */ /* server, don't log *//*		}		sprintf(msgbuf, "Cannot set group id to %s", grpp->gr_name);		logmessage(msgbuf);		exit(2); */ /* server, don't log *//*	}	if (setuid(pwdp->pw_uid)) {		sprintf(msgbuf, "Cannot set user id to %s", wdbp->dbf_id);		logmessage(msgbuf);		exit(2); */ /* server, don't log *//*	}	if (chdir(pwdp->pw_dir)) {		sprintf(msgbuf, "Cannot chdir to %s", pwdp->pw_dir);		logmessage(msgbuf);		exit(2); */ /* server, don't log *//*	}	DEBUG((9, "New uid %d New gid %d", getuid(), getgid()));	if (senviron(call, pwdp->pw_dir))  {		logmessage("Can't expand server's environment");	}	endpwent();*/	execve(path, argvp, environ);	/* exec returns only on failure!		*/	logmessage("listener could not exec server");	sys_error(E_SYS_ERROR, CONTINUE);	return(-1);}/* * senviron:	Update environment before exec-ing the server: *		The callers logical address is placed in the *		environment in hex/ascii character representation. * * Note:	no need to free the malloc'ed buffers since this process *		will either exec or exit. */static char provenv[2*PATHSIZE];static char homeenv[BUFSIZ];static char tzenv[BUFSIZ];#define TIMEZONE	"/etc/TIMEZONE"#define TZSTR	"TZ="intsenviron(call, home)register struct t_call *call;register char *home;{	register char *p;	char scratch[BUFSIZ];	extern void nlsaddr2c();	extern char *getenv();	char *parse();	FILE *fp;	sprintf(homeenv, "HOME=%s", home);	putenv(homeenv);/* * The following code handles the case where the listener was started with * no environment.  If so, supply a reasonable default path and find out * what timezone we're in so the log file is consistent. */	if (getenv("PATH") == NULL)		putenv("PATH=/bin:/etc:/usr/bin");	if (getenv("TZ") == NULL) {		fp = fopen(TIMEZONE, "r");		if (fp) {			while (fgets(tzenv, BUFSIZ, fp)) {				if (scratch[strlen(tzenv) - 1] == '\n')					tzenv[strlen(tzenv) - 1] = '\0';				if (!strncmp(TZSTR, tzenv, strlen(TZSTR))) {					putenv(parse(tzenv));					break;				}			}			fclose(fp);		}		else {			sprintf(scratch, "couldn't open %s, default to GMT", TIMEZONE);			logmessage(scratch);		}	}	if ((p = (char *)malloc(((call->addr.len)<<1) + 18)) == NULL)		return(-1);	strcpy(p, NLSADDR);	strcat(p, "=");	nlsaddr2c(p + strlen(p), call->addr.buf, call->addr.len);	DEBUG((7, "Adding %s to server's environment", p));	putenv(p);	if ((p = (char *)malloc(((call->opt.len)<<1) + 16)) == NULL)		return(-1);	strcpy(p, NLSOPT);	strcat(p, "=");	nlsaddr2c(p + strlen(p), call->opt.buf, call->opt.len);	DEBUG((7, "Adding %s to server's environment", p));	putenv(p);	p = provenv;	strcpy(p, NLSPROVIDER);	strcat(p, "=");	strcat(p, Netspec);	DEBUG((7, "Adding %s to environment", p));	putenv(p);	if ((p = (char *)malloc(((call->udata.len)<<1) + 20)) == NULL)		return(-1);	strcpy(p, NLSUDATA);	strcat(p, "=");	if ((int)call->udata.len >= 0)		nlsaddr2c(p + strlen(p), call->udata.buf, call->udata.len);	DEBUG((7, "Adding %s to server's environment", p));	putenv(p);	return (0);}/* * parse:	Parse TZ= string like init does for consistency *		Work on string in place since result will *		either be the same or shorter. */char *parse(s)char *s;{	register char *p;	register char *tp;	char scratch[BUFSIZ];	int delim;	tp = p = s + strlen("TZ=");	/* skip TZ= in parsing */	if ((*p == '"') || (*p == '\'')) {		/* it is quoted */		delim = *p++;		for (;;) {			if (*p == '\0') {				/* etc/TIMEZONE ill-formed, go without TZ */				sprintf(scratch, "%s ill-formed", TIMEZONE);				logmessage(scratch);				strcpy(s, "TZ=");				return(s);			}			if (*p == delim) {				*tp = '\0';				return(s);			}			else {				*tp++ = *p++;			}		}	}	else { /* look for comment or trailing whitespace */		for ( ; *p && !isspace(*p) && *p != '#'; ++p)			;		/* if a comment or trailing whitespace, trash it */		if (*p) {			*p = '\0';		}		return(s);	}}/* * login:	Start the intermediary process that handles *		pseudo-tty getty/login service. */login(fd, call)register fd;struct t_call *call;{	register dbf_t *dbp;	DEBUG((9,"in login (request for intermediary)"));	if (!(dbp = getdbfentry(DBF_INT_CODE)) || (dbp->dbf_flags & DBF_OFF))  {		log( E_NOINTERMEDIARY );		return(-1);	}	start_server(fd, dbp, (char **)0, call);	/* returns only on failure!			*/	logmessage("listener could not exec the intermediary process");	sys_error(E_SYS_ERROR, CONTINUE);	return(-1);}/* * isdigits:	string version of isdigit.  (See ctype(3)) */intisdigits(p)register char *p;{	register int flag = 1;	if (!strlen(p))		return(0);	while (*p)		if (!isdigit(*p++))			flag = 0;	return(flag);}/* * pushmod:	push modules if defined in the data base entry. * *		NOTE: there are no modules to push in WTLI. *		so this code is a noop on the S4.  However, *		the data base file is compatible. * *		WARNING: This routine writes into the in-memory copy *		of the database file.  Therefore, after it is called, *		the incore copy of the database file will no longer be valid. */intpushmod(fd, mp)int fd;register char *mp;{#ifndef	S4	register char *cp = mp;	register int pflag = 0;	char name[32];	DEBUG((9,"in pushmod:"));	if (!mp) {		DEBUG((9,"NULL list: exiting pushmod"));		return(0);	}	while (*cp) {	    if (*cp == ',') {	    	*cp = (char)0;		if (*mp && strcmp(mp, "NULL")) {	/*	 * if first time thru, pop off TIMOD if it is on top of stream	 */		    if  (!pflag) {			pflag++;			if (ioctl(fd, I_LOOK, name) >= 0) {			    if (strcmp(name, "timod") == 0) {				if (ioctl(fd, I_POP) < 0)				    DEBUG((9,"pushmod: I_POP failed"));			    }			}		    }		    DEBUG((9,"pushmod: about to push %s",mp));		    if (ioctl(fd, I_PUSH, mp) < 0) {			DEBUG((9,"pushmod: ioctl failed, errno = %d",errno));			return(1);		    }		} /* if */		mp = ++cp;		continue;	    } /* if */	    cp++;	} /* while */	DEBUG((9,"exiting pushmod:"));#endif	return(0);}intl_rcv(fd, bufp, bytes, flagp)int fd;char *bufp;int bytes;int *flagp;{	register int n;	register int count = bytes;	register char *bp = bufp;	DEBUG((9, "in l_rcv"));	do {		*flagp = 0;		n = t_rcv(fd, bp, count, flagp);		if (n < 0) {			DEBUG((9, "l_rcv, t_errno is %d", t_errno));#ifdef DEBUGMODE			if (t_errno == TLOOK) {				DEBUG((9, "l_rcv, t_look returns %d", t_look(fd)));			}#endif			return(n);		}		count -= n;		bp += n;	} while (count > 0);	return(bp - bufp);}/* * clr_call:	clear out a call structure */clr_call(call)struct t_call *call;{	call->sequence = 0;	call->addr.len = 0;	call->opt.len = 0;	call->udata.len = 0;	memset(call->addr.buf, 0, call->addr.maxlen);	memset(call->opt.buf, 0, call->opt.maxlen);	memset(call->udata.buf, 0, call->udata.maxlen);}/* * pitchcall: remove call from pending list */pitchcall(free, pending, disc)struct call_list *free;struct call_list *pending;struct t_discon *disc;{	register struct callsave *p, *oldp;	DEBUG((9, "pitching call, sequence # is %d", disc->sequence));	if (EMPTY(pending)) {		disc->sequence = -1;		return;	}	p = pending->cl_head;	oldp = (struct callsave *) NULL;	while (p) {		if (p->c_cp->sequence == disc->sequence) {			if (oldp == (struct callsave *) NULL) {				pending->cl_head = p->c_np;				if (pending->cl_head == (struct callsave *) NULL) {					pending->cl_tail = (struct callsave *) NULL;				}			}			else if (p == pending->cl_tail) {				oldp->c_np = p->c_np;				pending->cl_tail = oldp;			}			else {				oldp->c_np = p->c_np;			}			clr_call(p->c_cp);			queue(free, p);			disc->sequence = -1;			return;		}		oldp = p;		p = p->c_np;	}	logmessage("received disconnect with no pending call");	disc->sequence = -1;	return;}

⌨️ 快捷键说明

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