+** Side Effects:
+** as necessary for that control message.
+*/
+
+short NoIoctl[] = { M_IOANS };
+
+mpxcontrol(rec)
+ register struct rh *rec;
+{
+ register int cmd;
+ register short val;
+ register short *ap;
+# ifdef MPXDEBUG
+ char dbbuf[100];
+# endif MPXDEBUG
+
+# ifdef DEBUG
+ if (Debug > 7)
+ printf("%d byte control message\n", rec->ccount);
+# endif DEBUG
+
+ ap = (short *) (((char *) rec) + sizeof *rec);
+ cmd = *ap++ & 0377;
+ val = *ap++;
+# ifdef MPXDEBUG
+ logmsg(LOG_DEBUG, "mpxctl ch=%x cmd=%d val=%d", rec->index, cmd, val);
+# endif MPXDEBUG
+
+ switch (cmd)
+ {
+ case M_WATCH: /* attempted connect; value is uid */
+# ifdef DEBUG
+ if (Debug > 7)
+ printf("WATCH, uid=%d\n", val);
+# endif DEBUG
+ attach(rec->index, MailPort);
+ InChannel = extract(rec->index, MailPort);
+ RealUid = val;
+ detach(rec->index, MailPort);
+ i = fork();
+ if (i < 0)
+ {
+ syserr("daemon: cannot fork");
+ }
+ else if (i > 0)
+ {
+ /* parent -- wait for child */
+ auto int st;
+
+ (void) wait(&st);
+ }
+ else
+ {
+ /* child */
+ smtp();
+ syserr("smtp returns");
+ exit(EX_SOFTWARE);
+ }
+ break;
+
+ case M_CLOSE: /* close channel; value is unused */
+# ifdef DEBUG
+ if (Debug > 7)
+ printf("CLOSE, val=%d\n", val);
+# endif DEBUG
+ detach(rec->index, MailPort);
+ break;
+
+ case M_IOCTL:
+# ifdef DEBUG
+ if (Debug > 7)
+ printf("IOCTL, val=%d\n", val);
+# endif DEBUG
+ wmpxctl(rec->index, NoIoctl, sizeof NoIoctl);
+ break;
+
+ default:
+ syserr("unknown mpx cmd %d, val=%d\n", cmd, val);
+ break;
+ }
+}
+\f/*
+** WMPXCTL -- write mpx control message
+**
+** Parameters:
+** index -- index to write to.
+** buf -- place to write.
+** len -- length to write.
+**