📄 xconndis.c
字号:
addr = (struct sockaddr *) &inaddr; addrlen = sizeof (struct sockaddr_in); inaddr.sin_port = X_TCP_PORT + idisplay; inaddr.sin_port = htons (inaddr.sin_port); /* may be funky macro */ /* * Open the network connection. */ do { if ((fd = socket ((int) addr->sa_family, SOCK_STREAM, 0)) < 0) { return -1; } /* * turn off TCP coalescence */#ifdef TCP_NODELAY { int tmp = 1; setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tmp, sizeof (int)); }#endif /* * connect to the socket; if there is no X server or if the backlog has * been reached, then ECONNREFUSED will be returned. */ if (connect (fd, addr, addrlen) < 0) { int olderrno = errno; (void) close (fd); if (olderrno != ECONNREFUSED || retries <= 0) { errno = olderrno; return -1; } sleep (1); } else { break; } } while (retries-- > 0); /* * Success! So, save the auth information */#ifdef CRAY#ifdef OLDTCP len = sizeof(inaddr.sin_addr);#else len = SIZEOF_in_addr;#endif /* OLDTCP */ cp = (char *) &inaddr.sin_addr;#else /* else not CRAY */ len = sizeof(inaddr.sin_addr.s_addr); cp = (char *) &inaddr.sin_addr.s_addr;#endif /* CRAY */ /* * We are special casing the BSD hack localhost address * 127.0.0.1, since this address shouldn't be copied to * other machines. So, we simply omit generating the auth info * since we set it to the local machine before calling this routine! */ if (!((len == 4) && (cp[0] == 127) && (cp[1] == 0) && (cp[2] == 0) && (cp[3] == 1))) { *saddrp = Xmalloc (len); if (*saddrp) { *saddrlenp = len; bcopy (cp, *saddrp, len); *familyp = FamilyInternet; } else { *saddrlenp = 0; } } return fd;}#undef INVALID_INETADDR#endif /* TCPCONN *//***************************************************************************** * * * Connection Utility Routines * * * *****************************************************************************//* * Disconnect from server. */int _XDisconnectDisplay (server) int server;{ (void) close(server); return 0;}/* * This is an OS dependent routine which: * 1) returns as soon as the connection can be written on.... * 2) if the connection can be read, must enqueue events and handle errors, * until the connection is writable. */_XWaitForWritable(dpy) Display *dpy;{ unsigned long r_mask[MSKCNT]; unsigned long w_mask[MSKCNT]; int nfound; CLEARBITS(r_mask); CLEARBITS(w_mask); while (1) { BITSET(r_mask, dpy->fd); BITSET(w_mask, dpy->fd); do { nfound = select (dpy->fd + 1, r_mask, w_mask, (char *)NULL, (char *)NULL); if (nfound < 0 && errno != EINTR) _XIOError(dpy); } while (nfound <= 0); if (_XANYSET(r_mask)) { char buf[BUFSIZE]; long pend_not_register; register long pend; register xEvent *ev; /* find out how much data can be read */ if (BytesReadable(dpy->fd, (char *) &pend_not_register) < 0) _XIOError(dpy); pend = pend_not_register; /* must read at least one xEvent; if none is pending, then we'll just block waiting for it */ if (pend < SIZEOF(xEvent)) pend = SIZEOF(xEvent); /* but we won't read more than the max buffer size */ if (pend > BUFSIZE) pend = BUFSIZE; /* round down to an integral number of XReps */ pend = (pend / SIZEOF(xEvent)) * SIZEOF(xEvent); _XRead (dpy, buf, pend); /* no space between comma and type or else macro will die */ STARTITERATE (ev,xEvent, buf, (pend > 0), (pend -= SIZEOF(xEvent))) { if (ev->u.u.type == X_Error) _XError (dpy, (xError *) ev); else /* it's an event packet; enqueue it */ _XEnq (dpy, ev); } ENDITERATE } if (_XANYSET(w_mask)) return; }}_XWaitForReadable(dpy) Display *dpy;{ unsigned long r_mask[MSKCNT]; int result; CLEARBITS(r_mask); do { BITSET(r_mask, dpy->fd); result = select(dpy->fd + 1, r_mask, (char *)NULL, (char *)NULL, (char *)NULL); if (result == -1 && errno != EINTR) _XIOError(dpy); } while (result <= 0);}static int padlength[4] = {0, 3, 2, 1}; /* make sure auth is multiple of 4 */Bool_XSendClientPrefix (dpy, client, auth_proto, auth_string) Display *dpy; xConnClientPrefix *client; /* contains count for auth_* */ char *auth_proto, *auth_string; /* NOT null-terminated */{ int auth_length = client->nbytesAuthProto; int auth_strlen = client->nbytesAuthString; char padbuf[3]; /* for padding to 4x bytes */ int pad; struct iovec iovarray[5], *iov = iovarray; int niov = 0; int len = 0;#define add_to_iov(b,l) \ { iov->iov_base = (b); iov->iov_len = (l); iov++, niov++; len += (l); } add_to_iov ((caddr_t) client, SIZEOF(xConnClientPrefix)); /* * write authorization protocol name and data */ if (auth_length > 0) { add_to_iov (auth_proto, auth_length); pad = padlength [auth_length & 3]; if (pad) add_to_iov (padbuf, pad); } if (auth_strlen > 0) { add_to_iov (auth_string, auth_strlen); pad = padlength [auth_strlen & 3]; if (pad) add_to_iov (padbuf, pad); }#undef add_to_iov len -= WritevToServer (dpy->fd, iovarray, niov); /* * Set the connection non-blocking since we use select() to block. */ /* ultrix reads hang on Unix sockets, hpux reads fail */#if defined(O_NONBLOCK) && (!defined(ultrix) && !defined(hpux) && !defined(AIXV3)) (void) fcntl (dpy->fd, F_SETFL, O_NONBLOCK);#else#ifdef FIOSNBIO { int arg = 1; ioctl (dpy->fd, FIOSNBIO, &arg); }#else#if defined(AIXV3) && defined(FIONBIO) { int arg; arg = 1; ioctl(dpy->fd, FIONBIO, &arg); }#else (void) fcntl (dpy->fd, F_SETFL, FNDELAY);#endif#endif#endif return len == 0;}#ifdef STREAMSCONN#ifdef SVR4#include <tiuser.h>#else#undef HASXDMAUTH#endif#endif#ifdef SECURE_RPC#include <rpc/rpc.h>#ifdef ultrix#include <time.h>#include <rpc/auth_des.h>#endif#endif/* * First, a routine for setting authorization data */static int xauth_namelen = 0;static char *xauth_name = NULL; /* NULL means use default mechanism */static int xauth_datalen = 0;static char *xauth_data = NULL; /* NULL means get default data *//* * This is a list of the authorization names which Xlib currently supports. * Xau will choose the file entry which matches the earliest entry in this * array, allowing us to prioritize these in terms of the most secure first */static char *default_xauth_names[] = {#ifdef SECURE_RPC "SUN-DES-1",#endif#ifdef HASXDMAUTH "XDM-AUTHORIZATION-1",#endif "MIT-MAGIC-COOKIE-1"};static int default_xauth_lengths[] = {#ifdef SECURE_RPC 9, /* strlen ("SUN-DES-1") */#endif#ifdef HASXDMAUTH 19, /* strlen ("XDM-AUTHORIZATION-1") */#endif 18 /* strlen ("MIT-MAGIC-COOKIE-1") */};#define NUM_DEFAULT_AUTH (sizeof (default_xauth_names) / sizeof (default_xauth_names[0])) static char **xauth_names = default_xauth_names;static int *xauth_lengths = default_xauth_lengths;static int xauth_names_length = NUM_DEFAULT_AUTH;void XSetAuthorization (name, namelen, data, datalen) int namelen, datalen; /* lengths of name and data */ char *name, *data; /* NULL or arbitrary array of bytes */{ char *tmpname, *tmpdata; if (xauth_name) Xfree (xauth_name); /* free any existing data */ if (xauth_data) Xfree (xauth_data); xauth_name = xauth_data = NULL; /* mark it no longer valid */ xauth_namelen = xauth_datalen = 0; if (namelen < 0) namelen = 0; /* check for bogus inputs */ if (datalen < 0) datalen = 0; /* maybe should return? */ if (namelen > 0) { /* try to allocate space */ tmpname = Xmalloc ((unsigned) namelen); if (!tmpname) return; bcopy (name, tmpname, namelen); } else { tmpname = NULL; } if (datalen > 0) { tmpdata = Xmalloc ((unsigned) datalen); if (!tmpdata) { if (tmpname) (void) Xfree (tmpname); return; } bcopy (data, tmpdata, datalen); } else { tmpdata = NULL; } xauth_name = tmpname; /* and store the suckers */ xauth_namelen = namelen; if (tmpname) { xauth_names = &xauth_name; xauth_lengths = &xauth_namelen; xauth_names_length = 1; } else { xauth_names = default_xauth_names; xauth_lengths = default_xauth_lengths; xauth_names_length = NUM_DEFAULT_AUTH; } xauth_data = tmpdata; xauth_datalen = datalen; return;}#ifdef SECURE_RPC/* * Create a credential that we can send to the X server. */static intauth_ezencode(servername, window, cred_out, len) char *servername; int window; char *cred_out; int *len;{ AUTH *a; XDR xdr; a = authdes_create(servername, window, NULL, NULL); if (a == (AUTH *)NULL) { perror("auth_create"); return 0; } xdrmem_create(&xdr, cred_out, *len, XDR_ENCODE); if (AUTH_MARSHALL(a, &xdr) == FALSE) { perror("auth_marshall"); AUTH_DESTROY(a); return 0; } *len = xdr_getpos(&xdr); AUTH_DESTROY(a); return 1;}#endifstatic voidGetAuthorization(fd, family, saddr, saddrlen, idisplay, auth_namep, auth_namelenp, auth_datap, auth_datalenp) int fd; int family; int saddrlen; int idisplay; char *saddr; char **auth_namep; /* RETURN */ int *auth_namelenp; /* RETURN */ char **auth_datap; /* RETURN */ int *auth_datalenp; /* RETURN */{#ifdef SECURE_RPC char rpc_cred[MAX_AUTH_BYTES];#endif#ifdef HASXDMAUTH char xdmcp_data[192/8];#endif char *auth_name; int auth_namelen; char *auth_data; int auth_datalen; Xauth *authptr = NULL;/* * Look up the authorization protocol name and data if necessary. */ if (xauth_name && xauth_data) { auth_namelen = xauth_namelen; auth_name = xauth_name; auth_datalen = xauth_datalen; auth_data = xauth_data; } else { char dpynumbuf[40]; /* big enough to hold 2^64 and more */ (void) sprintf (dpynumbuf, "%d", idisplay); authptr = XauGetBestAuthByAddr ((unsigned short) family, (unsigned short) saddrlen, saddr, (unsigned short) strlen (dpynumbuf), dpynumbuf, xauth_names_length, xauth_names, xauth_lengths); if (authptr) { auth_namelen = authptr->name_length; auth_name = (char *)authptr->name; auth_datalen = authptr->data_length; auth_data = (char *)authptr->data; } else { auth_namelen = 0; auth_name = NULL; auth_datalen = 0; auth_data = NULL; } }#ifdef HASXDMAUTH /* * build XDM-AUTHORIZATION-1 data */ if (auth_namelen == 19 && !strncmp (auth_name, "XDM-AUTHORIZATION-1", 19)) { int j; long now; for (j = 0; j < 8; j++) xdmcp_data[j] = auth_data[j];#ifdef STREAMSCONN /* && SVR4 */ { int i; struct netbuf netb; char addrret[1024]; netb.maxlen = sizeof addrret; netb.buf = addrret; if (t_getname (fd, &netb, LOCALNAME) == -1) t_error ("t_getname"); /* * XXX - assumes that the return data * are in a struct sockaddr_in, and that * the data structure is layed out in * the normal fashion. This WILL NOT WORK * on a non 32-bit machine (same in Xstreams.c) */ for (i = 4; i < 8; i++) xdmcp_data[j++] = netb.buf[i]; for (i = 2; i < 4; i++) xdmcp_data[j++] = netb.buf[i]; }#else { unsigned long addr; unsigned short port;#ifdef TCPCONN int addrlen; struct sockaddr_in in_addr; addrlen = sizeof (in_addr); if (getsockname (fd, (struct sockaddr *) &in_addr, &addrlen) != -1 && addrlen >= sizeof in_addr && in_addr.sin_family == AF_INET) { addr = ntohl (in_addr.sin_addr.s_addr); port = ntohs (in_addr.sin_port); } else#endif { static unsigned long unix_addr = 0xFFFFFFFF; addr = unix_addr--; port = getpid (); } xdmcp_data[j++] = (addr >> 24) & 0xFF; xdmcp_data[j++] = (addr >> 16) & 0xFF; xdmcp_data[j++] = (addr >> 8) & 0xFF; xdmcp_data[j++] = (addr >> 0) & 0xFF; xdmcp_data[j++] = (port >> 8) & 0xFF; xdmcp_data[j++] = (port >> 0) & 0xFF; }#endif time (&now); xdmcp_data[j++] = (now >> 24) & 0xFF; xdmcp_data[j++] = (now >> 16) & 0xFF; xdmcp_data[j++] = (now >> 8) & 0xFF; xdmcp_data[j++] = (now >> 0) & 0xFF; while (j < 192 / 8) xdmcp_data[j++] = 0; XdmcpWrap (xdmcp_data, auth_data + 8, xdmcp_data, j); auth_data = xdmcp_data; auth_datalen = j; }#endif /* HASXDMAUTH */#ifdef SECURE_RPC /* * The SUN-DES-1 authorization protocol uses the * "secure RPC" mechanism in SunOS 4.0+. */ if (auth_namelen == 9 && !strncmp(auth_name, "SUN-DES-1", 9)) { char servernetname[MAXNETNAMELEN + 1]; /* * Copy over the server's netname from the authorization * data field filled in by XauGetAuthByAddr(). */ if (auth_datalen > MAXNETNAMELEN) { auth_datalen = 0; auth_data = NULL; } else { bcopy(auth_data, servernetname, auth_datalen); servernetname[auth_datalen] = '\0'; auth_datalen = sizeof (rpc_cred); if (auth_ezencode(servernetname, 100, rpc_cred, &auth_datalen)) auth_data = rpc_cred; else auth_data = NULL; } }#endif if (saddr) Xfree (saddr); if (*auth_namelenp = auth_namelen) { if (*auth_namep = Xmalloc(auth_namelen)) bcopy(auth_name, *auth_namep, auth_namelen); else *auth_namelenp = 0; } else *auth_namep = NULL; if (*auth_datalenp = auth_datalen) { if (*auth_datap = Xmalloc(auth_datalen)) bcopy(auth_data, *auth_datap, auth_datalen); else *auth_datalenp = 0; } else *auth_datap = NULL; if (authptr) XauDisposeAuth (authptr);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -