|
|
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: {
1.1.1.2 ! root 23: struct utsname uts;
1.1 root 24: char displaybuf[256]; /* Display string buffer */
1.1.1.2 ! root 25: char ipcstring[256]; /* ipcopen string */
1.1 root 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 */
1.1.1.2 ! root 31: int port;
1.1 root 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);
1.1.1.2 ! root 88: port = display_num + X_TCP_PORT;
1.1 root 89:
90: /*
91: * If the display name is missing, use current host.
92: */
1.1.1.2 ! root 93: if (displaybuf[0] == '\0') {
! 94: sprintf(ipcstring, "/cs/tcp.%d", port);
1.1 root 95: /*
1.1.1.2 ! root 96: * Read in the local system name
1.1 root 97: */
1.1.1.2 ! root 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) {
1.1 root 103: (void) close (fd);
1.1.1.2 ! root 104: return(-1);
! 105: }
! 106:
1.1 root 107: /*
108: * set it non-blocking. This is so we can read data when blocked
109: * for writing in the library.
110: */
1.1.1.2 ! root 111: (void) ioctl(fd, FIOWNBLK, 0);
1.1 root 112: /*
113: * Return the id if the connection succeeded. Rebuild the expanded
114: * spec and return it in the result parameter.
115: */
116: display_ptr = displaybuf;
117: while (*(++display_ptr) != '\0')
118: ;
119: *(display_ptr++) = ':';
120: numbuf_ptr = numberbuf;
121: while (*numbuf_ptr != '\0')
122: *(display_ptr++) = *(numbuf_ptr++);
123: *display_ptr = '\0';
124: (void) strcpy(expanded_name, displaybuf);
125: return(fd);
126:
127: }
128:
129: /*
130: * Disconnect from server.
131: */
132:
133: int _XDisconnectDisplay (server)
134:
135: int server;
136:
137: {
138: (void) close(server);
139: }
140:
141: #undef NULL
142: #define NULL ((char *) 0)
143: /*
144: * This is an OS dependent routine which:
145: * 1) returns as soon as the connection can be written on....
146: * 2) if the connection can be read, must enqueue events and handle errors,
147: * until the connection is writable.
148: */
149: _XWaitForWritable(dpy)
150: Display *dpy;
151: {
152: unsigned long r_mask[MSKCNT];
153: unsigned long w_mask[MSKCNT];
154: int nfound;
155:
156: CLEARBITS(r_mask);
157: CLEARBITS(w_mask);
158:
159: while (1) {
160: BITSET(r_mask, dpy->fd);
161: BITSET(w_mask, dpy->fd);
162:
163: do {
1.1.1.2 ! root 164: nfound = select (dpy->fd + 1, r_mask, w_mask, 0x6fffffff);
1.1 root 165: if (nfound < 0 && errno != EINTR)
166: (*_XIOErrorFunction)(dpy);
167: } while (nfound <= 0);
168:
169: if (ANYSET(r_mask)) {
170: char buf[BUFSIZE];
171: long pend_not_register;
172: register long pend;
173: register xEvent *ev;
174:
175: /* find out how much data can be read */
176: if (BytesReadable(dpy->fd, (char *) &pend_not_register) < 0)
177: (*_XIOErrorFunction)(dpy);
178: pend = pend_not_register;
179:
180: /* must read at least one xEvent; if none is pending, then
181: we'll just block waiting for it */
182: if (pend < sizeof(xEvent)) pend = sizeof (xEvent);
183:
184: /* but we won't read more than the max buffer size */
185: if (pend > BUFSIZE) pend = BUFSIZE;
186:
187: /* round down to an integral number of XReps */
188: pend = (pend / sizeof (xEvent)) * sizeof (xEvent);
189:
190: _XRead (dpy, buf, pend);
191: for (ev = (xEvent *) buf; pend > 0; ev++, pend -= sizeof(xEvent))
192: {
193: if (ev->u.u.type == X_Error)
194: _XError (dpy, (xError *) ev);
195: else /* it's an event packet; enqueue it */
196: _XEnq (dpy, ev);
197: }
198: }
199: if (ANYSET(w_mask))
200: return;
201: }
202: }
203:
204:
205: _XWaitForReadable(dpy)
206: Display *dpy;
207: {
208: unsigned long r_mask[MSKCNT];
209: int result;
210:
211: CLEARBITS(r_mask);
212: do {
213: BITSET(r_mask, dpy->fd);
1.1.1.2 ! root 214: result = select(dpy->fd + 1, r_mask, NULL, 0x7fffffff);
1.1 root 215: if (result == -1 && errno != EINTR) (*_XIOErrorFunction)(dpy);
216: } while (result <= 0);
217: }
218:
219: static int padlength[4] = {0, 3, 2, 1};
220:
221: _XSendClientPrefix (dpy, client)
222: Display *dpy;
223: xConnClientPrefix *client;
224: {
225: /*
226: * Authorization string stuff.... Must always transmit multiple of 4
227: * bytes.
228: */
229:
230: char *auth_proto = "";
231: int auth_length;
232: char *auth_string = "";
233: int auth_strlen;
234: char pad[3];
235: char buffer[BUFSIZ], *bptr;
236:
237: int bytes=0;
238:
239: auth_length = strlen(auth_proto);
240: auth_strlen = strlen(auth_string);
241: client->nbytesAuthProto = auth_length;
242: client->nbytesAuthString = auth_strlen;
243:
244: bytes = (sizeof(xConnClientPrefix) +
245: auth_length + padlength[auth_length & 3] +
246: auth_strlen + padlength[auth_strlen & 3]);
247:
248: bcopy(client, buffer, sizeof(xConnClientPrefix));
249: bptr = buffer + sizeof(xConnClientPrefix);
250: if (auth_length)
251: {
252: bcopy(auth_proto, bptr, auth_length);
253: bptr += auth_length;
254: if (padlength[auth_length & 3])
255: {
256: bcopy(pad, bptr, padlength[auth_length & 3]);
257: bptr += padlength[auth_length & 3];
258: }
259: }
260: if (auth_strlen)
261: {
262: bcopy(auth_string, bptr, auth_strlen);
263: bptr += auth_strlen;
264: if (padlength[auth_strlen & 3])
265: {
266: bcopy(pad, bptr, padlength[auth_strlen & 3]);
267: bptr += padlength[auth_strlen & 3];
268: }
269: }
270: (void) WriteToServer(dpy->fd, buffer, bytes);
271: return;
272: }
273:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.