Annotation of researchv9/X11/src/X.V11R1/server/os/4.2bsd/connection.c, revision 1.1.1.1

1.1       root        1: /***********************************************************
                      2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
                      3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
                      4: 
                      5:                         All Rights Reserved
                      6: 
                      7: Permission to use, copy, modify, and distribute this software and its 
                      8: documentation for any purpose and without fee is hereby granted, 
                      9: provided that the above copyright notice appear in all copies and that
                     10: both that copyright notice and this permission notice appear in 
                     11: supporting documentation, and that the names of Digital or MIT not be
                     12: used in advertising or publicity pertaining to distribution of the
                     13: software without specific, written prior permission.  
                     14: 
                     15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     21: SOFTWARE.
                     22: 
                     23: ******************************************************************/
                     24: /* $Header: connection.c,v 1.62 87/09/07 17:12:18 rws Exp $ */
                     25: /*****************************************************************
                     26:  *  Stuff to create connections --- OS dependent
                     27:  *
                     28:  *      EstablishNewConnections, CreateWellKnownSockets,
                     29:  *      CloseDownConnection, CheckConnections, AddEnabledDevice,
                     30:  *     RemoveEnabledDevice, OnlyListToOneClient,
                     31:  *      ListenToAllClients,
                     32:  *
                     33:  *      (WaitForSomething is in its own file)
                     34:  *
                     35:  *      In this implementation, a client socket table is not kept.
                     36:  *      Instead, what would be the index into the table is just the
                     37:  *      file descriptor of the socket.  This won't work for if the
                     38:  *      socket ids aren't small nums (0 - 2^8)
                     39:  *
                     40:  *****************************************************************/
                     41: 
                     42: #include <dbm.h>
                     43: #undef NULL
                     44: #include "X.h"
                     45: #include "Xproto.h"
                     46: #include <sys/param.h>
                     47: #include <errno.h>
                     48: #include <sys/types.h>
                     49: #include <sys/socket.h>
                     50: #include <sys/time.h>
                     51: #include <signal.h>
                     52: #include <fcntl.h>
                     53: #include <setjmp.h>
                     54: #ifdef TCPCONN
                     55: #include <netinet/in.h>
                     56: #endif
                     57: #ifdef UNIXCONN
                     58: #include <sys/un.h>
                     59: #endif
                     60: #include <stdio.h>
                     61: #include <sys/uio.h>
                     62: #include <strings.h>
                     63: #include "osstruct.h"
                     64: #include "osdep.h"
                     65: #include "opaque.h"
                     66: 
                     67: #include "dixstruct.h"
                     68: 
                     69: #ifdef DNETCONN
                     70: #include <netdnet/dn.h>
                     71: #endif /* DNETCONN */
                     72: 
                     73: typedef long CCID;      /* mask of indices into client socket table */
                     74: 
                     75: #define X_UNIX_PATH    "/tmp/.X11-unix" 
                     76: 
                     77: char *display;                 /* The display number */
                     78: int lastfdesc;                  /* maximum file descriptor */
                     79: 
                     80: long WellKnownConnections;    /* Listener mask */
                     81: long EnabledDevices;           /* mask for input devices that are on */
                     82: long AllSockets[mskcnt];        /* select on this */
                     83: long AllClients[mskcnt];              /* available clients */
                     84: long LastSelectMask[mskcnt];          /* mask returned from last select call */
                     85: long ClientsWithInput[mskcnt];
                     86: long MaxClients = MAXSOCKS ;
                     87: long NConnBitArrays = mskcnt;
                     88: long FirstClient;
                     89: 
                     90: static Bool debug_conns = FALSE;
                     91: 
                     92: static char whichByteIsFirst;
                     93: 
                     94: static int SavedAllClients[mskcnt];
                     95: static int SavedAllSockets[mskcnt];
                     96: static int SavedClientsWithInput[mskcnt];
                     97: static Bool GrabDone = FALSE;
                     98: 
                     99: ClientPtr ConnectionTranslation[MAXSOCKS];
                    100: extern ClientPtr NextAvailableClient();
                    101: 
                    102: extern ConnectionInput inputBuffers[];
                    103: 
                    104: int swappedClients[MAXSOCKS];
                    105: 
                    106: extern int AutoResetServer();
                    107: extern int GiveUp();
                    108: 
                    109: /*****************
                    110:  * CreateWellKnownSockets
                    111:  *    At initialization, create the sockets to listen on for new clients.
                    112:  *    There are potentially 4: DECnet, UNIX Domain, TCP-IP with MSB first, 
                    113:  *    with TCP-IP with LSB first.
                    114:  *****************/
                    115: 
                    116: void
                    117: CreateWellKnownSockets()
                    118: {
                    119:     char       fname[32];
                    120:     int                request, i;
                    121:     int                whichbyte;          /* used to figure out whether this is
                    122:                                         LSB or MSB */
                    123: #ifdef TCPCONN
                    124:     struct sockaddr_in insock;
                    125:     int                tcpportReg;         /* port with same byte order as server */
                    126: 
                    127: #ifdef SO_LINGER
                    128:     static int linger[2] = { 0, 0 };
                    129: #endif /* SO_LINGER */
                    130: 
                    131: #endif /* TCPCONN */
                    132: 
                    133: #ifdef UNIXCONN
                    134:     struct sockaddr_un unsock;
                    135:     int         oldUmask;
                    136: #endif /* UNIXCONN */
                    137: 
                    138: #ifdef DNETCONN
                    139:     struct sockaddr_dn dnsock;
                    140: #endif /* DNETCONN */
                    141:     int retry;
                    142: 
                    143:     CLEARBITS(AllSockets);
                    144:     CLEARBITS(AllClients);
                    145:     CLEARBITS(LastSelectMask);
                    146:     CLEARBITS(ClientsWithInput);
                    147: 
                    148:     for (i=0; i<MAXSOCKS; i++) ConnectionTranslation[i] = (ClientPtr)NULL;
                    149:     
                    150:     lastfdesc = getdtablesize() - 1;
                    151:     if (lastfdesc > MAXSOCKS)
                    152:     {
                    153:        lastfdesc = MAXSOCKS;
                    154:        ErrorF( "GOT TO END OF SOCKETS %d\n", MAXSOCKS);
                    155:     }
                    156: 
                    157:        /* hack test to decide where to log errors */
                    158: 
                    159:     if (write (2, fname, 0)) 
                    160:     {
                    161:        long t; 
                    162: 
                    163:        char *ctime();
                    164:         close(stdin);
                    165:         close(stdout);
                    166:        strcpy (fname, "/usr/adm/X");
                    167:        strcat (fname, display);
                    168:        strcat (fname, "msgs");
                    169:        freopen (fname, "a+", stderr);
                    170:        setlinebuf(stderr);
                    171:        time (&t);
                    172:        fprintf (stderr, "start %s", ctime(&t));
                    173:     }
                    174:        if (getpgrp (0) == 0)
                    175:            setpgrp (0, getpid ());
                    176: 
                    177:     WellKnownConnections = 0;
                    178:     whichbyte = 1;
                    179:     
                    180:     if (*(char *) &whichbyte)
                    181:         whichByteIsFirst = 'l';
                    182:     else
                    183:         whichByteIsFirst = 'B';
                    184: 
                    185: 
                    186: #ifdef TCPCONN
                    187: 
                    188:     tcpportReg = atoi (display); 
                    189:     tcpportReg += X_TCP_PORT;
                    190: 
                    191:     if ((request = socket (AF_INET, SOCK_STREAM, 0)) < 0) 
                    192:     {
                    193:        Notice ("Creating TCP socket");
                    194:     } 
                    195:     else 
                    196:     {
                    197:        bzero ((char *)&insock, sizeof (insock));
                    198:        insock.sin_family = AF_INET;
                    199:        insock.sin_port = htons (tcpportReg);
                    200:        insock.sin_addr.s_addr = htonl(INADDR_ANY);
                    201:        retry = 20;
                    202:        while (i = bind(request, (struct sockaddr *) &insock, sizeof (insock))) 
                    203:        {
                    204:            if (--retry == 0)
                    205:                Error ("Binding MSB TCP socket");
                    206:            sleep (10);
                    207:        }
                    208: #ifdef SO_LINGER
                    209:        if(setsockopt (request, SOL_SOCKET, SO_LINGER, linger, sizeof(linger)))
                    210:            Notice ("Setting TCP SO_LINGER\n");
                    211: #endif /* SO_LINGER */
                    212:        if (listen (request, 5))
                    213:            Error ("Reg TCP Listening");
                    214:        WellKnownConnections |= (1 << request);
                    215:        DefineSelf (request);
                    216:     }
                    217: 
                    218: #endif /* TCPCONN */
                    219: 
                    220: #ifdef UNIXCONN
                    221:     unsock.sun_family = AF_UNIX;
                    222:     oldUmask = umask (0);
                    223:     mkdir (X_UNIX_PATH, 0777);
                    224:     (void)umask(oldUmask);
                    225:     strcpy (unsock.sun_path, X_UNIX_PATH);
                    226:     strcat (unsock.sun_path, "/X");
                    227:     strcat (unsock.sun_path, display);
                    228:     unlink (unsock.sun_path);
                    229:     if ((request = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) 
                    230:     {
                    231:        Notice ("Creating Unix socket");
                    232:     } 
                    233:     else 
                    234:     {
                    235:        if(bind(request,(struct sockaddr *)&unsock, strlen(unsock.sun_path)+2))
                    236:            Error ("Binding Unix socket");
                    237:        if (listen (request, 5)) Error ("Unix Listening");
                    238:        WellKnownConnections |= (1 << request);
                    239:     }
                    240: #endif /*UNIXCONN */
                    241: 
                    242: #ifdef DNETCONN
                    243:     if ((request = socket (AF_DECnet, SOCK_STREAM, 0)) < 0) 
                    244:     {
                    245:        Notice ("Creating DECnet socket");
                    246:     } 
                    247:     else 
                    248:     {
                    249:        bzero ((char *)&dnsock, sizeof (dnsock));
                    250:        dnsock.sdn_family = AF_DECnet;
                    251:        sprintf(dnsock.sdn_objname, "X%d", atoi (display));
                    252:        dnsock.sdn_objnamel = strlen(dnsock.sdn_objname);
                    253:        if (bind (request, (struct sockaddr *) &dnsock, sizeof (dnsock)))
                    254:                Error ("Binding DECnet socket");
                    255:        if (listen (request, 5)) Error ("DECnet Listening");
                    256:        WellKnownConnections |= (1 << request);
                    257:        DefineSelf (request);
                    258:     }
                    259: #endif /* DNETCONN */
                    260:     if (WellKnownConnections == 0)
                    261:         Error ("No Listeners, nothing to do");
                    262:     signal (SIGPIPE, SIG_IGN);
                    263:     signal (SIGHUP, AutoResetServer);
                    264:     signal (SIGINT, GiveUp);
                    265:     signal (SIGTERM, GiveUp);
                    266:     FirstClient = request + 1;
                    267:     AllSockets[0] = WellKnownConnections;
                    268:     ResetHosts(display);
                    269: 
                    270:     for (i=0; i<MaxClients; i++)
                    271:     {
                    272:        inputBuffers[i].buffer = (char *) NULL;
                    273:        inputBuffers[i].bufptr = (char *) NULL;
                    274:        inputBuffers[i].bufcnt = 0;
                    275:        inputBuffers[i].lenLastReq = 0;
                    276:        inputBuffers[i].size = 0;
                    277:     }
                    278: }
                    279: 
                    280: /* We want to read the connection information.  If the client doesn't
                    281:  * send us enough data, however, we want to time out eventually.
                    282:  * The scheme is to clear a flag, set an alarm, and keep doing non-blocking
                    283:  * reads until we get all the data we want. If the alarm goes
                    284:  * off, the handler will clear the flag.  If we see that the flag is
                    285:  * cleared, we know we've timed out and return with an error.
                    286:  *
                    287:  * there remains one problem with this code:
                    288:  * there is a window of vulnerability in which we might get an alarm
                    289:  * even though all the data has come in properly.  This is because I
                    290:  * can't atomically clear the alarm.
                    291:  * 
                    292:  * Anyone who sees how to fix this problem should do so and
                    293:  * submit a fix.
                    294:  */
                    295: 
                    296: jmp_buf        env;
                    297: void TimeOut()
                    298: {
                    299:     longjmp(env, 1);
                    300: }
                    301: static Bool 
                    302: ReadBuffer(conn, buffer, charsWanted)
                    303:     long conn;
                    304:     char *buffer;
                    305:     int charsWanted;
                    306: {
                    307:     char *bptr = buffer;
                    308:     int got, fTimeOut;
                    309:     struct itimerval   itv;
                    310: 
                    311:     signal(SIGALRM, TimeOut);
                    312:     fTimeOut = FALSE;
                    313:     /* only 1 alarm, please, not 1 per minute */
                    314:     timerclear(&itv.it_interval);
                    315:     itv.it_value.tv_sec = TimeOutValue;
                    316:     itv.it_value.tv_usec = 0;
                    317:     setitimer(ITIMER_REAL, &itv, NULL);
                    318:     /* It better not take a full minute to get to the read call */
                    319: 
                    320:     while (charsWanted && (fTimeOut = setjmp(env)) == FALSE)
                    321:     {
                    322:        got = read(conn, bptr, charsWanted);    
                    323:        if (got <= 0)
                    324:            return FALSE;
                    325:        if(got > 0)
                    326:        {
                    327:            charsWanted -= got;
                    328:            bptr += got;
                    329:            /* Ok, we got something, reset the timer */
                    330:            itv.it_value.tv_sec = TimeOutValue;
                    331:             itv.it_value.tv_usec = 0;
                    332:            setitimer(ITIMER_REAL, &itv, NULL);
                    333:        }
                    334:     }
                    335:     /* disable the timer */
                    336:     timerclear(&itv.it_value);
                    337:     setitimer(ITIMER_REAL, &itv, NULL);
                    338:     /* If we got here and we didn't time out, then return TRUE, because
                    339:      * we must have read what we wanted. If we timed out, return FALSE */
                    340:     if(fTimeOut && debug_conns)
                    341:        ErrorF("Timed out on connection %d\n", conn);
                    342:     return (!fTimeOut);
                    343: }
                    344: 
                    345: /*****************************************************************
                    346:  * ClientAuthorized
                    347:  *
                    348:  *    Sent by the client at connection setup:
                    349:  *                typedef struct _xConnClientPrefix {
                    350:  *                   CARD8     byteOrder;
                    351:  *                   BYTE      pad;
                    352:  *                   CARD16    majorVersion, minorVersion;
                    353:  *                   CARD16    nbytesAuthProto;    
                    354:  *                   CARD16    nbytesAuthString;   
                    355:  *                 } xConnClientPrefix;
                    356:  *
                    357:  *             It is hoped that eventually one protocol will be agreed upon.  In the
                    358:  *        mean time, a server that implements a different protocol than the
                    359:  *        client expects, or a server that only implements the host-based
                    360:  *        mechanism, will simply ignore this information.
                    361:  *
                    362:  *****************************************************************/
                    363: 
                    364: int 
                    365: ClientAuthorized(conn, pswapped, reason)
                    366:     long conn;
                    367:     int  *pswapped;
                    368:     char **reason;   /* if authorization fails, put reason in here */
                    369: {
                    370:     short slen;
                    371:     union {
                    372:        struct sockaddr sa;
                    373: #ifdef UNIXCONN
                    374:        struct sockaddr_un un;
                    375: #endif /* UNIXCONN */
                    376: #ifdef TCPCONN
                    377:        struct sockaddr_in in;
                    378: #endif /* TCPCONN */
                    379: #ifdef DNETCONN
                    380:        struct sockaddr_dn dn;
                    381: #endif /* DNETCONN */
                    382:     } from;
                    383:     int        fromlen;
                    384:     xConnClientPrefix xccp;
                    385:     char auth_proto[100];
                    386:     char auth_string[100];
                    387: 
                    388:     if (!ReadBuffer(conn, &xccp, sizeof(xConnClientPrefix)))
                    389:     {
                    390:        /* If they can't even give us this much, just blow them off
                    391:         * without an error message */
                    392:        *reason = 0;
                    393:         return 0;
                    394:     }
                    395:     if (xccp.byteOrder != whichByteIsFirst)
                    396:     {        
                    397:        SwapConnClientPrefix(&xccp);
                    398:        *pswapped = TRUE;
                    399:     }
                    400:     else
                    401:         *pswapped = FALSE;
                    402:     if ((xccp.majorVersion != X_PROTOCOL) ||
                    403:        (xccp.minorVersion != X_PROTOCOL_REVISION))
                    404:     {        
                    405: #define STR "Protocol version mismatch"
                    406:         *reason = (char *)Xalloc(strlen(STR) + 1);
                    407:         strcpy(*reason, STR);
                    408:        if (debug_conns)
                    409:            ErrorF("%s\n", STR);
                    410: #undef STR
                    411:         return 0;
                    412:     }
                    413:     fromlen = sizeof (from);
                    414:     if (getpeername (conn, &from.sa, &fromlen) ||
                    415:         InvalidHost (&from.sa, fromlen)) 
                    416:     {
                    417: #define STR "Server is not authorized to connect to host"      
                    418:         *reason = (char *)Xalloc(strlen(STR));
                    419:         strcpy(*reason, STR);
                    420: #undef STR
                    421:         return 0;
                    422:     }
                    423:     
                    424:    slen = (xccp.nbytesAuthProto + 3) & ~3;  
                    425:     if ( slen )
                    426:         if (!ReadBuffer(conn, auth_proto, slen))
                    427:         {
                    428: #define STR "Length error in xConnClientPrefix for protocol authorization "
                    429:             *reason = (char *)Xalloc(strlen(STR));
                    430:             strcpy(*reason, STR);
                    431:             return 0;
                    432: #undef STR
                    433:        }
                    434:     auth_proto[slen] = '\0';
                    435: 
                    436:     slen = (xccp.nbytesAuthString + 3) & ~3;   
                    437:     if ( slen)
                    438:         if (!ReadBuffer(conn, auth_string, slen))
                    439:         {
                    440: #define STR "Length error in xConnClientPrefix for protocol string"
                    441:             *reason = (char *)Xalloc(strlen(STR));
                    442:             strcpy(*reason, STR);
                    443:             return 0;
                    444: #undef STR
                    445:        }
                    446:     auth_string[slen] = '\0';
                    447: 
                    448:     /* At this point, if the client is authorized to change the access control
                    449:      * list, we should getpeername() information, and add the client to
                    450:      * the selfhosts list.  It's not really the host machine, but the
                    451:      * true purpose of the selfhosts list is to see who may change the
                    452:      * access control list.
                    453:      */
                    454:     return(1);
                    455: }    
                    456: 
                    457: static int padlength[4] = {0, 3, 2, 1};
                    458: 
                    459: /*****************
                    460:  * EstablishNewConnections
                    461:  *    If anyone is waiting on listened sockets, accept them.
                    462:  *    Returns a mask with indices of new clients.  Updates AllClients
                    463:  *    and AllSockets.
                    464:  *****************/
                    465: 
                    466: void
                    467: EstablishNewConnections(newclients, nnew)
                    468:     ClientPtr          *newclients;
                    469:     int                *nnew;
                    470: {
                    471:     long readyconnections;     /* mask of listeners that are ready */
                    472:     long curconn;                  /* fd of listener that's ready */
                    473:     long newconn;                  /* fd of new client */
                    474:     int         swapped;               /* set by ClientAuthorized if connection is
                    475:                                 * swapped */
                    476:     char *reason;
                    477:     struct iovec iov[2];
                    478:     char p[3];
                    479: 
                    480: #ifdef TCP_NODELAY
                    481:     union {
                    482:        struct sockaddr sa;
                    483: #ifdef UNIXCONN
                    484:        struct sockaddr_un un;
                    485: #endif /* UNIXCONN */
                    486: #ifdef TCPCONN
                    487:        struct sockaddr_in in;
                    488: #endif /* TCPCONN */
                    489: #ifdef DNETCONN
                    490:        struct sockaddr_dn dn;
                    491: #endif /* DNETCONN */
                    492:     } from;
                    493:     int        fromlen;
                    494: #endif TCP_NODELAY
                    495: 
                    496:     *nnew = 0;
                    497:     if (readyconnections = (LastSelectMask[0] & WellKnownConnections)) 
                    498:     {
                    499:        while (readyconnections) 
                    500:        {
                    501:            curconn = ffs (readyconnections) - 1;
                    502:            if ((newconn = accept (curconn,
                    503:                                  (struct sockaddr *) NULL, 
                    504:                                  (int *)NULL)) >= 0) 
                    505:            {
                    506:                if (newconn >= lastfdesc)
                    507:                {
                    508:                    if (debug_conns)
                    509: ErrorF("Didn't make connection: Out of file descriptors for connections\n");
                    510:                    close (newconn);
                    511:                } 
                    512:                else 
                    513:                {
                    514: #ifdef TCP_NODELAY
                    515:                    fromlen = sizeof (from);
                    516:                     if (!getpeername (newconn, &from.sa, &fromlen))
                    517:                    {
                    518:                        if (fromlen && (from.sa.sa_family == AF_INET)) 
                    519:                        {
                    520:                            mi = 1;
                    521:                            setsockopt (newconn, IPPROTO_TCP, TCP_NODELAY,
                    522:                                       &mi, sizeof (int));
                    523:                        }
                    524:                    }
                    525: #endif /* TCP_NODELAY */
                    526:                    if (ClientAuthorized(newconn, &swapped, &reason))
                    527:                    {
                    528:                        ClientPtr next;
                    529: 
                    530:                        fcntl (newconn, F_SETFL, FNDELAY);
                    531:                        inputBuffers[newconn].used = 1; 
                    532:                         if (! inputBuffers[newconn].size) 
                    533:                        {
                    534:                            inputBuffers[newconn].buffer = 
                    535:                                        (char *)Xalloc(BUFSIZE);
                    536:                            inputBuffers[newconn].size = BUFSIZE;
                    537:                            inputBuffers[newconn].bufptr =      
                    538:                                        inputBuffers[newconn].buffer;
                    539:                        }
                    540:                        if (GrabDone)
                    541:                        {
                    542:                            BITSET(SavedAllClients, newconn);
                    543:                            BITSET(SavedAllSockets, newconn);
                    544:                        }
                    545:                        else
                    546:                        {
                    547:                            BITSET(AllClients, newconn);
                    548:                            BITSET(AllSockets, newconn);
                    549:                        }
                    550:                        next = NextAvailableClient();
                    551:                        if (next != (ClientPtr)NULL)
                    552:                        {
                    553:                           osPrivPtr priv;
                    554: 
                    555:                           newclients[(*nnew)++] = next;
                    556:                           next->swapped = swapped;
                    557:                           ConnectionTranslation[newconn] = next;
                    558:                           priv =  (osPrivPtr)Xalloc(sizeof(osPrivRec));
                    559:                           priv->fd = newconn;
                    560:                           next->osPrivate = (pointer)priv;
                    561:                        }
                    562:                    }
                    563:                    else
                    564:                    {
                    565:                        xConnSetupPrefix c;
                    566: 
                    567:                        if(reason)
                    568:                        {
                    569:                            c.success = xFalse;
                    570:                            c.lengthReason = strlen(reason);
                    571:                            c.length = (c.lengthReason + 3) >> 2;
                    572:                            c.majorVersion = X_PROTOCOL;
                    573:                            c.minorVersion = X_PROTOCOL_REVISION;
                    574:                            if(swapped)
                    575:                            {
                    576:                                int     n;
                    577: 
                    578:                                swaps(&c.majorVersion, n);
                    579:                                swaps(&c.minorVersion, n);
                    580:                                swaps(&c.length, n);
                    581:                            }
                    582: 
                    583:                            write(newconn, &c, sizeof(xConnSetupPrefix)); 
                    584:                            iov[0].iov_len = c.lengthReason;
                    585:                            iov[0].iov_base = reason;
                    586:                            iov[1].iov_len = padlength[c.lengthReason & 3];
                    587:                            iov[1].iov_base = p;
                    588:                            writev(newconn, iov, 2);
                    589:                            if (debug_conns)
                    590:                                ErrorF("Didn't make connection:%s\n", reason);
                    591:                        }
                    592:                        close(newconn);
                    593:                        Xfree(reason);
                    594:                    }
                    595: 
                    596:                }
                    597:            }
                    598:            readyconnections &= ~(1 << curconn);
                    599:        }
                    600:     }
                    601: }
                    602: 
                    603: /************
                    604:  *   CloseDwonFileDescriptor:
                    605:  *     Remove this file descriptor and it's inputbuffers, etc.
                    606:  ************/
                    607: 
                    608: void
                    609: CloseDownFileDescriptor(connection)
                    610:     long connection;
                    611: {
                    612:     close(connection);
                    613: 
                    614:     inputBuffers[connection].bufptr = inputBuffers[connection].buffer;
                    615:     inputBuffers[connection].bufcnt = 0;
                    616:     inputBuffers[connection].lenLastReq = 0;
                    617:     inputBuffers[connection].used = 0;
                    618: 
                    619:     BITCLEAR(AllSockets, connection);
                    620:     BITCLEAR(AllClients, connection);
                    621:     BITCLEAR(ClientsWithInput, connection);
                    622: 
                    623: }
                    624: 
                    625: /*****************
                    626:  * CheckConections
                    627:  *    Some connection has died, go find which one and shut it down 
                    628:  *    The file descriptor has been closed, but is still in AllClients.
                    629:  *    If would truly be wonderful if select() would put the bogus
                    630:  *    file descriptors in the exception mask, but nooooo.  So we have
                    631:  *    to check each and every socket individually.
                    632:  *****************/
                    633: 
                    634: void
                    635: CheckConnections()
                    636: {
                    637:     long               mask[mskcnt];
                    638:     long               tmask[mskcnt]; 
                    639:     register int       curclient;
                    640:     int                        i;
                    641:     struct timeval     notime;
                    642:     ClientPtr           bad;
                    643:     int r;
                    644: 
                    645:     notime.tv_sec = 0;
                    646:     notime.tv_usec = 0;
                    647: 
                    648:     COPYBITS(AllClients, mask);
                    649:     for (i=0; i<mskcnt; i++)
                    650:     {
                    651:         while (mask[i])
                    652:        {
                    653:            curclient = ffs (mask[i]) - 1 + (i << 5);
                    654:             CLEARBITS(tmask);
                    655:             BITSET(tmask, curclient);
                    656:             r = select (curclient + 1, tmask, (int *)NULL, (int *)NULL, 
                    657:                        &notime);
                    658:             if (r < 0)
                    659:             {
                    660:                if (bad = ConnectionTranslation[curclient])
                    661:                    CloseDownClient(bad);
                    662:                 else
                    663:                     CloseDownFileDescriptor(curclient);
                    664:             }
                    665:            BITCLEAR(mask, curclient);
                    666:        }
                    667:     }  
                    668: }
                    669: 
                    670: 
                    671: /*****************
                    672:  * CloseDownConnection
                    673:  *    Delete client from AllClients and free resources 
                    674:  *****************/
                    675: 
                    676: CloseDownConnection(client)
                    677:     ClientPtr client;
                    678: {
                    679:     int connection = ((osPrivPtr)client->osPrivate)->fd;
                    680: 
                    681:     ConnectionTranslation[connection] = (ClientPtr)NULL;
                    682:     CloseDownFileDescriptor(connection);
                    683:     Xfree(client->osPrivate);
                    684: }
                    685: 
                    686: 
                    687: AddEnabledDevice(fd)
                    688:     int fd;
                    689: {
                    690:     EnabledDevices |= (1<<fd);
                    691:     BITSET(AllSockets, fd);
                    692: }
                    693: 
                    694: 
                    695: RemoveEnabledDevice(fd)
                    696:     int fd;
                    697: {
                    698:     EnabledDevices &= ~(1<<fd);
                    699:     BITCLEAR(AllSockets, fd);
                    700: }
                    701: 
                    702: /*****************
                    703:  * OnlyListenToOneClient:
                    704:  *    Only accept requests from  one client.  Continue to handle new
                    705:  *    connections, but don't take any protocol requests from the new
                    706:  *    ones.  Note that if GrabDone is set, EstablishNewConnections
                    707:  *    needs to put new clients into SavedAllSockets and SavedAllClients.
                    708:  *    Note also that there is no timeout for this in the protocol.
                    709:  *    This routine is "undone" by ListenToAllClients()
                    710:  *****************/
                    711: 
                    712: OnlyListenToOneClient(client)
                    713:     ClientPtr client;
                    714: {
                    715:     int connection = ((osPrivPtr)client->osPrivate)->fd;
                    716: 
                    717:     if (! GrabDone)
                    718:     {
                    719:        COPYBITS (ClientsWithInput, SavedClientsWithInput);
                    720:         BITCLEAR (SavedClientsWithInput, connection);
                    721:        if (GETBIT(ClientsWithInput, connection))
                    722:        {
                    723:            CLEARBITS(ClientsWithInput);            
                    724:            BITSET(ClientsWithInput, connection);
                    725:        }
                    726:        else
                    727:         {
                    728:            CLEARBITS(ClientsWithInput);            
                    729:        }
                    730:        COPYBITS(AllSockets, SavedAllSockets);
                    731:        COPYBITS(AllClients, SavedAllClients);
                    732: 
                    733:        UNSETBITS(AllSockets, AllClients);
                    734:        BITSET(AllSockets, connection);
                    735:        CLEARBITS(AllClients);
                    736:        BITSET(AllClients, connection);
                    737:        GrabDone = TRUE;
                    738:     }
                    739: }
                    740: 
                    741: /****************
                    742:  * ListenToAllClients:
                    743:  *    Undoes OnlyListentToOneClient()
                    744:  ****************/
                    745: 
                    746: ListenToAllClients()
                    747: {
                    748:     if (GrabDone)
                    749:     {
                    750:        ORBITS(AllSockets, AllSockets, SavedAllSockets);
                    751:        ORBITS(AllClients, AllClients, SavedAllClients);
                    752:        ORBITS(ClientsWithInput, ClientsWithInput, SavedClientsWithInput);
                    753:        GrabDone = FALSE;
                    754:     }  
                    755: }
                    756: 
                    757: 

unix.superglobalmegacorp.com

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