# 2.11BSD#431 - /usr/src/usr.sbin/sendmail/aux/mail-dm.c

##### Functions

    closemail         X
    datamail          X
    mail              X
    openmail          X

##### Variables

    Mail_pid          X
    Mail_user         X

##### Macros

    gt                X

       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

- in line 149, 230

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

- in line 88, 211

#### Defined variables

Mail_pid defined in line 303; used 2 times

- in line 359, 406

Mail_user defined in line 304; used 3 times

- in line 318, 412, 421

SccsId defined in line 13; never used

#### Defined macros

gt defined in line 77; used 6 times

- in line 95-99(3), 117, 130, 141

Last modified: 1996-11-30 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: ?E00 |