📄 sockets.c
字号:
/* ********************************************************************** * * <copyright> * * BBN Technologies, a Verizon Company * 10 Moulton Street * Cambridge, MA 02138 * (617) 873-8000 * * Copyright (C) BBNT Solutions LLC. All rights reserved. * * </copyright> * ********************************************************************** * * $Source: /cvs/distapps/openmap/src/cserver/toolLib/src/sockets.c,v $ * $RCSfile: sockets.c,v $ * $Revision: 1.2 $ * $Date: 2004/01/26 19:07:10 $ * $Author: dietrick $ * * ********************************************************************** *//* SYSTEM LEVEL HEADER FILES */#include <stdio.h>#include <sys/types.h>#ifdef _AIX#include <fcntl.h>#else#include <sys/fcntl.h>#endif#include <sys/socket.h>#include <netinet/in.h> /* Order of these matters under Solaris */#include <arpa/inet.h> /* Order of these matters under Solaris */#include <netinet/tcp.h>#include <netdb.h>#if defined(_AIX) || defined(ultrix) || defined(__hpux)#include <sys/ioctl.h>#else#include <sys/filio.h>#endif#include <errno.h>#include <sys/un.h>#include <string.h>#include <sys/param.h>#ifdef SVR4#include <memory.h>#define bzero(addr, n) memset(addr, 0, n)#define bcopy(from, to, n) memcpy(to, from, n)#endif#ifdef c_plusplus#include <sysent.h> #endif/* OTHER HEADER FILES */#include "compat.h"#define DEBUG_ME "DEBUG_TOOLLIB"#include "debugging.h"#include "style.h"#include "sockets.h"#include "error_hand.h"DebugVariable(sockets, "sockets", 0x01); /* LOCAL HEADER FILES *//* LOCAL FUNCTIONS */static int open_client_socket( int *, /* sock */ const char *, /* service_name */ const char *, /* host_name */ int, /* domain */ int /* port */); static int open_server_socket ( int *, /* sock */ const char *, /* service_name */ int, /* domain */ int /* port */); /* Global variables */ #define AF AF_INET#define SOCK_TYPE SOCK_STREAM#define MEDIUM "tcp"static int domain = AF_INET;static char message[1024];static int hunt_mode = 0;static int quiet_mode = 0;/* * Look for a server on the specified host * * Given a service name, hostname, unis port, internet port, and * an int pointer to put the socket number into, try to connect * to that service on the host, or on the local host if the * hostname is not given, preferentially by the unix port, then * by the inet port. * * RETURNS: * -1 on failure, 0 on success */ int LookForServer( const char *service, const char *hostname, int unixPort, int inetPort, int *socketp){ int result; char localhost[MAXHOSTNAMELEN + 1]; if(socketp == (int *) 0) { WARNING_MESSAGE("LookForServer called with NULL socket pointer"); return(-1); } *socketp = -1; if(service == (char *) 0) { WARNING_MESSAGE("LookForServer called with NULL service name"); return(-1); } if(Debug(sockets)) { sprintf(message, "LookForServer(%s, %s, %d, %d, 0x%x)", service, hostname, unixPort, inetPort, socketp); DEBUG_MESSAGE(message); } /* * Algorithm: * * If no hostname is given, try to connect to the local host via * unix port, otherwise connect via inetPort. * * If hostname is given, force connection via inetPort. * */ quiet_mode = 1; if(strlen(hostname) == 0) { result = ConnectToServer(service, hostname, AF_UNIX, unixPort, socketp); if(result < 0) { result = gethostname(localhost, MAXHOSTNAMELEN); if(result < 0) { WARNING_PERROR ("Couldn't get local hostname, using 'localhost'"); strcpy(localhost, "localhost"); } result = ConnectToServer(service, localhost, AF_INET, inetPort, socketp); if(result < 0) { sprintf(msgBuf, "Could not connect to %s anywhere!", service); WARNING_MESSAGE(msgBuf); quiet_mode = 0; return(-1); } } } else { result = ConnectToServer(service, hostname, AF_INET, inetPort, socketp); if(result < 0) { sprintf(msgBuf, "Could not connect to %s anywhere!", service); WARNING_MESSAGE(msgBuf); quiet_mode = 0; return(-1); } } quiet_mode = 0; return(0);}int ConnectToServer( const char *serviceName, const char *hostName, int type, int port, int *socketp){ struct servent *serverEntry = (struct servent *) 0; char thisHost[MAXHOSTNAMELEN + 1]; char sockname[1024]; int result; /* * UNIX connection: * * Build a unix socket path * using the service name and the port */ if(type == AF_UNIX) { sprintf(sockname, "%s/%s.%d", UnixSocketPath, serviceName, port); result = open_unix_port(socketp, sockname, CLIENT); if(result < 0) { *socketp = -1; return(-1); } return(0); } /* * INET connection: * * If the port number is 0, try to find the port in /etc/services, * use given port otherwise */ if(hostName == (char *) 0) { result = gethostname(thisHost, MAXHOSTNAMELEN); if(result < 0) { sprintf(message, "ConnectToServer: no host name for internet connection"); WARNING_PERROR(message); *socketp = -1; return(-1); } } else { strncpy(thisHost, hostName, MAXHOSTNAMELEN); } if(serviceName != (char *) 0 && port == 0) { if ((serverEntry = getservbyname (serviceName, "tcp")) != NULL) { port = serverEntry->s_port; } } /* * Either we got a port number or a port was passed in to this function * as a fallback if port is > 0 here. */ if(port > 0) { result = open_socket_port(socketp, port, hostName, CLIENT); if(result < 0) { *socketp = -1; return(-1); } } return(0);}/* ------------------------------------------------------------------------ * * SetupSockets - Opens the sockets/ports that it will listen to and reports * the result to stderr/stdout. * * RETURNS: * * ------------------------------------------------------------------------ */int SetupSockets( const char *serviceName, int inetPort, int unixPort, int *inetSocketp, int *unixSocketp){ struct servent *serverEntry = (struct servent *) 0; char sockname[1024]; int result; Bool doInetSocket = False; Bool doUnixSocket = False; if(inetSocketp != (int *) 0) doInetSocket = True; if(unixSocketp != (int *) 0) doUnixSocket = True; if(doInetSocket) { /* * TCP connection: * * If the inetPort is 0, then look up the service name in * /etc/services to try to get a port number, otherwise use the port * number given. */ *inetSocketp = -1; if(serviceName != (char *) 0 && inetPort == 0) { if ((serverEntry = getservbyname (serviceName, "tcp")) != NULL) { inetPort = serverEntry->s_port; } } /* * Either we got a port number or a port was passed in to this function * as a fallback if inetPort is > 0 here. */ if(inetPort > 0) { result = open_socket_port(inetSocketp, inetPort, (char *) 0, SERVER); if(result < 0) { sprintf(message, "Error opening internet port %d\n", inetPort); WARNING_MESSAGE(message); return(-1); } } sprintf(message, "Using TCP Port %d", inetPort); INFO_MESSAGE(message); } if(doUnixSocket) { /* * UNIX connection: * * Build a unix socket path * using the service name and the port */ *unixSocketp = -1; sprintf(sockname, "%s/%s.%d", UnixSocketPath, serviceName, unixPort); unlink(sockname); result = open_unix_port(unixSocketp, sockname, SERVER); if(result < 0) { close_socket(*inetSocketp); sprintf(message, "Error opening unix socket %s\n", sockname); WARNING_MESSAGE(message); return(-1); } sprintf(message, "Using UNIX Port '%s'", sockname); INFO_MESSAGE(message); } return(0);}/* ------------------------------------------------------------------------ * * set_hunt_mode() * * Turns on or off error messages when a socket is being opened on * a port that's busy. * * RETURNS: * Nothing * * ------------------------------------------------------------------------ */void set_hunt_mode(int flag){ hunt_mode = flag;}/* * set_socket_domain() * * Sets the domain to either AF_INET or AF_UNIX. * * RETURNS: * Old Domain. */int set_socket_domain( int newDomain) /* New domain to use */{ int old = domain; if(newDomain != AF_UNIX && newDomain != AF_INET) return(old); domain = newDomain; return(old);}/* * open_socket() * * Given a service 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_socket ( int *sock, /* handle to socket id to open */ const char *service_name, /* find /etc/services */ const char *host_name, /* String to use as host name */ int mode) /* SERVER or CLIENT */{ int result; int optval = 1; int optlen; struct protoent *tcp_proto; if (mode == SERVER) result = open_server_socket (sock, service_name, domain, 0); else result = open_client_socket (sock, service_name, host_name, domain, 0); if(result != -1 && domain == AF_INET) { tcp_proto = getprotobyname(MEDIUM); if(tcp_proto != NULL) { optlen = sizeof(optval); optval = 1; if (setsockopt (*sock, tcp_proto->p_proto, TCP_NODELAY, (char *) &optval, optlen) < 0) { WARNING_PERROR("Error in TCP_NODELAY setsockopt call"); if(close(*sock) < 0) WARNING_PERROR("Error in socket close"); return (-1); } } } if(result != -1) set_hunt_mode(0); return(result);}/* * open_socket_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_socket_port ( int *sock, /* handle to socket id to open */ int port, /* port id for service */ const char *host_name, /* String to use as host name */ int mode) /* SERVER or CLIENT */{ int result; int optval = 1; int optlen; struct protoent *tcp_proto; if (mode == SERVER) { result = open_server_socket (sock, (char *) 0, domain, port); } else { result = open_client_socket (sock, (char *) 0, host_name, domain, port); } if(result != -1 && domain == AF_INET) { tcp_proto = getprotobyname(MEDIUM); if(tcp_proto != NULL) { optlen = sizeof(optval); optval = 1; if (setsockopt (*sock, tcp_proto->p_proto, TCP_NODELAY, (char *) &optval, optlen) < 0) { WARNING_PERROR("Error in TCP_NODELAY setsockopt call"); if(close(*sock) < 0) WARNING_PERROR("Error in socket close"); return (-1); } } } return(result);}/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -