1: #include <arpa/netopen.h>
2: #include "srvrftp.h"
3: #include <statbuf.h>
4: #include <arpa/hostnames.h>
5: #include <io_buf.h>
6: #include <arpa/mail.h>
7: #include <ident.h>
8: #include <signal.h>
9: #include <log.h>
10: extern int fout;
11:
12: static char SccsId[] = "@(#)mail-dm.c 4.1 7/25/83";
13:
14: /*
15: Name:
16: mail
17:
18: Function:
19: handle the MAIL <user> command over the command connection
20:
21: Algorithm:
22: see if we have a known user
23:
24: if mailbox file can't be gotten
25: return
26: tell him it is ok to go ahead with mail
27:
28: while he doesn't type a period
29: read and write data
30: say completed
31:
32: Parameters:
33: username in arg
34:
35: Returns:
36: nothing
37:
38: Globals:
39: arg
40: username=
41:
42: Calls:
43: strmove
44: getuser
45: loguser
46: openmail
47: closemail
48: getline
49: chown (sys)
50: time (sys)
51: printf (sys)
52: getch (util)
53: putch (util)
54:
55: Called by:
56: main thru command array
57:
58: History:
59: initial coding Mark Kampe UCLA-ATS
60: modified 4/13/76 by S. F. Holmgren for Illinois version
61: modified 6/30/76 by S. F. Holmgren to call getmbox
62: modified 10/18/76 by J. S. Kravitz to improve net mail header
63: chown removed by R. Balocca @ CAC, Sunday 1977 February 20
64: getline removed and limit on line length removed by using
65: getch and putch added by R. Balocca @ CAC, 1977 March 8 Tuesday
66: Fixed oversight in above (forgot to translate <crlf> to <lf>)
67: 1977 March 10 Thursday by Rick Balocca @ CAC
68: Added openmail & closemail, added logging, and fixed several
69: bugs on or about 12/21/79 by Eric Allman, UCB/INGRES.
70: Changed to always accept mail -- bad mail will be sent back --
71: 1/9/80 by Eric Allman, UCB/INGRES.
72: Don't print out 350 enter mail or 256 mail accepted messages --
73: sendmail will do that. 8/19/81 Eric Allman UCB/INGRES.
74: */
75: #define gt (c = getch())
76: mail()
77: {
78: register char *p; /* general use */
79: register int c;
80: int i;
81:
82: /* extern struct io_buf obuf; */
83:
84: /* get to open mailbox file descriptor */
85: fflush(&fout);
86: if( (fout = openmail(arg, 0)) < 0 )
87: return;
88:
89: for(;;) /* while no error or <crlf>.<crlf> */
90: {
91: /* we are at beginning of line */
92:
93: if(gt=='.') /*"."*/
94: {
95: if(gt=='\r') /*".\r"*/
96: {
97: if(gt=='\n') /*".\r\n"*/
98: {
99: /* end of message */
100: break;
101: }
102: else
103: { /*".\r"c*/
104: putch('.');
105: putch('\r');
106: }
107: }
108: else /*"."c"*/
109: putch('.');
110: }
111: /*"-"*/
112: /* c */
113: for(;;)
114: {
115: for(; c != '\r'; gt)
116: {
117: if( c < 0 )
118: {
119: fflush(&fout);
120: write(fout, "\n***** Sender aborted connection *****\n", 39);
121: goto out;
122: }
123: else
124: putch(c);
125: }
126:
127: /*"\r"*/
128: if( gt == '\n' )
129: { /*"\r\n"*/
130: crlf:
131: putch('\n');
132: break;
133: }
134: else
135: { /*"\r"c*/
136: crc:
137: putch('\r');
138: if(c=='\0')
139: gt; /* "\r\0" */
140: /* is arpa escape for "\r" */
141: }
142: }
143: }
144:
145: out:
146: fflush(&fout);
147: closemail(fout);
148: }
149:
150: /*
151: Name:
152: datamail
153:
154: Function:
155: handle the MLFL command
156:
157: Algorithm:
158: fork
159: make sure we have a valid user
160: say bad user and exit
161: send sock command
162: open data connection
163: get open mailbox file descriptor
164: call rcvdata to receive mail
165:
166: Parameters:
167: username in arg
168:
169: Returns:
170: nothing
171:
172: Globals:
173: arg
174:
175: Calls:
176: fork (sys)
177: strmove
178: netreply
179: sendsock
180: dataconnection
181: getmbox
182: rcvdata
183: printf (sys)
184: time (sys)
185:
186: Called by:
187: main thru command array
188:
189: History:
190: initial coding 4/13/76 by S. F. Holmgren
191: modified 10/18/76 by J. S. Kravitz to put net mail header
192: chown removed by R. Balocca @ CAC, Sunday 1977 February 20
193: */
194: datamail()
195: {
196: register netdata;
197: /* register mboxfid; */
198: register int i;
199:
200: i = fork();
201: if (i < 0)
202: {
203: netreply("455 Mail server temporarily unavailable\r\n");
204: return;
205: }
206: else if (i == 0)
207: {
208: fflush(&fout);
209: if ((fout = openmail(arg, 1)) < 0)
210: exit(3);
211:
212: /* send sock command */
213: sendsock( U4 );
214:
215: /* open data connection */
216: netdata = dataconnection( U4 );
217:
218: /* say its ok to proceed */
219: numreply( NUM250 );
220:
221: /* get data from net connection and copy to mail file */
222: /* rcvdata( netdata,mboxfid ); */
223: if (rcvdata(netdata, fout) < 0)
224: exit(1);
225:
226: /* close the mail, see if ok; if so say ok */
227: fflush(&fout);
228: closemail(fout);
229:
230: exit( 0 );
231: }
232: }
233: /*
234: ** OPENMAIL -- Open a channel to the mail server
235: **
236: ** Gets the mail server started up ready to handle our
237: ** mail.
238: **
239: ** Algorithm:
240: ** See if the user is specified.
241: ** If not, send to user "root".
242: ** See if the user exists.
243: ** If not, signal error 450 and return.
244: ** Fork.
245: ** Create a pipe
246: ** Signal "unavailable" and exit on failure.
247: ** Fork.
248: ** Signal "unavailable" and exit on failure
249: ** In child:
250: ** Call mailer: /etc/delivermail is preferred.
251: ** In parent:
252: ** Avoid pipe signals in case delivermail dies.
253: ** Save the childs pid.
254: ** Return file descriptor.
255: **
256: ** Notes:
257: ** The check to see if the user actually exists should
258: ** go away so that we can do real mail forwarding.
259: **
260: ** Parameters:
261: ** who -- the user to send the mail to.
262: ** mode -- 0 -- called from mail
263: ** 1 -- called from mlfl
264: **
265: ** Returns:
266: ** File descriptor to send mail to.
267: ** -1 on failure.
268: **
269: ** Side Effects:
270: ** Forks /etc/delivermail or /bin/mail or /usr/bin/mail.
271: ** Becomes "network" in the child.
272: **
273: ** Requires:
274: ** strmove
275: ** getuser
276: ** netreply
277: ** pipe (sys)
278: ** fork (sys)
279: ** close (sys)
280: ** dup (sys)
281: ** execl (sys)
282: ** signal (sys)
283: ** exit (sys)
284: **
285: ** Called By:
286: ** mail
287: ** datamail
288: **
289: ** History:
290: ** 1/9/80 -- Added 050 & 455 reply messages if execl's
291: ** fail. Eric Allman UCB/INGRES.
292: ** 11/26/79 -- Modified to map upper case to lower
293: ** case. Eric Allman UCB/INGRES.
294: ** 11/10/79 -- Written by Eric Allman UCB/INGRES
295: ** 3/6/80 -- Dropped case mapping; delivermail does
296: ** that now. EPA UCB/INGRES.
297: ** 8/19/81 -- Added "mode" parameter; call sendmail
298: ** instead of delivermail. EPA
299: */
300:
301: int Mail_pid;
302: char *Mail_user;
303:
304: openmail(who, mode)
305: char *who;
306: int mode;
307: {
308: register char *w;
309: register int i;
310: int pvect[2];
311: register char *p;
312:
313: w = who;
314: if (w == 0)
315: w = "root";
316: Mail_user = w;
317:
318: /* see if the user exists */
319: strmove(w, username);
320:
321: /* try to get a pipe to the mailer */
322: if (pipe(pvect) < 0)
323: {
324: unavailable:
325: netreply("455 Mail server temporarily unavailable\r\n");
326: return (-1);
327: }
328:
329: /* fork */
330: i = fork();
331: if (i < 0)
332: {
333: /* failure */
334: close(pvect[0]);
335: close(pvect[1]);
336: goto unavailable;
337: }
338: else if (i == 0)
339: {
340: /* child */
341: close(pvect[1]);
342: close(0);
343: dup(pvect[0]);
344: close(pvect[0]);
345: setuid(NETUID);
346:
347: /* try to call something to deliver the mail */
348: execl("/etc/sendmail", "sendmail", "-v", mode == 1 ? "-af" : "-am", w, 0);
349:
350: /* doesn't seem to be anything around */
351: netreply("455 Mail server unavailable\r\n");
352: exit(3);
353: }
354:
355: /* else parent */
356: signal(SIGPIPE, SIG_IGN);
357: Mail_pid = i;
358: close(pvect[0]);
359: return (pvect[1]);
360: }
361: /*
362: ** CLOSEMAIL -- Close the mail file and get actual status
363: **
364: ** The mail file is closed.
365: **
366: ** Algorithm:
367: ** Wait for the mailer to die.
368: ** If it wasn't there, be non-comittal.
369: ** If it died a violent death, give error.
370: **
371: ** Parameters:
372: ** fd -- the file descriptor of the mail file.
373: **
374: ** Returns:
375: ** none.
376: **
377: ** Side Effects:
378: ** mailer is soaked up.
379: **
380: ** Requires:
381: ** close (sys)
382: ** wait (sys)
383: **
384: ** Called By:
385: ** mail
386: ** datamail
387: **
388: ** History:
389: ** 1/9/80 -- Changed to not check for errors in mailing,
390: ** since these will be mailed back.
391: ** 11/10/79 -- Written by Eric Allman UCB/INGRES.
392: */
393:
394: closemail(fd)
395: int fd;
396: {
397: auto int st;
398: register int i;
399:
400: /* close the pipe -- mail should go away */
401: close(fd);
402:
403: /* wait for its body */
404: while ((i = wait(&st)) != Mail_pid)
405: {
406: if (i < 0)
407: {
408: /* how did this happen? */
409: logmsg(LOG_ERR, "mail from host %d to %s: no child",
410: openparams.o_frnhost & 0377, Mail_user);
411: goto unavailable;
412: }
413: }
414:
415: /* 'st' is now the status of the mailer */
416: if ((st & 0377) != 0)
417: {
418: logmsg(LOG_ERR, "mail from host %d to %s: status %o",
419: openparams.o_frnhost & 0377, Mail_user, st);
420: unavailable:
421: netreply("455 Mail not delivered -- local system error\r\n");
422: return (-1);
423: }
424:
425: return (0);
426: }
Defined functions
mail
defined in line
76;
never used
Defined variables
Defined macros
gt
defined in line
75; used 6 times