|
|
1.1 ! root 1: #include "copyright.h" ! 2: /* $XConsortium: XConnDis.c,v 11.36 88/09/16 11:09:34 jim Exp $ */ ! 3: /* Copyright Massachusetts Institute of Technology 1985, 1986 */ ! 4: #define NEED_EVENTS ! 5: /* ! 6: * THIS IS AN OS DEPENDENT FILE! It should work on 4.2BSD derived ! 7: * systems. VMS and System V should plan to have their own version. ! 8: */ ! 9: #include <stdio.h> ! 10: #include <X11/Xos.h> ! 11: #include "Xlibint.h" ! 12: #include <sys/socket.h> ! 13: #ifndef hpux ! 14: #include <netinet/tcp.h> ! 15: #endif ! 16: ! 17: #ifdef hpux ! 18: #include <sys/utsname.h> ! 19: #endif ! 20: ! 21: #ifdef UNIXCONN ! 22: #include <sys/un.h> ! 23: #ifndef X_UNIX_PATH ! 24: #define X_UNIX_PATH "/tmp/.X11-unix/X" ! 25: #endif /* X_UNIX_PATH */ ! 26: #endif /* UNIXCONN */ ! 27: void bcopy(); ! 28: ! 29: #ifdef ISOCONN ! 30: #include <isode/psap.h> ! 31: #include <isode/tsap.h> ! 32: #include <isode/isoservent.h> ! 33: ! 34: #ifdef ISODEBUG ! 35: extern char *isodetcpath; ! 36: ! 37: int isodexbug = 0; ! 38: #endif /* ISODEBUG */ ! 39: #endif /* ISOCONN */ ! 40: ! 41: #ifdef ISOCONN ! 42: ! 43: /* ! 44: * array of fd 2 family map so we can lookup right function below... ! 45: * Its initialised at connection setup... ! 46: */ ! 47: int fd2family[MAXSOCKS]; ! 48: /* ! 49: * Globals for storing functions appropos each fd/socket type ! 50: * UNIX_IO (0) map to sys calls ! 51: * ISODE_IO (1) maps to my fns... ! 52: */ ! 53: extern int read(), TReadFromServer(); ! 54: int (*readfn[])() = ! 55: { ! 56: read, TReadFromServer ! 57: }; ! 58: extern int write(), TWriteToServer(); ! 59: int (*writefn[])() = ! 60: { ! 61: write, TWriteToServer ! 62: }; ! 63: extern int readv(), TReadvFromServer(); ! 64: int (*readvfn[])() = ! 65: { ! 66: readv, TReadvFromServer ! 67: }; ! 68: extern writev(), TWritevToServer(); ! 69: int (*writevfn[])() = ! 70: { ! 71: writev, TWritevToServer ! 72: }; ! 73: extern int UBytesReadable(), TBytesReadable(); ! 74: int (*ioctlfn[])() = ! 75: { ! 76: UBytesReadable, TBytesReadable ! 77: }; ! 78: extern int close(), TDiscFromServer(); ! 79: int (*closefn[])() = ! 80: { ! 81: close, TDiscFromServer ! 82: }; ! 83: ! 84: static ! 85: int iso_conn(server) ! 86: char *server; ! 87: { ! 88: struct TSAPconnect tcs; ! 89: struct TSAPconnect *tc = &tcs; ! 90: struct TSAPdisconnect tds; ! 91: struct TSAPdisconnect *td = &tds; ! 92: struct QOStype qo; ! 93: struct QOStype *qos = &qo; ! 94: AEI aei; ! 95: struct PSAPaddr *pa, rpa, *mpa, rmpa; ! 96: int ret; ! 97: char *x; ! 98: extern char *index(); ! 99: ! 100: #ifdef ISODEBUG ! 101: isodetcpath = ISODEPATH; ! 102: #endif /* ISODEBUG */ ! 103: ! 104: /* ! 105: * Get their TSAP from their AEI ! 106: */ ! 107: if ((x = index(server, ':')) != NULL) { ! 108: *(x++) = '\0'; ! 109: aei = str2aei(server, x); ! 110: } else { ! 111: aei = str2aei(server, DEFAULTTSERVICE); ! 112: } ! 113: ! 114: if (aei == NULLAEI) { ! 115: fprintf(stderr, "No AEI for %s\n", server); ! 116: return -1; ! 117: } ! 118: ! 119: if ((pa = aei2addr (aei)) == NULLPA) { ! 120: fprintf (stderr, "address translation failed"); ! 121: return -1; ! 122: } ! 123: rpa = *pa; /* struct copy */ ! 124: /* ! 125: * Get my address for completeness ! 126: */ ! 127: mpa = NULLPA; ! 128: if (x != NULL) ! 129: aei = str2aei(TLocalHostName(), x); ! 130: else ! 131: aei = str2aei(TLocalHostName(), DEFAULTTSERVICE); ! 132: if (aei == NULLAEI) { ! 133: fprintf (stderr, "my AEI lookup failed %s\n", ! 134: TLocalHostName()); ! 135: return -1; ! 136: } ! 137: ! 138: if ((mpa = aei2addr (aei)) == NULLPA) { ! 139: fprintf (stderr, "my address translation failed %s\n", ! 140: TLocalHostName()); ! 141: return -1; ! 142: } ! 143: ! 144: rmpa = *mpa; /* struct copy */ ! 145: /* ! 146: * No Xpedited required ! ! 147: */ ! 148: tc->tc_expedited = 0; ! 149: /* ! 150: * Just a guess - i dont understand ! 151: * the comment in the documentation about TSDUsizes ! 152: */ ! 153: tc->tc_tsdusize = 16000; ! 154: tc->tc_cc = 0; ! 155: qos->qos_reliability = LOW_QUALITY; /* Well this is X after all */ ! 156: ! 157: ret = TConnRequest(&(rmpa.pa_addr.sa_addr), ! 158: &(rpa.pa_addr.sa_addr), ! 159: 0, 0, NULLCP, qos, tc, td); ! 160: ! 161: /* ! 162: * Should map errors to perrors somehow??? ! 163: */ ! 164: if (ret == NOTOK) { ! 165: #ifdef ISODEBUG ! 166: if (isodexbug) ! 167: fprintf(stderr, "TCR Failed %s\n", ! 168: TErrString(td->td_reason)); ! 169: #endif /* ISODEBUG */ ! 170: return -1; ! 171: } ! 172: else { ! 173: #ifdef ISODEBUG ! 174: if (isodexbug) ! 175: fprintf(stderr, "client: isoconn ok\n"); ! 176: #endif /* ISODEBUG */ ! 177: ret = tc->tc_sd; ! 178: return ret; ! 179: } ! 180: } ! 181: #endif /* ISOCONN */ ! 182: ! 183: /* ! 184: * Attempts to connect to server, given display name. Returns file descriptor ! 185: * (network socket) or -1 if connection fails. The expanded display name ! 186: * of the form hostname:number.screen ("::" if DECnet) is returned in a result ! 187: * parameter. The screen number to use is also returned. ! 188: */ ! 189: int _XConnectDisplay (display_name, expanded_name, prop_name, screen_num) ! 190: char *display_name; ! 191: char *expanded_name; /* return */ ! 192: char *prop_name; /* return */ ! 193: int *screen_num; /* return */ ! 194: ! 195: { ! 196: char displaybuf[256]; /* Display string buffer */ ! 197: register char *display_ptr; /* Display string buffer pointer */ ! 198: register char *numbuf_ptr; /* Server number buffer pointer */ ! 199: char *screen_ptr; /* Pointer for locating screen num */ ! 200: int display_num; /* Display number */ ! 201: struct sockaddr_in inaddr; /* INET socket address. */ ! 202: unsigned long hostinetaddr; /* result of inet_addr of arpa addr */ ! 203: #ifdef UNIXCONN ! 204: struct sockaddr_un unaddr; /* UNIX socket address. */ ! 205: #endif ! 206: struct sockaddr *addr; /* address to connect to */ ! 207: struct hostent *host_ptr; ! 208: int addrlen; /* length of address */ ! 209: extern char *getenv(); ! 210: extern struct hostent *gethostbyname(); ! 211: int fd; /* Network socket */ ! 212: char numberbuf[16]; ! 213: char *dot_ptr = NULL; /* Pointer to . before screen num */ ! 214: #ifdef DNETCONN ! 215: int dnet = 0; ! 216: char objname[20]; ! 217: extern int dnet_conn(); ! 218: #endif ! 219: #ifdef ISOCONN ! 220: int isoconn = 0; ! 221: char isochar = 'X'; ! 222: ! 223: /* ! 224: * ISO Host name are "host:T-Namenumber" ! 225: * T-Name = T (for TCP) or X (for X.25) should really be ! 226: * TP4 or TP0 whathaveyou ! 227: */ ! 228: #endif /* ISOCONN */ ! 229: ! 230: /* ! 231: * Find the ':' seperator and extract the hostname and the ! 232: * display number. ! 233: * NOTE - if DECnet is to be used, the display name is formatted ! 234: * as "host::number" ! 235: */ ! 236: (void) strncpy(displaybuf, display_name, sizeof(displaybuf)); ! 237: if ((display_ptr = SearchString(displaybuf,':')) == NULL) return (-1); ! 238: #ifdef DNETCONN ! 239: if (*(display_ptr + 1) == ':') { ! 240: dnet++; ! 241: *(display_ptr++) = '\0'; ! 242: } ! 243: #endif ! 244: #ifdef ISOCONN ! 245: if ((*(display_ptr + 1) == 'X') || (*(display_ptr + 1) == 'T')) { ! 246: isochar = *(display_ptr + 1); ! 247: isoconn++; ! 248: *(display_ptr++) = '\0'; ! 249: } ! 250: #endif /* ISOCONN */ ! 251: *(display_ptr++) = '\0'; ! 252: ! 253: /* displaybuf now contains only a null-terminated host name, and ! 254: * display_ptr points to the display number. ! 255: * If the display number is missing there is an error. */ ! 256: ! 257: if (*display_ptr == '\0') return(-1); ! 258: ! 259: /* ! 260: * Build a string of the form <display-number>.<screen-number> in ! 261: * numberbuf, using ".0" as the default. ! 262: */ ! 263: screen_ptr = display_ptr; /* points to #.#.propname */ ! 264: numbuf_ptr = numberbuf; /* beginning of buffer */ ! 265: while (*screen_ptr != '\0') { ! 266: if (*screen_ptr == '.') { /* either screen or prop */ ! 267: if (dot_ptr) { /* then found prop_name */ ! 268: screen_ptr++; ! 269: break; ! 270: } ! 271: dot_ptr = numbuf_ptr; /* found screen_num */ ! 272: *(screen_ptr++) = '\0'; ! 273: *(numbuf_ptr++) = '.'; ! 274: } else { ! 275: *(numbuf_ptr++) = *(screen_ptr++); ! 276: } ! 277: } ! 278: ! 279: /* ! 280: * If the spec doesn't include a screen number, add ".0" (or "0" if ! 281: * only "." is present.) ! 282: */ ! 283: if (dot_ptr == NULL) { /* no screen num or prop */ ! 284: dot_ptr = numbuf_ptr; ! 285: *(numbuf_ptr++) = '.'; ! 286: *(numbuf_ptr++) = '0'; ! 287: } else { ! 288: if (*(numbuf_ptr - 1) == '.') ! 289: *(numbuf_ptr++) = '0'; ! 290: } ! 291: *numbuf_ptr = '\0'; ! 292: ! 293: /* ! 294: * Return the screen number and property names in the result parameters ! 295: */ ! 296: *screen_num = atoi(dot_ptr + 1); ! 297: strcpy (prop_name, screen_ptr); ! 298: ! 299: /* ! 300: * Convert the server number string to an integer. ! 301: */ ! 302: display_num = atoi(display_ptr); ! 303: ! 304: /* ! 305: * If the display name is missing, use current host. ! 306: */ ! 307: if (displaybuf[0] == '\0') ! 308: #ifdef DNETCONN ! 309: if (dnet) ! 310: (void) strcpy (displaybuf, "0"); ! 311: else ! 312: #endif ! 313: #ifdef UNIXCONN ! 314: ; /* Do nothing if UNIX DOMAIN. Will be handled below. */ ! 315: #else ! 316: #ifdef hpux ! 317: /* ! 318: * same host name crock as in server and xinit. ! 319: */ ! 320: { ! 321: struct utsname name; ! 322: ! 323: uname(&name); ! 324: strcpy(displaybuf, name.nodename); ! 325: } ! 326: #else ! 327: (void) gethostname (displaybuf, sizeof(displaybuf)); ! 328: #endif /* hpux */ ! 329: #endif /* UNIXCONN else TCPCONN (assumed) */ ! 330: ! 331: #ifdef DNETCONN ! 332: if (dnet) { ! 333: /* ! 334: * build the target object name. ! 335: */ ! 336: sprintf(objname, "X$X%d", display_num); ! 337: /* ! 338: * Attempt to open the DECnet connection, return -1 if fails. ! 339: */ ! 340: if ((fd = dnet_conn(displaybuf, ! 341: objname, SOCK_STREAM, 0, 0, 0, 0)) < 0) ! 342: return(-1); /* errno set by dnet_conn. */ ! 343: #ifdef ISOCONN ! 344: else ! 345: fd2family[fd] = UNIX_IO; ! 346: #endif /* ISOCONN */ ! 347: ! 348: } else ! 349: #endif ! 350: #ifdef ISOCONN ! 351: if (isoconn) { ! 352: if ((fd = iso_conn(displaybuf)) < 0) ! 353: return(-1); ! 354: else ! 355: fd2family[fd] = ISODE_IO; ! 356: } else ! 357: #endif ! 358: { ! 359: #ifdef UNIXCONN ! 360: if ((displaybuf[0] == '\0') || ! 361: (strcmp("unix", displaybuf) == 0)) { ! 362: /* Connect locally using Unix domain. */ ! 363: unaddr.sun_family = AF_UNIX; ! 364: (void) strcpy(unaddr.sun_path, X_UNIX_PATH); ! 365: strcat(unaddr.sun_path, display_ptr); ! 366: addr = (struct sockaddr *) &unaddr; ! 367: addrlen = strlen(unaddr.sun_path) + 2; ! 368: /* ! 369: * Open the network connection. ! 370: */ ! 371: if ((fd = socket((int) addr->sa_family, SOCK_STREAM, 0)) < 0) ! 372: return(-1); /* errno set by system call. */ ! 373: } else ! 374: #endif ! 375: { ! 376: /* Get the statistics on the specified host. */ ! 377: hostinetaddr = inet_addr (displaybuf); ! 378: if (hostinetaddr == -1) { ! 379: if ((host_ptr = gethostbyname(displaybuf)) == NULL) { ! 380: /* No such host! */ ! 381: errno = EINVAL; ! 382: return(-1); ! 383: } ! 384: /* Check the address type for an internet host. */ ! 385: if (host_ptr->h_addrtype != AF_INET) { ! 386: /* Not an Internet host! */ ! 387: errno = EPROTOTYPE; ! 388: return(-1); ! 389: } ! 390: ! 391: /* Set up the socket data. */ ! 392: inaddr.sin_family = host_ptr->h_addrtype; ! 393: #if defined(CRAY) && defined(OLDTCP) ! 394: /* Only Cray UNICOS3 and UNICOS4 will define this */ ! 395: { ! 396: long t; ! 397: bcopy((char *)host_ptr->h_addr, ! 398: (char *)&t, ! 399: sizeof(inaddr.sin_addr)); ! 400: inaddr.sin_addr = t; ! 401: } ! 402: #else ! 403: bcopy((char *)host_ptr->h_addr, ! 404: (char *)&inaddr.sin_addr, ! 405: sizeof(inaddr.sin_addr)); ! 406: #endif /* CRAY and OLDTCP */ ! 407: } else { ! 408: #if defined(CRAY) && defined(OLDTCP) ! 409: /* Only Cray UNICOS3 and UNICOS4 will define this */ ! 410: inaddr.sin_addr = hostinetaddr; ! 411: #else ! 412: inaddr.sin_addr.s_addr = hostinetaddr; ! 413: #endif /* CRAY and OLDTCP */ ! 414: inaddr.sin_family = AF_INET; ! 415: } ! 416: addr = (struct sockaddr *) &inaddr; ! 417: addrlen = sizeof (struct sockaddr_in); ! 418: inaddr.sin_port = display_num; ! 419: inaddr.sin_port += X_TCP_PORT; ! 420: inaddr.sin_port = htons(inaddr.sin_port); ! 421: /* ! 422: * Open the network connection. ! 423: */ ! 424: ! 425: if ((fd = socket((int) addr->sa_family, SOCK_STREAM, 0)) < 0) ! 426: return(-1); /* errno set by system call. */ ! 427: #ifdef ISOCONN ! 428: fd2family[fd] = UNIX_IO; ! 429: #endif /* ISOCONN */ ! 430: /* make sure to turn off TCP coalescence */ ! 431: #ifdef TCP_NODELAY ! 432: { ! 433: int mi = 1; ! 434: setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &mi, sizeof (int)); ! 435: } ! 436: #endif ! 437: } ! 438: ! 439: ! 440: if (connect(fd, addr, addrlen) == -1) { ! 441: (void) close (fd); ! 442: return(-1); /* errno set by system call. */ ! 443: } ! 444: } ! 445: ! 446: #ifdef ISOCONN ! 447: if (!isoconn) { ! 448: #endif /* ISOCONN */ ! 449: /* ! 450: * Not required for ISO T-Service ! 451: */ ! 452: /* ! 453: * set it non-blocking. This is so we can read data when blocked ! 454: * for writing in the library. ! 455: */ ! 456: #ifdef FIOSNBIO ! 457: { ! 458: int arg = 1; ! 459: ioctl(fd, FIOSNBIO, &arg); ! 460: } ! 461: #else ! 462: (void) fcntl(fd, F_SETFL, FNDELAY); ! 463: #endif /* FIOSNBIO */ ! 464: ! 465: #ifdef ISOCONN ! 466: } ! 467: #endif /* ISOCONN */ ! 468: /* ! 469: * Return the id if the connection succeeded. Rebuild the expanded ! 470: * spec and return it in the result parameter. ! 471: */ ! 472: display_ptr = displaybuf-1; ! 473: while (*(++display_ptr) != '\0') ! 474: ; ! 475: *(display_ptr++) = ':'; ! 476: #ifdef DNETCONN ! 477: if (dnet) ! 478: *(display_ptr++) = ':'; ! 479: #endif ! 480: #ifdef ISOCONN ! 481: if (isoconn) { ! 482: *(display_ptr++) = isochar; ! 483: } ! 484: #endif ! 485: numbuf_ptr = numberbuf; ! 486: while (*numbuf_ptr != '\0') ! 487: *(display_ptr++) = *(numbuf_ptr++); ! 488: if (prop_name[0] != '\0') { ! 489: char *cp; ! 490: ! 491: *(display_ptr++) = '.'; ! 492: for (cp = prop_name; *cp; cp++) *(display_ptr++) = *cp; ! 493: } ! 494: *display_ptr = '\0'; ! 495: (void) strcpy(expanded_name, displaybuf); ! 496: return(fd); ! 497: ! 498: } ! 499: ! 500: /* ! 501: * Disconnect from server. ! 502: */ ! 503: ! 504: int _XDisconnectDisplay (server) ! 505: ! 506: int server; ! 507: ! 508: { ! 509: #ifdef ISOCONN ! 510: (void)CloseToServer(server); ! 511: #else /* ISOCONN */ ! 512: (void) close(server); ! 513: #endif /* ISOCONN */ ! 514: } ! 515: ! 516: #undef NULL ! 517: #define NULL ((char *) 0) ! 518: /* ! 519: * This is an OS dependent routine which: ! 520: * 1) returns as soon as the connection can be written on.... ! 521: * 2) if the connection can be read, must enqueue events and handle errors, ! 522: * until the connection is writable. ! 523: */ ! 524: _XWaitForWritable(dpy) ! 525: Display *dpy; ! 526: { ! 527: unsigned long r_mask[MSKCNT]; ! 528: unsigned long w_mask[MSKCNT]; ! 529: int nfound; ! 530: ! 531: CLEARBITS(r_mask); ! 532: CLEARBITS(w_mask); ! 533: ! 534: while (1) { ! 535: BITSET(r_mask, dpy->fd); ! 536: BITSET(w_mask, dpy->fd); ! 537: ! 538: do { ! 539: #ifdef ISOCONN ! 540: /* ! 541: * Note, we shouldnt get any connections to us as we're a client, ! 542: * But the elements of style say we should check... ! 543: * and of course, a TDR ! 544: */ ! 545: int vecp; ! 546: char *vec[4]; ! 547: struct TSAPdisconnect tds; ! 548: struct TSAPdisconnect *td = &tds; ! 549: nfound = TNetAccept(&vecp, vec, dpy->fd + 1, r_mask, w_mask, ! 550: NULL, NOTOK, td); ! 551: #ifdef ISODEBUG ! 552: if (nfound < 0) { ! 553: int sverrno = errno; ! 554: fprintf(stderr, "TNetAcc err %d %s\n", errno, ! 555: TErrString(td->td_reason)); ! 556: errno = sverrno; ! 557: } ! 558: #endif /* ISODEBUG */ ! 559: #ifdef ISODEBUG ! 560: if (vecp > 0) { ! 561: fprintf(stderr, "Weirdness, connect to a client?\n"); ! 562: } ! 563: #endif ! 564: #else /* ISOCONN */ ! 565: nfound = select (dpy->fd + 1, r_mask, w_mask, NULL, NULL); ! 566: #endif /* ISOCONN */ ! 567: if (nfound < 0 && errno != EINTR) ! 568: (*_XIOErrorFunction)(dpy); ! 569: } while (nfound <= 0); ! 570: ! 571: if (ANYSET(r_mask)) { ! 572: char buf[BUFSIZE]; ! 573: long pend_not_register; ! 574: register long pend; ! 575: register xEvent *ev; ! 576: ! 577: /* find out how much data can be read */ ! 578: if (BytesReadable(dpy->fd, (char *) &pend_not_register) < 0) ! 579: (*_XIOErrorFunction)(dpy); ! 580: pend = pend_not_register; ! 581: ! 582: /* must read at least one xEvent; if none is pending, then ! 583: we'll just block waiting for it */ ! 584: if (pend < SIZEOF(xEvent)) pend = SIZEOF(xEvent); ! 585: ! 586: /* but we won't read more than the max buffer size */ ! 587: if (pend > BUFSIZE) pend = BUFSIZE; ! 588: ! 589: /* round down to an integral number of XReps */ ! 590: pend = (pend / SIZEOF(xEvent)) * SIZEOF(xEvent); ! 591: ! 592: _XRead (dpy, buf, pend); ! 593: ! 594: /* no space between comma and type or else macro will die */ ! 595: STARTITERATE (ev,xEvent, buf, (pend > 0), ! 596: (pend -= SIZEOF(xEvent))) { ! 597: if (ev->u.u.type == X_Error) ! 598: _XError (dpy, (xError *) ev); ! 599: else /* it's an event packet; enqueue it */ ! 600: _XEnq (dpy, ev); ! 601: } ! 602: ENDITERATE ! 603: } ! 604: if (ANYSET(w_mask)) ! 605: return; ! 606: } ! 607: } ! 608: ! 609: ! 610: _XWaitForReadable(dpy) ! 611: Display *dpy; ! 612: { ! 613: unsigned long r_mask[MSKCNT]; ! 614: int result; ! 615: ! 616: CLEARBITS(r_mask); ! 617: do { ! 618: #ifdef ISOCONN ! 619: /* ! 620: * Note, we shouldnt get any connections to us as we're a client, ! 621: * But the elements of style say we should check... ! 622: * and of course, a TDR ! 623: */ ! 624: int vecp; ! 625: char *vec[4]; ! 626: struct TSAPdisconnect tds; ! 627: struct TSAPdisconnect *td = &tds; ! 628: ! 629: BITSET(r_mask, dpy->fd); ! 630: result = TNetAccept(&vecp, vec, dpy->fd + 1, r_mask, NULL, NULL, ! 631: NOTOK, td); ! 632: #else /* ISOCONN */ ! 633: BITSET(r_mask, dpy->fd); ! 634: result = select(dpy->fd + 1, r_mask, NULL, NULL, NULL); ! 635: #endif /* ISOCONN */ ! 636: if (result == -1 && errno != EINTR) (*_XIOErrorFunction)(dpy); ! 637: } while (result <= 0); ! 638: } ! 639: ! 640: static int padlength[4] = {0, 3, 2, 1}; ! 641: ! 642: _XSendClientPrefix (dpy, client) ! 643: Display *dpy; ! 644: xConnClientPrefix *client; ! 645: { ! 646: /* ! 647: * Authorization string stuff.... Must always transmit multiple of 4 ! 648: * bytes. ! 649: */ ! 650: ! 651: char *auth_proto = ""; ! 652: int auth_length; ! 653: char *auth_string = ""; ! 654: int auth_strlen; ! 655: char pad[3]; ! 656: char buffer[BUFSIZ], *bptr; ! 657: ! 658: int bytes=0; ! 659: ! 660: auth_length = strlen(auth_proto); ! 661: auth_strlen = strlen(auth_string); ! 662: client->nbytesAuthProto = auth_length; ! 663: client->nbytesAuthString = auth_strlen; ! 664: ! 665: bytes = (SIZEOF(xConnClientPrefix) + ! 666: auth_length + padlength[auth_length & 3] + ! 667: auth_strlen + padlength[auth_strlen & 3]); ! 668: ! 669: bcopy(client, buffer, SIZEOF(xConnClientPrefix)); ! 670: bptr = buffer + SIZEOF(xConnClientPrefix); ! 671: if (auth_length) ! 672: { ! 673: bcopy(auth_proto, bptr, auth_length); ! 674: bptr += auth_length; ! 675: if (padlength[auth_length & 3]) ! 676: { ! 677: bcopy(pad, bptr, padlength[auth_length & 3]); ! 678: bptr += padlength[auth_length & 3]; ! 679: } ! 680: } ! 681: if (auth_strlen) ! 682: { ! 683: bcopy(auth_string, bptr, auth_strlen); ! 684: bptr += auth_strlen; ! 685: if (padlength[auth_strlen & 3]) ! 686: { ! 687: bcopy(pad, bptr, padlength[auth_strlen & 3]); ! 688: bptr += padlength[auth_strlen & 3]; ! 689: } ! 690: } ! 691: (void) WriteToServer(dpy->fd, buffer, bytes); ! 692: return; ! 693: } ! 694:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.