|
|
1.1 ! root 1: /* tsaprovider.c - implement the transport service */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/tsap/RCS/tsaprovider.c,v 7.3 90/03/23 17:31:50 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/tsap/RCS/tsaprovider.c,v 7.3 90/03/23 17:31:50 mrose Exp $ ! 9: * ! 10: * ! 11: * $Log: tsaprovider.c,v $ ! 12: * Revision 7.3 90/03/23 17:31:50 mrose ! 13: * 8 ! 14: * ! 15: * Revision 7.2 90/01/11 18:38:09 mrose ! 16: * real-sync ! 17: * ! 18: * Revision 7.1 89/12/07 01:07:53 mrose ! 19: * queued writes ! 20: * ! 21: * Revision 7.0 89/11/23 22:30:56 mrose ! 22: * Release 6.0 ! 23: * ! 24: */ ! 25: ! 26: /* ! 27: * NOTICE ! 28: * ! 29: * Acquisition, use, and distribution of this module and related ! 30: * materials are subject to the restrictions of a license agreement. ! 31: * Consult the Preface in the User's Manual for the full terms of ! 32: * this agreement. ! 33: * ! 34: */ ! 35: ! 36: ! 37: /* LINTLIBRARY */ ! 38: ! 39: #include <stdio.h> ! 40: #include <signal.h> ! 41: #include "tpkt.h" ! 42: #include "mpkt.h" ! 43: #include "isoservent.h" ! 44: #include "tailor.h" ! 45: ! 46: ! 47: #define selmask(fd,m,n) \ ! 48: { \ ! 49: FD_SET (fd, &(m)); \ ! 50: if ((fd) >= (n)) \ ! 51: (n) = (fd) + 1; \ ! 52: } ! 53: ! 54: /* DATA */ ! 55: ! 56: static int once_only = 0; ! 57: static struct tsapblk tsapque; ! 58: static struct tsapblk *THead = &tsapque; ! 59: ! 60: ! 61: #ifndef SIGPOLL ! 62: static int TPid = NOTOK; ! 63: #endif ! 64: ! 65: /* T-DATA.REQUEST */ ! 66: ! 67: int TDataRequest (sd, data, cc, td) ! 68: int sd; ! 69: char *data; ! 70: int cc; ! 71: struct TSAPdisconnect *td; ! 72: { ! 73: SBV smask, ! 74: imask; ! 75: SFP istat; ! 76: int result; ! 77: struct udvec uvs[2]; ! 78: register struct udvec *uv = uvs; ! 79: register struct tsapblk *tb; ! 80: ! 81: missingP (data); ! 82: if (cc <= 0) ! 83: return tsaplose (td, DR_PARAMETER, NULLCP, ! 84: "illegal value for TSDU length (%d)", cc); ! 85: missingP (td); ! 86: ! 87: smask = sigioblock (); ! 88: ! 89: tsapPsig (tb, sd); ! 90: ! 91: if ((istat = signal (SIGINT, SIG_DFL)) != SIG_DFL) { ! 92: (void) signal (SIGINT, istat); ! 93: imask = siginblock (); ! 94: } ! 95: ! 96: uv -> uv_base = data, uv -> uv_len = cc, uv++; ! 97: uv -> uv_base = NULL; ! 98: ! 99: result = (*tb -> tb_writePfnx) (tb, uvs, 0, td); ! 100: ! 101: if (istat != SIG_DFL) ! 102: (void) siginmask (imask); ! 103: ! 104: (void) sigiomask (smask); ! 105: ! 106: return result; ! 107: } ! 108: ! 109: /* T-EXPEDITED-DATA.REQUEST */ ! 110: ! 111: int TExpdRequest (sd, data, cc, td) ! 112: int sd; ! 113: char *data; ! 114: int cc; ! 115: struct TSAPdisconnect *td; ! 116: { ! 117: SBV smask, ! 118: imask; ! 119: SFP istat; ! 120: int result; ! 121: struct udvec uvs[2]; ! 122: register struct udvec *uv = uvs; ! 123: register struct tsapblk *tb; ! 124: ! 125: missingP (data); ! 126: toomuchP (data, cc, TX_SIZE, "expedited"); ! 127: if (cc <= 0) ! 128: return tsaplose (td, DR_PARAMETER, NULLCP, ! 129: "illegal value for XSDU length (%d)", cc); ! 130: missingP (td); ! 131: ! 132: smask = sigioblock (); ! 133: ! 134: tsapPsig (tb, sd); ! 135: ! 136: if ((istat = signal (SIGINT, SIG_DFL)) != SIG_DFL) { ! 137: (void) signal (SIGINT, istat); ! 138: imask = siginblock (); ! 139: } ! 140: ! 141: uv -> uv_base = data, uv -> uv_len = cc, uv++; ! 142: uv -> uv_base = NULL; ! 143: ! 144: if (tb -> tb_flags & TB_EXPD) ! 145: result = (*tb -> tb_writePfnx) (tb, uvs, 1, td); ! 146: else ! 147: result = tsaplose (td, DR_OPERATION, NULLCP, ! 148: "expedited service unavailable"); ! 149: ! 150: if (istat != SIG_DFL) ! 151: (void) siginmask (imask); ! 152: ! 153: (void) sigiomask (smask); ! 154: ! 155: return result; ! 156: } ! 157: ! 158: /* T-WRITE.REQUEST (pseudo; write user data vectors) */ ! 159: ! 160: int TWriteRequest (sd, uv, td) ! 161: int sd; ! 162: struct udvec *uv; ! 163: struct TSAPdisconnect *td; ! 164: { ! 165: register int n; ! 166: SBV smask, ! 167: imask; ! 168: SFP istat; ! 169: int result; ! 170: register struct tsapblk *tb; ! 171: register struct udvec *vv; ! 172: ! 173: missingP (uv); ! 174: n = 0; ! 175: for (vv = uv; vv -> uv_base; vv++) ! 176: n += vv -> uv_len; ! 177: if (n == 0) ! 178: return tsaplose (td, DR_PARAMETER, NULLCP, "zero-length TSDU"); ! 179: missingP (td); ! 180: ! 181: smask = sigioblock (); ! 182: ! 183: tsapPsig (tb, sd); ! 184: ! 185: if ((istat = signal (SIGINT, SIG_DFL)) != SIG_DFL) { ! 186: (void) signal (SIGINT, istat); ! 187: imask = siginblock (); ! 188: } ! 189: ! 190: result = (*tb -> tb_writePfnx) (tb, uv, 0, td); ! 191: ! 192: if (istat != SIG_DFL) ! 193: (void) siginmask (imask); ! 194: ! 195: (void) sigiomask (smask); ! 196: ! 197: return result; ! 198: } ! 199: ! 200: /* T-READ.REQUEST (pseudo; synchronous read) */ ! 201: ! 202: int TReadRequest (sd, tx, secs, td) ! 203: int sd; ! 204: register struct TSAPdata *tx; ! 205: int secs; ! 206: register struct TSAPdisconnect *td; ! 207: { ! 208: SBV smask, ! 209: imask; ! 210: SFP istat; ! 211: int nfds, ! 212: oob, ! 213: result; ! 214: fd_set ifds, ! 215: efds, ! 216: mask; ! 217: register struct tsapblk *tb; ! 218: ! 219: missingP (tx); ! 220: missingP (td); ! 221: ! 222: smask = sigioblock (); ! 223: ! 224: tsapPsig (tb, sd); ! 225: ! 226: if ((istat = signal (SIGINT, SIG_DFL)) != SIG_DFL) { ! 227: (void) signal (SIGINT, istat); ! 228: imask = siginblock (); ! 229: } ! 230: ! 231: nfds = 0; ! 232: FD_ZERO (&mask); ! 233: selmask (tb -> tb_fd, mask, nfds); ! 234: ! 235: for (;;) { ! 236: ifds = efds = mask; /* struct copy */ ! 237: ! 238: if (tb -> tb_checkfnx == NULLIFP || (*tb -> tb_checkfnx) (tb) != OK) ! 239: switch ((*tb -> tb_selectfnx) (nfds, &ifds, NULLFD, &efds, secs)) { ! 240: case NOTOK: /* let read function find error... */ ! 241: ifds = mask; ! 242: break; ! 243: ! 244: case OK: ! 245: result = tsaplose (td, DR_TIMER, NULLCP, NULLCP); ! 246: goto out; ! 247: ! 248: default: ! 249: break; ! 250: } ! 251: else ! 252: FD_ZERO (&efds); ! 253: ! 254: if ((oob = FD_ISSET (tb -> tb_fd, &efds)) ! 255: || FD_ISSET (tb -> tb_fd, &ifds)) ! 256: result = (*tb -> tb_readPfnx) (tb, tx, td, secs != NOTOK, oob); ! 257: else ! 258: result = DONE; ! 259: if (result != DONE) ! 260: break; ! 261: if (secs != NOTOK) { ! 262: result = tsaplose (td, DR_TIMER, NULLCP, NULLCP); ! 263: break; ! 264: } ! 265: } ! 266: out: ; ! 267: ! 268: if (istat != SIG_DFL) ! 269: (void) siginmask (imask); ! 270: ! 271: (void) sigiomask (smask); ! 272: ! 273: return result; ! 274: } ! 275: ! 276: /* T-DISCONNECT.REQUEST */ ! 277: ! 278: int TDiscRequest (sd, data, cc, td) ! 279: int sd; ! 280: char *data; ! 281: int cc; ! 282: register struct TSAPdisconnect *td; ! 283: { ! 284: SBV smask; ! 285: int result; ! 286: register struct tsapblk *tb; ! 287: ! 288: toomuchP (data, cc, TD_SIZE, "disconnect"); ! 289: ! 290: smask = sigioblock (); ! 291: ! 292: if ((tb = findtblk (sd)) == NULL) { ! 293: (void) sigiomask (smask); ! 294: return tsaplose (td, DR_PARAMETER, NULLCP, ! 295: "invalid transport descriptor"); ! 296: } ! 297: ! 298: result = (*tb -> tb_discPfnx) (tb, data, cc, td); ! 299: ! 300: (void) sigiomask (smask); ! 301: ! 302: return result; ! 303: } ! 304: ! 305: /* set asynchronous event indications */ ! 306: ! 307: int TSetIndications (sd, data, disc, td) ! 308: int sd; ! 309: IFP data, ! 310: disc; ! 311: struct TSAPdisconnect *td; ! 312: { ! 313: SBV smask; ! 314: int result; ! 315: register struct tsapblk *tb; ! 316: ! 317: if (data || disc) { ! 318: missingP (data); ! 319: missingP (disc); ! 320: } ! 321: ! 322: smask = sigioblock (); ! 323: ! 324: tsapPsig (tb, sd); ! 325: ! 326: if (tb -> tb_DataIndication = data) ! 327: tb -> tb_flags |= TB_ASYN; ! 328: else ! 329: tb -> tb_flags &= ~TB_ASYN; ! 330: tb -> tb_DiscIndication = disc; ! 331: ! 332: result = TWakeUp (tb, td); ! 333: ! 334: (void) sigiomask (smask); ! 335: ! 336: return result; ! 337: } ! 338: ! 339: /* map transport descriptors for select() */ ! 340: ! 341: int TSelectMask (sd, mask, nfds, td) ! 342: int sd; ! 343: fd_set *mask; ! 344: int *nfds; ! 345: register struct TSAPdisconnect *td; ! 346: { ! 347: SBV smask; ! 348: register struct tsapblk *tb; ! 349: ! 350: missingP (mask); ! 351: missingP (nfds); ! 352: ! 353: smask = sigioblock (); ! 354: ! 355: if ((tb = findtblk (sd)) == NULL) { ! 356: (void) sigiomask (smask); ! 357: return tsaplose (td, DR_PARAMETER, NULLCP, ! 358: "invalid transport descriptor"); ! 359: } ! 360: ! 361: if (tb -> tb_checkfnx && (*tb -> tb_checkfnx) (tb) == OK) { ! 362: (void) sigiomask (smask); ! 363: return tsaplose (td, DR_WAITING, NULLCP, NULLCP); ! 364: } ! 365: ! 366: selmask (tb -> tb_fd, *mask, *nfds); ! 367: ! 368: (void) sigiomask (smask); ! 369: ! 370: return OK; ! 371: } ! 372: ! 373: /* NSAP interface: N-DATA.INDICATION */ ! 374: ! 375: /* ARGSUSED */ ! 376: ! 377: static SFD DATAser (sig, code, sc) ! 378: int sig; ! 379: long code; ! 380: struct sigcontext *sc; ! 381: { ! 382: int n, ! 383: nfds, ! 384: oob, ! 385: sd; ! 386: fd_set ifds, ! 387: efds, ! 388: imask, ! 389: emask; ! 390: #ifndef BSDSIGS ! 391: SBV smask; ! 392: #endif ! 393: IFP disc; ! 394: register struct tsapblk *tb, ! 395: *tb2; ! 396: struct TSAPdata txs; ! 397: register struct TSAPdata *tx = &txs; ! 398: struct TSAPdisconnect tds; ! 399: register struct TSAPdisconnect *td = &tds; ! 400: ! 401: #ifndef BSDSIGS ! 402: (void) signal (SIGEMT, DATAser); ! 403: ! 404: smask = sigioblock (); ! 405: #endif ! 406: ! 407: for (;;) { ! 408: n = 0; ! 409: FD_ZERO (&ifds); ! 410: FD_ZERO (&efds); ! 411: for (tb = THead -> tb_forw; tb != THead; tb = tb -> tb_forw) ! 412: if (tb -> tb_fd != NOTOK && (tb -> tb_flags & TB_ASYN)) { ! 413: nfds = 0; ! 414: FD_ZERO (&imask); ! 415: selmask (tb -> tb_fd, imask, nfds); ! 416: emask = imask; /* struct copy */ ! 417: if ((*tb -> tb_selectfnx) (nfds, &imask, NULLFD, &emask, 0) ! 418: > OK) { ! 419: if (FD_ISSET (tb -> tb_fd, &imask)) ! 420: FD_SET (tb -> tb_fd, &ifds); ! 421: if (FD_ISSET (tb -> tb_fd, &emask)) ! 422: FD_SET (tb -> tb_fd, &efds); ! 423: n++; ! 424: } ! 425: } ! 426: ! 427: if (n == 0) ! 428: break; ! 429: ! 430: for (tb = THead -> tb_forw; tb != THead; tb = tb2) { ! 431: tb2 = tb -> tb_forw; ! 432: ! 433: sd = tb -> tb_fd; ! 434: if ((oob = FD_ISSET (sd, &efds)) || FD_ISSET (sd, &ifds)) { ! 435: disc = tb -> tb_DiscIndication; ! 436: switch ((*tb -> tb_readPfnx) (tb, tx, td, 1, oob)) { ! 437: case NOTOK: ! 438: (*disc) (sd, td); ! 439: break; ! 440: ! 441: case OK: ! 442: (*tb -> tb_DataIndication) (sd, tx); ! 443: break; ! 444: ! 445: case DONE: /* partially assembled TSDU */ ! 446: break; ! 447: } ! 448: } ! 449: } ! 450: } ! 451: ! 452: #ifndef SIGPOLL ! 453: (void) kill (TPid, SIGEMT); ! 454: #endif ! 455: ! 456: #ifndef BSDSIGS ! 457: (void) sigiomask (smask); ! 458: #endif ! 459: } ! 460: ! 461: /* */ ! 462: ! 463: #ifndef SIGPOLL ! 464: static int TWakeUp (tb, td) ! 465: register struct tsapblk *tb; ! 466: struct TSAPdisconnect *td; ! 467: { ! 468: int i, ! 469: nfds; ! 470: fd_set mask; ! 471: char buf1[10], ! 472: buf2[10], ! 473: buf3[10]; ! 474: register struct isoservent *is; ! 475: static int inited = 0; ! 476: ! 477: if (TPid > OK) { ! 478: (void) kill (TPid, SIGTERM); ! 479: TPid = NOTOK; ! 480: } ! 481: ! 482: nfds = 0; ! 483: FD_ZERO (&mask); ! 484: for (tb = THead -> tb_forw; tb != THead; tb = tb -> tb_forw) ! 485: if (tb -> tb_fd != NOTOK && (tb -> tb_flags & TB_ASYN)) ! 486: selmask (tb -> tb_fd, mask, nfds); ! 487: ! 488: if (nfds == 0) ! 489: return OK; ! 490: ! 491: if (nfds > sizeof (int) * 8) ! 492: return tsaplose (td, DR_CONGEST, NULLCP, "you lose"); ! 493: if (!inited) { ! 494: #ifndef BSDSIGS ! 495: int smask = sigsetmask (sigblock (0) & ~sigmask (SIGEMT)); ! 496: #endif ! 497: ! 498: (void) signal (SIGEMT, DATAser); ! 499: #ifndef BSDSIGS ! 500: (void) sigiomask (smask); ! 501: #endif ! 502: inited++; ! 503: } ! 504: ! 505: if ((is = getisoserventbyname ("isore", "tsap")) == NULL) ! 506: return tsaplose (td, DR_CONGEST, NULLCP, ! 507: "ISO service tsap/isore not found"); ! 508: ! 509: (void) sprintf (buf1, "%d", nfds); ! 510: *is -> is_tail++ = buf1; ! 511: (void) sprintf (buf2, "0x%x", mask.fds_bits[0]); ! 512: *is -> is_tail++ = buf2; ! 513: (void) sprintf (buf3, "%d", getpid ()); ! 514: *is -> is_tail++ = buf3; ! 515: *is -> is_tail = NULL; ! 516: ! 517: for (i = 0; i < 5; i++) ! 518: switch (TPid = vfork ()) { ! 519: case NOTOK: ! 520: continue; ! 521: ! 522: case OK: ! 523: (void) signal (SIGEMT, SIG_DFL); ! 524: (void) execv (*is -> is_vec, is -> is_vec); ! 525: _exit (1); ! 526: ! 527: default: ! 528: return OK; ! 529: } ! 530: ! 531: return tsaplose (td, DR_CONGEST, "isore", "unable to fork"); ! 532: } ! 533: #else ! 534: #ifdef BSDSIGS ! 535: #include <fcntl.h> ! 536: #include <sys/ioctl.h> ! 537: #else ! 538: #include <sys/stropts.h> ! 539: #endif ! 540: ! 541: ! 542: static int TWakeUp (tb, td) ! 543: register struct tsapblk *tb; ! 544: struct TSAPdisconnect *td; ! 545: { ! 546: int result; ! 547: #ifndef notdef ! 548: int pgrp; ! 549: #endif ! 550: static int inited = 0; ! 551: ! 552: if (tb -> tb_flags & TB_ASYN) { ! 553: if (!inited) { ! 554: (void) signal (SIGPOLL, DATAser); ! 555: ! 556: inited++; ! 557: } ! 558: ! 559: #ifdef BSDSIGS ! 560: #ifdef notdef ! 561: if (fcntl (tb -> tb_fd, F_SETOWN, getpid ()) == NOTOK) ! 562: return tsaplose (td, DR_CONGEST, "failed", "fcntl F_SETOWN"); ! 563: #else ! 564: pgrp = -getpid (); ! 565: if (ioctl (tb -> tb_fd, SIOCSPGRP, (char *) &pgrp) == NOTOK) ! 566: return tsaplose (td, DR_CONGEST, "failed", "ioctl SIOCSPGRP %d", ! 567: pgrp); ! 568: #endif ! 569: if ((result = fcntl (tb -> tb_fd, F_GETFL, 0x00)) == NOTOK) ! 570: return tsaplose (td, DR_CONGEST, "failed", "fcntl F_GETFL"); ! 571: result |= FASYNC; ! 572: if (fcntl (tb -> tb_fd, F_SETFL, result) == NOTOK) ! 573: return tsaplose (td, DR_CONGEST, "failed", "fcntl F_SETFL 0x%x", ! 574: result); ! 575: #else ! 576: #ifdef notdef ! 577: if (ioctl (tb -> tb_fd, I_GETSIG, &result) == NOTOK) ! 578: result = 0; ! 579: result |= S_INPUT; ! 580: if (ioctl (tb -> tb_fd, I_SETSIG, result) == NOTOK) ! 581: return tsaplose (td, DR_CONGEST, "failed", "ioctl I_SETSIG 0x%x", ! 582: result); ! 583: #else ! 584: return tsaplose (td, DR_CONGEST, NULLCP, ! 585: "asynchronous operations not yet supported under SVR3"); ! 586: #endif ! 587: #endif ! 588: } ! 589: else { ! 590: #ifdef BSDSIGS ! 591: if ((result = fcntl (tb -> tb_fd, F_GETFL, 0x00)) == NOTOK) ! 592: return tsaplose (td, DR_CONGEST, "failed", "fcntl F_GETFL"); ! 593: result &= ~FASYNC; ! 594: if (fcntl (tb -> tb_fd, F_SETFL, result) == NOTOK) ! 595: return tsaplose (td, DR_CONGEST, "failed", "fcntl F_SETFL 0x%x", ! 596: result); ! 597: #else ! 598: if (ioctl (tb -> tb_fd, I_GETSIG, &result) == NOTOK) ! 599: return tsaplose (td, DR_CONGEST, "failed", "ioctl I_GETSIG"); ! 600: result &= ~S_INPUT; ! 601: if (ioctl (tb -> tb_fd, I_SETSIG, result) == NOTOK) ! 602: return tsaplose (td, DR_CONGEST, "failed", "ioctl I_SETSIG 0x%x", ! 603: result); ! 604: #endif ! 605: } ! 606: ! 607: return OK; ! 608: } ! 609: #endif ! 610: ! 611: /* INTERNAL */ ! 612: ! 613: struct tsapblk *newtblk () { ! 614: register struct tsapblk *tb; ! 615: ! 616: tb = (struct tsapblk *) calloc (1, sizeof *tb); ! 617: if (tb == NULL) ! 618: return NULL; ! 619: ! 620: tb -> tb_fd = NOTOK; ! 621: ! 622: tb -> tb_qbuf.qb_forw = tb -> tb_qbuf.qb_back = &tb -> tb_qbuf; ! 623: tb -> tb_qwrites.qb_forw = tb -> tb_qwrites.qb_back = &tb -> tb_qwrites; ! 624: ! 625: if (once_only == 0) { ! 626: THead -> tb_forw = THead -> tb_back = THead; ! 627: once_only++; ! 628: } ! 629: ! 630: insque (tb, THead -> tb_back); ! 631: ! 632: return tb; ! 633: } ! 634: ! 635: ! 636: freetblk (tb) ! 637: register struct tsapblk *tb; ! 638: { ! 639: SBV smask; ! 640: #ifndef SIGPOLL ! 641: struct TSAPdisconnect tds; ! 642: #endif ! 643: ! 644: if (tb == NULL) ! 645: return; ! 646: ! 647: smask = sigioblock (); ! 648: ! 649: if (tb -> tb_fd != NOTOK) { ! 650: (void) (*tb -> tb_closefnx) (tb -> tb_fd); ! 651: #ifdef MGMT ! 652: if (tb -> tb_manfnx) ! 653: (*tb -> tb_manfnx) (DISCREQ, tb); ! 654: #endif ! 655: } ! 656: ! 657: if (tb -> tb_retry) ! 658: freetpkt (tb -> tb_retry); ! 659: ! 660: if (tb -> tb_calling) ! 661: free ((char *) tb -> tb_calling); ! 662: if (tb -> tb_called) ! 663: free ((char *) tb -> tb_called); ! 664: if (tb -> tb_data) ! 665: free (tb -> tb_data); ! 666: ! 667: #ifndef SIGPOLL ! 668: if ((tb -> tb_flags & TB_ASYN) && TPid > OK) { ! 669: (void) kill (TPid, SIGTERM); ! 670: TPid = NOTOK; ! 671: } ! 672: #endif ! 673: ! 674: QBFREE (&tb -> tb_qbuf); ! 675: ! 676: if (tb -> tb_queuePfnx) ! 677: (*tb -> tb_queuePfnx) (tb, 0, (struct TSAPdisconnect *) 0); ! 678: QBFREE (&tb -> tb_qwrites); ! 679: ! 680: remque (tb); ! 681: ! 682: free ((char *) tb); ! 683: ! 684: #ifndef SIGPOLL ! 685: for (tb = THead -> tb_forw; tb != THead; tb = tb -> tb_forw) ! 686: if (tb -> tb_fd != NOTOK && (tb -> tb_flags & TB_ASYN)) { ! 687: (void) TWakeUp (tb, &tds); ! 688: break; ! 689: } ! 690: #endif ! 691: ! 692: (void) sigiomask (smask); ! 693: } ! 694: ! 695: /* */ ! 696: ! 697: struct tsapblk *findtblk (sd) ! 698: register int sd; ! 699: { ! 700: register struct tsapblk *tb; ! 701: ! 702: if (once_only == 0) ! 703: return NULL; ! 704: ! 705: for (tb = THead -> tb_forw; tb != THead; tb = tb -> tb_forw) ! 706: if (tb -> tb_fd == sd) ! 707: return tb; ! 708: ! 709: return NULL; ! 710: } ! 711: ! 712: /* */ ! 713: ! 714: int copyTSAPaddrX (in, out) ! 715: struct tsapADDR *in; ! 716: struct TSAPaddr *out; ! 717: { ! 718: bzero ((char *) out, sizeof *out); ! 719: ! 720: bcopy (in -> ta_selector, out -> ta_selector, ! 721: out -> ta_selectlen = in -> ta_selectlen); ! 722: ! 723: if (in -> ta_present) { ! 724: out -> ta_addrs[0] = in -> ta_addr; /* struct copy */ ! 725: out -> ta_naddr = 1; ! 726: } ! 727: } ! 728: ! 729: ! 730: int copyTSAPaddrY (in, out) ! 731: struct TSAPaddr *in; ! 732: struct tsapADDR *out; ! 733: { ! 734: bzero ((char *) out, sizeof *out); ! 735: ! 736: bcopy (in -> ta_selector, out -> ta_selector, ! 737: out -> ta_selectlen = in -> ta_selectlen); ! 738: ! 739: if (out -> ta_present = (in -> ta_naddr >= 1) ? 1 : 0) ! 740: out -> ta_addr = in -> ta_addrs[0]; /* struct copy */ ! 741: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.