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