📄 xconndis.c
字号:
#include "copyright.h"/* $XConsortium: XConnDis.c,v 11.36 88/09/16 11:09:34 jim Exp $ *//* Copyright Massachusetts Institute of Technology 1985, 1986 */#define NEED_EVENTS/* * THIS IS AN OS DEPENDENT FILE! It should work on 4.2BSD derived * systems. VMS and System V should plan to have their own version. */#include <stdio.h>#include <X11/Xos.h>#include "Xlibint.h"#include <sys/socket.h>#ifndef hpux#include <netinet/tcp.h>#endif#ifdef hpux#include <sys/utsname.h>#endif#ifdef UNIXCONN#include <sys/un.h>#ifndef X_UNIX_PATH#define X_UNIX_PATH "/tmp/.X11-unix/X"#endif /* X_UNIX_PATH */#endif /* UNIXCONN */void bcopy();#ifdef ISOCONN#include <isode/psap.h>#include <isode/tsap.h>#include <isode/isoservent.h>#ifdef ISODEBUGextern char *isodetcpath;int isodexbug = 0;#endif /* ISODEBUG */#endif /* ISOCONN */#ifdef ISOCONN/* * array of fd 2 family map so we can lookup right function below... * Its initialised at connection setup... */int fd2family[MAXSOCKS];/* * Globals for storing functions appropos each fd/socket type * UNIX_IO (0) map to sys calls * ISODE_IO (1) maps to my fns... */extern int read(), TReadFromServer();int (*readfn[])() = { read, TReadFromServer};extern int write(), TWriteToServer();int (*writefn[])() ={ write, TWriteToServer};extern int readv(), TReadvFromServer();int (*readvfn[])() ={ readv, TReadvFromServer};extern writev(), TWritevToServer();int (*writevfn[])() ={ writev, TWritevToServer};extern int UBytesReadable(), TBytesReadable();int (*ioctlfn[])() ={ UBytesReadable, TBytesReadable};extern int close(), TDiscFromServer();int (*closefn[])() ={ close, TDiscFromServer}; staticint iso_conn(server)char *server;{ struct TSAPconnect tcs; struct TSAPconnect *tc = &tcs; struct TSAPdisconnect tds; struct TSAPdisconnect *td = &tds; struct QOStype qo; struct QOStype *qos = &qo; AEI aei; struct PSAPaddr *pa, rpa, *mpa, rmpa; int ret; char *x; extern char *index();#ifdef ISODEBUG isodetcpath = ISODEPATH;#endif /* ISODEBUG *//* * Get their TSAP from their AEI */ if ((x = index(server, ':')) != NULL) { *(x++) = '\0'; aei = str2aei(server, x); } else { aei = str2aei(server, DEFAULTTSERVICE); } if (aei == NULLAEI) { fprintf(stderr, "No AEI for %s\n", server); return -1; } if ((pa = aei2addr (aei)) == NULLPA) { fprintf (stderr, "address translation failed"); return -1; } rpa = *pa; /* struct copy *//* * Get my address for completeness */ mpa = NULLPA; if (x != NULL) aei = str2aei(TLocalHostName(), x); else aei = str2aei(TLocalHostName(), DEFAULTTSERVICE); if (aei == NULLAEI) { fprintf (stderr, "my AEI lookup failed %s\n", TLocalHostName()); return -1; } if ((mpa = aei2addr (aei)) == NULLPA) { fprintf (stderr, "my address translation failed %s\n", TLocalHostName()); return -1; } rmpa = *mpa; /* struct copy *//* * No Xpedited required ! */ tc->tc_expedited = 0;/* * Just a guess - i dont understand * the comment in the documentation about TSDUsizes */ tc->tc_tsdusize = 16000; tc->tc_cc = 0; qos->qos_reliability = LOW_QUALITY; /* Well this is X after all */ ret = TConnRequest(&(rmpa.pa_addr.sa_addr), &(rpa.pa_addr.sa_addr), 0, 0, NULLCP, qos, tc, td); /* * Should map errors to perrors somehow??? */ if (ret == NOTOK) {#ifdef ISODEBUG if (isodexbug) fprintf(stderr, "TCR Failed %s\n", TErrString(td->td_reason));#endif /* ISODEBUG */ return -1; } else {#ifdef ISODEBUG if (isodexbug) fprintf(stderr, "client: isoconn ok\n");#endif /* ISODEBUG */ ret = tc->tc_sd; return ret; }}#endif /* ISOCONN *//* * Attempts to connect to server, given display name. Returns file descriptor * (network socket) or -1 if connection fails. The expanded display name * of the form hostname:number.screen ("::" if DECnet) is returned in a result * parameter. The screen number to use is also returned. */int _XConnectDisplay (display_name, expanded_name, prop_name, screen_num) char *display_name; char *expanded_name; /* return */ char *prop_name; /* return */ int *screen_num; /* return */{ char displaybuf[256]; /* Display string buffer */ register char *display_ptr; /* Display string buffer pointer */ register char *numbuf_ptr; /* Server number buffer pointer */ char *screen_ptr; /* Pointer for locating screen num */ int display_num; /* Display number */ struct sockaddr_in inaddr; /* INET socket address. */ unsigned long hostinetaddr; /* result of inet_addr of arpa addr */#ifdef UNIXCONN struct sockaddr_un unaddr; /* UNIX socket address. */#endif struct sockaddr *addr; /* address to connect to */ struct hostent *host_ptr; int addrlen; /* length of address */ extern char *getenv(); extern struct hostent *gethostbyname(); int fd; /* Network socket */ char numberbuf[16]; char *dot_ptr = NULL; /* Pointer to . before screen num */#ifdef DNETCONN int dnet = 0; char objname[20]; extern int dnet_conn();#endif#ifdef ISOCONN int isoconn = 0; char isochar = 'X'; /* * ISO Host name are "host:T-Namenumber" * T-Name = T (for TCP) or X (for X.25) should really be * TP4 or TP0 whathaveyou */#endif /* ISOCONN */ /* * Find the ':' seperator and extract the hostname and the * display number. * NOTE - if DECnet is to be used, the display name is formatted * as "host::number" */ (void) strncpy(displaybuf, display_name, sizeof(displaybuf)); if ((display_ptr = SearchString(displaybuf,':')) == NULL) return (-1);#ifdef DNETCONN if (*(display_ptr + 1) == ':') { dnet++; *(display_ptr++) = '\0'; }#endif#ifdef ISOCONN if ((*(display_ptr + 1) == 'X') || (*(display_ptr + 1) == 'T')) { isochar = *(display_ptr + 1); isoconn++; *(display_ptr++) = '\0'; }#endif /* ISOCONN */ *(display_ptr++) = '\0'; /* displaybuf now contains only a null-terminated host name, and * display_ptr points to the display number. * If the display number is missing there is an error. */ if (*display_ptr == '\0') return(-1); /* * Build a string of the form <display-number>.<screen-number> in * numberbuf, using ".0" as the default. */ screen_ptr = display_ptr; /* points to #.#.propname */ numbuf_ptr = numberbuf; /* beginning of buffer */ while (*screen_ptr != '\0') { if (*screen_ptr == '.') { /* either screen or prop */ if (dot_ptr) { /* then found prop_name */ screen_ptr++; break; } dot_ptr = numbuf_ptr; /* found screen_num */ *(screen_ptr++) = '\0'; *(numbuf_ptr++) = '.'; } else { *(numbuf_ptr++) = *(screen_ptr++); } } /* * If the spec doesn't include a screen number, add ".0" (or "0" if * only "." is present.) */ if (dot_ptr == NULL) { /* no screen num or prop */ dot_ptr = numbuf_ptr; *(numbuf_ptr++) = '.'; *(numbuf_ptr++) = '0'; } else { if (*(numbuf_ptr - 1) == '.') *(numbuf_ptr++) = '0'; } *numbuf_ptr = '\0'; /* * Return the screen number and property names in the result parameters */ *screen_num = atoi(dot_ptr + 1); strcpy (prop_name, screen_ptr); /* * Convert the server number string to an integer. */ display_num = atoi(display_ptr); /* * If the display name is missing, use current host. */ if (displaybuf[0] == '\0')#ifdef DNETCONN if (dnet) (void) strcpy (displaybuf, "0"); else#endif#ifdef UNIXCONN ; /* Do nothing if UNIX DOMAIN. Will be handled below. */#else#ifdef hpux /* * same host name crock as in server and xinit. */ { struct utsname name; uname(&name); strcpy(displaybuf, name.nodename); }#else (void) gethostname (displaybuf, sizeof(displaybuf));#endif /* hpux */#endif /* UNIXCONN else TCPCONN (assumed) */#ifdef DNETCONN if (dnet) { /* * build the target object name. */ sprintf(objname, "X$X%d", display_num); /* * Attempt to open the DECnet connection, return -1 if fails. */ if ((fd = dnet_conn(displaybuf, objname, SOCK_STREAM, 0, 0, 0, 0)) < 0) return(-1); /* errno set by dnet_conn. */#ifdef ISOCONN else fd2family[fd] = UNIX_IO;#endif /* ISOCONN */ } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -