SRI-NOSC/mh/send.c

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

#include "mh.h";
#include "iobuf.h"
#include "stat.h"

#define DEBUG 1			  /* Comment out normally */
#define TIMJUL  1
#define TIMSECS 2
#define TIMREG  3

/* Include a -msgid switch to .mh_defs to cause a
 * Message-Id component to be added to outgoing mail.
 */

char   *anoyes[],		  /* Std no/yes gans array        */
        draft[],
	locname[],		/* local host name */
	sbmitloc[],		/* location (pathname) of submit process */
	sbmitnam[];		/* name of submit process */
struct swit switches[]
{
    "debug", -1,		  /* 0 */
    "draft", 0,			  /* 1 */
    "format", 0,		  /* 2 */
    "noformat", 0,		  /* 3 */
    "msgid", 0,			  /* 4 */
    "nomsgid", 0,		  /* 5 */
    "verbose", 1,		  /* 6 *//* DBG dhc */
    "noverbose", 0,		  /* 7 */
    "help", 4,			  /* 8 */
    0, 0
};
struct iobuf    in,
                pin,
                pout,
                fout,
                fccout;
int     errno;
int     format 0;		  /* re-formatting is the default */
int     sbmitfd[2];
int     sbchild;

char   *logn,
       *parptr,
       *nmsg,
        fccfile[256],
        sberrline[256];

main (argc, argv)
char   *argv[];
{
    int     debug;
    register char  *cp;
    register int    state;
    char   *to,
           *cc,
           *bcc,
           *dist_to,
           *dist_cc,
           *dist_bcc;
    char   *tolist,
           *cclist,
           *adrlist,
           *sender,
	*fieldptr,
           *fcc,
           *dist_fcc;
    char    msg[128];
    char    name[NAMESZ],
            field[512];
    int     specfld,
            dist,
            fcconly;
    int     from,
            loc,
            net,
            verbose,
            msgid;
    char   *ap,
	inp;
    char   *arguments[50],
          **argp;

    fout.b_fildes = dup (1);
    msgid = from = loc = net = to = cc = bcc = dist = fcc = dist_fcc =
	dist_to = dist_cc = dist_bcc = fcconly = debug = 0;

    loc = net = 1;  /* DBG during testing of new submit */

    state = FLD;
    msg[0] = 0;
	ap = cp = argv[0];
	while(*cp)
		if(*cp++ == '/')
			ap = cp;
	inp = ap;
    copyip (argv + 1, arguments);
    argp = arguments;
    while (cp = *argp++)
    {
	if (*cp == '-')
	    switch (smatch (++cp, switches))
	    {
		case -2: 
		    ambigsw (cp, switches);
				  /* ambiguous */
		    leave ("Illegal switch setting: \"%s\"", --cp);
				  /* unknown */
		case -1: 
		    leave ("-%s unknown", cp);
		case 0: 
		    verbose++;
		    debug++;
		    continue;     /* -debug */
		case 1: 
		    copy (m_maildir (draft), msg);
		    continue;     /* -draft  */
		case 2: 
/* disabled for now format = 1;                         */
		    continue;     /* -format */
		case 3: 
		    format = 0;
		    continue;     /* -noformat */
		case 4: 
		    msgid = 1;
		    continue;     /* -msgid */
		case 5: 
		    msgid = 0;
		    continue;     /* -nomsgid */
		case 6: 
		    loc = 1;
		    net = 1;
		    continue;     /* -verbose */
		case 7: 
		    loc = 0;
		    net = 0;
		    continue;     /* -noverbose */
		case 8: 
  		  help (concat( inp, " [file] [switches]", 0),
			    switches);
		    leave (0);
	    }
	if (msg[0])
	    leave ("Only one message at a time!");
	else
	    copy (cp, msg);
    }
    if (msg[0] == 0)
    {
	copy (m_maildir (draft), msg);
	if (stat (msg, &field) == -1)
	{
	    printf ("Draft file: %s doesn't exist.\n", msg);
	    flush ();
	    exit (1);
	}
	/* cp = concat ("Use \"", msg, "\"? ", 0);
	if (!gans (cp, anoyes))
	    exit (0); */
    }
    if (fopen (msg, &in) < 0)
	leave ("Can't open \"%s\" for reading.", msg);

    state = FLD;

    if (!loc && !net)
        printf ("Message being processed...\n");
    flush ();
    for (;;)
	switch (state = m_getfld (state, name, field, sizeof field, &in))
	{

	    case FLD: 
	    case FLDEOF: 
	    case FLDPLUS: 
		if (!dist && field[0] != 'n' &&  uleq (name, "to"))
		    to = adrlist = add (field, adrlist);
		else
		    if (!dist && field[0] != 'n' && uleq (name, "cc"))
			cc = adrlist = add (field, adrlist);
		    else
			if (!dist && uleq (name, "bcc"))
			    adrlist = add (field, adrlist);
			else
			    if (!dist && uleq (name, "fcc"))
				fcc = add (field, fcc);
			    else
				if (field[0] != 'n' && uleq (name, "distribute-to"))
				{
				    dist++;
				  /* use presence of field as flag */
				    to = adrlist = add (field, adrlist);
				}
				else
				    if (field[0] != 'n' && uleq (name, "distribute-cc"))
					cc = adrlist = add (field, adrlist);
				    else
					if (field[0] != 'n' && uleq (name, "distribute-bcc"))
					    adrlist = add (field, adrlist);
					else
					    if (uleq (name, "distribute-fcc"))
						dist_fcc = add (field, dist_fcc);
					    else
						if (uleq (name, "from"))
						    from++;

		if (state != FLDEOF)
		    continue;
	    case BODY: 
	    case BODYEOF: 
		goto done;

	    default: 
		leave ("getfld returned %d", state);
	}
done: 
    if (dist)
    {
/*      to = dist_to;                                                   */
/*      cc = dist_cc;                                                   */
/*      bcc = dist_bcc;                                                 */
	fcc = dist_fcc;
    }
    if (!(to || cc))
	if (!fcc)
	    leave ("Message %s has no addresses!!", msg);
	else
	    fcconly++;
     /****/ pin.b_fildes = dup (2);
/**** pout.b_fildes = 3;*/

/*  if ((to && parse (to, 'c')) ||                                      */
/*      (cc && parse (cc, 'c')) ||                                      */
/*      (bcc && parse (bcc, 'c'))                                       */
/*          leavit ();                                                  */

/*  parptr = adrlist;                                                   */
/*  compress ();                                                        */
/*  adrlist = parptr;                                                   */
    parptr = 0;
    if (verbose)
    {
	printf ("Address List:\n%s", adrlist);
	flush ();
    }

/*  if (to && parse (to, 'r', dist ? "Distribute-To: " : "To: "))       */
/*          leave (0);                                                  */
/*  tolist = parptr;                                                    */
/*  parptr = 0;                                                         */
/*  if (cc && parse (cc, 'r', dist ? "Distribute-cc: " : "cc: "))       */
/*          leave (0);                                                  */
/*  cclist = parptr;                                                    */
/*  parptr = 0;                                                         */
/*                                                                      */
/*  if (verbose)                                                        */
/*  {                                                                   */
/*      if (tolist)                                                     */
/*          printf (tolist);                                            */
/*      if (cclist)                                                     */
/*          printf (cclist);                                            */
/*      flush ();                                                       */
/*  }                                                                   */
    if (fcc)
    {
	if (*fcc == ' ')
	    fcc++;
	for (cp = fcc; *cp && *cp != '\n'; cp++);
	*cp = 0;
	if (debug)
	    printf ("fcc: \"%s\"\n", fcc);
	flush ();
	if ((fccout.b_fildes = filemsg (fcc)) == -1)
	    leave ("Problem beginning fcc message transfer");
    }

/*  if (parse (field, 'r', dist ? "Distributed-By: "                    */
/*               : (from ? "Sender: " : "From: ")))                     */
/*      leave (0);                                                      */

    sender = add ((dist) ? "Distributed-By: "
	    : (from) ? "Sender: "
	    : "From: ", sender);
fieldptr = copy ((logn = getlogn (getruid ())), field);
fieldptr = copy (" at ", fieldptr);
fieldptr = copy ( locname, fieldptr);
copy ( "\n", fieldptr);
    sender = add (field, sender);
/*    parptr = 0;                                                       */
    seek (in.b_fildes, 0, 0);
/* ***   INVOKE SUBMIT, AT LAST   ***  */
    ap = arguments;
    *ap++ = '-';		  /* indicate a switch sequence               
				  */
    /* *ap++ = 'd';	/*DBG have submit output messages */
    *ap++ = 'm';		  /* mail, not screen-notice, yet             
				  */
/*  cputc ('s', &pout); */
/* ******* During initial testing, mail always sent immediately, ****** */
/*         so that users can verify delivery...                         */
/*         Can't trust new software these days...                ****** */

/*  if (loc)                    */
	*ap++ = 'l';              /* send local mail now        */
    if (net)
	*ap++ = 'n';              /* send net mail now          */
    if (net || loc)
	*ap++ = 'w';              /* user will watch deliveries */

/* *******  * * * * * * * * * * * * * * * * * * * * * * * * * *  ****** */

    *ap++ = 'r';		  /* return messages go to sender             
				  */
    *ap = '\0';

    if (debug)
	pout.b_fildes = 1;	  /* Send msg to std output for debugging */
    else
	if (fcconly)
	    pout.b_fildes = 0;    /* Flush send output if only an fcc */
	else
	{
	    if ((sbchild = sbmitinit (arguments, sbmitfd)) == -1)
		leave ("Unable to invoke submit");
	    pout.b_fildes = sbmitfd[1];
	}

    puts (adrlist, &pout);
    puts ("!\n", &pout);	  /* end the address list                 */
    puts2 (sender, &pout);
    puts2 (dist ? "Distribution-Date: " : "Date: ", &pout);
    puts2 (cnvtdate (TIMREG), &pout);
    puts2 ("\n", &pout);
    if (msgid)
    {
	puts2 (dist ? "Distribution-ID: " : "Message-ID: ", &pout);
	puts2 ("<", &pout);
	puts2 (cnvtdate (TIMJUL), &pout);
	puts2 (".", &pout);
	puts2 (locv (0, getpid ()), &pout);
	puts2 (" at ", &pout);
	puts2 (locname, &pout);
	puts2 ("\n", &pout);
    }
    seek (in.b_fildes, 0, 0);
    in.b_nleft = in.b_nextp = 0;
    state = FLD;
    for (;;)
	switch (state = m_getfld (state, name, field, sizeof field, &in))
	{
	    case FLD: 
	    case FLDEOF: 
	    case FLDPLUS: 
		specfld = 0;
		if (format && uleq (name, dist ? "distribute-to" : "to"))
		{
		    specfld++;
		    if (tolist)
			puts2 (tolist, &pout);
		}
		else
		    if (format && uleq (name, dist ? "distribute-cc" : "cc"))
		    {
			specfld++;
			if (cclist)
			    puts2 (cclist, &pout);
		    }
		    else
			if (uleq (name, dist ? "distribute-bcc" : "bcc") ||
				uleq (name, dist ? "distributed-by" : "sender") ||
				uleq (name, dist ? "distribution-date" : "date") ||
				uleq (name, dist ? "distribution-id" : "message-id") ||
				uleq (name, dist ? "distribution-fcc" : "fcc"))
			    specfld++;
				  /* Ignore these if present */
			else
			{
			    puts2 (name, &pout);
			    puts2 (":", &pout);
			    puts2 (field, &pout);
			}
		while (state == FLDPLUS)
		{		  /* read rest of field */
		    state = m_getfld (state, name, field, sizeof field, &in);
		    if (specfld)
			continue;
/*                  puts2(name, &pout); puts2(":", &pout);  */
		    puts2 (field, &pout);
		}
		if (state == FLDEOF)
		    goto endit;
		continue;
	    case BODY: 
	    case BODYEOF: 
		if (field[0])
		{
		    puts2 ("\n", &pout);
		    puts2 (field, &pout);
		}

		while (state == BODY)
		{
		    state = m_getfld (state, name, field, sizeof field, &in);
		    puts2 (field, &pout);
		}
		if (state == BODYEOF)
		    goto endit;
	    default: 
		leave ("Error from getfld=%d", state);
	}

endit: 
    errno = 0;
    if (pout.b_fildes)
	if (fflush (&pout) <  0 || errno != 0)
	    leave ("Problem writing data to Submit.");
    if (fccout.b_fildes)
    {
	fflush (&fccout);
	close (fccout.b_fildes);
    }
    if (!debug && !fcconly)
    {
/*      if ((state = read (2, &field, sizeof field)) != 1 || field[0])  */
	if (loc || net)
	{
	    printf ("Delivery being attempted...\n");
	    flush ();
	}
	if (sbresp (&sbmitfd) != 0)
	    leave ("Mail submission program ended abnormally");
    }
    if (fccout.b_fildes)
	printf ("Filed: %s:%s\n", fcc, nmsg);
    if (!debug)
    {
	if (!fcconly)
	{
	    printf ("Message processed.\n");
/*	    printf ("Message %s processed.\n", msg);*/
	    flush ();
	}
	cp = copy (msg, field);
				  /*  for(cp = field; *cp++; ) ;  */
	cp[1] = 0;
	do
	    *cp = cp[-1];
	while (--cp >= field && *cp != '/');
	*++cp = ',';		  /* New backup convention */
	unlink (field);
	if (link (msg, field) == -1 || unlink (msg) == -1)
	    printf ("Can't rename %s to %s\n", msg, field);
    }
    m_update ();
/*    childend ();  */
    flush ();
    exit (0);
}

