|
|
1.1 ! root 1: /* tsapd.c - OSI transport server */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/support/RCS/tsapd.c,v 7.2 90/07/09 14:51:00 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/support/RCS/tsapd.c,v 7.2 90/07/09 14:51:00 mrose Exp $ ! 9: * ! 10: * ! 11: * $Log: tsapd.c,v $ ! 12: * Revision 7.2 90/07/09 14:51:00 mrose ! 13: * sync ! 14: * ! 15: * Revision 7.1 90/02/19 13:09:53 mrose ! 16: * update ! 17: * ! 18: * Revision 7.0 89/11/23 22:27:46 mrose ! 19: * Release 6.0 ! 20: * ! 21: */ ! 22: ! 23: /* ! 24: * NOTICE ! 25: * ! 26: * Acquisition, use, and distribution of this module and related ! 27: * materials are subject to the restrictions of a license agreement. ! 28: * Consult the Preface in the User's Manual for the full terms of ! 29: * this agreement. ! 30: * ! 31: */ ! 32: ! 33: ! 34: #include <errno.h> ! 35: #include <signal.h> ! 36: #include <stdio.h> ! 37: #include <varargs.h> ! 38: #include "manifest.h" ! 39: #include <sys/ioctl.h> ! 40: #include <sys/stat.h> ! 41: #ifdef BSD42 ! 42: #include <sys/file.h> ! 43: #endif ! 44: #ifdef SYS5 ! 45: #include <fcntl.h> ! 46: #endif ! 47: #ifndef X_OK ! 48: #define X_OK 1 ! 49: #endif ! 50: ! 51: #ifndef NOGOSIP ! 52: #include "rosap.h" ! 53: #include "rtsap.h" ! 54: #include "psap2.h" ! 55: #include "ssap.h" ! 56: #endif ! 57: #include "tpkt.h" ! 58: ! 59: #ifdef TCP ! 60: #include "internet.h" ! 61: #endif ! 62: #ifdef X25 ! 63: #include "x25.h" ! 64: #endif ! 65: #ifdef TP4 ! 66: #include "tp4.h" ! 67: #endif ! 68: #include "isoservent.h" ! 69: #include "tailor.h" ! 70: ! 71: /* */ ! 72: ! 73: static int debug = 0; ! 74: static int nbits = FD_SETSIZE; ! 75: ! 76: static LLog _pgm_log = { ! 77: "tsapd.log", NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, ! 78: LLOG_FATAL, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK ! 79: }; ! 80: LLog *pgm_log = &_pgm_log; ! 81: ! 82: static char *myname = "tsapd"; ! 83: static char myhost[BUFSIZ]; ! 84: ! 85: static int tcpservice = 1; ! 86: static int x25service = 1; ! 87: static int bridgeservice = 1; ! 88: static int tp4service = 1; ! 89: ! 90: ! 91: #define NTADDRS FD_SETSIZE ! 92: ! 93: static struct TSAPaddr *tz; ! 94: static struct TSAPaddr tas[NTADDRS]; ! 95: ! 96: ! 97: ! 98: ! 99: void adios (), advise (); ! 100: void ts_advise (); ! 101: ! 102: #ifdef NOGOSIP ! 103: #define ssapd NULLIFP ! 104: #else ! 105: int ssapd (), psapd (); ! 106: #endif ! 107: ! 108: ! 109: ! 110: extern int errno; ! 111: ! 112: /* */ ! 113: ! 114: /* ARGSUSED */ ! 115: ! 116: main (argc, argv, envp) ! 117: int argc; ! 118: char **argv, ! 119: **envp; ! 120: { ! 121: int failed, ! 122: listening, ! 123: vecp; ! 124: char *vec[4]; ! 125: register struct NSAPaddr *na; ! 126: register struct TSAPaddr *ta; ! 127: struct TSAPdisconnect tds; ! 128: register struct TSAPdisconnect *td = &tds; ! 129: ! 130: arginit (argv); ! 131: envinit (); ! 132: ! 133: failed = listening = 0; ! 134: ! 135: for (ta = tas; ta < tz; ta++) { ! 136: if (ta -> ta_naddr == 0) { ! 137: if (!tp4service) ! 138: continue; ! 139: } ! 140: else { ! 141: na = ta -> ta_addrs; ! 142: ! 143: switch (na -> na_stack) { ! 144: case NA_TCP: ! 145: if (!tcpservice) ! 146: continue; ! 147: break; ! 148: ! 149: case NA_X25: ! 150: if (!x25service) ! 151: continue; ! 152: break; ! 153: ! 154: case NA_BRG: ! 155: if (!bridgeservice) ! 156: continue; ! 157: break; ! 158: ! 159: case NA_NSAP: ! 160: if (!tp4service) ! 161: continue; ! 162: break; ! 163: ! 164: default: ! 165: adios (NULLCP, "unknown network type 0x%x", na -> na_stack); ! 166: /* NOTREACHED */ ! 167: } ! 168: } ! 169: ! 170: advise (LLOG_NOTICE, NULLCP, "listening on %s", taddr2str (ta)); ! 171: ! 172: if (TNetListen (ta, td) == NOTOK) { ! 173: ts_advise (td, LLOG_EXCEPTIONS, "TNetListen failed"); ! 174: failed++; ! 175: } ! 176: else ! 177: listening++; ! 178: } ! 179: ! 180: if (!listening) ! 181: adios (NULLCP, failed ? "no successful listens" ! 182: : "no network services selected"); ! 183: ! 184: for (;;) { ! 185: if (TNetAccept (&vecp, vec, 0, NULLFD, NULLFD, NULLFD, NOTOK, td) ! 186: == NOTOK) { ! 187: ts_advise (td, LLOG_EXCEPTIONS, "TNetAccept failed"); ! 188: continue; ! 189: } ! 190: ! 191: if (vecp <= 0) ! 192: continue; ! 193: ! 194: switch (TNetFork (vecp, vec, td)) { ! 195: case OK: ! 196: ll_hdinit (pgm_log, myname); ! 197: tsapd (vecp, vec); ! 198: exit (1); ! 199: /* NOTREACHED */ ! 200: ! 201: case NOTOK: ! 202: ts_advise (td, LLOG_EXCEPTIONS, "TNetFork failed"); ! 203: default: ! 204: break; ! 205: } ! 206: } ! 207: } ! 208: ! 209: /* */ ! 210: ! 211: static char buffer1[4096]; ! 212: static char buffer2[32768]; ! 213: ! 214: ! 215: static int tsapd (vecp, vec) ! 216: int vecp; ! 217: char **vec; ! 218: { ! 219: char buffer[BUFSIZ]; ! 220: register struct isoservent *is; ! 221: struct tsapblk *tb; ! 222: struct TSAPstart tss; ! 223: register struct TSAPstart *ts = &tss; ! 224: struct TSAPdisconnect tds; ! 225: register struct TSAPdisconnect *td = &tds; ! 226: IFP hook; ! 227: ! 228: /* begin UGLY */ ! 229: (void) strcpy (buffer1, vec[1]); ! 230: (void) strcpy (buffer2, vec[2]); ! 231: /* end UGLY */ ! 232: ! 233: if (TInit (vecp, vec, ts, td) == NOTOK) { ! 234: ts_advise (td, LLOG_EXCEPTIONS, "T-CONNECT.INDICATION"); ! 235: return; ! 236: } ! 237: ! 238: /* used to print this in ssapd()... */ ! 239: advise (LLOG_NOTICE, NULLCP, ! 240: "T-CONNECT.INDICATION: <%d, %s, %s, %d, %d>", ! 241: ts -> ts_sd, ! 242: taddr2str (&ts -> ts_calling), taddr2str (&ts -> ts_called), ! 243: ts -> ts_expedited, ts -> ts_tsdusize); ! 244: ! 245: ! 246: hook = ssapd; ! 247: if (ts -> ts_called.ta_selectlen) { ! 248: if ((is = getisoserventbyselector ("tsap", ts -> ts_called.ta_selector, ! 249: ts -> ts_called.ta_selectlen)) ! 250: == NULL) { ! 251: (void) sprintf (buffer, "OSI service tsap/%s not found", ! 252: sel2str (ts -> ts_called.ta_selector, ! 253: ts -> ts_called.ta_selectlen, 1)); ! 254: goto out; ! 255: } ! 256: } ! 257: else ! 258: if (hook == NULLIFP ! 259: || (is = getisoserventbyname ("session", "tsap")) == NULL) { ! 260: (void) strcpy (buffer, "default session service not found"); ! 261: goto out; ! 262: } ! 263: ! 264: *is -> is_tail++ = buffer1; ! 265: *is -> is_tail++ = buffer2; ! 266: *is -> is_tail = NULL; ! 267: ! 268: if (tb = findtblk (ts -> ts_sd)) ! 269: tb -> tb_fd = NOTOK; ! 270: switch (hook ? (*hook) (is, td) : OK) { ! 271: case NOTOK: ! 272: ts_advise (td, LLOG_EXCEPTIONS, "service not started at tsap"); ! 273: case DONE: ! 274: exit (1); ! 275: /* NOTREACHED */ ! 276: ! 277: case OK: ! 278: default: ! 279: (void) setperms (is); ! 280: (void) execv (*is -> is_vec, is -> is_vec); ! 281: (void) sprintf (buffer, "unable to exec %s: %s", ! 282: *is -> is_vec, sys_errname (errno)); ! 283: SLOG (pgm_log, LLOG_FATAL, NULLCP, ("%s", buffer)); ! 284: break; ! 285: } ! 286: ! 287: out: ; ! 288: advise (LLOG_EXCEPTIONS, NULLCP, "%s", buffer); ! 289: if (strlen (buffer) >= TD_SIZE) ! 290: buffer[0] = NULL; ! 291: (void) TDiscRequest (ts -> ts_sd, buffer, strlen (buffer) + 1, td); ! 292: ! 293: exit (1); ! 294: } ! 295: ! 296: /* */ ! 297: ! 298: static int setperms (is) ! 299: register struct isoservent *is; ! 300: { ! 301: struct stat st; ! 302: ! 303: if (stat (*is -> is_vec, &st) == NOTOK) { ! 304: (void) setgid (1); ! 305: (void) setuid (1); ! 306: } ! 307: else { ! 308: (void) setgid (st.st_gid); ! 309: (void) setuid (st.st_uid); ! 310: } ! 311: } ! 312: ! 313: /* */ ! 314: ! 315: static void ts_advise (td, code, event) ! 316: register struct TSAPdisconnect *td; ! 317: int code; ! 318: char *event; ! 319: { ! 320: char buffer[BUFSIZ]; ! 321: ! 322: if (td -> td_cc > 0) ! 323: (void) sprintf (buffer, "[%s] %*.*s", ! 324: TErrString (td -> td_reason), ! 325: td -> td_cc, td -> td_cc, td -> td_data); ! 326: else ! 327: (void) sprintf (buffer, "[%s]", TErrString (td -> td_reason)); ! 328: ! 329: advise (code, NULLCP, "%s: %s", event, buffer); ! 330: } ! 331: ! 332: /* */ ! 333: ! 334: #ifndef NOGOSIP ! 335: static int ssapd (is, td) ! 336: register struct isoservent *is; ! 337: register struct TSAPdisconnect *td; ! 338: { ! 339: int sd; ! 340: struct TSAPstart tss; ! 341: register struct TSAPstart *ts = &tss; ! 342: struct SSAPindication sis; ! 343: register struct SSAPabort *sa = &sis.si_abort; ! 344: ! 345: if (strcmp (is -> is_entity, "session") ! 346: || strcmp (is -> is_provider, "tsap")) ! 347: return OK; ! 348: ! 349: if (TInit (is -> is_tail - is -> is_vec, is -> is_vec, ts, td) == NOTOK) ! 350: return NOTOK; ! 351: ! 352: sd = ts -> ts_sd; ! 353: ! 354: if (TConnResponse (sd, &ts -> ts_called, ts -> ts_expedited, NULLCP, 0, ! 355: NULLQOS, td) == NOTOK) ! 356: return NOTOK; ! 357: ! 358: if (SExec (ts, &sis, psapd, setperms) == NOTOK) { ! 359: advise (LLOG_EXCEPTIONS, NULLCP, "service not started at ssap: %s", ! 360: SErrString (sa -> sa_reason)); ! 361: if (sa -> sa_cc > 0) ! 362: advise (LLOG_EXCEPTIONS, NULLCP, " %*.*s", ! 363: sa -> sa_cc, sa -> sa_cc, sa -> sa_data); ! 364: ! 365: SAFREE (sa); ! 366: } ! 367: ! 368: return DONE; ! 369: } ! 370: ! 371: /* */ ! 372: ! 373: #define RMASK \ ! 374: "\020\01HALFDUPLEX\02DUPLEX\03EXPEDITED\04MINORSYNC\05MAJORSYNC\06RESYNC\ ! 375: \07ACTIVITY\010NEGOTIATED\011CAPABILITY\012EXCEPTIONS\013TYPEDATA" ! 376: ! 377: ! 378: static int psapd (is, si) ! 379: register struct isoservent *is; ! 380: register struct SSAPindication *si; ! 381: { ! 382: struct SSAPstart sss; ! 383: register struct SSAPstart *ss = &sss; ! 384: struct PSAPindication pis; ! 385: register struct PSAPabort *pa = &pis.pi_abort; ! 386: struct RtSAPindication rtis; ! 387: register struct RtSAPabort *rta = &rtis.rti_abort; ! 388: struct RoSAPindication rois; ! 389: register struct RoSAPpreject *rop = &rois.roi_preject; ! 390: ! 391: if (strcmp (is -> is_provider, "ssap")) ! 392: return OK; ! 393: ! 394: if (strcmp (is -> is_entity, "presentation") ! 395: && strcmp (is -> is_entity, "rts") ! 396: && strcmp (is -> is_entity, "ros")) ! 397: return OK; ! 398: ! 399: /* begin UGLY */ ! 400: (void) strcpy (buffer1, *(is -> is_tail - 2)); ! 401: (void) strcpy (buffer2, *(is -> is_tail - 1)); ! 402: /* end UGLY */ ! 403: if (SInit (is -> is_tail - is -> is_vec, is -> is_vec, ss, si) == NOTOK) ! 404: return NOTOK; ! 405: advise (LLOG_NOTICE, NULLCP, ! 406: "S-CONNECT.INDICATION: <%d, %s, %s, %s, %s, %ld, %d>", ! 407: ss -> ss_sd, sprintref (&ss -> ss_connect), ! 408: saddr2str (&ss -> ss_calling), saddr2str (&ss -> ss_called), ! 409: sprintb (ss -> ss_requirements, RMASK), ss -> ss_isn, ! 410: ss -> ss_ssdusize); ! 411: ! 412: if (strcmp (is -> is_entity, "presentation") == 0) { ! 413: if (PExec (ss, &pis, buffer1, buffer2, NULLIFP, setperms) == NOTOK) { ! 414: advise (LLOG_EXCEPTIONS, NULLCP, ! 415: "service not started at psap: %s", ! 416: PErrString (pa -> pa_reason)); ! 417: if (pa -> pa_cc > 0) ! 418: advise (LLOG_EXCEPTIONS, NULLCP, " %*.*s", ! 419: pa -> pa_cc, pa -> pa_cc, pa -> pa_data); ! 420: } ! 421: ! 422: return DONE; ! 423: } ! 424: ! 425: if (strcmp (is -> is_entity, "rts") == 0) { ! 426: if (RtExec (ss, &rtis, buffer1, buffer2, NULLIFP, setperms) == NOTOK) { ! 427: advise (LLOG_EXCEPTIONS, NULLCP, ! 428: "service not started at rtsap: %s", ! 429: RtErrString (rta -> rta_reason)); ! 430: if (rta -> rta_cc > 0) ! 431: advise (LLOG_EXCEPTIONS, NULLCP, " %*.*s", ! 432: rta -> rta_cc, rta -> rta_cc, rta -> rta_data); ! 433: } ! 434: } ! 435: else { ! 436: if (RoExec (ss, &rois, buffer1, buffer2, NULLIFP, setperms) == NOTOK) { ! 437: advise (LLOG_EXCEPTIONS, NULLCP, ! 438: "service not started at rosap: %s", ! 439: RoErrString (rop -> rop_reason)); ! 440: if (rop -> rop_cc > 0) ! 441: advise (LLOG_EXCEPTIONS, NULLCP, " %*.*s", ! 442: rop -> rop_cc, rop -> rop_cc, rop -> rop_data); ! 443: } ! 444: } ! 445: ! 446: return DONE; ! 447: } ! 448: #endif ! 449: ! 450: /* */ ! 451: ! 452: static arginit (vec) ! 453: char **vec; ! 454: { ! 455: int rflag; ! 456: register char *ap; ! 457: #ifdef TCP ! 458: int port; ! 459: struct NSAPaddr *tcp_na; ! 460: register struct servent *sp; ! 461: #endif ! 462: #ifdef X25 ! 463: struct NSAPaddr *x25_na; ! 464: #endif ! 465: #ifdef BRIDGE_X25 ! 466: struct NSAPaddr *bridge_na; ! 467: #endif ! 468: #ifdef TP4 ! 469: register struct isoservent *is; ! 470: #endif ! 471: struct stat st; ! 472: ! 473: if (myname = rindex (*vec, '/')) ! 474: myname++; ! 475: if (myname == NULL || *myname == NULL) ! 476: myname = *vec; ! 477: ! 478: isodetailor (myname, 0); ! 479: ll_hdinit (pgm_log, myname); ! 480: ! 481: rflag = 0; ! 482: ! 483: (void) strcpy (myhost, TLocalHostName ()); ! 484: ! 485: bzero ((char *) tas, sizeof tas); ! 486: tz = tas; ! 487: ! 488: #ifdef TCP ! 489: if (!(ts_stacks & TS_TCP)) ! 490: tcpservice = 0; ! 491: if ((sp = getservbyname ("tsap", "tcp")) == NULL ! 492: && (sp = getservbyname ("iso-tsap", "tcp")) == NULL) ! 493: advise (LLOG_EXCEPTIONS, NULLCP, "tcp/tsap: unknown service"); ! 494: ! 495: tcp_na = tz -> ta_addrs; ! 496: tcp_na -> na_stack = NA_TCP; ! 497: tcp_na -> na_community = ts_comm_tcp_default; ! 498: tcp_na -> na_domain[0] = NULL; ! 499: tcp_na -> na_port = sp ? sp -> s_port : htons ((u_short) 102); ! 500: tz -> ta_naddr = 1; ! 501: ! 502: tz++; ! 503: #endif ! 504: ! 505: #ifdef X25 ! 506: if (!(ts_stacks & TS_X25)) ! 507: x25service = 0; ! 508: ! 509: x25_na = tz -> ta_addrs; ! 510: x25_na -> na_stack = NA_X25; ! 511: x25_na -> na_community = ts_comm_x25_default; ! 512: if (x25_local_dte && *x25_local_dte) { ! 513: (void) strcpy (x25_na -> na_dte, x25_local_dte); ! 514: x25_na -> na_dtelen = strlen (x25_na -> na_dte); ! 515: } ! 516: if (x25_local_pid && *x25_local_pid) ! 517: x25_na -> na_pidlen = ! 518: str2sel (x25_local_pid, -1, x25_na -> na_pid, NPSIZE); ! 519: tz -> ta_naddr = 1; ! 520: ! 521: tz++; ! 522: #endif ! 523: ! 524: #ifdef BRIDGE_X25 ! 525: if (!(ts_stacks & TS_BRG)) ! 526: bridgeservice = 0; ! 527: ! 528: bridge_na = tz -> ta_addrs; ! 529: bridge_na -> na_stack = NA_BRG; ! 530: bridge_na -> na_community = ts_comm_x25_default; ! 531: if (x25_bridge_listen && *x25_bridge_listen) { ! 532: (void) strcpy (bridge_na -> na_dte, x25_bridge_listen); ! 533: bridge_na -> na_dtelen = strlen (bridge_na -> na_dte); ! 534: } ! 535: if (x25_bridge_pid && *x25_bridge_pid) ! 536: bridge_na -> na_pidlen = ! 537: str2sel (x25_bridge_pid, -1, bridge_na -> na_pid, NPSIZE); ! 538: tz -> ta_naddr = 1; ! 539: ! 540: tz++; ! 541: #endif ! 542: ! 543: #ifdef TP4 ! 544: if (!(ts_stacks & TS_TP4)) ! 545: tp4service = 0; ! 546: ! 547: (void) setisoservent (0); ! 548: while (is = getisoservent ()) ! 549: if (strcmp (is -> is_provider, "tsap") == 0 ! 550: && (strcmp (*is -> is_vec, "tsapd-bootstrap") == 0 ! 551: || access (*is -> is_vec, X_OK) != NOTOK)) { ! 552: if (strcmp (is -> is_entity, "isore") == 0) ! 553: continue; ! 554: ! 555: if (tz >= tas + NTADDRS) { ! 556: advise (LLOG_EXCEPTIONS, NULLCP, ! 557: "too many services, starting with %s", ! 558: is -> is_entity); ! 559: break; ! 560: } ! 561: ! 562: bcopy (is -> is_selector, tz -> ta_selector, ! 563: tz -> ta_selectlen = is -> is_selectlen); ! 564: tz -> ta_naddr = 0; ! 565: ! 566: tz++; ! 567: } ! 568: (void) endisoservent (); ! 569: #endif ! 570: ! 571: for (vec++; ap = *vec; vec++) { ! 572: if (*ap == '-') ! 573: switch (*++ap) { ! 574: case 'd': ! 575: debug++; ! 576: continue; ! 577: ! 578: case 't': ! 579: ts_stacks = TS_TCP; ! 580: tcpservice = 1; ! 581: x25service = bridgeservice = tp4service = 0; ! 582: continue; ! 583: ! 584: case 'x': ! 585: ts_stacks = TS_X25; ! 586: x25service = 1; ! 587: tcpservice = bridgeservice = tp4service = 0; ! 588: continue; ! 589: ! 590: case 'z': ! 591: ts_stacks = TS_TP4; ! 592: tp4service = 1; ! 593: tcpservice = x25service = bridgeservice = 0; ! 594: continue; ! 595: ! 596: case 'b': ! 597: ts_stacks = TS_BRG; ! 598: bridgeservice = 1; ! 599: tcpservice = x25service = tp4service = 0; ! 600: continue; ! 601: ! 602: case 'r': ! 603: rflag = 1; ! 604: continue; ! 605: ! 606: #ifdef TCP ! 607: case 'p': ! 608: if ((ap = *++vec) == NULL ! 609: || *ap == '-' ! 610: || (port = atoi (ap)) <= 0) ! 611: adios (NULLCP, "usage: %s -p portno", myname); ! 612: tcp_na -> na_port = htons ((u_short) port); ! 613: continue; ! 614: #endif ! 615: ! 616: #ifdef X25 ! 617: /* This permits listening on a specific subaddress. */ ! 618: case 'a': ! 619: if ((ap = *++vec) == NULL || *ap == '-') ! 620: adios (NULLCP, "usage: %s -a x121address", myname); ! 621: (void) strcpy (x25_na -> na_dte, ap); ! 622: x25_na -> na_dtelen = strlen (ap); ! 623: continue; ! 624: ! 625: /* This permits listening on a specific protocol id. ! 626: In fact, SunLink X.25 lets you listen on a protocol ! 627: id mask, but let's keep it simple. */ ! 628: case 'i': ! 629: if ((ap = *++vec) == NULL || *ap == '-' ) ! 630: adios (NULLCP, "usage: %s -i pid", myname); ! 631: x25_na -> na_pidlen = ! 632: str2sel (ap, -1, x25_na -> na_pid, NPSIZE); ! 633: continue; ! 634: #endif ! 635: ! 636: #ifdef BRIDGE_X25 ! 637: case 'A': ! 638: if ((ap = *++vec) == NULL || ! 639: *ap == '-') ! 640: adios (NULLCP, "usage: %s -A x121address", myname); ! 641: (void) strcpy (bridge_na -> na_dte, ap); ! 642: bridge_na -> na_dtelen = strlen (ap); ! 643: continue; ! 644: ! 645: case 'I': ! 646: if ((ap = *++vec) == NULL || *ap == '-') ! 647: adios (NULLCP, "usage: %s -I pid", myname); ! 648: bridge_na -> na_pidlen = ! 649: str2sel (ap, -1, bridge_na -> na_pid, NPSIZE); ! 650: continue; ! 651: #endif ! 652: ! 653: default: ! 654: adios (NULLCP, "-%s: unknown switch", ap); ! 655: } ! 656: ! 657: adios (NULLCP, "usage: %s [switches]", myname); ! 658: } ! 659: ! 660: if (!rflag ! 661: && getuid () == 0 ! 662: && stat (ap = isodefile ("isoservices", 0), &st) != NOTOK ! 663: && st.st_uid != 0) ! 664: adios (NULLCP, "%s not owned by root", ap); ! 665: } ! 666: ! 667: /* */ ! 668: ! 669: static envinit () { ! 670: int i, ! 671: sd; ! 672: ! 673: nbits = getdtablesize (); ! 674: ! 675: if (debug == 0 && !(debug = isatty (2))) { ! 676: for (i = 0; i < 5; i++) { ! 677: switch (fork ()) { ! 678: case NOTOK: ! 679: sleep (5); ! 680: continue; ! 681: ! 682: case OK: ! 683: break; ! 684: ! 685: default: ! 686: _exit (0); ! 687: } ! 688: break; ! 689: } ! 690: ! 691: (void) chdir ("/"); ! 692: ! 693: if ((sd = open ("/dev/null", O_RDWR)) == NOTOK) ! 694: adios ("/dev/null", "unable to read"); ! 695: if (sd != 0) ! 696: (void) dup2 (sd, 0), (void) close (sd); ! 697: (void) dup2 (0, 1); ! 698: (void) dup2 (0, 2); ! 699: ! 700: #ifdef SETSID ! 701: if (setsid () == NOTOK) ! 702: advise (LLOG_EXCEPTIONS, "failed", "setsid"); ! 703: #endif ! 704: #ifdef TIOCNOTTY ! 705: if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) { ! 706: (void) ioctl (sd, TIOCNOTTY, NULLCP); ! 707: (void) close (sd); ! 708: } ! 709: #else ! 710: #ifdef SYS5 ! 711: (void) setpgrp (); ! 712: (void) signal (SIGINT, SIG_IGN); ! 713: (void) signal (SIGQUIT, SIG_IGN); ! 714: #endif ! 715: #endif ! 716: } ! 717: else ! 718: ll_dbinit (pgm_log, myname); ! 719: ! 720: #ifndef sun /* damn YP... */ ! 721: for (sd = 3; sd < nbits; sd++) ! 722: if (pgm_log -> ll_fd != sd) ! 723: (void) close (sd); ! 724: #endif ! 725: ! 726: (void) signal (SIGPIPE, SIG_IGN); ! 727: ! 728: ll_hdinit (pgm_log, myname); ! 729: advise (LLOG_NOTICE, NULLCP, "starting"); ! 730: } ! 731: ! 732: /* ERRORS */ ! 733: ! 734: #ifndef lint ! 735: void adios (va_alist) ! 736: va_dcl ! 737: { ! 738: va_list ap; ! 739: ! 740: va_start (ap); ! 741: ! 742: _ll_log (pgm_log, LLOG_FATAL, ap); ! 743: ! 744: va_end (ap); ! 745: ! 746: _exit (1); ! 747: } ! 748: #else ! 749: /* VARARGS */ ! 750: ! 751: void adios (what, fmt) ! 752: char *what, ! 753: *fmt; ! 754: { ! 755: adios (what, fmt); ! 756: } ! 757: #endif ! 758: ! 759: ! 760: #ifndef lint ! 761: void advise (va_alist) ! 762: va_dcl ! 763: { ! 764: int code; ! 765: va_list ap; ! 766: ! 767: va_start (ap); ! 768: ! 769: code = va_arg (ap, int); ! 770: ! 771: _ll_log (pgm_log, code, ap); ! 772: ! 773: va_end (ap); ! 774: } ! 775: #else ! 776: /* VARARGS */ ! 777: ! 778: void advise (code, what, fmt) ! 779: char *what, ! 780: *fmt; ! 781: int code; ! 782: { ! 783: advise (code, what, fmt); ! 784: } ! 785: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.