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