/***********************************************************************
 * lmail.c --  Local mail delivery agent
 *
 * This is a very simple program which is called by sendmail to
 * deliver mail on a local system.  It does not handle file locking,
 * but works well on an end-node workstation.  Tested under 386/486
 * Unix (3.2, 4.0, Linux).
 *
 * Written by Richard Braun, November 1992    richb@rkbhome.jti.com
 *
 * Distributed under terms of Gnu General Public License, version 2.
 ***********************************************************************/

#include <stdio.h>
#include <string.h>
#include <sysexits.h>
   /* sysexits.h, if not found on your system, is in sendmail/support */
   /* directory.                                                      */

#define SPOOLDIR "/usr/spool/mail"

int main (argc, argv)
int argc;
char **argv;
{
int i;
char fromuser[80];
char *touser;
char mailfile[100];
FILE *fp, *fp2;
char line[200];
char uname[50];
char tmpname[50];
int uidlist[200];
char *progname;
int  argnum;
int  lineno;

   /*
    * Get program name for error message output
    */
   progname = strrchr (argv[0], '/');
   if (progname == NULL)
     progname = argv[0];
   else
     progname++;
   argv++;
   argc--;

   /*
    * Look for (and ignore) a -f option
    */

   if (argc >= 3 && !strcmp (argv[0], "-f")) {
       strcpy (fromuser, argv[1]);
       argc -= 2;
       argv += 2;
   }
   if (argc < 1) {
       fprintf (stderr, "%s: usage: [-f fromuser] user\n", progname);
       exit(EX_USAGE);
   }

   /*
    * Copy stdin to a temp file
    */
   sprintf (tmpname, "/tmp/lmail%d", getpid());
   if ((fp = fopen (tmpname, "w")) == NULL) {
       fprintf (stderr, "%s: error creating tmp file\n", progname);
       exit(EX_IOERR);
   }
   lineno = 0;
   while (fgets (line, sizeof line, stdin) != NULL) {
       /*
	* After first line, translate leading "From" into ">From"
	*/
       if (lineno++) {
	   if (!strncmp (line, "From ", 5))
	     fputc ('>', fp);
       }
       if (fputs (line, fp) != strlen (line)) {
	   fprintf (stderr, "%s: write failed to temp file %s\n", progname,
		    tmpname);
	   exit(EX_IOERR);
       }
   }
   fclose (fp);

   /*
    * Validate the recipient list
    */
   for (argnum = 0; argnum < argc; argnum++) {
       touser = argv[argnum];
       if ((fp = fopen("/etc/passwd", "r")) == NULL) {
	   fprintf (stderr, "%s: can't open password file\n", progname);
	   exit(EX_OSFILE);
       }
       uname[0] = '\0';
       while (fgets (line, sizeof line, fp) != NULL) {
	   char *ptr;
	   ptr = strtok (line, ":");
	   strcpy (uname, ptr);
	   ptr = strtok (NULL, ":");
	   ptr = strtok (NULL, ":");
	   /*
	    * Save the UIDs; we'll need them later to set the file
	    * ownership
	    */
	   sscanf (ptr, "%d", &uidlist[argnum]);
	   if (!strcmp (uname, touser))
	     break;
       }
       fclose (fp);
       if (!strlen(touser) || strcmp (touser, uname) != 0) {
	   fprintf (stderr, "%s: user %s does not exist\n", progname, touser);
	   exit(EX_NOUSER);
       }
   }

   /*
    * Append mail into each recipient's spool file
    */
   argnum = 0;
   while (argc--) {
       touser = *argv++;
       sprintf (mailfile, "%s/%s", SPOOLDIR, touser);
       if ((fp = fopen (mailfile, "a")) == NULL) {
	   fprintf (stderr, "%s: could not open mail file %s\n", progname, mailfile);
	   exit(EX_CANTCREAT);
       }
       if ((fp2 = fopen (tmpname, "r")) == NULL) {
	   fprintf (stderr, "%s: error finding tmp file\n", progname);
	   exit(EX_IOERR);
       }
       while ((fgets (line, sizeof line, fp2)) != NULL) {
	   if (fputs (line, fp) != strlen (line)) {
	       fprintf (stderr, "%s: write failed to mail file %s\n", progname,
			mailfile);
	       exit(EX_IOERR);
	   }
       }
       fclose (fp);
       fclose (fp2);
       chmod (mailfile, 0600);
       chown (mailfile, uidlist[argnum++], 6);
   }
   unlink(tmpname);
   exit(EX_OK);
}
