*/
#include "sockhelp.h"
+#include "extern.h"
/* Take a service name, and a service type, and return a port number. If
the
{
int port;
long int lport;
- struct servent *serv;
char *errpos;
- /* First try to read it from /etc/services */
- serv = getservbyname(service, proto);
- if (serv != NULL)
- port = serv->s_port;
- else { /* Not in services, maybe a number? */
lport = strtol(service,&errpos,0);
if ( (errpos[0] != 0) || (lport < 1) || (lport > 65535) )
return -1; /* Invalid port address */
+
port = htons(lport);
- }
+
return port;
}
struct in_addr *atoaddr(char *address)
{
struct hostent *host;
- static struct in_addr saddr;
- /* First try it as aaa.bbb.ccc.ddd. */
- saddr.s_addr = inet_addr(address);
- if (saddr.s_addr != 0) {
- return &saddr;
- }
host = gethostbyname(address);
if (host != NULL) {
return (struct in_addr *) *host->h_addr_list;
else
return listening_socket;
}
+#if !HAVE_GETHOSTBYNAME
+
+/* Translate an IP dotted-quad address to a 4-byte character string.
+ * Return NULL if the given string is not in dotted-quad format.
+ */
+
+static char *pack_ip(const char *ipaddr)
+{
+ static char ipbuf[4];
+ int tmp[4], i;
+
+ if (sscanf(ipaddr, "%d.%d.%d.%d", &tmp[0], &tmp[1], &tmp[2], &tmp[3])
+ != 4)
+ return NULL;
+ for (i = 0; i < 4; i++) {
+ if (tmp[i] < 0 || tmp[i] > 255)
+ return NULL;
+ ipbuf[i] = tmp[i];
+ }
+ return ipbuf;
+}
+
+#endif
+
+/*************************************************************************/
+
+/*************************************************************************/
+
+/* lhost/lport specify the local side of the connection. If they are not
+ * given (lhost==NULL, lport==0), then they are left free to vary.
+ */
+
+int conn(const char *host, int port, const char *lhost, int lport)
+{
+#if HAVE_GETHOSTBYNAME
+ struct hostent *hp;
+#else
+ char *addr;
+#endif
+ struct sockaddr_in sa, lsa;
+ int sock;
+
+ memset(&lsa, 0, sizeof(lsa));
+ if (lhost)
+ {
+#if HAVE_GETHOSTBYNAME
+ if ((hp = gethostbyname(lhost)) != NULL)
+ {
+ memcpy((char *) &lsa.sin_addr, hp->h_addr, hp->h_length);
+ lsa.sin_family = hp->h_addrtype;
+#else
+ if (addr = pack_ip(lhost))
+ {
+ memcpy((char *) &lsa.sin_addr, addr, 4);
+ lsa.sin_family = AF_INET;
+#endif
+ }
+ else
+ {
+ lhost = NULL;
+ }
+ }
+ if (lport)
+ {
+ lsa.sin_port = htons((unsigned short) lport);
+ }
+
+ memset(&sa, 0, sizeof(sa));
+#if HAVE_GETHOSTBYNAME
+ if (!(hp = gethostbyname(host)))
+ {
+ return -1;
+ }
+ memcpy((char *) &sa.sin_addr, hp->h_addr, hp->h_length);
+ sa.sin_family = hp->h_addrtype;
+#else
+ if (!(addr = pack_ip(host)))
+ {
+ log("conn(): `%s' is not a valid IP address", host);
+ errno = EINVAL;
+ return -1;
+ }
+ memcpy((char *) &sa.sin_addr, addr, 4);
+ sa.sin_family = AF_INET;
+#endif
+ sa.sin_port = htons((unsigned short) port);
+
+ if ((sock = socket(sa.sin_family, SOCK_STREAM, 0)) < 0)
+ {
+ return -1;
+ }
+
+ if ((lhost || lport)
+ && bind(sock, (struct sockaddr *) &lsa, sizeof(lsa)) < 0)
+ {
+ int errno_save = errno;
+ close(sock);
+ errno = errno_save;
+ return -1;
+ }
+
+ if (connect(sock, (struct sockaddr *) &sa, sizeof(sa)) < 0)
+ {
+ int errno_save = errno;
+ close(sock);
+ errno = errno_save;
+ return -1;
+ }
+
+ return sock;
+}
+
/* This is a generic function to make a connection to a given server/port.
service is the port name/number,
type is either SOCK_STREAM or SOCK_DGRAM, and
sock = socket(AF_INET, type, 0);
- printf("Connecting to %s on port %d.\n",inet_ntoa(*addr),htons(port));
+ log("Connecting to %s on port %d.",inet_ntoa(*addr),htons(port));
if (type == SOCK_STREAM) {
connected = connect(sock, (struct sockaddr *) &address,