00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <config.h>
00037
00038 #include <ctype.h>
00039 #include <errno.h>
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <string.h>
00043 #ifndef _WIN32
00044 #include <sys/types.h>
00045 #include <sys/socket.h>
00046 #include <netinet/in.h>
00047 #include <arpa/inet.h>
00048 #include <netdb.h>
00049 #include <unistd.h>
00050 #else
00051 #define close(fd) w32_close_socket((fd))
00052 #endif
00053 #include "misc.h"
00054
00055 #ifdef HAVE_GETADDRINFO
00056
00057
00058
00059
00060
00061 int
00062 tcp_connect(char *host, char *serv)
00063 {
00064 int sockfd, n;
00065 struct addrinfo hints, *res, *ressave;
00066
00067 memset(&hints, 0, sizeof(struct addrinfo));
00068 hints.ai_family = AF_UNSPEC;
00069 hints.ai_socktype = SOCK_STREAM;
00070
00071 if ((n = getaddrinfo(host, serv, &hints, &res)) != 0) {
00072 fprintf(stderr, "Can't connect to %s:%s: %s\n",
00073 host, serv, gai_strerror(n));
00074 exit(1);
00075 }
00076 ressave = res;
00077
00078 do {
00079 sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
00080 if (sockfd < 0)
00081 continue;
00082
00083 if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)
00084 break;
00085 close(sockfd);
00086 } while ((res = res->ai_next) != NULL);
00087
00088 if (res == NULL) {
00089 fprintf(stderr, "Can't connect to %s:%s: %s\n",
00090 host, serv, strerror(errno));
00091 exit(1);
00092 }
00093
00094 freeaddrinfo(ressave);
00095
00096 return sockfd;
00097 }
00098
00099 #else
00100
00101 static int
00102 hostaddr(char *name, struct sockaddr_in *addr)
00103 {
00104 struct hostent *hp;
00105
00106 if (name == NULL || *name == 0)
00107 return 0;
00108 if (isdigit(*name)) {
00109 addr->sin_addr.s_addr = inet_addr(name);
00110 } else {
00111 hp = gethostbyname(name);
00112 if (hp == NULL)
00113 return 0;
00114 memcpy(&addr->sin_addr, hp->h_addr, sizeof(addr->sin_addr));
00115 }
00116 return 1;
00117 }
00118
00119 static int
00120 hostport(char *name, struct sockaddr_in *addr)
00121 {
00122 struct servent *sp;
00123
00124 if (name == NULL || *name == 0)
00125 return 0;
00126 if (isdigit(*name)) {
00127 addr->sin_port = htons(atoi(name));
00128 } else {
00129 sp = getservbyname(name, "tcp");
00130 if (sp == NULL)
00131 return 0;
00132 addr->sin_port = sp->s_port;
00133 }
00134 return 1;
00135 }
00136
00137 static int
00138 hostconnect(struct sockaddr_in *addr)
00139 {
00140
00141 int s;
00142
00143 s = socket(AF_INET, SOCK_STREAM, 0);
00144 if (s < 0) {
00145 return -1;
00146 }
00147 addr->sin_family = AF_INET;
00148 if (connect(s, (struct sockaddr *)addr, sizeof(*addr)) < 0) {
00149 (void)close(s);
00150 return -1;
00151 }
00152 return s;
00153 }
00154
00155 int
00156 tcp_connect(char *host, char *serv)
00157 {
00158 struct sockaddr_in sin;
00159 int sock;
00160
00161 if (!hostport(serv, &sin)) {
00162 fprintf(stderr, "Can't resolve Empire port %s\n", serv);
00163 exit(1);
00164 }
00165 if (!hostaddr(host, &sin)) {
00166 fprintf(stderr, "Can't resolve Empire host %s\n", host);
00167 exit(1);
00168 }
00169 if ((sock = hostconnect(&sin)) < 0) {
00170 fprintf(stderr, "Can't connect to %s:%s: %s\n",
00171 serv, host, strerror(errno));
00172 exit(1);
00173 }
00174 return sock;
00175 }
00176 #endif