+ extern putmessage();
+ int pid;
+
+ /*
+ ** Create connection to mailer.
+ */
+
+ pid = openmailer(m, pvp, ctladdr, FALSE, &mfile, &rfile);
+ if (pid < 0)
+ return (-1);
+
+ /*
+ ** Format and send message.
+ */
+
+ (void) signal(SIGPIPE, SIG_IGN);
+ if (editfcn == NULL)
+ editfcn = putmessage;
+
+ (*editfcn)(mfile, m, FALSE);
+ (void) fclose(mfile);
+
+ i = endmailer(pid, pvp[0]);
+ giveresponse(i, TRUE, m);
+ return (i);
+}
+\f/*
+** ENDMAILER -- Wait for mailer to terminate.
+**
+** We should never get fatal errors (e.g., segmentation
+** violation), so we report those specially. For other
+** errors, we choose a status message (into statmsg),
+** and if it represents an error, we print it.
+**
+** Parameters:
+** pid -- pid of mailer.
+** name -- name of mailer (for error messages).
+**
+** Returns:
+** exit code of mailer.
+**
+** Side Effects:
+** none.
+*/
+
+endmailer(pid, name)
+ int pid;
+ char *name;
+{
+ register int i;
+ auto int st;
+
+ while ((i = wait(&st)) > 0 && i != pid)
+ continue;
+ if (i < 0)
+ {
+ syserr("wait");
+ return (-1);
+ }
+ if ((st & 0377) != 0)
+ {
+ syserr("%s: stat %o", name, st);
+ ExitStat = EX_UNAVAILABLE;
+ return (-1);
+ }
+ i = (st >> 8) & 0377;
+ return (i);
+}
+\f/*
+** OPENMAILER -- open connection to mailer.
+**
+** Parameters:
+** m -- mailer descriptor.
+** pvp -- parameter vector to pass to mailer.
+** ctladdr -- controlling address for user.
+** clever -- create a full duplex connection.
+** pmfile -- pointer to mfile (to mailer) connection.
+** prfile -- pointer to rfile (from mailer) connection.
+**
+** Returns:
+** pid of mailer.
+** -1 on error.
+**
+** Side Effects:
+** creates a mailer in a subprocess.
+*/
+
+openmailer(m, pvp, ctladdr, clever, pmfile, prfile)
+ struct mailer *m;
+ char **pvp;
+ ADDRESS *ctladdr;
+ bool clever;
+ FILE **pmfile;
+ FILE **prfile;
+{