1 # include <ctype.h>
2 # include <wellknown.h>
3 # include <sysexits.h>
4 # include <stdio.h>
5 # include <useful.h>
6 
7 static char	SccsId[] =	"@(#)usersmtp.c	3.2	11/07/81";
8 
9 /*
10 **  TCP -- TCP/Ethernet/ARPAnet mailer
11 **
12 **	This arranges to send a message over the TCP connection.
13 */
14 
15 # define MAXLINE	200
16 
17 char	*MailCommand =	"/usr/lib/sendmail";
18 char	*MailUser =	"network";
19 char	*MailPassword =	"mailhack";
20 FILE	*InConnection;
21 FILE	*OutConnection;
22 bool	Verbose;
23 bool	Debug;
24 
25 main(argc, argv)
26 	int argc;
27 	char **argv;
28 {
29 	register int stat;
30 
31 	while (argc > 1 && argv[1][0] == '-')
32 	{
33 		register char *p = *++argv;
34 
35 		argc--;
36 		switch (p[1])
37 		{
38 		  case 'v':
39 			Verbose = TRUE;
40 			break;
41 
42 		  case 'd':
43 			Debug = TRUE;
44 			break;
45 		}
46 	}
47 
48 	if (argc < 4)
49 	{
50 		if (Debug)
51 			printf("Usage\n");
52 		exit(EX_USAGE);
53 	}
54 
55 	if (openconnection(argv[2]) < 0)
56 		exit(EX_TEMPFAIL);
57 
58 	stat = runsmtp(argv[1], &argv[3]);
59 
60 	if (Debug)
61 		printf("Finishing with stat %d\n", stat);
62 
63 	exit(stat);
64 }
65 /*
66 **  OPENCONNECTION -- open connection to SMTP socket
67 **
68 **	Parameters:
69 **		none.
70 **
71 **	Returns:
72 **		file pointer of connection.
73 **		NULL on error.
74 **
75 **	Side Effects:
76 **		none.
77 */
78 
79 openconnection(host)
80 	char *host;
81 {
82 	char cmdbuf[100];
83 	register int fd;
84 
85 	/* create the command name */
86 	sprintf(cmdbuf, "%s -as%s%s", MailCommand,
87 					Verbose ? " -v" : "",
88 					Debug ? " -d" : "");
89 
90 	if (Debug)
91 		printf("Creating connection to \"%s\" on %s\n", cmdbuf, host);
92 
93 	/* create connection (we hope) */
94 	fd = rexec(&host, SHELLSERVER, cmdbuf, MailUser, MailPassword);
95 	if (fd < 0)
96 		return (-1);
97 	InConnection = fdopen(fd, "r");
98 	OutConnection = fdopen(fd, "w");
99 	if (InConnection == NULL || OutConnection == NULL)
100 		return (-1);
101 
102 	if (Debug)
103 		printf("Connection open to %s\n", host);
104 
105 	return (0);
106 }
107 /*
108 **  RUNSMTP -- run the SMTP protocol over connection.
109 **
110 **	Parameters:
111 **		fr -- from person.
112 **		tolist -- list of recipients.
113 **
114 **	Returns:
115 **		none.
116 **
117 **	Side Effects:
118 **		Sends the mail via SMTP.
119 */
120 
121 runsmtp(fr, tolist)
122 	char *fr;
123 	char **tolist;
124 {
125 	register int r;
126 	register char **t;
127 	char buf[MAXLINE];
128 
129 	/* get greeting message */
130 	r = reply();
131 	if (r / 100 != 2)
132 		return (EX_TEMPFAIL);
133 
134 	/* send the mail command */
135 	message("MAIL From:<%s>\r\n", fr);
136 	r = reply();
137 	if (r != 250)
138 		return (EX_SOFTWARE);
139 
140 	/* send the recipients */
141 	for (t = tolist; *t != NULL; t++)
142 	{
143 		message("MRCP To:<%s>\r\n", *t);
144 		r = reply();
145 		if (r != 250)
146 			return (EX_NOUSER);
147 	}
148 
149 	/* send the data */
150 	message("DATA\r\n");
151 	r = reply();
152 	if (r != 354)
153 		return (EX_SOFTWARE);
154 	while (fgets(buf, sizeof buf, stdin) != NULL)
155 	{
156 		/* change trailing newline to crlf */
157 		register char *p = index(buf, '\n');
158 
159 		if (p != NULL)
160 			*p = '\0';
161 		if (buf[0] == '.')
162 			message(".");
163 		message("%s\r\n", buf);
164 	}
165 	message(".\r\n");
166 	r = reply();
167 	if (r != 250)
168 		return (EX_SOFTWARE);
169 
170 	/* force delivery */
171 	message("DOIT\r\n");
172 	r = reply();
173 	if (r != 250)
174 		return (EX_TEMPFAIL);
175 
176 	message("QUIT\r\n");
177 	r = reply();
178 	if (r != 221)
179 		return (EX_SOFTWARE);
180 
181 	return (EX_OK);
182 }
183 /*
184 **  REPLY -- read arpanet reply
185 **
186 **	Parameters:
187 **		none.
188 **
189 **	Returns:
190 **		reply code it reads.
191 **
192 **	Side Effects:
193 **		flushes the mail file.
194 */
195 
196 reply()
197 {
198 	fflush(OutConnection);
199 
200 	if (Debug)
201 		printf("reply\n");
202 
203 	/* read the input line */
204 	for (;;)
205 	{
206 		char buf[MAXLINE];
207 		register int r;
208 
209 		if (fgets(buf, sizeof buf, InConnection) == NULL)
210 			return (-1);
211 		if (Verbose)
212 			fputs(buf, stdout);
213 		if (buf[3] == '-' || !isdigit(buf[0]))
214 			continue;
215 		r = atoi(buf);
216 		if (r < 100)
217 			continue;
218 		return (r);
219 	}
220 }
221 /*
222 **  MESSAGE -- send message to server
223 **
224 **	Parameters:
225 **		f -- format
226 **		a, b, c -- parameters
227 **
228 **	Returns:
229 **		none.
230 **
231 **	Side Effects:
232 **		writes message to OutChannel.
233 */
234 
235 message(f, a, b, c)
236 	char *f;
237 {
238 	char buf[100];
239 
240 	sprintf(buf, f, a, b, c);
241 	if (Debug)
242 		fputs(buf, stdout);
243 	fputs(buf, OutConnection);
244 }
245