14535Seric # include "sendmail.h" 2*4631Seric # include <sys/mx.h> 34535Seric 4*4631Seric static char SccsId[] = "@(#)daemon.c 3.2.1.1 10/27/81"; 54535Seric 64535Seric /* 74535Seric ** DAEMON.C -- routines to use when running as a daemon. 84535Seric */ 9*4631Seric 10*4631Seric static FILE *MailPort; /* port that mail comes in on */ 114535Seric /* 124535Seric ** GETREQUESTS -- open mail IPC port and get requests. 134535Seric ** 144535Seric ** Parameters: 154535Seric ** none. 164535Seric ** 174535Seric ** Returns: 184535Seric ** none. 194535Seric ** 204535Seric ** Side Effects: 214535Seric ** Waits until some interesting activity occurs. When 224535Seric ** it does, a child is created to process it, and the 234535Seric ** parent waits for completion. Return from this 244535Seric ** routine is always in the child. 254535Seric */ 264535Seric 274535Seric getrequests() 284535Seric { 29*4631Seric char *portname = "/dev/mailbox"; 30*4631Seric 314628Seric /* initsys(); */ 32*4631Seric 33*4631Seric /* 34*4631Seric ** Create "/dev/mailbox" 35*4631Seric */ 36*4631Seric 37*4631Seric if (Debug) 38*4631Seric portname = "mailbox"; 39*4631Seric unlink(portname); 40*4631Seric MailPort = mpx(portname, 0222); 41*4631Seric if (MailPort < 0) 42*4631Seric { 43*4631Seric syserr("cannot create %s", portname); 44*4631Seric exit(EX_OSFILE); 45*4631Seric } 46*4631Seric chmod(portname, 0222); 47*4631Seric 48*4631Seric /* 49*4631Seric ** Wait for connection. 50*4631Seric */ 51*4631Seric 52*4631Seric for (;;) 53*4631Seric { 54*4631Seric i = read(MailPort, line, sizeof line); 55*4631Seric if (i < 0) 56*4631Seric { 57*4631Seric if (errno == EINTR) 58*4631Seric continue; 59*4631Seric syserr("mpx read"); 60*4631Seric errct++; 61*4631Seric if (errct > 1000) 62*4631Seric { 63*4631Seric syserr("mpx read: too many errors"); 64*4631Seric finis(); 65*4631Seric } 66*4631Seric sleep(5); 67*4631Seric continue; 68*4631Seric } 69*4631Seric mpxcrack(line, i); 70*4631Seric } 714535Seric } 724535Seric /* 73*4631Seric ** MPXCRACK -- parse & handle an input line. 744535Seric ** 754535Seric ** Parameters: 76*4631Seric ** rec -- the input record. 77*4631Seric ** bc -- the byte count for rec. 78*4631Seric ** 79*4631Seric ** Returns: 80*4631Seric ** nothing 81*4631Seric ** 82*4631Seric ** Side Effects: 83*4631Seric ** rec is processed. 84*4631Seric */ 85*4631Seric 86*4631Seric # define skip(rec, n) ((struct rh *) (((char *) rec) + n)) 87*4631Seric 88*4631Seric mpxcrack(rec, bc) 89*4631Seric register struct rh *rec; 90*4631Seric int bc; 91*4631Seric { 92*4631Seric struct rh *endrec; 93*4631Seric 94*4631Seric endrec = skip(rec, bc); 95*4631Seric 96*4631Seric while (rec < endrec) 97*4631Seric { 98*4631Seric if (rec->count == 0) 99*4631Seric { 100*4631Seric /* control record from mpx file */ 101*4631Seric mpxcontrol(rec); 102*4631Seric } 103*4631Seric else 104*4631Seric { 105*4631Seric /* data record -- process message */ 106*4631Seric syserr("data record!!"); 107*4631Seric } 108*4631Seric rec->count += rec->ccount; 109*4631Seric if (rec->count & 01) 110*4631Seric rec->count++; 111*4631Seric rec = skip(rec, rec->count + sizeof *rec); 112*4631Seric } 113*4631Seric } 114*4631Seric /* 115*4631Seric ** MPXCONTROL -- handle mpx control messages. 116*4631Seric ** 117*4631Seric ** Parameters: 118*4631Seric ** rec -- control message. 119*4631Seric ** 120*4631Seric ** Returns: 1214535Seric ** none. 1224535Seric ** 123*4631Seric ** Side Effects: 124*4631Seric ** as necessary for that control message. 125*4631Seric */ 126*4631Seric 127*4631Seric short NoIoctl[] = { M_IOANS }; 128*4631Seric 129*4631Seric mpxcontrol(rec) 130*4631Seric register struct rh *rec; 131*4631Seric { 132*4631Seric register int cmd; 133*4631Seric register short val; 134*4631Seric register short *ap; 135*4631Seric # ifdef MPXDEBUG 136*4631Seric char dbbuf[100]; 137*4631Seric # endif MPXDEBUG 138*4631Seric 139*4631Seric # ifdef DEBUG 140*4631Seric if (Debug > 7) 141*4631Seric printf("%d byte control message\n", rec->ccount); 142*4631Seric # endif DEBUG 143*4631Seric 144*4631Seric ap = (short *) (((char *) rec) + sizeof *rec); 145*4631Seric cmd = *ap++ & 0377; 146*4631Seric val = *ap++; 147*4631Seric # ifdef MPXDEBUG 148*4631Seric logmsg(LOG_DEBUG, "mpxctl ch=%x cmd=%d val=%d", rec->index, cmd, val); 149*4631Seric # endif MPXDEBUG 150*4631Seric 151*4631Seric switch (cmd) 152*4631Seric { 153*4631Seric case M_WATCH: /* attempted connect; value is uid */ 154*4631Seric # ifdef DEBUG 155*4631Seric if (Debug > 7) 156*4631Seric printf("WATCH, uid=%d\n", val); 157*4631Seric # endif DEBUG 158*4631Seric attach(rec->index, MailPort); 159*4631Seric InChannel = extract(rec->index, MailPort); 160*4631Seric RealUid = val; 161*4631Seric detach(rec->index, MailPort); 162*4631Seric i = fork(); 163*4631Seric if (i < 0) 164*4631Seric { 165*4631Seric syserr("daemon: cannot fork"); 166*4631Seric } 167*4631Seric else if (i > 0) 168*4631Seric { 169*4631Seric /* parent -- wait for child */ 170*4631Seric auto int st; 171*4631Seric 172*4631Seric (void) wait(&st); 173*4631Seric } 174*4631Seric else 175*4631Seric { 176*4631Seric /* child */ 177*4631Seric smtp(); 178*4631Seric syserr("smtp returns"); 179*4631Seric exit(EX_SOFTWARE); 180*4631Seric } 181*4631Seric break; 182*4631Seric 183*4631Seric case M_CLOSE: /* close channel; value is unused */ 184*4631Seric # ifdef DEBUG 185*4631Seric if (Debug > 7) 186*4631Seric printf("CLOSE, val=%d\n", val); 187*4631Seric # endif DEBUG 188*4631Seric detach(rec->index, MailPort); 189*4631Seric break; 190*4631Seric 191*4631Seric case M_IOCTL: 192*4631Seric # ifdef DEBUG 193*4631Seric if (Debug > 7) 194*4631Seric printf("IOCTL, val=%d\n", val); 195*4631Seric # endif DEBUG 196*4631Seric wmpxctl(rec->index, NoIoctl, sizeof NoIoctl); 197*4631Seric break; 198*4631Seric 199*4631Seric default: 200*4631Seric syserr("unknown mpx cmd %d, val=%d\n", cmd, val); 201*4631Seric break; 202*4631Seric } 203*4631Seric } 204*4631Seric /* 205*4631Seric ** WMPXCTL -- write mpx control message 206*4631Seric ** 207*4631Seric ** Parameters: 208*4631Seric ** index -- index to write to. 209*4631Seric ** buf -- place to write. 210*4631Seric ** len -- length to write. 211*4631Seric ** 2124535Seric ** Returns: 2134535Seric ** none. 2144535Seric ** 2154535Seric ** Side Effects: 216*4631Seric ** writes to MailPort. 2174535Seric */ 2184535Seric 219*4631Seric wmpxctl(index, buf, cnt) 220*4631Seric int index; 221*4631Seric char *buf; 222*4631Seric int cnt; 2234535Seric { 224*4631Seric struct wh wbuf; 225*4631Seric 226*4631Seric wbuf.index = index; 227*4631Seric wbuf.count = 0; 228*4631Seric wbuf.ccount = cnt; 229*4631Seric wbuf.data = buf; 230*4631Seric write(MailPort, &wbuf, sizeof wbuf); 2314535Seric } 232