Annotation of researchv9/X11/src/X.V11R1/lib/X/XConnDis.c, revision 1.1

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: /*
        !             6:  * THIS IS AN OS DEPENDENT FILE! It should work on 4.2BSD derived
        !             7:  * systems.  VMS and System V should plan to have their own version.
        !             8:  */
        !             9: #include <stdio.h>
        !            10: #include "Xlibint.h"
        !            11: #include <fcntl.h>
        !            12: #include <sys/socket.h>
        !            13: #include <strings.h>
        !            14: 
        !            15: #ifdef UNIXCONN
        !            16: #include <sys/un.h>
        !            17: #define X_UNIX_PATH "/tmp/.X11-unix/X"
        !            18: #endif /* UNIXCONN */
        !            19: void bcopy();
        !            20: /* 
        !            21:  * Attempts to connect to server, given display name. Returns file descriptor
        !            22:  * (network socket) or -1 if connection fails. The expanded display name
        !            23:  * of the form hostname:number.screen ("::" if DECnet) is returned in a result
        !            24:  * parameter. The screen number to use is also returned.
        !            25:  */
        !            26: int _XConnectDisplay (display_name, expanded_name, screen_num)
        !            27: 
        !            28:     char *display_name;
        !            29:     char *expanded_name;       /* return */
        !            30:     int *screen_num;           /* return */
        !            31: 
        !            32: {
        !            33:        char displaybuf[256];           /* Display string buffer */     
        !            34:        register char *display_ptr;     /* Display string buffer pointer */
        !            35:        register char *numbuf_ptr;      /* Server number buffer pointer */
        !            36:        char *screen_ptr;               /* Pointer for locating screen num */
        !            37:        int display_num;                /* Display number */
        !            38:        struct sockaddr_in inaddr;      /* INET socket address. */
        !            39: #ifdef UNIXCONN
        !            40:        struct sockaddr_un unaddr;      /* UNIX socket address. */
        !            41: #endif
        !            42:        struct sockaddr *addr;          /* address to connect to */
        !            43:         struct hostent *host_ptr;
        !            44:        int addrlen;                    /* length of address */
        !            45:        extern char *getenv();
        !            46:        extern struct hostent *gethostbyname();
        !            47:         int fd;                                /* Network socket */
        !            48:        char numberbuf[16];
        !            49:        char *dot_ptr = NULL;           /* Pointer to . before screen num */
        !            50: #ifdef DNETCONN
        !            51:        int dnet = 0;
        !            52:        char objname[20];
        !            53:        extern int dnet_conn();
        !            54: #endif
        !            55: 
        !            56:        /* 
        !            57:         * Find the ':' seperator and extract the hostname and the
        !            58:         * display number.
        !            59:         * NOTE - if DECnet is to be used, the display name is formatted
        !            60:         * as "host::number"
        !            61:         */
        !            62:        (void) strncpy(displaybuf, display_name, sizeof(displaybuf));
        !            63:        if ((display_ptr = SearchString(displaybuf,':')) == NULL) return (-1);
        !            64: #ifdef DNETCONN
        !            65:        if (*(display_ptr + 1) == ':') {
        !            66:            dnet++;
        !            67:            *(display_ptr++) = '\0';
        !            68:        }
        !            69: #endif
        !            70:        *(display_ptr++) = '\0';
        !            71:  
        !            72:        /* displaybuf now contains only a null-terminated host name, and
        !            73:         * display_ptr points to the display number.
        !            74:         * If the display number is missing there is an error. */
        !            75: 
        !            76:        if (*display_ptr == '\0') return(-1);
        !            77: 
        !            78:        /*
        !            79:         * Build a string of the form <display-number>.<screen-number> in
        !            80:         * numberbuf, using ".0" as the default.
        !            81:         */
        !            82:        screen_ptr = display_ptr;
        !            83:        numbuf_ptr = numberbuf;
        !            84:        while (*screen_ptr != '\0') {
        !            85:            if (*screen_ptr == '.') {
        !            86:                dot_ptr = numbuf_ptr;
        !            87:                *(screen_ptr++) = '\0';
        !            88:                *(numbuf_ptr++) = '.';
        !            89:            } else {
        !            90:                *(numbuf_ptr++) = *(screen_ptr++);
        !            91:            }
        !            92:        }
        !            93: 
        !            94:        /*
        !            95:         * If the spec doesn't include a screen number, add ".0" (or "0" if
        !            96:         * only "." is present.)
        !            97:         */
        !            98:        if (dot_ptr == NULL) {
        !            99:            dot_ptr = numbuf_ptr;
        !           100:            *(numbuf_ptr++) = '.';
        !           101:            *(numbuf_ptr++) = '0';
        !           102:        } else {
        !           103:            if (*(numbuf_ptr - 1) == '.')
        !           104:                *(numbuf_ptr++) = '0';
        !           105:        }
        !           106:        *numbuf_ptr = '\0';
        !           107: 
        !           108:        /*
        !           109:         * Return the screen number in the result parameter
        !           110:         */
        !           111:        *screen_num = atoi(dot_ptr + 1);
        !           112: 
        !           113:        /*
        !           114:         * Convert the server number string to an integer.
        !           115:         */
        !           116:        display_num = atoi(display_ptr);
        !           117: 
        !           118:        /*
        !           119:         * If the display name is missing, use current host.
        !           120:         */
        !           121:        if (displaybuf[0] == '\0')
        !           122: #ifdef DNETCONN
        !           123:            if (dnet) 
        !           124:                (void) strcpy (displaybuf, "0");
        !           125:             else
        !           126: #endif
        !           127: #ifdef UNIXCONN
        !           128:                ;       /* Do nothing if UNIX DOMAIN. Will be handled below. */
        !           129: #else
        !           130:                (void) gethostname (displaybuf, sizeof(displaybuf));
        !           131: #endif
        !           132: 
        !           133: #ifdef DNETCONN
        !           134:        if (dnet) {
        !           135:            /*
        !           136:             * build the target object name.
        !           137:             */
        !           138:            sprintf(objname, "X%d", display_num);
        !           139:            /*
        !           140:             * Attempt to open the DECnet connection, return -1 if fails.
        !           141:             */
        !           142:            if ((fd = dnet_conn(displaybuf, 
        !           143:                   objname, SOCK_STREAM, 0, 0, 0, 0)) < 0)
        !           144:                return(-1);         /* errno set by dnet_conn. */
        !           145:        } else
        !           146: #endif
        !           147:        {
        !           148: #ifdef UNIXCONN
        !           149:            if ((displaybuf[0] == '\0') || 
        !           150:                (strcmp("unix", displaybuf) == 0)) {
        !           151:                /* Connect locally using Unix domain. */
        !           152:                unaddr.sun_family = AF_UNIX;
        !           153:                (void) strcpy(unaddr.sun_path, X_UNIX_PATH);
        !           154:                strcat(unaddr.sun_path, display_ptr);
        !           155:                addr = (struct sockaddr *) &unaddr;
        !           156:                addrlen = strlen(unaddr.sun_path) + 2;
        !           157:                /*
        !           158:                 * Open the network connection.
        !           159:                 */
        !           160:                if ((fd = socket((int) addr->sa_family, SOCK_STREAM, 0)) < 0)
        !           161:                    return(-1);     /* errno set by system call. */
        !           162:            } else
        !           163: #endif
        !           164:            {
        !           165:                /* Get the statistics on the specified host. */
        !           166:                if ((inaddr.sin_addr.s_addr = inet_addr(displaybuf)) == -1) {
        !           167:                        if ((host_ptr = gethostbyname(displaybuf)) == NULL) {
        !           168:                                /* No such host! */
        !           169:                                errno = EINVAL;
        !           170:                                return(-1);
        !           171:                        }
        !           172:                        /* Check the address type for an internet host. */
        !           173:                        if (host_ptr->h_addrtype != AF_INET) {
        !           174:                                /* Not an Internet host! */
        !           175:                                errno = EPROTOTYPE;
        !           176:                                return(-1);
        !           177:                        }
        !           178:  
        !           179:                        /* Set up the socket data. */
        !           180:                        inaddr.sin_family = host_ptr->h_addrtype;
        !           181:                        bcopy((char *)host_ptr->h_addr, 
        !           182:                              (char *)&inaddr.sin_addr, 
        !           183:                              sizeof(inaddr.sin_addr));
        !           184:                } else {
        !           185:                        inaddr.sin_family = AF_INET;
        !           186:                }
        !           187:                addr = (struct sockaddr *) &inaddr;
        !           188:                addrlen = sizeof (struct sockaddr_in);
        !           189:                inaddr.sin_port = display_num;
        !           190:                inaddr.sin_port += X_TCP_PORT;
        !           191:                inaddr.sin_port = htons(inaddr.sin_port);
        !           192:                /*
        !           193:                 * Open the network connection.
        !           194:                 */
        !           195: 
        !           196:                if ((fd = socket((int) addr->sa_family, SOCK_STREAM, 0)) < 0)
        !           197:                    return(-1);     /* errno set by system call. */
        !           198:                /* make sure to turn off TCP coalescence */
        !           199: #ifdef TCP_NODELAY
        !           200:                {
        !           201:                int mi;
        !           202:                setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &mi, sizeof (int));
        !           203:                }
        !           204: #endif
        !           205:            }
        !           206:  
        !           207: 
        !           208:            if (connect(fd, addr, addrlen) == -1) {
        !           209:                (void) close (fd);
        !           210:                return(-1);         /* errno set by system call. */
        !           211:            }
        !           212:         }
        !           213:        /*
        !           214:         * set it non-blocking.  This is so we can read data when blocked
        !           215:         * for writing in the library.
        !           216:         */
        !           217:        (void) fcntl(fd, F_SETFL, FNDELAY);
        !           218:        /*
        !           219:         * Return the id if the connection succeeded. Rebuild the expanded
        !           220:         * spec and return it in the result parameter.
        !           221:         */
        !           222:        display_ptr = displaybuf;
        !           223:        while (*(++display_ptr) != '\0')
        !           224:            ;
        !           225:        *(display_ptr++) = ':';
        !           226: #ifdef DNETCONN
        !           227:        if (dnet)
        !           228:            *(display_ptr++) = ':';
        !           229: #endif
        !           230:        numbuf_ptr = numberbuf;
        !           231:        while (*numbuf_ptr != '\0')
        !           232:            *(display_ptr++) = *(numbuf_ptr++);
        !           233:        *display_ptr = '\0';
        !           234:        (void) strcpy(expanded_name, displaybuf);
        !           235:        return(fd);
        !           236: 
        !           237: }
        !           238: 
        !           239: /* 
        !           240:  * Disconnect from server.
        !           241:  */
        !           242: 
        !           243: int _XDisconnectDisplay (server)
        !           244: 
        !           245:     int server;
        !           246: 
        !           247: {
        !           248:     (void) close(server);
        !           249: }
        !           250: 
        !           251: #undef NULL
        !           252: #define NULL ((char *) 0)
        !           253: /*
        !           254:  * This is an OS dependent routine which:
        !           255:  * 1) returns as soon as the connection can be written on....
        !           256:  * 2) if the connection can be read, must enqueue events and handle errors,
        !           257:  * until the connection is writable.
        !           258:  */
        !           259: _XWaitForWritable(dpy)
        !           260:     Display *dpy;
        !           261: {
        !           262:     unsigned long r_mask[MSKCNT];
        !           263:     unsigned long w_mask[MSKCNT];
        !           264:     int nfound;
        !           265: 
        !           266:     CLEARBITS(r_mask);
        !           267:     CLEARBITS(w_mask);
        !           268: 
        !           269:     while (1) {
        !           270:        BITSET(r_mask, dpy->fd);
        !           271:         BITSET(w_mask, dpy->fd);
        !           272: 
        !           273:        do {
        !           274:            nfound = select (dpy->fd + 1, r_mask, w_mask, NULL, NULL);
        !           275:            if (nfound < 0 && errno != EINTR)
        !           276:                (*_XIOErrorFunction)(dpy);
        !           277:        } while (nfound <= 0);
        !           278: 
        !           279:        if (ANYSET(r_mask)) {
        !           280:            char buf[BUFSIZE];
        !           281:            long pend_not_register;
        !           282:            register long pend;
        !           283:            register xEvent *ev;
        !           284: 
        !           285:            /* find out how much data can be read */
        !           286:            if (BytesReadable(dpy->fd, (char *) &pend_not_register) < 0)
        !           287:                (*_XIOErrorFunction)(dpy);
        !           288:            pend = pend_not_register;
        !           289: 
        !           290:            /* must read at least one xEvent; if none is pending, then
        !           291:               we'll just block waiting for it */
        !           292:            if (pend < sizeof(xEvent)) pend = sizeof (xEvent);
        !           293:                
        !           294:            /* but we won't read more than the max buffer size */
        !           295:            if (pend > BUFSIZE) pend = BUFSIZE;
        !           296: 
        !           297:            /* round down to an integral number of XReps */
        !           298:            pend = (pend / sizeof (xEvent)) * sizeof (xEvent);
        !           299: 
        !           300:            _XRead (dpy, buf, pend);
        !           301:            for (ev = (xEvent *) buf; pend > 0; ev++, pend -= sizeof(xEvent))
        !           302:            {
        !           303:                if (ev->u.u.type == X_Error)
        !           304:                    _XError (dpy, (xError *) ev);
        !           305:                else            /* it's an event packet; enqueue it */
        !           306:                    _XEnq (dpy, ev);
        !           307:            }
        !           308:        }
        !           309:        if (ANYSET(w_mask))
        !           310:            return;
        !           311:     }
        !           312: }
        !           313: 
        !           314: 
        !           315: _XWaitForReadable(dpy)
        !           316:   Display *dpy;
        !           317: {
        !           318:     unsigned long r_mask[MSKCNT];
        !           319:     int result;
        !           320:        
        !           321:     CLEARBITS(r_mask);
        !           322:     do {
        !           323:        BITSET(r_mask, dpy->fd);
        !           324:        result = select(dpy->fd + 1, r_mask, NULL, NULL, NULL);
        !           325:        if (result == -1 && errno != EINTR) (*_XIOErrorFunction)(dpy);
        !           326:     } while (result <= 0);
        !           327: }
        !           328: 
        !           329: static int padlength[4] = {0, 3, 2, 1};
        !           330: 
        !           331: _XSendClientPrefix (dpy, client)
        !           332:      Display *dpy;
        !           333:      xConnClientPrefix *client;
        !           334: {
        !           335:        /*
        !           336:         * Authorization string stuff....  Must always transmit multiple of 4
        !           337:         * bytes.
        !           338:         */
        !           339: 
        !           340:         char *auth_proto = ""; 
        !           341:        int auth_length;
        !           342:        char *auth_string = "";
        !           343:        int auth_strlen;
        !           344:        char pad[3];
        !           345:        char buffer[BUFSIZ], *bptr;
        !           346: 
        !           347:         int bytes=0;
        !           348: 
        !           349:         auth_length = strlen(auth_proto);
        !           350:         auth_strlen = strlen(auth_string);
        !           351:         client->nbytesAuthProto = auth_length;
        !           352:        client->nbytesAuthString = auth_strlen;
        !           353: 
        !           354:        bytes = (sizeof(xConnClientPrefix) + 
        !           355:                        auth_length + padlength[auth_length & 3] +
        !           356:                        auth_strlen + padlength[auth_strlen & 3]);
        !           357: 
        !           358:        bcopy(client, buffer, sizeof(xConnClientPrefix));
        !           359:         bptr = buffer + sizeof(xConnClientPrefix);
        !           360:         if (auth_length)
        !           361:        {
        !           362:            bcopy(auth_proto, bptr, auth_length);
        !           363:             bptr += auth_length;
        !           364:             if (padlength[auth_length & 3])
        !           365:            {
        !           366:                bcopy(pad, bptr, padlength[auth_length & 3]);
        !           367:                bptr += padlength[auth_length & 3];
        !           368:            }
        !           369:        }
        !           370:         if (auth_strlen)
        !           371:        {
        !           372:            bcopy(auth_string, bptr, auth_strlen);
        !           373:             bptr += auth_strlen;
        !           374:             if (padlength[auth_strlen & 3])
        !           375:            {
        !           376:                bcopy(pad, bptr, padlength[auth_strlen & 3]);
        !           377:                bptr += padlength[auth_strlen & 3];
        !           378:            }
        !           379:        }
        !           380:        (void) WriteToServer(dpy->fd, buffer, bytes);
        !           381:        return;
        !           382: }
        !           383: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.