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: }

Defined functions

closemail defined in line 413; used 2 times
datamail defined in line 197; never used
mail defined in line 71; 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

Defined macros

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