SRI-NOSC/mmdf/poboxsnd.c

Compare this file to the similar file:
Show the results in this format:

#
#include "mailer.h"

extern struct adr  adr;
extern int timeout ();
extern int errno;
extern char eosstr[];

struct iobuf usribuf;
int savenv;
int     domsg;
int     uid;
int     gid;
int     infd;                     /* handle on source text        */
char *sender;
char   *txtname;
char   *userdir;
char    errline[100];

main (argc, argv)
int     argc;
char   *argv[];
/* if run in user mode:                                              */
/* [name,] infd, namebuf.fildes, resbuf.fildes, logbuf.files,txtfile */
{                       /* pass msgs thru standard i/o          */
    int result;

    signal (SIGCLK, &timeout);
    initcom (argc, argv);

    if ((result = getusr ()) < OK ||
	(result = privpgm (argc, argv)) != TRYMAIL)
	exit (result);
snsbstrt:
    for EVER
    {                          /* iterate thru mail to be sent      */
	switch (getname())
	{                      /* 1st addr has mode info   */
	 case NOTOK:           /* no more messages         */
	 case DONE:            /* end of adr list          */
	    exit (OK);
	 case OK:
	    break;
	 default:               /* illegal getname return       */
	    exit (NOTOK);
	}
	domsg = (adr.adr_hand == 'w');
	sbmitinit ();
	for EVER
	{
	    procadr ();
	    result = getresp ();
	    putresp ((result == OK) ? T_OK : result, errline);
	    switch (getname())
	    {
	     case DONE:                     /* null => end of adrlist   */
		write (1, "!\n", 2);
		switch (msgxfer ())
		{case NOTOK:
		    putresp (NOTOK, "error reading message file");
		    goto snsbstrt;
		 case HOSTDEAD:
		    putresp (HOSTDEAD, "it done disappeared");
		    exit (HOSTDEAD);
		 case OK:
		    write (1, "\0", 1); /* signal eof   */
		    result = getresp ();
		    if (result == DONE)
			result = OK;
		    putresp (result, (result == OK) ? 0 : errline);
		    break;                  /* real validation of xfer  */
		 default:
		    exit (NOTOK);
		}
		if ((result = newfile ()) != OK)
		    exit (result);      /* must be "!=" and not "<"     */
		goto snsbstrt;
	     case OK:
		continue;
	     default:
	     case NOTOK:
		exit (NOTOK);               /* whoops                   */
	    }
	    break;
	}
    }
}
/* *************  PRIVATE PROTOCOL HANDLING  ************************ */

getusr ()
{
    char pwline[200];
    register char  *p,
		   *q;

    if (getpw (getuid () & 0377, &pwline) == -1)
	return (NOTOK);
    for (q= pwline; *q++ != ':'; );      /* user name    */
    while (*q++ != ':');                 /* skip a field */
    uid = atoi (q);                      /* get uid      */
    while (*q++ != ':');                 /* skip over it */
    gid = atoi (q);                      /* get gid      */
    while (*q++ != ':');                 /* skip over it]*/
    for (p = q; *p != ':' && *p != '\n'; p++);
    *p = '\0';                           /* login directory     */
    userdir = strdup (q);
    return (OK);
}

privpgm ()
{
    extern char userpo[];
    register char  *p,
		   *q;
    register int    result;
    int filesiz;
    int     i;
    int     temp;
    int     status;
    char    *userprog;
    int     f;

    userprog = strcat (userdir, userpo);
    if (access (userprog, 1))      /* Is it executable? */
    {
	free (userprog);
	return (TRYMAIL);
    }
    log("[POBOX]");
    switch (f = fork ())
    {
     case 0:
	if (infd != 0)
	{
	    close (0);          /* NO!  */
	    dup (infd);         /*  "   */
	    close (infd);       /*  "   */
	}
	setgid (gid);
	setuid (uid);
	execl (userprog, userpo, adr.adr_delv, txtname, sender, 0);
	error ("can't exec program");
	exit (TRYAGN);
     case -1:
	error ("can't fork");
	free (userprog);
	return (TRYAGN);
    }
    free (userprog);
    if (envsave (&savenv))
    {
	filesiz = infdsize ();
    /*  alarm (filesiz * 10 + 30);      */
	while ((temp = waita (&status)) != f && temp != -1);
	alarm (0);
    }
    else
    {
	result = TIMEOUT;
	error ("user program timed out");
	kill (f, 9);
    }
    if (temp == -1)		  /* This shouldn't happen */
	result = TRYAGN;
    else
    {
	result = (status >> 8) & 0377;
	if (result < MINSTAT || result > MAXSTAT)
	    result = HOSTERR;
    }
    if (result < OK)
  /*    msg ("delivered")*/;
    return (result);
}

getresp ()
{
    char linebuf[LINESIZE];
    int respenv;
    register int     c;
    register char resp;

    respenv = savenv;
    if (!envsave (&savenv))
	return (TIMEOUT);

/*  alarm (30); */
    if ((c = gcread (&usribuf, &linebuf, sizeof linebuf - 1, "\000\n\377"))
	    <= 0)
	return (HOSTDEAD);
    alarm (0);
    savenv = respenv;
    linebuf[0] =- 060;       /* convert it to binary           */
    linebuf[c] = '\0';
    if (linebuf[0] < OK)
	strcpy (&linebuf[1], errline);
    return (linebuf[0]);
}

sbmitinit ()
{
    int result;
    register char *p;

    p = nmultcat ("     ",
		    (adr.adr_delv == DELMAIL) ? "m"
		    : (adr.adr_delv == DELTTY)   ? "a"
		    : "s",
/*          "fForwarded by Rand-Unix to U of Delaware", */
/*          "\n", 0);                                   */
/*  if ((result = write (1, p, strlen (p))) != -1)      */
/*  {                                                   */
/*      free (p);                                       */
/*      p = nmultcat (sender, " at Rand-Unix", "\n", 0);*/
		  sender, /*" at Rand-Unix", */"\n", 0);
	result = write (1, p, strlen (p));
/*  }   */
    free (p);
    return ((result == -1) ? NOTOK : OK);
}
/* *************  ADDRESS & MESSAGE PROCESSING  ********************* */

procadr ()
{                               /* specify addr to remote host */
    char linebuf[LINESIZE];
    register char *p;

/* BUG!!  there is a lie built in, currently, since the address
 *        list is sent before the message.  An OK for an address
 *        does not mean that a message for it has been adquately
 *        queued.  If we go down before completing xmission of
 *        the ENTIRE list AND text, some addrs, at the source,
 *        will show a completed status, when they haven't really been.
 */
			       /* already in arpanet form           */
			       /* build submit adr spec line        */
/*    for (p = adr.adr_name; *p++ != ' '; ); DN: send both host and username */
      p = adr.adr_name; /* DN: send both host and user names */
    strcpy (p, linebuf);
    p = linebuf + strlen(linebuf);
/*  printx ("%s: ", linebuf);   */
    if (adr.adr_name[strlen (adr.adr_name) - 1] != '\n')
	*p++ = '\n';
    *p = '\0';

    write (1, linebuf, strlen (linebuf));
			    /* send the address             */
    return (OK);
}

msgxfer ()
{
    int count;
    char buf[512];
    char lastchar;

    for (seek (infd, 0, 0); (count = read (infd, buf, sizeof buf)) > 0;
		lastchar = buf[count - 1])
	if (write (1, buf, count) < 0)
	{
	    error ("error writing to mailbox");
	    return (TRYAGN);
	}
    if (lastchar != '\n')
	write (1, "\n", 1);
    return (OK);
}