leave (form, a1, a2, a3)
char   *form,
       *a1,
       *a2,
       *a3;
{
    if (form != 0)
    {
	printf (form, a1, a2, a3);
        putchar ('\n');
    }
if (sbchild != 0)
    kill (sbchild, 9);
    printf ("[ Message NOT Delivered! ]\n");
    if (fccout.b_fildes)
	unlink (fccfile);
    m_update ();
    flush ();
    exit (1);
}

parse (ptr, type, fldname)
char   *fldname;
{
    register int    i;
    register int    l;
    char    line[128];

    errno = 0;
    putc (type, &pout);
    puts ("\n", &pout);
    puts (ptr, &pout);
    if (fflush (&pout) < 0 || errno != 0)
	leave ("Problem sending data to Submit.");
    write (pout.b_fildes, "", 1);
    l = 0;

    while ((i = getl (&pin, line, (sizeof line) - 1)) > 0)
    {
	line[i] = 0;
	if (line[0] == 0)
	{
	    if (type == 'r')
	    {
		if (l > 0)
		    parptr = add ("\n", parptr);
	    }
	    return (0);
	}
	else
	    if (line[0] == '?')
	    {
		printf ("Submit returned: %s", line);
		return (1);
	    }
	if (type == 'r')
	{
	    line[--i] = 0;
	    if (l + i > 70)
	    {
		parptr = add ("\n", parptr);
		l = 0;
	    }
	    if (l == 0)
	    {
		parptr = add (fldname, parptr);
		l =+ length (fldname);
	    }
	    else
	    {
		parptr = add (", ", parptr);
		l =+ 2;
	    }
	    parptr = add (line + 1, parptr);
	    l =+ i;
	}
	else
	    parptr = add (line, parptr);
    }
    printf ("Error from Submit.\n");
    return (1);
}

