Annotation of researchv9/X11/src/X.V11R1/lib/X/XConnDis.c, revision 1.1.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.