?? xtranssock.c
字號:
"SocketReopenCOTSServer(%d, %s)\n", fd, port, 0); SocketInitOnce(); if ((i = TRANS(SocketSelectFamily) (thistrans->TransName)) < 0) { PRMSG (1, "SocketReopenCOTSServer: Unable to determine socket type for %s\n", thistrans->TransName, 0, 0); return NULL; } if ((ciptr = TRANS(SocketReopen) ( i, Sockettrans2devtab[i].devcotsname, fd, port)) == NULL) { PRMSG (1, "SocketReopenCOTSServer: Unable to reopen socket for %s\n", thistrans->TransName, 0, 0); return NULL; } /* Save the index for later use */ ciptr->index = i; return ciptr;}static XtransConnInfoTRANS(SocketReopenCLTSServer) (thistrans, fd, port)Xtransport *thistrans;int fd;char *port;{ XtransConnInfo ciptr; int i; PRMSG (2, "SocketReopenCLTSServer(%d, %s)\n", fd, port, 0); SocketInitOnce(); if ((i = TRANS(SocketSelectFamily) (thistrans->TransName)) < 0) { PRMSG (1, "SocketReopenCLTSServer: Unable to determine socket type for %s\n", thistrans->TransName, 0, 0); return NULL; } if ((ciptr = TRANS(SocketReopen) ( i, Sockettrans2devtab[i].devcotsname, fd, port)) == NULL) { PRMSG (1, "SocketReopenCLTSServer: Unable to reopen socket for %s\n", thistrans->TransName, 0, 0); return NULL; } /* Save the index for later use */ ciptr->index = i; return ciptr;}#endif /* TRANS_REOPEN */static intTRANS(SocketSetOption) (ciptr, option, arg)XtransConnInfo ciptr;int option;int arg;{ PRMSG (2,"SocketSetOption(%d,%d,%d)\n", ciptr->fd, option, arg); return -1;}#ifdef TRANS_SERVERstatic intTRANS(SocketCreateListener) (ciptr, sockname, socknamelen)XtransConnInfo ciptr;struct sockaddr *sockname;int socknamelen;{ int namelen = socknamelen; int fd = ciptr->fd; int retry; PRMSG (3, "SocketCreateListener(%x,%d)\n", ciptr, fd, 0); if (Sockettrans2devtab[ciptr->index].family == AF_INET) retry = 20; else retry = 0; while (bind (fd, (struct sockaddr *) sockname, namelen) < 0) { if (errno == EADDRINUSE) return TRANS_ADDR_IN_USE; if (retry-- == 0) { PRMSG (1, "SocketCreateListener: failed to bind listener\n", 0, 0, 0); close (fd); return TRANS_CREATE_LISTENER_FAILED; }#ifdef SO_REUSEADDR sleep (1);#else sleep (10);#endif /* SO_REUSEDADDR */ } if (Sockettrans2devtab[ciptr->index].family == AF_INET) {#ifdef SO_DONTLINGER setsockopt (fd, SOL_SOCKET, SO_DONTLINGER, (char *) NULL, 0);#else#ifdef SO_LINGER { static int linger[2] = { 0, 0 }; setsockopt (fd, SOL_SOCKET, SO_LINGER, (char *) linger, sizeof (linger)); }#endif#endif} if (listen (fd, BACKLOG) < 0) { PRMSG (1, "SocketCreateListener: listen() failed\n", 0, 0, 0); close (fd); return TRANS_CREATE_LISTENER_FAILED; } /* Set a flag to indicate that this connection is a listener */ ciptr->flags = 1; return 0;}#ifdef TCPCONNstatic intTRANS(SocketINETCreateListener) (ciptr, port)XtransConnInfo ciptr;char *port;{ struct sockaddr_in sockname; int namelen = sizeof(sockname); int status; short tmpport; _Xgetservbynameparams sparams; struct servent *servp;#define PORTBUFSIZE 64 /* what is a real size for this? */ char portbuf[PORTBUFSIZE]; PRMSG (2, "SocketINETCreateListener(%s)\n", port, 0, 0);#ifdef X11_t /* * X has a well known port, that is transport dependent. It is easier * to handle it here, than try and come up with a transport independent * representation that can be passed in and resolved the usual way. * * The port that is passed here is really a string containing the idisplay * from ConnectDisplay(). */ if (is_numeric (port)) { tmpport = (short) atoi (port); sprintf (portbuf,"%d", X_TCP_PORT+tmpport); } else strncpy (portbuf, port, PORTBUFSIZE); port = portbuf;#endif if (port && *port) { /* Check to see if the port string is just a number (handles X11) */ if (!is_numeric (port)) { if ((servp = _XGetservbyname (port,"tcp",sparams)) == NULL) { PRMSG (1, "SocketINETCreateListener: Unable to get service for %s\n", port, 0, 0); return TRANS_CREATE_LISTENER_FAILED; } sockname.sin_port = servp->s_port; } else { tmpport = (short) atoi (port); sockname.sin_port = htons (tmpport); } } else sockname.sin_port = htons (0);#ifdef BSD44SOCKETS sockname.sin_len = sizeof (sockname);#endif sockname.sin_family = AF_INET; sockname.sin_addr.s_addr = htonl (INADDR_ANY); if ((status = TRANS(SocketCreateListener) (ciptr, (struct sockaddr *) &sockname, namelen)) < 0) { PRMSG (1, "SocketINETCreateListener: ...SocketCreateListener() failed\n", 0, 0, 0); return status; } if (TRANS(SocketINETGetAddr) (ciptr) < 0) { PRMSG (1, "SocketINETCreateListener: ...SocketINETGetAddr() failed\n", 0, 0, 0); return TRANS_CREATE_LISTENER_FAILED; } return 0;}#endif /* SOCKCONN */#ifdef UNIXCONNstaticTRANS(SocketUNIXCreateListener) (ciptr, port)XtransConnInfo ciptr;char *port;{ struct sockaddr_un sockname; int namelen; int oldUmask; int status; PRMSG (2, "SocketUNIXCreateListener(%s)\n", port ? port : "NULL", 0, 0); /* Make sure the directory is created */ oldUmask = umask (0);#ifdef UNIX_DIR if (!mkdir (UNIX_DIR, 0777)) chmod (UNIX_DIR, 0777);#endif sockname.sun_family = AF_UNIX; if (port && *port) { if (*port == '/') { /* a full pathname */ sprintf (sockname.sun_path, "%s", port); } else { sprintf (sockname.sun_path, "%s%s", UNIX_PATH, port); } } else { sprintf (sockname.sun_path, "%s%d", UNIX_PATH, getpid()); }#if defined(BSD44SOCKETS) && !defined(Lynx) sockname.sun_len = strlen(sockname.sun_path); namelen = SUN_LEN(&sockname);#else namelen = strlen(sockname.sun_path) + sizeof(sockname.sun_family);#endif unlink (sockname.sun_path); if ((status = TRANS(SocketCreateListener) (ciptr, (struct sockaddr *) &sockname, namelen)) < 0) { PRMSG (1, "SocketUNIXCreateListener: ...SocketCreateListener() failed\n", 0, 0, 0); return status; } /* * Now that the listener is esablished, create the addr info for * this connection. getpeername() doesn't work for UNIX Domain Sockets * on some systems (hpux at least), so we will just do it manually, instead * of calling something like TRANS(SocketUNIXGetAddr). */ namelen = sizeof (sockname); /* this will always make it the same size */ if ((ciptr->addr = (char *) xalloc (namelen)) == NULL) { PRMSG (1, "SocketUNIXCreateListener: Can't allocate space for the addr\n", 0, 0, 0); return TRANS_CREATE_LISTENER_FAILED; } ciptr->family = sockname.sun_family; ciptr->addrlen = namelen; memcpy (ciptr->addr, &sockname, ciptr->addrlen); (void) umask (oldUmask); return 0;}staticTRANS(SocketUNIXResetListener) (ciptr)XtransConnInfo ciptr;{ /* * See if the unix domain socket has disappeared. If it has, recreate it. */ struct sockaddr_un *unsock = (struct sockaddr_un *) ciptr->addr; struct stat statb; int status = TRANS_RESET_NOOP; void TRANS(FreeConnInfo) (); PRMSG (3, "SocketUNIXResetListener(%x,%d)\n", ciptr, ciptr->fd, 0); if (stat (unsock->sun_path, &statb) == -1 || ((statb.st_mode & S_IFMT) !=#if (defined (sun) && defined(SVR4)) || defined(NCR) || defined(SCO) || defined(sco) || !defined(S_IFSOCK) S_IFIFO))#else S_IFSOCK))#endif { int oldUmask = umask (0);#ifdef UNIX_DIR if (!mkdir (UNIX_DIR, 0777)) chmod (UNIX_DIR, 0777);#endif close (ciptr->fd); unlink (unsock->sun_path); if ((ciptr->fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) { TRANS(FreeConnInfo) (ciptr); return TRANS_RESET_FAILURE; } if (bind (ciptr->fd, (struct sockaddr *) unsock, ciptr->addrlen) < 0) { close (ciptr->fd); TRANS(FreeConnInfo) (ciptr); return TRANS_RESET_FAILURE; } if (listen (ciptr->fd, BACKLOG) < 0) { close (ciptr->fd); TRANS(FreeConnInfo) (ciptr); return TRANS_RESET_FAILURE; } umask (oldUmask); status = TRANS_RESET_NEW_FD; } return status;}#endif /* UNIXCONN */#ifdef TCPCONNstatic XtransConnInfoTRANS(SocketINETAccept) (ciptr, status)XtransConnInfo ciptr;int *status;{ XtransConnInfo newciptr; struct sockaddr_in sockname; int namelen = sizeof(sockname); PRMSG (2, "SocketINETAccept(%x,%d)\n", ciptr, ciptr->fd, 0); if ((newciptr = (XtransConnInfo) xcalloc ( 1, sizeof(struct _XtransConnInfo))) == NULL) { PRMSG (1, "SocketINETAccept: malloc failed\n", 0, 0, 0); *status = TRANS_ACCEPT_BAD_MALLOC; return NULL; } if ((newciptr->fd = accept (ciptr->fd, (struct sockaddr *) &sockname, &namelen)) < 0) { PRMSG (1, "SocketINETAccept: accept() failed\n", 0, 0, 0); xfree (newciptr); *status = TRANS_ACCEPT_FAILED; return NULL; }#ifdef TCP_NODELAY { /* * turn off TCP coalescence for INET sockets */ int tmp = 1; setsockopt (newciptr->fd, IPPROTO_TCP, TCP_NODELAY, (char *) &tmp, sizeof (int)); }#endif /* * Get this address again because the transport may give a more * specific address now that a connection is established. */ if (TRANS(SocketINETGetAddr) (newciptr) < 0) { PRMSG (1, "SocketINETAccept: ...SocketINETGetAddr() failed:\n", 0, 0, 0); close (newciptr->fd); xfree (newciptr); *status = TRANS_ACCEPT_MISC_ERROR; return NULL; } if (TRANS(SocketINETGetPeerAddr) (newciptr) < 0) { PRMSG (1, "SocketINETAccept: ...SocketINETGetPeerAddr() failed:\n", 0, 0, 0); close (newciptr->fd); if (newciptr->addr) xfree (newciptr->addr); xfree (newciptr); *status = TRANS_ACCEPT_MISC_ERROR; return NULL; } *status = 0; return newciptr;}#endif /* TCPCONN */#ifdef UNIXCONNstatic XtransConnInfoTRANS(SocketUNIXAccept) (ciptr, status)XtransConnInfo ciptr;int *status;{ XtransConnInfo newciptr; struct sockaddr_un sockname;#if defined(SVR4) || defined(SCO325) size_t namelen = sizeof sockname;#else int namelen = sizeof sockname;#endif PRMSG (2, "SocketUNIXAccept(%x,%d)\n", ciptr, ciptr->fd, 0); if ((newciptr = (XtransConnInfo) xcalloc ( 1, sizeof(struct _XtransConnInfo))) == NULL) { PRMSG (1, "SocketUNIXAccept: malloc() failed\n", 0, 0, 0); *status = TRANS_ACCEPT_BAD_MALLOC; return NULL; } if ((newciptr->fd = accept (ciptr->fd, (struct sockaddr *) &sockname, &namelen)) < 0) { PRMSG (1, "SocketUNIXAccept: accept() failed\n", 0, 0, 0); xfree (newciptr); *status = TRANS_ACCEPT_FAILED; return NULL; } /* * Get the socket name and the peer name from the listener socket, * since this is unix domain. */ if ((newciptr->addr = (char *) xalloc (ciptr->addrlen)) == NULL) { PRMSG (1, "SocketUNIXAccept: Can't allocate space for the addr\n", 0, 0, 0); close (newciptr->fd); xfree (newciptr); *status = TRANS_ACCEPT_BAD_MALLOC; return NULL; } newciptr->addrlen = ciptr->addrlen; memcpy (newciptr->addr, ciptr->addr, newciptr->addrlen); if ((newciptr->peeraddr = (char *) xalloc (ciptr->addrlen)) == NULL) { PRMSG (1, "SocketUNIXAccept: Can't allocate space for the addr\n", 0, 0, 0); close (newciptr->fd); if (newciptr->addr) xfree (newciptr->addr); xfree (newciptr); *status = TRANS_ACCEPT_BAD_MALLOC; return NULL; } newciptr->peeraddrlen = ciptr->addrlen; memcpy (newciptr->peeraddr, ciptr->addr, newciptr->addrlen); newciptr->family = AF_UNIX; *status = 0; return newciptr;}#endif /* UNIXCONN */#endif /* TRANS_SERVER */#ifdef TRANS_CLIENT#ifdef TCPCONNstatic intTRANS(SocketINETConnect) (ciptr, host, port)XtransConnInfo ciptr;char *host;char *port;{ struct sockaddr_in sockname;#if defined(SVR4) || defined(SCO325) size_t namelen = sizeof sockname;#else int namelen = sizeof sockname;#endif _Xgethostbynameparams hparams; _Xgetservbynameparams sparams; struct hostent *hostp; struct servent *servp;#define PORTBUFSIZE 64 /* what is a real size for this? */ char portbuf[PORTBUFSIZE]; int ret; short tmpport; unsigned long tmpaddr; char hostnamebuf[256]; /* tmp space */ PRMSG (2,"SocketINETConnect(%d,%s,%s)\n", ciptr->fd, host, port); if (!host) { hostnamebuf[0] = '\0'; (void) TRANS(GetHostname) (hostnamebuf, sizeof hostnamebuf); host = hostnamebuf; }#ifdef X11_t /* * X has a well known port, that is transport dependent. It is easier * to handle it here, than try and come up with a transport independent * representation that can be passed in and resolved the usual way. * * The port that is passed here is really a string containing the idisplay * from ConnectDisplay(). */ if (is_numeric (port)) { tmpport = (short) atoi (port); sprintf (portbuf, "%d", X_TCP_PORT + tmpport); } else#endif strncpy (portbuf, port, PORTBUFSIZE); /* * Build the socket name. */#ifdef BSD44SOCKETS sockname.sin_len = sizeof (struct sockaddr_in);#endif sockname.sin_family = AF_INET; /* * fill in sin_addr */ /* check for ww.xx.yy.zz host string */ if (isascii (host[0]) && isdigit (host[0])) { tmpaddr = inet_addr (host); /* returns network byte order */ } else { tmpaddr = -1; } PRMSG (4,"SocketINETConnect: inet_addr(%s) = %x\n", host, tmpaddr, 0); if (tmpaddr == -1) { if ((hostp = _XGethostbyname(host,hparams)) == NULL) { PRMSG (1,"SocketINETConnect: Can't get address for %s\n", host, 0, 0); ESET(EINVAL); return TRANS_CONNECT_FAILED; } if (hostp->h_addrtype != AF_INET) /* is IP host? */ { PRMSG (1,"SocketINETConnect: not INET host%s\n", host, 0, 0); ESET(EPROTOTYPE); return TRANS_CONNECT_FAILED; } #if defined(CRAY) && defined(OLDTCP) /* Only Cray UNICOS3 and UNICOS4 will define this */ { long t; memcpy ((char *)&t, (char *) hostp->h_addr, sizeof (t)); sockname.sin_addr = t; }#else memcpy ((char *) &sockname.sin_addr, (char *) hostp->h_addr, sizeof (sockname.sin_addr));#endif /* CRAY and OLDTCP */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -