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

📄 xtransam.c

📁 远程桌面连接工具
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (ERR_STATUS(size)) {	    Error(("TCP/IP read failed (%s)\n", tcpip_why(ERR_CONVERT(size))));	    chandesc->status |= CONN_KILLED;	    chandesc->status &= ~CONN_ALIVE;	    chandesc->signal = -1;	    thread_exit();	}	if (size == 0 || cb_puts(chandesc->circbuf, buffer, size)) {	    if (size != 0) {		Error(("TCP/IP short write to circular buffer for %d\n",		       XAmChanDescToFd(chandesc)));	    } else {		Error(("TCP/IP read failed for client %d\n",		       XAmChanDescToFd(chandesc)));	    }	    chandesc->status |= CONN_KILLED;	    chandesc->status &= ~CONN_ALIVE;	    chandesc->signal = -1;	    thread_exit();	}	UnblockMain(XAmChanDescToFd(chandesc));    }}static XAmChanDesc *AllocClientChannel(){    XAmChanDesc *chandesc;    int fd;    chandesc = XAmAllocChanDesc();    if (chandesc == NULL) {	return NULL;    }    fd = XAmChanDescToFd(chandesc);    if (fd >= maxClient) {	maxClient = fd + 1;	dbprintf(("new max Client: %d\n", fd));    }    if (fd < minClient) {	minClient = fd;    }    return chandesc;}static errstatAmRegisterRPCconn(client_ports, server_ports)am_port_t client_ports[2];am_port_t server_ports[2];{    XAmChanDesc *chandesc;    if ((chandesc = AllocClientChannel()) == NULL) {	return STD_NOSPACE;    }    chandesc->type = ACDT_VIRTCIRC;    chandesc->virtcirc = vc_create(&server_ports[0], &server_ports[1],				   MAXBUFSIZE, MAXBUFSIZE);    if (chandesc->virtcirc == NULL) {	Error(("Connection refused: No memory for virtual circuit\n"));	XAmFreeChanDesc(chandesc);	return STD_NOSPACE;    }    dbprintf(("Amoeba connection registered\n"));    vc_warn(chandesc->virtcirc, VC_IN, UnblockMain, XAmChanDescToFd(chandesc));        chandesc->status = CONN_INIT;    /* cause WaitFor to call EstablishNewConnections: */    nNewConns++;    WakeUpMainThread();    return STD_OK;}static XAmChanDesc *XAmFetchConnectingClient(){    XAmChanDesc *chandesc;    int fd;    for (fd = minClient; fd < maxClient; fd++) {	chandesc = XAmFdToChanDesc(fd);	if (chandesc->status & CONN_INIT) {	    Error(("Client %d is connecting\n", fd));	    chandesc->status &= ~CONN_INIT;	    return chandesc;	}    }    return NULL;}static errstatAmRegisterTCPconn(chancap)capability *chancap;{    XAmChanDesc *chandesc, **param;    if ((chandesc = AllocClientChannel()) == NULL) {	return STD_NOSPACE;    }        chandesc->type = ACDT_TCPIP;    chandesc->chancap = *chancap;    if ((chandesc->circbuf = cb_alloc(MAXBUFSIZE)) == NULL) {	Error(("TCPconn refused: No memory for circular buffer\n"));	XAmFreeChanDesc(chandesc);	return STD_NOSPACE;    }    chandesc->signal = sig_uniq();    param = (XAmChanDesc **) xalloc(sizeof(XAmChanDesc *)); /* error checking? */    *param = chandesc;    if (thread_newthread(TcpIpReaderThread, MAXBUFSIZE + CONNECTOR_STACK,			 (char *)param, sizeof(XAmChanDesc *)) == 0)    {	Error(("TCPconn refused: Cannot start reader thread\n"));	cb_close(chandesc->circbuf);	cb_free(chandesc->circbuf);	XAmFreeChanDesc(chandesc);	return STD_NOSPACE;    }    dbprintf(("TCP connection registered\n"));    chandesc->status = CONN_INIT;    /* cause WaitFor to call EstablishNewConnections: */    nNewConns++;    WakeUpMainThread();    return STD_OK;}/* * Establishing a new connection is done in two phases. This thread does the * first part. It filters out bad connect requests. A new rendevous port is * sent to the client and the main loop is informed if there is a legal * request. The sleep synchronizes with the main loop so that the paperwork * is finished for the current connect request before the thread is ready to * accept another connect. */static voidAmConnectorThread(){    header	req, rep;    am_port_t	client_ports[2];    am_port_t	server_ports[2];    short	s;    char	*repb;    extern	CreateNewClient();    WaitForInitialization();    dbprintf(("AmConnectorThread() running ...\n"));    if ((repb = (char *)xalloc(REPLY_BUFSIZE)) == NULL) {	Fatal(("Amoeba connector thread: malloc failed"));    }    for (;;) {	do {	    req.h_port = X.cap_port;	    s = getreq(&req, NILBUF, 0);	} while (ERR_CONVERT(s) == RPC_ABORTED);	if (ERR_STATUS(s))	    Fatal(("Amoeba connector thread: getreq failed"));	/* TODO: check privilege fields here */	dbprintf(("AmConnectorThread() accepting a request\n"));	switch (req.h_command) {	case STD_INFO:	    rep.h_status = STD_OK;	    sprintf(repb, "X11R6 server on %s", XServerHostName);	    rep.h_size = strlen(repb);	    putrep(&rep, repb, rep.h_size);	    break;	case STD_STATUS:	    rep.h_status = ConnectionStatus(&rep, repb, REPLY_BUFSIZE);	    putrep(&rep, repb, rep.h_size);	    break;#ifdef XSERV_t	case AX_SHUTDOWN:	    rep.h_status = STD_OK;	    putrep(&rep, NILBUF, 0);	    GiveUp(SIGTERM);	    break;	case AX_REINIT:	    rep.h_status = STD_OK;	    putrep(&rep, NILBUF, 0);	    AutoResetServer(SIGINT);	    break;#endif	case AX_CONNECT:	    uniqport(&client_ports[0]);	    uniqport(&server_ports[1]);	    priv2pub(&client_ports[0], &server_ports[0]);	    priv2pub(&server_ports[1], &client_ports[1]);	    rep.h_status = AmRegisterRPCconn(client_ports, server_ports);	    if (rep.h_status == STD_OK) {		putrep(&rep, (bufptr)client_ports, 2*sizeof(am_port_t));	    } else {		putrep(&rep, NILBUF, 0);	    }	    break;	default:	    rep.h_status = STD_COMBAD;	    putrep(&rep, NILBUF, 0);	    break;	}    }}#ifdef XSERV_t/* * To prevent the X-server from generating lots of error messages, * in case the server is gone or when its full. */#define	LOOP_OPEN	1#define	LOOP_SETCONF	2#define	LOOP_LISTEN	4extern char *display;		/* The display number *//* * The TCP/IP connector thread listens to a well known port (6000 + * display number) for connection request. When such a request arrives * it allocates a communication structure and a reader thread. This * thread prevents the main loop from blocking when there's no data. */static voidAmTCPConnectorThread(){    capability		svrcap, chancap;    nwio_tcpconf_t	tcpconf;    nwio_tcpcl_t	tcpconnopt;    char 		name[BUFSIZ];    errstat 		err;    int			result;    int			looping = 0;    strncpy(name, XTcpServerName, BUFSIZ);    if ((err = name_lookup(name, &svrcap)) != STD_OK) {	sprintf(name, "%s/%s", TCP_SVR_NAME, XTcpServerName);	if ((err = name_lookup(name, &svrcap)) != STD_OK)	    Fatal(("Lookup %s failed: %s\n", XTcpServerName, err_why(err)));    }    WaitForInitialization();    dbprintf(("AmTCPConnectorThread() running ...\n"));    for (;;) {	/*	 * Listen to TCP/IP port X_TCP_PORT + display for connections.	 * Some interesting actions have to be taken to keep this connection	 * alive and kicking :-)	 */	if ((err = tcpip_open(&svrcap, &chancap)) != STD_OK) {	    /* the server probably disappeared, just wait for it to return */	    if (looping & LOOP_OPEN) {		Error(("TCP/IP open failed: %s\n", tcpip_why(err)));		looping |= LOOP_OPEN;	    }	    sleep(60);	    (void) name_lookup(name, &svrcap);	    continue;	}	looping &= ~LOOP_OPEN;	tcpconf.nwtc_locport = htons(X_TCP_PORT + atoi(display));	tcpconf.nwtc_flags = NWTC_EXCL | NWTC_LP_SET | NWTC_UNSET_RA | 								NWTC_UNSET_RP;	if ((err = tcp_ioc_setconf(&chancap, &tcpconf)) != STD_OK) {	    /* couldn't configure, probably server space problem */	    if (looping & LOOP_SETCONF) {		Error(("TCP/IP setconf failed: %s\n", tcpip_why(err)));		looping |= LOOP_SETCONF;	    }	    std_destroy(&chancap);	    sleep(60);	    continue;	}	looping &= ~LOOP_SETCONF;	tcpconnopt.nwtcl_flags = 0;	if ((err = tcp_ioc_listen(&chancap, &tcpconnopt)) != STD_OK) {	    /* couldn't listen, definitely a server memory problem */	    if (looping & LOOP_LISTEN) {		Error(("TCP/IP listen failed: %s\n", tcpip_why(err)));		looping |= LOOP_LISTEN;	    }	    std_destroy(&chancap);	    sleep(60);	    continue;	}	looping &= ~LOOP_LISTEN;	if ((err = tcpip_keepalive_cap(&chancap)) != STD_OK) {	    Error(("TCP/IP keep alive failed: %s\n", tcpip_why(err)));	    std_destroy(&chancap);	    continue;	}	err = AmRegisterTCPconn(&chancap);	if (err != STD_OK) {	    Error(("AmRegisterTCPconn failed (%s)\n", err_why(err)));	    std_destroy(&chancap);	}    }}static voidAmStartXserverThreads(chandesc)XAmChanDesc *chandesc;{    char		host[100];    errstat		err;    capability		pubX;    static int		threadsStarted = 0;    /*     * Each time the server is reset this routine is called to     * setup the new well known sockets. For Amoeba we'll just     * keep using the old threads that are already running.     */    if (!threadsStarted) {	threadsStarted = 1;	/*	 * Create a new capability for this X server	 */	if (XServerHostName == NULL)	    XServerHostName = getenv("XHOST");	if (XServerHostName == NULL) {	    Fatal(("XHOST not set, or server host name not given\n"));	}	sprintf(host, "%s/%s:%s", DEF_XSVRDIR, XServerHostName, display);	uniqport(&X.cap_port);	priv2pub(&X.cap_port, &pubX.cap_port);	(void) name_delete(host);	if ((err = name_append(host, &pubX)) != 0) {	    Error(("Cannot create capability %s: %s\n", host, err_why(err)));	    exit(1);	}	/* Allow WaitFor module to initialize */	AmInitWaitFor();	/* Also, initialize main thread locking */	InitMainThread();	/* Initialize and start IOP reader thread */	InitializeIOPServerReader();	/* Start native Amoeba service threads */	if (thread_newthread(AmConnectorThread, CONNECTOR_STACK, 0, 0) <= 0) {	    Fatal(("Cannot start Amoeba connector thread\n"));	}	if (thread_newthread(AmConnectorThread, CONNECTOR_STACK, 0, 0) <= 0) {	    Fatal(("Cannot start Amoeba connector thread\n"));	}	chandesc->type = ACDT_VIRTCIRC;	chandesc->status = CONN_ALIVE;	/*	 * Start TCP/IP service threads	 */	if (XTcpServerName) {	    if (thread_newthread(AmTCPConnectorThread,				 CONNECTOR_STACK, 0, 0) <= 0)		Fatal(("Cannot start TCP connector thread\n"));	    if (thread_newthread(AmTCPConnectorThread,				 CONNECTOR_STACK, 0, 0) <= 0)		Fatal(("Cannot start TCP connector thread\n"));	}    }}intAmFindReadyClients(pClientsReady, mask)int *pClientsReady;long *mask;{    /* Check for clients needing attention.  They may have input,     * or they might be dying.  Ignore the clients not present in     * the file descriptor bit vector `mask'.  This is used for     * implementing server grabs.     * Returns the number of clients having data for us.     */    extern int ConnectionTranslation[];    XAmChanDesc *chandesc;    int fd;    int nready;    /* Since we're scheduled non-preemptively by default, allow the     * listener threads to run first, if needed:     */    threadswitch();    nready = 0;    for (fd = minClient; fd < maxClient; fd++) {	int which;	int n;	if (fd > 0 && (fd % 32) == 0) {	    /* switch to next fd mask */	    mask++;	}	if ((*mask & (1L << fd)) == 0) {	    dbprintf(("skip %d\n", fd));	    continue;	}	chandesc = XAmFdToChanDesc(fd);	if (chandesc->state != ACDS_USED) {	    dbprintf(("AmFindReady: fd %d not in use\n", fd));	    continue;	}	which = ConnectionTranslation[fd];	dbprintf(("checking client %d (fd %d) of %d\n",		  fd, which, maxClient));	if (chandesc->status & CONN_KILLED) {	    dbprintf(("conn killed; close client with fd %d\n", fd));	    CloseDownClient(clients[which]);	    chandesc->status &= ~(CONN_KILLED | CONN_ALIVE);	    continue;	}	if ((chandesc->status & CONN_ALIVE) == 0) {	    dbprintf(("conn with %d is not alive\n", fd));	    continue;	}	/* see if there is data available */	switch (chandesc->type) {	case ACDT_TCPIP:	    n = cb_full(chandesc->circbuf);	    break;	case ACDT_VIRTCIRC:	    n = vc_avail(chandesc->virtcirc, VC_IN);	    break;	default:	    n = -1;	}	if (n < 0) {	    dbprintf(("avail %d; close client %d\n", n, which));	    CloseDownClient(clients[which]);	    continue;	} else {	    if (n > 0) {		*pClientsReady++ = which;		nready++;		dbprintf(("client %d has %d bytes available\n", which, n));	    } else {		dbprintf(("client %d has no data available\n", which, n));	    }	}	/* Clients that already have (possibly inserted) data are found	 * with help from io.c (the ClientsWithData bit array).	 */    }    return nready;}#endif /* XSERV_t */#endif /* XSERV_t || FS_t */staticTRANS(AmSetAddr)(ciptr, chandesc)    XtransConnInfo  ciptr;    XAmChanDesc    *chandesc;{    switch (chandesc->type) {    case ACDT_TCPIP:	/* should really ask the TCP/IP server */	ciptr->family = AF_INET;	ciptr->addr = strdup("XXXXTODO");

⌨️ 快捷键说明

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