1*294Seric # include <stdio.h>
2*294Seric # include <pwd.h>
3*294Seric # include "dlvrmail.h"
4*294Seric # include <whoami.h>
5*294Seric 
6*294Seric /*
7*294Seric **  CONF.C -- Delivermail Configuration Tables.
8*294Seric **
9*294Seric **	Defines the configuration of this installation.
10*294Seric **
11*294Seric **	The first table describes available mailers.  This is
12*294Seric **	just a list of argument vectors, with the following
13*294Seric **	codes embedded:
14*294Seric **		$u -- insert the user name.
15*294Seric **		$h -- insert the host name.
16*294Seric **		$f -- insert the from person name.
17*294Seric **		$c -- insert the hop count.
18*294Seric **	This stuff is interpreted in buildmail.  There are two
19*294Seric **	important conventions here: entry zero must be the
20*294Seric **	local mailer & entry one must be the shell.
21*294Seric **
22*294Seric **	The second table gives a list of special characters.  This
23*294Seric **	table is scanned linearly by parse() until an entry is
24*294Seric **	found using one of the magic characters.  Other fields
25*294Seric **	give more information on how to handle it.
26*294Seric **
27*294Seric **	Defined Constants:
28*294Seric **		M_* -- indices into Mailer, used only in this module.
29*294Seric **
30*294Seric **	Defines:
31*294Seric **		Mailer -- the mailer descriptor table.
32*294Seric **		ParseTab -- the parse table.
33*294Seric **
34*294Seric **	Notes:
35*294Seric **		Ingres 11/70 version.
36*294Seric **
37*294Seric **	History:
38*294Seric **		3/5/80 -- Generalized to use <whoami.h>.
39*294Seric **		12/26/79 -- written for Ingres 11/70.
40*294Seric */
41*294Seric 
42*294Seric 
43*294Seric 
44*294Seric 
45*294Seric 
46*294Seric # ifdef ING70
47*294Seric static char	*BerkLocal[] = { "i", "ingres", "ing70", NULL };
48*294Seric char		*MyLocNam = "Ing70";
49*294Seric # define HASARPA
50*294Seric # define V6
51*294Seric # endif ING70
52*294Seric 
53*294Seric # ifdef INGVAX
54*294Seric /* untested */
55*294Seric static char	*BerkLocal[] = { "j", "ingvax", NULL };
56*294Seric char		*MyLocNam = "IngVax";
57*294Seric # endif INGVAX
58*294Seric 
59*294Seric # ifdef CSVAX
60*294Seric /* untested */
61*294Seric static char	*BerkLocal[] = { "v", "csvax", "vax", NULL };
62*294Seric char		*MyLocNam = "CSVax";
63*294Seric # define HASUUCP
64*294Seric # define NETV6MAIL
65*294Seric # endif CSVAX
66*294Seric 
67*294Seric # ifdef CORY
68*294Seric /* untested */
69*294Seric static char	*BerkLocal[] = { "y", "cory", NULL };
70*294Seric char		*MyLocNam = "Cory";
71*294Seric # endif CORY
72*294Seric 
73*294Seric # ifdef IMAGE
74*294Seric /* untested */
75*294Seric static char	*BerkLocal[] = { "m", "image", NULL };
76*294Seric char		*MyLocNam = "Image";
77*294Seric # define V6
78*294Seric # endif IMAGE
79*294Seric 
80*294Seric # ifdef ESVAX
81*294Seric /* untested */
82*294Seric static char	*BerkLocal[] = { "o", "esvax", NULL };
83*294Seric char		*MyLocNam = "ESVax";
84*294Seric # endif ESVAX
85*294Seric 
86*294Seric # ifdef EECS40
87*294Seric /* untested */
88*294Seric static char	*BerkLocal[] = { "z", "eecs40", NULL };
89*294Seric char		*MyLocNam = "EECS40";
90*294Seric # define V6
91*294Seric # endif EECS40
92*294Seric 
93*294Seric struct mailer Mailer[] =
94*294Seric {
95*294Seric 	/* local mail -- must be #0 */
96*294Seric 	{
97*294Seric # ifdef NETV6MAIL
98*294Seric 		"/usr/net/bin/v6mail",
99*294Seric # else
100*294Seric 		"/bin/mail",
101*294Seric # endif
102*294Seric 		M_ROPT|M_NOHOST|M_STRIPQ,	EX_NOUSER,	NULL,
103*294Seric 		{ "...local%mail", "-d", "$u", NULL }
104*294Seric 	},
105*294Seric 	/* pipes through programs -- must be #1 */
106*294Seric 	{
107*294Seric 		"/bin/csh",
108*294Seric 		M_HDR|M_NOHOST,			EX_UNAVAIL,	NULL,
109*294Seric 		{ "...prog%mail", "-fc", "$u", NULL }
110*294Seric 	},
111*294Seric 	/* local berkeley mail */
112*294Seric 	{
113*294Seric 		"/usr/net/bin/sendberkmail",
114*294Seric 		M_FOPT|M_HDR,			EX_UNAVAIL,	BerkLocal,
115*294Seric 		{ "...berk%mail", "-m", "$h", "-t", "$u", "-h", "$c", NULL }
116*294Seric 	},
117*294Seric 	/* arpanet mail */
118*294Seric 	{
119*294Seric 		"/usr/lib/mailers/arpa",
120*294Seric 		0,				0,		NULL,
121*294Seric 		{ "...arpa%mail", "$f", "$h", "$u", NULL }
122*294Seric 	},
123*294Seric 	/* uucp mail (cheat & use Bell's v7 mail) */
124*294Seric 	{
125*294Seric # ifdef UCKMAIL
126*294Seric 		"/bin/badmail",
127*294Seric # else
128*294Seric 		"/bin/mail",
129*294Seric # endif
130*294Seric 		M_ROPT|M_NOHOST|M_STRIPQ,	EX_NOUSER,	NULL,
131*294Seric # ifdef DUMBMAIL
132*294Seric 		{ "...uucp%mail", "$h!$u", NULL }
133*294Seric # else
134*294Seric 		{ "...uucp%mail", "-d", "$h!$u", NULL }
135*294Seric # endif DUMBMAIL
136*294Seric 	},
137*294Seric };
138*294Seric 
139*294Seric # define M_LOCAL	0
140*294Seric # define M_BERK		2
141*294Seric # define M_ARPA		3
142*294Seric # define M_UUCP		4
143*294Seric 
144*294Seric 
145*294Seric 
146*294Seric struct parsetab ParseTab[] =
147*294Seric {
148*294Seric 	':',	M_BERK,		P_ONE,				NULL,
149*294Seric # ifdef HASARPA
150*294Seric 	'@',	M_ARPA,		P_HLAST|P_USR_UPPER,		NULL,
151*294Seric # else
152*294Seric 	'@',	M_BERK,		P_HLAST|P_USR_UPPER|P_MOVE,	"ing70",
153*294Seric # endif HASARPA
154*294Seric 	'^',	-1,		P_MAP,				"!",
155*294Seric # ifdef HASUUCP
156*294Seric 	'!',	M_UUCP,		0,				NULL,
157*294Seric # else
158*294Seric 	'!',	M_BERK,		P_MOVE,				"csvax",
159*294Seric # endif HASUUCP
160*294Seric 	'.',	-1,		P_MAP|P_ONE,			":",
161*294Seric 	'\0',	M_LOCAL,	P_MOVE,				"",
162*294Seric };
163*294Seric /*
164*294Seric **  GETNAME -- Get the current users login name.
165*294Seric **
166*294Seric **	This is in config.c because it is somewhat machine dependent.
167*294Seric **	Examine it carefully for your installation.
168*294Seric **
169*294Seric **	Algorithm:
170*294Seric **		See if the person is logged in.  If so, return
171*294Seric **			the name s/he is logged in as.
172*294Seric **		Look up the user id in /etc/passwd.  If found,
173*294Seric **			return that name.
174*294Seric **		Return NULL.
175*294Seric **
176*294Seric **	Parameters:
177*294Seric **		none
178*294Seric **
179*294Seric **	Returns:
180*294Seric **		The login name of this user.
181*294Seric **		NULL if this person is noone.
182*294Seric **
183*294Seric **	Side Effects:
184*294Seric **		none
185*294Seric **
186*294Seric **	Requires:
187*294Seric **		getlogin (sys)
188*294Seric **		getpwuid (sys)
189*294Seric **		getuid (sys)
190*294Seric **
191*294Seric **	Called By:
192*294Seric **		main
193*294Seric **
194*294Seric **	History:
195*294Seric **		12/26/79 -- written.
196*294Seric */
197*294Seric 
198*294Seric char *
199*294Seric getname()
200*294Seric {
201*294Seric 	register char *p;
202*294Seric 	register struct passwd *w;
203*294Seric 	extern char *getlogin();
204*294Seric 	extern struct passwd *getpwuid();
205*294Seric 	static char namebuf[9];
206*294Seric 
207*294Seric 	p = getlogin();
208*294Seric 	if (p != NULL && p[0] != '\0')
209*294Seric 		return (p);
210*294Seric # ifdef V6
211*294Seric 	w = getpwuid(getuid() & 0377);
212*294Seric # else
213*294Seric 	w = getpwuid(getuid());
214*294Seric # endif V6
215*294Seric 	if (w != NULL)
216*294Seric 	{
217*294Seric 		strcpy(namebuf, w->pw_name);
218*294Seric 		return (namebuf);
219*294Seric 	}
220*294Seric 	return (NULL);
221*294Seric }
222*294Seric 
223*294Seric # ifdef V6
224*294Seric /*
225*294Seric **  TTYPATH -- Get the path of the user's tty -- Version 6 version.
226*294Seric **
227*294Seric **	Returns the pathname of the user's tty.  Returns NULL if
228*294Seric **	the user is not logged in or if s/he has write permission
229*294Seric **	denied.
230*294Seric **
231*294Seric **	Parameters:
232*294Seric **		none
233*294Seric **
234*294Seric **	Returns:
235*294Seric **		pathname of the user's tty.
236*294Seric **		NULL if not logged in or write permission denied.
237*294Seric **
238*294Seric **	Side Effects:
239*294Seric **		none.
240*294Seric **
241*294Seric **	WARNING:
242*294Seric **		Return value is in a local buffer.
243*294Seric **
244*294Seric **	Requires:
245*294Seric **		stat (sys)
246*294Seric **		ttyn (sys)
247*294Seric **		open (sys)
248*294Seric **		read (sys)
249*294Seric **		close (sys)
250*294Seric **		seek (sys)
251*294Seric **
252*294Seric **	Called By:
253*294Seric **		savemail
254*294Seric **
255*294Seric **	History:
256*294Seric **		1/12/80 -- written.
257*294Seric */
258*294Seric 
259*294Seric # include <sys/types.h>
260*294Seric # include <sys/stat.h>
261*294Seric 
262*294Seric char *
263*294Seric ttypath()
264*294Seric {
265*294Seric 	struct stat stbuf;
266*294Seric 	register int i;
267*294Seric 	static char pathn[] = "/dev/ttyx";
268*294Seric 	extern int errno;
269*294Seric 
270*294Seric 	/* compute the pathname of the controlling tty */
271*294Seric 	if ((i = ttyn(2)) == 'x' && (i = ttyn(1)) == 'x' && (i = ttyn(0)) == 'x')
272*294Seric 	{
273*294Seric 		errno = 0;
274*294Seric 		return (NULL);
275*294Seric 	}
276*294Seric 	pathn[8] = i;
277*294Seric 
278*294Seric 	/* see if we have write permission */
279*294Seric 	if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode))
280*294Seric 	{
281*294Seric 		errno = 0;
282*294Seric 		return (NULL);
283*294Seric 	}
284*294Seric 
285*294Seric 	/* see if the user is logged in */
286*294Seric 	if (getlogin() == NULL)
287*294Seric 		return (NULL);
288*294Seric 
289*294Seric 	/* looks good */
290*294Seric 	return (pathn);
291*294Seric }
292*294Seric /*
293*294Seric **  FDOPEN -- Open a stdio file given an open file descriptor.
294*294Seric **
295*294Seric **	This is included here because it is standard in v7, but we
296*294Seric **	need it in v6.
297*294Seric **
298*294Seric **	Algorithm:
299*294Seric **		Open /dev/null to create a descriptor.
300*294Seric **		Close that descriptor.
301*294Seric **		Copy the existing fd into the descriptor.
302*294Seric **
303*294Seric **	Parameters:
304*294Seric **		fd -- the open file descriptor.
305*294Seric **		type -- "r", "w", or whatever.
306*294Seric **
307*294Seric **	Returns:
308*294Seric **		The file descriptor it creates.
309*294Seric **
310*294Seric **	Side Effects:
311*294Seric **		none
312*294Seric **
313*294Seric **	Requires:
314*294Seric **		fopen (sys)
315*294Seric **
316*294Seric **	Called By:
317*294Seric **		deliver
318*294Seric **
319*294Seric **	Notes:
320*294Seric **		The mode of fd must match "type".
321*294Seric */
322*294Seric 
323*294Seric FILE *
324*294Seric fdopen(fd, type)
325*294Seric 	int fd;
326*294Seric 	char *type;
327*294Seric {
328*294Seric 	register FILE *f;
329*294Seric 
330*294Seric 	f = fopen("/dev/null", type);
331*294Seric 	close(fileno(f));
332*294Seric 	fileno(f) = fd;
333*294Seric 	return (f);
334*294Seric }
335*294Seric /*
336*294Seric **  INDEX -- Return pointer to character in string
337*294Seric **
338*294Seric **	For V7 compatibility.
339*294Seric **
340*294Seric **	Parameters:
341*294Seric **		s -- a string to scan.
342*294Seric **		c -- a character to look for.
343*294Seric **
344*294Seric **	Returns:
345*294Seric **		If c is in s, returns the address of the first
346*294Seric **			instance of c in s.
347*294Seric **		NULL if c is not in s.
348*294Seric **
349*294Seric **	Side Effects:
350*294Seric **		none.
351*294Seric **
352*294Seric **	Requires:
353*294Seric **		none.
354*294Seric **
355*294Seric **	History:
356*294Seric **		3/14/80 -- written.  Why isn't this in -lS?
357*294Seric */
358*294Seric 
359*294Seric index(s, c)
360*294Seric 	register char *s;
361*294Seric 	register char c;
362*294Seric {
363*294Seric 	while (*s != '\0')
364*294Seric 	{
365*294Seric 		if (*s++ == c)
366*294Seric 			return (--s);
367*294Seric 	}
368*294Seric 	return (NULL);
369*294Seric }
370*294Seric # endif V6
371*294Seric 
372*294Seric # ifndef V6
373*294Seric /*
374*294Seric **  TTYPATH -- Get the path of the user's tty -- Version 7 version.
375*294Seric **
376*294Seric **	Returns the pathname of the user's tty.  Returns NULL if
377*294Seric **	the user is not logged in or if s/he has write permission
378*294Seric **	denied.
379*294Seric **
380*294Seric **	Parameters:
381*294Seric **		none
382*294Seric **
383*294Seric **	Returns:
384*294Seric **		pathname of the user's tty.
385*294Seric **		NULL if not logged in or write permission denied.
386*294Seric **
387*294Seric **	Side Effects:
388*294Seric **		none.
389*294Seric **
390*294Seric **	WARNING:
391*294Seric **		Return value is in a local buffer.
392*294Seric **
393*294Seric **	Requires:
394*294Seric **		stat (sys)
395*294Seric **		ttyn (sys)
396*294Seric **		open (sys)
397*294Seric **		read (sys)
398*294Seric **		close (sys)
399*294Seric **		seek (sys)
400*294Seric **
401*294Seric **	Called By:
402*294Seric **		savemail
403*294Seric **
404*294Seric **	History:
405*294Seric **		1/12/80 -- written.
406*294Seric */
407*294Seric 
408*294Seric # include <sys/types.h>
409*294Seric # include <sys/stat.h>
410*294Seric 
411*294Seric char *
412*294Seric ttypath()
413*294Seric {
414*294Seric 	struct stat stbuf;
415*294Seric 	register char *pathn;
416*294Seric 	extern int errno;
417*294Seric 	extern char *ttyname();
418*294Seric 
419*294Seric 	/* compute the pathname of the controlling tty */
420*294Seric 	if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL && (pathn = ttyname(0)) == NULL)
421*294Seric 	{
422*294Seric 		errno = 0;
423*294Seric 		return (NULL);
424*294Seric 	}
425*294Seric 
426*294Seric 	/* see if we have write permission */
427*294Seric 	if (stat(pathn, &stbuf) < 0 || !flagset(02, stbuf.st_mode))
428*294Seric 	{
429*294Seric 		errno = 0;
430*294Seric 		return (NULL);
431*294Seric 	}
432*294Seric 
433*294Seric 	/* see if the user is logged in */
434*294Seric 	if (getlogin() == NULL)
435*294Seric 		return (NULL);
436*294Seric 
437*294Seric 	/* looks good */
438*294Seric 	return (pathn);
439*294Seric }
440*294Seric # endif V6
441