|
|
1.1 root 1: # include <errno.h>
2: # include "sendmail.h"
3:
4: #ifndef DAEMON
5: SCCSID(@(#)bbn_daemon.c 3.36+ 12/13/82 (w/o daemon mode));
6: #else
7: SCCSID(@(#)bbn_daemon.c 3.36+ 12/13/82 (w/ daemon mode));
8:
9: /*
10: ** DAEMON.C -- routines to use when running as a daemon.
11: **
12: ** BB&N Version. Hack attack!! This version is not supported,
13: ** and probably has some bugs......
14: **
15: ** Basic semantics are:
16: **
17: ** getrequests()
18: ** Opens a port and initiates a connection.
19: ** Returns in a child. Must set InChannel and
20: ** OutChannel appropriately.
21: ** makeconnection(host, port, outfile, infile)
22: ** Make a connection to the named host on the given
23: ** port. Set *outfile and *infile to the files
24: ** appropriate for communication. Returns zero on
25: ** success, else an exit status describing the
26: ** error.
27: **
28: ** The semantics of both of these should be clean.
29: */
30:
31: #include "netlib.h"
32: #include "con.h"
33: #include <wait.h>
34:
35: #define SMTPSOCK 25
36: /*
37: ** GETREQUESTS -- open mail IPC port and get requests.
38: **
39: ** Parameters:
40: ** none.
41: **
42: ** Returns:
43: ** none.
44: **
45: ** Side Effects:
46: ** Waits until some interesting activity occurs. When
47: ** it does, a child is created to process it, and the
48: ** parent waits for completion. Return from this
49: ** routine is always in the child.
50: */
51:
52: getrequests()
53: {
54: int t;
55: int iretval;
56: union wait status;
57: struct con openparams;
58:
59: /*
60: ** Set up the address for the mailer.
61: */
62:
63: bzero (&openparams, sizeof openparams); /* clear out the structure */
64:
65:
66: openparams.c_mode = CONTCP;
67: openparams.c_lport = SMTPSOCK;
68: openparams.c_rbufs = 2; /* 2k receive buffer */
69:
70: /*
71: ** Try to actually open the connection.
72: */
73:
74: # ifdef DEBUG
75: if (tTd(15, 1))
76: printf("getrequests\n");
77: # endif DEBUG
78:
79: for (;;)
80: {
81: /* wait for a connection */
82: register int pid;
83:
84: do
85: {
86: errno = 0;
87: t = open("/dev/net/net", &openparams);
88: } while (t < 0 && errno == EINTR);
89: if (t < 0)
90: {
91: syserr("getrequests: open");
92: sleep(500);
93: continue;
94: }
95:
96:
97: /* set 'eol' mode in connection */
98:
99: ioctl (t, NETSETE, 0);
100:
101: /*
102: ** Create a subprocess to process the mail.
103: */
104:
105: # ifdef DEBUG
106: if (tTd(15, 2))
107: printf("getrequests: forking (fd = %d)\n", t);
108: # endif DEBUG
109:
110: pid = fork();
111: if (pid < 0)
112: {
113: syserr("daemon: cannot fork");
114: sleep(10);
115: (void) close(t);
116: continue;
117: }
118:
119: if (pid == 0)
120: {
121: /*
122: ** CHILD -- return to caller.
123: ** Verify calling user id if possible here.
124: */
125:
126: InChannel = fdopen(t, "r");
127: OutChannel = fdopen(t, "w");
128: # ifdef DEBUG
129: if (tTd(15, 2))
130: printf("getreq: returning\n");
131: # endif DEBUG
132: # ifdef LOG
133: if (LogLevel > 11)
134: syslog(LOG_DEBUG, "connected, pid=%d", getpid());
135: # endif LOG
136: return;
137: }
138:
139: /*
140: ** PARENT -- wait for child to terminate.
141: ** Perhaps we should allow concurrent processing?
142: */
143:
144: # ifdef DEBUG
145: if (tTd(15, 2))
146: {
147: sleep(2);
148: printf("getreq: parent waiting\n");
149: }
150: # endif DEBUG
151:
152: /* close the port so that others will hang (for a while) */
153: if ((iretval = close(t)) < 0)
154: syserr("getreq: cannot close port 25: %d", iretval) ;
155:
156:
157: /* pick up old zombies; implement load limiting */
158: while (wait3(&status, WNOHANG, 0) > 0)
159: continue;
160: }
161: }
162: /*
163: ** MAKECONNECTION -- make a connection to an SMTP socket on another machine.
164: **
165: ** Parameters:
166: ** host -- the name of the host.
167: ** port -- the port number to connect to.
168: ** outfile -- a pointer to a place to put the outfile
169: ** descriptor.
170: ** infile -- ditto for infile.
171: **
172: ** Returns:
173: ** An exit code telling whether the connection could be
174: ** made and if not why not.
175: **
176: ** Side Effects:
177: ** none.
178: */
179:
180: makeconnection(host, port, outfile, infile)
181: char *host;
182: u_short port;
183: FILE **outfile;
184: FILE **infile;
185: {
186: register int s;
187: struct con openparams;
188:
189: bzero (&openparams, sizeof openparams); /* clear structure's memory */
190:
191: openparams.c_mode = CONACT | CONTCP;
192: openparams.c_timeo = 60;
193:
194: /*
195: ** Set up the address for the mailer.
196: ** Accept "[a.b.c.d]" syntax for host name.
197: */
198:
199: if (host[0] == '[')
200: {
201: long hid = 0;
202: int i, j;
203: register char *p = host;
204:
205: for (i = 3; i >= 0 && *p != ']' && *p != '\0'; i--)
206: {
207: j = 0;
208: while (isdigit(*++p))
209: j = j * 10 + (*p - '0');
210: if (*p != (i == 0 ? ']' : '.') || j > 255 || j < 0)
211: break;
212: hid |= j << ((3 - i) * 8);
213: }
214: if (i >= 0 || *p != ']' || *++p != '\0')
215: {
216: usrerr("Invalid numeric domain spec \"%s\"", host);
217: return (EX_NOHOST);
218: }
219: openparams.c_fcon._na_l = hid;
220: }
221: else
222: {
223:
224: openparams.c_fcon = gethost(host);
225: if (isbadhost(openparams.c_fcon))
226: return (EX_NOHOST);
227: }
228:
229: /*
230: ** Determine the port number.
231: */
232:
233: if (port == 0)
234: openparams.c_fport = SMTPSOCK;
235: else
236: openparams.c_fport = port;
237:
238: /*
239: ** Try to actually open the connection.
240: */
241:
242: # ifdef DEBUG
243: if (tTd(16, 1))
244: printf("makeconnection(%s=%X)\n", host, openparams.c_fcon._na_l);
245: # endif DEBUG
246:
247: s = open("/dev/net/net", &openparams);
248:
249: # ifdef DEBUG
250: if (tTd(16, 1))
251: printf("makeconnection: %d\n", s);
252: # endif DEBUG
253:
254: if (s < 0)
255: return (EX_TEMPFAIL);
256:
257: /* connection ok, put it into canonical form */
258: *outfile = fdopen(s, "w");
259: *infile = fdopen(s, "r");
260:
261: return (0);
262: }
263:
264: # endif DAEMON
265: /*
266: ** MYHOSTNAME -- return the name of this host.
267: **
268: ** This is a hideous hack.... It should be fixed to really work
269: ** under the BB&N code. However, since Brendan's configuration
270: ** tables don't use this feature it won't matter.
271: **
272: ** Parameters:
273: ** hostbuf -- a place to return the name of this host.
274: ** size -- the size of hostbuf.
275: **
276: ** Returns:
277: ** A list of aliases for this host.
278: ** NULL if it cannot be found.
279: **
280: ** Side Effects:
281: ** none.
282: */
283:
284: char **
285: myhostname(hostbuf, size)
286: char hostbuf[];
287: int size;
288: {
289: register FILE *f;
290:
291: hostbuf[0] = '\0';
292: f = fopen("/usr/include/whoami", "r");
293: if (f != NULL)
294: {
295: (void) fgets(hostbuf, size, f);
296: fixcrlf(hostbuf, TRUE);
297: (void) fclose(f);
298: }
299: return (NULL);
300: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.