1955eb5e1SGarrett D'Amore /*
2955eb5e1SGarrett D'Amore  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
3955eb5e1SGarrett D'Amore  * Use is subject to license terms.
4955eb5e1SGarrett D'Amore  *
5955eb5e1SGarrett D'Amore  *	Copyright (c) 1983, 1984, 1986, 1986, 1987, 1988, 1989 AT&T
6955eb5e1SGarrett D'Amore  *	  All Rights Reserved
7955eb5e1SGarrett D'Amore  */
8955eb5e1SGarrett D'Amore 
9955eb5e1SGarrett D'Amore /*
10955eb5e1SGarrett D'Amore  *  Vacation
11955eb5e1SGarrett D'Amore  *  Copyright (c) 1983  Eric P. Allman
12955eb5e1SGarrett D'Amore  *  Berkeley, California
13955eb5e1SGarrett D'Amore  *
14955eb5e1SGarrett D'Amore  *  Copyright (c) 1983 Regents of the University of California.
15955eb5e1SGarrett D'Amore  *  All rights reserved.  The Berkeley software License Agreement
16955eb5e1SGarrett D'Amore  *  specifies the terms and conditions for redistribution.
17955eb5e1SGarrett D'Amore  */
18955eb5e1SGarrett D'Amore 
19955eb5e1SGarrett D'Amore #include <pwd.h>
20955eb5e1SGarrett D'Amore #include <stdio.h>
21955eb5e1SGarrett D'Amore #include <stdarg.h>
22955eb5e1SGarrett D'Amore #include <stdlib.h>
23955eb5e1SGarrett D'Amore #include <unistd.h>
24955eb5e1SGarrett D'Amore #include <sysexits.h>
25955eb5e1SGarrett D'Amore #include <string.h>
26955eb5e1SGarrett D'Amore #include <ctype.h>
27955eb5e1SGarrett D'Amore #include <sm/bitops.h>
28955eb5e1SGarrett D'Amore #include "conf.h"
29955eb5e1SGarrett D'Amore 
30955eb5e1SGarrett D'Amore /*
31955eb5e1SGarrett D'Amore  *  MAILCOMPAT -- Deliver mail to a user's mailbox with the "From's" stuffed.
32955eb5e1SGarrett D'Amore  */
33955eb5e1SGarrett D'Amore 
34955eb5e1SGarrett D'Amore typedef int bool;
35955eb5e1SGarrett D'Amore 
36955eb5e1SGarrett D'Amore #define	FALSE	0
37955eb5e1SGarrett D'Amore #define	TRUE	1
38955eb5e1SGarrett D'Amore 
39955eb5e1SGarrett D'Amore bool	Debug = FALSE;
40955eb5e1SGarrett D'Amore char	*myname;		/* person who is to have their mail filtered */
41955eb5e1SGarrett D'Amore char	*homedir;		/* home directory of said person */
42955eb5e1SGarrett D'Amore char	*AliasList[MAXLINE];	/* list of aliases to allow */
43955eb5e1SGarrett D'Amore char    *fromp;
44955eb5e1SGarrett D'Amore char    *fromuser;
45955eb5e1SGarrett D'Amore int	AliasCount = 0;
46955eb5e1SGarrett D'Amore 
47955eb5e1SGarrett D'Amore static char *newstr();
48955eb5e1SGarrett D'Amore 
49955eb5e1SGarrett D'Amore int	ask(char *);
50955eb5e1SGarrett D'Amore int	sendmessage(char *);
51955eb5e1SGarrett D'Amore void	AutoInstall(void);
52955eb5e1SGarrett D'Amore void	usrerr(const char *, ...);
53955eb5e1SGarrett D'Amore 
54955eb5e1SGarrett D'Amore int
main(argc,argv)55955eb5e1SGarrett D'Amore main(argc, argv)
56955eb5e1SGarrett D'Amore 	int argc;
57955eb5e1SGarrett D'Amore 	char **argv;
58955eb5e1SGarrett D'Amore {
59955eb5e1SGarrett D'Amore 	register char *p;
60955eb5e1SGarrett D'Amore 	struct passwd *pw;
61955eb5e1SGarrett D'Amore 	extern char *getfrom();
62955eb5e1SGarrett D'Amore 
63955eb5e1SGarrett D'Amore 	/* process arguments */
64955eb5e1SGarrett D'Amore 	while (--argc > 0 && (p = *++argv) != NULL && *p == '-')
65955eb5e1SGarrett D'Amore 	{
66955eb5e1SGarrett D'Amore 		switch (*++p)
67955eb5e1SGarrett D'Amore 		{
68955eb5e1SGarrett D'Amore 		    case 'd':	/* debug */
69955eb5e1SGarrett D'Amore 			Debug = TRUE;
70955eb5e1SGarrett D'Amore 			break;
71955eb5e1SGarrett D'Amore 		    default:
72955eb5e1SGarrett D'Amore 			usrerr("Unknown flag -%s", p);
73955eb5e1SGarrett D'Amore 			exit(EX_USAGE);
74955eb5e1SGarrett D'Amore 		}
75955eb5e1SGarrett D'Amore 	}
76955eb5e1SGarrett D'Amore 
77955eb5e1SGarrett D'Amore 	/* verify recipient argument */
78955eb5e1SGarrett D'Amore 	if (argc != 1)
79955eb5e1SGarrett D'Amore 	{
80955eb5e1SGarrett D'Amore 		if (argc == 0)
81955eb5e1SGarrett D'Amore 			AutoInstall();
82955eb5e1SGarrett D'Amore 		else
83955eb5e1SGarrett D'Amore 			usrerr("Usage: mailcompat username (or) mailcompat -r");
84955eb5e1SGarrett D'Amore 		exit(EX_USAGE);
85955eb5e1SGarrett D'Amore 	}
86955eb5e1SGarrett D'Amore 
87955eb5e1SGarrett D'Amore 	myname = p;
88955eb5e1SGarrett D'Amore 	/* find user's home directory */
89955eb5e1SGarrett D'Amore 	pw = getpwnam(myname);
90955eb5e1SGarrett D'Amore 	if (pw == NULL)
91955eb5e1SGarrett D'Amore 	{
92955eb5e1SGarrett D'Amore 		usrerr("user: %s look up failed, name services outage ?", myname);
93955eb5e1SGarrett D'Amore 		exit(EX_TEMPFAIL);
94955eb5e1SGarrett D'Amore 	}
95955eb5e1SGarrett D'Amore 	homedir = newstr(pw->pw_dir);
96955eb5e1SGarrett D'Amore 
97955eb5e1SGarrett D'Amore 	/* read message from standard input (just from line) */
98955eb5e1SGarrett D'Amore 	fromuser = getfrom(&fromp);
99955eb5e1SGarrett D'Amore 	return (sendmessage(fromuser));
100955eb5e1SGarrett D'Amore }
101955eb5e1SGarrett D'Amore 
102955eb5e1SGarrett D'Amore /*
103955eb5e1SGarrett D'Amore **  sendmessage -- read message from standard input do the from stuffing
104955eb5e1SGarrett D'Amore **             and forward to /bin/mail, Being sure to delete any
105955eb5e1SGarrett D'Amore **             content-length headers (/bin/mail recalculates them).
106955eb5e1SGarrett D'Amore **
107955eb5e1SGarrett D'Amore **
108955eb5e1SGarrett D'Amore **	Parameters:
109955eb5e1SGarrett D'Amore **		none.
110955eb5e1SGarrett D'Amore **
111955eb5e1SGarrett D'Amore **
112955eb5e1SGarrett D'Amore **	Side Effects:
113955eb5e1SGarrett D'Amore **		Reads first line from standard input.
114955eb5e1SGarrett D'Amore */
115955eb5e1SGarrett D'Amore 
116955eb5e1SGarrett D'Amore #define	L_HEADER	"Content-Length:"
117955eb5e1SGarrett D'Amore #define	LL_HEADER	15
118955eb5e1SGarrett D'Amore 
119955eb5e1SGarrett D'Amore int
sendmessage(from)120955eb5e1SGarrett D'Amore sendmessage(from)
121955eb5e1SGarrett D'Amore char *from;
122955eb5e1SGarrett D'Amore {
123955eb5e1SGarrett D'Amore 	static char line[MAXLINE];
124955eb5e1SGarrett D'Amore 	static char command[MAXLINE];
125955eb5e1SGarrett D'Amore 	bool in_body = FALSE;
126955eb5e1SGarrett D'Amore 	FILE *mail_fp;
127955eb5e1SGarrett D'Amore 	static char user_name[L_cuserid];
128955eb5e1SGarrett D'Amore 
129955eb5e1SGarrett D'Amore 	if (from == NULL)
130955eb5e1SGarrett D'Amore 		from = cuserid(user_name);
131955eb5e1SGarrett D'Amore 
132955eb5e1SGarrett D'Amore 	snprintf(command, sizeof (command), "/bin/mail -f %s -d %s", from,
133955eb5e1SGarrett D'Amore 	    myname);
134955eb5e1SGarrett D'Amore 	mail_fp = popen(command, "w");
135955eb5e1SGarrett D'Amore 
136955eb5e1SGarrett D'Amore 	/* read the  line */
137955eb5e1SGarrett D'Amore 	while (fgets(line, sizeof line, stdin) != NULL)
138955eb5e1SGarrett D'Amore 	{
139955eb5e1SGarrett D'Amore 		if (line[0] == (char)'\n')  /* end of mail headers */
140955eb5e1SGarrett D'Amore 			in_body = TRUE;
141955eb5e1SGarrett D'Amore 		if (in_body && (strncmp(line, "From ", 5) == 0))
142955eb5e1SGarrett D'Amore 			fprintf(mail_fp, ">");
143955eb5e1SGarrett D'Amore 		if (in_body || (strncasecmp(line, L_HEADER, LL_HEADER) != 0))
144955eb5e1SGarrett D'Amore 			fputs(line, mail_fp);
145955eb5e1SGarrett D'Amore 	}
146955eb5e1SGarrett D'Amore 	return (pclose(mail_fp));
147955eb5e1SGarrett D'Amore }
148955eb5e1SGarrett D'Amore 
149955eb5e1SGarrett D'Amore char *
getfrom(shortp)150955eb5e1SGarrett D'Amore getfrom(shortp)
151955eb5e1SGarrett D'Amore char **shortp;
152955eb5e1SGarrett D'Amore {
153955eb5e1SGarrett D'Amore 	static char line[MAXLINE];
154955eb5e1SGarrett D'Amore 	register char *p, *start, *at, *bang;
155955eb5e1SGarrett D'Amore 	char saveat;
156955eb5e1SGarrett D'Amore 
157955eb5e1SGarrett D'Amore 	/* read the from line */
158955eb5e1SGarrett D'Amore 	if (fgets(line, sizeof line, stdin) == NULL ||
159*fad16a7eSToomas Soome 	    strncmp(line, "From ", 5) != 0)
160955eb5e1SGarrett D'Amore 	{
161955eb5e1SGarrett D'Amore 		usrerr("No initial From line");
162955eb5e1SGarrett D'Amore 		exit(EX_USAGE);
163955eb5e1SGarrett D'Amore 	}
164955eb5e1SGarrett D'Amore 
165955eb5e1SGarrett D'Amore 	/* find the end of the sender address and terminate it */
166955eb5e1SGarrett D'Amore 	start = &line[5];
167955eb5e1SGarrett D'Amore 	p = strchr(start, ' ');
168955eb5e1SGarrett D'Amore 	if (p == NULL)
169955eb5e1SGarrett D'Amore 	{
170955eb5e1SGarrett D'Amore 		usrerr("Funny From line '%s'", line);
171955eb5e1SGarrett D'Amore 		exit(EX_USAGE);
172955eb5e1SGarrett D'Amore 	}
173955eb5e1SGarrett D'Amore 	*p = '\0';
174955eb5e1SGarrett D'Amore 
175955eb5e1SGarrett D'Amore 	/*
176955eb5e1SGarrett D'Amore 	 * Strip all but the rightmost UUCP host
177955eb5e1SGarrett D'Amore 	 * to prevent loops due to forwarding.
178955eb5e1SGarrett D'Amore 	 * Start searching leftward from the leftmost '@'.
179955eb5e1SGarrett D'Amore 	 *	a!b!c!d yields a short name of c!d
180955eb5e1SGarrett D'Amore 	 *	a!b!c!d@e yields a short name of c!d@e
181955eb5e1SGarrett D'Amore 	 *	e@a!b!c yields the same short name
182955eb5e1SGarrett D'Amore 	 */
183955eb5e1SGarrett D'Amore #ifdef VDEBUG
184955eb5e1SGarrett D'Amore printf("start='%s'\n", start);
185955eb5e1SGarrett D'Amore #endif /* VDEBUG */
186955eb5e1SGarrett D'Amore 	*shortp = start;			/* assume whole addr */
187955eb5e1SGarrett D'Amore 	if ((at = strchr(start, '@')) == NULL)	/* leftmost '@' */
188955eb5e1SGarrett D'Amore 		at = p;				/* if none, use end of addr */
189955eb5e1SGarrett D'Amore 	saveat = *at;
190955eb5e1SGarrett D'Amore 	*at = '\0';
191955eb5e1SGarrett D'Amore 	if ((bang = strrchr(start, '!')) != NULL) {	/* rightmost '!' */
192955eb5e1SGarrett D'Amore 		char *bang2;
193955eb5e1SGarrett D'Amore 		*bang = '\0';
194955eb5e1SGarrett D'Amore 		if ((bang2 = strrchr(start, '!')) != NULL) /* 2nd rightmost '!' */
195955eb5e1SGarrett D'Amore 			*shortp = bang2 + 1;		/* move past ! */
196955eb5e1SGarrett D'Amore 		*bang = '!';
197955eb5e1SGarrett D'Amore 	}
198955eb5e1SGarrett D'Amore 	*at = saveat;
199955eb5e1SGarrett D'Amore #ifdef VDEBUG
200955eb5e1SGarrett D'Amore printf("place='%s'\n", *shortp);
201955eb5e1SGarrett D'Amore #endif /* VDEBUG */
202955eb5e1SGarrett D'Amore 
203955eb5e1SGarrett D'Amore 	/* return the sender address */
204955eb5e1SGarrett D'Amore 	return newstr(start);
205955eb5e1SGarrett D'Amore }
206955eb5e1SGarrett D'Amore 
207955eb5e1SGarrett D'Amore /*
208955eb5e1SGarrett D'Amore **  USRERR -- print user error
209955eb5e1SGarrett D'Amore **
210955eb5e1SGarrett D'Amore **	Parameters:
211955eb5e1SGarrett D'Amore **		f -- format.
212955eb5e1SGarrett D'Amore **
213955eb5e1SGarrett D'Amore **	Returns:
214955eb5e1SGarrett D'Amore **		none.
215955eb5e1SGarrett D'Amore **
216955eb5e1SGarrett D'Amore **	Side Effects:
217955eb5e1SGarrett D'Amore **		none.
218955eb5e1SGarrett D'Amore */
219955eb5e1SGarrett D'Amore 
220955eb5e1SGarrett D'Amore void
usrerr(const char * f,...)221955eb5e1SGarrett D'Amore usrerr(const char *f, ...)
222955eb5e1SGarrett D'Amore {
223955eb5e1SGarrett D'Amore 	va_list alist;
224955eb5e1SGarrett D'Amore 
225955eb5e1SGarrett D'Amore 	va_start(alist, f);
226955eb5e1SGarrett D'Amore 	(void) fprintf(stderr, "mailcompat: ");
227955eb5e1SGarrett D'Amore 	(void) vfprintf(stderr, f, alist);
228955eb5e1SGarrett D'Amore 	(void) fprintf(stderr, "\n");
229955eb5e1SGarrett D'Amore 	va_end(alist);
230955eb5e1SGarrett D'Amore }
231955eb5e1SGarrett D'Amore 
232955eb5e1SGarrett D'Amore /*
233955eb5e1SGarrett D'Amore **  NEWSTR -- copy a string
234955eb5e1SGarrett D'Amore **
235955eb5e1SGarrett D'Amore **	Parameters:
236955eb5e1SGarrett D'Amore **		s -- the string to copy.
237955eb5e1SGarrett D'Amore **
238955eb5e1SGarrett D'Amore **	Returns:
239955eb5e1SGarrett D'Amore **		A copy of the string.
240955eb5e1SGarrett D'Amore **
241955eb5e1SGarrett D'Amore **	Side Effects:
242955eb5e1SGarrett D'Amore **		none.
243955eb5e1SGarrett D'Amore */
244955eb5e1SGarrett D'Amore 
245955eb5e1SGarrett D'Amore char *
newstr(s)246955eb5e1SGarrett D'Amore newstr(s)
247955eb5e1SGarrett D'Amore 	char *s;
248955eb5e1SGarrett D'Amore {
249955eb5e1SGarrett D'Amore 	char *p;
250955eb5e1SGarrett D'Amore 	size_t psize = strlen(s) + 1;
251955eb5e1SGarrett D'Amore 
252955eb5e1SGarrett D'Amore 	p = malloc(psize);
253955eb5e1SGarrett D'Amore 	if (p == NULL)
254955eb5e1SGarrett D'Amore 	{
255955eb5e1SGarrett D'Amore 		usrerr("newstr: cannot alloc memory");
256955eb5e1SGarrett D'Amore 		exit(EX_OSERR);
257955eb5e1SGarrett D'Amore 	}
258955eb5e1SGarrett D'Amore 	strlcpy(p, s, psize);
259955eb5e1SGarrett D'Amore 	return (p);
260955eb5e1SGarrett D'Amore }
261955eb5e1SGarrett D'Amore 
262955eb5e1SGarrett D'Amore /*
263955eb5e1SGarrett D'Amore  * When invoked with no arguments, we fall into an automatic installation
264955eb5e1SGarrett D'Amore  * mode, stepping the user through a default installation.
265955eb5e1SGarrett D'Amore  */
266955eb5e1SGarrett D'Amore void
AutoInstall()267955eb5e1SGarrett D'Amore AutoInstall()
268955eb5e1SGarrett D'Amore {
269955eb5e1SGarrett D'Amore 	char forward[MAXLINE];
270955eb5e1SGarrett D'Amore 	char line[MAXLINE];
271955eb5e1SGarrett D'Amore 	static char user_name[L_cuserid];
272955eb5e1SGarrett D'Amore 	FILE *f;
273955eb5e1SGarrett D'Amore 
274955eb5e1SGarrett D'Amore 	myname = cuserid(user_name);
275955eb5e1SGarrett D'Amore 	homedir = getenv("HOME");
276955eb5e1SGarrett D'Amore 	if (homedir == NULL) {
277955eb5e1SGarrett D'Amore 		usrerr("Home directory unknown");
278955eb5e1SGarrett D'Amore 		exit(EX_CONFIG);
279955eb5e1SGarrett D'Amore 	}
280955eb5e1SGarrett D'Amore 
281955eb5e1SGarrett D'Amore 	printf("This program can be used to store your mail in a format\n");
282955eb5e1SGarrett D'Amore 	printf("that you can read with SunOS 4.X based mail readers\n");
283955eb5e1SGarrett D'Amore 	(void) strlcpy(forward, homedir, sizeof (forward));
284955eb5e1SGarrett D'Amore 	(void) strlcat(forward, "/.forward", sizeof (forward));
285955eb5e1SGarrett D'Amore 	f = fopen(forward, "r");
286955eb5e1SGarrett D'Amore 	if (f) {
287955eb5e1SGarrett D'Amore 		printf("You have a .forward file in your home directory");
288955eb5e1SGarrett D'Amore 		printf("  containing:\n");
289955eb5e1SGarrett D'Amore 		while (fgets(line, MAXLINE, f))
290955eb5e1SGarrett D'Amore 			printf("    %s", line);
291955eb5e1SGarrett D'Amore 		fclose(f);
292955eb5e1SGarrett D'Amore 		if (!ask("Would you like to remove it and disable the mailcompat feature"))
293955eb5e1SGarrett D'Amore 			exit(0);
294955eb5e1SGarrett D'Amore 		if (unlink(forward))
295955eb5e1SGarrett D'Amore 			perror("Error removing .forward file:");
296955eb5e1SGarrett D'Amore 		else
297955eb5e1SGarrett D'Amore 			printf("Back to normal reception of mail.\n");
298955eb5e1SGarrett D'Amore 		exit(0);
299955eb5e1SGarrett D'Amore 	}
300955eb5e1SGarrett D'Amore 
301955eb5e1SGarrett D'Amore 	printf("To enable the mailcompat feature a \".forward\" ");
302955eb5e1SGarrett D'Amore 	printf("file is created.\n");
303955eb5e1SGarrett D'Amore 	if (!ask("Would you like to enable the mailcompat feature")) {
304955eb5e1SGarrett D'Amore 		printf("OK, mailcompat feature NOT enabled.\n");
305955eb5e1SGarrett D'Amore 		exit(0);
306955eb5e1SGarrett D'Amore 	}
307955eb5e1SGarrett D'Amore 	f = fopen(forward, "w");
308955eb5e1SGarrett D'Amore 	if (f == NULL) {
309955eb5e1SGarrett D'Amore 		perror("Error opening .forward file");
310955eb5e1SGarrett D'Amore 		exit(EX_USAGE);
311955eb5e1SGarrett D'Amore 	}
312955eb5e1SGarrett D'Amore 	fprintf(f, "\"|/usr/bin/mailcompat %s\"\n", myname);
313955eb5e1SGarrett D'Amore 	fclose(f);
314955eb5e1SGarrett D'Amore 	printf("Mailcompat feature ENABLED.");
315955eb5e1SGarrett D'Amore 	printf("Run mailcompat with no arguments to remove it\n");
316955eb5e1SGarrett D'Amore }
317955eb5e1SGarrett D'Amore 
318955eb5e1SGarrett D'Amore 
319955eb5e1SGarrett D'Amore /*
320955eb5e1SGarrett D'Amore  * Ask the user a question until we get a reasonable answer
321955eb5e1SGarrett D'Amore  */
322955eb5e1SGarrett D'Amore int
ask(prompt)323955eb5e1SGarrett D'Amore ask(prompt)
324955eb5e1SGarrett D'Amore 	char *prompt;
325955eb5e1SGarrett D'Amore {
326955eb5e1SGarrett D'Amore 	char line[MAXLINE];
327955eb5e1SGarrett D'Amore 
328955eb5e1SGarrett D'Amore 	for (;;) {
329955eb5e1SGarrett D'Amore 		printf("%s? ", prompt);
330955eb5e1SGarrett D'Amore 		fflush(stdout);
331955eb5e1SGarrett D'Amore 		fgets(line, sizeof (line), stdin);
332955eb5e1SGarrett D'Amore 		if (line[0] == 'y' || line[0] == 'Y')
333955eb5e1SGarrett D'Amore 			return (TRUE);
334955eb5e1SGarrett D'Amore 		if (line[0] == 'n' || line[0] == 'N')
335955eb5e1SGarrett D'Amore 			return (FALSE);
336955eb5e1SGarrett D'Amore 		printf("Please reply \"yes\" or \"no\" (\'y\' or \'n\')\n");
337955eb5e1SGarrett D'Amore 	}
338955eb5e1SGarrett D'Amore 	/* NOTREACHED */
339955eb5e1SGarrett D'Amore }
340