|
|
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.