|
|
1.1 root 1: /* lppd.c - lpp listen and dispatch daemon */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/support/RCS/lppd.c,v 7.2 90/07/09 14:50:54 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/support/RCS/lppd.c,v 7.2 90/07/09 14:50:54 mrose Exp $
9: *
10: * Contributed by The Wollongong Group, Inc.
11: *
12: *
13: * $Log: lppd.c,v $
14: * Revision 7.2 90/07/09 14:50:54 mrose
15: * sync
16: *
17: * Revision 7.1 90/02/19 13:09:50 mrose
18: * update
19: *
20: * Revision 7.0 89/11/23 22:27:39 mrose
21: * Release 6.0
22: *
23: */
24:
25: /*
26: * NOTICE
27: *
28: * Acquisition, use, and distribution of this module and related
29: * materials are subject to the restrictions of a license agreement.
30: * Consult the Preface in the User's Manual for the full terms of
31: * this agreement.
32: *
33: */
34:
35:
36: #include <errno.h>
37: #include <signal.h>
38: #include <stdio.h>
39: #include <varargs.h>
40: #include "manifest.h"
41: #include <sys/ioctl.h>
42: #include <sys/stat.h>
43: #ifdef BSD42
44: #include <sys/file.h>
45: #endif
46: #ifdef SYS5
47: #include <fcntl.h>
48: #endif
49: #ifndef X_OK
50: #define X_OK 1
51: #endif
52: #include "psap.h"
53: #include "tsap.h"
54: #include "isoservent.h"
55: #include "logger.h"
56: #include "tailor.h"
57:
58: /* */
59:
60: static int debug = 0;
61: static int nbits = FD_SETSIZE;
62:
63: static LLog _pgm_log = {
64: "lppd.log", NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE,
65: LLOG_FATAL, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK
66: };
67: LLog *pgm_log = &_pgm_log;
68:
69: static char *myname = "lppd";
70: static char myhost[BUFSIZ];
71:
72:
73: #define NTADDRS FD_SETSIZE
74:
75: static struct TSAPaddr *tz;
76: static struct TSAPaddr tas[NTADDRS];
77:
78:
79: struct dispatch {
80: char *dp_entity;
81:
82: u_short dp_port;
83: };
84:
85: static struct dispatch *dz;
86: static struct dispatch dps[NTADDRS];
87:
88:
89: void adios (), advise ();
90: void ts_advise ();
91:
92:
93: extern int errno;
94:
95: /* */
96:
97: /* ARGSUSED */
98:
99: main (argc, argv, envp)
100: int argc;
101: char **argv,
102: **envp;
103: {
104: int listen,
105: vecp;
106: char *vec[4];
107: register struct NSAPaddr *na;
108: register struct TSAPaddr *ta;
109: register struct dispatch *dp;
110: struct TSAPdisconnect tds;
111: register struct TSAPdisconnect *td = &tds;
112:
113: arginit (argv);
114: envinit ();
115:
116: listen = 0;
117:
118: for (ta = tas, dp = dps; ta < tz; ta++, dp++) {
119: na = ta -> ta_addrs;
120: if (na -> na_stack != NA_TCP)
121: adios (NULLCP, "unexpected network type 0x%x", na -> na_stack);
122: if (na -> na_tset != NA_TSET_TCP)
123: adios (NULLCP, "unexpected transport base 0x%x", na -> na_tset);
124:
125: advise (LLOG_NOTICE, NULLCP, "listening on %s for \"%s\"",
126: taddr2str (ta), dp -> dp_entity);
127:
128: if (TNetListen (ta, td) == NOTOK) {
129: ts_advise (td, LLOG_EXCEPTIONS, "listen failed");
130: _exit (1);
131: }
132:
133: listen++;
134: }
135:
136: if (!listen)
137: adios (NULLCP, "no network services selected");
138:
139: for (ta = tas;;) {
140: if (TNetAcceptAux (&vecp, vec, NULLIP, ta, 0, NULLFD, NULLFD, NULLFD,
141: NOTOK, td) == NOTOK) {
142: ts_advise (td, LLOG_EXCEPTIONS, "TNetAccept");
143: continue;
144: }
145:
146: if (vecp <= 0)
147: continue;
148:
149: switch (TNetFork (vecp, vec, td)) {
150: case OK:
151: ll_hdinit (pgm_log, myname);
152: lppd (vecp, vec, ta);
153: exit (1);
154: /* NOTREACHED */
155:
156: case NOTOK:
157: ts_advise (td, LLOG_EXCEPTIONS, "fork failed");
158: default:
159: break;
160: }
161: }
162: }
163:
164: /* */
165:
166: /* ARGSUSED */
167:
168: static int lppd (vecp, vec, ta)
169: int vecp;
170: char **vec;
171: struct TSAPaddr *ta;
172: {
173: register u_short port = ta -> ta_addrs[0].na_port;
174: register struct dispatch *dp;
175: register struct isoservent *is;
176:
177: for (dp = dps; dp < dz; dp++)
178: if (dp -> dp_port == port)
179: break;
180: if (dp >= dz)
181: adios (NULLCP, "unable to find service associated with local port %d",
182: ntohs (port));
183:
184: if ((is = getisoserventbyname (dp -> dp_entity, "lpp")) == NULL)
185: adios (NULLCP, "unable to find program associated with service %s",
186: dp -> dp_entity);
187:
188: *is -> is_tail++ = vec[1];
189: *is -> is_tail++ = vec[2];
190: *is -> is_tail = NULL;
191:
192: advise (LLOG_NOTICE, NULLCP, "exec \"%s\" for \"%s\"", *is -> is_vec,
193: dp -> dp_entity);
194:
195: (void) execv (*is -> is_vec, is -> is_vec);
196:
197: adios (*is -> is_vec, "unable to exec");
198: }
199:
200: /* */
201:
202: static void ts_advise (td, code, event)
203: register struct TSAPdisconnect *td;
204: int code;
205: char *event;
206: {
207: char buffer[BUFSIZ];
208:
209: if (td -> td_cc > 0)
210: (void) sprintf (buffer, "[%s] %*.*s",
211: TErrString (td -> td_reason),
212: td -> td_cc, td -> td_cc, td -> td_data);
213: else
214: (void) sprintf (buffer, "[%s]", TErrString (td -> td_reason));
215:
216: advise (code, NULLCP, "%s: %s", event, buffer);
217: }
218:
219: /* */
220:
221: static arginit (vec)
222: char **vec;
223: {
224: register int n;
225: register char *ap;
226: struct stat st;
227: register struct isoservent *is;
228: register struct PSAPaddr *pa;
229: register struct NSAPaddr *na;
230: AEI aei;
231:
232: if (myname = rindex (*vec, '/'))
233: myname++;
234: if (myname == NULL || *myname == NULL)
235: myname = *vec;
236:
237: isodetailor (myname, 0);
238: ll_hdinit (pgm_log, myname);
239:
240: if (getuid () == 0
241: && stat (ap = isodefile ("isoservices", 0), &st) != NOTOK
242: && st.st_uid != 0)
243: adios (NULLCP, "%s not owned by root", ap);
244:
245: (void) strcpy (myhost, TLocalHostName ());
246:
247: for (vec++; ap = *vec; vec++) {
248: if (*ap == '-')
249: switch (*++ap) {
250: case 'd':
251: debug++;
252: continue;
253:
254: case 's':
255: if ((ap = *++vec) == NULL || *ap == '-')
256: adios (NULLCP, "usage: %s -s service-designator");
257: (void) strcpy (myhost, ap);
258: continue;
259:
260: default:
261: adios (NULLCP, "-%s: unknown switch", ap);
262: }
263:
264: adios (NULLCP, "usage: %s [switches]", myname);
265: }
266:
267: bzero ((char *) tas, sizeof tas);
268: tz = tas;
269:
270: bzero ((char *) dps, sizeof dps);
271: dz = dps;
272:
273: (void) setisoservent (0);
274: while (is = getisoservent ())
275: if (strcmp (is -> is_provider, "lpp") == 0
276: && access (*is -> is_vec, X_OK) != NOTOK) {
277: if ((aei = str2aei (myhost, is -> is_entity)) == NULLAEI)
278: continue;
279: if ((pa = aei2addr (aei)) == NULLPA)
280: adios (NULLCP, "address translation failed on %s-%s",
281: myhost, is -> is_entity);
282:
283: for (na = pa -> pa_addr.sa_addr.ta_addrs,
284: n = pa -> pa_addr.sa_addr.ta_naddr;
285: n > 0;
286: na++, n--) {
287: if (na -> na_stack != NA_TCP)
288: continue;
289: if (na -> na_tset == 0)
290: na -> na_tset = NA_TSET_TCP;
291: else
292: if (na -> na_tset != NA_TSET_TCP)
293: continue;
294: if (na -> na_port == 0)
295: continue;
296:
297: if (tz >= tas + NTADDRS) {
298: advise (LLOG_EXCEPTIONS, NULLCP,
299: "too many services, starting with %s",
300: is -> is_entity);
301: goto no_more;
302: }
303:
304: bcopy ((char *) na, (char *) tz -> ta_addrs, sizeof *na);
305: tz -> ta_naddr = 1;
306: tz++;
307:
308: if ((dz -> dp_entity =
309: malloc ((unsigned) (strlen (is -> is_entity) + 1)))
310: == NULL)
311: adios (NULLCP, "out of memory");
312: (void) strcpy (dz -> dp_entity, is -> is_entity);
313: dz -> dp_port = na -> na_port;
314: dz++;
315: }
316: }
317: no_more: ;
318: (void) endisoservent ();
319: }
320:
321: /* */
322:
323: static envinit () {
324: int i,
325: sd;
326:
327: nbits = getdtablesize ();
328:
329: if (debug == 0 && !(debug = isatty (2))) {
330: for (i = 0; i < 5; i++) {
331: switch (fork ()) {
332: case NOTOK:
333: sleep (5);
334: continue;
335:
336: case OK:
337: break;
338:
339: default:
340: _exit (0);
341: }
342: break;
343: }
344:
345: (void) chdir ("/");
346:
347: if ((sd = open ("/dev/null", O_RDWR)) == NOTOK)
348: adios ("/dev/null", "unable to read");
349: if (sd != 0)
350: (void) dup2 (sd, 0), (void) close (sd);
351: (void) dup2 (0, 1);
352: (void) dup2 (0, 2);
353:
354: #ifdef SETSID
355: if (setsid () == NOTOK)
356: advise (LLOG_EXCEPTIONS, "failed", "setsid");
357: #endif
358: #ifdef TIOCNOTTY
359: if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) {
360: (void) ioctl (sd, TIOCNOTTY, NULLCP);
361: (void) close (sd);
362: }
363: #else
364: #ifdef SYS5
365: (void) setpgrp ();
366: (void) signal (SIGINT, SIG_IGN);
367: (void) signal (SIGQUIT, SIG_IGN);
368: #endif
369: #endif
370: }
371: else
372: ll_dbinit (pgm_log, myname);
373:
374: #ifndef sun /* damn YP... */
375: for (sd = 3; sd < nbits; sd++)
376: if (pgm_log -> ll_fd != sd)
377: (void) close (sd);
378: #endif
379:
380: (void) signal (SIGPIPE, SIG_IGN);
381:
382: ll_hdinit (pgm_log, myname);
383: advise (LLOG_NOTICE, NULLCP, "starting");
384: }
385:
386: /* ERRORS */
387:
388: #ifndef lint
389: void adios (va_alist)
390: va_dcl
391: {
392: va_list ap;
393:
394: va_start (ap);
395:
396: _ll_log (pgm_log, LLOG_FATAL, ap);
397:
398: va_end (ap);
399:
400: _exit (1);
401: }
402: #else
403: /* VARARGS */
404:
405: void adios (what, fmt)
406: char *what,
407: *fmt;
408: {
409: adios (what, fmt);
410: }
411: #endif
412:
413:
414: #ifndef lint
415: void advise (va_alist)
416: va_dcl
417: {
418: int code;
419: va_list ap;
420:
421: va_start (ap);
422:
423: code = va_arg (ap, int);
424:
425: _ll_log (pgm_log, code, ap);
426:
427: va_end (ap);
428: }
429: #else
430: /* VARARGS */
431:
432: void advise (code, what, fmt)
433: char *what,
434: *fmt;
435: int code;
436: {
437: advise (code, what, fmt);
438: }
439: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.