1*4796Seric # include <ctype.h>
24684Seric # include <wellknown.h>
34684Seric # include <sysexits.h>
44684Seric # include <stdio.h>
54684Seric # include <useful.h>
64684Seric 
7*4796Seric static char	SccsId[] =	"@(#)usersmtp.c	3.2	11/07/81";
84684Seric 
94684Seric /*
104684Seric **  TCP -- TCP/Ethernet/ARPAnet mailer
114684Seric **
124684Seric **	This arranges to send a message over the TCP connection.
134684Seric */
144684Seric 
154684Seric # define MAXLINE	200
164684Seric 
174684Seric char	*MailCommand =	"/usr/lib/sendmail";
184684Seric char	*MailUser =	"network";
19*4796Seric char	*MailPassword =	"mailhack";
20*4796Seric FILE	*InConnection;
21*4796Seric FILE	*OutConnection;
224684Seric bool	Verbose;
23*4796Seric bool	Debug;
244684Seric 
254684Seric main(argc, argv)
264684Seric 	int argc;
274684Seric 	char **argv;
284684Seric {
294684Seric 	register int stat;
304684Seric 
31*4796Seric 	while (argc > 1 && argv[1][0] == '-')
32*4796Seric 	{
33*4796Seric 		register char *p = *++argv;
34*4796Seric 
35*4796Seric 		argc--;
36*4796Seric 		switch (p[1])
37*4796Seric 		{
38*4796Seric 		  case 'v':
39*4796Seric 			Verbose = TRUE;
40*4796Seric 			break;
41*4796Seric 
42*4796Seric 		  case 'd':
43*4796Seric 			Debug = TRUE;
44*4796Seric 			break;
45*4796Seric 		}
46*4796Seric 	}
47*4796Seric 
484684Seric 	if (argc < 4)
49*4796Seric 	{
50*4796Seric 		if (Debug)
51*4796Seric 			printf("Usage\n");
524684Seric 		exit(EX_USAGE);
53*4796Seric 	}
544684Seric 
55*4796Seric 	if (openconnection(argv[2]) < 0)
564684Seric 		exit(EX_TEMPFAIL);
574684Seric 
584684Seric 	stat = runsmtp(argv[1], &argv[3]);
594684Seric 
60*4796Seric 	if (Debug)
61*4796Seric 		printf("Finishing with stat %d\n", stat);
62*4796Seric 
634684Seric 	exit(stat);
644684Seric }
654684Seric /*
664684Seric **  OPENCONNECTION -- open connection to SMTP socket
674684Seric **
684684Seric **	Parameters:
694684Seric **		none.
704684Seric **
714684Seric **	Returns:
724684Seric **		file pointer of connection.
734684Seric **		NULL on error.
744684Seric **
754684Seric **	Side Effects:
764684Seric **		none.
774684Seric */
784684Seric 
794684Seric openconnection(host)
804684Seric 	char *host;
814684Seric {
824684Seric 	char cmdbuf[100];
83*4796Seric 	register int fd;
844684Seric 
854684Seric 	/* create the command name */
86*4796Seric 	sprintf(cmdbuf, "%s -as%s%s", MailCommand,
87*4796Seric 					Verbose ? " -v" : "",
88*4796Seric 					Debug ? " -d" : "");
894684Seric 
90*4796Seric 	if (Debug)
91*4796Seric 		printf("Creating connection to \"%s\" on %s\n", cmdbuf, host);
92*4796Seric 
934684Seric 	/* create connection (we hope) */
94*4796Seric 	fd = rexec(&host, SHELLSERVER, cmdbuf, MailUser, MailPassword);
95*4796Seric 	if (fd < 0)
96*4796Seric 		return (-1);
97*4796Seric 	InConnection = fdopen(fd, "r");
98*4796Seric 	OutConnection = fdopen(fd, "w");
99*4796Seric 	if (InConnection == NULL || OutConnection == NULL)
100*4796Seric 		return (-1);
1014684Seric 
102*4796Seric 	if (Debug)
103*4796Seric 		printf("Connection open to %s\n", host);
104*4796Seric 
105*4796Seric 	return (0);
1064684Seric }
1074684Seric /*
1084684Seric **  RUNSMTP -- run the SMTP protocol over connection.
1094684Seric **
1104684Seric **	Parameters:
1114684Seric **		fr -- from person.
1124684Seric **		tolist -- list of recipients.
1134684Seric **
1144684Seric **	Returns:
1154684Seric **		none.
1164684Seric **
1174684Seric **	Side Effects:
1184684Seric **		Sends the mail via SMTP.
1194684Seric */
1204684Seric 
121*4796Seric runsmtp(fr, tolist)
1224684Seric 	char *fr;
1234684Seric 	char **tolist;
1244684Seric {
1254684Seric 	register int r;
1264684Seric 	register char **t;
1274684Seric 	char buf[MAXLINE];
1284684Seric 
1294684Seric 	/* get greeting message */
130*4796Seric 	r = reply();
1314684Seric 	if (r / 100 != 2)
1324684Seric 		return (EX_TEMPFAIL);
1334684Seric 
1344684Seric 	/* send the mail command */
135*4796Seric 	message("MAIL From:<%s>\r\n", fr);
136*4796Seric 	r = reply();
1374684Seric 	if (r != 250)
1384684Seric 		return (EX_SOFTWARE);
1394684Seric 
1404684Seric 	/* send the recipients */
1414684Seric 	for (t = tolist; *t != NULL; t++)
1424684Seric 	{
143*4796Seric 		message("MRCP To:<%s>\r\n", *t);
144*4796Seric 		r = reply();
1454684Seric 		if (r != 250)
1464684Seric 			return (EX_NOUSER);
1474684Seric 	}
1484684Seric 
1494684Seric 	/* send the data */
150*4796Seric 	message("DATA\r\n");
151*4796Seric 	r = reply();
1524684Seric 	if (r != 354)
1534684Seric 		return (EX_SOFTWARE);
1544684Seric 	while (fgets(buf, sizeof buf, stdin) != NULL)
1554684Seric 	{
1564684Seric 		/* change trailing newline to crlf */
1574684Seric 		register char *p = index(buf, '\n');
1584684Seric 
1594684Seric 		if (p != NULL)
1604684Seric 			*p = '\0';
1614684Seric 		if (buf[0] == '.')
162*4796Seric 			message(".");
163*4796Seric 		message("%s\r\n", buf);
1644684Seric 	}
165*4796Seric 	message(".\r\n");
166*4796Seric 	r = reply();
1674684Seric 	if (r != 250)
1684684Seric 		return (EX_SOFTWARE);
1694684Seric 
1704684Seric 	/* force delivery */
171*4796Seric 	message("DOIT\r\n");
172*4796Seric 	r = reply();
1734684Seric 	if (r != 250)
1744684Seric 		return (EX_TEMPFAIL);
1754684Seric 
176*4796Seric 	message("QUIT\r\n");
177*4796Seric 	r = reply();
1784684Seric 	if (r != 221)
1794684Seric 		return (EX_SOFTWARE);
1804684Seric 
1814684Seric 	return (EX_OK);
1824684Seric }
1834684Seric /*
1844684Seric **  REPLY -- read arpanet reply
1854684Seric **
1864684Seric **	Parameters:
187*4796Seric **		none.
1884684Seric **
1894684Seric **	Returns:
1904684Seric **		reply code it reads.
1914684Seric **
1924684Seric **	Side Effects:
1934684Seric **		flushes the mail file.
1944684Seric */
1954684Seric 
196*4796Seric reply()
1974684Seric {
198*4796Seric 	fflush(OutConnection);
1994684Seric 
200*4796Seric 	if (Debug)
201*4796Seric 		printf("reply\n");
202*4796Seric 
2034684Seric 	/* read the input line */
2044684Seric 	for (;;)
2054684Seric 	{
2064684Seric 		char buf[MAXLINE];
2074684Seric 		register int r;
2084684Seric 
209*4796Seric 		if (fgets(buf, sizeof buf, InConnection) == NULL)
2104684Seric 			return (-1);
2114684Seric 		if (Verbose)
2124684Seric 			fputs(buf, stdout);
213*4796Seric 		if (buf[3] == '-' || !isdigit(buf[0]))
2144684Seric 			continue;
2154684Seric 		r = atoi(buf);
2164684Seric 		if (r < 100)
2174684Seric 			continue;
2184684Seric 		return (r);
2194684Seric 	}
2204684Seric }
221*4796Seric /*
222*4796Seric **  MESSAGE -- send message to server
223*4796Seric **
224*4796Seric **	Parameters:
225*4796Seric **		f -- format
226*4796Seric **		a, b, c -- parameters
227*4796Seric **
228*4796Seric **	Returns:
229*4796Seric **		none.
230*4796Seric **
231*4796Seric **	Side Effects:
232*4796Seric **		writes message to OutChannel.
233*4796Seric */
234*4796Seric 
235*4796Seric message(f, a, b, c)
236*4796Seric 	char *f;
237*4796Seric {
238*4796Seric 	char buf[100];
239*4796Seric 
240*4796Seric 	sprintf(buf, f, a, b, c);
241*4796Seric 	if (Debug)
242*4796Seric 		fputs(buf, stdout);
243*4796Seric 	fputs(buf, OutConnection);
244*4796Seric }
245