1*4684Seric # include <wellknown.h>
2*4684Seric # include <sysexits.h>
3*4684Seric # include <stdio.h>
4*4684Seric # include <useful.h>
5*4684Seric 
6*4684Seric static char	SccsId[] =	"@(#)usersmtp.c	3.1	10/31/81";
7*4684Seric 
8*4684Seric /*
9*4684Seric **  TCP -- TCP/Ethernet/ARPAnet mailer
10*4684Seric **
11*4684Seric **	This arranges to send a message over the TCP connection.
12*4684Seric */
13*4684Seric 
14*4684Seric # define MAXLINE	200
15*4684Seric 
16*4684Seric char	*MailCommand =	"/usr/lib/sendmail";
17*4684Seric char	*MailUser =	"network";
18*4684Seric char	*MailPassword =	NULL;
19*4684Seric FILE	*MailFile;
20*4684Seric bool	Verbose;
21*4684Seric 
22*4684Seric main(argc, argv)
23*4684Seric 	int argc;
24*4684Seric 	char **argv;
25*4684Seric {
26*4684Seric 	extern FILE *openconnection();
27*4684Seric 	register int stat;
28*4684Seric 
29*4684Seric 	if (argc < 4)
30*4684Seric 		exit(EX_USAGE);
31*4684Seric 
32*4684Seric 	MailFile = openconnection(argv[2]);
33*4684Seric 	if (MailFile == NULL)
34*4684Seric 		exit(EX_TEMPFAIL);
35*4684Seric 
36*4684Seric 	stat = runsmtp(argv[1], &argv[3]);
37*4684Seric 
38*4684Seric 	exit(stat);
39*4684Seric }
40*4684Seric /*
41*4684Seric **  OPENCONNECTION -- open connection to SMTP socket
42*4684Seric **
43*4684Seric **	Parameters:
44*4684Seric **		none.
45*4684Seric **
46*4684Seric **	Returns:
47*4684Seric **		file pointer of connection.
48*4684Seric **		NULL on error.
49*4684Seric **
50*4684Seric **	Side Effects:
51*4684Seric **		none.
52*4684Seric */
53*4684Seric 
54*4684Seric FILE *
55*4684Seric openconnection(host)
56*4684Seric 	char *host;
57*4684Seric {
58*4684Seric 	char cmdbuf[100];
59*4684Seric 	extern FILE *rexec();
60*4684Seric 	register FILE *f;
61*4684Seric 
62*4684Seric 	/* create the command name */
63*4684Seric 	sprintf(cmdbuf, "%s -p", MailCommand);
64*4684Seric 
65*4684Seric 	/* create connection (we hope) */
66*4684Seric 	f = rexec(&host, SHELLSERVER, cmdbuf, &MailUser, NULL);
67*4684Seric 
68*4684Seric 	return (f);
69*4684Seric }
70*4684Seric /*
71*4684Seric **  RUNSMTP -- run the SMTP protocol over connection.
72*4684Seric **
73*4684Seric **	Parameters:
74*4684Seric **		fr -- from person.
75*4684Seric **		tolist -- list of recipients.
76*4684Seric **		mf -- mail connection file.
77*4684Seric **
78*4684Seric **	Returns:
79*4684Seric **		none.
80*4684Seric **
81*4684Seric **	Side Effects:
82*4684Seric **		Sends the mail via SMTP.
83*4684Seric */
84*4684Seric 
85*4684Seric runsmtp(fr, tolist, mf)
86*4684Seric 	char *fr;
87*4684Seric 	char **tolist;
88*4684Seric 	FILE *mf;
89*4684Seric {
90*4684Seric 	register int r;
91*4684Seric 	register char **t;
92*4684Seric 	char buf[MAXLINE];
93*4684Seric 
94*4684Seric 	/* get greeting message */
95*4684Seric 	r = reply(mf);
96*4684Seric 	if (r / 100 != 2)
97*4684Seric 		return (EX_TEMPFAIL);
98*4684Seric 
99*4684Seric 	/* send the mail command */
100*4684Seric 	fprintf(mf, "MAIL From:<%s>\r\n", fr);
101*4684Seric 	r = reply(mf);
102*4684Seric 	if (r != 250)
103*4684Seric 		return (EX_SOFTWARE);
104*4684Seric 
105*4684Seric 	/* send the recipients */
106*4684Seric 	for (t = tolist; *t != NULL; t++)
107*4684Seric 	{
108*4684Seric 		fprintf(mf, "MRCP To:<%s>\r\n", *t);
109*4684Seric 		r = reply(mf);
110*4684Seric 		if (r != 250)
111*4684Seric 			return (EX_NOUSER);
112*4684Seric 	}
113*4684Seric 
114*4684Seric 	/* send the data */
115*4684Seric 	fprintf(mf, "DATA\r\n");
116*4684Seric 	r = reply(mf);
117*4684Seric 	if (r != 354)
118*4684Seric 		return (EX_SOFTWARE);
119*4684Seric 	while (fgets(buf, sizeof buf, stdin) != NULL)
120*4684Seric 	{
121*4684Seric 		/* change trailing newline to crlf */
122*4684Seric 		register char *p = index(buf, '\n');
123*4684Seric 
124*4684Seric 		if (p != NULL)
125*4684Seric 			*p = '\0';
126*4684Seric 		if (buf[0] == '.')
127*4684Seric 			fprintf(mf, ".");
128*4684Seric 		fprintf(mf, "%s\r\n", buf);
129*4684Seric 	}
130*4684Seric 	fprintf(mf, ".\r\n");
131*4684Seric 	r = reply(mf);
132*4684Seric 	if (r != 250)
133*4684Seric 		return (EX_SOFTWARE);
134*4684Seric 
135*4684Seric 	/* force delivery */
136*4684Seric 	fprintf(mf, "DOIT\r\n");
137*4684Seric 	r = reply(mf);
138*4684Seric 	if (r != 250)
139*4684Seric 		return (EX_TEMPFAIL);
140*4684Seric 
141*4684Seric 	fprintf(mf, "QUIT\r\n");
142*4684Seric 	r = reply(mf);
143*4684Seric 	if (r != 221)
144*4684Seric 		return (EX_SOFTWARE);
145*4684Seric 
146*4684Seric 	return (EX_OK);
147*4684Seric }
148*4684Seric /*
149*4684Seric **  REPLY -- read arpanet reply
150*4684Seric **
151*4684Seric **	Parameters:
152*4684Seric **		mf -- mail file.
153*4684Seric **
154*4684Seric **	Returns:
155*4684Seric **		reply code it reads.
156*4684Seric **
157*4684Seric **	Side Effects:
158*4684Seric **		flushes the mail file.
159*4684Seric */
160*4684Seric 
161*4684Seric reply(mf)
162*4684Seric 	FILE *mf;
163*4684Seric {
164*4684Seric 	fflush(mf);
165*4684Seric 
166*4684Seric 	/* read the input line */
167*4684Seric 	for (;;)
168*4684Seric 	{
169*4684Seric 		char buf[MAXLINE];
170*4684Seric 		register int r;
171*4684Seric 
172*4684Seric 		if (fgets(buf, sizeof buf, mf) == NULL)
173*4684Seric 			return (-1);
174*4684Seric 		if (Verbose)
175*4684Seric 			fputs(buf, stdout);
176*4684Seric 		if (buf[3] == '-')
177*4684Seric 			continue;
178*4684Seric 		r = atoi(buf);
179*4684Seric 		if (r < 100)
180*4684Seric 			continue;
181*4684Seric 		return (r);
182*4684Seric 	}
183*4684Seric }
184