|
|
1.1 ! root 1: /* tp0bridge.c - TCP/X.25 TP0 bridge */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/others/tp0bridge/RCS/tp0bridge.c,v 7.1 90/07/09 14:42:52 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/others/tp0bridge/RCS/tp0bridge.c,v 7.1 90/07/09 14:42:52 mrose Exp $ ! 9: * ! 10: * Contributed by Julian Onions, Nottingham University in the UK ! 11: * ! 12: * ! 13: * $Log: tp0bridge.c,v $ ! 14: * Revision 7.1 90/07/09 14:42:52 mrose ! 15: * sync ! 16: * ! 17: * Revision 7.0 89/11/23 22:11:02 mrose ! 18: * Release 6.0 ! 19: * ! 20: */ ! 21: ! 22: /* ! 23: * NOTICE ! 24: * ! 25: * Acquisition, use, and distribution of this module and related ! 26: * materials are subject to the restrictions of a license agreement. ! 27: * Consult the Preface in the User's Manual for the full terms of ! 28: * this agreement. ! 29: * ! 30: */ ! 31: ! 32: ! 33: #include <signal.h> ! 34: #include <stdio.h> ! 35: #include <varargs.h> ! 36: #include "tpkt.h" ! 37: #include <sys/ioctl.h> ! 38: #ifdef BSD42 ! 39: #include <sys/file.h> ! 40: #endif ! 41: #ifdef SYS5 ! 42: #include <fcntl.h> ! 43: #endif ! 44: #include "internet.h" ! 45: #include "x25.h" ! 46: #include "logger.h" ! 47: #include "tailor.h" ! 48: ! 49: /* */ ! 50: ! 51: static int debug = 0; ! 52: static int options = 0; ! 53: static int nbits = FD_SETSIZE; ! 54: ! 55: static LLog _pgm_log = { ! 56: "tp0bridge.log", NULLCP, NULLCP, ! 57: LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, LLOG_FATAL, -1, ! 58: LLOGCLS | LLOGCRT | LLOGZER, NOTOK ! 59: }; ! 60: LLog *pgm_log = &_pgm_log; ! 61: ! 62: static char *myname = "tp0bridge"; ! 63: static char myhost[64]; ! 64: ! 65: static char *myprotocol = "tcp"; ! 66: static char *myservice = "x25bridge"; ! 67: ! 68: static int tcp_fd; ! 69: static int nfds; ! 70: static fd_set ifds; ! 71: static struct sockaddr_in main_in_socket; ! 72: static struct sockaddr_in *mainisock = &main_in_socket; ! 73: static struct sockaddr_in emptyaddr; ! 74: ! 75: static fd_set sentinel; ! 76: static int sent2list[FD_SETSIZE]; ! 77: static int list2sent[FD_SETSIZE]; ! 78: static struct sockaddr_in callbacks[FD_SETSIZE]; ! 79: #ifdef CAMTEC ! 80: static struct NSAPaddr listens[FD_SETSIZE]; ! 81: #define FORK_LISTENER /* new process per listener */ ! 82: #endif ! 83: ! 84: ! 85: void abortfd (), shuffle (); ! 86: void adios (), advise (); ! 87: #ifdef BSD42 ! 88: int chldser (); ! 89: #else ! 90: int alrmser (); ! 91: #endif ! 92: ! 93: ! 94: extern int errno; ! 95: ! 96: /* */ ! 97: ! 98: /* ARGSUSED */ ! 99: ! 100: main (argc, argv, envp) ! 101: int argc; ! 102: char **argv, ! 103: **envp; ! 104: { ! 105: int fd; ! 106: fd_set mask; ! 107: ! 108: arginit (argv); ! 109: envinit (); ! 110: ! 111: nfds = 0; ! 112: FD_ZERO (&ifds); ! 113: FD_ZERO (&sentinel); ! 114: ! 115: if ((tcp_fd = start_tcp_server (mainisock, SOMAXCONN, options & SO_DEBUG ! 116: ? SO_DEBUG : 0, 0)) == NOTOK) ! 117: adios ("failed", "start_tcp_server"); ! 118: FD_SET (tcp_fd, &ifds); ! 119: if (tcp_fd >= nfds) ! 120: nfds = tcp_fd + 1; ! 121: ! 122: #ifdef BSD42 ! 123: (void) signal (SIGCHLD, chldser); ! 124: #endif ! 125: ! 126: for (;;) { ! 127: mask = ifds; ! 128: ! 129: #ifdef CAMTEC ! 130: /* due to problems in select when camtec is enabled, a small ! 131: timeout is given. This should not affect anything I hope. ! 132: */ ! 133: (void) xselect (nfds, &mask, NULLFD, NULLFD, 1); ! 134: #else ! 135: (void) xselect (nfds, &mask, NULLFD, NULLFD, NOTOK); ! 136: #endif ! 137: ! 138: for (fd = 0; fd < nbits; fd++) ! 139: if (FD_ISSET (fd, &mask)) { ! 140: if (fd == tcp_fd) ! 141: do_new_fd (); ! 142: else if (FD_ISSET (fd, &sentinel)) ! 143: abortfd (fd); ! 144: else ! 145: do_old_fd (fd); ! 146: } ! 147: ! 148: #ifndef BSD42 ! 149: while (mywait3 (NULLIP) != NOTOK) ! 150: continue; ! 151: #endif ! 152: } ! 153: } ! 154: ! 155: /* */ ! 156: ! 157: static do_new_fd () ! 158: { ! 159: int fd; ! 160: char c; ! 161: struct sockaddr_in zosock; ! 162: struct sockaddr_in *osock = & zosock; ! 163: ! 164: if ((fd = join_tcp_client (tcp_fd, osock)) == NOTOK) { ! 165: if (errno != EINTR) ! 166: advise (LLOG_EXCEPTIONS, "failed", "join_tcp_client"); ! 167: return; ! 168: } ! 169: ! 170: if (read_tcp_socket (fd, &c, 1) != 1) { ! 171: advise (LLOG_EXCEPTIONS, "failed", "initial read_tcp_socket"); ! 172: goto out; ! 173: } ! 174: ! 175: switch (c) { ! 176: case 1: ! 177: #ifdef DEBUG ! 178: advise (LLOG_DEBUG, NULLCP, "outgoing connection"); ! 179: #endif ! 180: switch (fork ()) { ! 181: case OK: ! 182: do_outgoing (fd); ! 183: _exit (1); /* NOTREACHED */ ! 184: ! 185: case NOTOK: ! 186: advise (LLOG_EXCEPTIONS, "TCP socket", ! 187: "no forks, so rejecting connection on"); ! 188: default: ! 189: (void) close_tcp_socket (fd); ! 190: #ifdef EXOS ! 191: FD_CLR (tcp_fd, &ifds); ! 192: if ((tcp_fd = start_tcp_server (isock, SOMAXCONN, ! 193: options & SO_DEBUG ? SO_DEBUG : 0, 0)) ! 194: == NOTOK) ! 195: adios ("failed", "start_tcp_server"); ! 196: FD_SET (tcp_fd, &ifds); ! 197: if (tcp_fd >= nfds) ! 198: nfds = tcp_fd + 1; ! 199: #endif ! 200: break; ! 201: } ! 202: break; ! 203: ! 204: case 2: ! 205: #ifdef DEBUG ! 206: advise (LLOG_DEBUG, NULLCP, "setup listen address"); ! 207: #endif ! 208: do_listen (fd); ! 209: break; ! 210: ! 211: default: ! 212: advise (LLOG_NOTICE, NULLCP, "unknown dialogue mode 0x%x", c); ! 213: out: ; ! 214: (void) close_tcp_socket (fd); ! 215: break; ! 216: ! 217: } ! 218: } ! 219: ! 220: /* */ ! 221: ! 222: static do_outgoing (fd) ! 223: int fd; ! 224: { ! 225: int sd; ! 226: struct NSAPaddr znsap; ! 227: register struct NSAPaddr *nsap = &znsap; ! 228: ! 229: #ifdef SOCKETS ! 230: (void) close_tcp_socket (tcp_fd); ! 231: #endif ! 232: for (sd = 0; sd < nbits; sd++) ! 233: if (sd != fd && FD_ISSET (sd, &ifds)) ! 234: (void) close (sd); ! 235: #ifdef BSD42 ! 236: (void) signal (SIGCHLD, SIG_DFL); ! 237: #endif ! 238: ! 239: (void) ll_close (pgm_log); ! 240: ! 241: if (bridge_read_nsap_addr (fd, nsap, read_tcp_socket) == NOTOK) ! 242: adios ("failed", "read of NSAP"); ! 243: ! 244: switch (nsap -> na_stack) { ! 245: case NA_BRG: ! 246: nsap -> na_stack = NA_X25; /* we use real X.25 here */ ! 247: break; ! 248: case NA_X25: ! 249: break; ! 250: case NA_NSAP: ! 251: case NA_TCP: ! 252: default: ! 253: adios (NULLCP, "Addressing style not supported (type %d)", ! 254: nsap -> na_stack); ! 255: break; ! 256: } ! 257: ! 258: #ifdef DEBUG ! 259: advise(LLOG_DEBUG, NULLCP, "x25 call on to %*s\n", ! 260: nsap->na_dtelen, nsap->na_dte); ! 261: #endif ! 262: if ((sd = start_x25_client (nsap)) == NOTOK) ! 263: adios ("failed", "start_x25_client"); ! 264: ! 265: if (join_x25_server (sd, nsap) == NOTOK) ! 266: adios ("failed", "join_x25_server"); ! 267: ! 268: transfer (sd, fd); ! 269: } ! 270: ! 271: /* */ ! 272: ! 273: static do_listen (fd) ! 274: int fd; ! 275: { ! 276: struct sockaddr_in in_socket; ! 277: register struct sockaddr_in *isock = &in_socket; ! 278: struct NSAPaddr znsap; ! 279: register struct NSAPaddr *nsap = &znsap; ! 280: int newfd; ! 281: ! 282: if (bridge_read_nsap_addr (fd, nsap, read_tcp_socket) == NOTOK) { ! 283: advise (LLOG_EXCEPTIONS, "failed", "read of NSAP"); ! 284: goto out; ! 285: } ! 286: switch (nsap -> na_stack) { ! 287: case NA_BRG: ! 288: nsap -> na_stack = NA_X25; /* we use real X.25 here */ ! 289: break; ! 290: case NA_X25: ! 291: break; ! 292: case NA_NSAP: ! 293: case NA_TCP: ! 294: default: ! 295: adios (NULLCP, "Addressing style not supported (type %d)", ! 296: nsap -> na_stack); ! 297: break; ! 298: } ! 299: ! 300: #ifdef DEBUG ! 301: advise (LLOG_DEBUG, NULLCP, "type=%d Listening on '%s' len=%d", ! 302: nsap -> na_stack, nsap -> na_dte, nsap -> na_dtelen); ! 303: advise (LLOG_DEBUG, NULLCP, "pid='%s'(%d) fac='%s'(%d) cudf='%s'(%d)", ! 304: nsap -> na_pid, nsap -> na_pidlen, ! 305: nsap -> na_fac, nsap -> na_faclen, ! 306: nsap -> na_pid, nsap -> na_pidlen, ! 307: nsap -> na_cudf, nsap -> na_cudflen); ! 308: #endif ! 309: if (readx (fd, (char *) isock, sizeof *isock, read_tcp_socket) ! 310: != sizeof *isock) { ! 311: advise (LLOG_EXCEPTIONS, "failed", ! 312: "read_tcp_socket of sockaddr_in"); ! 313: goto out; ! 314: } ! 315: isock -> sin_family = ntohs (isock -> sin_family); ! 316: ! 317: #ifdef FORK_LISTENER ! 318: switch (fork ()) { ! 319: case OK: ! 320: { ! 321: int i; ! 322: ! 323: for (i = 0; i < nbits; i++) ! 324: if (i != fd && FD_ISSET (i, &ifds)) ! 325: (void) close (i); ! 326: break; ! 327: } ! 328: case NOTOK: ! 329: advise (LLOG_EXCEPTIONS, "X25 socket", ! 330: "no forks, so rejecting listen on"); ! 331: default: ! 332: (void) close_tcp_socket (fd); ! 333: return; ! 334: } ! 335: /* more from the 'stamp out boring names' committee */ ! 336: #define iso_defining_new_protocols 1 ! 337: while (iso_defining_new_protocols) ! 338: { ! 339: #endif ! 340: if ((newfd = start_x25_server (nsap, SOMAXCONN, options & SO_DEBUG ! 341: ? SO_DEBUG : 0, 0)) == NOTOK) { ! 342: advise (LLOG_EXCEPTIONS, "failed", "start_x25_server"); ! 343: #ifdef FORK_LISTENER ! 344: _exit (0); ! 345: #endif ! 346: return; ! 347: } ! 348: #ifdef CAMTEC ! 349: listens[newfd] = *nsap; /* struct copy */ ! 350: #endif ! 351: callbacks[newfd] = *isock; /* struct copy */ ! 352: ! 353: /* set up the admin stuff */ ! 354: FD_SET (newfd, &ifds); /* listen for new connections */ ! 355: FD_SET (fd, &ifds); /* listen for problems */ ! 356: FD_SET (fd, &sentinel); ! 357: sent2list[fd] = newfd; ! 358: list2sent[newfd] = fd; ! 359: if (newfd >= nfds) ! 360: nfds = newfd + 1; ! 361: #ifdef FORK_LISTENER ! 362: do_old_fd (newfd); ! 363: (void) close (newfd); ! 364: } /* loop again */ ! 365: #endif ! 366: return; ! 367: ! 368: out: ; ! 369: (void) close_tcp_socket (fd); ! 370: } ! 371: ! 372: ! 373: /* */ ! 374: ! 375: static do_old_fd (fd) ! 376: int fd; ! 377: { ! 378: int sd; ! 379: register struct sockaddr_in *isock = &callbacks[fd]; ! 380: struct NSAPaddr znsap; ! 381: register struct NSAPaddr *nsap = &znsap; ! 382: ! 383: #ifdef DEBUG ! 384: advise (LLOG_DEBUG, NULLCP, "callback"); ! 385: #endif ! 386: if (isock == NULL || isock -> sin_family != AF_INET) { ! 387: advise (LLOG_EXCEPTIONS, NULLCP, "Callback has bogus address"); ! 388: return; ! 389: } ! 390: ! 391: if ((sd = join_x25_client (fd, nsap)) == NOTOK) { ! 392: if (errno != EINTR) { ! 393: advise (LLOG_EXCEPTIONS, "failed", "join_x25_client"); ! 394: abortfd (list2sent[fd]); ! 395: } ! 396: return; ! 397: } ! 398: #ifdef DEBUG ! 399: advise (LLOG_DEBUG, NULLCP, "type=%d Accepted '%s' len=%d", ! 400: nsap -> na_stack, nsap -> na_dte, nsap -> na_dtelen); ! 401: advise (LLOG_DEBUG, NULLCP, "pid='%s'(%d) fac='%s'(%d) cudf='%s'(%d)", ! 402: nsap -> na_pid, nsap -> na_pidlen, ! 403: nsap -> na_fac, nsap -> na_faclen, ! 404: nsap -> na_pid, nsap -> na_pidlen, ! 405: nsap -> na_cudf, nsap -> na_cudflen); ! 406: #endif ! 407: nsap -> na_stack = NA_BRG; ! 408: ! 409: #ifdef CAMTEC ! 410: /* get back addressing info for this fd into nsap ! 411: */ ! 412: nsap = &listens[fd]; ! 413: #endif ! 414: ! 415: switch (fork ()) { ! 416: case OK: ! 417: break; ! 418: ! 419: case NOTOK: ! 420: advise (LLOG_EXCEPTIONS, "X.25 socket", ! 421: "no forks, so rejecting connection on"); ! 422: default: ! 423: (void) close (sd); ! 424: return; ! 425: } ! 426: ! 427: #ifndef CAMTEC ! 428: (void) close (fd); ! 429: #endif ! 430: for (fd = 0; fd < nbits; fd++) ! 431: if (fd != sd && FD_ISSET (fd, &ifds)) ! 432: (void) close (fd); ! 433: #ifdef BSD42 ! 434: (void) signal (SIGCHLD, SIG_DFL); ! 435: #endif ! 436: ! 437: (void) ll_close (pgm_log); ! 438: ! 439: #ifdef DEBUG ! 440: advise (LLOG_DEBUG, NULLCP, "connecting to %s", inet_ntoa (isock -> sin_addr)); ! 441: advise (LLOG_DEBUG, NULLCP, "port=%d", (int) ntohs (isock -> sin_port)); ! 442: #endif ! 443: ! 444: if ((fd = start_tcp_client ((struct sockaddr_in *) NULL, 0)) == NOTOK) ! 445: adios ("failed", "start_tcp_client"); ! 446: if (join_tcp_server (fd, isock) == NOTOK) ! 447: adios ("failed", "join_tcp_server"); ! 448: ! 449: if (bridge_write_nsap_addr (fd, nsap, write_tcp_socket) == NOTOK) ! 450: adios ("failed", "write of NSAP"); ! 451: ! 452: transfer (sd, fd); ! 453: _exit (1); /* NOTREACHED */ ! 454: } ! 455: ! 456: /* */ ! 457: ! 458: static transfer (sd, fd) ! 459: int sd, ! 460: fd; ! 461: { ! 462: int mfds; ! 463: fd_set rfds, ! 464: mask; ! 465: struct tsapblk *tcpb, ! 466: *x25b; ! 467: ! 468: FD_ZERO (&rfds); ! 469: mfds = (sd > fd ? sd : fd) + 1; ! 470: FD_SET (sd, &rfds); ! 471: FD_SET (fd, &rfds); ! 472: ! 473: if ((tcpb = newtblk ()) == NULL) ! 474: adios (NULLCP, "out of memory"); ! 475: tcpb -> tb_fd = fd; ! 476: (void) TTService (tcpb); ! 477: ! 478: if ((x25b = newtblk ()) == NULL) ! 479: adios (NULLCP, "out of memory"); ! 480: x25b -> tb_fd = sd; ! 481: (void) XTService (x25b); ! 482: ! 483: #ifndef CAMTEC ! 484: for (;;) { ! 485: mask = rfds; ! 486: if (xselect (mfds, &mask, NULLFD, NULLFD, NOTOK) == NOTOK) ! 487: adios ("failed", "xselect"); ! 488: if (FD_ISSET (sd, &mask)) ! 489: shuffle (x25b, tcpb); ! 490: if (FD_ISSET (fd, &mask)) ! 491: shuffle (tcpb, x25b); ! 492: } ! 493: #else ! 494: for (;;) { ! 495: FD_ZERO (&mask); ! 496: mfds = fd + 1; ! 497: FD_SET (fd, &mask); ! 498: if (xselect (mfds, &mask, NULLFD, NULLFD, 1) == NOTOK) ! 499: adios ("failed", "xselect tcp"); ! 500: if (FD_ISSET (fd, &mask)) { ! 501: advise (LLOG_DEBUG, NULLCP, "tcp -> x25"); ! 502: shuffle (tcpb, x25b); ! 503: } ! 504: ! 505: FD_ZERO (&mask); ! 506: mfds = sd + 1; ! 507: FD_SET (sd, &mask); ! 508: if (xselect (mfds, &mask, NULLFD, NULLFD, 1) == NOTOK) ! 509: adios ("failed", "xselect x25"); ! 510: if (FD_ISSET (sd, &mask)) { ! 511: advise (LLOG_DEBUG, NULLCP, "x25 -> tcp"); ! 512: shuffle (x25b, tcpb); ! 513: } ! 514: } ! 515: #endif ! 516: } ! 517: ! 518: /* */ ! 519: ! 520: static void shuffle (from, to) ! 521: register struct tsapblk *from, ! 522: *to; ! 523: { ! 524: register struct udvec *uv; ! 525: register struct tsapkt *t; ! 526: ! 527: if ((t = fd2tpkt (from -> tb_fd, from -> tb_initfnx, from -> tb_readfnx)) ! 528: == NULL || t -> t_errno != OK) ! 529: adios (NULLCP, "fd2tpkt failed (%d)", t ? t -> t_errno : NOTOK); ! 530: #ifdef DEBUG ! 531: advise (LLOG_DEBUG, NULLCP, "read: code=0x%x user len=%d", ! 532: TPDU_CODE (t), t -> t_qbuf ? t -> t_qbuf -> qb_len : 0); ! 533: #endif ! 534: ! 535: uv = t -> t_udvec; ! 536: if (t -> t_qbuf) { ! 537: uv -> uv_base = t -> t_qbuf -> qb_data; ! 538: uv -> uv_len = t -> t_qbuf -> qb_len; ! 539: uv++; ! 540: } ! 541: uv -> uv_base = NULL; ! 542: ! 543: if (tpkt2fd (to -> tb_fd, t, to -> tb_writefnx) == NOTOK) ! 544: adios (NULLCP, "tpkt2fd failed (%d)", t -> t_errno); ! 545: ! 546: freetpkt (t); ! 547: } ! 548: ! 549: static void abortfd (fd) ! 550: int fd; ! 551: { ! 552: int assocfd = sent2list[fd]; /* get fd that is listening on */ ! 553: ! 554: #ifdef DEBUG ! 555: advise (LLOG_DEBUG, NULLCP, "Shutdown listen (%d,%d)", fd, assocfd); ! 556: #endif ! 557: FD_CLR (fd, &sentinel); ! 558: FD_CLR (fd, &ifds); ! 559: FD_CLR (assocfd, &ifds); ! 560: (void) close_tcp_socket (fd); ! 561: (void) close_x25_socket (assocfd); ! 562: sent2list[fd] = -1; ! 563: list2sent[assocfd] = -1; ! 564: callbacks[assocfd] = emptyaddr; /* struct copy */ ! 565: } ! 566: ! 567: /* */ ! 568: ! 569: static arginit (vec) ! 570: char **vec; ! 571: { ! 572: int port; ! 573: register char *ap; ! 574: struct hostent *hp; ! 575: struct servent *sp; ! 576: ! 577: if (myname = rindex (*vec, '/')) ! 578: myname++; ! 579: if (myname == NULL || *myname == NULL) ! 580: myname = *vec; ! 581: ! 582: isodetailor (myname, 0); ! 583: ll_hdinit (pgm_log, myname); ! 584: ! 585: (void) gethostname (myhost, sizeof myhost); ! 586: if (hp = gethostbyname (myhost)) ! 587: (void) strcpy (myhost, hp -> h_name); ! 588: ! 589: if ((sp = getservbyname (myservice, myprotocol)) == NULL) ! 590: mainisock -> sin_port = x25_bridge_port; ! 591: else ! 592: mainisock -> sin_port = sp -> s_port; ! 593: mainisock -> sin_family = AF_INET; ! 594: mainisock -> sin_addr.s_addr = INADDR_ANY; ! 595: if ((nbits = getdtablesize ()) > FD_SETSIZE) ! 596: nbits = FD_SETSIZE; ! 597: ! 598: for (vec++; ap = *vec; vec++) { ! 599: if (*ap == '-') ! 600: switch (*++ap) { ! 601: case 'd': ! 602: debug++; ! 603: continue; ! 604: ! 605: case 'p': ! 606: if ((ap = *++vec) == NULL ! 607: || *ap == '-' ! 608: || (port = atoi (ap)) <= 0) ! 609: adios (NULLCP, "usage: %s -p portno", myname); ! 610: mainisock -> sin_port = htons ((u_short) port); ! 611: continue; ! 612: ! 613: default: ! 614: adios (NULLCP, "-%s: unknown switch", ap); ! 615: } ! 616: ! 617: adios (NULLCP, "usage: %s [switches]", myname); ! 618: } ! 619: } ! 620: ! 621: /* */ ! 622: ! 623: static envinit () { ! 624: int i, ! 625: sd; ! 626: ! 627: if (debug == 0 && !(debug = isatty (2))) { ! 628: for (i = 0; i < 5; i++) { ! 629: switch (fork ()) { ! 630: case NOTOK: ! 631: sleep (5); ! 632: continue; ! 633: ! 634: case OK: ! 635: break; ! 636: ! 637: default: ! 638: _exit (0); ! 639: } ! 640: break; ! 641: } ! 642: ! 643: (void) chdir ("/"); ! 644: ! 645: if ((sd = open ("/dev/null", O_RDWR)) == NOTOK) ! 646: adios ("/dev/null", "unable to read"); ! 647: if (sd != 0) ! 648: (void) dup2 (sd, 0), (void) close (sd); ! 649: (void) dup2 (0, 1); ! 650: (void) dup2 (0, 2); ! 651: ! 652: #ifdef SETSID ! 653: if (setsid () == NOTOK) ! 654: advise (LLOG_EXCEPTIONS, "failed", "setsid"); ! 655: #endif ! 656: #ifdef TIOCNOTTY ! 657: if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) { ! 658: (void) ioctl (sd, TIOCNOTTY, NULLCP); ! 659: (void) close (sd); ! 660: } ! 661: #endif ! 662: } ! 663: else { ! 664: options |= SO_DEBUG; ! 665: ll_dbinit (pgm_log, myname); ! 666: } ! 667: ! 668: #ifndef sun /* damn YP... */ ! 669: for (sd = 3; sd < nbits; sd++) ! 670: if (pgm_log -> ll_fd != sd) ! 671: (void) close (sd); ! 672: #endif ! 673: ! 674: (void) signal (SIGPIPE, SIG_IGN); ! 675: ! 676: ll_hdinit (pgm_log, myname); ! 677: advise (LLOG_NOTICE, NULLCP, "starting"); ! 678: #ifdef DEBUG ! 679: advise (LLOG_DEBUG, NULLCP, "options=0x%x port=%d", ! 680: options, ntohs (mainisock -> sin_port)); ! 681: #endif ! 682: } ! 683: ! 684: /* Berkeley UNIX: 4.2 */ ! 685: ! 686: #ifdef BSD42 ! 687: ! 688: #include <sys/wait.h> ! 689: ! 690: /* ARGSUSED */ ! 691: ! 692: static int chldser (sig, code, sc) ! 693: int sig; ! 694: long code; ! 695: struct sigcontext *sc; ! 696: { ! 697: union wait status; ! 698: ! 699: while (wait3 (&status, WNOHANG, (struct rusage *) NULL) > 0) ! 700: continue; ! 701: } ! 702: ! 703: #else ! 704: ! 705: /* AT&T UNIX: 5 */ ! 706: ! 707: #include <setjmp.h> ! 708: ! 709: #define WAITSECS ((unsigned) 2) ! 710: ! 711: ! 712: static jmp_buf jmpenv; ! 713: ! 714: ! 715: /* ARGSUSED */ ! 716: ! 717: static int alrmser (sig) ! 718: int sig; ! 719: { ! 720: (void) signal (SIGALRM, alrmser); ! 721: ! 722: longjmp (jmpenv, NOTOK); ! 723: } ! 724: ! 725: ! 726: static int mywait3 (status) ! 727: int *status; ! 728: { ! 729: int result; ! 730: ! 731: switch (setjmp (jmpenv)) { ! 732: case OK: ! 733: (void) signal (SIGALRM, alrmser); ! 734: (void) alarm (WAITSECS); ! 735: result = wait (status); ! 736: (void) alarm (0); ! 737: break; ! 738: ! 739: default: ! 740: result = NOTOK; ! 741: break; ! 742: } ! 743: ! 744: return result; ! 745: } ! 746: #endif ! 747: ! 748: /* */ ! 749: ! 750: static int readx (fd, buffer, n, readfnx) ! 751: int fd; ! 752: char *buffer; ! 753: int n; ! 754: IFP readfnx; ! 755: { ! 756: register int i, ! 757: cc; ! 758: register char *bp; ! 759: ! 760: for (bp = buffer, i = n; i > 0; bp += cc, i -= cc) { ! 761: switch (cc = (*readfnx) (fd, bp, i)) { ! 762: case NOTOK: ! 763: return (i = bp - buffer) ? i : NOTOK; ! 764: ! 765: case OK: ! 766: break; ! 767: ! 768: default: ! 769: continue; ! 770: } ! 771: break; ! 772: } ! 773: ! 774: return (bp - buffer); ! 775: } ! 776: ! 777: /* ERRORS */ ! 778: ! 779: #ifndef lint ! 780: void adios (va_alist) ! 781: va_dcl ! 782: { ! 783: va_list ap; ! 784: ! 785: va_start (ap); ! 786: ! 787: _ll_log (pgm_log, LLOG_FATAL, ap); ! 788: ! 789: va_end (ap); ! 790: ! 791: _exit (1); ! 792: } ! 793: #else ! 794: /* VARARGS */ ! 795: ! 796: void adios (what, fmt) ! 797: char *what, ! 798: *fmt; ! 799: { ! 800: adios (what, fmt); ! 801: } ! 802: #endif ! 803: ! 804: ! 805: #ifndef lint ! 806: void advise (va_alist) ! 807: va_dcl ! 808: { ! 809: int code; ! 810: va_list ap; ! 811: ! 812: va_start (ap); ! 813: ! 814: code = va_arg (ap, int); ! 815: ! 816: _ll_log (pgm_log, code, ap); ! 817: ! 818: va_end (ap); ! 819: } ! 820: #else ! 821: /* VARARGS */ ! 822: ! 823: void advise (code, what, fmt) ! 824: char *what, ! 825: *fmt; ! 826: int code; ! 827: { ! 828: advise (code, what, fmt); ! 829: } ! 830: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.