⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xconndis.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $XConsortium: XConnDis.c,v 11.88 91/12/17 17:55:57 rws Exp $ * * Copyright 1989 Massachusetts Institute of Technology * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in advertising * or publicity pertaining to distribution of the software without specific, * written prior permission.  M.I.T. makes no representations about the * suitability of this software for any purpose.  It is provided "as is" * without express or implied warranty. * * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * *  * This file contains operating system dependencies. */#define NEED_EVENTS#include <X11/Xlibint.h>#include <X11/Xos.h>#include "Xlibnet.h"#include <X11/Xauth.h>#include <stdio.h>#include <ctype.h>#ifdef DNETCONN#include <netdnet/dn.h>#include <netdnet/dnetdb.h>#endif#ifdef STREAMSCONN#define select _XSelect#endif#ifndef X_CONNECTION_RETRIES		/* number retries on ECONNREFUSED */#define X_CONNECTION_RETRIES 5#endif#ifdef DNETCONNstatic int MakeDECnetConnection();#endif#ifdef UNIXCONNstatic int MakeUNIXSocketConnection();#endif#ifdef TCPCONNstatic int MakeTCPConnection();#endif#ifdef STREAMSCONNextern int _XMakeStreamsConnection();#endifstatic void GetAuthorization();static char *copystring (src, len)    char *src;    int len;{    char *dst = Xmalloc (len + 1);    if (dst) {	strncpy (dst, src, len);	dst[len] = '\0';    }    return dst;}/*  * Attempts to connect to server, given display name. Returns file descriptor * (network socket) or -1 if connection fails.  Display names may be of the * following format: * *     [hostname] : [:] displaynumber [.screennumber] * * The second colon indicates a DECnet style name.  No hostname is interpretted * as the most efficient local connection to a server on the same machine.   * This is usually: * *     o  shared memory *     o  local stream *     o  UNIX domain socket *     o  TCP to local host */int _XConnectDisplay (display_name, fullnamep, dpynump, screenp,		      auth_namep, auth_namelenp, auth_datap, auth_datalenp)    char *display_name;    char **fullnamep;			/* RETURN */    int *dpynump;			/* RETURN */    int *screenp;			/* RETURN */    char **auth_namep;			/* RETURN */    int *auth_namelenp;			/* RETURN */    char **auth_datap;			/* RETURN */    int *auth_datalenp;			/* RETURN */{    int family;    int saddrlen;    char *saddr;    char *lastp, *p;			/* char pointers */    char *phostname = NULL;		/* start of host of display */    char *pdpynum = NULL;		/* start of dpynum of display */    char *pscrnum = NULL;		/* start of screen of display */    Bool dnet = False;			/* if true, then DECnet format */    int idisplay;			/* required display number */    int iscreen = 0;			/* optional screen number */    int (*connfunc)();			/* method to create connection */    int fd = -1;			/* file descriptor to return */    int len;				/* length tmp variable */    p = display_name;    saddrlen = 0;			/* set so that we can clear later */    saddr = NULL;    /*     * Step 1, find the hostname.  This is delimited by the required      * first colon.     */    for (lastp = p; *p && *p != ':'; p++) ;    if (!*p) return -1;		/* must have a colon */    if (p != lastp) {		/* no hostname given */	phostname = copystring (lastp, p - lastp);	if (!phostname) goto bad;	/* no memory */    }    /*     * Step 2, see if this is a DECnet address by looking for the optional     * second colon.     */    if (p[1] == ':') {			/* then DECnet format */	dnet = True;	p++;    }    /*     * see if we're allowed to have a DECnet address     */#ifndef DNETCONN    if (dnet) goto bad;#endif        /*     * Step 3, find the display number.  This field is required and is      * delimited either by a nul or a period, depending on whether or not     * a screen number is present.     */    for (lastp = ++p; *p && isascii(*p) && isdigit(*p); p++) ;    if ((p == lastp) ||			/* required field */	(*p != '\0' && *p != '.') ||	/* invalid non-digit terminator */	!(pdpynum = copystring (lastp, p - lastp)))  /* no memory */      goto bad;    idisplay = atoi (pdpynum);    /*     * Step 4, find the screen number.  This field is optional.  It is      * present only if the display number was followed by a period (which     * we've already verified is the only non-nul character).     */    if (*p) {	for (lastp = ++p; *p && isascii(*p) && isdigit (*p); p++) ;	if (*p ||			/* non-digits */	    !(pscrnum = copystring (lastp, p - lastp)))	 /* no memory */	  goto bad;	iscreen = atoi (lastp);    }    /*     * At this point, we know the following information:     *     *     phostname                hostname string or NULL     *     idisplay                 display number     *     iscreen                  screen number     *     dnet                     DECnet boolean     *      * We can now decide which transport to use based on the ConnectionFlags     * build parameter the hostname string.  If phostname is NULL or equals     * the string "local", then choose the best transport.  If phostname     * is "unix", then choose BSD UNIX domain sockets (if configured).     *     * First, choose default transports:  DECnet else (TCP or STREAMS)     */#ifdef DNETCONN    if (dnet)      connfunc = MakeDECnetConnection;    else#endif#ifdef TCPCONN      connfunc = MakeTCPConnection;#else#ifdef STREAMSCONN      connfunc = _XMakeStreamsConnection;#else      connfunc = NULL;#endif#endif#ifdef UNIXCONN    /*     * Now that the defaults have been established, see if we have any      * special names that we have to override:     *     *     :N         =>     if UNIXCONN then unix-domain-socket     *     ::N        =>     if UNIXCONN then unix-domain-socket     *     unix:N     =>     if UNIXCONN then unix-domain-socket     *     * Note that if UNIXCONN isn't defined, then we can use the default     * transport connection function set above.     */    if (!phostname) {#ifdef apollo	;   /* Unix domain sockets are *really* bad on apollos */#else	connfunc = MakeUNIXSocketConnection;#endif    }    else if (strcmp (phostname, "unix") == 0) {	connfunc = MakeUNIXSocketConnection;    }#endif    if (!connfunc)	goto bad;#ifdef UNIXCONN#define LOCALCONNECTION (!phostname || connfunc == MakeUNIXSocketConnection)#else#define LOCALCONNECTION (!phostname)#endif    if (LOCALCONNECTION) {	/*	 * Get the auth info for local hosts so that it doesn't have to be	 * repeated everywhere; the particular values in these fields are	 * not part of the protocol.	 */	char hostnamebuf[256];	int len = _XGetHostname (hostnamebuf, sizeof hostnamebuf);	family = FamilyLocal;	if (len > 0) {	    saddr = Xmalloc (len + 1);	    if (saddr) {		strcpy (saddr, hostnamebuf);		saddrlen = len;	    } else {		saddrlen = 0;	    }	}    }#undef LOCALCONNECTION    /*     * Make the connection, also need to get the auth address info for     * non-local connections.  Do retries in case server host has hit its     * backlog (which, unfortunately, isn't distinguishable from there not     * being a server listening at all, which is why we have to not retry     * too many times).     */    if ((fd = (*connfunc) (phostname, idisplay, X_CONNECTION_RETRIES,			   &family, &saddrlen, &saddr)) < 0)      goto bad;    if (fd >= OPEN_MAX)	goto bad;    /*     * Set close-on-exec so that programs that fork() doesn't get confused.     */#ifdef FD_CLOEXEC    (void) fcntl (fd, F_SETFD, FD_CLOEXEC);#else    (void) fcntl (fd, F_SETFD, 1);#endif    /*     * Build the expanded display name:     *     *     [host] : [:] dpy . scr \0     */    len = ((phostname ? strlen(phostname) : 0) + 1 + (dnet ? 1 : 0) +	   strlen(pdpynum) + 1 + (pscrnum ? strlen(pscrnum) : 1) + 1);    *fullnamep = (char *) Xmalloc (len);    if (!*fullnamep) goto bad;    sprintf (*fullnamep, "%s%s%d.%d",	     (phostname ? phostname : ""), (dnet ? "::" : ":"),	     idisplay, iscreen);    *dpynump = idisplay;    *screenp = iscreen;    if (phostname) Xfree (phostname);    if (pdpynum) Xfree (pdpynum);    if (pscrnum) Xfree (pscrnum);    GetAuthorization(fd, family, saddr, saddrlen, idisplay,		     auth_namep, auth_namelenp, auth_datap, auth_datalenp);    return fd;    /*     * error return; make sure everything is cleaned up.     */  bad:    if (fd >= 0) (void) close (fd);    if (saddr) Xfree (saddr);    if (phostname) Xfree (phostname);    if (pdpynum) Xfree (pdpynum);    if (pscrnum) Xfree (pscrnum);    return -1;}/***************************************************************************** *                                                                           * *			   Make Connection Routines                          * *                                                                           * *****************************************************************************/#ifdef DNETCONN				/* stupid makedepend */#define NEED_BSDISH#endif#ifdef UNIXCONN#define NEED_BSDISH#endif#ifdef TCPCONN#define NEED_BSDISH#endif#ifdef NEED_BSDISH			/* makedepend can't handle #if *//* * 4.2bsd-based systems */#include <sys/socket.h>#ifdef hpux#define NO_TCP_H#endif#ifdef MOTOROLA#ifdef SYSV#define NO_TCP_H#endif#endif#ifndef NO_TCP_H#ifdef __OSF1__#include <sys/param.h>#endif#include <netinet/tcp.h>#endif#endif /* NEED_BSDISH */#ifdef DNETCONNstatic int MakeDECnetConnection (phostname, idisplay, retries,				 familyp, saddrlenp, saddrp)    char *phostname;    int idisplay;    int retries;    int *familyp;			/* RETURN */    int *saddrlenp;			/* RETURN */    char **saddrp;			/* RETURN */{    int fd;    char objname[20];    extern int dnet_conn();    struct dn_naddr *dnaddrp, dnaddr;    struct nodeent *np;    if (!phostname) phostname = "0";    /*     * build the target object name.     */    sprintf (objname, "X$X%d", idisplay);    /*     * Attempt to open the DECnet connection, return -1 if fails; ought to     * do some retries here....     */    if ((fd = dnet_conn (phostname, objname, SOCK_STREAM, 0, 0, 0, 0)) < 0) {	return -1;    }    *familyp = FamilyDECnet;    if (dnaddrp = dnet_addr (phostname)) {  /* stolen from xhost */	dnaddr = *dnaddrp;    } else {	if ((np = getnodebyname (phostname)) == NULL) {	    (void) close (fd);	    return -1;	}	dnaddr.a_len = np->n_length;	bcopy (np->n_addr, dnaddr.a_addr, np->n_length);    }    *saddrlenp = sizeof (struct dn_naddr);    *saddrp = Xmalloc (*saddrlenp);    if (!*saddrp) {	(void) close (fd);	return -1;    }    bcopy ((char *)&dnaddr, *saddrp, *saddrlenp);    return fd;}#endif /* DNETCONN */#ifdef UNIXCONN#include <sys/un.h>/*ARGSUSED*/static int MakeUNIXSocketConnection (phostname, idisplay, retries,				     familyp, saddrlenp, saddrp)    char *phostname;    int idisplay;    int retries;    int *familyp;			/* RETURN */    int *saddrlenp;			/* RETURN */    char **saddrp;			/* RETURN */{    struct sockaddr_un unaddr;		/* UNIX socket data block */    struct sockaddr *addr;		/* generic socket pointer */    int addrlen;			/* length of addr */    int fd;				/* socket file descriptor */#ifdef hpux /* this is disgusting */    struct sockaddr_un ounaddr;		/* UNIX socket data block */    struct sockaddr *oaddr;		/* generic socket pointer */    int oaddrlen;			/* length of addr */#endif    unaddr.sun_family = AF_UNIX;    sprintf (unaddr.sun_path, "%s%d", X_UNIX_PATH, idisplay);    addr = (struct sockaddr *) &unaddr;#ifdef SUN_LEN    addrlen = SUN_LEN(&unaddr);#else    addrlen = strlen(unaddr.sun_path) + sizeof(unaddr.sun_family);#endif#ifdef hpux /* this is disgusting */    ounaddr.sun_family = AF_UNIX;    sprintf (ounaddr.sun_path, "%s%d", OLD_UNIX_PATH, idisplay);    oaddr = (struct sockaddr *) &ounaddr;    oaddrlen = strlen(ounaddr.sun_path) + sizeof(ounaddr.sun_family);#endif    /*     * Open the network connection.     */    do {	if ((fd = socket ((int) addr->sa_family, SOCK_STREAM, 0)) < 0) {	    return -1;	}	if (connect (fd, addr, addrlen) < 0) {	    int olderrno = errno;	    (void) close (fd);#ifdef hpux /* this is disgusting */	    if (olderrno == ENOENT) {		fd = socket ((int) oaddr->sa_family, SOCK_STREAM, 0);		if (fd >= 0) {		    if (connect (fd, oaddr, oaddrlen) >= 0)			break;		    olderrno = errno;		    (void) close (fd);		}	    }#endif	    if (olderrno != ENOENT || retries <= 0) {		errno = olderrno;		return -1;	    }	    sleep (1);	} else {	    break;	}    } while (retries-- > 0);    /*     * Don't need to get auth info since we're local     */    return fd;}#endif /* UNIXCONN */#ifdef TCPCONNstatic int MakeTCPConnection (phostname, idisplay, retries,			      familyp, saddrlenp, saddrp)    char *phostname;    int idisplay;    int retries;    int *familyp;			/* RETURN */    int *saddrlenp;			/* RETURN */    char **saddrp;			/* RETURN */{    char hostnamebuf[256];		/* tmp space */    unsigned long hostinetaddr;		/* result of inet_addr of arpa addr */    struct sockaddr_in inaddr;		/* IP socket */    struct sockaddr *addr;		/* generic socket pointer */    int addrlen;			/* length of addr */    struct hostent *hp;			/* entry in hosts table */    char *cp;				/* character pointer iterator */    int fd;				/* file descriptor to return */    int len;				/* length tmp variable */#define INVALID_INETADDR ((unsigned long) -1)    if (!phostname) {	hostnamebuf[0] = '\0';	(void) _XGetHostname (hostnamebuf, sizeof hostnamebuf);	phostname = hostnamebuf;    }    /*     * if numeric host name then try to parse it as such; do the number     * first because some systems return garbage instead of INVALID_INETADDR     */    if (isascii(phostname[0]) && isdigit(phostname[0])) {	hostinetaddr = inet_addr (phostname);    } else {	hostinetaddr = INVALID_INETADDR;    }    /*     * try numeric     */    if (hostinetaddr == INVALID_INETADDR) {	if ((hp = gethostbyname(phostname)) == NULL) {	    /* No such host! */	    return -1;	}	if (hp->h_addrtype != AF_INET) {  /* is IP host? */	    /* Not an Internet host! */	    return -1;	} 	/* Set up the socket data. */	inaddr.sin_family = hp->h_addrtype;#if defined(CRAY) && defined(OLDTCP)	/* Only Cray UNICOS3 and UNICOS4 will define this */	{	    long t;	    bcopy ((char *)hp->h_addr, (char *)&t, sizeof(t));	    inaddr.sin_addr = t;	}#else	bcopy ((char *)hp->h_addr, (char *)&inaddr.sin_addr, 	       sizeof(inaddr.sin_addr));#endif /* CRAY and OLDTCP */    } else {#if defined(CRAY) && defined(OLDTCP)	/* Only Cray UNICOS3 and UNICOS4 will define this */	inaddr.sin_addr = hostinetaddr;#else	inaddr.sin_addr.s_addr = hostinetaddr;#endif /* CRAY and OLDTCP */	inaddr.sin_family = AF_INET;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -