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