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

📄 listen.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*	@(#)listen.c 1.1 92/07/30 SMI 	*//*	Copyright (c) 1984 AT&T	*//*	  All Rights Reserved  	*//*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*//*	The copyright notice above does not evidence any   	*//*	actual or intended publication of such source code.	*/#ident	"@(#)listen:listen.c	1.19.4.4"/* * Network Listener Process * *		data base version: * *		accepts the following message to start servers: * *		NLPS:000:001:svc_code	where svc_code is a null terminated  *					char string ( <= SVC_CODE_SZ bytes) * *		command line: * *		listen [ -n netspec ] [ -r external_addr ] [ -l external_addr ] *		all options take appropriate defaults for STARLAN NETWORK. *		-r: address to listen for remote login requests. *		-l: address to listen for listener service requests. * *//* system include files	*/#include <fcntl.h>#include <signal.h>#include <stdio.h>#include <varargs.h>#include <string.h>#include <errno.h>#include <memory.h>#include <sys/ioctl.h>#include <sys/utsname.h>#include <tiuser.h>#include <sys/param.h>#include <sys/types.h>#include <sys/stat.h>#include <values.h>#include <ctype.h>#include <pwd.h>#include <grp.h>#include <sys/poll.h>#include <sys/dir.h>#include <sys/stropts.h>/* S4 status manager interface					*/#ifdef	S4#include <status.h>#endif/* listener include files */#include "lsparam.h"		/* listener parameters		*/#include "lsfiles.h"		/* listener files info		*/#include "lserror.h"		/* listener error codes		*/#include "lsnlsmsg.h"		/* NLPS listener protocol	*/#include "lssmbmsg.h"		/* MS_NET identifier		*/#include "lsdbf.h"		/* data base file stuff		*/#include "nlsenv.h"		/* environ variable names	*/#include "listen.h"/* defines	*/#define NAMESIZE	(NAMEBUFSZ-1)#define SPLhi()		Splflag = 1#define SPLlo()		Splflag = 0#define GEN	1#define LOGIN	0/* global variables	*/int	Child;		/* set if process is a listener child (worker bee) */int	Pid;		/* listener's process ID (original listener's child) */char	*Progname;		/* listener's basename (from argv[0])	*/static char Provbuf[PATHSIZE];char	*Provider = Provbuf;	/* name of transport provider		*/char	*Netspec = NETSPEC;int	Nfd1 = -1;		/* Net fd's, init to illegal		*/int	Nfd2 = -1;int	Nfd3 = -1;char	_rlbuf[NAMEBUFSZ];		/* remote login name		*/char	_lsbuf[NAMEBUFSZ];		/* listener service name	*/char	*Nodename = _rlbuf;		/* my normalized name (login svc)*/char	*Pnodename = _lsbuf;		/* my permuted name (listener svc) */char	*Rxname = NULL;			/* remote login external name	*/char	*Lxname = NULL;			/* listener svc external name	*/int	Rlen = NAMEBUFSZ;int	Llen = NAMEBUFSZ;struct	call_list	Lfree;		/* network call save free list */struct	call_list	Lpend;		/* network call save pending list */unsigned int	Lmaxcon;		/* maximum # of connections for gen. listen */struct	call_list	Rfree;		/* rem login call save free list */struct	call_list	Rpend;		/* rem login call save pending list */unsigned int	Rmaxcon;		/* maximum # of connections for remote login */char	*Basedir = BASEDIR;		/* base dir */char	*Home;				/* listener's home directory	*/char	Homebuf[BUFSIZ];FILE	*Debugfp = stderr;FILE	*Logfp;int	Pidfd;int	Background;			/* are we in background?	*/char	Lastmsg[BUFSIZ];		/* contains last msg logged (by stampbuf) */int	Logmax = LOGMAX;int	Validate;		/* from -v flag: validate data base only */int	Lckfd;int	Sigusr1;		/* data base file changed		*/int	Splflag;		/* logfile critical region flag		*/static char *badnspmsg = "Bad netspec on command line ( Pathname too long )\n";static char *badstart  = "Listener failed to start properly\n";main(argc, argv)int argc;char **argv;{	register char **av;	struct stat buf;	int ret;	extern void exit(), logexit();	/*	 * pre-initialization:	 */	if (geteuid() != 0) {		fprintf(stderr, "Must be root to start listener\n");		logexit(1, badstart);	}	/*	 * quickly, find -n [ and -v ] argument on command line		 */	av = argv; ++av;		/* skip argv[0]	*/	while(*av)  {		if (!strncmp(*av,"-n", 2)) {			if (*(*av + 2) == NULL)				Netspec = *++av;			else				Netspec = (*av + 2);		} else {			if (!strcmp(*av, "-v"))				++Validate;		}		++av;	}	if (strlen(Netspec) > PATHSIZE)  {		fprintf(stderr, badnspmsg);		logexit(1, badstart);	}	strcat(Homebuf,Basedir);	strcat(Homebuf,"/");	strcat(Homebuf,Netspec);	Home = Homebuf;	strcpy(Provbuf, "/dev/");	strcat(Provbuf, Netspec);	if (chdir(Home))  {		fprintf(stderr,"Cannot change directory to %s\n",Home);		logexit(1, badstart);	}	/*	 * -v flag tells listener to validate the data base only	 */	if (Validate)  {		Logfp = stderr;#ifdef	DEBUGMODE		umask(022);		if (!(Debugfp = fopen(VDBGNAME, "w")))  {			fprintf(stderr,"Can't create debug file: %s in %s\n",				VDBGNAME, Home);			exit(1); /* don't log validation exits */		}#endif		ret = init_dbf();		logmessage(ret ? "Bad data base file": "Good data base file");		exit(ret); /* don't log validation exits */	}	umask(0);	if (((Lckfd = open(LCKNAME, O_WRONLY | O_CREAT, 0666 )) == -1) 		|| (locking(Lckfd, 2, 0L) == -1)) {		fprintf(stderr, "Errno %d opening lock file %s/%s.\n", 			errno, Home, LCKNAME);		fprintf(stderr, "Listener may already be running!\n");		logexit(1, badstart);	}	write(Lckfd, "lock", 4);	if (locking(Lckfd, 1, 0L) == -1)  {		fprintf(stderr, "Errno %d while locking lock file\n", errno);		logexit(1, badstart);	}	umask(022);	if (stat(LOGNAME, &buf) == 0) {		/* file exists, try and save it but if we can't don't worry */		unlink(OLOGNAME);		if (link(LOGNAME, OLOGNAME)) {			fprintf(stderr, "Lost old log file\n");		}		unlink(LOGNAME);	}/* * At this point, either it didn't exist, we successfully saved it * or we couldn't save it.  In any case, just open and continue. */	Logfp = fopen(LOGNAME, "w");#ifdef	DEBUGMODE	Debugfp = fopen(DBGNAME, "w");#endif#ifdef	DEBUGMODE	if ((!Logfp) || (!Debugfp))  {#else	if (!Logfp) {#endif		fprintf(stderr,"listener cannot create file(s) in %s\n",Home);		logexit(1, badstart);	}	logmessage("@(#)listen:listen.c	1.19.4.4");#ifdef	DEBUGMODE	logmessage("Listener process with DEBUG capability");#endif	initialize(argv, argc);	listen();}initialize(argv, argc)int argc;char **argv;{	/* try to get my "basename"		*/	DEBUG((9,"in initialize"));	Progname = strrchr(argv[0], '/');	if (Progname && Progname[1])		++Progname;	else		Progname = argv[0];	cmd_line_args(argv,argc);	init_dbf();	pid_open();			/* create pid file		*/	net_open();			/* init, open, bind names 	*/	catch_signals();	divorce_parent();	logmessage("Initialization Complete");}/* * cmd_line_args uses getopt(3) to read command line arguments. */static char *Optflags = "n:r:l:L:";cmd_line_args(argv,argc)int argc;char **argv;{	register i;	extern char *optarg;	extern int optind, opterr;	extern int isdigits();	int errflag = 0;	DEBUG((9,"in cmd_line_args"));#ifdef	DEBUGMODE	DEBUG((9,"cmd_line_args: argc = %d",argc));	for (i=0;  i < argc; i++)		DEBUG((9,"argv[%d] = %s",i,argv[i]));#else	opterr = 1;		/* disable getopt's stderr output */#endif	/* DEBUGMODE */	while ( (i = getopt(argc, argv, Optflags)) != EOF )		switch (i)  {		case 'n':		/* netspec			*/			break;		/* (read previously)		*/		case 'r':		/* remote login external addr	*/			Rxname = optarg;			break;		case 'l':		/* listener svc external addr	*/			Lxname = optarg;			break;		case 'L':		/* max log entries		*/			if (isdigits(optarg))  {				Logmax = atoi( optarg );				if (Logmax < LOGMIN)					Logmax = LOGMIN;				DEBUG((5, "Logmax = %d", Logmax));			} else				++errflag;			break;		case '?':			++errflag;			break;		}#ifndef S4		if (!Lxname)			++errflag;#endif	if (errflag)		error(E_CMDLINE, EXIT | NOCORE);}/* * pid_open: * * open pidfile with specified oflags and modes * */static char *pidopenmsg ="Can't create process ID file in home directory";pid_open(){	int pid;	int ret;	unsigned i;	char pidstring[20];	DEBUG((9,"in pid_open()"));	if ((Pidfd = open(PIDNAME, PIDOFLAG, PIDMODE)) == -1)  {		logmessage(pidopenmsg);		error(E_CREAT, EXIT | NOCORE | NO_MSG);	}	pid = getpid();	i = sprintf(pidstring, "%d", pid) + 1;	if ((ret = write(Pidfd, pidstring, i)) != i) {		if (ret < 0)			sys_error(E_PIDWRITE, EXIT);		else			error(E_PIDWRITE, EXIT);	}	(void) lseek(Pidfd, 0L, 0);}/* * net_open: open and bind communications channels *		The name generation code in net_open, open_bind and bind is,  * 		for the	most part, specific to STARLAN NETWORK.   *		This name generation code is included in the listener *		as a developer debugging aid. */net_open(){	extern char *memcpy();	extern char *t_alloc();	extern int nlsc2addr();	void queue();#ifdef	S4	register char *p;	extern char *getnodename();	extern char *nlsname();		/* STARLAN specific	*/#endif#ifdef	CHARADDR	char pbuf[NAMEBUFSZ + 1];#endif	register int i;	register struct callsave *tmp;	char scratch[BUFSIZ];	DEBUG((9,"in net_open"));	DEBUG((3, "Rxname = %s", Rxname));	DEBUG((3, "Lxname = %s", Lxname));	if (Rxname)  {			/* -r cmd line argument		*/		DEBUG((3, "Decoding remote login address"));		if ((Rlen = nlsc2addr(Nodename, NAMEBUFSZ, Rxname)) < 0)  {			logmessage("Error decoding remote login name");			error(E_CMDLINE, EXIT | NOCORE | NO_MSG);		}	}#ifdef	S4	else  {		p = getnodename();		DEBUG((3, "machine nodename = %s", p));		Rlen = strlen(p);		(void)memcpy(Nodename, p, Rlen);	}#endif	/* S4 */	if (Lxname)  {			/* -l cmd line argument		*/		DEBUG((3, "Decoding listener service address"));		if ((Llen = nlsc2addr(Pnodename, NAMEBUFSZ, Lxname)) < 0)  {			logmessage("Error decoding listener service name");			error(E_CMDLINE, EXIT | NOCORE | NO_MSG);		}	}#ifdef	S4	else  {		p = getnodename();		DEBUG((3, "machine nodename = %s", p));		p = nlsname(p);		Llen = strlen(p);		(void)memcpy(Pnodename,p,Llen);		DEBUG((3,"nlsname = %s, Pnodename = %s, Llen = %d",			p, Pnodename, Llen));	}#endif /* S4 */#ifdef	CHARADDR	/* this debug code assumes addresses are printable characters */	/* not necessarily null terminated.	*/	if (Rxname) {		(void)memcpy(pbuf, Nodename, Rlen);		*(pbuf+Rlen) = (char)0;		DEBUG((3, "Nodename = %s, length = %d", pbuf, Rlen));	}	(void)memcpy(pbuf, Pnodename, Llen);	*(pbuf+Llen) = (char)0;	DEBUG((3, "Pnodename = %s, length = %d", pbuf, Llen));#endif	/* CHARADDR	*/	if (Rxname) {		Nfd1 = open_bind(Nodename, MAXCON, Rlen, &Rmaxcon);		sprintf(scratch, "Rmaxcon is %d", Rmaxcon);		logmessage(scratch);	}/* * set up call save list for remote login service */	if (Rxname) {		Rfree.cl_head = (struct callsave *) NULL;		Rfree.cl_tail = (struct callsave *) NULL;		for (i = 0; i < Rmaxcon; ++i) {			if ((tmp = (struct callsave *) malloc(sizeof(struct callsave))) == NULL) {				error(E_MALLOC, NOCORE | EXIT);			}			if ((tmp->c_cp = (struct t_call *) t_alloc(Nfd1, T_CALL, T_ALL)) == NULL) {				tli_error(E_T_ALLOC, EXIT);			}			queue(&Rfree, tmp);		}	}	Nfd2 = open_bind(Pnodename, MAXCON, Llen, &Lmaxcon);	sprintf(scratch, "Lmaxcon is %d", Lmaxcon);	logmessage(scratch);/* * set up call save list for general network listen service */	Lfree.cl_head = (struct callsave *) NULL;	Lfree.cl_tail = (struct callsave *) NULL;	for (i = 0; i < Lmaxcon; ++i) {		if ((tmp = (struct callsave *) malloc(sizeof(struct callsave))) == NULL) {			error(E_MALLOC, NOCORE | EXIT);		}		if ((tmp->c_cp = (struct t_call *) t_alloc(Nfd2, T_CALL, T_ALL)) == NULL) {			tli_error(E_T_ALLOC, EXIT);		}		queue(&Lfree, tmp);	}	if ( ((Nfd1 == -1) && Rxname) || (Nfd2 == -1) )		error(E_OPENBIND, EXIT);	logmessage("Net opened, names bound");}/*

⌨️ 快捷键说明

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