|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.