cnvtdate (flag)
int     flag;			  /* date format option value     */
{
    static char datbuf[128];
    extern int  daylight;
    int     tvec[2];
    long int    seconds;
    register int
                   *i;
    register char
                   *p,
                   *t;

    time (tvec);
    i = localtime (tvec);
    t = ctime (tvec);
    p = datbuf;

    switch (flag)
    {
	case TIMJUL: 		  /* Julian-oriented for msg-ids  */
	    for (itoa (i[5], p); *p; p++);
	    *p++ = '.';
	    for (itoa (i[7], p); *p; p++);
	    *p++ = '.';
	    seconds = i[2];
	    seconds = i[0] + (i[1] * 60) + (seconds * 3600);
	    litoa (seconds, p);   /* seconds since midnight     */
	    break;
	case TIMREG: 		  /* RFC 733 standard time string */
	default: 		  /* "Sat, 21 Jan 76 14:30-PDT"   */
	    *p++ = t[0];
	    *p++ = t[1];
	    *p++ = t[2];
	    *p++ = ',';
	    *p++ = ' ';
	    *p++ = t[8];	  /* day of month                 */
	    *p++ = t[9];
	    *p++ = ' ';
	    *p++ = t[4];	  /* month abbreviation eg: "JAN" */
	    *p++ = t[5];
	    *p++ = t[6];
	    *p++ = ' ';
	    *p++ = t[22];	  /* year eg: "76"              */
	    *p++ = t[23];
	    *p++ = ' ';
	    *p++ = t[11];	  /* hours & minutes eg: "14:30" */
	    *p++ = t[12];
	    *p++ = ':';
	    *p++ = t[14];
	    *p++ = t[15];
	    *p++ = '-';
	    *p++ = 'P';		  /* time zone eg: "PDT"          */
	    *p++ = (i[8]) ? 'D' : 'S';
	    *p++ = 'T';
	    *p++ = '\000';
    }
    free (i);
    free (t);
    return (datbuf);
}

