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

closemail defined in line 394; used 2 times
datamail defined in line 194; never used
mail defined in line 76; never used
openmail defined in line 304; used 2 times

Defined variables

Mail_pid defined in line 301; used 2 times
Mail_user defined in line 302; used 3 times
SccsId defined in line 12; never used

Defined macros

gt defined in line 75; used 6 times
Last modified: 1983-12-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: ?E00
Valid CSS Valid XHTML 1.0 Strict