|
|
1.1 ! root 1: /* isoc.c - "minimal" ISODE client for testing */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/support/RCS/isoc.c,v 7.1 89/12/07 21:19:51 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/support/RCS/isoc.c,v 7.1 89/12/07 21:19:51 mrose Exp $ ! 9: * ! 10: * ! 11: * $Log: isoc.c,v $ ! 12: * Revision 7.1 89/12/07 21:19:51 mrose ! 13: * stuff ! 14: * ! 15: * Revision 7.0 89/11/23 22:27:15 mrose ! 16: * Release 6.0 ! 17: * ! 18: */ ! 19: ! 20: /* ! 21: * NOTICE ! 22: * ! 23: * Acquisition, use, and distribution of this module and related ! 24: * materials are subject to the restrictions of a license agreement. ! 25: * Consult the Preface in the User's Manual for the full terms of ! 26: * this agreement. ! 27: * ! 28: */ ! 29: ! 30: ! 31: #include <stdio.h> ! 32: #include <varargs.h> ! 33: #include "rosap.h" ! 34: #include "rtsap.h" ! 35: #include "acsap.h" ! 36: #include "psap2.h" ! 37: #include "ssap.h" ! 38: #include "tsap.h" ! 39: #ifdef TCP ! 40: #include "internet.h" ! 41: #ifdef BSD42 ! 42: #include <sys/ioctl.h> ! 43: #endif ! 44: #ifdef SVR3 ! 45: #include <fcntl.h> ! 46: #endif ! 47: #endif ! 48: #include "isoservent.h" ! 49: #include "tailor.h" ! 50: #include <sys/stat.h> ! 51: ! 52: #undef TIMER ! 53: #undef TMS ! 54: #ifdef BSD42 ! 55: #define TIMER ! 56: #endif ! 57: #ifdef SYS5 ! 58: #define TIMER ! 59: #ifndef HPUX ! 60: #include <sys/times.h> ! 61: #define TMS ! 62: #endif ! 63: #endif ! 64: ! 65: #if !defined (TCP) || defined (FIONBIO) || defined (SVR3) ! 66: #define ASYNC ! 67: #endif ! 68: ! 69: /* DATA */ ! 70: ! 71: #define ISN(req) \ ! 72: (req & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY)) \ ! 73: ? (long) ((getpid () % (SERIAL_MAX - SERIAL_MIN + 1)) + SERIAL_MIN) \ ! 74: : SERIAL_NONE ! 75: ! 76: static enum { echo, sink, XXX } mode = XXX; ! 77: ! 78: static int testing_queued_writes = 0; ! 79: ! 80: static char *isacs = NULL; ! 81: static int isrts = 0; ! 82: ! 83: static int status = 0; ! 84: ! 85: static char *myname = "isoc"; ! 86: ! 87: ! 88: void adios (), advise (); ! 89: void ts_adios (), ts_advise (); ! 90: void ss_adios (), ss_advise (); ! 91: void ps_adios (), ps_advise (); ! 92: void acs_adios (), acs_advise (); ! 93: void rts_adios (), rts_advise (); ! 94: void ros_adios (), ros_advise (); ! 95: ! 96: ! 97: long lseek (); ! 98: ! 99: /* MAIN */ ! 100: ! 101: #define chkacs() if (isacs) \ ! 102: adios (NULLCP, "no association control for %s", \ ! 103: argv[2]) ! 104: ! 105: /* ARGSUSED */ ! 106: ! 107: main (argc, argv, envp) ! 108: int argc; ! 109: char **argv, ! 110: **envp; ! 111: { ! 112: register struct isoservent *is; ! 113: ! 114: if (myname = rindex (argv[0], '/')) ! 115: myname++; ! 116: if (myname == NULL || *myname == NULL) ! 117: myname = argv[0]; ! 118: ! 119: isodetailor (myname, 1); ! 120: ! 121: if (argc != 4) ! 122: adios (NULLCP, "usage: %s host provider entity", myname); ! 123: ! 124: #ifdef TCP ! 125: if (strcmp (argv[2], "raw") == 0) { ! 126: raw_main (argv[3], argv[1]); ! 127: exit (0); ! 128: } ! 129: #endif ! 130: ! 131: if (index (argv[3], '/')) { ! 132: mode = strcmp (isacs = argv[3], "isode/sink") ? echo : sink; ! 133: } ! 134: else { ! 135: if ((is = getisoserventbyname (argv[3], argv[2])) == NULL) ! 136: adios (NULLCP, "%s/%s: unknown provider/entity pair", ! 137: argv[2], argv[3]); ! 138: ! 139: mode = strcmp (is -> is_entity, "sink") ? echo : sink; ! 140: } ! 141: ! 142: if (strcmp (argv[2], "tsap") == 0) { ! 143: chkacs (); ! 144: ts_main (is, argv[1]); ! 145: } ! 146: else ! 147: if (strcmp (argv[2], "ssap") == 0) { ! 148: chkacs (); ! 149: ss_main (is, argv[1]); ! 150: } ! 151: else ! 152: if (strcmp (argv[2], "psap") == 0) ! 153: ps_main (is, argv[1]); ! 154: else ! 155: if (strcmp (argv[2], "rtsap") == 0) { ! 156: isrts = 1; ! 157: rts_main (is, argv[1]); ! 158: } ! 159: else ! 160: if (strcmp (argv[2], "rosap") == 0) ! 161: ros_main (is, argv[1]); ! 162: else ! 163: adios (NULLCP, "unknown provider: \"%s\"", argv[2]); ! 164: ! 165: exit (status); /* NOTREACHED */ ! 166: } ! 167: ! 168: /* RAW */ ! 169: ! 170: #ifdef TCP ! 171: static int raw_main (service, addr) ! 172: char *service, ! 173: *addr; ! 174: { ! 175: int sd, ! 176: cc, ! 177: i, ! 178: j; ! 179: char *cp, ! 180: *dp; ! 181: register struct hostent *hp; ! 182: register struct servent *sp; ! 183: struct sockaddr_in in_socket; ! 184: register struct sockaddr_in *isock = &in_socket; ! 185: struct stat st; ! 186: ! 187: if (strcmp (service, "sink")) ! 188: adios (NULLCP, "only sink on raw tcp is supported"); ! 189: if ((sp = getservbyname (service, "tcp")) == NULL) ! 190: adios (NULLCP, "%s/%s: unknown service", "tcp", service); ! 191: if ((hp = gethostbystring (addr)) == NULL) ! 192: adios (NULLCP, "%s: unknown host", addr); ! 193: ! 194: bzero ((char *) isock, sizeof *isock); ! 195: isock -> sin_family = hp -> h_addrtype; ! 196: isock -> sin_port = sp -> s_port; ! 197: inaddr_copy (hp, isock); ! 198: ! 199: if ((sd = start_tcp_client ((struct sockaddr_in *) 0, 0)) == NOTOK) ! 200: adios ("socket", "unable to start"); ! 201: fprintf (stderr, "%s... ", hp -> h_name); ! 202: (void) fflush (stderr); ! 203: if (join_tcp_server (sd, isock) == NOTOK) { ! 204: fprintf (stderr, "failed\n"); ! 205: adios ("socket", "unable to connect"); ! 206: } ! 207: fprintf (stderr, "connected\n"); ! 208: ! 209: if (fstat (fileno (stdin), &st) == NOTOK ! 210: || (st.st_mode & S_IFMT) != S_IFREG ! 211: || (cc = st.st_size) == 0) ! 212: adios (NULLCP, "standard input not a regular file"); ! 213: (void) lseek (fileno (stdin), 0L, 0); ! 214: ! 215: if ((cp = malloc ((unsigned) cc)) == NULL) ! 216: adios (NULLCP, "no memory"); ! 217: for (dp = cp, j = cc; j > 0; dp += i, j -= i) ! 218: switch (i = read (fileno (stdin), dp, j)) { ! 219: case NOTOK: ! 220: adios ("on stdin", "read failed"); ! 221: ! 222: case OK: ! 223: adios (NULLCP, "premature end-of-file"); ! 224: ! 225: default: ! 226: break; ! 227: } ! 228: ! 229: #ifdef TIMER ! 230: timer (0); ! 231: #endif ! 232: if (write_tcp_socket (sd, cp, cc) != cc) ! 233: adios ("writing", "error"); ! 234: (void) close_tcp_socket (sd); ! 235: #ifdef TIMER ! 236: timer (cc); ! 237: #endif ! 238: } ! 239: #endif ! 240: ! 241: /* TSAP */ ! 242: ! 243: static int ts_main (is, addr) ! 244: struct isoservent *is; ! 245: char *addr; ! 246: { ! 247: int sd, ! 248: cc, ! 249: i, ! 250: j, ! 251: expedited, ! 252: expd; ! 253: char *cp, ! 254: *dp, ! 255: buffer[BUFSIZ]; ! 256: struct TSAPaddr *ta; ! 257: struct TSAPconnect tcs; ! 258: register struct TSAPconnect *tc = &tcs; ! 259: struct TSAPdisconnect tds; ! 260: register struct TSAPdisconnect *td = &tds; ! 261: struct stat st; ! 262: ! 263: if ((ta = is2taddr (addr, NULLCP, is)) == NULL) ! 264: adios (NULLCP, "address translation failed"); ! 265: ! 266: fprintf (stderr, "%s... ", addr); ! 267: (void) fflush (stderr); ! 268: #ifndef ASYNC ! 269: if (TConnRequest (NULLTA, ta, 1, NULLCP, 0, NULLQOS, tc, td) == NOTOK) { ! 270: fprintf (stderr, "failed\n"); ! 271: ts_adios (td, "T-CONNECT.REQUEST"); ! 272: } ! 273: sd = tc -> tc_sd; ! 274: #else ! 275: if ((i = TAsynConnRequest (NULLTA, ta, 1, NULLCP, 0, NULLQOS, tc, td, 1)) ! 276: == NOTOK) { ! 277: fprintf (stderr, "failed\n"); ! 278: ts_adios (td, "T-(ASYN-)CONNECT.REQUEST"); ! 279: } ! 280: sd = tc -> tc_sd, cc = 0; ! 281: while (i == CONNECTING_1 || i == CONNECTING_2) { ! 282: int nfds; ! 283: fd_set mask, ! 284: *rmask, ! 285: *wmask; ! 286: ! 287: nfds = 0; ! 288: FD_ZERO (&mask); ! 289: if (TSelectMask (sd, &mask, &nfds, td) == NOTOK) { ! 290: fprintf (stderr, "failed\n"); ! 291: ts_adios (td, "T-(ASYN-)CONNECT.REQUEST(TSelectMask)"); ! 292: } ! 293: rmask = (i == CONNECTING_2) ? &mask : NULLFD; ! 294: wmask = (i == CONNECTING_2) ? NULLFD : &mask; ! 295: ! 296: fprintf (stderr, "."); ! 297: (void) fflush (stderr); ! 298: if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) { ! 299: fprintf (stderr, "failed\n"); ! 300: adios ("failed", "select"); ! 301: } ! 302: ! 303: if ((rmask && FD_ISSET (sd, rmask) == 0) ! 304: || (wmask && FD_ISSET (sd, wmask) == 0)) ! 305: continue; ! 306: ! 307: if ((i = TAsynRetryRequest (sd, tc, td)) == NOTOK) { ! 308: fprintf (stderr, "failed\n"); ! 309: ts_adios (td, "T-ASYN-RETRY.REQUEST"); ! 310: } ! 311: } ! 312: #endif ! 313: fprintf (stderr, "connected\n"); ! 314: ! 315: ! 316: if (getenv ("TEST_QUEUED_WRITES")) { ! 317: if (TSetQueuesOK (tc -> tc_sd, 1, td) == NOTOK) ! 318: ts_adios (td, "T-SET-QUEUES-OK"); ! 319: ! 320: tsap_log -> ll_events |= LLOG_EXCEPTIONS; ! 321: tsap_log -> ll_file = "-"; ! 322: (void) ll_close (tsap_log); ! 323: ! 324: testing_queued_writes = 1; ! 325: } ! 326: ! 327: expd = tc -> tc_expedited; ! 328: #ifdef DEBUG ! 329: { ! 330: advise (NULLCP, "responding TSAP address: %s", ! 331: taddr2str (&tc -> tc_responding)); ! 332: ! 333: if (tc -> tc_cc > 0) ! 334: advise (NULLCP, "greetings: %d octets", tc -> tc_cc); ! 335: } ! 336: #endif ! 337: ! 338: if (fstat (fileno (stdin), &st) != NOTOK ! 339: && (st.st_mode & S_IFMT) == S_IFREG ! 340: && (cc = st.st_size) != 0) { ! 341: (void) lseek (fileno (stdin), 0L, 0); ! 342: ! 343: if ((cp = malloc ((unsigned) cc)) == NULL) ! 344: adios (NULLCP, "no memory"); ! 345: for (dp = cp, j = cc; j > 0; dp += i, j -= i) ! 346: switch (i = read (fileno (stdin), dp, j)) { ! 347: case NOTOK: ! 348: adios ("on stdin", "read failed"); ! 349: ! 350: case OK: ! 351: adios (NULLCP, "premature end-of-file"); ! 352: ! 353: default: ! 354: break; ! 355: } ! 356: for (i = 10; i > 0; i--) { ! 357: #ifdef TIMER ! 358: timer (0); ! 359: #endif ! 360: ts_datarequest (sd, cp, cc, 0); ! 361: #ifdef TIMER ! 362: timer (cc); ! 363: #endif ! 364: } ! 365: free (cp); ! 366: } ! 367: else ! 368: for (expedited = 0; ! 369: fgets (buffer, sizeof buffer, stdin); ! 370: expedited = !expedited) { ! 371: if ((cc = strlen (buffer) + 1) > TX_SIZE && expedited) ! 372: expedited = 0; ! 373: ! 374: ts_datarequest (sd, buffer, cc, expd ? expedited : 0); ! 375: } ! 376: ! 377: if (TDiscRequest (sd, NULLCP, 0, td) == NOTOK) ! 378: ts_adios (td, "T-DISCONNECT.REQUEST"); ! 379: } ! 380: ! 381: /* */ ! 382: ! 383: static int ts_datarequest (sd, data, cc, expedited) ! 384: int sd; ! 385: char *data; ! 386: int cc, ! 387: expedited; ! 388: { ! 389: struct TSAPdata txs; ! 390: register struct TSAPdata *tx = &txs; ! 391: struct TSAPdisconnect tds; ! 392: register struct TSAPdisconnect *td = &tds; ! 393: ! 394: if ((expedited ? TExpdRequest (sd, data, cc, td) ! 395: : TDataRequest (sd, data, cc, td)) == NOTOK) ! 396: if (expedited) ! 397: ts_adios (td, "T-EXPEDITED-DATA.REQUEST"); ! 398: else ! 399: ts_adios (td, "T-DATA.REQUEST"); ! 400: ! 401: if (mode == echo) { ! 402: if (testing_queued_writes) { ! 403: int vecp; ! 404: char *vec[4]; ! 405: fd_set rfds; ! 406: ! 407: FD_ZERO (&rfds); ! 408: FD_SET (sd, &rfds); ! 409: if (TNetAccept (&vecp, vec, sd + 1, &rfds, NULLFD, NULLFD, NOTOK, ! 410: td) == NOTOK) ! 411: ts_adios (td, "T-NET-ACCEPT"); ! 412: } ! 413: ! 414: if (TReadRequest (sd, tx, NOTOK, td) == NOTOK) ! 415: ts_adios (td, "T-READ.REQUEST"); ! 416: if (cc != tx -> tx_cc) { ! 417: advise (NULLCP, "length mismatch, orig=%d echo=%d", ! 418: cc, tx -> tx_cc); ! 419: status++; ! 420: } ! 421: else ! 422: if (qcmp (data, &tx -> tx_qbuf, cc)) ! 423: status++; ! 424: TXFREE (tx) ! 425: } ! 426: } ! 427: ! 428: /* */ ! 429: ! 430: static void ts_adios (td, event) ! 431: register struct TSAPdisconnect *td; ! 432: char *event; ! 433: { ! 434: ts_advise (td, event); ! 435: ! 436: _exit (1); ! 437: } ! 438: ! 439: ! 440: static void ts_advise (td, event) ! 441: register struct TSAPdisconnect *td; ! 442: char *event; ! 443: { ! 444: char data[BUFSIZ]; ! 445: ! 446: if (td -> td_cc > 0) { ! 447: (void) sprintf (data, "[%s] %*.*s", ! 448: TErrString (td -> td_reason), ! 449: td -> td_cc, td -> td_cc, td -> td_data); ! 450: } ! 451: else ! 452: (void) sprintf (data, "[%s]", TErrString (td -> td_reason)); ! 453: ! 454: advise (NULLCP, "%s: %s", event, data); ! 455: } ! 456: ! 457: /* SSAP */ ! 458: ! 459: static int requirements = SR_HALFDUPLEX | SR_DUPLEX | SR_EXPEDITED ! 460: | SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY ! 461: | SR_NEGOTIATED | SR_CAPABILITY | SR_EXCEPTIONS | SR_TYPEDATA; ! 462: ! 463: static int owned = 0; ! 464: static int avail = 0; ! 465: ! 466: static long ssn; ! 467: ! 468: static int nmodes; ! 469: static int datamodes[4]; ! 470: ! 471: static char userdata[1024]; ! 472: ! 473: /* */ ! 474: ! 475: static int ss_main (is, addr) ! 476: struct isoservent *is; ! 477: char *addr; ! 478: { ! 479: int sd, ! 480: cc, ! 481: i, ! 482: j, ! 483: k, ! 484: l, ! 485: tokens; ! 486: char *cp, ! 487: *dp, ! 488: buffer[BUFSIZ]; ! 489: struct SSAPactid ids; ! 490: register struct SSAPactid *id = &ids; ! 491: register struct SSAPaddr *sz; ! 492: struct SSAPref sfs; ! 493: register struct SSAPref *sf; ! 494: struct SSAPconnect scs; ! 495: register struct SSAPconnect *sc = &scs; ! 496: struct SSAPrelease srs; ! 497: register struct SSAPrelease *sr = &srs; ! 498: struct SSAPindication sis; ! 499: register struct SSAPindication *si = &sis; ! 500: register struct SSAPabort *sa = &si -> si_abort; ! 501: struct stat st; ! 502: ! 503: bzero (userdata, sizeof userdata); ! 504: ! 505: if ((sz = is2saddr (addr, NULLCP, is)) == NULL) ! 506: adios (NULLCP, "address translation failed"); ! 507: if ((sf = addr2ref (SLocalHostName ())) == NULL) { ! 508: sf = &sfs; ! 509: (void) bzero ((char *) sf, sizeof *sf); ! 510: } ! 511: ! 512: tokens = 0; ! 513: #define dotoken(requires,shift,bit,type) \ ! 514: { \ ! 515: if (requirements & requires) \ ! 516: tokens |= ST_CALL_VALUE << shift; \ ! 517: } ! 518: dotokens (); ! 519: #undef dotoken ! 520: ! 521: fprintf (stderr, "%s... ", addr); ! 522: (void) fflush (stderr); ! 523: #ifndef ASYNC ! 524: if (SConnRequest (sf, NULLSA, sz, requirements, tokens, ISN (requirements), ! 525: userdata, sizeof userdata /*SS_SIZE*/, NULLQOS, sc, si) == NOTOK) { ! 526: fprintf (stderr, "failed\n"); ! 527: ss_adios (sa, "S-CONNECT.REQUEST"); ! 528: } ! 529: sd = sc -> sc_sd; ! 530: #else ! 531: if ((i = SAsynConnRequest (sf, NULLSA, sz, requirements, tokens, ! 532: ISN (requirements), userdata, sizeof userdata /*SS_SIZE*/, NULLQOS, ! 533: sc, si, 1)) ! 534: == NOTOK) { ! 535: fprintf (stderr, "failed\n"); ! 536: ss_adios (sa, "S-(ASYN-)CONNECT.REQUEST"); ! 537: } ! 538: sd = sc -> sc_sd, cc = 0; ! 539: while (i == CONNECTING_1 || i == CONNECTING_2) { ! 540: int nfds; ! 541: fd_set mask, ! 542: *rmask, ! 543: *wmask; ! 544: ! 545: nfds = 0; ! 546: FD_ZERO (&mask); ! 547: if (SSelectMask (sd, &mask, &nfds, si) == NOTOK) { ! 548: fprintf (stderr, "failed\n"); ! 549: ss_adios (sa, "S-(ASYN-)CONNECT.REQUEST(SSelectMask)"); ! 550: } ! 551: rmask = (i == CONNECTING_2) ? &mask : NULLFD; ! 552: wmask = (i == CONNECTING_2) ? NULLFD : &mask; ! 553: ! 554: fprintf (stderr, "."); ! 555: if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) { ! 556: fprintf (stderr, "failed\n"); ! 557: adios ("failed", "select"); ! 558: } ! 559: ! 560: if ((rmask && FD_ISSET (sd, rmask) == 0) ! 561: || (wmask && FD_ISSET (sd, wmask) == 0)) ! 562: continue; ! 563: ! 564: if ((i = SAsynRetryRequest (sd, sc, si)) == NOTOK) { ! 565: fprintf (stderr, "failed\n"); ! 566: ss_adios (sa, "S-ASYN-RETRY.REQUEST"); ! 567: } ! 568: } ! 569: #endif ! 570: ! 571: if (sc -> sc_result != SC_ACCEPT) { ! 572: fprintf (stderr, "failed\n"); ! 573: if (sc -> sc_cc > 0) ! 574: adios (NULLCP, "connection rejected: [%s] %*.*s", ! 575: SErrString (sc -> sc_result), ! 576: sc -> sc_cc, sc -> sc_cc, sc -> sc_data); ! 577: else ! 578: adios (NULLCP, "connection rejected: [%s]", ! 579: SErrString (sc -> sc_result)); ! 580: } ! 581: fprintf (stderr, "connected\n"); ! 582: ! 583: #ifdef DEBUG ! 584: { ! 585: advise (NULLCP, "responding SSAP address: %s", ! 586: saddr2str (&sc -> sc_responding)); ! 587: ! 588: if (sc -> sc_cc > 0) ! 589: advise (NULLCP, "greetings: %d octets", sc -> sc_cc); ! 590: } ! 591: #endif ! 592: requirements = sc -> sc_requirements; ! 593: nmodes = 0; ! 594: datamodes[nmodes++] = SX_NORMAL; ! 595: if (requirements & SR_EXPEDITED) ! 596: datamodes[nmodes++] = SX_EXPEDITED; ! 597: if ((requirements & SR_CAPABILITY) && (requirements & SR_ACTIVITY)) ! 598: datamodes[nmodes++] = SX_CAPDIND; ! 599: if (requirements & SR_TYPEDATA) ! 600: datamodes[nmodes++] = SX_TYPED; ! 601: ! 602: #define dotoken(requires,shift,bit,type) \ ! 603: { \ ! 604: if (requirements & requires) \ ! 605: switch (sc -> sc_settings & (ST_MASK << shift)) { \ ! 606: case ST_CALL_VALUE: \ ! 607: adios (NULLCP, "%s token: choice", type); \ ! 608: \ ! 609: case ST_INIT_VALUE: \ ! 610: owned |= bit, avail |= bit; \ ! 611: break; \ ! 612: \ ! 613: case ST_RESP_VALUE: \ ! 614: avail |= bit; \ ! 615: break; \ ! 616: \ ! 617: default: \ ! 618: adios (NULLCP, "%s token: reserved", type); \ ! 619: } \ ! 620: } ! 621: dotokens (); ! 622: #undef dotoken ! 623: ! 624: if (requirements & SR_ACTIVITY) { ! 625: (void) strcpy (id -> sd_data, mode == echo ? "echo" : "sink"); ! 626: id -> sd_len = strlen (id -> sd_data); ! 627: if (SActStartRequest (sd, id, userdata, SV_SIZE, si) == NOTOK) ! 628: ss_adios (sa, "S-ACTIVITY-START.REQUEST"); ! 629: } ! 630: ! 631: if (fstat (fileno (stdin), &st) != NOTOK ! 632: && (st.st_mode & S_IFMT) == S_IFREG ! 633: && (cc = st.st_size) != 0) { ! 634: (void) lseek (fileno (stdin), 0L, 0); ! 635: ! 636: if ((cp = malloc ((unsigned) cc)) == NULL) ! 637: adios (NULLCP, "no memory"); ! 638: for (dp = cp, j = cc; j > 0; dp += i, j -= i) ! 639: switch (i = read (fileno (stdin), dp, j)) { ! 640: case NOTOK: ! 641: adios ("on stdin", "read failed"); ! 642: ! 643: case OK: ! 644: adios (NULLCP, "premature end-of-file"); ! 645: ! 646: default: ! 647: break; ! 648: } ! 649: for (i = 10; i > 0; i--) { ! 650: #ifdef TIMER ! 651: timer (0); ! 652: #endif ! 653: ss_datarequest (sd, cp, cc, SX_NORMAL, 0); ! 654: #ifdef TIMER ! 655: timer (cc); ! 656: #endif ! 657: } ! 658: free (cp); ! 659: } ! 660: else { ! 661: for (j = l = 0; fgets (buffer, sizeof buffer, stdin); ) { ! 662: k = j >= nmodes ? SX_EXPEDITED : datamodes[j++ % nmodes]; ! 663: if ((cc = strlen (buffer) + 1) > SX_EXSIZE && k == SX_EXPEDITED) { ! 664: if ((k = datamodes[j++ % nmodes]) == SX_EXPEDITED) ! 665: k = datamodes[j++ % nmodes]; ! 666: } ! 667: ! 668: switch (k) { ! 669: case SX_CAPDIND: ! 670: if (!(requirements & SR_RESYNC) || l++ & 0x01) { ! 671: ss_waitfor (sd, ST_ACT_TOKEN); ! 672: if (l & 0x03) { ! 673: if (SActIntrRequest (sd, SP_SEQUENCE, si) ! 674: == NOTOK) ! 675: ss_adios (sa, "S-ACTIVITY-INTERRUPT.REQUEST"); ! 676: } ! 677: else { ! 678: if (SActDiscRequest (sd, SP_SEQUENCE, si) ! 679: == NOTOK) ! 680: ss_adios (sa, "S-ACTIVITY-DISCARD.REQUEST"); ! 681: } ! 682: ss_waitfor (sd, -1); ! 683: goto push_data; ! 684: } ! 685: if (!(requirements & SR_RESYNC)) ! 686: break; ! 687: tokens = 0; ! 688: #define dotoken(requires,shift,bit,type) \ ! 689: { \ ! 690: if (requirements & requires) \ ! 691: tokens |= ST_CALL_VALUE << shift; \ ! 692: } ! 693: dotokens (); ! 694: #undef dotoken ! 695: if (SReSyncRequest (sd, SYNC_SET, ssn - 1, tokens, ! 696: userdata, SN_SIZE, si) == NOTOK) ! 697: ss_adios (sa, "S-RESYNCHRONIZE.REQUEST"); ! 698: ss_waitfor (sd, -1); ! 699: break; ! 700: ! 701: case SX_EXPEDITED: ! 702: if (j >= nmodes) ! 703: j = j % nmodes;/* fall... */ ! 704: if (!(requirements & SR_EXPEDITED)) ! 705: k = SX_NORMAL; /* fall... */ ! 706: default: ! 707: push_data: ; ! 708: ss_datarequest (sd, buffer, cc, k, 1); ! 709: if (k == SX_CAPDIND ! 710: && SActResumeRequest (sd, id, id, ! 711: (long) (getpid () % (SERIAL_MAX - SERIAL_MIN + 1)) ! 712: + SERIAL_MIN, sf, userdata, SV_SIZE, si) ! 713: == NOTOK) ! 714: ss_adios (sa, "S-ACTIVITY-RESUME.REQUEST"); ! 715: break; ! 716: } ! 717: } ! 718: ! 719: if (requirements & SR_EXCEPTIONS) { ! 720: if (owned & ST_DAT_TOKEN) ! 721: if (SGTokenRequest (sd, ST_DAT_TOKEN, si) == NOTOK) ! 722: ss_adios (sa, "S-TOKEN-GIVE.REQUEST"); ! 723: else ! 724: owned &= ~ST_DAT_TOKEN; ! 725: if (SUReportRequest (sd, SP_NOREASON, userdata, SP_SIZE, si) ! 726: == NOTOK) ! 727: ss_adios (sa, "S-U-EXCEPTION-REPORT.REQUEST"); ! 728: ss_waitfor (sd, -1); ! 729: } ! 730: } ! 731: ! 732: if ((requirements & SR_MAJORSYNC) && !(requirements & SR_ACTIVITY)) { ! 733: if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si) == NOTOK) ! 734: switch (sa -> sa_reason) { ! 735: case SC_OPERATION: ! 736: ss_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN ! 737: | ST_MAJ_TOKEN); ! 738: if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si) ! 739: == OK) ! 740: break; /* else fall */ ! 741: ! 742: default: ! 743: ss_adios (sa, "S-MAJOR-SYNC.REQUEST"); ! 744: } ! 745: ! 746: ss_waitfor (sd, -1); ! 747: } ! 748: ! 749: if (requirements & SR_ACTIVITY) { ! 750: if (SActEndRequest (sd, &ssn, userdata, SV_SIZE, si) == NOTOK) ! 751: switch (sa -> sa_reason) { ! 752: case SC_OPERATION: ! 753: ss_waitfor (sd, avail); ! 754: if (SActEndRequest (sd, &ssn, userdata, SV_SIZE, si) == OK) ! 755: break; /* else fall */ ! 756: ! 757: default: ! 758: ss_adios (sa, "S-ACTIVITY-END.REQUEST"); ! 759: } ! 760: ! 761: ss_waitfor (sd, -1); ! 762: ! 763: if (SGControlRequest (sd, si) == NOTOK) ! 764: switch (sa -> sa_reason) { ! 765: case SC_OPERATION: ! 766: ss_waitfor (sd, avail); ! 767: if (SGControlRequest (sd, si) == OK) ! 768: break; /* else fall */ ! 769: ! 770: default: ! 771: ss_adios (sa, "S-CONTROL-GIVE.REQUEST"); ! 772: } ! 773: ! 774: owned = 0; ! 775: ! 776: ss_waitfor (sd, -1); ! 777: } ! 778: ! 779: if (SRelRequest (sd, userdata, SF_SIZE, NOTOK, sr, si) == NOTOK) ! 780: switch (sa -> sa_reason) { ! 781: case SC_OPERATION: ! 782: case SC_WAITING: ! 783: ss_waitfor (sd, avail); ! 784: if (SRelRequest (sd, userdata, SF_SIZE, NOTOK, sr, si) == OK) ! 785: break; /* else fall */ ! 786: ! 787: default: ! 788: ss_adios (sa, "S-RELEASE.REQUEST"); ! 789: } ! 790: ! 791: if (!sr -> sr_affirmative) { ! 792: (void) SUAbortRequest (sd, NULLCP, 0, si); ! 793: ! 794: if (sr -> sr_cc > 0) ! 795: adios (NULLCP, "release rejected by peer: %*.*s", ! 796: sr -> sr_cc, sr -> sr_cc, sr -> sr_data); ! 797: else ! 798: adios (NULLCP, "release rejected by peer"); ! 799: } ! 800: SRFREE (sr); ! 801: } ! 802: ! 803: /* */ ! 804: ! 805: static int ss_datarequest (sd, data, cc, dm, sync) ! 806: int sd; ! 807: char *data; ! 808: int cc, ! 809: dm, ! 810: sync; ! 811: { ! 812: int result; ! 813: struct SSAPdata sxs; ! 814: register struct SSAPdata *sx = &sxs; ! 815: struct SSAPindication sis; ! 816: register struct SSAPindication *si = &sis; ! 817: register struct SSAPabort *sa = &si -> si_abort; ! 818: ! 819: switch (dm) { ! 820: default: ! 821: if (SDataRequest (sd, data, cc, si) == NOTOK) ! 822: switch (sa -> sa_reason) { ! 823: case SC_OPERATION: ! 824: ss_waitfor (sd, ST_DAT_TOKEN); ! 825: if (SDataRequest (sd, data, cc, si) == OK) ! 826: break;/* else fall */ ! 827: ! 828: default: ! 829: ss_adios (sa, "S-DATA.REQUEST"); ! 830: } ! 831: break; ! 832: ! 833: case SX_EXPEDITED: ! 834: if (SExpdRequest (sd, data, cc, si) == NOTOK) ! 835: ss_adios (sa, "S-EXPEDITED-DATA.REQUEST"); ! 836: break; ! 837: ! 838: case SX_CAPDIND: ! 839: if (SCapdRequest (sd, data, cc, si) == NOTOK) ! 840: switch (sa -> sa_reason) { ! 841: case SC_OPERATION: ! 842: ss_waitfor (sd, avail & ~ST_RLS_TOKEN); ! 843: if (SCapdRequest (sd, data, cc, si) == OK) ! 844: break;/* else fall */ ! 845: ! 846: default: ! 847: ss_adios (sa, "S-CAPABILITY-DATA.REQUEST"); ! 848: } ! 849: break; ! 850: ! 851: case SX_TYPED: ! 852: if (STypedRequest (sd, data, cc, si) == NOTOK) ! 853: ss_adios (sa, "S-TYPED-DATA.REQUEST"); ! 854: break; ! 855: } ! 856: ! 857: if (mode == echo || dm == SX_CAPDIND) ! 858: for (;;) { ! 859: switch (result = SReadRequest (sd, sx, NOTOK, si)) { ! 860: case NOTOK: ! 861: ss_adios (sa, "S-READ.REQUEST"); ! 862: ! 863: case OK: ! 864: if ((dm != SX_CAPDIND ? dm : SX_CAPDCNF) ! 865: != sx -> sx_type) { ! 866: advise (NULLCP, ! 867: "data indication type mismatch, orig=%d echo=%d", ! 868: dm, sx -> sx_type); ! 869: status++; ! 870: } ! 871: if (cc != sx -> sx_cc) { ! 872: advise (NULLCP, "length mismatch, orig=%d echo=%d", ! 873: cc, sx -> sx_cc); ! 874: status++; ! 875: } ! 876: else ! 877: if (qcmp (data, &sx -> sx_qbuf, cc)) ! 878: status++; ! 879: SXFREE (sx) ! 880: break; ! 881: ! 882: case DONE: ! 883: ss_event (sd, si); ! 884: continue; ! 885: ! 886: default: ! 887: adios (NULLCP, "unknown return from SReadRequest=%d", ! 888: result); ! 889: } ! 890: break; ! 891: } ! 892: ! 893: if (sync && ! 894: (requirements & SR_MINORSYNC) && !(requirements & SR_ACTIVITY)) { ! 895: if (SMinSyncRequest (sd, SYNC_CONFIRM, &ssn, userdata, SN_SIZE, si) ! 896: == NOTOK) ! 897: switch (sa -> sa_reason) { ! 898: case SC_OPERATION: ! 899: ss_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN); ! 900: if (SMinSyncRequest (sd, SYNC_CONFIRM, &ssn, userdata, ! 901: SN_SIZE, si) == OK) ! 902: break; /* else fall */ ! 903: ! 904: default: ! 905: ss_adios (sa, "S-MINOR-SYNC.REQUEST"); ! 906: } ! 907: ! 908: ss_waitfor (sd, -1); ! 909: } ! 910: else ! 911: if (sync ! 912: && (requirements & SR_ACTIVITY) ! 913: && (requirements & SR_MAJORSYNC) ! 914: && dm == SX_NORMAL) { ! 915: if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si) == NOTOK) ! 916: switch (sa -> sa_reason) { ! 917: case SC_OPERATION: ! 918: ss_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN ! 919: | ST_MAJ_TOKEN); ! 920: if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si) ! 921: == OK) ! 922: break;/* else fall */ ! 923: ! 924: default: ! 925: ss_adios (sa, "S-MAJOR-SYNC.REQUEST"); ! 926: } ! 927: ! 928: ss_waitfor (sd, -1); ! 929: } ! 930: } ! 931: ! 932: /* */ ! 933: ! 934: static int ss_waitfor (sd, want) ! 935: int sd, ! 936: want; ! 937: { ! 938: int result, ! 939: tokens; ! 940: char buffer[BUFSIZ]; ! 941: struct SSAPdata sxs; ! 942: register struct SSAPdata *sx = &sxs; ! 943: struct SSAPindication sis; ! 944: register struct SSAPindication *si = &sis; ! 945: register struct SSAPabort *sa = &si -> si_abort; ! 946: ! 947: for (;;) { ! 948: if (want == -1) { ! 949: want = avail; ! 950: goto read_it; ! 951: } ! 952: ! 953: tokens = 0; ! 954: #define dotoken(requires,shift,bit,type) \ ! 955: { \ ! 956: if ((want & bit) && !(owned & bit)) \ ! 957: tokens |= bit; \ ! 958: } ! 959: dotokens (); ! 960: #undef dotoken ! 961: if (tokens == 0) ! 962: return; ! 963: ! 964: if (SPTokenRequest (sd, tokens, userdata, ST_SIZE, si) == NOTOK) ! 965: ss_adios (sa, "S-TOKEN-PLEASE.REQUEST"); ! 966: ! 967: read_it: ; ! 968: switch (result = SReadRequest (sd, sx, NOTOK, si)) { ! 969: case NOTOK: ! 970: ss_adios (sa, "S-READ.REQUEST"); ! 971: ! 972: case OK: ! 973: (void) strcpy (buffer, "protocol screw-up"); ! 974: if (SUAbortRequest (sd, buffer, strlen (buffer) + 1, si) == NOTOK) ! 975: ss_adios (sa, "S-U-ABORT.REQUEST"); ! 976: adios (NULLCP, "%s, data indication type=0x%x", ! 977: buffer, sx -> sx_type); ! 978: ! 979: case DONE: ! 980: ss_event (sd, si); ! 981: break; ! 982: ! 983: default: ! 984: adios (NULLCP, "unknown return from SReadRequest=%d", ! 985: result); ! 986: } ! 987: } ! 988: } ! 989: ! 990: /* */ ! 991: ! 992: static ss_event (sd, si) ! 993: int sd; ! 994: register struct SSAPindication *si; ! 995: { ! 996: register struct SSAPabort *sa = &si -> si_abort; ! 997: register struct SSAPactivity *sv = &si -> si_activity; ! 998: register struct SSAPfinish *sf = &si -> si_finish; ! 999: register struct SSAPreport *sp = &si -> si_report; ! 1000: register struct SSAPsync *sn = &si -> si_sync; ! 1001: register struct SSAPtoken *st = &si -> si_token; ! 1002: ! 1003: switch (si -> si_type) { ! 1004: case SI_TOKEN: ! 1005: switch (st -> st_type) { ! 1006: case ST_GIVE: ! 1007: case ST_CONTROL: ! 1008: owned = st -> st_owned; ! 1009: break; ! 1010: ! 1011: case ST_PLEASE: ! 1012: if (SGTokenRequest (sd, ! 1013: (int) st -> st_tokens, si) ! 1014: == NOTOK) ! 1015: ss_adios (sa, "S-TOKEN-GIVE.REQUEST"); ! 1016: else ! 1017: owned &= ~st -> st_tokens; ! 1018: break; ! 1019: ! 1020: default: ! 1021: adios (NULLCP, ! 1022: "unknown token indication type=0x%x, %d bytes", ! 1023: st -> st_type, st -> st_cc); ! 1024: } ! 1025: STFREE (st); ! 1026: break; ! 1027: ! 1028: case SI_SYNC: ! 1029: switch (sn -> sn_type) { ! 1030: case SN_MAJORIND: ! 1031: adios (NULLCP, "majorsync indication %d, %d bytes", ! 1032: sn -> sn_ssn, sn -> sn_cc); ! 1033: break; ! 1034: ! 1035: case SN_MAJORCNF: ! 1036: break; ! 1037: ! 1038: case SN_MINORIND: ! 1039: adios (NULLCP, "minorsync indication %d%s, %d bytes", ! 1040: sn -> sn_ssn, sn -> sn_options == SYNC_CONFIRM ! 1041: ? " (wants confirmation)" : NULLCP, sn -> sn_cc); ! 1042: break; ! 1043: ! 1044: case SN_MINORCNF: ! 1045: break; ! 1046: ! 1047: case SN_RESETIND: ! 1048: #define dotoken(requires,shift,bit,type) \ ! 1049: { \ ! 1050: if (requirements & requires) \ ! 1051: switch (sn -> sn_settings & (ST_MASK << shift)) { \ ! 1052: case ST_CALL_VALUE << shift: \ ! 1053: sn -> sn_settings &= ~(ST_MASK << shift); \ ! 1054: sn -> sn_settings |= ST_RESP_VALUE << shift; \ ! 1055: case ST_RESP_VALUE << shift: \ ! 1056: owned &= ~bit; \ ! 1057: break; \ ! 1058: \ ! 1059: case ST_INIT_VALUE << shift: \ ! 1060: owned |= bit; \ ! 1061: break; \ ! 1062: \ ! 1063: default: \ ! 1064: adios (NULLCP, "%s token: reserved", type); \ ! 1065: break; \ ! 1066: } \ ! 1067: } ! 1068: dotokens (); ! 1069: #undef dotoken ! 1070: if (SReSyncResponse (sd, sn -> sn_ssn, sn -> sn_settings, ! 1071: userdata, SN_SIZE, si) == NOTOK) ! 1072: ss_adios (sa, "S-RESYNCHRONIZE.RESPONSE"); ! 1073: break; ! 1074: ! 1075: case SN_RESETCNF: ! 1076: break; ! 1077: ! 1078: default: ! 1079: adios (NULLCP, ! 1080: "unknown sync indication=0x%x, ssn=%d, %d bytes", ! 1081: sn -> sn_type, sn -> sn_ssn, sn -> sn_cc); ! 1082: } ! 1083: SNFREE (sn); ! 1084: break; ! 1085: ! 1086: case SI_ACTIVITY: ! 1087: switch (sv -> sv_type) { ! 1088: case SV_START: ! 1089: adios (NULLCP, ! 1090: "activity start indication: %*.*s, %d bytes", ! 1091: sv -> sv_id.sd_len, sv -> sv_id.sd_len, ! 1092: sv -> sv_id.sd_data, sv -> sv_cc); ! 1093: ! 1094: case SV_RESUME: ! 1095: adios (NULLCP, ! 1096: "activity resume indication: id=%*.*s oid=%*.*s connect=%s ssn=%d, %d bytes", ! 1097: sv -> sv_id.sd_len, sv -> sv_id.sd_len, ! 1098: sv -> sv_id.sd_data, sv -> sv_oid.sd_len, ! 1099: sv -> sv_oid.sd_len, sv -> sv_oid.sd_data, ! 1100: sprintref (&sv -> sv_connect), sv -> sv_ssn, ! 1101: sv -> sv_cc); ! 1102: ! 1103: case SV_INTRIND: ! 1104: adios (NULLCP, ! 1105: "activity interrupt indication %d, %d bytes", ! 1106: sv -> sv_reason, sv -> sv_cc); ! 1107: ! 1108: case SV_INTRCNF: ! 1109: break; ! 1110: ! 1111: case SV_DISCIND: ! 1112: adios (NULLCP, ! 1113: "activity discard indication %d, %d bytes", ! 1114: sv -> sv_reason, sv -> sv_cc); ! 1115: ! 1116: case SV_DISCCNF: ! 1117: break; ! 1118: ! 1119: case SV_ENDIND: ! 1120: adios (NULLCP, "activity end indication %d, %d bytes", ! 1121: sv -> sv_ssn, sv -> sv_cc); ! 1122: ! 1123: case SV_ENDCNF: ! 1124: break; ! 1125: ! 1126: default: ! 1127: adios (NULLCP, ! 1128: "unknown activity indication=0x%x, %d bytes", ! 1129: sv -> sv_type, sv -> sv_cc); ! 1130: } ! 1131: SVFREE (sv); ! 1132: break; ! 1133: ! 1134: case SI_REPORT: ! 1135: if (requirements & SR_DAT_EXISTS) { ! 1136: if (SGTokenRequest (sd, ST_DAT_TOKEN, si) == NOTOK) ! 1137: ss_adios (sa, "S-TOKEN-GIVE.REQUEST (to clear exception)"); ! 1138: else ! 1139: owned &= ~ST_DAT_TOKEN; ! 1140: } ! 1141: else ! 1142: if (SUAbortRequest (sd, NULLCP, 0, si) == NOTOK) ! 1143: ss_adios (sa, "S-U-ABORT.REQUEST"); ! 1144: else ! 1145: adios (NULLCP, "aborted"); ! 1146: SPFREE (sp); ! 1147: break; ! 1148: ! 1149: case SI_FINISH: ! 1150: if (SRelResponse (sd, SC_REJECTED, NULLCP, 0, si) == NOTOK) ! 1151: ss_adios (sa, "S-RELEASE.RESPONSE"); ! 1152: SFFREE (sf); ! 1153: break; ! 1154: ! 1155: default: ! 1156: adios (NULLCP, "unknown indication type=0x%x", ! 1157: si -> si_type); ! 1158: } ! 1159: } ! 1160: ! 1161: /* */ ! 1162: ! 1163: static void ss_adios (sa, event) ! 1164: register struct SSAPabort *sa; ! 1165: char *event; ! 1166: { ! 1167: ss_advise (sa, event); ! 1168: ! 1169: _exit (1); ! 1170: } ! 1171: ! 1172: ! 1173: static void ss_advise (sa, event) ! 1174: register struct SSAPabort *sa; ! 1175: char *event; ! 1176: { ! 1177: char buffer[BUFSIZ]; ! 1178: ! 1179: if (sa -> sa_cc > 0) ! 1180: (void) sprintf (buffer, "[%s] %*.*s", ! 1181: SErrString (sa -> sa_reason), ! 1182: sa -> sa_cc, sa -> sa_cc, sa -> sa_data); ! 1183: else ! 1184: (void) sprintf (buffer, "[%s]", SErrString (sa -> sa_reason)); ! 1185: ! 1186: advise (NULLCP, "%s: %s%s", event, buffer, ! 1187: sa -> sa_peer ? " (peer initiated)" : ""); ! 1188: ! 1189: SAFREE (sa); ! 1190: } ! 1191: ! 1192: /* PSAP */ ! 1193: ! 1194: static int prequirements = 0; ! 1195: #define srequirements requirements ! 1196: ! 1197: static int nctxs; ! 1198: static int datactxs[NPCTX]; ! 1199: ! 1200: /* */ ! 1201: ! 1202: static int ps_main (is, addr) ! 1203: struct isoservent *is; ! 1204: char *addr; ! 1205: { ! 1206: int sd, ! 1207: cc, ! 1208: i, ! 1209: j, ! 1210: k, ! 1211: l, ! 1212: m, ! 1213: tokens; ! 1214: char *cp, ! 1215: *dp, ! 1216: buffer[BUFSIZ]; ! 1217: register struct PSAPaddr *pz; ! 1218: struct SSAPactid ids; ! 1219: register struct SSAPactid *id = &ids; ! 1220: struct SSAPref sfs; ! 1221: register struct SSAPref *sf; ! 1222: struct PSAPconnect pcs; ! 1223: register struct PSAPconnect *pc = &pcs; ! 1224: struct PSAPctxlist pls; ! 1225: register struct PSAPctxlist *pl = &pls; ! 1226: struct PSAPrelease prs; ! 1227: register struct PSAPrelease *pr = &prs; ! 1228: struct PSAPindication pis; ! 1229: register struct PSAPindication *pi = &pis; ! 1230: register struct PSAPabort *pa = &pi -> pi_abort; ! 1231: struct AcSAPconnect accs; ! 1232: register struct AcSAPconnect *acc = &accs; ! 1233: struct AcSAPrelease acrs; ! 1234: register struct AcSAPrelease *acr = &acrs; ! 1235: struct AcSAPindication acis; ! 1236: register struct AcSAPindication *aci = &acis; ! 1237: register struct AcSAPabort *aca = &aci -> aci_abort; ! 1238: register PE pe; ! 1239: PE udata[NPDATA]; ! 1240: AEI aei; ! 1241: OID oid, ! 1242: ode; ! 1243: struct stat st; ! 1244: ! 1245: if (isacs) { ! 1246: if ((aei = str2aei (addr, isacs)) == NULLAEI) ! 1247: adios (NULLCP, "%s-%s: unknown application-entity", addr, isacs); ! 1248: if ((pz = aei2addr (aei)) == NULLPA) ! 1249: adios (NULLCP, "address translation failed"); ! 1250: ! 1251: cp = mode == echo ? "isode echo pci" : "isode sink pci"; ! 1252: if ((ode = ode2oid (cp)) == NULLOID) ! 1253: adios (NULLCP, "%s: unknown object descriptor", cp); ! 1254: ode = oid_cpy (ode); ! 1255: } ! 1256: else ! 1257: if ((pz = is2paddr (addr, NULLCP, is)) == NULL) ! 1258: adios (NULLCP, "address translation failed"); ! 1259: if ((sf = addr2ref (PLocalHostName ())) == NULL) { ! 1260: sf = &sfs; ! 1261: (void) bzero ((char *) sf, sizeof *sf); ! 1262: } ! 1263: ! 1264: tokens = 0; ! 1265: #define dotoken(requires,shift,bit,type) \ ! 1266: { \ ! 1267: if (srequirements & requires) \ ! 1268: tokens |= ST_CALL_VALUE << shift; \ ! 1269: } ! 1270: dotokens (); ! 1271: #undef dotoken ! 1272: ! 1273: for (i = (pl -> pc_nctx = NPCTX - (isacs ? 1 : 0)) - 1; i >= 0; i--) { ! 1274: pl -> pc_ctx[i].pc_id = i * 2 + 1; ! 1275: if ((oid = ode2oid ("iso asn.1 abstract syntax")) == NULLOID) ! 1276: adios (NULLCP, "iso asn.1 abstract syntax: unknown"); ! 1277: pl -> pc_ctx[i].pc_asn = oid_cpy (oid); ! 1278: pl -> pc_ctx[i].pc_atn = NULLOID; ! 1279: } ! 1280: ! 1281: for (i = 0; i < NPDATA; i++) { ! 1282: if ((pe = int2prim (i)) == NULLPE) ! 1283: adios (NULLCP, "unable to allocate hello"); ! 1284: pe -> pe_context = (i % pl -> pc_nctx) * 2 + 1; ! 1285: udata[i] = pe; ! 1286: } ! 1287: ! 1288: fprintf (stderr, "%s... ", addr); ! 1289: (void) fflush (stderr); ! 1290: if (isacs) { ! 1291: #ifndef ASYNC ! 1292: if (AcAssocRequest (ode, NULLAEI, aei, NULLPA, pz, pl, ode, ! 1293: prequirements, srequirements, ISN (srequirements), tokens, sf, ! 1294: udata, NACDATA, NULLQOS, acc, aci) ! 1295: == NOTOK) { ! 1296: fprintf (stderr, "failed\n"); ! 1297: acs_adios (aca, "A-ASSOCIATE.REQUEST"); ! 1298: } ! 1299: sd = acc -> acc_sd; ! 1300: #else ! 1301: if ((i = AcAsynAssocRequest (ode, NULLAEI, aei, NULLPA, pz, pl, ode, ! 1302: prequirements, srequirements, ISN (srequirements), tokens, sf, ! 1303: udata, NACDATA, NULLQOS, acc, aci, 1)) == NOTOK) { ! 1304: fprintf (stderr, "failed\n"); ! 1305: acs_adios (aca, "A-(ASYN-)ASSOCIATE.REQUEST"); ! 1306: } ! 1307: sd = acc -> acc_sd, cc = 0; ! 1308: while (i == CONNECTING_1 || i == CONNECTING_2) { ! 1309: int nfds; ! 1310: fd_set mask, ! 1311: *rmask, ! 1312: *wmask; ! 1313: ! 1314: nfds = 0; ! 1315: FD_ZERO (&mask); ! 1316: if (PSelectMask (sd, &mask, &nfds, pi) == NOTOK) { ! 1317: fprintf (stderr, "failed\n"); ! 1318: acs_adios (aca, "A-(ASYN-)ASSOCIATE.REQUEST(PSelectMask)"); ! 1319: } ! 1320: rmask = (i == CONNECTING_2) ? &mask : NULLFD; ! 1321: wmask = (i == CONNECTING_2) ? NULLFD : &mask; ! 1322: ! 1323: fprintf (stderr, "."); ! 1324: if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) { ! 1325: fprintf (stderr, "failed\n"); ! 1326: adios ("failed", "select"); ! 1327: } ! 1328: ! 1329: if ((rmask && FD_ISSET (sd, rmask) == 0) ! 1330: || (wmask && FD_ISSET (sd, wmask) == 0)) ! 1331: continue; ! 1332: ! 1333: if ((i = AcAsynRetryRequest (sd, acc, aci)) == NOTOK) { ! 1334: fprintf (stderr, "failed\n"); ! 1335: acs_adios (aca, "A-ASYN-RETRY.REQUEST"); ! 1336: } ! 1337: } ! 1338: #endif ! 1339: ! 1340: if (acc -> acc_result != ACS_ACCEPT) { ! 1341: fprintf (stderr, "failed\n"); ! 1342: adios (NULLCP, "connection rejected: [%s], %d elements", ! 1343: AcErrString (acc -> acc_result), acc -> acc_ninfo); ! 1344: } ! 1345: } ! 1346: else { ! 1347: #ifndef ASYNC ! 1348: if (PConnRequest (NULLPA, pz, pl, NULLOID, prequirements, ! 1349: srequirements, srequirements ! 1350: & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY) ! 1351: ? (long) (getpid () % (SERIAL_MAX - SERIAL_MIN + 1)) + SERIAL_MIN ! 1352: : SERIAL_NONE, tokens, sf, udata, NPDATA, NULLQOS, pc, pi) == NOTOK) { ! 1353: fprintf (stderr, "failed\n"); ! 1354: ps_adios (pa, "P-CONNECT.REQUEST"); ! 1355: } ! 1356: sd = pc -> pc_sd; ! 1357: #else ! 1358: if ((i = PAsynConnRequest (NULLPA, pz, pl, NULLOID, prequirements, ! 1359: srequirements, ISN (srequirements), tokens, sf, udata, NPDATA, ! 1360: NULLQOS, pc, pi, 1)) == NOTOK) { ! 1361: fprintf (stderr, "failed\n"); ! 1362: ps_adios (pa, "P-CONNECT.REQUEST"); ! 1363: } ! 1364: sd = pc -> pc_sd, cc = 0; ! 1365: while (i == CONNECTING_1 || i == CONNECTING_2) { ! 1366: int nfds; ! 1367: fd_set mask, ! 1368: *rmask, ! 1369: *wmask; ! 1370: ! 1371: nfds = 0; ! 1372: FD_ZERO (&mask); ! 1373: if (PSelectMask (sd, &mask, &nfds, pi) == NOTOK) { ! 1374: fprintf (stderr, "failed\n"); ! 1375: ps_adios (pa, "P-CONNECT.REQUEST(PSelectMask)"); ! 1376: } ! 1377: rmask = (i == CONNECTING_2) ? &mask : NULLFD; ! 1378: wmask = (i == CONNECTING_2) ? NULLFD : &mask; ! 1379: ! 1380: fprintf (stderr, "."); ! 1381: if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) { ! 1382: fprintf (stderr, "failed\n"); ! 1383: adios ("failed", "select"); ! 1384: } ! 1385: ! 1386: if ((rmask && FD_ISSET (sd, rmask) == 0) ! 1387: || (wmask && FD_ISSET (sd, wmask) == 0)) ! 1388: continue; ! 1389: ! 1390: if ((i = PAsynRetryRequest (sd, pc, pi)) == NOTOK) { ! 1391: fprintf (stderr, "failed\n"); ! 1392: ps_adios (pa, "P-ASYN-RETRY.REQUEST"); ! 1393: } ! 1394: } ! 1395: #endif ! 1396: ! 1397: if (pc -> pc_result != PC_ACCEPT) { ! 1398: fprintf (stderr, "failed\n"); ! 1399: adios (NULLCP, "connection rejected: [%s], %d elements", ! 1400: PErrString (pc -> pc_result), pc -> pc_ninfo); ! 1401: } ! 1402: } ! 1403: fprintf (stderr, "connected\n"); ! 1404: ! 1405: if (isacs) { ! 1406: pc = &acc -> acc_connect; ! 1407: ! 1408: #ifdef DEBUG ! 1409: { ! 1410: advise (NULLCP, "context: %s", oid2ode (acc -> acc_context)); ! 1411: ! 1412: advise (NULLCP, ! 1413: "responding AE title: %s, responding PSAP address: %s", ! 1414: sprintaei (&acc -> acc_respondtitle), ! 1415: paddr2str (&pc -> pc_responding, NULLNA)); ! 1416: ! 1417: advise (NULLCP, "greetings: %d elements", acc -> acc_ninfo); ! 1418: ! 1419: pl = &pc -> pc_ctxlist; ! 1420: for (i = 0; i < pl -> pc_nctx; i++) ! 1421: advise (NULLCP, "ctx %d: 0x%x 0x%x %d", ! 1422: pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn, ! 1423: pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result); ! 1424: advise (NULLCP, "default %d", pc -> pc_defctxresult); ! 1425: advise (NULLCP, "p/s requirements 0x%x/0x%x", ! 1426: pc -> pc_prequirements, pc -> pc_srequirements); ! 1427: } ! 1428: #endif ! 1429: ! 1430: pl = &pc -> pc_ctxlist; ! 1431: ! 1432: if (mode == echo) { ! 1433: if (acc -> acc_ninfo != NACDATA) ! 1434: adios (NULLCP, "expecting %d hellos, got %d elements", ! 1435: NACDATA, acc -> acc_ninfo); ! 1436: for (i = 0; i < NACDATA; i++) { ! 1437: if ((pe = acc -> acc_info[i]) == NULLPE) ! 1438: adios (NULLCP, "hello %d: NULL", i); ! 1439: if ((j = prim2num (pe)) == NOTOK ! 1440: && pe -> pe_errno != PE_ERR_NONE) ! 1441: adios (NULLCP, "hello %d: %s", i, ! 1442: pe_error (pe -> pe_errno)); ! 1443: if (j != i) ! 1444: adios (NULLCP, "hello %d: value %d", i, j); ! 1445: if (pe -> pe_context != udata[i] -> pe_context) ! 1446: adios (NULLCP, "hello %d: context of %d instead of %d", ! 1447: i, pe -> pe_context, udata[i] -> pe_context); ! 1448: } ! 1449: } ! 1450: ! 1451: goto do_release; ! 1452: } ! 1453: else { ! 1454: #ifdef DEBUG ! 1455: { ! 1456: advise (NULLCP, "responding PSAP address: %s", ! 1457: paddr2str (&pc -> pc_responding, NULLNA)); ! 1458: ! 1459: advise (NULLCP, "greetings: %d elements", pc -> pc_ninfo); ! 1460: ! 1461: pl = &pc -> pc_ctxlist; ! 1462: for (i = 0; i < pl -> pc_nctx; i++) ! 1463: advise (NULLCP, "ctx %d: 0x%x 0x%x %d", ! 1464: pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn, ! 1465: pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result); ! 1466: advise (NULLCP, "default %d", pc -> pc_defctxresult); ! 1467: advise (NULLCP, "p/s requirements 0x%x/0x%x", ! 1468: pc -> pc_prequirements, pc -> pc_srequirements); ! 1469: } ! 1470: #endif ! 1471: ! 1472: if (mode == echo) { ! 1473: if (pc -> pc_ninfo != NPDATA) ! 1474: adios (NULLCP, "expecting %d hellos, got %d elements", ! 1475: NPDATA, pc -> pc_ninfo); ! 1476: for (i = 0; i < NPDATA; i++) { ! 1477: if ((pe = pc -> pc_info[i]) == NULLPE) ! 1478: adios (NULLCP, "hello %d: NULL", i); ! 1479: if ((j = prim2num (pe)) == NOTOK ! 1480: && pe -> pe_errno != PE_ERR_NONE) ! 1481: adios (NULLCP, "hello %d: %s", i, ! 1482: pe_error (pe -> pe_errno)); ! 1483: if (j != i) ! 1484: adios (NULLCP, "hello %d: value %d", i, j); ! 1485: if (pe -> pe_context != udata[i] -> pe_context) ! 1486: adios (NULLCP, "hello %d: context of %d instead of %d", ! 1487: i, pe -> pe_context, udata[i] -> pe_context); ! 1488: } ! 1489: } ! 1490: } ! 1491: ! 1492: nctxs = 0; ! 1493: pl = &pc -> pc_ctxlist; ! 1494: for (i = 0; i < pl -> pc_nctx; i++) ! 1495: if (pl -> pc_ctx[i].pc_result == PC_ACCEPT) ! 1496: datactxs[nctxs++] = pl -> pc_ctx[i].pc_id; ! 1497: ! 1498: srequirements = pc -> pc_srequirements; ! 1499: nmodes = 0; ! 1500: datamodes[nmodes++] = SX_NORMAL; ! 1501: if (srequirements & SR_EXPEDITED) ! 1502: datamodes[nmodes++] = SX_EXPEDITED; ! 1503: if ((srequirements & SR_CAPABILITY) && (srequirements & SR_ACTIVITY)) ! 1504: datamodes[nmodes++] = SX_CAPDIND; ! 1505: if (srequirements & SR_TYPEDATA) ! 1506: datamodes[nmodes++] = SX_TYPED; ! 1507: ! 1508: #define dotoken(requires,shift,bit,type) \ ! 1509: { \ ! 1510: if (srequirements & requires) \ ! 1511: switch (pc -> pc_settings & (ST_MASK << shift)) { \ ! 1512: case ST_CALL_VALUE: \ ! 1513: adios (NULLCP, "%s token: choice", type); \ ! 1514: \ ! 1515: case ST_INIT_VALUE: \ ! 1516: owned |= bit, avail |= bit; \ ! 1517: break; \ ! 1518: \ ! 1519: case ST_RESP_VALUE: \ ! 1520: avail |= bit; \ ! 1521: break; \ ! 1522: \ ! 1523: default: \ ! 1524: adios (NULLCP, "%s token: reserved", type); \ ! 1525: } \ ! 1526: } ! 1527: dotokens (); ! 1528: #undef dotoken ! 1529: ! 1530: if (isacs) ! 1531: ACCFREE (acc) ! 1532: else ! 1533: PCFREE (pc); ! 1534: ! 1535: if (srequirements & SR_ACTIVITY) { ! 1536: (void) strcpy (id -> sd_data, mode == echo ? "echo" : "sink"); ! 1537: id -> sd_len = strlen (id -> sd_data); ! 1538: if (PActStartRequest (sd, id, udata, NPDATA, pi) == NOTOK) ! 1539: ps_adios (pa, "P-ACTIVITY-START.REQUEST"); ! 1540: } ! 1541: ! 1542: if (fstat (fileno (stdin), &st) != NOTOK ! 1543: && (st.st_mode & S_IFMT) == S_IFREG ! 1544: && (cc = st.st_size) != 0) { ! 1545: (void) lseek (fileno (stdin), 0L, 0); ! 1546: ! 1547: if ((cp = malloc ((unsigned) cc)) == NULL) ! 1548: adios (NULLCP, "no memory"); ! 1549: for (dp = cp, j = cc; j > 0; dp += i, j -= i) ! 1550: switch (i = read (fileno (stdin), dp, j)) { ! 1551: case NOTOK: ! 1552: adios ("on stdin", "read failed"); ! 1553: ! 1554: case OK: ! 1555: adios (NULLCP, "premature end-of-file"); ! 1556: ! 1557: default: ! 1558: break; ! 1559: } ! 1560: if ((pe = oct2prim (cp, cc)) == NULLPE) ! 1561: adios (NULLCP, "unable to allocate PSDU"); ! 1562: free (cp); ! 1563: if (nctxs) ! 1564: pe -> pe_context = datactxs[0]; ! 1565: for (i = 10; i > 0; i--) { ! 1566: #ifdef TIMER ! 1567: timer (0); ! 1568: #endif ! 1569: ps_datarequest (sd, pe, SX_NORMAL, 0); ! 1570: #ifdef TIMER ! 1571: timer (cc); ! 1572: #endif ! 1573: } ! 1574: pe_free (pe); ! 1575: } ! 1576: else { ! 1577: for (j = l = m = 0; fgets (buffer, sizeof buffer, stdin); ) { ! 1578: k = j >= nmodes ? SX_EXPEDITED : datamodes[j++ % nmodes]; ! 1579: if ((cc = strlen (buffer) + 1) > SX_EXSIZE - 7 ! 1580: && k == SX_EXPEDITED) { ! 1581: if ((k = datamodes[j++ % nmodes]) == SX_EXPEDITED) ! 1582: k = datamodes[j++ % nmodes]; ! 1583: } ! 1584: ! 1585: switch (k) { ! 1586: case SX_CAPDIND: ! 1587: if (!(requirements & SR_RESYNC) || l++ & 0x01) { ! 1588: ps_waitfor (sd, ST_ACT_TOKEN); ! 1589: if (l & 0x03) { ! 1590: if (PActIntrRequest (sd, SP_SEQUENCE, pi) ! 1591: == NOTOK) ! 1592: ps_adios (pa, "P-ACTIVITY-INTERRUPT.REQUEST"); ! 1593: } ! 1594: else { ! 1595: if (PActDiscRequest (sd, SP_SEQUENCE, pi) ! 1596: == NOTOK) ! 1597: ps_adios (pa, "P-ACTIVITY-DISCARD.REQUEST"); ! 1598: } ! 1599: ps_waitfor (sd, -1); ! 1600: goto push_data; ! 1601: } ! 1602: tokens = 0; ! 1603: #define dotoken(requires,shift,bit,type) \ ! 1604: { \ ! 1605: if (requirements & requires) \ ! 1606: tokens |= ST_CALL_VALUE << shift; \ ! 1607: } ! 1608: dotokens (); ! 1609: #undef dotoken ! 1610: if (PReSyncRequest (sd, SYNC_SET, ssn - 1, tokens, ! 1611: udata, NPDATA, pi) == NOTOK) ! 1612: ps_adios (pa, "P-RESYNCHRONIZE.REQUEST"); ! 1613: ps_waitfor (sd, -1); ! 1614: break; ! 1615: ! 1616: case SX_EXPEDITED: ! 1617: if (j >= nmodes) ! 1618: j = j % nmodes; ! 1619: if (!(srequirements & SR_EXPEDITED)) ! 1620: k = SX_NORMAL; /* fall... */ ! 1621: default: ! 1622: push_data: ; ! 1623: if ((pe = oct2prim (buffer, cc)) == NULLPE) ! 1624: adios (NULLCP, "unable to allocate PSDU"); ! 1625: if (nctxs && k != SX_EXPEDITED) ! 1626: pe -> pe_context = datactxs[m++ % nctxs]; ! 1627: ps_datarequest (sd, pe, k, 1); ! 1628: pe_free (pe); ! 1629: if (k == SX_CAPDIND ! 1630: && PActResumeRequest (sd, id, id, ! 1631: (long) (getpid () % (SERIAL_MAX - SERIAL_MIN + 1)) ! 1632: + SERIAL_MIN, sf, udata, NPDATA, pi) ! 1633: == NOTOK) ! 1634: ps_adios (pa, "P-ACTIVITY-RESUME.REQUEST"); ! 1635: break; ! 1636: } ! 1637: } ! 1638: ! 1639: if (requirements & SR_EXCEPTIONS) { ! 1640: if (owned & ST_DAT_TOKEN) ! 1641: if (PGTokenRequest (sd, ST_DAT_TOKEN, pi) == NOTOK) ! 1642: ps_adios (pa, "P-TOKEN-GIVE.REQUEST"); ! 1643: else ! 1644: owned &= ~ST_DAT_TOKEN; ! 1645: if (PUReportRequest (sd, SP_NOREASON, udata, NPDATA, pi) == NOTOK) ! 1646: ps_adios (pa, "P-U-EXCEPTION-REPORT.REQUEST"); ! 1647: ps_waitfor (sd, -1); ! 1648: } ! 1649: } ! 1650: ! 1651: if ((requirements & SR_MAJORSYNC) && !(requirements & SR_ACTIVITY)) { ! 1652: if (PMajSyncRequest (sd, &ssn, udata, NPDATA, pi) == NOTOK) ! 1653: switch (pa -> pa_reason) { ! 1654: case PC_OPERATION: ! 1655: ps_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN ! 1656: | ST_MAJ_TOKEN); ! 1657: if (PMajSyncRequest (sd, &ssn, udata, NPDATA, pi) == OK) ! 1658: break; /* else fall */ ! 1659: ! 1660: default: ! 1661: ps_adios (pa, "P-MAJOR-SYNC.REQUEST"); ! 1662: } ! 1663: ! 1664: ps_waitfor (sd, -1); ! 1665: } ! 1666: ! 1667: if (requirements & SR_ACTIVITY) { ! 1668: if (PActEndRequest (sd, &ssn, udata, NPDATA, pi) == NOTOK) ! 1669: switch (pa -> pa_reason) { ! 1670: case PC_OPERATION: ! 1671: ps_waitfor (sd, avail); ! 1672: if (PActEndRequest (sd, &ssn, udata, NPDATA, pi) == OK) ! 1673: break; /* else fall */ ! 1674: ! 1675: default: ! 1676: ps_adios (pa, "P-ACTIVITY-END.REQUEST"); ! 1677: } ! 1678: ! 1679: ps_waitfor (sd, -1); ! 1680: ! 1681: if (PGControlRequest (sd, pi) == NOTOK) ! 1682: switch (pa -> pa_reason) { ! 1683: case PC_OPERATION: ! 1684: ps_waitfor (sd, avail); ! 1685: if (PGControlRequest (sd, pi) == OK) ! 1686: break; /* else fall */ ! 1687: ! 1688: default: ! 1689: ps_adios (pa, "P-CONTROL-GIVE.REQUEST"); ! 1690: } ! 1691: ! 1692: owned = 0; ! 1693: ! 1694: ps_waitfor (sd, -1); ! 1695: } ! 1696: ! 1697: do_release: ; ! 1698: if (isacs) { ! 1699: if (AcRelRequest (sd, ACF_NORMAL, udata, NACDATA, NOTOK, acr, aci) ! 1700: == NOTOK) ! 1701: switch (aca -> aca_reason) { ! 1702: case ACS_OPERATION: ! 1703: ps_waitfor (sd, avail); ! 1704: if (AcRelRequest (sd, ACF_NORMAL, udata, NACDATA, NOTOK, ! 1705: acr, aci) == OK) ! 1706: break; /* else fall */ ! 1707: ! 1708: default: ! 1709: acs_adios (aca, "A-RELEASE.REQUEST"); ! 1710: } ! 1711: ! 1712: if (!acr -> acr_affirmative) { ! 1713: (void) AcUAbortRequest (sd, NULLPEP, 0, aci); ! 1714: adios (NULLCP, "release rejected by peer: %d, %d elements", ! 1715: acr -> acr_reason, acr -> acr_ninfo); ! 1716: } ! 1717: ! 1718: #ifdef DEBUG ! 1719: advise (NULLCP, "A-RELEASE.CONFIRMATION: %d, %d elements", ! 1720: acr -> acr_reason, acr -> acr_ninfo); ! 1721: #endif ! 1722: ACRFREE (acr); ! 1723: } ! 1724: else { ! 1725: if (PRelRequest (sd, udata, NPDATA, NOTOK, pr, pi) == NOTOK) ! 1726: switch (pa -> pa_reason) { ! 1727: case PC_OPERATION: ! 1728: case PC_WAITING: ! 1729: ps_waitfor (sd, avail); ! 1730: if (PRelRequest (sd, udata, NPDATA, NOTOK, pr, pi) == OK) ! 1731: break; /* else fall */ ! 1732: ! 1733: default: ! 1734: ps_adios (pa, "P-RELEASE.REQUEST"); ! 1735: } ! 1736: ! 1737: if (!pr -> pr_affirmative) { ! 1738: (void) PUAbortRequest (sd, NULLPEP, 0, pi); ! 1739: adios (NULLCP, "release rejected by peer: %d elements", ! 1740: pr -> pr_ninfo); ! 1741: } ! 1742: PRFREE (pr); ! 1743: } ! 1744: ! 1745: for (i = 0; i < NPDATA; i++) ! 1746: pe_free (udata[i]); ! 1747: } ! 1748: ! 1749: /* */ ! 1750: ! 1751: static int ps_datarequest (sd, pe, dm, sync) ! 1752: int sd; ! 1753: PE pe; ! 1754: int dm, ! 1755: sync; ! 1756: { ! 1757: int result; ! 1758: struct PSAPdata pxs; ! 1759: register struct PSAPdata *px = &pxs; ! 1760: struct PSAPindication pis; ! 1761: register struct PSAPindication *pi = &pis; ! 1762: register struct PSAPabort *pa = &pi -> pi_abort; ! 1763: ! 1764: switch (dm) { ! 1765: default: ! 1766: if (PDataRequest (sd, &pe, 1, pi) == NOTOK) ! 1767: switch (pa -> pa_reason) { ! 1768: case PC_OPERATION: ! 1769: ps_waitfor (sd, ST_DAT_TOKEN); ! 1770: if (PDataRequest (sd, &pe, 1, pi) == OK) ! 1771: break;/* else fall */ ! 1772: ! 1773: default: ! 1774: ps_adios (pa, "P-DATA.REQUEST"); ! 1775: } ! 1776: break; ! 1777: ! 1778: case SX_EXPEDITED: ! 1779: if (PExpdRequest (sd, &pe, 1, pi) == NOTOK) ! 1780: ps_adios (pa, "P-EXPEDITED-DATA.REQUEST"); ! 1781: break; ! 1782: ! 1783: case SX_CAPDIND: ! 1784: if (PCapdRequest (sd, &pe, 1, pi) == NOTOK) ! 1785: switch (pa -> pa_reason) { ! 1786: case PC_OPERATION: ! 1787: ps_waitfor (sd, avail & ~ST_RLS_TOKEN); ! 1788: if (PCapdRequest (sd, &pe, 1, pi) == OK) ! 1789: break;/* else fall */ ! 1790: ! 1791: default: ! 1792: ps_adios (pa, "P-CAPABILITY-DATA.REQUEST"); ! 1793: } ! 1794: break; ! 1795: ! 1796: case SX_TYPED: ! 1797: if (PTypedRequest (sd, &pe, 1, pi) == NOTOK) ! 1798: ps_adios (pa, "P-TYPED-DATA.REQUEST"); ! 1799: break; ! 1800: } ! 1801: ! 1802: if (mode == echo || dm == SX_CAPDIND) ! 1803: for (;;) { ! 1804: switch (result = PReadRequest (sd, px, NOTOK, pi)) { ! 1805: case NOTOK: ! 1806: ps_adios (pa, "P-READ.REQUEST"); ! 1807: ! 1808: case OK: ! 1809: if ((dm != SX_CAPDIND ? dm : SX_CAPDCNF) ! 1810: != px -> px_type) { ! 1811: advise (NULLCP, ! 1812: "data indication type mismatch, orig=%d echo=%d", ! 1813: dm, px -> px_type); ! 1814: status++; ! 1815: } ! 1816: if (px -> px_ninfo != 1) { ! 1817: advise (NULLCP, "length mismatch, orig=%d echo=%d", ! 1818: 1, px -> px_ninfo); ! 1819: status++; ! 1820: } ! 1821: if (pe -> pe_context != (*px -> px_info) -> pe_context) { ! 1822: advise (NULLCP, "context mismatch, orig=%d echo=%d", ! 1823: pe -> pe_context, ! 1824: (*px -> px_info) -> pe_context); ! 1825: status++; ! 1826: } ! 1827: if (pe_cmp (pe, *px -> px_info)) { ! 1828: advise (NULLCP, "data mismatch"); ! 1829: status++; ! 1830: } ! 1831: PXFREE (px) ! 1832: break; ! 1833: ! 1834: case DONE: ! 1835: ps_event (sd, pi); ! 1836: continue; ! 1837: ! 1838: default: ! 1839: adios (NULLCP, "unknown return from PReadRequest=%d", ! 1840: result); ! 1841: } ! 1842: break; ! 1843: } ! 1844: ! 1845: if (sync && ! 1846: (srequirements & SR_MINORSYNC) && !(srequirements & SR_ACTIVITY)) { ! 1847: if (PMinSyncRequest (sd, SYNC_CONFIRM, &ssn, NULLPEP, 0, pi) == NOTOK) ! 1848: switch (pa -> pa_reason) { ! 1849: case PC_OPERATION: ! 1850: ps_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN); ! 1851: if (PMinSyncRequest (sd, SYNC_CONFIRM, &ssn, NULLPEP, 0, ! 1852: pi) == OK) ! 1853: break; /* else fall */ ! 1854: ! 1855: default: ! 1856: ps_adios (pa, "P-MINOR-SYNC.REQUEST"); ! 1857: } ! 1858: ! 1859: ps_waitfor (sd, -1); ! 1860: } ! 1861: else ! 1862: if (sync ! 1863: && (srequirements & SR_ACTIVITY) ! 1864: && (srequirements & SR_MAJORSYNC) ! 1865: && dm == SX_NORMAL) { ! 1866: if (PMajSyncRequest (sd, &ssn, NULLPEP, 0, pi) == NOTOK) ! 1867: switch (pa -> pa_reason) { ! 1868: case PC_OPERATION: ! 1869: ps_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN ! 1870: | ST_MAJ_TOKEN); ! 1871: if (PMajSyncRequest (sd, &ssn, NULLPEP, 0, pi) == OK) ! 1872: break;/* else fall */ ! 1873: ! 1874: default: ! 1875: ps_adios (pa, "P-MAJOR-SYNC.REQUEST"); ! 1876: } ! 1877: ! 1878: ps_waitfor (sd, -1); ! 1879: } ! 1880: } ! 1881: ! 1882: /* */ ! 1883: ! 1884: static int ps_waitfor (sd, want) ! 1885: int sd, ! 1886: want; ! 1887: { ! 1888: int result, ! 1889: tokens; ! 1890: struct PSAPdata pxs; ! 1891: register struct PSAPdata *px = &pxs; ! 1892: struct PSAPindication pis; ! 1893: register struct PSAPindication *pi = &pis; ! 1894: register struct PSAPabort *pa = &pi -> pi_abort; ! 1895: ! 1896: for (;;) { ! 1897: if (want == -1) { ! 1898: want = avail; ! 1899: goto read_it; ! 1900: } ! 1901: ! 1902: tokens = 0; ! 1903: #define dotoken(requires,shift,bit,type) \ ! 1904: { \ ! 1905: if ((want & bit) && !(owned & bit)) \ ! 1906: tokens |= bit; \ ! 1907: } ! 1908: dotokens (); ! 1909: #undef dotoken ! 1910: if (tokens == 0) ! 1911: return; ! 1912: ! 1913: if (PPTokenRequest (sd, tokens, NULLPEP, 0, pi) == NOTOK) ! 1914: ps_adios (pa, "P-TOKEN-PLEASE.REQUEST"); ! 1915: ! 1916: read_it: ; ! 1917: switch (result = PReadRequest (sd, px, NOTOK, pi)) { ! 1918: case NOTOK: ! 1919: ps_adios (pa, "P-READ.REQUEST"); ! 1920: ! 1921: case OK: ! 1922: ps_abort (sd, "protocol screw-up"); ! 1923: ! 1924: case DONE: ! 1925: ps_event (sd, pi); ! 1926: break; ! 1927: ! 1928: default: ! 1929: adios (NULLCP, "unknown return from PReadRequest=%d", ! 1930: result); ! 1931: } ! 1932: } ! 1933: } ! 1934: ! 1935: /* */ ! 1936: ! 1937: static ps_event (sd, pi) ! 1938: int sd; ! 1939: register struct PSAPindication *pi; ! 1940: { ! 1941: register struct PSAPabort *pa = &pi -> pi_abort; ! 1942: register struct PSAPactivity *pv = &pi -> pi_activity; ! 1943: register struct PSAPfinish *pf = &pi -> pi_finish; ! 1944: register struct PSAPreport *pp = &pi -> pi_report; ! 1945: register struct PSAPsync *pn = &pi -> pi_sync; ! 1946: register struct PSAPtoken *pt = &pi -> pi_token; ! 1947: struct AcSAPindication acis; ! 1948: register struct AcSAPindication *aci = &acis; ! 1949: register struct AcSAPabort *aca = &aci -> aci_abort; ! 1950: register struct AcSAPfinish *acf = &aci -> aci_finish; ! 1951: ! 1952: switch (pi -> pi_type) { ! 1953: case PI_TOKEN: ! 1954: switch (pt -> pt_type) { ! 1955: case ST_GIVE: ! 1956: case ST_CONTROL: ! 1957: owned = pt -> pt_owned; ! 1958: break; ! 1959: ! 1960: case ST_PLEASE: ! 1961: if (PGTokenRequest (sd, ! 1962: (int) pt -> pt_tokens, pi) ! 1963: == NOTOK) ! 1964: ps_adios (pa, "P-TOKEN-GIVE.REQUEST"); ! 1965: else ! 1966: owned &= ~pt -> pt_tokens; ! 1967: break; ! 1968: ! 1969: default: ! 1970: adios (NULLCP, ! 1971: "unknown token indication type=0x%x", ! 1972: pt -> pt_type); ! 1973: } ! 1974: PTFREE (pt); ! 1975: break; ! 1976: ! 1977: case PI_SYNC: ! 1978: switch (pn -> pn_type) { ! 1979: case SN_MAJORIND: ! 1980: adios (NULLCP, "majorsync indication %d", ! 1981: pn -> pn_ssn); ! 1982: break; ! 1983: ! 1984: case SN_MAJORCNF: ! 1985: break; ! 1986: ! 1987: case SN_MINORIND: ! 1988: adios (NULLCP, "minorsync indication %d%s", ! 1989: pn -> pn_ssn, pn -> pn_options == SYNC_CONFIRM ! 1990: ? " (wants confirmation)" : NULLCP); ! 1991: break; ! 1992: ! 1993: case SN_MINORCNF: ! 1994: break; ! 1995: ! 1996: case SN_RESETIND: ! 1997: #define dotoken(requires,shift,bit,type) \ ! 1998: { \ ! 1999: if (srequirements & requires) \ ! 2000: switch (pn -> pn_settings & (ST_MASK << shift)) { \ ! 2001: case ST_CALL_VALUE << shift: \ ! 2002: pn -> pn_settings &= ~(ST_MASK << shift); \ ! 2003: pn -> pn_settings |= ST_RESP_VALUE << shift; \ ! 2004: case ST_RESP_VALUE << shift: \ ! 2005: owned &= ~bit; \ ! 2006: break; \ ! 2007: \ ! 2008: case ST_INIT_VALUE << shift: \ ! 2009: owned |= bit; \ ! 2010: break; \ ! 2011: \ ! 2012: default: \ ! 2013: adios (NULLCP, "%s token: reserved", type); \ ! 2014: break; \ ! 2015: } \ ! 2016: } ! 2017: dotokens (); ! 2018: #undef dotoken ! 2019: if (PReSyncResponse (sd, pn -> pn_ssn, pn -> pn_settings, ! 2020: NULLPEP, 0, pi) == NOTOK) ! 2021: ps_adios (pa, "P-RESYNCHRONIZE.RESPONSE"); ! 2022: break; ! 2023: ! 2024: case SN_RESETCNF: ! 2025: break; ! 2026: ! 2027: default: ! 2028: adios (NULLCP, "unknown sync indication=0x%x, ssn=%d", ! 2029: pn -> pn_type, pn -> pn_ssn); ! 2030: } ! 2031: PNFREE (pn); ! 2032: break; ! 2033: ! 2034: case PI_ACTIVITY: ! 2035: switch (pv -> pv_type) { ! 2036: case SV_START: ! 2037: adios (NULLCP, "activity start indication: %*.*s", ! 2038: pv -> pv_id.sd_len, pv -> pv_id.sd_len, ! 2039: pv -> pv_id.sd_data); ! 2040: ! 2041: case SV_RESUME: ! 2042: adios (NULLCP, ! 2043: "activity resume indication: id=%*.*s oid=%*.*s connect=%s ssn=%d", ! 2044: pv -> pv_id.sd_len, pv -> pv_id.sd_len, ! 2045: pv -> pv_id.sd_data, pv -> pv_oid.sd_len, ! 2046: pv -> pv_oid.sd_len, pv -> pv_oid.sd_data, ! 2047: sprintref (&pv -> pv_connect), pv -> pv_ssn); ! 2048: ! 2049: case SV_INTRIND: ! 2050: adios (NULLCP, "activity interrupt indication %d", ! 2051: pv -> pv_reason); ! 2052: ! 2053: case SV_INTRCNF: ! 2054: break; ! 2055: ! 2056: case SV_DISCIND: ! 2057: adios (NULLCP, "activity discard indication %d", ! 2058: pv -> pv_reason); ! 2059: ! 2060: case SV_DISCCNF: ! 2061: break; ! 2062: ! 2063: case SV_ENDIND: ! 2064: adios (NULLCP, "activity end indication %d", ! 2065: pv -> pv_ssn); ! 2066: ! 2067: case SV_ENDCNF: ! 2068: break; ! 2069: ! 2070: default: ! 2071: adios (NULLCP, "unknown activity indication=0x%x", ! 2072: pv -> pv_type); ! 2073: } ! 2074: PVFREE (pv); ! 2075: break; ! 2076: ! 2077: case PI_REPORT: ! 2078: advise (NULLCP, "%s report %d", ! 2079: pp -> pp_peer ? "user" : "provider", pp -> pp_reason); ! 2080: if (srequirements & SR_DAT_EXISTS) { ! 2081: if (PGTokenRequest (sd, ST_DAT_TOKEN, pi) == NOTOK) ! 2082: ps_adios (pa, "P-TOKEN-GIVE.REQUEST (to clear exception)"); ! 2083: else ! 2084: owned &= ~ST_DAT_TOKEN; ! 2085: } ! 2086: else ! 2087: ps_abort (sd, "aborted"); ! 2088: PPFREE (pp); ! 2089: break; ! 2090: ! 2091: case PI_FINISH: ! 2092: if (isacs) { ! 2093: if (AcFINISHser (sd, pf, aci) == NOTOK) ! 2094: acs_adios (aca, "AcFINISHser"); ! 2095: #ifdef DEBUG ! 2096: advise (NULLCP, "A-RELEASE.INDICATION %d, %d elements", ! 2097: acf -> acf_reason, acf -> acf_ninfo); ! 2098: if (AcRelResponse (sd, ACS_USER_NOREASON, ACR_NOTFINISHED, ! 2099: NULLPEP, 0, aci) == NOTOK) ! 2100: acs_adios (aca, "A-RELEASE.RESPONSE"); ! 2101: #endif ! 2102: ! 2103: ACFFREE (acf); ! 2104: } ! 2105: else { ! 2106: if (PRelResponse (sd, PC_REJECTED, NULLPEP, 0, pi) == NOTOK) ! 2107: ps_adios (pa, "P-RELEASE.RESPONSE"); ! 2108: ! 2109: PFFREE (pf); ! 2110: } ! 2111: break; ! 2112: ! 2113: default: ! 2114: adios (NULLCP, "unknown indication type=0x%x", pi -> pi_type); ! 2115: } ! 2116: } ! 2117: ! 2118: /* */ ! 2119: ! 2120: static ps_abort (sd, reason) ! 2121: int sd; ! 2122: char *reason; ! 2123: { ! 2124: struct PSAPindication pis; ! 2125: register struct PSAPindication *pi = &pis; ! 2126: register struct PSAPabort *pa = &pi -> pi_abort; ! 2127: struct AcSAPindication acis; ! 2128: register struct AcSAPindication *aci = &acis; ! 2129: register struct AcSAPabort *aca = &aci -> aci_abort; ! 2130: ! 2131: if (isacs) { ! 2132: if (AcUAbortRequest (sd, NULLPEP, 0, aci) == NOTOK) ! 2133: acs_adios (aca, "A-U-ABORT.REQUEST"); ! 2134: } ! 2135: else { ! 2136: if (PUAbortRequest (sd, NULLPEP, 0, pi) == NOTOK) ! 2137: ps_adios (pa, "P-U-ABORT.REQUEST"); ! 2138: } ! 2139: ! 2140: adios (NULLCP, "%s", reason); ! 2141: } ! 2142: ! 2143: /* */ ! 2144: ! 2145: static void ps_adios (pa, event) ! 2146: register struct PSAPabort *pa; ! 2147: char *event; ! 2148: { ! 2149: ps_advise (pa, event); ! 2150: ! 2151: _exit (1); ! 2152: } ! 2153: ! 2154: ! 2155: static void ps_advise (pa, event) ! 2156: register struct PSAPabort *pa; ! 2157: char *event; ! 2158: { ! 2159: char buffer[BUFSIZ]; ! 2160: ! 2161: if (pa -> pa_cc > 0) ! 2162: (void) sprintf (buffer, "[%s] %*.*s", ! 2163: PErrString (pa -> pa_reason), ! 2164: pa -> pa_cc, pa -> pa_cc, pa -> pa_data); ! 2165: else ! 2166: (void) sprintf (buffer, "[%s]", PErrString (pa -> pa_reason)); ! 2167: ! 2168: advise (NULLCP, "%s: %s%s", event, buffer, ! 2169: pa -> pa_peer ? " (peer initiated)" : ""); ! 2170: } ! 2171: ! 2172: /* AcSAP */ ! 2173: ! 2174: static void acs_adios (aca, event) ! 2175: register struct AcSAPabort *aca; ! 2176: char *event; ! 2177: { ! 2178: acs_advise (aca, event); ! 2179: ! 2180: _exit (1); ! 2181: } ! 2182: ! 2183: ! 2184: static void acs_advise (aca, event) ! 2185: register struct AcSAPabort *aca; ! 2186: char *event; ! 2187: { ! 2188: char buffer[BUFSIZ]; ! 2189: ! 2190: if (aca -> aca_cc > 0) ! 2191: (void) sprintf (buffer, "[%s] %*.*s", ! 2192: AcErrString (aca -> aca_reason), ! 2193: aca -> aca_cc, aca -> aca_cc, aca -> aca_data); ! 2194: else ! 2195: (void) sprintf (buffer, "[%s]", AcErrString (aca -> aca_reason)); ! 2196: ! 2197: advise (NULLCP, "%s: %s (source %d)", event, buffer, ! 2198: aca -> aca_source); ! 2199: } ! 2200: ! 2201: /* RtSAP */ ! 2202: ! 2203: static int turn = 0; ! 2204: ! 2205: /* */ ! 2206: ! 2207: static int rts_main (is, addr) ! 2208: struct isoservent *is; ! 2209: char *addr; ! 2210: { ! 2211: int sd, ! 2212: cc, ! 2213: i, ! 2214: j, ! 2215: ros; ! 2216: char *cp, ! 2217: *dp, ! 2218: buffer[BUFSIZ]; ! 2219: register struct PSAPaddr *pa; ! 2220: struct PSAPctxlist pls; ! 2221: register struct PSAPctxlist *pl = &pls; ! 2222: struct AcSAPrelease acrs; ! 2223: register struct AcSAPrelease *acr = &acrs; ! 2224: struct RtSAPaddr rtzs; ! 2225: register struct RtSAPaddr *rtz = &rtzs; ! 2226: struct RtSAPconnect rtcs; ! 2227: register struct RtSAPconnect *rtc = &rtcs; ! 2228: struct RtSAPindication rtis; ! 2229: register struct RtSAPindication *rti = &rtis; ! 2230: register struct RtSAPabort *rta = &rti -> rti_abort; ! 2231: #ifdef DEBUG ! 2232: struct AcSAPconnect *acc= &rtc -> rtc_connect; ! 2233: struct PSAPconnect *pc = &acc -> acc_connect; ! 2234: #endif ! 2235: register PE pe; ! 2236: AEI aei; ! 2237: OID oid, ! 2238: ode; ! 2239: struct stat st; ! 2240: ! 2241: if ((pe = int2prim (i = getpid ())) == NULLPE) ! 2242: adios (NULLCP, "unable to allocate hello"); ! 2243: ! 2244: turn = mode == sink; ! 2245: ! 2246: if (isacs) { ! 2247: if (ros = strncmp (isacs, "isode/ros_", strlen ("isode/ros_")) == 0) ! 2248: mode = strcmp (isacs, "isode/ros_sink") ? echo : sink; ! 2249: else ! 2250: mode = strcmp (isacs, "isode/rtse sink") ? echo : sink; ! 2251: turn = mode == sink; ! 2252: ! 2253: if ((aei = str2aei (addr, isacs)) == NULLAEI) ! 2254: adios (NULLCP, "%s-%s: unknown application-entity", addr, isacs); ! 2255: if ((pa = aei2addr (aei)) == NULLPA) ! 2256: adios (NULLCP, "address translation failed"); ! 2257: ! 2258: cp = mode == echo ? "isode echo pci" : "isode sink pci"; ! 2259: if ((ode = ode2oid (cp)) == NULLOID) ! 2260: adios (NULLCP, "%s: unknown object descriptor", cp); ! 2261: ode = oid_cpy (ode); ! 2262: ! 2263: for (j = (pl -> pc_nctx = NPCTX - 2) - 1; j >= 0; j--) { ! 2264: pl -> pc_ctx[j].pc_id = j * 2 + 1; ! 2265: if ((oid = ode2oid ("iso asn.1 abstract syntax")) == NULLOID) ! 2266: adios (NULLCP, "iso asn.1 abstract syntax: unknown"); ! 2267: pl -> pc_ctx[j].pc_asn = oid_cpy (oid); ! 2268: pl -> pc_ctx[j].pc_atn = NULLOID; ! 2269: } ! 2270: ! 2271: fprintf (stderr, "%s... ", addr); ! 2272: (void) fflush (stderr); ! 2273: if (RtOpenRequest (RTS_TWA, turn ? RTS_INITIATOR : RTS_RESPONDER, ! 2274: ode, NULLAEI, aei, NULLPA, pa, pl, ode, pe, ! 2275: NULLQOS, rtc, rti) == NOTOK) { ! 2276: fprintf (stderr, "failed\n"); ! 2277: rts_adios (rta, "RT-OPEN.REQUEST"); ! 2278: } ! 2279: } ! 2280: else { ! 2281: register struct SSAPaddr *sa; ! 2282: ! 2283: if (ros = strncmp (is -> is_entity, "ros_", strlen ("ros_")) == 0) { ! 2284: mode = strcmp (is -> is_entity, "ros_sink") ? echo : sink; ! 2285: turn = mode == sink; ! 2286: } ! 2287: ! 2288: rtz -> rta_port = is -> is_port; /* yikes! */ ! 2289: if ((is = getisoserventbyname ("rts", "ssap")) == NULL) ! 2290: adios (NULLCP, "ssap/rts: unknown entity"); ! 2291: if ((sa = is2saddr (addr, NULLCP, is)) == NULLSA) ! 2292: adios (NULLCP, "address translation failed"); ! 2293: rtz -> rta_addr = *sa; /* struct copy */ ! 2294: ! 2295: fprintf (stderr, "%s... ", addr); ! 2296: (void) fflush (stderr); ! 2297: if (RtBeginRequest (rtz, RTS_TWA, turn ? RTS_INITIATOR : RTS_RESPONDER, ! 2298: pe, rtc, rti) == NOTOK) { ! 2299: fprintf (stderr, "failed\n"); ! 2300: rts_adios (rta, "RT-BEGIN.REQUEST"); ! 2301: } ! 2302: } ! 2303: ! 2304: pe_free (pe); ! 2305: ! 2306: if (rtc -> rtc_result != RTS_ACCEPT) { ! 2307: fprintf (stderr, "failed\n"); ! 2308: adios (NULLCP, "association rejected: [%s]", ! 2309: RtErrString (rtc -> rtc_result)); ! 2310: } ! 2311: fprintf (stderr, "connected\n"); ! 2312: ! 2313: #ifdef DEBUG ! 2314: advise (NULLCP, "sent greetings of %d", i); ! 2315: #endif ! 2316: ! 2317: sd = rtc -> rtc_sd; ! 2318: if (rtc -> rtc_data) { ! 2319: if ((i = prim2num (rtc -> rtc_data)) == NOTOK ! 2320: && rtc -> rtc_data -> pe_errno != PE_ERR_NONE) ! 2321: adios (NULLCP, "error decoding hello: %s (%d)", ! 2322: pe_error (rtc -> rtc_data -> pe_errno), i); ! 2323: #ifdef DEBUG ! 2324: advise (NULLCP, "received greetings of %d", i); ! 2325: #endif ! 2326: } ! 2327: ! 2328: #ifdef DEBUG ! 2329: if (isacs) { ! 2330: advise (NULLCP, "context: %s", oid2ode (acc -> acc_context)); ! 2331: ! 2332: advise (NULLCP, ! 2333: "responding AE title: %s, responding PSAP address: %s", ! 2334: sprintaei (&acc -> acc_respondtitle), ! 2335: paddr2str (&pc -> pc_responding, NULLNA)); ! 2336: ! 2337: advise (NULLCP, "greetings: %d elements", acc -> acc_ninfo); ! 2338: ! 2339: pl = &pc -> pc_ctxlist; ! 2340: for (i = 0; i < pl -> pc_nctx; i++) ! 2341: advise (NULLCP, "ctx %d: 0x%x 0x%x %d", ! 2342: pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn, ! 2343: pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result); ! 2344: advise (NULLCP, "default %d", pc -> pc_defctxresult); ! 2345: advise (NULLCP, "p/s requirements 0x%x/0x%x", ! 2346: pc -> pc_prequirements, pc -> pc_srequirements); ! 2347: } ! 2348: #endif ! 2349: ! 2350: RTCFREE (rtc); ! 2351: ! 2352: if (ros) { ! 2353: struct RoSAPindication rois; ! 2354: register struct RoSAPpreject *rop = &rois.roi_preject; ! 2355: ! 2356: if (RoSetService (sd, RoRtService, &rois) == NOTOK) ! 2357: ros_adios (rop, "set RO/PT fails"); ! 2358: ! 2359: do_ros (sd); ! 2360: return; ! 2361: } ! 2362: ! 2363: if (fstat (fileno (stdin), &st) != NOTOK ! 2364: && (st.st_mode & S_IFMT) == S_IFREG ! 2365: && (cc = st.st_size) != 0) { ! 2366: (void) lseek (fileno (stdin), 0L, 0); ! 2367: ! 2368: if ((cp = malloc ((unsigned) cc)) == NULL) ! 2369: adios (NULLCP, "no memory"); ! 2370: for (dp = cp, j = cc; j > 0; dp += i, j -= i) ! 2371: switch (i = read (fileno (stdin), dp, j)) { ! 2372: case NOTOK: ! 2373: adios ("on stdin", "read failed"); ! 2374: ! 2375: case OK: ! 2376: adios (NULLCP, "premature end-of-file"); ! 2377: ! 2378: default: ! 2379: break; ! 2380: } ! 2381: if ((pe = oct2prim (cp, cc)) == NULLPE) ! 2382: adios (NULLCP, "unable to allocate APDU"); ! 2383: free (cp); ! 2384: for (i = 10; i > 0; i--) { ! 2385: #ifdef TIMER ! 2386: timer (0); ! 2387: #endif ! 2388: rts_transferequest (sd, pe); ! 2389: #ifdef TIMER ! 2390: timer (cc); ! 2391: #endif ! 2392: } ! 2393: pe_free (pe); ! 2394: } ! 2395: else ! 2396: while (fgets (buffer, sizeof buffer, stdin)) { ! 2397: if ((pe = oct2prim (buffer, strlen (buffer) + 1)) == NULLPE) ! 2398: adios (NULLCP, "unable to allocate APDU"); ! 2399: rts_transferequest (sd, pe); ! 2400: pe_free (pe); ! 2401: } ! 2402: ! 2403: if (isacs) { ! 2404: if ((pe = int2prim (i = getpid ())) == NULLPE) ! 2405: adios (NULLCP, "unable to allocate hello"); ! 2406: ! 2407: if (RtCloseRequest (sd, ACF_NORMAL, pe, acr, rti) == NOTOK) ! 2408: switch (rta -> rta_reason) { ! 2409: case RTS_OPERATION: ! 2410: case RTS_WAITING: ! 2411: rts_waitfor (sd); ! 2412: if (RtCloseRequest (sd, ACF_NORMAL, pe, acr, rti) ! 2413: == OK) ! 2414: break; /* else fall */ ! 2415: ! 2416: default: ! 2417: rts_adios (rta, "RT-CLOSE.REQUEST"); ! 2418: } ! 2419: ! 2420: if (!acr -> acr_affirmative) { ! 2421: (void) RtUAbortRequest (sd, NULLPE, rti); ! 2422: adios (NULLCP, "release rejected by peer: %d, %d elements", ! 2423: acr -> acr_reason, acr -> acr_ninfo); ! 2424: } ! 2425: ! 2426: if (mode == echo) { ! 2427: if (acr -> acr_ninfo != 1) ! 2428: advise (NULLCP, "got %d elements returned on close", ! 2429: acr -> acr_ninfo); ! 2430: if (pe_cmp (pe, acr -> acr_info[0])) { ! 2431: advise (NULLCP, "data mismatch"); ! 2432: status++; ! 2433: } ! 2434: } ! 2435: ! 2436: ACRFREE (acr); ! 2437: ! 2438: pe_free (pe); ! 2439: } ! 2440: else ! 2441: if (RtEndRequest (sd, rti) == NOTOK) ! 2442: switch (rta -> rta_reason) { ! 2443: case RTS_OPERATION: ! 2444: case RTS_WAITING: ! 2445: rts_waitfor (sd); ! 2446: if (RtEndRequest (sd, rti) == OK) ! 2447: break; /* else fall */ ! 2448: ! 2449: default: ! 2450: rts_adios (rta, "RT-END.REQUEST"); ! 2451: } ! 2452: } ! 2453: ! 2454: /* */ ! 2455: ! 2456: static int rts_transferequest (sd, pe) ! 2457: int sd; ! 2458: register PE pe; ! 2459: { ! 2460: int result; ! 2461: struct RtSAPindication rtis; ! 2462: register struct RtSAPindication *rti = &rtis; ! 2463: register struct RtSAPabort *rta = &rti -> rti_abort; ! 2464: register struct RtSAPtransfer *rtt = &rti -> rti_transfer; ! 2465: ! 2466: if (RtTransferRequest (sd, pe, NOTOK, rti) == NOTOK) ! 2467: switch (rta -> rta_reason) { ! 2468: case RTS_OPERATION: ! 2469: rts_waitfor (sd); ! 2470: if (RtTransferRequest (sd, pe, NOTOK, rti) == OK) ! 2471: break; /* else fall */ ! 2472: ! 2473: default: ! 2474: if (RTS_FATAL (rta -> rta_reason)) ! 2475: rts_adios (rta, "RT-TRANSFER.REQUEST"); ! 2476: rts_advise (rta, "RT-TRANSFER.REQUEST"); ! 2477: return; ! 2478: } ! 2479: ! 2480: if (mode == echo) ! 2481: for (;;) ! 2482: switch (result = RtWaitRequest (sd, NOTOK, rti)) { ! 2483: case NOTOK: ! 2484: rts_adios (rta, "RT-WAIT.REQUEST"); ! 2485: ! 2486: case OK: ! 2487: if (pe_cmp (pe, rtt -> rtt_data)) { ! 2488: advise (NULLCP, "data mismatch"); ! 2489: status++; ! 2490: } ! 2491: RTTFREE (rtt); ! 2492: return; ! 2493: ! 2494: case DONE: ! 2495: rts_event (sd, rti); ! 2496: break; ! 2497: ! 2498: default: ! 2499: adios (NULLCP, "unknown return from RtWaitRequest=%d", ! 2500: result); ! 2501: } ! 2502: } ! 2503: ! 2504: /* */ ! 2505: ! 2506: static int rts_waitfor (sd) ! 2507: int sd; ! 2508: { ! 2509: int result; ! 2510: struct RtSAPindication rtis; ! 2511: register struct RtSAPindication *rti = &rtis; ! 2512: register struct RtSAPabort *rta = &rti -> rti_abort; ! 2513: static int priority = 1; ! 2514: ! 2515: if (turn) ! 2516: return; ! 2517: ! 2518: if (RtPTurnRequest (sd, priority++, rti) == NOTOK) ! 2519: rts_adios (rta, "RT-TURN-PLEASE.REQUEST"); ! 2520: ! 2521: while (!turn) ! 2522: switch (result = RtWaitRequest (sd, NOTOK, rti)) { ! 2523: case NOTOK: ! 2524: rts_adios (rta, "RT-WAIT.REQUEST"); ! 2525: ! 2526: case OK: ! 2527: adios (NULLCP, "protocol screw-up"); ! 2528: ! 2529: case DONE: ! 2530: rts_event (sd, rti); ! 2531: break; ! 2532: ! 2533: default: ! 2534: adios (NULLCP, "unknown return from RtWaitRequest=%d", ! 2535: result); ! 2536: } ! 2537: } ! 2538: ! 2539: /* */ ! 2540: ! 2541: static int rts_event (sd, rti) ! 2542: int sd; ! 2543: register struct RtSAPindication *rti; ! 2544: { ! 2545: register struct RtSAPabort *rta = &rti -> rti_abort; ! 2546: register struct RtSAPturn *rtu = &rti -> rti_turn; ! 2547: ! 2548: switch (rti -> rti_type) { ! 2549: case RTI_TURN: ! 2550: if (rtu -> rtu_please) { ! 2551: if (RtGTurnRequest (sd, rti) == NOTOK) ! 2552: rts_adios (rta, "RT-TURN-GIVE.REQUEST"); ! 2553: turn = 0; ! 2554: } ! 2555: else ! 2556: turn = 1; ! 2557: break; ! 2558: ! 2559: case RTI_CLOSE: ! 2560: adios (NULLCP, "got RT-END.INDICATION"); ! 2561: ! 2562: case RTI_FINISH: ! 2563: adios (NULLCP, "got RT-CLOSE.INDICATION"); ! 2564: ! 2565: default: ! 2566: adios (NULLCP, "unknown indication type=0x%x", ! 2567: rti -> rti_type); ! 2568: } ! 2569: } ! 2570: ! 2571: /* */ ! 2572: ! 2573: static void rts_adios (rta, event) ! 2574: register struct RtSAPabort *rta; ! 2575: char *event; ! 2576: { ! 2577: rts_advise (rta, event); ! 2578: ! 2579: _exit (1); ! 2580: } ! 2581: ! 2582: ! 2583: static void rts_advise (rta, event) ! 2584: register struct RtSAPabort *rta; ! 2585: char *event; ! 2586: { ! 2587: char buffer[BUFSIZ]; ! 2588: ! 2589: if (rta -> rta_cc > 0) ! 2590: (void) sprintf (buffer, "[%s] %*.*s", RtErrString (rta -> rta_reason), ! 2591: rta -> rta_cc, rta -> rta_cc, rta -> rta_data); ! 2592: else ! 2593: (void) sprintf (buffer, "[%s]", RtErrString (rta -> rta_reason)); ! 2594: ! 2595: advise (NULLCP, "%s: %s", event, buffer); ! 2596: } ! 2597: ! 2598: /* RoSAP */ ! 2599: ! 2600: static int ros_main (is, addr) ! 2601: struct isoservent *is; ! 2602: char *addr; ! 2603: { ! 2604: int sd, ! 2605: i; ! 2606: char *cp; ! 2607: struct SSAPref sfs; ! 2608: register struct SSAPref *sf; ! 2609: register struct PSAPaddr *pa; ! 2610: struct AcSAPconnect accs; ! 2611: register struct AcSAPconnect *acc = &accs; ! 2612: struct AcSAPindication acis; ! 2613: register struct AcSAPindication *aci = &acis; ! 2614: register struct AcSAPabort *aca = &aci -> aci_abort; ! 2615: struct RoSAPaddr roas; ! 2616: register struct RoSAPaddr *roa = &roas; ! 2617: struct RoSAPconnect rocs; ! 2618: register struct RoSAPconnect *roc = &rocs; ! 2619: struct RoSAPindication rois; ! 2620: register struct RoSAPindication *roi = &rois; ! 2621: register struct RoSAPpreject *rop = &roi -> roi_preject; ! 2622: #ifdef DEBUG ! 2623: struct PSAPconnect *pc = &acc -> acc_connect; ! 2624: #endif ! 2625: struct PSAPctxlist pls; ! 2626: register struct PSAPctxlist *pl = &pls; ! 2627: AEI aei; ! 2628: OID oid, ! 2629: ode; ! 2630: register PE pe; ! 2631: ! 2632: if (isacs) { ! 2633: if ((aei = str2aei (addr, isacs)) == NULLAEI) ! 2634: adios (NULLCP, "%s-%s: unknown application-entity", addr, isacs); ! 2635: if ((pa = aei2addr (aei)) == NULLPA) ! 2636: adios (NULLCP, "address translation failed"); ! 2637: ! 2638: cp = mode == echo ? "isode echo pci" : "isode sink pci"; ! 2639: if ((ode = ode2oid (cp)) == NULLOID) ! 2640: adios (NULLCP, "%s: unknown object descriptor", cp); ! 2641: ode = oid_cpy (ode); ! 2642: ! 2643: if ((sf = addr2ref (PLocalHostName ())) == NULL) { ! 2644: sf = &sfs; ! 2645: (void) bzero ((char *) sf, sizeof *sf); ! 2646: } ! 2647: pl -> pc_nctx = 1; ! 2648: pl -> pc_ctx[0].pc_id = 1; ! 2649: if ((oid = ode2oid ("iso asn.1 abstract syntax")) == NULLOID) ! 2650: adios (NULLCP, "iso asn.1 abstract syntax: unknown"); ! 2651: pl -> pc_ctx[0].pc_asn = oid_cpy (oid); ! 2652: pl -> pc_ctx[0].pc_atn = NULLOID; ! 2653: ! 2654: fprintf (stderr, "%s... ", addr); ! 2655: (void) fflush (stderr); ! 2656: if (AcAssocRequest (ode, NULLAEI, aei, NULLPA, pa, pl, ode, ! 2657: 0, ROS_MYREQUIRE, SERIAL_NONE, 0, sf, NULLPEP, 0, NULLQOS, ! 2658: acc, aci) ! 2659: == NOTOK) ! 2660: acs_adios (aca, "A-ASSOCIATE.REQUEST"); ! 2661: ! 2662: if (acc -> acc_result != ACS_ACCEPT) { ! 2663: fprintf (stderr, "failed\n"); ! 2664: adios (NULLCP, "association rejected: [%s]", ! 2665: AcErrString (acc -> acc_result)); ! 2666: } ! 2667: fprintf (stderr, "connected\n"); ! 2668: ! 2669: sd = acc -> acc_sd; ! 2670: ! 2671: #ifdef DEBUG ! 2672: pa = &pc -> pc_responding; ! 2673: { ! 2674: advise (NULLCP, "context: %s", oid2ode (acc -> acc_context)); ! 2675: ! 2676: advise (NULLCP, ! 2677: "responding AE title: %s, responding PSAP address: %s", ! 2678: sprintaei (&acc -> acc_respondtitle), ! 2679: paddr2str (&pc -> pc_responding, NULLNA)); ! 2680: ! 2681: advise (NULLCP, "greetings: %d elements", acc -> acc_ninfo); ! 2682: ! 2683: pl = &pc -> pc_ctxlist; ! 2684: for (i = 0; i < pl -> pc_nctx; i++) ! 2685: advise (NULLCP, "ctx %d: 0x%x 0x%x %d", ! 2686: pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn, ! 2687: pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result); ! 2688: advise (NULLCP, "default %d", pc -> pc_defctxresult); ! 2689: advise (NULLCP, "p/s requirements 0x%x/0x%x", ! 2690: pc -> pc_prequirements, pc -> pc_srequirements); ! 2691: } ! 2692: #endif ! 2693: ! 2694: ACCFREE (acc); ! 2695: ! 2696: if (RoSetService (sd, RoPService, roi) == NOTOK) ! 2697: ros_adios (rop, "set RO/PT fails"); ! 2698: } ! 2699: else { ! 2700: register struct SSAPaddr *sa; ! 2701: ! 2702: roa -> roa_port = is -> is_port; /* yikes! */ ! 2703: if ((is = getisoserventbyname ("ros", "ssap")) == NULL) ! 2704: adios (NULLCP, "ssap/ros: unknown entity"); ! 2705: if ((sa = is2saddr (addr, NULLCP, is)) == NULLSA) ! 2706: adios (NULLCP, "address translation failed"); ! 2707: roa -> roa_addr = *sa; /* struct copy */ ! 2708: ! 2709: if ((pe = int2prim (i = getpid ())) == NULLPE) ! 2710: adios (NULLCP, "unable to allocate hello"); ! 2711: ! 2712: fprintf (stderr, "%s... ", addr); ! 2713: (void) fflush (stderr); ! 2714: if (RoBeginRequest (roa, pe, roc, roi) == NOTOK) { ! 2715: fprintf (stderr, "failed\n"); ! 2716: ros_adios (rop, "RO-BEGIN.REQUEST"); ! 2717: } ! 2718: ! 2719: pe_free (pe); ! 2720: ! 2721: if (roc -> roc_result != ROS_ACCEPT) { ! 2722: fprintf (stderr, "failed\n"); ! 2723: adios (NULLCP, "association rejected: [%s]", ! 2724: RoErrString (roc -> roc_result)); ! 2725: } ! 2726: fprintf (stderr, "connected\n"); ! 2727: ! 2728: #ifdef DEBUG ! 2729: advise (NULLCP, "sent greetings of %d", i); ! 2730: #endif ! 2731: ! 2732: sd = roc -> roc_sd; ! 2733: if (roc -> roc_data) { ! 2734: if ((i = prim2num (roc -> roc_data)) == NOTOK ! 2735: && roc -> roc_data -> pe_errno != PE_ERR_NONE) ! 2736: adios (NULLCP, "error decoding hello: %s (%d)", ! 2737: pe_error (roc -> roc_data -> pe_errno), i); ! 2738: #ifdef DEBUG ! 2739: advise (NULLCP, "received greetings of %d", i); ! 2740: #endif ! 2741: } ! 2742: ROCFREE (roc); ! 2743: } ! 2744: ! 2745: do_ros (sd); ! 2746: } ! 2747: ! 2748: /* */ ! 2749: ! 2750: static int do_ros (sd) ! 2751: int sd; ! 2752: { ! 2753: int cc, ! 2754: i, ! 2755: j; ! 2756: char *cp, ! 2757: *dp, ! 2758: buffer[BUFSIZ]; ! 2759: struct RoSAPindication rois; ! 2760: register struct RoSAPindication *roi = &rois; ! 2761: register struct RoSAPpreject *rop = &roi -> roi_preject; ! 2762: struct AcSAPrelease acrs; ! 2763: register struct AcSAPrelease *acr = &acrs; ! 2764: register PE pe; ! 2765: struct stat st; ! 2766: ! 2767: if (fstat (fileno (stdin), &st) != NOTOK ! 2768: && (st.st_mode & S_IFMT) == S_IFREG ! 2769: && (cc = st.st_size) != 0) { ! 2770: (void) lseek (fileno (stdin), 0L, 0); ! 2771: ! 2772: if ((cp = malloc ((unsigned) cc)) == NULL) ! 2773: adios (NULLCP, "no memory"); ! 2774: for (dp = cp, j = cc; j > 0; dp += i, j -= i) ! 2775: switch (i = read (fileno (stdin), dp, j)) { ! 2776: case NOTOK: ! 2777: adios ("on stdin", "read failed"); ! 2778: ! 2779: case OK: ! 2780: adios (NULLCP, "premature end-of-file"); ! 2781: ! 2782: default: ! 2783: break; ! 2784: } ! 2785: if ((pe = oct2prim (cp, cc)) == NULLPE) ! 2786: adios (NULLCP, "unable to allocate invocation argument"); ! 2787: free (cp); ! 2788: for (i = 10; i > 0; i--) { ! 2789: #ifdef TIMER ! 2790: timer (0); ! 2791: #endif ! 2792: ros_invokerequest (sd, pe); ! 2793: #ifdef TIMER ! 2794: timer (cc); ! 2795: #endif ! 2796: } ! 2797: pe_free (pe); ! 2798: } ! 2799: else ! 2800: while (fgets (buffer, sizeof buffer, stdin)) { ! 2801: if ((pe = oct2prim (buffer, strlen (buffer) + 1)) == NULLPE) ! 2802: adios (NULLCP, "unable to allocate invocation argument"); ! 2803: ros_invokerequest (sd, pe); ! 2804: pe_free (pe); ! 2805: } ! 2806: ! 2807: if (isrts) { ! 2808: struct RtSAPindication rtis; ! 2809: register struct RtSAPindication *rti = &rtis; ! 2810: register struct RtSAPabort *rta = &rti -> rti_abort; ! 2811: ! 2812: if (isacs) { ! 2813: if (RtCloseRequest (sd, ACF_NORMAL, NULLPE, acr, rti) == NOTOK) ! 2814: switch (rta -> rta_reason) { ! 2815: case RTS_OPERATION: ! 2816: case RTS_WAITING: ! 2817: rts_waitfor (sd); ! 2818: if (RtCloseRequest (sd, ACF_NORMAL, NULLPE, acr, rti) ! 2819: == OK) ! 2820: break; /* else fall */ ! 2821: ! 2822: default: ! 2823: rts_adios (rta, "RT-CLOSE.REQUEST"); ! 2824: } ! 2825: ! 2826: if (!acr -> acr_affirmative) { ! 2827: (void) RtUAbortRequest (sd, NULLPE, rti); ! 2828: adios (NULLCP, "release rejected by peer: %d, %d elements", ! 2829: acr -> acr_reason, acr -> acr_ninfo); ! 2830: } ! 2831: } ! 2832: else ! 2833: if (RtEndRequest (sd, rti) == NOTOK) ! 2834: switch (rta -> rta_reason) { ! 2835: case RTS_OPERATION: ! 2836: case RTS_WAITING: ! 2837: rts_waitfor (sd); ! 2838: if (RtEndRequest (sd, rti) == OK) ! 2839: break; /* else fall */ ! 2840: ! 2841: default: ! 2842: rts_adios (rta, "RT-END.REQUEST"); ! 2843: } ! 2844: } ! 2845: else ! 2846: if (isacs) { ! 2847: struct AcSAPindication acis; ! 2848: register struct AcSAPindication *aci = &acis; ! 2849: register struct AcSAPabort *aca = &aci -> aci_abort; ! 2850: ! 2851: if (AcRelRequest (sd, ACF_NORMAL, NULLPEP, 0, NOTOK, acr, aci) ! 2852: == NOTOK) ! 2853: acs_adios (aca, "A-RELEASE.REQUEST"); ! 2854: ! 2855: if (!acr -> acr_affirmative) { ! 2856: (void) AcUAbortRequest (sd, NULLPEP, 0, aci); ! 2857: adios (NULLCP, "release rejected by peer: %d, %d elements", ! 2858: acr -> acr_reason, acr -> acr_ninfo); ! 2859: } ! 2860: ACRFREE (acr); ! 2861: } ! 2862: else ! 2863: if (RoEndRequest (sd, ROS_NOPRIO, roi) == NOTOK) ! 2864: ros_adios (rop, "RO-END.REQUEST"); ! 2865: } ! 2866: ! 2867: /* */ ! 2868: ! 2869: static int ros_invokerequest (sd, pe) ! 2870: int sd; ! 2871: PE pe; ! 2872: { ! 2873: int result; ! 2874: struct RoSAPindication rois; ! 2875: register struct RoSAPindication *roi = &rois; ! 2876: register struct RoSAPpreject *rop = &roi -> roi_preject; ! 2877: static int id = 0; ! 2878: static int op = 0; ! 2879: ! 2880: switch (result = RoInvokeRequest (sd, op++, ROS_SYNC, pe, ++id, NULLIP, ! 2881: ROS_NOPRIO, roi)) { ! 2882: case NOTOK: ! 2883: if (ROS_FATAL (rop -> rop_reason)) ! 2884: ros_adios (rop, "RO-INVOKE.REQUEST"); ! 2885: ros_advise (rop, "RO-INVOKE.REQUEST"); ! 2886: break; ! 2887: ! 2888: case OK: ! 2889: switch (roi -> roi_type) { ! 2890: case ROI_INVOKE: ! 2891: adios (NULLCP, "got RO-INVOKE.INDICATION"); ! 2892: ! 2893: case ROI_RESULT: ! 2894: { ! 2895: register struct RoSAPresult *ror = &roi -> roi_result; ! 2896: ! 2897: if (ror -> ror_id != id) { ! 2898: advise (NULLCP, "id mismatch (wanted %d, got %d)", ! 2899: id, ror -> ror_id); ! 2900: status++; ! 2901: if (RoURejectRequest (sd, &ror -> ror_id, ! 2902: ROS_RRP_UNRECOG, ROS_NOPRIO, roi) == NOTOK) ! 2903: ros_adios (rop, "RO-REJECT-U.REQUEST"); ! 2904: } ! 2905: else ! 2906: if (mode == echo ! 2907: && pe_cmp (pe, ror -> ror_result)) { ! 2908: advise (NULLCP, "data mismatch"); ! 2909: status++; ! 2910: } ! 2911: ! 2912: RORFREE (ror); ! 2913: } ! 2914: break; ! 2915: ! 2916: case ROI_ERROR: ! 2917: { ! 2918: register struct RoSAPerror *roe = &roi -> roi_error; ! 2919: ! 2920: if (roe -> roe_id != id) { ! 2921: advise (NULLCP, "id mismatch (wanted %d, got %d)", ! 2922: id, roe -> roe_id); ! 2923: status++; ! 2924: if (RoURejectRequest (sd, &roe -> roe_id, ! 2925: ROS_REP_UNRECOG, ROS_NOPRIO, roi) == NOTOK) ! 2926: ros_adios (rop, "RO-REJECT-U.REQUEST"); ! 2927: } ! 2928: else ! 2929: if (mode == echo ! 2930: && pe_cmp (pe, roe -> roe_param)) { ! 2931: advise (NULLCP, "data mismatch"); ! 2932: status++; ! 2933: } ! 2934: ! 2935: ROEFREE (roe); ! 2936: } ! 2937: break; ! 2938: ! 2939: case ROI_UREJECT: ! 2940: { ! 2941: register struct RoSAPureject *rou = &roi -> roi_ureject; ! 2942: ! 2943: if (rou -> rou_noid) ! 2944: advise (NULLCP, "RO-REJECT-U.INDICATION: %s", ! 2945: RoErrString (rou -> rou_reason)); ! 2946: else ! 2947: advise (NULLCP, "RO-REJECT-U.INDICATION: %s (id=%d)", ! 2948: RoErrString (rou -> rou_reason), ! 2949: rou -> rou_id); ! 2950: if (!rou -> rou_noid && rou -> rou_id != id) { ! 2951: advise (NULLCP, "id mismatch (wanted %d, got %d)", ! 2952: id, rou -> rou_id); ! 2953: status++; ! 2954: } ! 2955: } ! 2956: break; ! 2957: ! 2958: default: ! 2959: adios (NULLCP, "unknown indication type=%d", ! 2960: roi -> roi_type); ! 2961: } ! 2962: if (isrts) ! 2963: turn = 0; ! 2964: break; ! 2965: ! 2966: case DONE: ! 2967: adios (NULLCP, "got RO-END.INDICATION"); ! 2968: ! 2969: default: ! 2970: adios (NULLCP, "unknown return from RoInvokeRequest=%d", result); ! 2971: } ! 2972: } ! 2973: ! 2974: ! 2975: /* */ ! 2976: ! 2977: static void ros_adios (rop, event) ! 2978: register struct RoSAPpreject *rop; ! 2979: char *event; ! 2980: { ! 2981: ros_advise (rop, event); ! 2982: ! 2983: _exit (1); ! 2984: } ! 2985: ! 2986: ! 2987: static void ros_advise (rop, event) ! 2988: register struct RoSAPpreject *rop; ! 2989: char *event; ! 2990: { ! 2991: char buffer[BUFSIZ]; ! 2992: ! 2993: if (rop -> rop_cc > 0) ! 2994: (void) sprintf (buffer, "[%s] %*.*s", RoErrString (rop -> rop_reason), ! 2995: rop -> rop_cc, rop -> rop_cc, rop -> rop_data); ! 2996: else ! 2997: (void) sprintf (buffer, "[%s]", RoErrString (rop -> rop_reason)); ! 2998: ! 2999: advise (NULLCP, "%s: %s", event, buffer); ! 3000: } ! 3001: ! 3002: /* TIMER */ ! 3003: ! 3004: #ifdef TIMER ! 3005: ! 3006: #ifndef NBBY ! 3007: #define NBBY 8 ! 3008: #endif ! 3009: ! 3010: ! 3011: #ifndef TMS ! 3012: static timer (cc) ! 3013: int cc; ! 3014: { ! 3015: int bytes; ! 3016: long ms; ! 3017: float bs; ! 3018: struct timeval stop, ! 3019: td; ! 3020: static struct timeval start; ! 3021: ! 3022: if (cc == 0) { ! 3023: (void) gettimeofday (&start, (struct timezone *) 0); ! 3024: return; ! 3025: } ! 3026: else ! 3027: (void) gettimeofday (&stop, (struct timezone *) 0); ! 3028: ! 3029: tvsub (&td, &stop, &start); ! 3030: ms = (td.tv_sec * 1000) + (td.tv_usec / 1000); ! 3031: bytes = mode == echo ? cc * 2 : cc; ! 3032: bs = (((float) bytes * NBBY * 1000) / (float) (ms ? ms : 1)) / NBBY; ! 3033: ! 3034: advise (NULLCP, "%d bytes %s in %d.%02d seconds (%.2f Kbytes/s)", ! 3035: cc, mode == echo ? "echoed" : "sunk", ! 3036: td.tv_sec, td.tv_usec / 10000, bs / 1024); ! 3037: } ! 3038: ! 3039: ! 3040: static tvsub (tdiff, t1, t0) ! 3041: register struct timeval *tdiff, ! 3042: *t1, ! 3043: *t0; ! 3044: { ! 3045: ! 3046: tdiff -> tv_sec = t1 -> tv_sec - t0 -> tv_sec; ! 3047: tdiff -> tv_usec = t1 -> tv_usec - t0 -> tv_usec; ! 3048: if (tdiff -> tv_usec < 0) ! 3049: tdiff -> tv_sec--, tdiff -> tv_usec += 1000000; ! 3050: } ! 3051: #else ! 3052: long times (); ! 3053: ! 3054: ! 3055: static timer (cc) ! 3056: int cc; ! 3057: { ! 3058: int bytes; ! 3059: long ms; ! 3060: float bs; ! 3061: long stop, ! 3062: td, ! 3063: secs, ! 3064: msecs; ! 3065: struct tms tm; ! 3066: static long start; ! 3067: ! 3068: if (cc == 0) { ! 3069: start = times (&tm); ! 3070: return; ! 3071: } ! 3072: else ! 3073: stop = times (&tm); ! 3074: ! 3075: td = stop - start; ! 3076: secs = td / 60, msecs = (td % 60) * 1000 / 60; ! 3077: ms = (secs * 1000) + msecs; ! 3078: bytes = mode == echo ? cc * 2 : cc; ! 3079: bs = (((float) bytes * NBBY * 1000) / (float) (ms ? ms : 1)) / NBBY; ! 3080: ! 3081: advise (NULLCP, "%d bytes %s in %d.%02d seconds (%.2f KBytes/s)", ! 3082: cc, mode == echo ? "echoed" : "sunk", ! 3083: secs, msecs / 10, bs / 1024); ! 3084: } ! 3085: #endif ! 3086: #endif ! 3087: ! 3088: /* QBUF */ ! 3089: ! 3090: static int qcmp (b, qb, l) ! 3091: register char *b; ! 3092: register struct qbuf *qb; ! 3093: register int l; ! 3094: { ! 3095: register struct qbuf *qp; ! 3096: ! 3097: for (qp = qb -> qb_forw; qp != qb; qp = qp -> qb_forw) { ! 3098: if ((l -= qp -> qb_len) < 0) { ! 3099: advise (NULLCP, "length mismatch(1)"); ! 3100: return NOTOK; ! 3101: } ! 3102: ! 3103: if (bcmp (b, qp -> qb_data, qp -> qb_len)) { ! 3104: advise (NULLCP, "data mismatch"); ! 3105: return NOTOK; ! 3106: } ! 3107: ! 3108: b += qp -> qb_len; ! 3109: } ! 3110: ! 3111: if (l != 0) { ! 3112: advise (NULLCP, "length mismatch(2)"); ! 3113: return NOTOK; ! 3114: } ! 3115: ! 3116: return OK; ! 3117: } ! 3118: ! 3119: /* ERRORS */ ! 3120: ! 3121: #ifndef lint ! 3122: void _advise (); ! 3123: ! 3124: ! 3125: void adios (va_alist) ! 3126: va_dcl ! 3127: { ! 3128: va_list ap; ! 3129: ! 3130: va_start (ap); ! 3131: ! 3132: _advise (ap); ! 3133: ! 3134: va_end (ap); ! 3135: ! 3136: _exit (1); ! 3137: } ! 3138: #else ! 3139: /* VARARGS */ ! 3140: ! 3141: void adios (what, fmt) ! 3142: char *what, ! 3143: *fmt; ! 3144: { ! 3145: adios (what, fmt); ! 3146: } ! 3147: #endif ! 3148: ! 3149: ! 3150: #ifndef lint ! 3151: void advise (va_alist) ! 3152: va_dcl ! 3153: { ! 3154: va_list ap; ! 3155: ! 3156: va_start (ap); ! 3157: ! 3158: _advise (ap); ! 3159: ! 3160: va_end (ap); ! 3161: } ! 3162: ! 3163: ! 3164: static void _advise (ap) ! 3165: va_list ap; ! 3166: { ! 3167: char buffer[BUFSIZ]; ! 3168: ! 3169: asprintf (buffer, ap); ! 3170: ! 3171: (void) fflush (stdout); ! 3172: ! 3173: fprintf (stderr, "%s: ", myname); ! 3174: (void) fputs (buffer, stderr); ! 3175: (void) fputc ('\n', stderr); ! 3176: ! 3177: (void) fflush (stderr); ! 3178: } ! 3179: #else ! 3180: /* VARARGS */ ! 3181: ! 3182: void advise (what, fmt) ! 3183: char *what, ! 3184: *fmt; ! 3185: { ! 3186: advise (what, fmt); ! 3187: } ! 3188: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.