|
|
1.1 ! root 1: /* tsbridge.c: transport bridge - jpo version ! */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/others/tsbridge/RCS/tsbridge.c,v 7.5 90/07/09 14:43:01 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/others/tsbridge/RCS/tsbridge.c,v 7.5 90/07/09 14:43:01 mrose Exp $ ! 9: * ! 10: * Contributed by Julian Onions, Nottingham University in the UK ! 11: * ! 12: * ! 13: * $Log: tsbridge.c,v $ ! 14: * Revision 7.5 90/07/09 14:43:01 mrose ! 15: * sync ! 16: * ! 17: * Revision 7.4 90/03/19 14:27:00 mrose ! 18: * jpo ! 19: * ! 20: * Revision 7.2 90/01/11 18:36:55 mrose ! 21: * real-sync ! 22: * ! 23: * Revision 7.1 89/11/27 05:43:28 mrose ! 24: * sync ! 25: * ! 26: * Revision 7.0 89/11/23 22:11:12 mrose ! 27: * Release 6.0 ! 28: * ! 29: */ ! 30: ! 31: /* ! 32: * NOTICE ! 33: * ! 34: * Acquisition, use, and distribution of this module and related ! 35: * materials are subject to the restrictions of a license agreement. ! 36: * Consult the Preface in the User's Manual for the full terms of ! 37: * this agreement. ! 38: * ! 39: */ ! 40: ! 41: ! 42: #include <signal.h> ! 43: #include <stdio.h> ! 44: #include <varargs.h> ! 45: #include "manifest.h" ! 46: #include <sys/ioctl.h> ! 47: #ifdef BSD42 ! 48: #include <sys/file.h> ! 49: #endif ! 50: #ifdef SYS5 ! 51: #include <fcntl.h> ! 52: #endif ! 53: #include "tsap.h" ! 54: #include "logger.h" ! 55: #include "psap.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: "tsbridge.log", NULLCP, NULLCP, ! 65: LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, LLOG_FATAL, ! 66: -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK ! 67: }; ! 68: ! 69: LLog *pgm_log = &_pgm_log; ! 70: ! 71: static char *myname = "tsbridge"; ! 72: ! 73: typedef struct ContTbl { ! 74: struct TSAPaddr src; ! 75: struct TSAPaddr dest; ! 76: unsigned int flags; ! 77: #define CONN_STRICT 01 ! 78: #define CONN_TRANS 02 ! 79: #define CONN_NOMUNGE 04 ! 80: #define CONN_FORCEMUNGE 010 ! 81: } ContTbl; ! 82: ContTbl con_tbl[FD_SETSIZE]; ! 83: int con_tbl_cnt = 0; ! 84: ! 85: static struct TSAPaddr *maketa (); ! 86: static struct TSAPaddr *getnewta (); ! 87: static ContTbl *find_connection (); ! 88: ! 89: static void read_file (); ! 90: ! 91: static void adios (), advise (); ! 92: ! 93: static void ts_adios (), ts_advise (); ! 94: static void ts_close (), ts_discon (); ! 95: static void tsbridge (), do_the_biz (), copy_tsdu (), arginit (), envinit (); ! 96: /* */ ! 97: ! 98: /* ARGSUSED */ ! 99: ! 100: main (argc, argv, envp) ! 101: int argc; ! 102: char **argv, ! 103: **envp; ! 104: { ! 105: struct TSAPdisconnect tds; ! 106: register struct TSAPdisconnect *td = &tds; ! 107: struct TSAPaddr tas, *ta = &tas; ! 108: int vecp; ! 109: char *vec[4]; ! 110: ! 111: arginit (argv); ! 112: ! 113: envinit (); ! 114: ! 115: for (vecp = 0; vecp < con_tbl_cnt; vecp++) { ! 116: advise (LLOG_TRACE, NULLCP, "Listening on %s", ! 117: taddr2str (&con_tbl[vecp].src)); ! 118: if (TNetListen (&con_tbl[vecp].src, td) == NOTOK) { ! 119: advise (LLOG_FATAL, NULLCP, "Listen failed on \"%s\"", ! 120: taddr2str (&con_tbl[vecp].src)); ! 121: ts_adios (td, "listen failed"); ! 122: } ! 123: } ! 124: ! 125: for (;;) { ! 126: if (TNetAcceptAux (&vecp, vec, NULLIP, ta, 0, NULLFD, NULLFD, ! 127: NULLFD, NOTOK, td) == NOTOK) ! 128: ts_adios (td, "accept failed"); ! 129: ! 130: if (vecp <= 0) ! 131: continue; ! 132: ! 133: advise (LLOG_TRACE, NULLCP, "accepted new connection"); ! 134: switch (TNetFork (vecp, vec, td)) { ! 135: case OK: ! 136: tsbridge (vecp, vec, ta); ! 137: exit (1); ! 138: /* NOTREACHED */ ! 139: ! 140: case NOTOK: ! 141: ts_advise (td, LLOG_EXCEPTIONS, "fork failed"); ! 142: break; ! 143: ! 144: default: ! 145: break; ! 146: } ! 147: } ! 148: } ! 149: ! 150: /* */ ! 151: ! 152: static void tsbridge (vecp, vec, ta) ! 153: int vecp; ! 154: char **vec; ! 155: struct TSAPaddr *ta; ! 156: { ! 157: struct TSAPstart tss; ! 158: register struct TSAPstart *ts = &tss; ! 159: struct TSAPdisconnect tds; ! 160: register struct TSAPdisconnect *td = &tds; ! 161: struct TSAPaddr *tota; ! 162: struct TSAPaddr *fromta; ! 163: struct TSAPconnect tcs; ! 164: struct TSAPconnect *tc = &tcs; ! 165: int sd; ! 166: ContTbl *ctp; ! 167: ! 168: if (TInit (vecp, vec, ts, td) == NOTOK) ! 169: ts_adios (td, "T-CONNECT.INDICATION failed"); ! 170: ! 171: sd = ts -> ts_sd; ! 172: advise (LLOG_NOTICE, NULLCP, ! 173: "T-CONNECT.INDICATION: <%d, %s, %s, %d, %d>", ! 174: ts -> ts_sd, taddr2str (&ts -> ts_calling), ! 175: taddr2str (&ts -> ts_called), ! 176: ts -> ts_expedited, ts -> ts_tsdusize); ! 177: ! 178: ctp = find_connection (ta); ! 179: if (ctp == NULL) { ! 180: ts_close (sd, "Unknown listener address"); ! 181: exit (1); ! 182: } ! 183: advise (LLOG_TRACE, NULLCP, "Accepted from address %s", ! 184: taddr2str (&ctp -> src)); ! 185: ! 186: tota = getnewta (&ts -> ts_called, sd, ctp); ! 187: ! 188: fromta = maketa (&ts -> ts_calling, tota -> ta_addrs[0].na_stack, ctp); ! 189: ! 190: if ((ctp -> flags & CONN_TRANS) == 0) { ! 191: ts -> ts_expedited = 0; ! 192: if (ts -> ts_cc > 0) { ! 193: advise (LLOG_EXCEPTIONS, NULLCP, ! 194: "%d octets initial user-data", ! 195: ts -> ts_cc); ! 196: ts_close (sd, "initial user-data not allowed"); ! 197: exit (1); ! 198: } ! 199: } ! 200: ! 201: advise (LLOG_NOTICE, NULLCP, ! 202: "T-CONNECT.REQUEST: <%s, %s, %d, 0x%x/%d>", ! 203: taddr2str (fromta), taddr2str (tota), ts -> ts_expedited, ! 204: ts -> ts_data, ts -> ts_cc); ! 205: ! 206: if (TConnRequest (fromta, tota, ts -> ts_expedited, ! 207: ts -> ts_data, ts -> ts_cc, &ts -> ts_qos, ! 208: tc, td) == NOTOK) { ! 209: ts_close (sd, "connection establishment failed"); ! 210: ts_adios(td, "T-CONNECT.REQUEST"); ! 211: } ! 212: if (TConnResponse (sd, &tc -> tc_responding, ! 213: tc -> tc_expedited, tc -> tc_data, tc -> tc_cc, ! 214: &tc -> tc_qos, td) == NOTOK) { ! 215: ts_close (sd, "connection establishment failed"); ! 216: ts_close (tc -> tc_sd, "connection establishment failed"); ! 217: ts_adios (td, "T-CONNECT.RESPONSE"); ! 218: } ! 219: ! 220: do_the_biz (sd, tc -> tc_sd); ! 221: } ! 222: ! 223: /* */ ! 224: ! 225: static void do_the_biz (sd1, sd2) ! 226: int sd1, sd2; ! 227: { ! 228: int nfds = 0; ! 229: fd_set rmask, imask; ! 230: struct TSAPdisconnect tds; ! 231: register struct TSAPdisconnect *td = &tds; ! 232: ! 233: FD_ZERO (&rmask); ! 234: ! 235: if (TSelectMask (sd1, &rmask, &nfds, td) == NOTOK ! 236: || TSelectMask (sd2, &rmask, &nfds, td) == NOTOK) ! 237: ts_adios (td, "TSelectMask failed"); ! 238: ! 239: for (;;) { ! 240: imask = rmask; ! 241: if (xselect (nfds, &imask, NULLFD, NULLFD, NOTOK) == NOTOK) ! 242: adios ("select", "failed"); ! 243: ! 244: if (FD_ISSET (sd1, &imask)) ! 245: copy_tsdu (sd1, sd2); ! 246: if (FD_ISSET (sd2, &imask)) ! 247: copy_tsdu (sd2, sd1); ! 248: } ! 249: } ! 250: ! 251: /* */ ! 252: ! 253: static void copy_tsdu (s1, s2) ! 254: int s1, s2; ! 255: { ! 256: struct TSAPdisconnect tds; ! 257: register struct TSAPdisconnect *td = &tds; ! 258: struct TSAPdata txs; ! 259: register struct TSAPdata *tx = &txs; ! 260: int result; ! 261: char *p; ! 262: ! 263: SLOG (pgm_log, LLOG_DEBUG, NULLCP, ("copy_tsdu (%d -> %d)", s1, s2)); ! 264: ! 265: if (TReadRequest (s1, tx, OK, td) == NOTOK) { ! 266: switch (td -> td_reason) { ! 267: case DR_TIMER: ! 268: case DR_WAITING: ! 269: case DR_OPERATION: ! 270: case DR_PARAMETER: ! 271: ts_advise (td, LLOG_TRACE, "TReadRequest"); ! 272: return; ! 273: ! 274: case DR_NORMAL: ! 275: ts_discon (td, s2); ! 276: break; ! 277: ! 278: default: ! 279: ts_adios (td, "TReadRequest"); ! 280: } ! 281: } ! 282: ! 283: if (tx -> tx_expedited) { ! 284: SLOG (pgm_log, LLOG_DEBUG, NULLCP, ("TExpdRequest")); ! 285: p = qb2str (&tx -> tx_qbuf); ! 286: result = TExpdRequest (s2, p, tx -> tx_cc, td); ! 287: free (p); ! 288: } ! 289: else { ! 290: struct qbuf *qb; ! 291: int uiocnt = 0; ! 292: struct udvec uvec[100]; ! 293: int total; ! 294: ! 295: total = uiocnt = 0; ! 296: for (qb = tx-> tx_qbuf.qb_forw; qb != &tx -> tx_qbuf; ! 297: qb = qb -> qb_forw) { ! 298: uvec[uiocnt].uv_base = qb -> qb_data; ! 299: uvec[uiocnt++].uv_len = qb -> qb_len; ! 300: total += qb -> qb_len; ! 301: if (uiocnt > 100) ! 302: adios (NULLCP, "Internal buffer overflow"); ! 303: } ! 304: uvec[uiocnt].uv_base = NULLCP; ! 305: uvec[uiocnt].uv_len = 0; ! 306: if (tx -> tx_cc != total) ! 307: advise (NULLCP, LLOG_EXCEPTIONS, ! 308: "Mismatch in data %d != %d", ! 309: tx -> tx_cc, total); ! 310: SLOG (pgm_log, LLOG_DEBUG, NULLCP, ("TWriteRequest")); ! 311: result = TWriteRequest (s2, uvec, td); ! 312: } ! 313: TXFREE (tx); ! 314: ! 315: if (result == NOTOK) { ! 316: if (td -> td_reason == DR_NORMAL) ! 317: ts_discon (td, s1); ! 318: ! 319: ts_adios (td, tx -> tx_expedited ? "T-EXPEDITED-DATA.REQUEST" ! 320: : "T-DATA.REQUEST"); ! 321: } ! 322: } ! 323: ! 324: /* */ ! 325: ! 326: static void ts_discon (td, sd) ! 327: struct TSAPdisconnect *td; ! 328: int sd; ! 329: { ! 330: ts_close (sd, "Normal Disconnect"); ! 331: ts_advise (td, LLOG_NOTICE, "T-DISCONNECT.INDICATION"); ! 332: ! 333: exit (0); ! 334: } ! 335: ! 336: /* */ ! 337: ! 338: static void ts_close (sd, event) ! 339: int sd; ! 340: char *event; ! 341: { ! 342: struct TSAPdisconnect tds; ! 343: register struct TSAPdisconnect *td = &tds; ! 344: ! 345: if (strlen (event) >= TD_SIZE) ! 346: event = NULLCP; ! 347: if (TDiscRequest (sd, event, event ? strlen (event) + 1: 0, td) ! 348: == NOTOK) ! 349: ts_advise (td, LLOG_EXCEPTIONS, "T-DISCONNECT.REQUEST"); ! 350: } ! 351: ! 352: /* */ ! 353: ! 354: static void ts_adios (td, event) ! 355: register struct TSAPdisconnect *td; ! 356: char *event; ! 357: { ! 358: ts_advise (td, LLOG_EXCEPTIONS, event); ! 359: ! 360: exit (1); ! 361: } ! 362: ! 363: /* */ ! 364: ! 365: static void ts_advise (td, code, event) ! 366: register struct TSAPdisconnect *td; ! 367: int code; ! 368: char *event; ! 369: { ! 370: char buffer[BUFSIZ]; ! 371: ! 372: if (td -> td_cc > 0) ! 373: (void) sprintf (buffer, "[%s] %*.*s", ! 374: TErrString (td -> td_reason), ! 375: td -> td_cc, td -> td_cc, td -> td_data); ! 376: else ! 377: (void) sprintf (buffer, "[%s]", TErrString (td -> td_reason)); ! 378: ! 379: advise (code, NULLCP, "%s: %s", event, buffer); ! 380: } ! 381: ! 382: /* */ ! 383: ! 384: static struct TSAPaddr *getnewta (ta, sd, ctp) ! 385: struct TSAPaddr *ta; ! 386: int sd; ! 387: ContTbl *ctp; ! 388: { ! 389: static struct TSAPaddr newta; ! 390: struct TSAPaddr *nta = &newta; ! 391: char buffer[TSSIZE + 1]; ! 392: ! 393: if (ctp -> flags & CONN_TRANS) { /* make transparent address */ ! 394: *nta = ctp -> dest; /* struct copy */ ! 395: nta -> ta_selectlen = ta -> ta_selectlen; ! 396: bcopy (ta -> ta_selector, nta -> ta_selector, ! 397: ta -> ta_selectlen); ! 398: return nta; ! 399: } ! 400: ! 401: /* do the real TS bridge stuff */ ! 402: if (ta -> ta_selectlen == 0) { ! 403: ts_close (sd, "no transport selector"); ! 404: adios (NULLCP, "no transport selector"); ! 405: } ! 406: ! 407: bcopy (ta -> ta_selector, buffer, ta -> ta_selectlen); ! 408: buffer[ta -> ta_selectlen] = NULL; ! 409: ! 410: if ((nta = str2taddr (buffer)) == NULLTA) { ! 411: ts_close (sd, "unable to translate address"); ! 412: adios (NULLCP, "unable to translate \"%s\"", buffer); ! 413: } ! 414: newta = *nta; ! 415: ! 416: return &newta; ! 417: } ! 418: ! 419: /* */ ! 420: ! 421: static struct TSAPaddr *maketa (ta, type, ctp) ! 422: struct TSAPaddr *ta; ! 423: long type; ! 424: ContTbl *ctp; ! 425: { ! 426: static struct TSAPaddr newta; ! 427: register struct TSAPaddr *nta = &newta; ! 428: char *p; ! 429: int i; ! 430: struct PSAPaddr pas; ! 431: struct PSAPaddr *pa = &pas; ! 432: ! 433: if (ctp -> flags & CONN_NOMUNGE) { ! 434: *nta = *ta; /* struct copy */ ! 435: } ! 436: if (!(ctp -> flags & CONN_NOMUNGE) || (ctp -> flags & CONN_FORCEMUNGE)) { ! 437: bzero ((char *)pa, sizeof *pa); ! 438: pa -> pa_addr.sa_addr = *ta; ! 439: if ((p = _paddr2str (pa, NULLNA, -1)) == NULL) { ! 440: if (ctp -> flags & CONN_STRICT) ! 441: adios (NULLCP, "unable to convert address to text"); ! 442: advise (LLOG_NOTICE, NULLCP, ! 443: "unable to convert address to text"); ! 444: return ta; /* this may work... */ ! 445: } ! 446: else { ! 447: if ((nta -> ta_selectlen = strlen (p)) >= TSSIZE) { ! 448: if (ctp -> flags & CONN_STRICT) ! 449: adios (NULLCP, "new selector \"%s\" is too big", ! 450: p); ! 451: ! 452: advise (LLOG_NOTICE, NULLCP, ! 453: "new selector \"%s\" is too big", p); ! 454: return ta; ! 455: } ! 456: else ! 457: bcopy (p, nta -> ta_selector, TSSIZE); ! 458: } ! 459: } ! 460: for (i = 0; i < ctp -> src.ta_naddr; i++) { ! 461: if (ctp -> src.ta_addrs[i].na_stack == type) { ! 462: /* our address */ ! 463: nta -> ta_addrs[0] = ctp->src.ta_addrs[i]; ! 464: nta -> ta_naddr = 1; ! 465: return nta; ! 466: } ! 467: } ! 468: /* ! 469: * This requires an explanation: ! 470: * If NOMUNGE && FORCEMUNGE we have a semi-transparent bridge ! 471: * and since [at least on my machine] the recipient of a "transparent" ! 472: * call sees it as coming from the bridge host, ie the effect is that ! 473: * of a strict call, the structure that is now in nta, viz: ! 474: * "calling address"/calling address ! 475: * is going to get clobbered and appear at the final host as originating ! 476: * "calling address"/bridge host ! 477: * anyway. This is what I want. ! 478: * => return nta ! 479: */ ! 480: if ((ctp -> flags & CONN_NOMUNGE) ! 481: && (ctp -> flags & CONN_FORCEMUNGE) ! 482: && !(ctp -> flags & CONN_STRICT)) { ! 483: return nta; ! 484: } ! 485: if (ctp -> flags & CONN_STRICT) ! 486: adios (NULLCP, "not listening on this network (%d)", type); ! 487: ! 488: advise (LLOG_NOTICE, NULLCP, ! 489: "not listening on this network (%d)", type); ! 490: ! 491: return ta; ! 492: } ! 493: ! 494: /* */ ! 495: ! 496: static ContTbl *find_connection (ta) ! 497: struct TSAPaddr *ta; ! 498: { ! 499: ContTbl *ctp; ! 500: struct NSAPaddr *na1, *na2; ! 501: ! 502: for (ctp = con_tbl; ctp < &con_tbl[con_tbl_cnt]; ctp ++) { ! 503: for (na1 = &ctp -> src.ta_addrs[0]; ! 504: na1 < &ctp -> src.ta_addrs[ctp->src.ta_naddr]; na1++) { ! 505: for (na2 = &ta -> ta_addrs[0]; ! 506: na2 < &ta -> ta_addrs[ta->ta_naddr]; na2 ++) { ! 507: if (na1 -> na_stack != na2 -> na_stack) ! 508: continue; ! 509: ! 510: switch (na1 -> na_stack) { ! 511: case NA_NSAP: ! 512: if (na1 -> na_addrlen == na2 -> na_addrlen && ! 513: bcmp (na1 -> na_address, na2 -> na_address, ! 514: na1 -> na_addrlen) == 0) ! 515: return ctp; ! 516: break; ! 517: ! 518: case NA_TCP: ! 519: if (na1 -> na_port == na2 -> na_port && ! 520: strcmp (na1 -> na_domain, na2 -> na_domain) == 0) ! 521: return ctp; ! 522: break; ! 523: ! 524: case NA_X25: ! 525: case NA_BRG: ! 526: if (na1 -> na_dtelen == na2 -> na_dtelen && ! 527: bcmp (na1 -> na_dte, na2 -> na_dte, ! 528: na1 -> na_dtelen) == 0 && ! 529: na1 -> na_pidlen == na2 -> na_pidlen && ! 530: bcmp (na1 -> na_pid, na2 -> na_pid, ! 531: na1 -> na_pidlen) == 0) ! 532: return ctp; ! 533: break; ! 534: } ! 535: } ! 536: } ! 537: } ! 538: return NULL; ! 539: } ! 540: ! 541: /* */ ! 542: ! 543: static void arginit (vec) ! 544: char **vec; ! 545: { ! 546: register char *ap; ! 547: register struct TSAPaddr *ta; ! 548: ! 549: if (myname = rindex (*vec, '/')) ! 550: myname++; ! 551: if (myname == NULL || *myname == NULL) ! 552: myname = *vec; ! 553: ! 554: for (vec++; ap = *vec; vec++) { ! 555: if (*ap == '-' && ap[1]) ! 556: switch (*++ap) { ! 557: case 'T': ! 558: if ((ap = *++vec) == NULL || *ap == '-') ! 559: adios (NULLCP, "usage: %s -T tailorfile", myname); ! 560: (void) isodesetailor (ap); ! 561: isodetailor (myname, 0); ! 562: ll_hdinit (pgm_log, myname); ! 563: continue; ! 564: ! 565: case 'a': ! 566: if ((ap = *++vec) == NULL || *ap == '-') ! 567: adios (NULLCP, "usage: %s -a address", myname); ! 568: if ((ta = str2taddr (ap)) == NULLTA) ! 569: adios (NULLCP, "bad address \"%s\"", ap); ! 570: con_tbl[0].src = *ta; /* struct copy */ ! 571: con_tbl[0].flags = 0; ! 572: con_tbl_cnt = 1; ! 573: continue; ! 574: ! 575: case 's': ! 576: con_tbl[0].flags |= CONN_STRICT; ! 577: continue; ! 578: ! 579: default: ! 580: adios (NULLCP, "unknown switch -%s", ap); ! 581: } ! 582: else ! 583: break; ! 584: ! 585: } ! 586: isodetailor (myname, 0); ! 587: ll_hdinit (pgm_log, myname); ! 588: ! 589: for (; ap = *vec; vec++) ! 590: read_file (ap); ! 591: ! 592: if (con_tbl_cnt <= 0) { ! 593: if ((ta = str2taddr (tsb_default_address)) == NULLTA) ! 594: adios (NULLCP, "bad default address \"%s\"", ! 595: tsb_default_address); ! 596: con_tbl[0].src = *ta; /* struct copy */ ! 597: con_tbl_cnt = 1; ! 598: } ! 599: } ! 600: ! 601: /* */ ! 602: ! 603: static void read_file (file) ! 604: char *file; ! 605: { ! 606: FILE *fp; ! 607: char buf[BUFSIZ]; ! 608: char *vec[50]; ! 609: char *ap; ! 610: int vecp, i; ! 611: ContTbl *ctp; ! 612: struct TSAPaddr *ta; ! 613: ! 614: if (strcmp (file, "-") == 0) ! 615: fp = stdin; ! 616: else if ((fp = fopen (file, "r")) == NULL) ! 617: adios (file, "Can't open "); ! 618: ! 619: while (fgets (buf, sizeof buf, fp) != NULLCP) { ! 620: if (buf[0] == '#' || buf[0] == '\n') ! 621: continue; ! 622: ! 623: vecp = sstr2arg (buf, 50, vec, " \t,\n"); ! 624: if (vecp <= 0) ! 625: continue; ! 626: ! 627: if ((ta = str2taddr (vec[0])) == NULLTA) ! 628: adios (NULLCP, "Bad address \"%s\" in file %s", vec[0], file); ! 629: ! 630: ctp = &con_tbl[con_tbl_cnt]; ! 631: ctp -> src = *ta; /* struct copy */ ! 632: con_tbl_cnt ++; ! 633: ! 634: for (i = 1; i < vecp; i++) { ! 635: ap = vec[i]; ! 636: if (*ap == '\0') ! 637: continue; ! 638: if (*ap == '-') { ! 639: switch (*++ap) { ! 640: case 's': ! 641: ctp -> flags |= CONN_STRICT; ! 642: break; ! 643: case 't': ! 644: ctp -> flags |= CONN_TRANS; ! 645: break; ! 646: case 'n': ! 647: ctp -> flags |= CONN_NOMUNGE; ! 648: break; ! 649: case 'f': ! 650: ctp -> flags |= CONN_FORCEMUNGE; ! 651: break; ! 652: ! 653: default: ! 654: adios (NULLCP, "Unknown option -%c", *ap); ! 655: } ! 656: } ! 657: else { ! 658: if ((ta = str2taddr (ap)) == NULLTA) ! 659: adios (NULLCP, "Bad address \"%s\" in file %s", ! 660: ap, file); ! 661: ctp -> dest = *ta; /* struct copy */ ! 662: ctp -> flags |= (CONN_TRANS|CONN_NOMUNGE); ! 663: } ! 664: } ! 665: ! 666: } ! 667: ! 668: if (strcmp (file, "-") != 0) ! 669: (void) fclose (fp); ! 670: } ! 671: ! 672: /* */ ! 673: ! 674: static void envinit () { ! 675: int i, ! 676: sd; ! 677: ! 678: nbits = getdtablesize (); ! 679: ! 680: if (!(debug = isatty (2))) { ! 681: for (i = 0; i < 5; i++) { ! 682: switch (fork ()) { ! 683: case NOTOK: ! 684: sleep (5); ! 685: continue; ! 686: ! 687: case OK: ! 688: break; ! 689: ! 690: default: ! 691: _exit (0); ! 692: } ! 693: break; ! 694: } ! 695: ! 696: (void) chdir ("/"); ! 697: ! 698: if ((sd = open ("/dev/null", O_RDWR)) == NOTOK) ! 699: adios ("/dev/null", "unable to read"); ! 700: if (sd != 0) ! 701: (void) dup2 (sd, 0), (void) close (sd); ! 702: (void) dup2 (0, 1); ! 703: (void) dup2 (0, 2); ! 704: ! 705: #ifdef SETSID ! 706: if (setsid () == NOTOK) ! 707: advise (LLOG_EXCEPTIONS, "failed", "setsid"); ! 708: #endif ! 709: #ifdef TIOCNOTTY ! 710: if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) { ! 711: (void) ioctl (sd, TIOCNOTTY, NULLCP); ! 712: (void) close (sd); ! 713: } ! 714: #else ! 715: #ifdef SYS5 ! 716: (void) setpgrp (); ! 717: (void) signal (SIGINT, SIG_IGN); ! 718: (void) signal (SIGQUIT, SIG_IGN); ! 719: #endif ! 720: #endif ! 721: } ! 722: else ! 723: ll_dbinit (pgm_log, myname); ! 724: ! 725: #ifndef sun /* damn YP... */ ! 726: for (sd = 3; sd < nbits; sd++) ! 727: if (pgm_log -> ll_fd != sd) ! 728: (void) close (sd); ! 729: #endif ! 730: ! 731: (void) signal (SIGPIPE, SIG_IGN); ! 732: ! 733: ll_hdinit (pgm_log, myname); ! 734: advise (LLOG_NOTICE, NULLCP, "starting"); ! 735: } ! 736: ! 737: /* ERRORS */ ! 738: ! 739: #ifndef lint ! 740: static void adios (va_alist) ! 741: va_dcl ! 742: { ! 743: va_list ap; ! 744: ! 745: va_start (ap); ! 746: ! 747: _ll_log (pgm_log, LLOG_FATAL, ap); ! 748: ! 749: va_end (ap); ! 750: ! 751: _exit (1); ! 752: } ! 753: #else ! 754: /* VARARGS */ ! 755: ! 756: static void adios (what, fmt) ! 757: char *what, ! 758: *fmt; ! 759: { ! 760: adios (what, fmt); ! 761: } ! 762: #endif ! 763: ! 764: ! 765: #ifndef lint ! 766: static void advise (va_alist) ! 767: va_dcl ! 768: { ! 769: int code; ! 770: va_list ap; ! 771: ! 772: va_start (ap); ! 773: ! 774: code = va_arg (ap, int); ! 775: ! 776: _ll_log (pgm_log, code, ap); ! 777: ! 778: va_end (ap); ! 779: } ! 780: #else ! 781: /* VARARGS */ ! 782: ! 783: static void advise (code, what, fmt) ! 784: char *what, ! 785: *fmt; ! 786: int code; ! 787: { ! 788: advise (code, what, fmt); ! 789: } ! 790: #endif ! 791:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.