diff options
Diffstat (limited to 'FICS/get_tcp_conn.c')
-rw-r--r-- | FICS/get_tcp_conn.c | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/FICS/get_tcp_conn.c b/FICS/get_tcp_conn.c new file mode 100644 index 0000000..904da47 --- /dev/null +++ b/FICS/get_tcp_conn.c @@ -0,0 +1,153 @@ +/* +** Routines to open a TCP connection +** +** New version that supports the old (pre 4.2 BSD) socket calls, +** and systems with the old (pre 4.2 BSD) hostname lookup stuff. +** Compile-time options are: +** +** OLDSOCKET - different args for socket() and connect() +** +** Erik E. Fair <fair@ucbarpa.berkeley.edu> +** +*/ + +/* Uncomment the following line if you are using old socket calls */ +/* #define OLDSOCKET */ + + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <netdb.h> +#include "get_tcp_conn.h" +#include "get_tcp_conn.proto.h" +#include "stdinclude.h" + +extern int errno; +extern int close(); + + + +/* +** Take the name of an internet host in ASCII (this may either be its +** official host name or internet number (with or without enclosing +** backets [])), and return a list of internet addresses. +** +** returns NULL for failure to find the host name in the local database, +** or for a bad internet address spec. +*/ +unsigned long ** + name_to_address(char *host) +{ + static u_long *host_addresses[2]; + static u_long haddr; + + if (host == (char *) NULL) { + return ((u_long **) NULL); + } + host_addresses[0] = &haddr; + host_addresses[1] = (u_long *) NULL; + + /* * Is this an ASCII internet address? (either of [10.0.0.78] or * + 10.0.0.78). We get away with the second test because hostnames * and + domain labels are not allowed to begin in numbers. * (cf. RFC952, + RFC882). */ + if (*host == '[' || isdigit(*host)) { + char namebuf[128]; + register char *cp = namebuf; + + /* * strip brackets [] or anything else we don't want. */ + while (*host != '\0' && cp < &namebuf[sizeof(namebuf)]) { + if (isdigit(*host) || *host == '.') + *cp++ = *host++; /* copy */ + else + host++; /* skip */ + } + *cp = '\0'; + haddr = inet_addr(namebuf); + return (&host_addresses[0]); + } else { + struct hostent *hstp = gethostbyname(host); + + if (hstp == NULL) { + return ((u_long **) NULL);/* no such host */ + } + if (hstp->h_length != sizeof(u_long)) + abort(); /* this is fundamental */ + return ((u_long **) hstp->h_addr_list); + } +} + +u_short +gservice(char *serv, char *proto) +{ + if (serv == (char *) NULL || proto == (char *) NULL) + return ((u_short) 0); + + if (isdigit(*serv)) { + return (htons((u_short) (atoi(serv)))); + } else { + struct servent *srvp = getservbyname(serv, proto); + + if (srvp == (struct servent *) NULL) + return ((u_short) 0); + return ((u_short) srvp->s_port); + } +} + +/* +** given a host name (either name or internet address) and port number +** give us a TCP connection to the +** requested service at the requested host (or give us FAIL). +*/ +int get_tcp_conn(host, port) +char *host; +int port; +{ + register int sock; + u_long **addrlist; + struct sockaddr_in sadr; +#ifdef OLDSOCKET + struct sockproto sp; + + sp.sp_family = (u_short) AF_INET; + sp.sp_protocol = (u_short) IPPROTO_TCP; +#endif + + if ((addrlist = name_to_address(host)) == (u_long **) NULL) { + return (NOHOST); + } + sadr.sin_family = (u_short) AF_INET; /* Only internet for now */ + sadr.sin_port = htons(port); + + for (; *addrlist != (u_long *) NULL; addrlist++) { + bcopy((caddr_t) * addrlist, (caddr_t) & sadr.sin_addr, + sizeof(sadr.sin_addr)); + +#ifdef OLDSOCKET + if ((sock = socket(SOCK_STREAM, &sp, (struct sockaddr *) NULL, 0)) < 0) + return (FAIL); + + if (connect(sock, (struct sockaddr *) & sadr) < 0) { +#else + if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) + return (FAIL); + + if (connect(sock, (struct sockaddr *) & sadr, sizeof(sadr)) < 0) { +#endif + int e_save = errno; + + fprintf(stderr, "%s [%s] port %d: %d\n", host, + inet_ntoa(sadr.sin_addr), port, errno); + (void) close(sock); /* dump descriptor */ + errno = e_save; + } else + return (sock); + } + return (FAIL); +} |