getl (iob, buf, size)
{
    register char  *cp;
    register int    cnt,
                    c;

    for (cp = buf, cnt = size; (c = getc (iob)) >= 0;)
    {
	*cp++ = c;
	--cnt;
	switch (c)
	{
	    case '\0': 
	    case '\n': 
		break;
	    default: 
		continue;
	}
	break;
    }
    return (size - cnt);
}

compress ()
{
    register char  *f1,
                   *f2,
                   *f3;

#ifdef DEBUG
    printf ("compress:\n%s-----\n", parptr);
#endif
    for (f1 = parptr; *f1;)
    {
	for (f2 = f1; *f2++ != '\n';);
	while (*f2)
	{
	    if (eqqq (f1, f2))
	    {
		for (f3 = f2; *f3++ != '\n';);
		copy (f3, f2);
	    }
	    else
		while (*f2++ != '\n');
	}
	while (*f1++ != '\n');
    }
}

eqqq (s1, s2)
{
    register char  *c1,
                   *c2;

    c1 = s1;
    c2 = s2;
    while (*c1 != '\n' && *c2 != '\n')
	if (*c1++ != *c2++)
	    return (0);
    return (*c1 == *c2);
}
filemsg (folder)
char   *folder;
{
    register int    i;
    register char  *fp;
    struct inode    stbuf;
    struct msgs *mp;

    fp = m_maildir (folder);
    if (stat (fp, &stbuf) < 0)
    {
/*	nmsg = concat ("Create folder \"",
		fp, "\"? ", 0);
	if (!gans (nmsg, anoyes))
	    return (-1); */
	if (!makedir (fp))
	{
	    printf ("Can't create folder.\n");
	    return (-1);
	}
    }
    if (chdir (fp) < 0)
    {
	perror (concat ("Can't chdir to ", fp, 0));
	return (-1);
    }
    if (!(mp = m_gmsg ()))
    {
	printf ("Can't read folder %s\n", folder);
	return (-1);
    }
    nmsg = m_name (mp -> hghmsg + 1);
    copy (nmsg, copy ("/", copy (m_maildir (fp), fccfile)));
    if ((i = creat (fccfile, m_gmprot ())) == -1)
	printf ("Can't create %s\n", fccfile);
    return (i);
}

puts2 (str, iob)
{
    puts (str, &fccout);
     errno = 0;
    puts (str, iob);
    if (fflush (iob) < 0 || errno != 0)
	leave ("Problem writing out data");
}
/* subroutines to interface to submit   */

#define CLOSEFD -1		  /* if equals fdarray[i], close (i);     */
#define PUREXEC 0		  /* simply exec over current process     */
#define FRKEXEC 1		  /* run it in lower process              */
#define SPNEXEC 2		  /* separate new process from old        */
#define FRKWAIT 1		  /* wait for FRKEXEC to complete         */
#define FRKPIGO 2		  /* Parent's signals off during FRKWAIT  */
#define FRKCIGO 4		  /* Childs signals off before execl      */
/*#define EXECR   8               ** Use execr, instead of execv          */
#define HIGHFD  16
#define NUMTRY  30

struct pstruct
{
    int     prd;
    int     pwrt;
};
int     highfd
{
    HIGHFD
};
int     regfdary[]
{
    0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};

sbmitinit (args, ioary)
char   *args;
int    *ioary;
{

    struct pstruct  sbpout;
    int     sbmitid;
    char    linebuf[256];
    char   *p;

    if (pipe (&sbpout) == -1)
	return (-1);
    regfdary[0] = sbpout.prd;
    regfdary[1] = fout.b_fildes;

    if ((sbmitid = newpgml (FRKEXEC, 0, regfdary,
		    sbmitloc, sbmitnam, args, 0)) == -1)
    {
flush ();
	close (sbpout.prd);
	close (sbpout.pwrt);
	return (-1);
    }

dbglog ("Ready to close");
    close (sbpout.prd);
    ioary[1] = sbpout.pwrt;
    return (sbmitid);
}

#ifdef COMMNET
sbmitadr (name, ioary)
char   *name;
int    *ioary;
{
    int     tmp;
    char    linebuf[256];
    char   *from,
           *to;

    for (from = name, to = linebuf; *to = *from++; to++);
    for (from = "\n"; *to++ = *from++;);
    tmp = to - &linebuf;

    if (write (ioary[1], linebuf, tmp) == -1)
	return (-1);

    return (sbresp (ioary));
}
#endif

sbresp (ioary)
int    *ioary;
{
    return (childend ());
}

newpgml (proctyp, pgmflags, fdarray, pgm, pgmparm)
int     proctyp,
        pgmflags,
        fdarray[];
char   *pgm,
       *pgmparm;
{
	int retval;
	char *parmptr;
				  /* printf ("newpgml: calling newpgmv\n"); */
    parmptr = &pgmparm;
    retval = newpgmv (proctyp, pgmflags, fdarray, pgm, parmptr);
    return (retval);
}

newpgmv (proctyp, pgmflags, fdarray, pgm, pgmparm)
int     proctyp,
        pgmflags,
        fdarray[];
char   *pgm,
       *pgmparm[];
{
    register int    tmp;
    int     tmp2;
    int     childid;
    int     tried;
    int     osig[3];

    if (proctyp != PUREXEC)
    {
				  /* printf ("This is a forking call.\n"); */
	for (tried = NUMTRY; (childid = fork ()) == -1 && tried--; sleep (1));
	if (childid == -1)
	    return (-1);
				  /* printf ("Successful fork\n"); */
	if (childid != 0)
	{			  /* parent process               */
	    if (pgmflags & FRKPIGO)
	    {			  /* disable parent signals       */
				  /* printf ("Parent to be
				     non-interruptible\n"); */
		osig[0] = signal (1, 1);
		osig[1] = signal (2, 1);
		osig[2] = signal (3, 1);
	    }
	    if ((proctyp == FRKEXEC) && (pgmflags & FRKWAIT))
	    {
				  /* printf ("Parent is to wait\n");      */
		while ((tmp = wait (&tmp2)) != childid && tmp != -1);
				  /* printf ("Parent done waiting\n");    */
		if (pgmflags & FRKPIGO)
		{
		    signal (1, osig[0]);
		    signal (2, osig[1]);
		    signal (3, osig[2]);
		}
		return (tmp2);
	    }
	    return (childid);
	}
	if (proctyp == SPNEXEC)
	{			  /* want it to be a spawn        */
				  /* printf ("This is a spawn\n");    */
	    for (tried = NUMTRY; (tmp = fork ()) < 0 && tried--;
		    sleep (1));
	    if (tmp != 0)	  /* split the grandparent from the   */
		exit (tmp < 0 ? -2 : 0);
				  /* grandchild: kill middle proc     */
	}
    }
    if (fdarray)
    {				  /* re-align fd array list           */
	fout.b_fildes = fdarray[1];
	for (tmp = 0; tmp < highfd; tmp++)
	{			  /* first do the re-positions        */
	    if (fdarray[tmp] != CLOSEFD && fdarray[tmp] != tmp)
	    {
				   dbglog ("Closing %2d\n", tmp);     
flush ();
		close (tmp);
		while ((tmp2 = dup (fdarray[tmp])) < tmp && tmp2 != -1);
		   dbglog ("Last dup'd %d into %d\n", fdarray[tmp], tmp2);     
flush ();
				  /* did we get right fd?     */
	    }
	}
	for (tmp = 0; tmp < highfd; tmp++)
	    if (fdarray[tmp] == CLOSEFD)
	    {
				   dbglog ("Closing %2d\n", tmp);     
flush ();
		close (tmp);      /* get rid of unwanted ones */
	    }
    }
fout.b_fildes = 1;

    if (pgmflags & FRKCIGO)
    {
				  /* printf ("Child's interrupts to be
				     disabled\n");      */
	signal (1, 1);
	signal (2, 1);
	signal (3, 1);
    }

 /* printf ("Execing %s\n", pgm);    */
/*  if (pgmflags & EXECR)       */
/*      execr (pgm, pgmparm);   */
/*  else                        */
    execv (pgm, pgmparm);
				  /* printf ("Exec not successful\n"); */
    if (proctyp == PUREXEC)
	return (-1);
    fout.b_fildes = 1;
    printf ("Unable to exec \"%s\"\n", pgm);
    flush ();
    for (tmp = 0; tmp < 20 && pgmparm[tmp][0] != 0 ; tmp++)
    {
	printf ("Parm %d = \"%s\"\n", tmp, pgmparm[tmp]); flush ();
    }
    exit (-3);
}

childend ()
{
    int     tmp,
            tmp2;

    /* close (sbmitfd[0]); */
    close (sbmitfd[1]);
    while ((tmp = wait (&tmp2)) != sbchild && tmp != -1);
    return (tmp2 >> 8);
}
dbglog (str)
{
return;
printf(str);
}