Annotation of researchv9/X11/src/X.V11R1/server/os/4.2bsd/connection.c, revision 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.