|
|
1.1 ! root 1: /* ssapinitiate.c - SPM: initiator */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapinitiate.c,v 7.2 90/01/27 10:27:27 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/ssap/RCS/ssapinitiate.c,v 7.2 90/01/27 10:27:27 mrose Exp $ ! 9: * ! 10: * ! 11: * $Log: ssapinitiate.c,v $ ! 12: * Revision 7.2 90/01/27 10:27:27 mrose ! 13: * touch-up ! 14: * ! 15: * Revision 7.1 89/11/27 10:30:40 mrose ! 16: * sync ! 17: * ! 18: * Revision 7.0 89/11/23 22:25:27 mrose ! 19: * Release 6.0 ! 20: * ! 21: */ ! 22: ! 23: /* ! 24: * NOTICE ! 25: * ! 26: * Acquisition, use, and distribution of this module and related ! 27: * materials are subject to the restrictions of a license agreement. ! 28: * Consult the Preface in the User's Manual for the full terms of ! 29: * this agreement. ! 30: * ! 31: */ ! 32: ! 33: ! 34: /* LINTLIBRARY */ ! 35: ! 36: #include <stdio.h> ! 37: #include <signal.h> ! 38: #include "spkt.h" ! 39: #include "tailor.h" ! 40: ! 41: /* S-(ASYN-)CONNECT.REQUEST */ ! 42: ! 43: #define dotoken(requires,shift,bit,type) \ ! 44: { \ ! 45: if (requirements & requires) \ ! 46: switch (settings & (ST_MASK << shift)) { \ ! 47: case ST_INIT_VALUE << shift: \ ! 48: case ST_RESP_VALUE << shift: \ ! 49: case ST_CALL_VALUE << shift: \ ! 50: break; \ ! 51: \ ! 52: default: \ ! 53: return ssaplose (si, SC_PARAMETER, NULLCP, \ ! 54: "improper choice of %s token setting", type); \ ! 55: } \ ! 56: } ! 57: ! 58: /* */ ! 59: ! 60: int SAsynConnRequest (ref, calling, called, requirements, settings, isn, ! 61: data, cc, qos, sc, si, async) ! 62: struct SSAPref *ref; ! 63: struct SSAPaddr *calling, ! 64: *called; ! 65: int requirements, ! 66: settings, ! 67: cc, ! 68: async; ! 69: long isn; ! 70: char *data; ! 71: struct QOStype *qos; ! 72: struct SSAPconnect *sc; ! 73: struct SSAPindication *si; ! 74: { ! 75: SBV smask; ! 76: int result; ! 77: ! 78: isodetailor (NULLCP, 0); ! 79: ! 80: missingP (ref); ! 81: refmuchP (ref); ! 82: if (ref -> sr_vlen) ! 83: return ssaplose (si, SC_PARAMETER, NULLCP, "bad format for reference"); ! 84: #ifdef notdef ! 85: missingP (calling); ! 86: #endif ! 87: missingP (called); ! 88: ! 89: if (requirements & ~SR_MYREQUIRE) ! 90: return ssaplose (si, SC_PARAMETER, NULLCP, ! 91: "requirements settings not supported"); ! 92: if ((requirements & SR_EXCEPTIONS) ! 93: && !(requirements & SR_HALFDUPLEX)) ! 94: return ssaplose (si, SC_PARAMETER, NULLCP, ! 95: "exception service requires half-duplex service"); ! 96: ! 97: dotokens (); ! 98: ! 99: if (requirements & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC)) { ! 100: if (!(requirements & SR_ACTIVITY) || isn != SERIAL_NONE) ! 101: if (SERIAL_MIN > isn || isn > SERIAL_MAX + 1) ! 102: return ssaplose (si, SC_PARAMETER, NULLCP, ! 103: "bad choice for initial serial number"); ! 104: } ! 105: else ! 106: if (isn != SERIAL_NONE) ! 107: return ssaplose (si, SC_PARAMETER, NULLCP, ! 108: "initial serial number invalid given requirements"); ! 109: ! 110: if (data == NULL) ! 111: cc = 0; ! 112: else ! 113: if (cc > CONNECT_MAX) ! 114: return ssaplose (si, SC_PARAMETER, NULLCP, ! 115: "too much initial user data, %d octets", cc); ! 116: ! 117: #ifdef notdef ! 118: missingP (qos); ! 119: #endif ! 120: missingP (sc); ! 121: missingP (si); ! 122: ! 123: smask = sigioblock (); ! 124: ! 125: result = SConnRequestAux (ref, calling, called, requirements, settings, ! 126: isn, data, cc, qos, sc, si, async); ! 127: ! 128: (void) sigiomask (smask); ! 129: ! 130: return result; ! 131: } ! 132: ! 133: #undef dotoken ! 134: ! 135: /* */ ! 136: ! 137: static int SConnRequestAux (ref, calling, called, requirements, settings, isn, ! 138: data, cc, qos, sc, si, async) ! 139: struct SSAPref *ref; ! 140: struct SSAPaddr *calling, ! 141: *called; ! 142: int requirements, ! 143: settings, ! 144: cc, ! 145: async; ! 146: long isn; ! 147: char *data; ! 148: struct QOStype *qos; ! 149: struct SSAPconnect *sc; ! 150: struct SSAPindication *si; ! 151: { ! 152: int result; ! 153: register struct ssapkt *s; ! 154: register struct ssapblk *sb; ! 155: struct TSAPconnect tcs; ! 156: register struct TSAPconnect *tc = &tcs; ! 157: struct TSAPdisconnect tds; ! 158: register struct TSAPdisconnect *td = &tds; ! 159: ! 160: if ((sb = newsblk ()) == NULL) ! 161: return ssaplose (si, SC_CONGEST, NULLCP, "out of memory"); ! 162: if (!async || qos == NULLQOS || qos -> qos_maxtime <= 0) ! 163: sb -> sb_maxtime = NOTOK; ! 164: else ! 165: sb -> sb_maxtime = qos -> qos_maxtime; ! 166: ! 167: if ((s = newspkt (SPDU_CN)) == NULL) { ! 168: (void) ssaplose (si, SC_CONGEST, NULLCP, "out of memory"); ! 169: goto out1; ! 170: } ! 171: ! 172: #ifdef notdef ! 173: if (called -> sa_selectlen > 0) { ! 174: if (calling == NULLSA) { ! 175: static struct SSAPaddr sas; ! 176: ! 177: calling = &sas; ! 178: bzero ((char *) calling, sizeof *calling); ! 179: } ! 180: ! 181: if (calling -> sa_selectlen == 0) { ! 182: calling -> sa_port = ! 183: htons ((u_short) (0x8000 | (getpid () & 0x7fff))); ! 184: calling -> sa_selectlen = sizeof calling -> sa_port; ! 185: } ! 186: } ! 187: #endif ! 188: ! 189: if (calling) { ! 190: if (calling -> sa_selectlen > 0) { ! 191: s -> s_mask |= SMASK_CN_CALLING; ! 192: bcopy (calling -> sa_selector, s -> s_calling, ! 193: s -> s_callinglen = calling -> sa_selectlen); ! 194: } ! 195: sb -> sb_initiating = *calling; /* struct copy */ ! 196: } ! 197: ! 198: if (called -> sa_selectlen > 0) { ! 199: s -> s_mask |= SMASK_CN_CALLED; ! 200: bcopy (called -> sa_selector, s -> s_called, ! 201: s -> s_calledlen = called -> sa_selectlen); ! 202: } ! 203: sb -> sb_responding = *called; /* struct copy */ ! 204: ! 205: sb -> sb_requirements = requirements; ! 206: sb -> sb_settings = settings; ! 207: ! 208: if ((result = TAsynConnRequest (calling ? &calling -> sa_addr : NULLTA, ! 209: &called -> sa_addr, ! 210: (qos ? qos -> qos_extended : 0) ! 211: || ((requirements & SR_EXPEDITED) ? 1 : 0), ! 212: NULLCP, 0, qos, tc, td, async)) == NOTOK) { ! 213: (void) ts2sslose (si, "TAsynConnRequest", td); ! 214: ! 215: bzero ((char *) sc, sizeof *sc); ! 216: sc -> sc_sd = NOTOK; ! 217: sc -> sc_result = si -> si_abort.sa_reason; ! 218: ! 219: result = DONE; ! 220: goto out2; ! 221: } ! 222: ! 223: sb -> sb_fd = tc -> tc_sd; ! 224: if (qos && qos -> qos_sversion < 0) { ! 225: sb -> sb_version = SB_VRSN1; ! 226: sb -> sb_vrsnmask = SB_ALLVRSNS; ! 227: } ! 228: else ! 229: sb -> sb_vrsnmask = 1 << (sb -> sb_version = ! 230: (cc > SS_SIZE ! 231: || (qos && qos -> qos_sversion > 1)) ! 232: ? SB_VRSN2 : SB_VRSN1); ! 233: ! 234: s -> s_mask |= SMASK_CN_REF | SMASK_CN_OPT | SMASK_CN_VRSN; ! 235: s -> s_cn_reference = *ref; /* struct copy */ ! 236: s -> s_options = CR_OPT_NULL; ! 237: s -> s_cn_version = sb -> sb_vrsnmask; ! 238: ! 239: if (isn != SERIAL_NONE) { ! 240: s -> s_mask |= SMASK_CN_ISN; ! 241: s -> s_isn = isn; ! 242: } ! 243: ! 244: if (cc > 0) { /* XXX: user musn't touch! */ ! 245: s -> s_mask |= SMASK_UDATA_PGI; ! 246: s -> s_udata = data, s -> s_ulen = cc; ! 247: } ! 248: else ! 249: s -> s_udata = NULL, s -> s_ulen = 0; ! 250: ! 251: sb -> sb_retry = s; ! 252: if (async) { ! 253: switch (result) { ! 254: case CONNECTING_1: ! 255: case CONNECTING_2: ! 256: sc -> sc_sd = sb -> sb_fd; ! 257: return result; ! 258: } ! 259: } ! 260: if ((result = SAsynRetryAux (sb, tc, sc, si)) == DONE && !async) ! 261: result = OK; ! 262: return result; ! 263: ! 264: out2: ; ! 265: freespkt (s); ! 266: out1: ; ! 267: freesblk (sb); ! 268: ! 269: return result; ! 270: } ! 271: ! 272: /* S-ASYN-RETRY.REQUEST (pseudo) */ ! 273: ! 274: int SAsynRetryRequest (sd, sc, si) ! 275: int sd; ! 276: struct SSAPconnect *sc; ! 277: struct SSAPindication *si; ! 278: { ! 279: SBV smask; ! 280: int result; ! 281: register struct ssapblk *sb; ! 282: struct TSAPconnect tcs; ! 283: register struct TSAPconnect *tc = &tcs; ! 284: struct TSAPdisconnect tds; ! 285: register struct TSAPdisconnect *td = &tds; ! 286: ! 287: missingP (sc); ! 288: missingP (si); ! 289: ! 290: smask = sigioblock (); ! 291: ! 292: if ((sb = findsblk (sd)) == NULL) { ! 293: (void) sigiomask (smask); ! 294: return ssaplose (si, SC_PARAMETER, NULLCP, ! 295: "invalid session descriptor"); ! 296: } ! 297: if (sb -> sb_flags & SB_CONN) { ! 298: (void) sigiomask (smask); ! 299: return ssaplose (si, SC_OPERATION, NULLCP, ! 300: "session descriptor connected"); ! 301: } ! 302: ! 303: switch (result = TAsynRetryRequest (sb -> sb_fd, tc, td)) { ! 304: case NOTOK: ! 305: (void) ts2sslose (si, "TAsynRetryRequest", td); ! 306: sb -> sb_fd = NOTOK; ! 307: ! 308: bzero ((char *) sc, sizeof *sc); ! 309: sc -> sc_sd = NOTOK; ! 310: sc -> sc_result = si -> si_abort.sa_reason; ! 311: ! 312: result = DONE; ! 313: freesblk (sb); ! 314: break; ! 315: ! 316: case CONNECTING_1: ! 317: case CONNECTING_2: ! 318: break; ! 319: ! 320: case DONE: ! 321: result = SAsynRetryAux (sb, tc, sc, si); ! 322: break; ! 323: } ! 324: ! 325: (void) sigiomask (smask); ! 326: ! 327: return result; ! 328: } ! 329: ! 330: /* S-ASYN-NEXT.REQUEST (pseudo) */ ! 331: ! 332: int SAsynNextRequest (sd, sc, si) ! 333: int sd; ! 334: struct SSAPconnect *sc; ! 335: struct SSAPindication *si; ! 336: { ! 337: SBV smask; ! 338: int result; ! 339: register struct ssapblk *sb; ! 340: struct TSAPconnect tcs; ! 341: register struct TSAPconnect *tc = &tcs; ! 342: struct TSAPdisconnect tds; ! 343: register struct TSAPdisconnect *td = &tds; ! 344: ! 345: missingP (sc); ! 346: missingP (si); ! 347: ! 348: smask = sigioblock (); ! 349: ! 350: if ((sb = findsblk (sd)) == NULL) { ! 351: (void) sigiomask (smask); ! 352: return ssaplose (si, SC_PARAMETER, NULLCP, ! 353: "invalid session descriptor"); ! 354: } ! 355: if (sb -> sb_flags & SB_CONN) { ! 356: (void) sigiomask (smask); ! 357: return ssaplose (si, SC_OPERATION, NULLCP, ! 358: "session descriptor connected"); ! 359: } ! 360: ! 361: switch (result = TAsynNextRequest (sb -> sb_fd, tc, td)) { ! 362: case NOTOK: ! 363: (void) ts2sslose (si, "TAsynRetryRequest", td); ! 364: sb -> sb_fd = NOTOK; ! 365: ! 366: bzero ((char *) sc, sizeof *sc); ! 367: sc -> sc_sd = NOTOK; ! 368: sc -> sc_result = si -> si_abort.sa_reason; ! 369: ! 370: result = DONE; ! 371: freesblk (sb); ! 372: break; ! 373: ! 374: case CONNECTING_1: ! 375: case CONNECTING_2: ! 376: break; ! 377: ! 378: case DONE: ! 379: result = SAsynRetryAux (sb, tc, sc, si); ! 380: break; ! 381: } ! 382: ! 383: (void) sigiomask (smask); ! 384: ! 385: return result; ! 386: } ! 387: ! 388: /* */ ! 389: ! 390: #define dotoken(requires,shift,bit,type) \ ! 391: { \ ! 392: if (sb -> sb_requirements & requires) { \ ! 393: switch (sb -> sb_settings & (ST_MASK << shift)) { \ ! 394: case ST_CALL_VALUE << shift: \ ! 395: if (!(s -> s_mask & SMASK_CN_SET)) \ ! 396: s -> s_settings = ST_INIT_VALUE << shift; \ ! 397: switch (s -> s_settings & (ST_MASK << shift)) { \ ! 398: case ST_INIT_VALUE << shift: \ ! 399: default: \ ! 400: sb -> sb_owned |= bit; \ ! 401: sc -> sc_settings |= ST_INIT_VALUE << shift; \ ! 402: break; \ ! 403: \ ! 404: case ST_RESP_VALUE << shift: \ ! 405: sc -> sc_settings |= ST_RESP_VALUE << shift; \ ! 406: break; \ ! 407: } \ ! 408: break; \ ! 409: \ ! 410: case ST_INIT_VALUE << shift: \ ! 411: sb -> sb_owned |= bit; \ ! 412: sc -> sc_settings |= ST_INIT_VALUE << shift; \ ! 413: break; \ ! 414: \ ! 415: case ST_RESP_VALUE << shift: \ ! 416: sc -> sc_settings |= ST_RESP_VALUE << shift; \ ! 417: break; \ ! 418: } \ ! 419: \ ! 420: if ((s -> s_mask & SMASK_AC_TOKEN) && (s -> s_ac_token & bit)) \ ! 421: sc -> sc_please |= bit; \ ! 422: } \ ! 423: } ! 424: ! 425: /* */ ! 426: ! 427: static int SAsynRetryAux (sb, tc, sc, si) ! 428: register struct ssapblk *sb; ! 429: struct TSAPconnect *tc; ! 430: struct SSAPconnect *sc; ! 431: struct SSAPindication *si; ! 432: { ! 433: int len, ! 434: result; ! 435: register struct ssapkt *s; ! 436: ! 437: s = sb -> sb_retry; ! 438: sb -> sb_retry = NULL; ! 439: ! 440: sb -> sb_responding.sa_addr = tc -> tc_responding; /* struct copy */ ! 441: if (tc -> tc_expedited) ! 442: sb -> sb_flags |= SB_EXPD; ! 443: else ! 444: sb -> sb_requirements &= ~SR_EXPEDITED; ! 445: if (sb -> sb_version < SB_VRSN2) /* XXX */ ! 446: sb -> sb_tsdu_us = sb -> sb_tsdu_them = ! 447: GET_TSDU_SIZE (tc -> tc_tsdusize); ! 448: ! 449: if (sb -> sb_tsdu_us || sb -> sb_tsdu_them) { ! 450: s -> s_mask |= SMASK_CN_TSDU; ! 451: s -> s_tsdu_resp = GET_TSDU_SIZE (sb -> sb_tsdu_us); ! 452: s -> s_tsdu_init = GET_TSDU_SIZE (sb -> sb_tsdu_them); ! 453: } ! 454: ! 455: s -> s_mask |= SMASK_CN_REQ; ! 456: if ((s -> s_cn_require = sb -> sb_requirements) & SR_TOKENS) { ! 457: s -> s_mask |= SMASK_CN_SET; ! 458: s -> s_settings = sb -> sb_settings; ! 459: } ! 460: ! 461: result = spkt2sd (s, sb -> sb_fd, 0, si); ! 462: s -> s_mask &= ~SMASK_UDATA_PGI; ! 463: s -> s_udata = NULL, s -> s_ulen = 0; ! 464: ! 465: freespkt (s); ! 466: if (result == NOTOK) ! 467: goto out1; ! 468: ! 469: if ((s = sb2spkt (sb, si, sb -> sb_maxtime, NULLTX)) == NULL) { ! 470: if (si -> si_abort.sa_reason == SC_TIMER) ! 471: (void) ssaplose (si, SC_CONGEST, NULLCP, "remote SPM timed-out"); ! 472: result = NOTOK; ! 473: goto out2; ! 474: } ! 475: ! 476: bzero ((char *) sc, sizeof *sc); ! 477: switch (s -> s_code) { ! 478: case SPDU_AC: ! 479: sc -> sc_sd = sb -> sb_fd; ! 480: sc -> sc_result = SC_ACCEPT; ! 481: if (s -> s_mask & SMASK_CN_REF) ! 482: sc -> sc_connect = s -> s_cn_reference; /* struct copy */ ! 483: if (s -> s_mask & SMASK_CN_OPT) ! 484: sb -> sb_options = s -> s_options; ! 485: if (!(s -> s_mask & SMASK_CN_TSDU)) ! 486: s -> s_tsdu_init = s -> s_tsdu_resp = 0; ! 487: if (s -> s_tsdu_init < sb -> sb_tsdu_us) ! 488: sb -> sb_tsdu_us = s -> s_tsdu_init; ! 489: if (s -> s_tsdu_resp < sb -> sb_tsdu_them) ! 490: sb -> sb_tsdu_them = s -> s_tsdu_resp; ! 491: if (BAD_TSDU_SIZE (sb -> sb_tsdu_us)) { ! 492: result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP, ! 493: "perposterous TSDU size (%d) for initiator", ! 494: sb -> sb_tsdu_us); ! 495: goto out2; ! 496: } ! 497: if (BAD_TSDU_SIZE (sb -> sb_tsdu_them)) { ! 498: result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP, ! 499: "perposterous TSDU size (%d) for responder", ! 500: sb -> sb_tsdu_them); ! 501: goto out2; ! 502: } ! 503: if (s -> s_mask & SMASK_CN_VRSN) { ! 504: if (!(s -> s_cn_version & sb -> sb_vrsnmask)) { ! 505: /* not SC_VERSION */ ! 506: result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP, ! 507: "version mismatch: expecting something in 0x%x, got 0x%x", ! 508: sb -> sb_vrsnmask, s -> s_cn_version); ! 509: goto out2; ! 510: } ! 511: sb -> sb_vrsnmask &= s -> s_cn_version; ! 512: } ! 513: sb -> sb_version = (sb -> sb_vrsnmask & (1 << SB_VRSN2)) ! 514: ? SB_VRSN2 : SB_VRSN1; ! 515: if (s -> s_mask & SMASK_CN_ISN) ! 516: sc -> sc_isn = sb -> sb_V_A = sb -> sb_V_M = s -> s_isn; ! 517: else ! 518: sc -> sc_isn = SERIAL_NONE; ! 519: if (!(s -> s_mask & SMASK_CN_REQ)) { ! 520: s -> s_mask |= SMASK_CN_REQ; ! 521: s -> s_cn_require = SR_DEFAULT; ! 522: } ! 523: switch (sb -> sb_requirements & (SR_HALFDUPLEX | SR_DUPLEX)) { ! 524: case SR_HALFDUPLEX: ! 525: if (s -> s_cn_require & SR_HALFDUPLEX) ! 526: break; ! 527: result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP, ! 528: "half-duplex negotiation failed"); ! 529: goto out2; ! 530: ! 531: case SR_DUPLEX: ! 532: if (s -> s_cn_require & SR_DUPLEX) ! 533: break; ! 534: result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP, ! 535: "full-duplex negotiation failed"); ! 536: goto out2; ! 537: ! 538: default: ! 539: break; ! 540: } ! 541: #ifdef notdef /* screwy session protocol... */ ! 542: if (s -> s_cn_require & ~sb -> sb_requirements) { ! 543: result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP, ! 544: "requirements negotiation failed"); ! 545: goto out2; ! 546: } ! 547: #endif ! 548: sb -> sb_requirements &= s -> s_cn_require; ! 549: switch (sb -> sb_requirements & (SR_HALFDUPLEX | SR_DUPLEX)) { ! 550: case SR_HALFDUPLEX: ! 551: case SR_DUPLEX: ! 552: break; ! 553: ! 554: default: ! 555: result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP, ! 556: "half/full-duplex negotiation failed"); ! 557: goto out2; ! 558: } ! 559: if ((sb -> sb_requirements & SR_EXCEPTIONS) ! 560: && !(sb -> sb_requirements & SR_HALFDUPLEX)) { ! 561: result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP, ! 562: "exception service requires half-duplex service"); ! 563: goto out2; ! 564: } ! 565: sc -> sc_requirements = sb -> sb_requirements; ! 566: sc -> sc_settings = sc -> sc_please = 0; ! 567: dotokens (); ! 568: if (s -> s_mask & SMASK_CN_CALLED) { ! 569: if ((len = s -> s_calledlen) ! 570: > sizeof sb -> sb_responding.sa_selector) ! 571: len = sizeof sb -> sb_responding.sa_selector; ! 572: bcopy (s -> s_called, sb -> sb_responding.sa_selector, ! 573: sb -> sb_responding.sa_selectlen = len); ! 574: } ! 575: sc -> sc_responding = sb -> sb_responding; /* struct copy */ ! 576: if ((sc -> sc_ssdusize = sb -> sb_tsdu_us - SSDU_MAGIC) < 0) ! 577: sc -> sc_ssdusize = tc -> tc_tsdusize - SSDU_MAGIC; ! 578: sc -> sc_qos = tc -> tc_qos; /* struct copy */ ! 579: sc -> sc_qos.qos_sversion = sb -> sb_version + 1; ! 580: sc -> sc_qos.qos_extended = (sb -> sb_flags & SB_EXPD) ? 1 : 0; ! 581: copySPKTdata (s, sc); ! 582: ! 583: freespkt (s); ! 584: sb -> sb_flags |= SB_CONN | SB_INIT; ! 585: ! 586: return DONE; ! 587: ! 588: case SPDU_RF: /* ignore s -> s_rf_disconnect */ ! 589: sc -> sc_sd = NOTOK; ! 590: sc -> sc_result = s -> s_rlen > 0 ? *s -> s_rdata ! 591: : SC_NOTSPECIFIED; ! 592: if (s -> s_mask & SMASK_RF_REF) ! 593: sc -> sc_connect = s -> s_rf_reference; /* struct copy */ ! 594: if ((sc -> sc_result == SC_REJECTED) ! 595: && (s -> s_mask & SMASK_RF_REQ)) ! 596: sc -> sc_requirements = s -> s_rf_require; ! 597: if ((s -> s_mask & SMASK_CN_CALLED) ! 598: && (sc -> sc_result & SC_BASE)) { ! 599: if ((len = s -> s_calledlen) ! 600: > sizeof sb -> sb_responding.sa_selector) ! 601: len = sizeof sb -> sb_responding.sa_selector; ! 602: bcopy (s -> s_called, sb -> sb_responding.sa_selector, ! 603: sb -> sb_responding.sa_selectlen = len); ! 604: } ! 605: sc -> sc_responding = sb -> sb_responding; /* struct copy */ ! 606: sc -> sc_data = s -> s_rdata + 1, sc -> sc_cc = s -> s_rlen - 1; ! 607: sc -> sc_realdata = s -> s_rdata, s -> s_rdata = NULL; ! 608: si -> si_type = SI_ABORT; ! 609: { ! 610: register struct SSAPabort *sa = &si -> si_abort; ! 611: ! 612: sa -> sa_peer = 0; ! 613: sa -> sa_reason = sc -> sc_result; ! 614: sa -> sa_info = sc -> sc_data, sa -> sa_cc = sc -> sc_cc; ! 615: sa -> sa_realinfo = NULL; ! 616: } ! 617: result = DONE; ! 618: break; ! 619: ! 620: case SPDU_AB: ! 621: sc -> sc_sd = NOTOK; ! 622: sc -> sc_result = SC_ABORT; ! 623: si -> si_type = SI_ABORT; ! 624: { ! 625: register struct SSAPabort *sa = &si -> si_abort; ! 626: ! 627: if (!(sa -> sa_peer = (s -> s_ab_disconnect & AB_DISC_USER) ! 628: ? 1 : 0)) ! 629: sa -> sa_reason = sc -> sc_result; ! 630: sa -> sa_info = s -> s_udata, sa -> sa_cc = s -> s_ulen; ! 631: sa -> sa_realinfo = s -> s_udata, s -> s_udata = NULL; ! 632: } ! 633: result = DONE; ! 634: break; ! 635: ! 636: default: ! 637: result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP, ! 638: "session protocol mangled: expecting 0x%x, got 0x%x", ! 639: SPDU_AC, s -> s_code); ! 640: break; ! 641: } ! 642: ! 643: out2: ; ! 644: freespkt (s); ! 645: out1: ; ! 646: freesblk (sb); ! 647: ! 648: return result; ! 649: } ! 650: ! 651: #undef dotoken
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.