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

📄 vacation.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
/***  Vacation**  Copyright (c) 1983  Eric P. Allman**  Berkeley, California****  Copyright (c) 1983 Regents of the University of California.**  All rights reserved.  The Berkeley software License Agreement**  specifies the terms and conditions for redistribution.*/#ifndef lintstatic char	SccsId[] = "@(#)vacation.c 1.1 92/07/30 SMI"; /* from UCB 5.3 7/1/85 */#endif not lint# include <pwd.h># include <stdio.h># include <sysexits.h># include <ctype.h># include "useful.h"# include "userdbm.h"/***  VACATION -- return a message to the sender when on vacation.****	This program could be invoked as a message receiver**	when someone is on vacation.  It returns a message**	specified by the user to whoever sent the mail, taking**	care not to return a message too often to prevent**	"I am on vacation" loops.****	For best operation, this program should run setuid to**	root or uucp or someone else that sendmail will believe**	a -f flag from.  Otherwise, the user must be careful**	to include a header on his .vacation.msg file.****	Positional Parameters:**		the user to collect the vacation message from.****	Flag Parameters:**		-I	initialize the database.**		-d	turn on debugging.**		-tT	set the timeout to T.  messages arriving more**			often than T will be ignored to avoid loops.****	Side Effects:**		A message is sent back to the sender.****	Author:**		Eric Allman**		UCB/INGRES*/# define MAXLINE	256	/* max size of a line */# define ONEWEEK	(60L*60L*24L*7L)# define MsgFile "/.vacation.msg"time_t	Timeout = ONEWEEK;	/* timeout between notices per user */struct dbrec{	long	sentdate;};bool	Debug = FALSE;bool	AnswerAll = FALSE;	/* default to answer if in To:/Cc: only */char	*myname;		/* name of person "on vacation" */char	*homedir;		/* home directory of said person */char	*Subject = "";		/* subject in message header */char	*AliasList[MAXLINE];	/* list of aliases to allow */int	AliasCount = 0;main(argc, argv)	char **argv;{	char *from;	register char *p;	struct passwd *pw;	char *shortfrom;	char buf[MAXLINE];	extern struct passwd *getpwnam();	extern char *newstr();	extern char *getfrom();	extern bool knows();	extern bool junkmail();	extern time_t convtime();	if (argc == 1) {		AutoInstall();		exit (EX_OK);	}	/* process arguments */	while (--argc > 0 && (p = *++argv) != NULL && *p == '-')	{		switch (*++p)		{		  case 'a':	/* answer all mail, even if not in To/Cc */			AliasList[AliasCount++] = argv[1];			if (argc > 0) {				argc--; argv++;			}			break;		  case 'd':	/* debug */			Debug = TRUE;			break;		  case 'I':	/* initialize */			initialize();			exit(EX_OK);		  case 'j':	/* answer all mail, even if not in To/Cc */			AnswerAll = TRUE;			break;		  case 't':	/* set timeout */			Timeout = convtime(++p);			break;		  default:			usrerr("Unknown flag -%s", p);			exit(EX_USAGE);		}	}	/* verify recipient argument */	if (argc != 1)	{		usrerr("Usage: vacation [-j] [-a alias] [-tN] username  (or)  vacation -I");		exit(EX_USAGE);	}	myname = p;	/* find user's home directory */	pw = getpwnam(myname);	if (pw == NULL)	{		usrerr("Unknown user %s", myname);		exit(EX_NOUSER);	}	homedir = newstr(pw->pw_dir);	(void) strcpy(buf, homedir);	(void) strcat(buf, "/.vacation");	dbminit(buf);	/* read message from standard input (just from line) */	from = getfrom(&shortfrom);	/* check if junk mail or this person is already informed */	if (!junkmail(shortfrom) && !knows(shortfrom))	{		/* mark this person as knowing */		setknows(shortfrom);		/* send the message back */		(void) strcpy(buf, homedir);		(void) strcat(buf, MsgFile);		if (Debug)			printf("Sending %s to %s\n", buf, from);		else		{			sendmessage(buf, from, myname);			/*NOTREACHED*/		}	}	exit (EX_OK);}/***  GETFROM -- read message from standard input and return sender****	Parameters:**		none.****	Returns:**		pointer to the sender address.****	Side Effects:**		Reads first line from standard input.*/char *getfrom(shortp)char **shortp;{	static char line[MAXLINE];	register char *p, *start, *at, *bang;	char saveat;	/* read the from line */	if (fgets(line, sizeof line, stdin) == NULL ||	    strncmp(line, "From ", 5) != NULL)	{		usrerr("No initial From line");		exit(EX_USAGE);	}	/* find the end of the sender address and terminate it */	start = &line[5];	p = index(start, ' ');	if (p == NULL)	{		usrerr("Funny From line '%s'", line);		exit(EX_USAGE);	}	*p = '\0';	/*	 * Strip all but the rightmost UUCP host	 * to prevent loops due to forwarding.	 * Start searching leftward from the leftmost '@'.	 *	a!b!c!d yields a short name of c!d	 *	a!b!c!d@e yields a short name of c!d@e	 *	e@a!b!c yields the same short name	 */#ifdef VDEBUGprintf("start='%s'\n", start);#endif VDEBUG	*shortp = start;			/* assume whole addr */	if ((at = index(start, '@')) == NULL)	/* leftmost '@' */		at = p;				/* if none, use end of addr */	saveat = *at;	*at = '\0';	if ((bang = rindex(start, '!')) != NULL) {	/* rightmost '!' */		char *bang2;		*bang = '\0';		if ((bang2 = rindex(start, '!')) != NULL) /* 2nd rightmost '!' */			*shortp = bang2 + 1;		/* move past ! */		*bang = '!';	}	*at = saveat;#ifdef VDEBUGprintf("place='%s'\n", *shortp);#endif VDEBUG	/* return the sender address */	return start;}/***  JUNKMAIL -- read the header and tell us if this is junk/bulk mail.****	Parameters:**		from -- the Return-Path of the sender.  We assume that**			anything from "*-REQUEST@*" is bulk mail.****	Returns:**		TRUE -- if this is junk or bulk mail (that is, if the**			sender shouldn't receive a response).**		FALSE -- if the sender deserves a response.****	Side Effects:**		May read the header from standard input.  When this**		returns the position on stdin is undefined.*/booljunkmail(from)	char *from;{	register char *p;	char buf[MAXLINE+1];	extern char *index();	extern char *rindex();	extern char *strtok();	extern bool sameword();	bool inside, foundto, onlist;	/* test for inhuman sender */	p = rindex(from, '@');	if (p != NULL)	{		*p = '\0';		if (sameword(&p[-8],  "-REQUEST") ||		    sameword(&p[-10], "Postmaster") ||		    sameword(&p[-13], "MAILER-DAEMON"))		{			*p = '@';			return (TRUE);		}		*p = '@';	}# define Delims " \t\n,:;()<>@.!"	/* read the header looking for "interesting" lines */	inside = FALSE;	onlist = FALSE;	foundto = FALSE;	while (fgets(buf, MAXLINE, stdin) != NULL && buf[0] != '\n')	{		if (buf[0]!=' ' && buf[0] != '\t' && index(buf,':') == NULL)			return(FALSE);			/* no header found */		p = strtok(buf, Delims);		if (p==NULL)			continue;		if (sameword(p, "To") || sameword(p, "Cc"))		{			inside = TRUE;			p = strtok(NULL, Delims);			if (p==NULL)				continue;		}		else				/* continuation line? */		    if (inside)					    	inside =  (buf[0]==' ' || buf[0]=='\t');		if (inside) {		    int i;		    do {			if (sameword(p,myname))				onlist = TRUE;		/* I am on the list */			for (i=0;i<AliasCount;i++)			    if (sameword(p,AliasList[i]))				onlist = TRUE;		/* alias on list */		    } while (p = strtok(NULL, Delims));		    foundto = TRUE;		    continue;		}				if (sameword(p, "Precedence"))		{			/* find the value of this field */			p = strtok(NULL, Delims);			if (p == NULL)				continue;			/* see if it is "junk" or "bulk" */			p[4] = '\0';			if (sameword(p, "junk") || sameword(p, "bulk"))				return (TRUE);		}		if (sameword(p, "Subject"))		{			Subject = newstr(buf+9);			if (p = rindex(Subject,'\n'))				*p = '\0';			if (Debug) 				printf("Subject=%s\n", Subject);		}	}	if (AnswerAll)		return (FALSE);	else		return (foundto && !onlist);}/***  KNOWS -- predicate telling if user has already been informed.****	Parameters:**		user -- the user who sent this message.****	Returns:**		TRUE if 'user' has already been informed that the**			recipient is on vacation.**		FALSE otherwise.****	Side Effects:**		none.*/boolknows(user)	char *user;{	DATUM k, d;	long now;	auto long then;	time(&now);	k.dptr = user;	k.dsize = strlen(user) + 1;	d = fetch(k);	if (d.dptr == NULL)		return (FALSE);		/* be careful on 68k's and others with alignment restrictions */	bcopy((char *) &((struct dbrec *) d.dptr)->sentdate, (char *) &then, sizeof then);	if (then + Timeout < now)		return (FALSE);	if (Debug)		printf("User %s already knows\n");	return (TRUE);}/***  SETKNOWS -- set that this user knows about the vacation.****	Parameters:**		user -- the user who should be marked.****	Returns:**		none.****	Side Effects:**		The dbm file is updated as appropriate.*/setknows(user)	char *user;{	DATUM k, d;	struct dbrec xrec;	k.dptr = user;	k.dsize = strlen(user) + 1;	time(&xrec.sentdate);	d.dptr = (char *) &xrec;	d.dsize = sizeof xrec;	store(k, d);}/***  SENDMESSAGE -- send a message to a particular user.****	Parameters:**		msgf -- filename containing the message.**		user -- user who should receive it.****	Returns:**		none.****	Side Effects:**		sends mail to 'user' using /usr/lib/sendmail.*/sendmessage(msgf, user, myname)	char *msgf;	char *user;	char *myname;{	FILE *f, *pipe;	char line[MAXLINE];	char *p;	/* find the message to send */	f = fopen(msgf, "r");	if (f == NULL)	{		f = fopen("/usr/lib/vacation.def", "r");		if (f == NULL)			syserr("No message to send");	}	(void) sprintf(line, "/usr/lib/sendmail -eq -f %s %s", myname, user);	pipe = popen(line, "w");	if (pipe == NULL)		syserr("Cannot exec /usr/lib/sendmail");	while (fgets(line, MAXLINE, f)) {		p = index(line,'$');		if (p && strncmp(p,"$SUBJECT",8)==0) {			*p = '\0';			fputs(line, pipe);			fputs(Subject, pipe);			fputs(p+8, pipe);			continue;		}		fputs(line, pipe);	}	pclose(pipe);	fclose(f);}/***  INITIALIZE -- initialize the database before leaving for vacation****	Parameters:**		none.****	Returns:**		none.****	Side Effects:**		Initializes the files .vacation.{pag,dir} in the**		caller's home directory.*/initialize(){	char *homedir;	char buf[MAXLINE];	extern char *getenv();	setgid(getgid());	setuid(getuid());	homedir = getenv("HOME");	if (homedir == NULL)		syserr("No home!");	(void) strcpy(buf, homedir);	(void) strcat(buf, "/.vacation.dir");	if (close(creat(buf, 0644)) < 0)		syserr("Cannot create %s", buf);	(void) strcpy(buf, homedir);	(void) strcat(buf, "/.vacation.pag");	if (close(creat(buf, 0644)) < 0)		syserr("Cannot create %s", buf);}/***  USRERR -- print user error****	Parameters:**		f -- format.**		p -- first parameter.****	Returns:**		none.****	Side Effects:**		none.*/usrerr(f, p)	char *f;	char *p;{	fprintf(stderr, "vacation: ");	_doprnt(f, &p, stderr);	fprintf(stderr, "\n");}/***  SYSERR -- print system error****	Parameters:**		f -- format.**		p -- first parameter.****	Returns:**		none.****	Side Effects:**		none.*/syserr(f, p)	char *f;	char *p;{	fprintf(stderr, "vacation: ");	_doprnt(f, &p, stderr);	fprintf(stderr, "\n");	exit(EX_USAGE);}/***  NEWSTR -- copy a string****	Parameters:**		s -- the string to copy.****	Returns:**		A copy of the string.****	Side Effects:**		none.*/char *newstr(s)	char *s;{	char *p;	extern char *malloc();	p = malloc((unsigned)strlen(s) + 1);	if (p == NULL)	{		syserr("newstr: cannot alloc memory");		exit(EX_OSERR);	}	strcpy(p, s);	return (p);}/***  SAMEWORD -- return TRUE if the words are the same****	Ignores case.****	Parameters:**		a, b -- the words to compare.****	Returns:**		TRUE if a & b match exactly (modulo case)**		FALSE otherwise.****	Side Effects:**		none.*/boolsameword(a, b)	register char *a, *b;{	char ca, cb;	do	{		ca = *a++;		cb = *b++;		if (isascii(ca) && isupper(ca))			ca = ca - 'A' + 'a';		if (isascii(cb) && isupper(cb))			cb = cb - 'A' + 'a';	} while (ca != '\0' && ca == cb);	return (ca == cb);}/* * When invoked with no arguments, we fall into an automatic installation * mode, stepping the user through a default installation. */AutoInstall(){	char file[MAXLINE];	char forward[MAXLINE];	char cmd[MAXLINE];	char line[MAXLINE];	char *editor;	FILE *f;myname = getenv("USER");homedir = getenv("HOME");if (homedir == NULL)	syserr("Home directory unknown");printf("This program can be used to answer your mail automatically\n");printf("when you go away on vacation.\n");(void) strcpy(file, homedir);(void) strcat(file, MsgFile);do {	f = fopen(file,"r");	if (f) {printf("You have a message file in %s.\n", file);if (ask("Would you like to see it")) {	sprintf(cmd, "/usr/ucb/more %s", file);	system(cmd);}if (ask("Would you like to edit it"))		f = NULL;	}	else {printf("You need to create a message file in %s first.\n", file);		f = fopen(file,"w");		if (myname)fprintf(f,"From: %s (via the vacation program)\n", myname);fprintf(f,"Subject: away from my mail\n");fprintf(f,"\nI will not be reading my mail for a while.\n");fprintf(f,"Your mail regarding \"$SUBJECT\" will be read when I return.\n");		fclose(f);		f = NULL;	}	if (f == NULL) {		editor = getenv("VISUAL");		if (editor == NULL)			editor = getenv("EDITOR");		if (editor == NULL)			editor = "/usr/ucb/vi";		sprintf(cmd, "%s %s", editor, file);printf("Please use your editor (%s) to edit this file.\n", editor);		system(cmd);	}} while (f == NULL);fclose(f);(void) strcpy(forward, homedir);(void) strcat(forward, "/.forward");f = fopen(forward,"r");if (f) {printf("You have a .forward file in your home directory containing:\n");while (fgets(line, MAXLINE, f))	printf("    %s", line);fclose(f);if (!ask("Would you like to remove it and disable the vacation feature")) 	exit(0);if (unlink(forward))	perror("Error removing .forward file:");else	printf("Back to normal reception of mail.\n");exit(0);}printf("To enable the vacation feature a \".forward\" file is created.\n");if (!ask("Would you like to enable the vacation feature")) {	printf("OK, vacation feature NOT enabled.\n");	exit(0);}f = fopen(forward,"w");if (f==NULL) {	perror("Error opening .forward file");	exit(EX_USAGE);}fprintf(f,"\\%s, \"|/usr/ucb/vacation %s\"\n", myname, myname);fclose(f);printf("Vacation feature ENABLED. Please remember to turn it off when\n");printf("you get back from vacation. Bon voyage.\n");initialize();}/* * Ask the user a question until we get a reasonable answer */ask(prompt)	char *prompt;{	char line[MAXLINE];	while (1) {		printf("%s? ", prompt);		fflush(stdout);		gets(line);		if (line[0]=='y' || line[0]=='Y') return(TRUE);		if (line[0]=='n' || line[0]=='N') return(FALSE);		printf("Please reply \"yes\" or \"no\" (\'y\' or \'n\')\n");	}	}

⌨️ 快捷键说明

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