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

Defined functions

closemail defined in line 396; used 2 times
datamail defined in line 196; never used
mail defined in line 78; never used
openmail defined in line 306; used 2 times

Defined variables

Mail_pid defined in line 303; used 2 times
Mail_user defined in line 304; used 3 times
SccsId defined in line 13; never used

Defined macros

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