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

📄 syslog.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
*/shutdown(){	extern die();	logmsg(LOG_CRIT, "syslog: shutdown within 30 seconds\n");	ShutDown++;	signal(SIGALRM, die);	alarm(30);	signal(SIGTERM, die);	if (Debug)		signal(SIGINT, die);}/***  DIE -- really die.****	Parameters:**		none****	Returns:**		never****	Side Effects:**		Syslog dies.****	Requires:**		exit (sys)****	Called By:**		alarm clock (signal 14)*/die(){	alarm(0);	logmsg(LOG_CRIT, "syslog: down\n");	sleep(2);	/* wait for output to drain */# ifndef LOG_IPC	if (!Debug)		unlink("/dev/log");# endif LOG_IPC	sync();		/* This sync is ok. */	exit(0);}/***  STAMPED -- tell if line is already time stamped.****	Accepts time stamps of the form "Sep 13 00:15:17".**	Currently just looks for blanks and colons.****	Parameters:**		l -- the line to check.****	Returns:**		nonzero -- if the line is time stamped.**		zero -- otherwise.****	Side Effects:**		none.*/stamped(l)register char *l;{	register int i;	/* timestamps are at least 15 bytes long */	for (i = 0; i < 15; i++)		if (l[i] == '\0')			return (0);	/* and they have blanks & colons in well-known places */	if (l[3] != ' ' || l[6] != ' ' || l[9] != ':' || l[12] != ':')		return (0);	return (1);}/***  LOGMSG -- log a message to the outputs****	Arranges to get the message to the correct places**	based on the priority of the message.  A timestamp**	is prepended to the message if one does not already**	exist.****	Parameters:**		pri -- the message priority.**		msg -- the message to be logged.****	Returns:**		none****	Side Effects:**		possibly messages to all users, or just specific**		users.*/char buf[MAXLINE+2];logmsg(pri, msg)	int	pri;	char	*msg;{	register char *m;	register char *p;	register struct filed *f;	register int l;	register int i;	auto int st;	auto long now;	extern char *ctime();	extern int errno;	p = buf;	l = MAXLINE;		/* output a time stamp if one is not already there */	time(&now);	if (!stamped(msg))	{		m = &ctime(&now)[4];		for (i = 16; i > 0; i--)			*p++ = *m++;		l -= 16;	}	/* find the end of the message */	for (m = msg; *m != '\0' &&l -- >= 0; )		*p++ = *m++;	if (*--m != '\n')		*p++ = '\n';		/* log the message to the particular outputs */	for (i = 0; i < NLOGS; i++)	{		f = &Files[i];		/* 0002 - puivax!ed */		/* if it isn't a tty and the file descriptor is NULL do nothing */		/* if it is a tty then keep going, ttys should always be closed */		if ( ! f->f_tty && f->f_file == NULL)			continue;		if (pri < 0)		{			if (!f->f_mark || f->f_time + MarkIntvl*60 > now)				continue;		}		else if (f->f_pmask < pri)			continue;		/* 0002 - puivax!ed moved from 10 lines above */		/* we've decided to really write this message to the file so... */		/* ttys are opened and closed for each write 0001 */		if (f->f_tty && f->f_file == NULL)			if ((f->f_file = fopen(f->f_name, "a")) == NULL)			        continue;		fseek(f->f_file, 0L, 2);		errno = 0;		fwrite(buf, p - buf, 1, f->f_file);		if (f->f_tty)			fwrite("\r", 1, 1, f->f_file);		f->f_time = now;		fflush(f->f_file);		if (ferror(f->f_file))		{			char namebuf[40];			fclose(f->f_file);			f->f_file = NULL;			f->f_tty = 0;	/* otherwise would reopen */			sprintf(namebuf, "write %s", f->f_name);			logerror(namebuf);		}		if (f->f_tty)		{			fclose(f->f_file);			f->f_file = NULL;		}	}	/* let's be paranoid.... *//* aps. *	sync(); */	/*	**  Output alert and subalert priority messages to terminals.	**	**	We double fork here so that we can continue.  Our	**	child will fork again and die; we wait for him.	**	Then process one inherits our grandchildren, we	**	can run off and have a good time.  Our grandchild	**	actually tries to do the writing (by calling	**	wallmsg).	**	**	Anything go wrong? -- just give up.	*/	if (pri <= LOG_SALERT && pri > 0)	{		if (fork() == 0)		{			if (fork() == 0)			{				wallmsg(pri == LOG_ALERT, buf, p - buf);				exit(0);			}			else				exit(0);		}		else			while (wait(&st) >= 0)				continue;	}}/***  INIT -- Initialize syslog from configuration table****	The configuration table consists of a series of lines**	broken into two sections by a blank line.  The first**	section gives a list of files to log on.  The first**	character is a digit which is the priority mask for**	that file.  If the second digit is an asterisk, then**	syslog arranges for something to be printed every fifteen**	minutes (even if only a null line), so that crashes and**	other events can be localized.  The rest of the line is**	the pathname of the log file.  The second section is**	a list of user names; these people are all notified**	when subalert messages occur (if they are logged on).****	The configuration table will be reread by this routine**	if a signal 1 occurs; for that reason, it is tricky**	about not re-opening files and closing files it will**	not be using.****	Parameters:**		none****	Returns:**		none****	Side Effects:**		'Files' and 'Susers' are (re)initialized.*/init(){	register int i;	register FILE *cf;	char cline[40];	register struct filed *f;	register char *p;	int mark;	int pmask;	dprintf("init\n");	/* ignore interrupts during this routine */	signal(SIGHUP, SIG_IGN);	logmsg(LOG_INFO, "reinitializing\n");	/* open the configuration file */	if ((cf = fopen(ConfFile, "r")) == NULL)	{		dprintf("cannot open %s\n", ConfFile);		return;	}	/*	**  Close all open files.	*/	for (f = Files; f < &Files[NLOGS]; f++)	{		if (f->f_file != NULL)			fclose(f->f_file);		f->f_file = NULL;	}	/*	**  Foreach line in the conf table, open that file.	*/	f = Files;	while (fgets(cline, sizeof cline, cf) != NULL)	{		dprintf("F: got line >%s<\n", cline, 0);		/* check for end-of-section */		if (cline[0] == '\n')			break;		/* strip off possible newline character */		for (p = cline; *p != '\0' && *p != '\n'; p++)			continue;		*p = '\0';		/* extract priority mask and mark flag */		p = cline;		mark = FALSE;		pmask = *p++ - '0';		if (*p == '*')		{			p++;			mark = TRUE;		}		/* insure that it is null-terminated */		p[sizeof Files[0].f_name - 1] = '\0';		if (f >= &Files[NLOGS])			continue;		/* mark entry as used and update flags */		strcpy(f->f_name, p);		f->f_file = fopen(p, "a");		f->f_time = 0;		f->f_pmask = pmask;		f->f_mark = mark;		f->f_tty = (f->f_file ? isatty(fileno(f->f_file)) : 0);		/*		 * tty lines have to be opened and closed for each message.		 *		 * 0001		 */		if (f->f_tty)		{			fclose(f->f_file);			f->f_file = NULL;		}		dprintf("File %s pmask %d mark %d tty %d\n", p, pmask, mark, f->f_tty);		f++;	}	/*	**  Read the list of users.	**	**	Anyone in this list is informed directly if s/he	**	is logged in when a "subalert" or higher priority	**	message comes through.	**	**	Out with the old order, in with the new.	*/	for (i = 0; i < NSUSERS && fgets(cline, sizeof cline, cf) != NULL; i++)	{		/* strip off newline */		for (p = cline; *p != '\0' && *p != '\n'; p++)			continue;		*p = '\0';		cline[8] = '\0';		strcpy(Susers[i], cline, 8);	}	/* zero the rest of the old superusers */	for (; i < NSUSERS; i++)		Susers[i][0] = '\0';	/* close the configuration file */	fclose(cf);	logmsg(LOG_INFO, "syslog restart\n");	/* arrange for signal 1 to reconfigure */	signal(SIGHUP, init);}/***  WALLMSG -- Write a message to the world at large****	This writes the specified message to either the entire**	world, or at least a list of approved users.****	It scans the utmp file.  For each user logged in, it**	checks to see if the user is on the approved list, or if**	this is an "alert" priority message.  In either case,**	it opens a line to that typewriter (unless mesg permission**	is denied) and outputs the message to that terminal.****	Parameters:**		toall -- if non-zero, writes the message to everyone.**		msg -- the message to write.**		len -- the length of the message.****	Returns:**		none****	Side Effects:**		none****	Requires:**		open(sys)**		read(sys)**		write(sys)**		fstat(sys)**		strcmp(sys)**		fork(sys)**		sleep(sys)**		exit(sys)**		close(sys)****	Called By:**		logmsg*/wallmsg(toall, msg, len)	int toall;	char *msg;	int len;{	struct utmp ut;	register int i;	register char *p;	int uf;	struct stat statbuf;	auto long t;	extern char *ctime();	char sbuf[1024];#ifdef LOG_IPC	extern char *gethostname();	char hbuf[32];	auto int hlen;#endif LOG_IPC	/* open the user login file */	uf = open("/etc/utmp", 0);	if (uf < 0)		return;	/* scan the user login file */	while (read(uf, &ut, sizeof ut) == sizeof ut)	{		/* is this slot used? */		if (ut.ut_name[0] == '\0')			continue;		/* if not "alert", check if this user is super */		if (!toall)		{			for (i = 0; i < NSUSERS; i++)			{				if (namecheck(Susers[i], ut.ut_name))					break;			}			if (i >= NSUSERS)			{				/* nope, just a serf */				continue;			}		}		/* fork so that the open can't hang us */		if (fork() != 0)			continue;		sleep(1);		/* compute the device name */# ifdef V6		p = "/dev/ttyx";		p[8] = ut.ut_tty;# else		p = "/dev/12345678";		strcpyn(&p[5], ut.ut_line, 8);# endif		/* open the terminal */		i = open(p, 1);		if (i < 0)			exit(1);		/* does he have write permission? */		if (fstat(i, &statbuf) < 0 || (statbuf.st_mode & 02) == 0)		{			/* no, just pass him by */			dprintf("Drop user, mode=%o\n", statbuf.st_mode, 0);			close(i);			exit(0);		}		/* yes, output the message */		time(&t);		strcpy(sbuf, "\r\n\007Broadcast message from ");#ifdef LOG_IPC		strcat(sbuf, "syslog@");		hlen = sizeof hbuf;		gethostname(hbuf, &hlen);		strcat(sbuf, hbuf);#else LOG_IPC		strcat(sbuf, sysname);		strcat(sbuf, "!syslog");#endif LOG_IPC		strcat(sbuf, " at ");		strncat(sbuf, ctime(&t), 24);		strcat(sbuf, "...\r\n");		write(i, sbuf, strlen(sbuf));		p = sbuf;		while (len-- > 0)		{			*msg &= 0177;			if (iscntrl(*msg))			{				*p++ = '^';				*p++ = *msg++ ^ 0100;			}			else				*p++ = *msg++;		}		strcpy(p, "\r\n");		write(i, sbuf, strlen(sbuf));		/* all finished!  go away */		exit(0);	}	/* close the user login file */	close(uf);}/***  CHECKNAME -- Do an equality comparison on names.****	Does right blank padding.****	Parameters:**		a, b -- pointers to the names to check.****	Returns:**		1 if equal**		0 otherwise.****	Side Effects:**		none****	Requires:**		none****	Called By:**		wallmsg*/namecheck(a, b)register char *a, *b;{	register int i;	for (i = 0; i < 8; i++)	{		if (*a != *b)		{			if (!((*a == ' ' && *b == '\0') || (*a == '\0' && *b == ' ')))				return (0);		}		if (*a != ' ' && *a != '\0')			a++;		if (*b != ' ' && *b != '\0')			b++;	}	return (1);}/***  DOMARK -- Make sure every marked file gets output every 15 minutes****	Just calls "logmsg" with a negative priority every time it**	gets called.****	Algorithm:**		create timestamp.**		call logmsg.****	Parameters:**		none****	Returns:**		none****	Side Effects:**		sets the alarm clock to call itself after MarkIntvl**			minutes.****	Requires:**		logmsg****	Called By:**		system alarm clock.**		init*/domark(){	auto long t;	extern char *ctime();	register char *p;	register char *q;	char buf[40];	alarm(0);	dprintf("domark\n");	time(&t);	q = buf;	for (p = " --- MARK --- "; (*q++ = *p++) != '\0'; )		continue;	q--;	for (p = ctime(&t); (*q++ = *p++) != '\0'; )		continue;	logmsg(-1, buf);	signal(SIGALRM, domark);	alarm(MarkIntvl*60);}

⌨️ 快捷键说明

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