|
|
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.