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