📄 sockets.c
字号:
* open_unix_port() * * Given a port and host name open a socket connection * to that service protocol on that host. * * RETURNS: * 0 if all went ok * -1 if not. */int open_unix_port ( int *sock, /* handle to socket id to open */ const char *sockname, /* pathname of port to open */ int mode) /* SERVER or CLIENT */{ int result; if (mode == SERVER) result = open_server_socket (sock, sockname, AF_UNIX, 0); else result = open_client_socket (sock, sockname, "", AF_UNIX, 0); return(result);}/*+------------------------------------------------------------------------ * open_client_socket() * * Given a service and host name open a socket connection * to that service protocol on that host as a client of the * service. * * RETURNS: * 0 if all went ok * -1 if not. * *________________________________________________________________________*/static intopen_client_socket( int *sock, /* handle to socket id to open */ const char *service_name,/* find in /etc/services */ const char *host_name, /* String containing host name */ int domain, /* AF_UNIX or AF_INET */ int port) /* Port # if service name is NULL */{ int optval; int optlen; struct hostent *host_entry = (struct hostent *) 0; struct servent *server_entry = (struct servent *) 0; struct sockaddr_in connect_addr; struct sockaddr_un unix_addr; int result; if(sock == NULL) { WARNING_MESSAGE("open_client_socket called with NULL sock"); return(-1); } if(service_name == NULL && port == 0) { WARNING_MESSAGE("open_client_socket called with NULL service_name and bad port number"); return(-1); } if(host_name == NULL) { WARNING_MESSAGE("open_client_socket called with NULL host_name"); return(-1); } if(domain == AF_INET) { if(service_name != (char *) 0) { if ((server_entry = getservbyname (service_name, "tcp")) == NULL) { sprintf(message, "Couldn't get service entry for %s", service_name); WARNING_PERROR(message); return (-1); } } if ((host_entry = gethostbyname (host_name)) == NULL) { sprintf(message, "Couldn't get host entry for %s", host_name); WARNING_PERROR(message); return (-1); } /* Check the host entry for validity */ if (host_entry->h_addrtype != AF_INET) { sprintf(message, "Got unexpected address type %d in host entry.", host_entry->h_addrtype); WARNING_PERROR(message); return (-1); } *sock = socket (domain, SOCK_TYPE, getprotobyname (MEDIUM)->p_proto); if (*sock < 0) { WARNING_PERROR("Error in socket call"); return (-1); } optlen = sizeof(optval); if (getsockopt (*sock, SOL_SOCKET, SO_REUSEADDR, (char *) &optval, &optlen) < 0) { WARNING_PERROR("Error in REUSEADDR getsockopt call"); if(close(*sock) < 0) WARNING_PERROR("Error in socket close"); return (-1); } if(optval == 0) { optval = 1; if (setsockopt (*sock, SOL_SOCKET, SO_REUSEADDR, (char *) &optval, optlen) < 0) { WARNING_PERROR("Error in REUSEASSR setsockopt call"); if(close(*sock) < 0) WARNING_PERROR("Error in socket close"); return (-1); } } #ifdef PLEASE_DONT_ROUTE optlen = sizeof(optval); if (getsockopt (*sock, SOL_SOCKET, SO_DONTROUTE, &optval, &optlen) < 0) { WARNING_PERROR("Error in DONTROUTE getsockopt call"); if(close(*sock) < 0) WARNING_PERROR("Error in socket close"); return (-1); } if(optval == 0) { optval = 1; if (setsockopt (*sock, SOL_SOCKET, SO_DONTROUTE, &optval, optlen) < 0) { WARNING_PERROR("Error in DONTROUTE setsockopt call"); if(close(*sock) < 0) WARNING_PERROR("Error in socket close"); return (-1); } }#endif /* Get ready to establish the socket and bind to it */ bzero ((char *) &connect_addr, sizeof (connect_addr)); bcopy (host_entry->h_addr, (char *) &connect_addr.sin_addr, host_entry->h_length); connect_addr.sin_family = host_entry->h_addrtype; if(server_entry != (struct servent *) 0) { /* Don't know if this is net or host order */ connect_addr.sin_port = server_entry->s_port; } else { connect_addr.sin_port = htons((short)port); } do { result = connect (*sock, (struct sockaddr *) &connect_addr, sizeof (connect_addr)); } while(result == -1 && (errno == EINTR)); if(result == -1) { WARNING_PERROR("Error in connect call"); if(close(*sock) < 0) WARNING_PERROR("Error in socket close"); return (-1); } } else { *sock = socket (AF_UNIX, SOCK_STREAM, 0); if (*sock < 0) { WARNING_PERROR("Error creating UNIX socket"); return(-1); } unix_addr.sun_family = AF_UNIX; if(service_name == (char *) 0) { sprintf(unix_addr.sun_path, "%d", port); } else { strncpy(unix_addr.sun_path, service_name, sizeof(unix_addr.sun_path) - 1); unix_addr.sun_path[sizeof(unix_addr.sun_path) - 1] = '\0'; } if(connect(*sock, (struct sockaddr *) &unix_addr, sizeof(unix_addr)) < 0) { if(quiet_mode == 0) WARNING_PERROR("Error connecting to socket"); if(close(*sock) < 0 && quiet_mode == 0) WARNING_PERROR("Error in socket close"); return(-1); } } return (0);}/*+------------------------------------------------------------------------ * open_server_socket() * * Given a service and host name open a socket connection * to that service protocol on that host as a provider of the * service. * * RETURNS: * 0 if all went ok * -1 if not. * *________________________________________________________________________*/static intopen_server_socket ( int *sock, /* handle to socket id to open */ const char *service_name, /* find in /etc/services */ int domain, /* AF_UNIX or AF_INET */ int port) /* Port number */{ int optval; int optlen; struct servent *server_entry = (struct servent *) 0; struct sockaddr_in connect_addr; struct sockaddr_un unix_addr; if(sock == NULL) { WARNING_MESSAGE("open_server_socket called with NULL sock"); return(-1); } if(service_name == NULL && port == 0) { WARNING_MESSAGE("open_server_socket called with NULL service_name and bad port"); return(-1); } if(domain == AF_INET) { if(service_name != (char *) 0) { server_entry = getservbyname (service_name, "tcp"); if (server_entry == NULL) { sprintf(message, "Couldn't get service entry for %s", service_name); WARNING_PERROR(message); return (-1); } } /* Get ready to establish the socket and bind to it */ /* Clear the structure first */ bzero ((char *) &connect_addr, sizeof (connect_addr)); /* Fill in the port entry */ if(server_entry == (struct servent *) 0) { connect_addr.sin_port = htons((short)port); } else { /* Don't know if this is host or net order */ connect_addr.sin_port = server_entry->s_port; } *sock = socket (domain, SOCK_TYPE, getprotobyname (MEDIUM)->p_proto); if (*sock < 0) { WARNING_PERROR("Error in socket call"); return (-1); } optlen = sizeof(optval); if (getsockopt (*sock, SOL_SOCKET, SO_REUSEADDR, (char *) &optval, &optlen) < 0) { WARNING_PERROR("Error in getsockopt call"); if(close(*sock) < 0) WARNING_PERROR("Error in socket close"); return (-1); } if(optval == 0) { optval = 1; if (setsockopt (*sock, SOL_SOCKET, SO_REUSEADDR, (char *) &optval, optlen) < 0) { WARNING_PERROR("Error in setsockopt call"); if(close(*sock) < 0) WARNING_PERROR("Error in socket close"); return (-1); } } if (bind (*sock, (struct sockaddr *) &connect_addr, sizeof (connect_addr)) < 0) { if(!hunt_mode) WARNING_PERROR("Error in bind call"); if(close(*sock) < 0) WARNING_PERROR("Error in socket close"); return (-1); } } else { *sock = socket (AF_UNIX, SOCK_STREAM, 0); if(*sock < 0) { WARNING_PERROR("Error opening UNIX socket"); return(-1); } unix_addr.sun_family = AF_UNIX; if(service_name == (char *) 0) { sprintf(unix_addr.sun_path, "%d", port); } else { strncpy(unix_addr.sun_path, service_name, sizeof(unix_addr.sun_path) - 1); unix_addr.sun_path[sizeof(unix_addr.sun_path) - 1] = '\0'; } if (bind (*sock, (struct sockaddr *) &unix_addr, sizeof (unix_addr)) < 0) { if(!hunt_mode) WARNING_PERROR("Error in bind call"); if(close(*sock) < 0) WARNING_PERROR("Error in socket close"); return(-1); } } if (listen (*sock, 5) < 0) { WARNING_PERROR("Error in listen call"); close_socket(*sock); return (-1); } return (0);}/*+------------------------------------------------------------------------ * close_socket() * * shut down a socket connection * * RETURNS: * 0 if it closes OK * -1 if not. *________________________________________________________________________*/int close_socket (int sock) /* Socket ID to close */{ int result; if (shutdown (sock, 2) < 0) { DEBUG_MESSAGE("Error in socket shutdown"); /* This is ok, still has to be closed */ } do { result = close(sock); } while(result == -1 && errno == EINTR); if(result < 0) { WARNING_PERROR("Error in socket close"); return(-1); } return (0);}/*+------------------------------------------------------------------------ * accept_socket() * * Given a socket id, accept a connection to that socket and * return a new socket id specific to that connection. * * RETURNS: * 0 if all went ok * -1 if not. *________________________________________________________________________*/static char lastHostAccepted[256];static int lastHostInitialized = 0;char *LastHostAccepted(){ if(lastHostInitialized) return(lastHostAccepted); else return("NoConnectionAcceptedYet");}int accept_socket ( int sock, /* Socket to accept from */ int *new_socket) /* Put new socket number here */{ struct sockaddr_in socket_address; int socket_address_length; struct hostent *connectingHost = (struct hostent *) 0; if(new_socket == NULL) { WARNING_MESSAGE("accept_socket called with NULL new_socket"); return(-1); } socket_address_length = sizeof (socket_address); do { *new_socket = accept (sock, (struct sockaddr *) &socket_address, &socket_address_length); } while (*new_socket ==-1 && errno == EINTR); if (*new_socket < 0) { WARNING_PERROR("Accept failed on socket"); return (-1); } if(socket_address.sin_family == AF_INET) { connectingHost = gethostbyaddr((char *) &socket_address.sin_addr, sizeof(struct in_addr), AF_INET); if(connectingHost != (struct hostent *) 0) { if(connectingHost->h_name != (char *) 0) { strncpy(lastHostAccepted, connectingHost->h_name, sizeof(lastHostAccepted) - 1); lastHostAccepted[sizeof(lastHostAccepted) - 1] = '\0'; lastHostInitialized = 1; } else { strcpy(lastHostAccepted, "UnknownHostName"); lastHostInitialized = 1; } } else { strcpy(lastHostAccepted, "UnknownInternetHost"); lastHostInitialized = 1; } } else if(socket_address.sin_family == AF_UNIX) { gethostname(lastHostAccepted, sizeof(lastHostAccepted) - 1); lastHostAccepted[sizeof(lastHostAccepted) - 1] = '\0'; lastHostInitialized = 1; } else { strcpy(lastHostAccepted, "UnknownNetwork/Host"); lastHostInitialized = 1; } return (0);}/*------------------------------------------------------------------------ * socket_receive() * * Tries to receive a buffer full of stuff from a file descriptor * * RETURNS: * -1 if error * number of bytes received if no error *________________________________________________________________________*/int socket_receive( int fd, /* File descriptor */ void *buf, /* Data buffer to use */ int nbytes) /* # of bytes to get */{ int bytes_to_receive = nbytes; int bytes_received = 0; char *receive_pointer = buf;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -