386BSD 0.0 development
authorWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Fri, 19 Apr 1991 20:55:36 +0000 (12:55 -0800)
committerWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Fri, 19 Apr 1991 20:55:36 +0000 (12:55 -0800)
Work on file usr/src/usr.sbin/sendmail/aux/mail-dm.c

Co-Authored-By: Lynne Greer Jolitz <ljolitz@cardio.ucsf.edu>
Synthesized-from: 386BSD-0.0/src

usr/src/usr.sbin/sendmail/aux/mail-dm.c [new file with mode: 0644]

diff --git a/usr/src/usr.sbin/sendmail/aux/mail-dm.c b/usr/src/usr.sbin/sendmail/aux/mail-dm.c
new file mode 100644 (file)
index 0000000..57becd8
--- /dev/null
@@ -0,0 +1,467 @@
+/*-
+ * Copyright (c) 1981 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1981 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)mail-dm.c  4.2 (Berkeley) 4/19/91";
+#endif /* not lint */
+
+#include <arpa/netopen.h>
+#include "srvrftp.h"
+#include <statbuf.h>
+#include <arpa/hostnames.h>
+#include <io_buf.h>
+#include <arpa/mail.h>
+#include <ident.h>
+#include <signal.h>
+#include <log.h>
+extern int fout;
+
+/*
+Name:
+       mail
+
+Function:
+       handle the MAIL <user> command over the command connection
+
+Algorithm:
+       see if we have a known user
+
+       if mailbox file can't be gotten
+               return
+       tell him it is ok to go ahead with mail
+
+       while he doesn't type a period
+               read and write data
+       say completed
+
+Parameters:
+       username in arg
+
+Returns:
+       nothing
+
+Globals:
+       arg
+       username=
+
+Calls:
+       strmove
+       getuser
+       loguser
+       openmail
+       closemail
+       getline
+       chown (sys)
+       time (sys)
+       printf (sys)
+       getch   (util)
+       putch   (util)
+
+Called by:
+       main thru command array
+
+History:
+       initial coding          Mark Kampe UCLA-ATS
+       modified 4/13/76 by S. F. Holmgren for Illinois version
+       modified 6/30/76 by S. F. Holmgren to call getmbox
+       modified 10/18/76 by J. S. Kravitz to improve net mail header
+       chown removed by R. Balocca @ CAC, Sunday 1977 February 20
+       getline removed and limit on line length removed by using
+       getch and putch added by R. Balocca @ CAC, 1977 March 8 Tuesday
+       Fixed oversight in above (forgot to translate <crlf> to <lf>)
+               1977 March 10 Thursday by Rick Balocca @ CAC
+       Added openmail & closemail, added logging, and fixed several
+               bugs on or about 12/21/79 by Eric Allman, UCB/INGRES.
+       Changed to always accept mail -- bad mail will be sent back --
+               1/9/80 by Eric Allman, UCB/INGRES.
+       Don't print out 350 enter mail or 256 mail accepted messages --
+               sendmail will do that.  8/19/81 Eric Allman UCB/INGRES.
+*/\f
+#define gt (c = getch())
+mail()
+{
+       register char *p;       /* general use */
+       register int c;
+       int i;
+
+       /* extern struct io_buf obuf; */
+
+       /* get to open mailbox file descriptor */
+       fflush(&fout);
+       if( (fout = openmail(arg, 0)) < 0 )
+               return;
+
+       for(;;)                         /* while no error or <crlf>.<crlf> */
+       {
+               /* we are at beginning of line */
+
+               if(gt=='.')                     /*"."*/
+               {
+                       if(gt=='\r')                    /*".\r"*/
+                       {
+                               if(gt=='\n')                    /*".\r\n"*/
+                               {
+                                       /* end of message */
+                                       break;
+                               }
+                               else
+                               {                               /*".\r"c*/
+                                       putch('.');
+                                       putch('\r');
+                               }
+                       }
+                       else                            /*"."c"*/
+                               putch('.');
+               }
+                                                               /*"-"*/
+                                       /* c */
+               for(;;)
+               {
+                       for(; c != '\r'; gt)
+                       {
+                               if( c < 0 )
+                               {
+                                       fflush(&fout);
+                                       write(fout, "\n***** Sender aborted connection *****\n", 39);
+                                       goto out;
+                               }
+                               else
+                                       putch(c);
+                       }
+       
+                                               /*"\r"*/
+                       if( gt == '\n' )
+                       {                       /*"\r\n"*/
+crlf:
+                               putch('\n');
+                               break;
+                       }
+                       else
+                       {                       /*"\r"c*/
+crc:
+                               putch('\r');
+                               if(c=='\0')
+                                       gt;     /* "\r\0" */
+                                               /* is arpa escape for "\r" */
+                       }
+               }
+       }
+
+out:
+       fflush(&fout);
+       closemail(fout);
+}
+
+\f/*
+Name:
+       datamail
+
+Function:
+       handle the MLFL command
+
+Algorithm:
+       fork
+               make sure we have a valid user
+                       say bad user and exit
+               send sock command
+               open data connection
+               get open mailbox file descriptor
+               call rcvdata to receive mail
+
+Parameters:
+       username in arg
+
+Returns:
+       nothing
+
+Globals:
+       arg
+
+Calls:
+       fork (sys)
+       strmove
+       netreply
+       sendsock
+       dataconnection
+       getmbox
+       rcvdata
+       printf (sys)
+       time (sys)
+
+Called by:
+       main thru command array 
+
+History:
+       initial coding 4/13/76 by S. F. Holmgren
+       modified 10/18/76 by J. S. Kravitz to put net mail header
+       chown removed by R. Balocca @ CAC, Sunday 1977 February 20
+*/\f
+datamail()
+{
+       register netdata;
+       /* register mboxfid; */
+       register int i;
+
+       i = fork();
+       if (i < 0)
+       {
+               netreply("455 Mail server temporarily unavailable\r\n");
+               return;
+       }
+       else if (i == 0)
+       {
+               fflush(&fout);
+               if ((fout = openmail(arg, 1)) < 0)
+                       exit(3);
+
+               /* send sock command */
+               sendsock( U4 );
+
+               /* open data connection */
+               netdata = dataconnection( U4 );
+
+               /* say its ok to proceed */
+               numreply( NUM250 );
+
+               /* get data from net connection and copy to mail file */
+               /* rcvdata( netdata,mboxfid ); */
+               if (rcvdata(netdata, fout) < 0)
+                       exit(1);
+
+               /* close the mail, see if ok; if so say ok */
+               fflush(&fout);
+               closemail(fout);
+
+               exit( 0 );
+       }
+}
+\f/*
+**  OPENMAIL -- Open a channel to the mail server
+**
+**     Gets the mail server started up ready to handle our
+**     mail.
+**
+**     Algorithm:
+**             See if the user is specified.
+**                     If not, send to user "root".
+**             See if the user exists.
+**                     If not, signal error 450 and return.
+**             Fork.
+**             Create a pipe
+**                     Signal "unavailable" and exit on failure.
+**             Fork.
+**                     Signal "unavailable" and exit on failure
+**                     In child:
+**                             Call mailer: /etc/delivermail is preferred.
+**                     In parent:
+**                             Avoid pipe signals in case delivermail dies.
+**                             Save the childs pid.
+**                             Return file descriptor.
+**
+**     Notes:
+**             The check to see if the user actually exists should
+**             go away so that we can do real mail forwarding.
+**
+**     Parameters:
+**             who -- the user to send the mail to.
+**             mode -- 0 -- called from mail
+**                     1 -- called from mlfl
+**
+**     Returns:
+**             File descriptor to send mail to.
+**             -1 on failure.
+**
+**     Side Effects:
+**             Forks /etc/delivermail or /bin/mail or /usr/bin/mail.
+**             Becomes "network" in the child.
+**
+**     Requires:
+**             strmove
+**             getuser
+**             netreply
+**             pipe (sys)
+**             fork (sys)
+**             close (sys)
+**             dup (sys)
+**             execl (sys)
+**             signal (sys)
+**             exit (sys)
+**
+**     Called By:
+**             mail
+**             datamail
+**
+**     History:
+**             1/9/80 -- Added 050 & 455 reply messages if execl's
+**                     fail.  Eric Allman UCB/INGRES.
+**             11/26/79 -- Modified to map upper case to lower
+**                     case.  Eric Allman UCB/INGRES.
+**             11/10/79 -- Written by Eric Allman UCB/INGRES
+**             3/6/80 -- Dropped case mapping; delivermail does
+**                     that now.  EPA UCB/INGRES.
+**             8/19/81 -- Added "mode" parameter; call sendmail
+**                     instead of delivermail.  EPA
+*/
+
+int Mail_pid;
+char *Mail_user;
+
+openmail(who, mode)
+       char *who;
+       int mode;
+{
+       register char *w;
+       register int i;
+       int pvect[2];
+       register char *p;
+
+       w = who;
+       if (w == 0)
+               w = "root";
+       Mail_user = w;
+
+       /* see if the user exists */
+       strmove(w, username);
+
+       /* try to get a pipe to the mailer */
+       if (pipe(pvect) < 0)
+       {
+         unavailable:
+               netreply("455 Mail server temporarily unavailable\r\n");
+               return (-1);
+       }
+
+       /* fork */
+       i = fork();
+       if (i < 0)
+       {
+               /* failure */
+               close(pvect[0]);
+               close(pvect[1]);
+               goto unavailable;
+       }
+       else if (i == 0)
+       {
+               /* child */
+               close(pvect[1]);
+               close(0);
+               dup(pvect[0]);
+               close(pvect[0]);
+               setuid(NETUID);
+
+               /* try to call something to deliver the mail */
+               execl("/etc/sendmail", "sendmail", "-v", mode == 1 ? "-af" : "-am", w, 0);
+
+               /* doesn't seem to be anything around */
+               netreply("455 Mail server unavailable\r\n");
+               exit(3);
+       }
+
+       /* else parent */
+       signal(SIGPIPE, SIG_IGN);
+       Mail_pid = i;
+       close(pvect[0]);
+       return (pvect[1]);
+}
+\f/*
+**  CLOSEMAIL -- Close the mail file and get actual status
+**
+**     The mail file is closed.
+**
+**     Algorithm:
+**             Wait for the mailer to die.
+**                     If it wasn't there, be non-comittal.
+**             If it died a violent death, give error.
+**
+**     Parameters:
+**             fd -- the file descriptor of the mail file.
+**
+**     Returns:
+**             none.
+**
+**     Side Effects:
+**             mailer is soaked up.
+**
+**     Requires:
+**             close (sys)
+**             wait (sys)
+**
+**     Called By:
+**             mail
+**             datamail
+**
+**     History:
+**             1/9/80 -- Changed to not check for errors in mailing,
+**                     since these will be mailed back.
+**             11/10/79 -- Written by Eric Allman UCB/INGRES.
+*/
+
+closemail(fd)
+       int fd;
+{
+       auto int st;
+       register int i;
+
+       /* close the pipe -- mail should go away */
+       close(fd);
+
+       /* wait for its body */
+       while ((i = wait(&st)) != Mail_pid)
+       {
+               if (i < 0)
+               {
+                       /* how did this happen? */
+                       logmsg(LOG_ERR, "mail from host %d to %s: no child",
+                           openparams.o_frnhost & 0377, Mail_user);
+                       goto unavailable;
+               }
+       }
+
+       /* 'st' is now the status of the mailer */
+       if ((st & 0377) != 0)
+       {
+               logmsg(LOG_ERR, "mail from host %d to %s: status %o",
+                   openparams.o_frnhost & 0377, Mail_user, st);
+unavailable:
+               netreply("455 Mail not delivered -- local system error\r\n");
+               return (-1);
+       }
+
+       return (0);
+}