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

📄 connection.c

📁 ftam等标准协议服务器和客户端的源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
    struct itimerval	itv;    signal(SIGALRM, TimeOut);    fTimeOut = FALSE;    /* only 1 alarm, please, not 1 per minute */    timerclear(&itv.it_interval);    itv.it_value.tv_sec = TimeOutValue;    itv.it_value.tv_usec = 0;    setitimer(ITIMER_REAL, &itv, (struct itimerval *)NULL);    /* It better not take a full minute to get to the read call */    while (charsWanted && (fTimeOut = setjmp(env)) == FALSE)    {#ifdef ISOCONN	got = SRead(conn, bptr, charsWanted, NOTOK);#else /* ISOCONN */	got = read(conn, bptr, charsWanted);	#endif /* ISOCONN */	if (got <= 0)	    return FALSE;	if(got > 0)	{	    charsWanted -= got;	    bptr += got;	    /* Ok, we got something, reset the timer */ 	    itv.it_value.tv_sec = TimeOutValue;            itv.it_value.tv_usec = 0;	    setitimer(ITIMER_REAL, &itv, (struct itimerval *)NULL);	}    }    /* disable the timer */    timerclear(&itv.it_value);    setitimer(ITIMER_REAL, &itv, (struct itimerval *)NULL);    /* If we got here and we didn't time out, then return TRUE, because     * we must have read what we wanted. If we timed out, return FALSE */    if(fTimeOut && debug_conns)	ErrorF("Timed out on connection %d\n", conn);    return (!fTimeOut);}#ifdef ISOCONN/* * Who's calling us? */getISOpeername (conn, from, alen) int conn;struct TSAPaddr *from;int *alen;{	struct TSAPdisconnect td;	if (TGetAddresses (conn, from, NULLTA, &td) == NOTOK) {		Error(TErrString(td.td_reason));		return TRUE;	};	*alen = sizeof(struct TSAPaddr);	return FALSE;}#endif /* ISOCONN *//***************************************************************** * ClientAuthorized * *    Sent by the client at connection setup: *                typedef struct _xConnClientPrefix { *                   CARD8	byteOrder; *                   BYTE	pad; *                   CARD16	majorVersion, minorVersion; *                   CARD16	nbytesAuthProto;     *                   CARD16	nbytesAuthString;    *                 } xConnClientPrefix; * *     	It is hoped that eventually one protocol will be agreed upon.  In the *        mean time, a server that implements a different protocol than the *        client expects, or a server that only implements the host-based *        mechanism, will simply ignore this information. * *****************************************************************/int ClientAuthorized(conn, pswapped, reason)    long conn;    int  *pswapped;    char **reason;   /* if authorization fails, put reason in here */{    short slen;    union {	struct sockaddr sa;#ifdef UNIXCONN	struct sockaddr_un un;#endif /* UNIXCONN */#ifdef TCPCONN	struct sockaddr_in in;#endif /* TCPCONN */#ifdef DNETCONN	struct sockaddr_dn dn;#endif /* DNETCONN */#ifdef ISOCONN	struct TSAPaddr ts;#endif /* ISOCONN */    } from;    int	fromlen;    xConnClientPrefix xccp;    char auth_proto[100];    char auth_string[100];#ifdef ISOCONN/* * For now we always auth an ISO client!! * should use directory etc etc */    *reason = 0;#endif /* ISOCONN */    if (!ReadBuffer(conn, (char *)&xccp, sizeof(xConnClientPrefix)))    {	/* If they can't even give us this much, just blow them off	 * without an error message */	*reason = 0;        return 0;    }    if (xccp.byteOrder != whichByteIsFirst)    {        	SwapConnClientPrefix(&xccp);	*pswapped = TRUE;    }    else        *pswapped = FALSE;    if ((xccp.majorVersion != X_PROTOCOL) ||	(xccp.minorVersion != X_PROTOCOL_REVISION))    {        #define STR "Protocol version mismatch"        *reason = (char *)xalloc(sizeof(STR));        strcpy(*reason, STR);	if (debug_conns)	    ErrorF("%s\n", STR);#undef STR        return 0;    }    fromlen = sizeof (from);#ifdef ISOCONN    if (SGetPeerName (conn, &(from.ts), &fromlen) ||        InvalidHost (&(from.ts), fromlen)) #else /* ISOCONN */    if (getpeername (conn, &from.sa, &fromlen) ||        InvalidHost (&from.sa, fromlen)) #endif /* ISOCONN */    {#define STR "Server is not authorized to connect to host"	        *reason = (char *)xalloc(sizeof(STR));        strcpy(*reason, STR);#undef STR        return 0;    }       slen = (xccp.nbytesAuthProto + 3) & ~3;      if ( slen )        if (!ReadBuffer(conn, auth_proto, slen))        {#define STR "Length error in xConnClientPrefix for protocol authorization "            *reason = (char *)xalloc(sizeof(STR));            strcpy(*reason, STR);            return 0;#undef STR	}    auth_proto[slen] = '\0';    slen = (xccp.nbytesAuthString + 3) & ~3;       if ( slen)        if (!ReadBuffer(conn, auth_string, slen))        {#define STR "Length error in xConnClientPrefix for protocol string"            *reason = (char *)xalloc(sizeof(STR));            strcpy(*reason, STR);            return 0;#undef STR	}    auth_string[slen] = '\0';    /* At this point, if the client is authorized to change the access control     * list, we should getpeername() information, and add the client to     * the selfhosts list.  It's not really the host machine, but the     * true purpose of the selfhosts list is to see who may change the     * access control list.     */    return(1);}    static int padlength[4] = {0, 3, 2, 1};/***************** * EstablishNewConnections *    If anyone is waiting on listened sockets, accept them. *    Returns a mask with indices of new clients.  Updates AllClients *    and AllSockets. *****************/void#ifdef ISOCONNEstablishNewConnections(newclients, nnew, vecp, vec)    ClientPtr	        *newclients;    int 		*nnew;    int			vecp;    char 		**vec;#else /* ISOCONN */EstablishNewConnections(newclients, nnew)    ClientPtr	        *newclients;    int 		*nnew;#endif /* ISOCONN */{    long readyconnections;     /* mask of listeners that are ready */    long curconn;                  /* fd of listener that's ready */    long newconn;                  /* fd of new client */    int	 swapped;		/* set by ClientAuthorized if connection is				 * swapped */    char *reason;    struct iovec iov[2];#ifdef ISOCONN    struct udvec uv[3];    struct TSAPdisconnect tds;    struct TSAPdisconnect *td = &tds;    struct TSAPstart tsts;    struct TSAPstart *tst = &tsts;#endif /* ISOCONN */    char p[3];#ifdef TCP_NODELAY    union {	struct sockaddr sa;#ifdef UNIXCONN	struct sockaddr_un un;#endif /* UNIXCONN */#ifdef TCPCONN	struct sockaddr_in in;#endif /* TCPCONN */#ifdef DNETCONN	struct sockaddr_dn dn;#endif /* DNETCONN */    } from;    int	fromlen;#endif TCP_NODELAY    *nnew = 0;    if (readyconnections = (LastSelectMask[0] & WellKnownConnections))     {	while (readyconnections) 	{	    curconn = ffs (readyconnections) - 1;#ifdef ISOCONN /* * At this point, a TAccept has finished with a vec > 0 * so we need to init them... */	    if ((newconn = SAccept(curconn, vecp, vec)) >= 0)	    {		fd2family[newconn] = ISODE_IO;#else /* ISOCONN */	    if ((newconn = accept (curconn,				  (struct sockaddr *) NULL, 				  (int *)NULL)) >= 0) 	    {		fd2family[newconn] = UNIX_IO;#endif /* ISOCONN */		if (newconn >= lastfdesc)		{		    if (debug_conns)ErrorF("Didn't make connection: Out of file descriptors for connections\n");#ifdef ISOCONN		    SClose(newconn);#else /* ISOCONN */		    close (newconn);#endif /* ISOCONN */		} 		else 		{		    ClientPtr next = (ClientPtr)NULL;#ifdef TCP_NODELAY#ifdef ISOCONN		    if (fd2family(newconn) == UNIX_IO) 		    {#endif /* ISOCONN */		    fromlen = sizeof (from);                    if (!getpeername (newconn, &from.sa, &fromlen))		    {			if (fromlen && (from.sa.sa_family == AF_INET)) 			{			    int mi = 1;			    setsockopt (newconn, IPPROTO_TCP, TCP_NODELAY,				       (char *)&mi, sizeof (int));			}		    }#ifdef ISOCONN		    }#endif /* ISOCONN */#endif /* TCP_NODELAY */		    if (ClientAuthorized(newconn, &swapped, &reason))		    {#ifdef	hpux			/*			 * HPUX does not have  FNDELAY			 */		        {			    int	arg;			    arg = 1;			    ioctl(newconn, FIOSNBIO, &arg);		        }#else		        fcntl (newconn, F_SETFL, FNDELAY);#endif /* hpux */			inputBuffers[newconn].used = 1;                         if (! inputBuffers[newconn].size) 			{			    inputBuffers[newconn].buffer = 					(char *)xalloc(BUFSIZE);			    inputBuffers[newconn].size = BUFSIZE;			    inputBuffers[newconn].bufptr = 						inputBuffers[newconn].buffer;			}			if (GrabDone)			{			    BITSET(SavedAllClients, newconn);			    BITSET(SavedAllSockets, newconn);		        }			else			{			    BITSET(AllClients, newconn);			    BITSET(AllSockets, newconn);		        }			next = NextAvailableClient();			if (next != (ClientPtr)NULL)			{			   OsCommPtr priv;			   newclients[(*nnew)++] = next;			   next->swapped = swapped;			   ConnectionTranslation[newconn] = next;			   priv =  (OsCommPtr)xalloc(sizeof(OsCommRec));			   priv->fd = newconn;			   priv->buf = (unsigned char *)					xalloc(OutputBufferSize);			   priv->bufsize = OutputBufferSize;			   priv->count = 0;			   next->osPrivate = (pointer)priv;		        }			else			{#define STR "Maximum number of clients exceeded"			   reason = (char *)xalloc(sizeof(STR));			   strcpy(reason, STR);#undef STR			}		    }		    if (next == (ClientPtr)NULL)		    {			xConnSetupPrefix c;			if(reason)			{			    c.success = xFalse;			    c.lengthReason = strlen(reason);			    c.length = (c.lengthReason + 3) >> 2;			    c.majorVersion = X_PROTOCOL;			    c.minorVersion = X_PROTOCOL_REVISION;			    if(swapped)			    {				int	n;				swaps(&c.majorVersion, n);				swaps(&c.minorVersion, n);				swaps(&c.length, n);			    }#ifdef ISOCONN			    (void)SWrite(newconn, (char *)&c, sizeof(xConnSetupPrefix)); #else /* ISOCONN */			    write(newconn, (char *)&c, sizeof(xConnSetupPrefix)); #endif /* ISOCONN */			    iov[0].iov_len = c.lengthReason;			    iov[0].iov_base = reason;			    iov[1].iov_len = padlength[c.lengthReason & 3];			    iov[1].iov_base = p;#ifdef ISOCONN			    SWritev(newconn, iov, 2);#else /* ISOCONN */			    writev(newconn, iov, 2);#endif /* ISOCONN */			    if (debug_conns)			        ErrorF("Didn't make connection:%s\n", reason);			}#ifdef ISOCONN			SClose(newconn);#else /* ISOCONN */			close(newconn);#endif /* ISOCONN */			xfree(reason);		    }		}	    }	    readyconnections &= ~(1 << curconn);	}    }}/************ *   CloseDownFileDescriptor: *     Remove this file descriptor and it's inputbuffers, etc. ************/voidCloseDownFileDescriptor(connection)    int connection;{#ifdef ISOCONN    struct TSAPdisconnect tds;#ifdef ISODEBUG	if (isodexbug)		fprintf(stderr, "server: TDiscReq\n");#endif /* ISODEBUG */    SClose(connection);#else /* ISOCONN */    close(connection);#endif /* ISOCONN */    if (inputBuffers[connection].size)    {	xfree(inputBuffers[connection].buffer);	inputBuffers[connection].buffer = (char *) NULL;	inputBuffers[connection].bufptr = (char *) NULL;	inputBuffers[connection].size = 0;    }    inputBuffers[connection].bufcnt = 0;    inputBuffers[connection].lenLastReq = 0;    inputBuffers[connection].used = 0;    BITCLEAR(AllSockets, connection);    BITCLEAR(AllClients, connection);    BITCLEAR(ClientsWithInput, connection);    BITCLEAR(ClientsWriteBlocked, connection);    if (!ANYSET(ClientsWriteBlocked))    	AnyClientsWriteBlocked = FALSE;}/***************** * CheckConections *    Some connection has died, go find which one and shut it down  *    The file descriptor has been closed, but is still in AllClients. *    If would truly be wonderful if select() would put the bogus *    file descriptors in the exception mask, but nooooo.  So we have *    to check each and every socket individually. *****************/voidCheckConnections(){    long		mask[mskcnt];    long		tmask[mskcnt];     register int	curclient;    int			i;    struct timeval	notime;    ClientPtr           bad;    int r;#ifdef ISOCONN    struct TSAPdisconnect tds;    struct TSAPdisconnect *td = &tds;    char *vec[4];    int vecp;#endif /* ISOCONN */    notime.tv_sec = 0;    notime.tv_usec = 0;    COPYBITS(AllClients, mask);    for (i=0; i<mskcnt; i++)    {        while (mask[i])    	{	    curclient = ffs (mask[i]) - 1 + (i << 5);            CLEARBITS(tmask);            BITSET(tmask, curclient);#ifdef ISOCONN            r = TNetAccept (&vecp, vec,			curclient + 1, tmask, (int *)NULL, (int *)NULL, 			OK, td);            if (r == NOTOK)            {		Error(TErrString(td->td_reason));		Error("TNetAccept");#else /* ISOCONN */            r = select (curclient + 1, tmask, (int *)NULL, (int *)NULL, 			&notime);            if (r < 0)            {#endif /* ISOCONN */	        if (bad = ConnectionTranslation[curclient])    		    CloseDownClient(bad);                else                    CloseDownFileDescriptor(curclient);            }	    BITCLEAR(mask, curclient);	}    }	}/***************** * CloseDownConnection *    Delete client from AllClients and free resources  *****************/CloseDownConnection(client)    ClientPtr client;{    OsCommPtr oc = (OsCommPtr)client->osPrivate;    ConnectionTranslation[oc->fd] = (ClientPtr)NULL;    CloseDownFileDescriptor(oc->fd);    if (oc->buf != NULL) /* an Xrealloc may have returned NULL */	xfree(oc->buf);    xfree(client->osPrivate);}AddEnabledDevice(fd)    int fd;{    EnabledDevices |= (1<<fd);    BITSET(AllSockets, fd);}RemoveEnabledDevice(fd)    int fd;{    EnabledDevices &= ~(1<<fd);    BITCLEAR(AllSockets, fd);}/***************** * OnlyListenToOneClient: *    Only accept requests from  one client.  Continue to handle new *    connections, but don't take any protocol requests from the new *    ones.  Note that if GrabDone is set, EstablishNewConnections *    needs to put new clients into SavedAllSockets and SavedAllClients. *    Note also that there is no timeout for this in the protocol. *    This routine is "undone" by ListenToAllClients() *****************/OnlyListenToOneClient(client)    ClientPtr client;{    OsCommPtr oc = (OsCommPtr)client->osPrivate;    int connection = oc->fd;    if (! GrabDone)    {	COPYBITS (ClientsWithInput, SavedClientsWithInput);        BITCLEAR (SavedClientsWithInput, connection);	if (GETBIT(ClientsWithInput, connection))	{	    CLEARBITS(ClientsWithInput);	    	    BITSET(ClientsWithInput, connection);	}	else        {	    CLEARBITS(ClientsWithInput);	    	}	COPYBITS(AllSockets, SavedAllSockets);	COPYBITS(AllClients, SavedAllClients);	UNSETBITS(AllSockets, AllClients);	BITSET(AllSockets, connection);	CLEARBITS(AllClients);	BITSET(AllClients, connection);	GrabDone = TRUE;    }}/**************** * ListenToAllClients: *    Undoes OnlyListentToOneClient() ****************/ListenToAllClients(){    if (GrabDone)    {	ORBITS(AllSockets, AllSockets, SavedAllSockets);	ORBITS(AllClients, AllClients, SavedAllClients);	ORBITS(ClientsWithInput, ClientsWithInput, SavedClientsWithInput);	GrabDone = FALSE;    }	}

⌨️ 快捷键说明

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