alias.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 786 行 · 第 1/2 页

C
786
字号
	modtime = stb.st_mtime;	(void) strcpy(buf, aliasfile);	(void) strcat(buf, ".pag");	stb.st_ino = 0;	if (!init && (stat(buf, &stb) < 0 || stb.st_mtime < modtime || atcnt < 0))	{		errno = 0;		if (AutoRebuild && stb.st_ino != 0 &&		    ((stb.st_mode & 0777) == 0666 || stb.st_uid == geteuid()))		{			init = TRUE;			automatic = TRUE;			message(Arpa_Info, "rebuilding alias database");#ifdef LOG			if (LogLevel >= 7)				syslog(LOG_INFO, "rebuilding alias database");#endif LOG		}		else		{#ifdef LOG			if (LogLevel >= 7)				syslog(LOG_INFO, "alias database out of date");#endif LOG			message(Arpa_Info, "Warning: alias database out of date");		}	}	/*	**  If necessary, load the DBM file.	**	If running without DBM, load the symbol table.	*/	if (init)	{#ifdef LOG		if (LogLevel >= 6)		{			extern char *username();			syslog(LOG_NOTICE, "alias database %srebuilt by %s",				automatic ? "auto" : "", username());		}#endif LOG		readaliases(aliasfile, TRUE);	}# else DBM	readaliases(aliasfile, init);# endif DBM}/***  READALIASES -- read and process the alias file.****	This routine implements the part of initaliases that occurs**	when we are not going to use the DBM stuff.****	Parameters:**		aliasfile -- the pathname of the alias file master.**		init -- if set, initialize the DBM stuff.****	Returns:**		none.****	Side Effects:**		Reads aliasfile into the symbol table.**		Optionally, builds the .dir & .pag files.*/staticreadaliases(aliasfile, init)	char *aliasfile;	bool init;{	register char *p;	char *rhs;	bool skipping;	int naliases, bytes, longest;	FILE *af;	void (*oldsigint)();	ADDRESS al, bl;	register STAB *s;	char line[BUFSIZ];	if ((af = fopen(aliasfile, "r")) == NULL)	{# ifdef DEBUG		if (tTd(27, 1))			printf("Can't open %s\n", aliasfile);# endif		errno = 0;		NoAlias++;		return;	}# ifdef DBM# ifdef FLOCK	/* see if someone else is rebuilding the alias file already */	if (flock(fileno(af), LOCK_EX | LOCK_NB) < 0 && errno == EWOULDBLOCK)	{		/* yes, they are -- wait until done and then return */		message(Arpa_Info, "Alias file is already being rebuilt");		if (OpMode != MD_INITALIAS)		{			/* wait for other rebuild to complete */			(void) flock(fileno(af), LOCK_EX);		}		(void) fclose(af);		errno = 0;		return;	}# endif FLOCK# endif DBM	/*	**  If initializing, create the new DBM files.	*/	if (init)	{		oldsigint = signal(SIGINT, SIG_IGN);		(void) strcpy(line, aliasfile);		(void) strcat(line, ".dir");		if (close(creat(line, DBMMODE)) < 0)		{			syserr("cannot make %s", line);			(void) signal(SIGINT, oldsigint);			return;		}		(void) strcpy(line, aliasfile);		(void) strcat(line, ".pag");		if (close(creat(line, DBMMODE)) < 0)		{			syserr("cannot make %s", line);			(void) signal(SIGINT, oldsigint);			return;		}		dbminit(aliasfile);	}	/*	**  Read and interpret lines	*/	FileName = aliasfile;	LineNumber = 0;	naliases = bytes = longest = 0;	skipping = FALSE;	while (fgets(line, sizeof (line), af) != NULL)	{		int lhssize, rhssize;		LineNumber++;		p = index(line, '\n');		if (p != NULL)			*p = '\0';		switch (line[0])		{		  case '#':		  case '\0':			skipping = FALSE;			continue;		  case ' ':		  case '\t':			if (!skipping)				syserr("Non-continuation line starts with space");			skipping = TRUE;			continue;		}		skipping = FALSE;		/*		**  Process the LHS		**	Find the final colon, and parse the address.		**	It should resolve to a local name -- this will		**	be checked later (we want to optionally do		**	parsing of the RHS first to maximize error		**	detection).		*/		for (p = line; *p != '\0' && *p != ':' && *p != '\n'; p++)			continue;		if (*p++ != ':')		{			syserr("missing colon");			continue;		}		if (parseaddr(line, &al, 1, ':') == NULL)		{			syserr("illegal alias name");			continue;		}		loweraddr(&al);		/*		**  Process the RHS.		**	'al' is the internal form of the LHS address.		**	'p' points to the text of the RHS.		*/		rhs = p;		for (;;)		{			register char c;			if (init && CheckAliases)			{				/* do parsing & compression of addresses */				while (*p != '\0')				{					extern char *DelimChar;					while (isspace(*p) || *p == ',')						p++;					if (*p == '\0')						break;					if (parseaddr(p, &bl, -1, ',') == NULL)						usrerr("%s... bad address", p);					p = DelimChar;				}			}			else			{				p = &p[strlen(p)];				if (p[-1] == '\n')					*--p = '\0';			}			/* see if there should be a continuation line */			c = fgetc(af);			if (!feof(af))				(void) ungetc(c, af);			if (c != ' ' && c != '\t')				break;			/* read continuation line */			if (fgets(p, sizeof line - (p - line), af) == NULL)				break;			LineNumber++;		}		if (al.q_mailer != LocalMailer)		{			syserr("cannot alias non-local names");			continue;		}		/*		**  Insert alias into symbol table or DBM file		*/		lhssize = strlen(al.q_user) + 1;		rhssize = strlen(rhs) + 1;# ifdef DBM		if (init)		{			DATUM key, content;			key.dsize = lhssize;			key.dptr = al.q_user;			content.dsize = rhssize;			content.dptr = rhs;			store(key, content);		}		else# endif DBM		{			s = stab(al.q_user, ST_ALIAS, ST_ENTER);			s->s_alias = newstr(rhs);		}		/* statistics */		naliases++;		bytes += lhssize + rhssize;		if (rhssize > longest)			longest = rhssize;	}# ifdef DBM	if (init)	{		/* add the distinquished alias "@" */		DATUM key;		key.dsize = 2;		key.dptr = "@";		store(key, key);		/* restore the old signal */		(void) signal(SIGINT, oldsigint);	}# endif DBM	/* closing the alias file drops the lock */	(void) fclose(af);	CurEnv->e_to = NULL;	FileName = NULL;	message(Arpa_Info, "%d aliases, longest %d bytes, %d bytes total",			naliases, longest, bytes);# ifdef LOG	if (LogLevel >= 8)		syslog(LOG_INFO, "%d aliases, longest %d bytes, %d bytes total",			naliases, longest, bytes);# endif LOG}/***  FORWARD -- Try to forward mail****	This is similar but not identical to aliasing.****	Parameters:**		user -- the name of the user who's mail we would like**			to forward to.  It must have been verified --**			i.e., the q_home field must have been filled**			in.**		sendq -- a pointer to the head of the send queue to**			put this user's aliases in.****	Returns:**		none.****	Side Effects:**		New names are added to send queues.*/forward(user, sendq)	ADDRESS *user;	ADDRESS **sendq;{	char buf[60];	extern bool safefile();	int realuser;# ifdef DEBUG	if (tTd(27, 1))		printf("forward(%s)\n", user->q_paddr);# endif DEBUG	if (user->q_mailer != LocalMailer || bitset(QBADADDR, user->q_flags))		return;# ifdef DEBUG	if (user->q_home == NULL)		syserr("forward: no home");# endif DEBUG	/* good address -- look for .forward file in home	 */	define('z', user->q_home, CurEnv);	expand("\001z/.forward", buf, &buf[sizeof buf - 1], CurEnv);	if (!safefile(buf, user->q_uid, S_IREAD)) {                /* Look for an alternate forward file.                 * Of the form: /usr/spool/mail/username.forward                 */                char aforward[MAXNAME];                strcpy(aforward,"/usr/spool/mail/");                strcat(aforward,user->q_user);                strcat(aforward,".forward");                expand(aforward, buf, &buf[sizeof buf - 1], CurEnv);# ifdef DEBUG                if (tTd(27, 1))                        printf("\naforward = %s\n",aforward);# endif DEBUG                if (!safefile(buf, user->q_uid, S_IREAD))                        return;	}	/* we do have an address to forward to -- do it	 * (include routine is in recipient.c)	 */	/*	 * Fix for NFS.	 * -----------	 * Become the desired user instead of root in order to	 * have the ability to chown across NFS.	 */	realuser = getuid();	setreuid(0,user->q_uid);# ifdef DEBUG	if (tTd(27, 1))		syslog(LOG_INFO,"becoming uid %d\n", user->q_uid);# endif DEBUG	include(buf, "forwarding", user, sendq);	setuid(0);	setreuid(realuser,0);}

⌨️ 快捷键说明

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