📄 xtransam.c
字号:
/* * Family type is set to Internet so that the .Xauthority * files from Unix will work under Amoeba (for Unix displays). */ *familyp = AF_INET; *saddrlenp = sizeof(ipaddr_t); *saddrp = xalloc(sizeof(ipaddr_t)); memcpy(*saddrp, (char *)&ipaddr, sizeof(ipaddr_t)); /* error checking? */ } return XAmChanDescToFd(chandesc);}/* * The TCP/IP server silently assumes a maximum buffer size of 30000 bytes. */#define TCPIP_BUFSIZE 16384static voidXAMCloseChannel(chandesc)XAmChanDesc *chandesc;{ if (chandesc->state == ACDS_USED && chandesc->type == ACDT_TCPIP) { cb_close(chandesc->circbuf); chandesc->state = ACDS_CLOSED; }}/* * Shutdown TCP/IP reader thread */static voidXAmReaderSignalCatcher(sig, us, extra) signum sig; thread_ustate *us; _VOIDSTAR extra;{ register XAmChanDesc *chandesc = (XAmChanDesc *)extra; XAMCloseChannel(chandesc); thread_exit();}/* * TCP/IP reader thread */static voidXAmReaderThread(argptr, argsize) void *argptr; int argsize;{ register XAmChanDesc *chandesc; chandesc = *((XAmChanDesc **)argptr); (void) sig_catch(chandesc->signal, XAmReaderSignalCatcher, (_VOIDSTAR) chandesc); while (chandesc->state == ACDS_USED) { char buffer[CIRCBUFSIZE]; bufsize size; size = tcpip_read(&chandesc->chancap, buffer, sizeof(buffer)); if (ERR_STATUS(size) || size == 0) { if (size == 0) { static char msg[] = "Xlib: TCP/IP channel closed\n"; write(2, msg, sizeof(msg)); } else { fprintf(stderr, "Xlib: TCP/IP read failed (%s)\n", err_why(ERR_CONVERT(size))); } XAMCloseChannel(chandesc); break; } if (cb_puts(chandesc->circbuf, buffer, size) != 0) { fprintf(stderr, "Xlib: short write to circular buffer\n"); XAMCloseChannel(chandesc); } } thread_exit();}/* * Wait until input is available or until the timer expires. */intTRANS(AmSelect)(ifd, timout) int ifd; int timout;{ XAmChanDesc *chandesc; int n; errno = 0; chandesc = XAmFdToChanDesc(ifd); if (chandesc == NULL || chandesc->state != ACDS_USED) { errno = EBADF; return -1; } if (chandesc->sema == NULL) { /* Allocate semaphore to sleep on when no data is * available. The underlying circular buffer and * virtual circuit packages manage this semaphore. */ chandesc->sema = (semaphore *) xalloc(sizeof(semaphore)); if (chandesc->sema == NULL) { errno = ENOMEM; return -1; } sema_init(chandesc->sema, 0); switch (chandesc->type) { case ACDT_TCPIP: cb_setsema(chandesc->circbuf, chandesc->sema); break; case ACDT_VIRTCIRC: vc_setsema(chandesc->virtcirc, chandesc->sema); break; } } switch (chandesc->type) { case ACDT_TCPIP: if ((n = cb_full(chandesc->circbuf)) != 0) { if (n < 0) errno = EPIPE; return n; /* includes error as well */ } if (sema_trydown(chandesc->sema, timout) < 0) { errno = EINTR; return -1; } else { /* we down for all the bytes in AMRead, so undo the down */ sema_up(chandesc->sema); } if ((n = cb_full(chandesc->circbuf)) < 0) { errno = EPIPE; return -1; } return n; case ACDT_VIRTCIRC: if ((n = vc_avail(chandesc->virtcirc, VC_IN)) != 0) { if (n < 0) errno = EPIPE; return n; /* includes error as well */ } if (sema_trydown(chandesc->sema, timout) < 0) { errno = EINTR; return -1; } else { /* we down for all the bytes in AMRead, so undo the down */ sema_up(chandesc->sema); } if ((n = vc_avail(chandesc->virtcirc, VC_IN)) < 0) { errno = EPIPE; return -1; } return n; } errno = EINVAL; return -1;}/* * This function gets the local address of the transport and stores it in the * XtransConnInfo structure for the connection. */static intTRANS(AMGetAddr)(ciptr)XtransConnInfo ciptr;{ PRMSG(1,"AMGetAddr(%x)\n", ciptr, 0,0 ); PRMSG(1,"AMGetAddr: TODO\n", 0, 0, 0); return -1;}/* * This function gets the remote address of the socket and stores it in the * XtransConnInfo structure for the connection. */static intTRANS(AMGetPeerAddr)(ciptr)XtransConnInfo ciptr;{ struct nwio_tcpconf tcpconf; errstat err; XAmChanDesc *chandesc; PRMSG(2,"AMGetPeerAddr(%x)\n", ciptr, 0,0 ); chandesc = XAmFdToChanDesc(ciptr->fd); if (chandesc == NULL || chandesc->state != ACDS_USED) { errno = EBADF; return -1; } switch (chandesc->type) { case ACDT_TCPIP: /* get the remote adress from the TCP/IP server */ if ((err = tcp_ioc_getconf(&chandesc->chancap, &tcpconf)) != STD_OK) { PRMSG (1, "AMGetPeerAddr: Cannot get remote address (%d)\n", (int) err, 0, 0); return -1; }#if 0 /* debug */ { struct hostent *remote; char *hostname; remote = gethostbyaddr((char *) &tcpconf.nwtc_remaddr, sizeof(tcpconf.nwtc_remaddr), AF_INET); if ((remote == NULL) || (remote->h_name == NULL)) { hostname = inet_ntoa(tcpconf.nwtc_remaddr); } else { hostname = remote->h_name; } PRMSG (1, "AMGetPeerAddr: remote addr `%s'\n", hostname, 0, 0); }#endif ciptr->peeraddrlen = sizeof(tcpconf.nwtc_remaddr); ciptr->peeraddr = (char *) xalloc (ciptr->peeraddrlen); if (ciptr->peeraddr == NULL) { PRMSG (1, "AMGetPeerAddr: Can't allocate peeraddr\n", 0, 0, 0); return -1; } memcpy (ciptr->peeraddr, &tcpconf.nwtc_remaddr, ciptr->peeraddrlen); break; case ACDT_VIRTCIRC: /* for Amoeba virtual circuits just copy the client address */ if ((ciptr->peeraddr = (char *) xalloc (ciptr->addrlen)) == NULL) { PRMSG (1, "AMGetPeerAddr: Can't allocate peeraddr\n", 0, 0, 0); return -1; } ciptr->peeraddrlen = ciptr->addrlen; memcpy (ciptr->peeraddr, ciptr->addr, ciptr->peeraddrlen); break; } return 0;}static XtransConnInfoTRANS(AMOpen)(device)char *device;{ PRMSG(1,"AMOpen(%s)\n", device, 0,0 ); PRMSG(1,"AMOpen: TODO\n", 0, 0, 0); return NULL;}static intTRANS(AMAddrToNetbuf)(tlifamily, host, port, netbufp)int tlifamily;char *host;char *port;struct netbuf *netbufp;{ PRMSG(1,"AMAddrToNetbuf(%d,%s,%s)\n", tlifamily, host, port ); PRMSG(1,"AMAddrToNetbuf: TODO\n", 0, 0, 0); return -1;}/* * These functions are the interface supplied in the Xtransport structure */#ifdef TRANS_CLIENTstatic XtransConnInfoTRANS(AMOpenCOTSClient)(thistrans, protocol, host, port)Xtransport *thistrans;char *protocol;char *host;char *port;{ XtransConnInfo ciptr; XAmChanDesc *chandesc; PRMSG(2,"AMOpenCOTSClient(%s,%s,%s)\n", protocol, host, port ); ciptr = (XtransConnInfo) xcalloc (1, sizeof(struct _XtransConnInfo)); if (ciptr == NULL) { PRMSG (1, "AMOpenCotsClient: malloc failed\n", 0, 0, 0); return NULL; } ciptr->fd = MakeAmConnection (host, 0 /* TODO */, &ciptr->family, &ciptr->addrlen, &ciptr->addr); if (ciptr->fd < 0) { PRMSG(1,"AMOpenCOTSClient: Unable to make connection to %s\n", host, 0,0 ); xfree(ciptr); return NULL; } /* set the back pointer */ chandesc = XAmFdToChanDesc(ciptr->fd); chandesc->conninfo = ciptr; TRANS(AMGetPeerAddr)(ciptr); PRMSG(2,"AMOpenCOTSClient: made connection to %s; fd = %d, family = %d\n", host, ciptr->fd, ciptr->family); return ciptr;}#endif /* TRANS_CLIENT */#if defined(XSERV_t) || defined(FS_t)/* The following defines come from osdep.h; * they should removed from there eventually. *//* * Some fundamental constants */#define CONNECTOR_STACK 4000 /* stack for connector task */#define DEVREADER_STACK 4000 /* stack for device reader */#define CREATOR_STACK 4000 /* stack for connection creator */#define MAXTASKS 100 /* Maximum # clients *//* * OsComm status bits */#define CONN_KILLED 0x1 /* Connection being closed */#define REQ_PUSHBACK 0x2 /* Request pushed back */#define IGNORE 0x4 /* True if client ignored */#define CONN_INIT 0x8 /* True if still initializing */#define CONN_ALIVE 0x10 /* True if living */#define REPLY_BUFSIZE 30000capability X; /* X capability */char *XServerHostName; /* X server host name */char *XTcpServerName; /* TCP/IP server name */static XtransConnInfo NewConns[MAXTASKS]; /* new client connections */int nNewConns; /* # of new clients */int maxClient; /* Highest allocated client fd + 1*/static int minClient = 1; /* Lowest allocated client fd */static char *OsCommStatus(status) int status;{ static char buf[100]; buf[0] = '\0'; if (status == 0) sprintf(buf, "NONE"); if (status & CONN_INIT) sprintf(buf, "%s INIT", buf); if (status & CONN_ALIVE) sprintf(buf, "%s ALIVE", buf); if (status & CONN_KILLED) sprintf(buf, "%s KILLED", buf); if (status & REQ_PUSHBACK) sprintf(buf, "%s PUSHBACK", buf); if (status & IGNORE) sprintf(buf, "%s IGNORE", buf); return buf;}static char *OsCommFamily(family) int family;{ if (family == FamilyAmoeba) { return "AMOEBA"; } else { return "TCP/IP"; }}/* * Return status information about the open connections */static errstatConnectionStatus(hdr, buf, size) header *hdr; char *buf; int size;{ char *begin, *end; char *bprintf(); int fd; XAmChanDesc *chandesc; begin = buf; end = buf + size; /* all active clients */ begin = bprintf(begin, end, "Active clients:\n"); for (fd = minClient; fd < maxClient; fd++) { static XAmChanDesc *chandesc; chandesc = XAmFdToChanDesc(fd); if (chandesc != NULL && chandesc->conninfo != NULL) { begin = bprintf(begin, end, "%d: Family %s, State %d, Status %s\n", fd, OsCommFamily(chandesc->conninfo->family), chandesc->state, OsCommStatus(chandesc->status)); } } if (begin == NULL) { hdr->h_size = 0; return STD_SYSERR; } else { hdr->h_size = begin - buf; return STD_OK; }}/* * Wakeup main thread if necessary */static voidUnblockMain(fd)int fd;{ XAmChanDesc *chandesc; chandesc = XAmFdToChanDesc(fd); if (chandesc != NULL) { if ((chandesc->status & IGNORE) == 0) { WakeUpMainThread(); } } else { Error(("UnblockMain: invalid fd %d\n", fd)); }}static voidTcpIpReaderSignalCatcher(sig, us, extra) signum sig; thread_ustate *us; _VOIDSTAR extra;{ XAmChanDesc *chandesc = (XAmChanDesc *) extra; if (chandesc->conninfo != NULL) { dbprintf(("TcpIpReaderSignalCatcher(%d), number %d\n", sig, chandesc->conninfo->fd)); if (chandesc->signal != sig) { Error(("TCP/IP Reader: Connection %s got unexpected signal %d\n", chandesc->conninfo->fd, sig)); } } chandesc->signal = -1; thread_exit();}voidTcpIpReaderThread(argptr, argsize) void *argptr; int argsize;{ XAmChanDesc *chandesc; if (argsize != sizeof(XAmChanDesc *)) { Fatal(("Internal error: TcpIpReaderThread incorrectly called\n")); } chandesc = * ((XAmChanDesc **) argptr); (void) sig_catch(chandesc->signal, TcpIpReaderSignalCatcher, (_VOIDSTAR) chandesc); for (;;) { char buffer[MAXBUFSIZE]; bufsize size; size = tcpip_read(&chandesc->chancap, buffer, sizeof(buffer)); dbprintf(("TcpIpReaderThread() read %d bytes\n", size));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -