# HG changeset patch # User masneyb # Date 1201217486 0 # Node ID 5b681cba67b24454123494536d38abb0068c1444 # Parent ca75331d0f821018855b964d991c831e55ca7539 2008-01-24 Brian Masney * lib/gftp.h lib/rfc959.c lib/protocols.c lib/misc.c - don't store the structure from getaddrinfo()/gethostbyname() in the gftp_request structure. Instead, store the address of the current server in a separate pointer. diff -r ca75331d0f82 -r 5b681cba67b2 ChangeLog --- a/ChangeLog Thu Jan 24 23:29:20 2008 +0000 +++ b/ChangeLog Thu Jan 24 23:31:26 2008 +0000 @@ -1,4 +1,9 @@ 2008-01-24 Brian Masney + * lib/gftp.h lib/rfc959.c lib/protocols.c lib/misc.c - don't store + the structure from getaddrinfo()/gethostbyname() in the + gftp_request structure. Instead, store the address of the current + server in a separate pointer. + * docs/sample.gftp/gftprc - updated the config file to the current release diff -r ca75331d0f82 -r 5b681cba67b2 lib/gftp.h --- a/lib/gftp.h Thu Jan 24 23:29:20 2008 +0000 +++ b/lib/gftp.h Thu Jan 24 23:31:26 2008 +0000 @@ -105,13 +105,6 @@ #define AF_LOCAL AF_UNIX #endif -#ifdef HAVE_GETADDRINFO -#define HAVE_IPV6 -#define GFTP_GET_AI_FAMILY(request) ((request) != NULL && (request)->hostp != NULL ? (request)->hostp->ai_family : -1) -#else -#define GFTP_GET_AI_FAMILY(request) AF_INET -#endif - /* Solaris needs this included for major()/minor() */ #ifdef HAVE_SYS_MKDEV_H #include @@ -161,6 +154,10 @@ # define GFTP_LOG_FUNCTION_ATTRIBUTES #endif +#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) +# define HAVE_IPV6 +#endif + #if defined (_LARGEFILE_SOURCE) && !defined (__hppa__) && !defined (__hppa) #define GFTP_OFF_T_HEX_PRINTF_MOD "%llx" #define GFTP_OFF_T_INTL_PRINTF_MOD "%'lld" @@ -388,22 +385,15 @@ int wakeup_main_thread[2]; /* FD that gets written to by the threads to wakeup the parent */ - /* One of these are used to lookup the IP address of the host we are - connecting to */ #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) - struct addrinfo *hostp, - *current_hostp; -#else - struct hostent host, *hostp; - int curhost; + void *remote_addr; + size_t remote_addr_len; #endif + int ai_family; - int ai_family; int server_type; /* The type of server we are connected to. See GFTP_DIRTYPE_* above */ - unsigned int free_hostp : 1, /* Should we free the hostp structure - in gftp_destroy_request() */ - use_proxy : 1, + unsigned int use_proxy : 1, always_connected : 1, need_hostport : 1, need_username : 1, @@ -1023,14 +1013,10 @@ char *proxy_hostname, unsigned int proxy_port ); -#if !defined (HAVE_GETADDRINFO) || !defined (HAVE_GAI_STRERROR) - struct hostent *r_gethostbyname ( const char *name, struct hostent *result_buf, int *h_errnop ); -#endif - struct servent *r_getservbyname ( const char *name, const char *proto, /*@out@*/ struct servent *result_buf, diff -r ca75331d0f82 -r 5b681cba67b2 lib/misc.c --- a/lib/misc.c Thu Jan 24 23:29:20 2008 +0000 +++ b/lib/misc.c Thu Jan 24 23:31:26 2008 +0000 @@ -461,6 +461,8 @@ while (templist != NULL) { tempfle = templist->data; + templist->data = NULL; + gftp_file_destroy (tempfle, 1); templist = templist->next; } @@ -488,6 +490,7 @@ if (fle->destfile) newfle->destfile = g_strdup (fle->destfile); + newfle->user_data = NULL; return (newfle); } @@ -591,41 +594,26 @@ newreq->account = g_strdup (req->account); if (req->directory) newreq->directory = g_strdup (req->directory); + if (req->url_prefix) + newreq->url_prefix = g_strdup (req->url_prefix); newreq->port = req->port; newreq->use_proxy = req->use_proxy; newreq->logging_function = req->logging_function; newreq->ai_family = req->ai_family; - if (req->hostp) +#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) + if (req->remote_addr == NULL) { -#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) - struct addrinfo *hostp = req->hostp; - struct addrinfo *newhostp = newreq->hostp; - - while (hostp != NULL) - { - newhostp = g_malloc (sizeof(struct addrinfo)); - memcpy (newhostp, hostp, sizeof (struct addrinfo)); - newhostp->ai_addr = g_malloc (sizeof (struct sockaddr)); - memcpy(newhostp->ai_addr, hostp->ai_addr, sizeof (struct sockaddr)); - if (hostp->ai_canonname) - newhostp->ai_canonname = strdup(hostp->ai_canonname); - - if (req->current_hostp == hostp) - newreq->current_hostp = newhostp; - - hostp = hostp->ai_next; newhostp = newhostp->ai_next; - } -#else - newreq->hostp = g_malloc (sizeof (struct hostent)); - memcpy(newreq->hostp, req->hostp, sizeof (struct hostent)); - newreq->host = req->host; - newreq->curhost = req->curhost; -#endif + newreq->remote_addr = NULL; + newreq->remote_addr_len = 0; } else - newreq->hostp = NULL; - newreq->free_hostp = 1; + { + newreq->remote_addr = g_malloc0 (req->remote_addr_len); + memcpy (newreq->remote_addr, req->remote_addr, req->remote_addr_len); + newreq->remote_addr_len = req->remote_addr_len; + } +#endif gftp_copy_local_options (&newreq->local_options_vars, &newreq->local_options_hash, @@ -942,8 +930,6 @@ } -#if !defined (HAVE_GETADDRINFO) || !defined (HAVE_GAI_STRERROR) - struct hostent * r_gethostbyname (const char *name, struct hostent *result_buf, int *h_errnop) { @@ -970,7 +956,6 @@ return (hent); } -#endif /* !HAVE_GETADDRINFO */ struct servent * r_getservbyname (const char *name, const char *proto, @@ -1027,7 +1012,7 @@ if (slen % 3 > 0) num++; - newstr = g_malloc ((gulong) num * 4 + 1); + newstr = g_malloc0 ((gulong) num * 4 + 1); newstr[num * 4] = '\0'; newpos = newstr; @@ -1264,7 +1249,7 @@ if (strcmp (password, "@EMAIL@") == 0) return (g_strdup (password)); - newstr = g_malloc ((gulong) strlen (password) * 2 + 2); + newstr = g_malloc0 ((gulong) strlen (password) * 2 + 2); newpos = newstr; *newpos++ = '$'; @@ -1292,7 +1277,7 @@ return (g_strdup (password)); passwordpos = password + 1; - newstr = g_malloc ((gulong) strlen (passwordpos) / 2 + 1); + newstr = g_malloc0 ((gulong) strlen (passwordpos) / 2 + 1); newpos = newstr; error = 0; diff -r ca75331d0f82 -r 5b681cba67b2 lib/protocols.c --- a/lib/protocols.c Thu Jan 24 23:29:20 2008 +0000 +++ b/lib/protocols.c Thu Jan 24 23:31:26 2008 +0000 @@ -48,15 +48,9 @@ if (request->username) g_free (request->username); if (request->password) - { - memset (request->password, 0, strlen (request->password)); - g_free (request->password); - } + g_free (request->password); if (request->account) - { - memset (request->account, 0, strlen (request->account)); - g_free (request->account); - } + g_free (request->account); if (request->directory) g_free (request->directory); if (request->last_ftp_response) @@ -64,6 +58,11 @@ if (request->protocol_data) g_free (request->protocol_data); +#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) + if (request->remote_addr != NULL) + g_free (request->remote_addr); +#endif + if (request->local_options_vars != NULL) { gftp_config_free_options (request->local_options_vars, @@ -143,12 +142,6 @@ { g_return_if_fail (request != NULL); -#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) - if (request->free_hostp && request->hostp != NULL) - freeaddrinfo (request->hostp); -#endif - request->hostp = NULL; - #ifdef USE_SSL if (request->ssl != NULL) { @@ -1164,6 +1157,7 @@ } +/* FIXME - clean up this function */ static int gftp_need_proxy (gftp_request * request, char *service, char *proxy_hostname, unsigned int proxy_port) @@ -1177,10 +1171,12 @@ gint32 netaddr; char *pos; #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) - struct addrinfo hints; + struct addrinfo hints, *hostp; unsigned int port; int errnum; char serv[8]; +#else + struct hostent host, *hostp; #endif gftp_lookup_global_option ("dont_use_proxy", &proxy_hosts); @@ -1191,9 +1187,8 @@ return (proxy_hostname != NULL && *proxy_hostname != '\0'); - request->hostp = NULL; + hostp = NULL; #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) - request->free_hostp = 1; memset (&hints, 0, sizeof (hints)); hints.ai_flags = AI_CANONNAME; hints.ai_family = PF_UNSPEC; @@ -1209,7 +1204,7 @@ _("Looking up %s\n"), request->hostname); if ((errnum = getaddrinfo (request->hostname, serv, &hints, - &request->hostp)) != 0) + &hostp)) != 0) { request->logging_function (gftp_logging_error, request, _("Cannot look up hostname %s: %s\n"), @@ -1217,14 +1212,13 @@ return (GFTP_ERETRYABLE); } - addr = request->hostp->ai_addr; + addr = hostp->ai_addr; #else /* !HAVE_GETADDRINFO */ request->logging_function (gftp_logging_misc, request, _("Looking up %s\n"), request->hostname); - if (!(request->hostp = r_gethostbyname (request->hostname, &request->host, - NULL))) + if (!(hostp = r_gethostbyname (request->hostname, &host, NULL))) { request->logging_function (gftp_logging_error, request, _("Cannot look up hostname %s: %s\n"), @@ -1232,7 +1226,7 @@ return (GFTP_ERETRYABLE); } - addr = (struct sockaddr *) request->host.h_addr_list[0]; + addr = (struct sockaddr *) host.h_addr_list[0]; #endif /* HAVE_GETADDRINFO */ @@ -1286,7 +1280,7 @@ savepos = *endpos; *endpos = '\0'; - *dest = g_malloc ((gulong) (endpos - source + 1)); + *dest = g_malloc0 ((gulong) (endpos - source + 1)); strcpy (*dest, source); *endpos = savepos; @@ -1917,7 +1911,7 @@ fle = g_malloc0 (sizeof (*fle)); while (gftp_get_next_file (request, NULL, fle) > 0) { - newsize = g_malloc (sizeof (*newsize)); + newsize = g_malloc0 (sizeof (*newsize)); *newsize = fle->size; g_hash_table_insert (dirhash, fle->file, newsize); fle->file = NULL; @@ -1981,7 +1975,7 @@ return (NULL); } - fle = g_malloc (sizeof (*fle)); + fle = g_malloc0 (sizeof (*fle)); templist = NULL; while (gftp_get_next_file (transfer->fromreq, NULL, fle) > 0) { @@ -2345,43 +2339,32 @@ return (port); } -#endif int -gftp_connect_server (gftp_request * request, char *service, - char *proxy_hostname, unsigned int proxy_port) +gftp_connect_server_with_getaddr (gftp_request * request, char *service, + char *proxy_hostname, unsigned int proxy_port) { + struct addrinfo *hostp, *current_hostp; char *connect_host, *disphost; - unsigned int port; - int sock = -1; -#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) struct addrinfo hints, *res; intptr_t enable_ipv6; + unsigned int port; + int ret, sock = -1; char serv[8]; - int errnum; - - if ((errnum = gftp_need_proxy (request, service, proxy_hostname, + + if ((ret = gftp_need_proxy (request, service, proxy_hostname, proxy_port)) < 0) - return (errnum); + return (ret); else - { - request->use_proxy = errnum; - if (request->use_proxy) - request->hostp = NULL; - } + request->use_proxy = ret; gftp_lookup_request_option (request, "enable_ipv6", &enable_ipv6); - request->free_hostp = 1; memset (&hints, 0, sizeof (hints)); hints.ai_flags = AI_CANONNAME; - if (enable_ipv6) - hints.ai_family = PF_UNSPEC; - else - hints.ai_family = AF_INET; - + hints.ai_family = enable_ipv6 ? PF_UNSPEC : AF_INET; hints.ai_socktype = SOCK_STREAM; if (request->use_proxy) @@ -2395,27 +2378,24 @@ port = request->port; } - if (request->hostp == NULL) + if (port == 0) + strcpy (serv, service); + else + snprintf (serv, sizeof (serv), "%d", port); + + request->logging_function (gftp_logging_misc, request, + _("Looking up %s\n"), connect_host); + if ((ret = getaddrinfo (connect_host, serv, &hints, + &hostp)) != 0) { - if (port == 0) - strcpy (serv, service); - else - snprintf (serv, sizeof (serv), "%d", port); - - request->logging_function (gftp_logging_misc, request, - _("Looking up %s\n"), connect_host); - if ((errnum = getaddrinfo (connect_host, serv, &hints, - &request->hostp)) != 0) - { - request->logging_function (gftp_logging_error, request, - _("Cannot look up hostname %s: %s\n"), - connect_host, gai_strerror (errnum)); - return (GFTP_ERETRYABLE); - } + request->logging_function (gftp_logging_error, request, + _("Cannot look up hostname %s: %s\n"), + connect_host, gai_strerror (ret)); + return (GFTP_ERETRYABLE); } disphost = connect_host; - for (res = request->hostp; res != NULL; res = res->ai_next) + for (res = hostp; res != NULL; res = res->ai_next) { disphost = res->ai_canonname ? res->ai_canonname : connect_host; port = get_port (res); @@ -2443,25 +2423,42 @@ continue; } - request->current_hostp = res; + current_hostp = res; request->ai_family = res->ai_family; break; } if (res == NULL) { - if (request->hostp != NULL) - { - freeaddrinfo (request->hostp); - request->hostp = NULL; - } + if (hostp != NULL) + freeaddrinfo (hostp); + return (GFTP_ERETRYABLE); } -#else /* !HAVE_GETADDRINFO */ + request->remote_addr_len = current_hostp->ai_addrlen; + request->remote_addr = g_malloc0 (request->remote_addr_len); + memcpy (request->remote_addr, &((struct sockaddr_in *) current_hostp->ai_addr)->sin_addr, + request->remote_addr_len); + + request->logging_function (gftp_logging_misc, request, + _("Connected to %s:%d\n"), connect_host, port); + + return (sock); +} +#endif + + +int +gftp_connect_server_legacy (gftp_request * request, char *service, + char *proxy_hostname, unsigned int proxy_port) +{ struct sockaddr_in remote_address; + char *connect_host, *disphost; + struct hostent host, *hostp; struct servent serv_struct; - int ret; + int ret, sock, curhost; + unsigned int port; if ((ret = gftp_need_proxy (request, service, proxy_hostname, proxy_port)) < 0) @@ -2469,7 +2466,7 @@ request->use_proxy = ret; if (request->use_proxy == 1) - request->hostp = NULL; + hostp = NULL; request->ai_family = AF_INET; if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) @@ -2513,33 +2510,30 @@ remote_address.sin_port = htons (port); - if (request->hostp == NULL) + request->logging_function (gftp_logging_misc, request, + _("Looking up %s\n"), connect_host); + + if (!(hostp = r_gethostbyname (connect_host, &host, NULL))) { - request->logging_function (gftp_logging_misc, request, - _("Looking up %s\n"), connect_host); - if (!(request->hostp = r_gethostbyname (connect_host, &request->host, - NULL))) - { - request->logging_function (gftp_logging_error, request, - _("Cannot look up hostname %s: %s\n"), - connect_host, g_strerror (errno)); - close (sock); - return (GFTP_ERETRYABLE); - } + request->logging_function (gftp_logging_error, request, + _("Cannot look up hostname %s: %s\n"), + connect_host, g_strerror (errno)); + close (sock); + return (GFTP_ERETRYABLE); } disphost = NULL; - for (request->curhost = 0; - request->host.h_addr_list[request->curhost] != NULL; - request->curhost++) + for (curhost = 0; + host.h_addr_list[curhost] != NULL; + curhost++) { - disphost = request->host.h_name; + disphost = host.h_name; memcpy (&remote_address.sin_addr, - request->host.h_addr_list[request->curhost], - request->host.h_length); + host.h_addr_list[curhost], + host.h_length); request->logging_function (gftp_logging_misc, request, _("Trying %s:%d\n"), - request->host.h_name, port); + host.h_name, port); if (connect (sock, (struct sockaddr *) &remote_address, sizeof (remote_address)) == -1) @@ -2551,25 +2545,42 @@ break; } - if (request->host.h_addr_list[request->curhost] == NULL) + if (host.h_addr_list[curhost] == NULL) { close (sock); return (GFTP_ERETRYABLE); } -#endif /* HAVE_GETADDRINFO */ + + return (sock); +} + + +int +gftp_connect_server (gftp_request * request, char *service, + char *proxy_hostname, unsigned int proxy_port) +{ + int sock; + +#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) + sock = gftp_connect_server_with_getaddr (request, service, proxy_hostname, + proxy_port); +#else + sock = gftp_connect_server_legacy (request, service, proxy_hostname, + proxy_port); +#endif + + if (sock < 0) + return (sock); if (fcntl (sock, F_SETFD, 1) == -1) { request->logging_function (gftp_logging_error, request, _("Error: Cannot set close on exec flag: %s\n"), g_strerror (errno)); - + close (sock); return (GFTP_ERETRYABLE); } - request->logging_function (gftp_logging_misc, request, - _("Connected to %s:%d\n"), connect_host, port); - if (gftp_fd_set_sockblocking (request, sock, 1) < 0) { close (sock); diff -r ca75331d0f82 -r 5b681cba67b2 lib/rfc959.c --- a/lib/rfc959.c Thu Jan 24 23:29:20 2008 +0000 +++ b/lib/rfc959.c Thu Jan 24 23:31:26 2008 +0000 @@ -767,14 +767,8 @@ &ignore_pasv_address); if (ignore_pasv_address) { -#if defined (HAVE_GETADDRINFO) - memcpy (&data_addr.sin_addr, - &((struct sockaddr_in *) request->current_hostp->ai_addr)->sin_addr, - sizeof (data_addr.sin_addr)); -#else - memcpy (&data_addr.sin_addr, request->hostp->h_addr_list[request->curhost], - request->hostp->h_length); -#endif + memcpy (&data_addr.sin_addr, request->remote_addr, + request->remote_addr_len); pos = (char *) &data_addr.sin_addr; request->logging_function (gftp_logging_error, request, @@ -871,7 +865,6 @@ struct sockaddr_in6 data_addr; char *pos, buf[64], *command; intptr_t passive_transfer; - socklen_t data_addr_len; rfc959_parms * parms; unsigned int port; int resp; @@ -895,9 +888,8 @@ return (GFTP_ERETRYABLE); } - data_addr_len = sizeof (data_addr); /* This condition shouldn't happen. We better check anyway... */ - if (data_addr_len != request->current_hostp->ai_addrlen) + if (sizeof (data_addr) != request->remote_addr_len) { request->logging_function (gftp_logging_error, request, _("Error: It doesn't look like we are connected via IPv6. Aborting connection.\n")); @@ -905,7 +897,7 @@ return (GFTP_EFATAL); } - memset (&data_addr, 0, data_addr_len); + memset (&data_addr, 0, sizeof (data_addr)); data_addr.sin6_family = AF_INET6; gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); @@ -943,11 +935,11 @@ return (GFTP_EFATAL); } - memcpy (&data_addr, request->current_hostp->ai_addr, data_addr_len); + memcpy (&data_addr, request->remote_addr, request->remote_addr_len); data_addr.sin6_port = htons (port); if (connect (parms->data_connection, (struct sockaddr *) &data_addr, - data_addr_len) == -1) + request->remote_addr_len) == -1) { request->logging_function (gftp_logging_error, request, _("Cannot create a data connection: %s\n"), @@ -958,11 +950,11 @@ } else { - memcpy (&data_addr, request->current_hostp->ai_addr, data_addr_len); + memcpy (&data_addr, request->remote_addr, request->remote_addr_len); data_addr.sin6_port = 0; if (bind (parms->data_connection, (struct sockaddr *) &data_addr, - data_addr_len) == -1) + request->remote_addr_len) == -1) { request->logging_function (gftp_logging_error, request, _("Cannot bind a port: %s\n"), @@ -972,7 +964,7 @@ } if (getsockname (parms->data_connection, (struct sockaddr *) &data_addr, - &data_addr_len) == -1) + &request->remote_addr_len) == -1) { request->logging_function (gftp_logging_error, request, _("Cannot get socket name: %s\n"), @@ -1487,7 +1479,7 @@ if (rsize != size) { - tempstr = g_malloc (rsize); + tempstr = g_malloc0 (rsize); for (i = 0, j = 0; i < size; i++) {