|
|
1.1 ! root 1: #include "copyright.h" ! 2: /* $Header: XConnDis.c,v 11.21 87/09/13 23:03:07 toddb Exp $ */ ! 3: /* Copyright Massachusetts Institute of Technology 1985, 1986 */ ! 4: #define NEED_EVENTS ! 5: #include <stdio.h> ! 6: #include "Xlibint.h" ! 7: #include <strings.h> ! 8: ! 9: void bcopy(); ! 10: /* ! 11: * Attempts to connect to server, given display name. Returns file descriptor ! 12: * (network socket) or -1 if connection fails. The expanded display name ! 13: * of the form hostname:number.screen ("::" if DECnet) is returned in a result ! 14: * parameter. The screen number to use is also returned. ! 15: */ ! 16: int _XConnectDisplay (display_name, expanded_name, screen_num) ! 17: ! 18: char *display_name; ! 19: char *expanded_name; /* return */ ! 20: int *screen_num; /* return */ ! 21: ! 22: { ! 23: struct utsname uts; ! 24: char displaybuf[256]; /* Display string buffer */ ! 25: char ipcstring[256]; /* ipcopen string */ ! 26: register char *display_ptr; /* Display string buffer pointer */ ! 27: register char *numbuf_ptr; /* Server number buffer pointer */ ! 28: char *screen_ptr; /* Pointer for locating screen num */ ! 29: int display_num; /* Display number */ ! 30: int fd; /* Network socket */ ! 31: int port; ! 32: char numberbuf[16]; ! 33: char *dot_ptr = NULL; /* Pointer to . before screen num */ ! 34: ! 35: /* ! 36: * Find the ':' seperator and extract the hostname and the ! 37: * display number. ! 38: */ ! 39: (void) strncpy(displaybuf, display_name, sizeof(displaybuf)); ! 40: if ((display_ptr = SearchString(displaybuf,':')) == NULL) return (-1); ! 41: *(display_ptr++) = '\0'; ! 42: ! 43: /* displaybuf now contains only a null-terminated host name, and ! 44: * display_ptr points to the display number. ! 45: * If the display number is missing there is an error. */ ! 46: ! 47: if (*display_ptr == '\0') return(-1); ! 48: ! 49: /* ! 50: * Build a string of the form <display-number>.<screen-number> in ! 51: * numberbuf, using ".0" as the default. ! 52: */ ! 53: screen_ptr = display_ptr; ! 54: numbuf_ptr = numberbuf; ! 55: while (*screen_ptr != '\0') { ! 56: if (*screen_ptr == '.') { ! 57: dot_ptr = numbuf_ptr; ! 58: *(screen_ptr++) = '\0'; ! 59: *(numbuf_ptr++) = '.'; ! 60: } else { ! 61: *(numbuf_ptr++) = *(screen_ptr++); ! 62: } ! 63: } ! 64: ! 65: /* ! 66: * If the spec doesn't include a screen number, add ".0" (or "0" if ! 67: * only "." is present.) ! 68: */ ! 69: if (dot_ptr == NULL) { ! 70: dot_ptr = numbuf_ptr; ! 71: *(numbuf_ptr++) = '.'; ! 72: *(numbuf_ptr++) = '0'; ! 73: } else { ! 74: if (*(numbuf_ptr - 1) == '.') ! 75: *(numbuf_ptr++) = '0'; ! 76: } ! 77: *numbuf_ptr = '\0'; ! 78: ! 79: /* ! 80: * Return the screen number in the result parameter ! 81: */ ! 82: *screen_num = atoi(dot_ptr + 1); ! 83: ! 84: /* ! 85: * Convert the server number string to an integer. ! 86: */ ! 87: display_num = atoi(display_ptr); ! 88: port = display_num + X_TCP_PORT; ! 89: ! 90: /* ! 91: * If the display name is missing, use current host. ! 92: */ ! 93: if (displaybuf[0] == '\0') { ! 94: sprintf(ipcstring, "/cs/tcp.%d", port); ! 95: /* ! 96: * Read in the local system name ! 97: */ ! 98: uname(&uts); ! 99: strcpy(displaybuf, uts.sysname); ! 100: } else ! 101: sprintf(ipcstring, "/cs/tcp!%s!tcp.%d", displaybuf, port); ! 102: if ((fd = ipcopen(ipcstring, "heavy")) == -1) { ! 103: (void) close (fd); ! 104: return(-1); ! 105: } ! 106: ! 107: /* ! 108: * Return the id if the connection succeeded. Rebuild the expanded ! 109: * spec and return it in the result parameter. ! 110: */ ! 111: display_ptr = displaybuf; ! 112: while (*(++display_ptr) != '\0') ! 113: ; ! 114: *(display_ptr++) = ':'; ! 115: numbuf_ptr = numberbuf; ! 116: while (*numbuf_ptr != '\0') ! 117: *(display_ptr++) = *(numbuf_ptr++); ! 118: *display_ptr = '\0'; ! 119: (void) strcpy(expanded_name, displaybuf); ! 120: return(fd); ! 121: ! 122: } ! 123: ! 124: /* ! 125: * Disconnect from server. ! 126: */ ! 127: ! 128: int _XDisconnectDisplay (server) ! 129: ! 130: int server; ! 131: ! 132: { ! 133: (void) close(server); ! 134: } ! 135: ! 136: #undef NULL ! 137: #define NULL ((char *) 0) ! 138: /* ! 139: * This is an OS dependent routine which: ! 140: * 1) returns as soon as the connection can be written on.... ! 141: * 2) if the connection can be read, must enqueue events and handle errors, ! 142: * until the connection is writable. ! 143: */ ! 144: _XWaitForWritable(dpy) ! 145: Display *dpy; ! 146: { ! 147: unsigned long r_mask[MSKCNT]; ! 148: unsigned long w_mask[MSKCNT]; ! 149: int nfound; ! 150: ! 151: CLEARBITS(r_mask); ! 152: CLEARBITS(w_mask); ! 153: ! 154: while (1) { ! 155: BITSET(r_mask, dpy->fd); ! 156: BITSET(w_mask, dpy->fd); ! 157: ! 158: do { ! 159: nfound = select (dpy->fd + 1, r_mask, w_mask, 0x7fffffff); ! 160: if (nfound < 0 && errno != EINTR) ! 161: (*_XIOErrorFunction)(dpy); ! 162: } while (nfound <= 0); ! 163: ! 164: if (ANYSET(r_mask)) { ! 165: char buf[BUFSIZE]; ! 166: long pend_not_register; ! 167: register long pend; ! 168: register xEvent *ev; ! 169: ! 170: /* find out how much data can be read */ ! 171: if (BytesReadable(dpy->fd, (char *) &pend_not_register) < 0) ! 172: (*_XIOErrorFunction)(dpy); ! 173: pend = pend_not_register; ! 174: ! 175: /* must read at least one xEvent; if none is pending, then ! 176: we'll just block waiting for it */ ! 177: again: ! 178: if (pend < sizeof(xEvent)) pend = sizeof (xEvent); ! 179: ! 180: /* but we won't read more than the max buffer size */ ! 181: if (pend > BUFSIZE) pend = BUFSIZE; ! 182: ! 183: /* round down to an integral number of XReps */ ! 184: pend = (pend / sizeof (xEvent)) * sizeof (xEvent); ! 185: ! 186: _XRead (dpy, buf, pend); ! 187: for (ev = (xEvent *) buf; pend > 0; ev++, pend -= sizeof(xEvent)) ! 188: { ! 189: if (ev->u.u.type == X_Error) ! 190: _XError (dpy, (xError *) ev); ! 191: else /* it's an event packet; enqueue it */ ! 192: _XEnq (dpy, ev); ! 193: } ! 194: nap(1); ! 195: if (BytesReadable(dpy->fd, (char *) &pend_not_register) < 0) ! 196: (*_XIOErrorFunction)(dpy); ! 197: pend = pend_not_register; ! 198: if(pend != 0) ! 199: goto again; ! 200: } ! 201: if (ANYSET(w_mask)) ! 202: return; ! 203: } ! 204: } ! 205: ! 206: ! 207: _XWaitForReadable(dpy) ! 208: Display *dpy; ! 209: { ! 210: unsigned long r_mask[MSKCNT]; ! 211: int result; ! 212: ! 213: CLEARBITS(r_mask); ! 214: do { ! 215: BITSET(r_mask, dpy->fd); ! 216: result = select(dpy->fd + 1, r_mask, NULL, 0x7fffffff); ! 217: if (result == -1 && errno != EINTR) (*_XIOErrorFunction)(dpy); ! 218: } while (result <= 0); ! 219: } ! 220: ! 221: static int padlength[4] = {0, 3, 2, 1}; ! 222: ! 223: _XSendClientPrefix (dpy, client) ! 224: Display *dpy; ! 225: xConnClientPrefix *client; ! 226: { ! 227: /* ! 228: * Authorization string stuff.... Must always transmit multiple of 4 ! 229: * bytes. ! 230: */ ! 231: ! 232: char *auth_proto = ""; ! 233: int auth_length; ! 234: char *auth_string = ""; ! 235: int auth_strlen; ! 236: char pad[3]; ! 237: char buffer[BUFSIZ], *bptr; ! 238: ! 239: int bytes=0; ! 240: ! 241: auth_length = strlen(auth_proto); ! 242: auth_strlen = strlen(auth_string); ! 243: client->nbytesAuthProto = auth_length; ! 244: client->nbytesAuthString = auth_strlen; ! 245: ! 246: bytes = (sizeof(xConnClientPrefix) + ! 247: auth_length + padlength[auth_length & 3] + ! 248: auth_strlen + padlength[auth_strlen & 3]); ! 249: ! 250: bcopy(client, buffer, sizeof(xConnClientPrefix)); ! 251: bptr = buffer + sizeof(xConnClientPrefix); ! 252: if (auth_length) ! 253: { ! 254: bcopy(auth_proto, bptr, auth_length); ! 255: bptr += auth_length; ! 256: if (padlength[auth_length & 3]) ! 257: { ! 258: bcopy(pad, bptr, padlength[auth_length & 3]); ! 259: bptr += padlength[auth_length & 3]; ! 260: } ! 261: } ! 262: if (auth_strlen) ! 263: { ! 264: bcopy(auth_string, bptr, auth_strlen); ! 265: bptr += auth_strlen; ! 266: if (padlength[auth_strlen & 3]) ! 267: { ! 268: bcopy(pad, bptr, padlength[auth_strlen & 3]); ! 269: bptr += padlength[auth_strlen & 3]; ! 270: } ! 271: } ! 272: (void) WriteToServer(dpy->fd, buffer, bytes); ! 273: return; ! 274: } ! 275:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.