/************************************************************************** Get ready to [try to] connect to a server: - translate HOSTNAME and PORT (with defaults of "localhost" and DEFAULT_SOCK_PORT respectively) to a raw IP address and port number, and store them in the `names' variable - return 0 on success or put an error message in ERRBUF and return -1 on failure **************************************************************************/ static int get_server_address(const char *hostname, int port, char *errbuf, int errbufsize) { if (port == 0) port = DEFAULT_SOCK_PORT; /* use name to find TCP/IP address of server */ if (!hostname) hostname = "localhost"; if (!net_lookup_service(hostname, port, &names[0], FALSE)) { (void) fc_strlcpy(errbuf, _("Failed looking up host."), errbufsize); return -1; } name_count = 1; #ifdef IPV6_SUPPORT if (names[0].saddr.sa_family == AF_INET6) { /* net_lookup_service() prefers IPv6 address. * Check if there is also IPv4 address. * TODO: This would be easier using getaddrinfo() */ if (net_lookup_service(hostname, port, &names[1], TRUE /* force IPv4 */)) { name_count = 2; } } #endif return 0; }
/************************************************************************** Get ready to [try to] connect to a server: - translate HOSTNAME and PORT (with defaults of "localhost" and DEFAULT_SOCK_PORT respectively) to a raw IP address and port number, and store them in the `server_addr' variable - return 0 on success or put an error message in ERRBUF and return -1 on failure **************************************************************************/ static int get_server_address(const char *hostname, int port, char *errbuf, int errbufsize) { if (port == 0) port = DEFAULT_SOCK_PORT; /* use name to find TCP/IP address of server */ if (!hostname) hostname = "localhost"; if (!net_lookup_service(hostname, port, &server_addr, FALSE)) { (void) mystrlcpy(errbuf, _("Failed looking up host."), errbufsize); return -1; } return 0; }
/**************************************************************************** Begin a metaserver scan for servers. This just initiates the connection to the metaserver; later get_meta_server_list should be called whenever the socket has data pending to read and parse it. Returns FALSE on error (in which case errbuf will contain an error message). ****************************************************************************/ static bool begin_metaserver_scan(struct server_scan *scan) { union fc_sockaddr addr; int s; scan->meta.urlpath = fc_lookup_httpd(scan->meta.name, &scan->meta.port, metaserver); if (!scan->meta.urlpath) { scan->error_func(scan, _("Invalid $http_proxy or metaserver value, must " "start with 'http://'")); return FALSE; } if (!net_lookup_service(scan->meta.name, scan->meta.port, &addr, FALSE)) { scan->error_func(scan, _("Failed looking up metaserver's host")); return FALSE; } if ((s = socket(addr.saddr.sa_family, SOCK_STREAM, 0)) == -1) { scan->error_func(scan, fc_strerror(fc_get_errno())); return FALSE; } fc_nonblock(s); if (fc_connect(s, &addr.saddr, sockaddr_size(&addr)) == -1) { if (errno == EINPROGRESS) { /* With non-blocking sockets this is the expected result. */ scan->meta.state = META_CONNECTING; scan->sock = s; } else { fc_closesocket(s); scan->error_func(scan, fc_strerror(fc_get_errno())); return FALSE; } } else { /* Instant connection? Whoa. */ scan->sock = s; scan->meta.state = META_CONNECTING; meta_send_request(scan); } return TRUE; }