Mercurial > gftp.yaz
comparison lib/protocols.c @ 944:5b681cba67b2
2008-01-24 Brian Masney <masneyb@gftp.org>
* 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.
author | masneyb |
---|---|
date | Thu, 24 Jan 2008 23:31:26 +0000 |
parents | f37091406523 |
children | c7d7a081cd9c |
comparison
equal
deleted
inserted
replaced
943:ca75331d0f82 | 944:5b681cba67b2 |
---|---|
46 if (request->hostname) | 46 if (request->hostname) |
47 g_free (request->hostname); | 47 g_free (request->hostname); |
48 if (request->username) | 48 if (request->username) |
49 g_free (request->username); | 49 g_free (request->username); |
50 if (request->password) | 50 if (request->password) |
51 { | 51 g_free (request->password); |
52 memset (request->password, 0, strlen (request->password)); | |
53 g_free (request->password); | |
54 } | |
55 if (request->account) | 52 if (request->account) |
56 { | 53 g_free (request->account); |
57 memset (request->account, 0, strlen (request->account)); | |
58 g_free (request->account); | |
59 } | |
60 if (request->directory) | 54 if (request->directory) |
61 g_free (request->directory); | 55 g_free (request->directory); |
62 if (request->last_ftp_response) | 56 if (request->last_ftp_response) |
63 g_free (request->last_ftp_response); | 57 g_free (request->last_ftp_response); |
64 if (request->protocol_data) | 58 if (request->protocol_data) |
65 g_free (request->protocol_data); | 59 g_free (request->protocol_data); |
60 | |
61 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) | |
62 if (request->remote_addr != NULL) | |
63 g_free (request->remote_addr); | |
64 #endif | |
66 | 65 |
67 if (request->local_options_vars != NULL) | 66 if (request->local_options_vars != NULL) |
68 { | 67 { |
69 gftp_config_free_options (request->local_options_vars, | 68 gftp_config_free_options (request->local_options_vars, |
70 request->local_options_hash, | 69 request->local_options_hash, |
140 | 139 |
141 void | 140 void |
142 gftp_disconnect (gftp_request * request) | 141 gftp_disconnect (gftp_request * request) |
143 { | 142 { |
144 g_return_if_fail (request != NULL); | 143 g_return_if_fail (request != NULL); |
145 | |
146 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) | |
147 if (request->free_hostp && request->hostp != NULL) | |
148 freeaddrinfo (request->hostp); | |
149 #endif | |
150 request->hostp = NULL; | |
151 | 144 |
152 #ifdef USE_SSL | 145 #ifdef USE_SSL |
153 if (request->ssl != NULL) | 146 if (request->ssl != NULL) |
154 { | 147 { |
155 SSL_free (request->ssl); | 148 SSL_free (request->ssl); |
1162 return (0); | 1155 return (0); |
1163 return (request->get_file_size (request, filename)); | 1156 return (request->get_file_size (request, filename)); |
1164 } | 1157 } |
1165 | 1158 |
1166 | 1159 |
1160 /* FIXME - clean up this function */ | |
1167 static int | 1161 static int |
1168 gftp_need_proxy (gftp_request * request, char *service, char *proxy_hostname, | 1162 gftp_need_proxy (gftp_request * request, char *service, char *proxy_hostname, |
1169 unsigned int proxy_port) | 1163 unsigned int proxy_port) |
1170 { | 1164 { |
1171 gftp_config_list_vars * proxy_hosts; | 1165 gftp_config_list_vars * proxy_hosts; |
1175 struct sockaddr *addr; | 1169 struct sockaddr *addr; |
1176 GList * templist; | 1170 GList * templist; |
1177 gint32 netaddr; | 1171 gint32 netaddr; |
1178 char *pos; | 1172 char *pos; |
1179 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) | 1173 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) |
1180 struct addrinfo hints; | 1174 struct addrinfo hints, *hostp; |
1181 unsigned int port; | 1175 unsigned int port; |
1182 int errnum; | 1176 int errnum; |
1183 char serv[8]; | 1177 char serv[8]; |
1178 #else | |
1179 struct hostent host, *hostp; | |
1184 #endif | 1180 #endif |
1185 | 1181 |
1186 gftp_lookup_global_option ("dont_use_proxy", &proxy_hosts); | 1182 gftp_lookup_global_option ("dont_use_proxy", &proxy_hosts); |
1187 | 1183 |
1188 if (proxy_hostname == NULL || *proxy_hostname == '\0') | 1184 if (proxy_hostname == NULL || *proxy_hostname == '\0') |
1189 return (0); | 1185 return (0); |
1190 else if (proxy_hosts->list == NULL) | 1186 else if (proxy_hosts->list == NULL) |
1191 return (proxy_hostname != NULL && | 1187 return (proxy_hostname != NULL && |
1192 *proxy_hostname != '\0'); | 1188 *proxy_hostname != '\0'); |
1193 | 1189 |
1194 request->hostp = NULL; | 1190 hostp = NULL; |
1195 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) | 1191 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) |
1196 request->free_hostp = 1; | |
1197 memset (&hints, 0, sizeof (hints)); | 1192 memset (&hints, 0, sizeof (hints)); |
1198 hints.ai_flags = AI_CANONNAME; | 1193 hints.ai_flags = AI_CANONNAME; |
1199 hints.ai_family = PF_UNSPEC; | 1194 hints.ai_family = PF_UNSPEC; |
1200 hints.ai_socktype = SOCK_STREAM; | 1195 hints.ai_socktype = SOCK_STREAM; |
1201 | 1196 |
1207 | 1202 |
1208 request->logging_function (gftp_logging_misc, request, | 1203 request->logging_function (gftp_logging_misc, request, |
1209 _("Looking up %s\n"), request->hostname); | 1204 _("Looking up %s\n"), request->hostname); |
1210 | 1205 |
1211 if ((errnum = getaddrinfo (request->hostname, serv, &hints, | 1206 if ((errnum = getaddrinfo (request->hostname, serv, &hints, |
1212 &request->hostp)) != 0) | 1207 &hostp)) != 0) |
1213 { | 1208 { |
1214 request->logging_function (gftp_logging_error, request, | 1209 request->logging_function (gftp_logging_error, request, |
1215 _("Cannot look up hostname %s: %s\n"), | 1210 _("Cannot look up hostname %s: %s\n"), |
1216 request->hostname, gai_strerror (errnum)); | 1211 request->hostname, gai_strerror (errnum)); |
1217 return (GFTP_ERETRYABLE); | 1212 return (GFTP_ERETRYABLE); |
1218 } | 1213 } |
1219 | 1214 |
1220 addr = request->hostp->ai_addr; | 1215 addr = hostp->ai_addr; |
1221 | 1216 |
1222 #else /* !HAVE_GETADDRINFO */ | 1217 #else /* !HAVE_GETADDRINFO */ |
1223 request->logging_function (gftp_logging_misc, request, | 1218 request->logging_function (gftp_logging_misc, request, |
1224 _("Looking up %s\n"), request->hostname); | 1219 _("Looking up %s\n"), request->hostname); |
1225 | 1220 |
1226 if (!(request->hostp = r_gethostbyname (request->hostname, &request->host, | 1221 if (!(hostp = r_gethostbyname (request->hostname, &host, NULL))) |
1227 NULL))) | |
1228 { | 1222 { |
1229 request->logging_function (gftp_logging_error, request, | 1223 request->logging_function (gftp_logging_error, request, |
1230 _("Cannot look up hostname %s: %s\n"), | 1224 _("Cannot look up hostname %s: %s\n"), |
1231 request->hostname, g_strerror (errno)); | 1225 request->hostname, g_strerror (errno)); |
1232 return (GFTP_ERETRYABLE); | 1226 return (GFTP_ERETRYABLE); |
1233 } | 1227 } |
1234 | 1228 |
1235 addr = (struct sockaddr *) request->host.h_addr_list[0]; | 1229 addr = (struct sockaddr *) host.h_addr_list[0]; |
1236 | 1230 |
1237 #endif /* HAVE_GETADDRINFO */ | 1231 #endif /* HAVE_GETADDRINFO */ |
1238 | 1232 |
1239 templist = proxy_hosts->list; | 1233 templist = proxy_hosts->list; |
1240 while (templist != NULL) | 1234 while (templist != NULL) |
1284 return (NULL); | 1278 return (NULL); |
1285 } | 1279 } |
1286 | 1280 |
1287 savepos = *endpos; | 1281 savepos = *endpos; |
1288 *endpos = '\0'; | 1282 *endpos = '\0'; |
1289 *dest = g_malloc ((gulong) (endpos - source + 1)); | 1283 *dest = g_malloc0 ((gulong) (endpos - source + 1)); |
1290 strcpy (*dest, source); | 1284 strcpy (*dest, source); |
1291 *endpos = savepos; | 1285 *endpos = savepos; |
1292 | 1286 |
1293 /* Skip the blanks till we get to the next entry */ | 1287 /* Skip the blanks till we get to the next entry */ |
1294 source = endpos + 1; | 1288 source = endpos + 1; |
1915 if (*ret == 0) | 1909 if (*ret == 0) |
1916 { | 1910 { |
1917 fle = g_malloc0 (sizeof (*fle)); | 1911 fle = g_malloc0 (sizeof (*fle)); |
1918 while (gftp_get_next_file (request, NULL, fle) > 0) | 1912 while (gftp_get_next_file (request, NULL, fle) > 0) |
1919 { | 1913 { |
1920 newsize = g_malloc (sizeof (*newsize)); | 1914 newsize = g_malloc0 (sizeof (*newsize)); |
1921 *newsize = fle->size; | 1915 *newsize = fle->size; |
1922 g_hash_table_insert (dirhash, fle->file, newsize); | 1916 g_hash_table_insert (dirhash, fle->file, newsize); |
1923 fle->file = NULL; | 1917 fle->file = NULL; |
1924 gftp_file_destroy (fle, 0); | 1918 gftp_file_destroy (fle, 0); |
1925 } | 1919 } |
1979 { | 1973 { |
1980 gftp_destroy_dir_hash (dirhash); | 1974 gftp_destroy_dir_hash (dirhash); |
1981 return (NULL); | 1975 return (NULL); |
1982 } | 1976 } |
1983 | 1977 |
1984 fle = g_malloc (sizeof (*fle)); | 1978 fle = g_malloc0 (sizeof (*fle)); |
1985 templist = NULL; | 1979 templist = NULL; |
1986 while (gftp_get_next_file (transfer->fromreq, NULL, fle) > 0) | 1980 while (gftp_get_next_file (transfer->fromreq, NULL, fle) > 0) |
1987 { | 1981 { |
1988 if (strcmp (fle->file, ".") == 0 || strcmp (fle->file, "..") == 0) | 1982 if (strcmp (fle->file, ".") == 0 || strcmp (fle->file, "..") == 0) |
1989 { | 1983 { |
2343 else | 2337 else |
2344 port = 0; | 2338 port = 0; |
2345 | 2339 |
2346 return (port); | 2340 return (port); |
2347 } | 2341 } |
2348 #endif | |
2349 | 2342 |
2350 | 2343 |
2351 int | 2344 int |
2352 gftp_connect_server (gftp_request * request, char *service, | 2345 gftp_connect_server_with_getaddr (gftp_request * request, char *service, |
2353 char *proxy_hostname, unsigned int proxy_port) | 2346 char *proxy_hostname, unsigned int proxy_port) |
2354 { | 2347 { |
2348 struct addrinfo *hostp, *current_hostp; | |
2355 char *connect_host, *disphost; | 2349 char *connect_host, *disphost; |
2356 unsigned int port; | |
2357 int sock = -1; | |
2358 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) | |
2359 struct addrinfo hints, *res; | 2350 struct addrinfo hints, *res; |
2360 intptr_t enable_ipv6; | 2351 intptr_t enable_ipv6; |
2352 unsigned int port; | |
2353 int ret, sock = -1; | |
2361 char serv[8]; | 2354 char serv[8]; |
2362 int errnum; | 2355 |
2363 | 2356 if ((ret = gftp_need_proxy (request, service, proxy_hostname, |
2364 if ((errnum = gftp_need_proxy (request, service, proxy_hostname, | |
2365 proxy_port)) < 0) | 2357 proxy_port)) < 0) |
2366 return (errnum); | 2358 return (ret); |
2367 else | 2359 else |
2368 { | 2360 request->use_proxy = ret; |
2369 request->use_proxy = errnum; | |
2370 if (request->use_proxy) | |
2371 request->hostp = NULL; | |
2372 } | |
2373 | 2361 |
2374 gftp_lookup_request_option (request, "enable_ipv6", &enable_ipv6); | 2362 gftp_lookup_request_option (request, "enable_ipv6", &enable_ipv6); |
2375 | 2363 |
2376 request->free_hostp = 1; | |
2377 memset (&hints, 0, sizeof (hints)); | 2364 memset (&hints, 0, sizeof (hints)); |
2378 hints.ai_flags = AI_CANONNAME; | 2365 hints.ai_flags = AI_CANONNAME; |
2379 | 2366 |
2380 if (enable_ipv6) | 2367 hints.ai_family = enable_ipv6 ? PF_UNSPEC : AF_INET; |
2381 hints.ai_family = PF_UNSPEC; | |
2382 else | |
2383 hints.ai_family = AF_INET; | |
2384 | |
2385 hints.ai_socktype = SOCK_STREAM; | 2368 hints.ai_socktype = SOCK_STREAM; |
2386 | 2369 |
2387 if (request->use_proxy) | 2370 if (request->use_proxy) |
2388 { | 2371 { |
2389 connect_host = proxy_hostname; | 2372 connect_host = proxy_hostname; |
2393 { | 2376 { |
2394 connect_host = request->hostname; | 2377 connect_host = request->hostname; |
2395 port = request->port; | 2378 port = request->port; |
2396 } | 2379 } |
2397 | 2380 |
2398 if (request->hostp == NULL) | 2381 if (port == 0) |
2399 { | 2382 strcpy (serv, service); |
2400 if (port == 0) | 2383 else |
2401 strcpy (serv, service); | 2384 snprintf (serv, sizeof (serv), "%d", port); |
2402 else | 2385 |
2403 snprintf (serv, sizeof (serv), "%d", port); | 2386 request->logging_function (gftp_logging_misc, request, |
2404 | 2387 _("Looking up %s\n"), connect_host); |
2405 request->logging_function (gftp_logging_misc, request, | 2388 if ((ret = getaddrinfo (connect_host, serv, &hints, |
2406 _("Looking up %s\n"), connect_host); | 2389 &hostp)) != 0) |
2407 if ((errnum = getaddrinfo (connect_host, serv, &hints, | 2390 { |
2408 &request->hostp)) != 0) | 2391 request->logging_function (gftp_logging_error, request, |
2409 { | 2392 _("Cannot look up hostname %s: %s\n"), |
2410 request->logging_function (gftp_logging_error, request, | 2393 connect_host, gai_strerror (ret)); |
2411 _("Cannot look up hostname %s: %s\n"), | 2394 return (GFTP_ERETRYABLE); |
2412 connect_host, gai_strerror (errnum)); | |
2413 return (GFTP_ERETRYABLE); | |
2414 } | |
2415 } | 2395 } |
2416 | 2396 |
2417 disphost = connect_host; | 2397 disphost = connect_host; |
2418 for (res = request->hostp; res != NULL; res = res->ai_next) | 2398 for (res = hostp; res != NULL; res = res->ai_next) |
2419 { | 2399 { |
2420 disphost = res->ai_canonname ? res->ai_canonname : connect_host; | 2400 disphost = res->ai_canonname ? res->ai_canonname : connect_host; |
2421 port = get_port (res); | 2401 port = get_port (res); |
2422 if (!request->use_proxy) | 2402 if (!request->use_proxy) |
2423 request->port = port; | 2403 request->port = port; |
2441 disphost, g_strerror (errno)); | 2421 disphost, g_strerror (errno)); |
2442 close (sock); | 2422 close (sock); |
2443 continue; | 2423 continue; |
2444 } | 2424 } |
2445 | 2425 |
2446 request->current_hostp = res; | 2426 current_hostp = res; |
2447 request->ai_family = res->ai_family; | 2427 request->ai_family = res->ai_family; |
2448 break; | 2428 break; |
2449 } | 2429 } |
2450 | 2430 |
2451 if (res == NULL) | 2431 if (res == NULL) |
2452 { | 2432 { |
2453 if (request->hostp != NULL) | 2433 if (hostp != NULL) |
2454 { | 2434 freeaddrinfo (hostp); |
2455 freeaddrinfo (request->hostp); | 2435 |
2456 request->hostp = NULL; | |
2457 } | |
2458 return (GFTP_ERETRYABLE); | 2436 return (GFTP_ERETRYABLE); |
2459 } | 2437 } |
2460 | 2438 |
2461 #else /* !HAVE_GETADDRINFO */ | 2439 request->remote_addr_len = current_hostp->ai_addrlen; |
2440 request->remote_addr = g_malloc0 (request->remote_addr_len); | |
2441 memcpy (request->remote_addr, &((struct sockaddr_in *) current_hostp->ai_addr)->sin_addr, | |
2442 request->remote_addr_len); | |
2443 | |
2444 request->logging_function (gftp_logging_misc, request, | |
2445 _("Connected to %s:%d\n"), connect_host, port); | |
2446 | |
2447 return (sock); | |
2448 } | |
2449 #endif | |
2450 | |
2451 | |
2452 int | |
2453 gftp_connect_server_legacy (gftp_request * request, char *service, | |
2454 char *proxy_hostname, unsigned int proxy_port) | |
2455 { | |
2462 struct sockaddr_in remote_address; | 2456 struct sockaddr_in remote_address; |
2457 char *connect_host, *disphost; | |
2458 struct hostent host, *hostp; | |
2463 struct servent serv_struct; | 2459 struct servent serv_struct; |
2464 int ret; | 2460 int ret, sock, curhost; |
2461 unsigned int port; | |
2465 | 2462 |
2466 if ((ret = gftp_need_proxy (request, service, proxy_hostname, | 2463 if ((ret = gftp_need_proxy (request, service, proxy_hostname, |
2467 proxy_port)) < 0) | 2464 proxy_port)) < 0) |
2468 return (ret); | 2465 return (ret); |
2469 | 2466 |
2470 request->use_proxy = ret; | 2467 request->use_proxy = ret; |
2471 if (request->use_proxy == 1) | 2468 if (request->use_proxy == 1) |
2472 request->hostp = NULL; | 2469 hostp = NULL; |
2473 | 2470 |
2474 request->ai_family = AF_INET; | 2471 request->ai_family = AF_INET; |
2475 if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) | 2472 if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) |
2476 { | 2473 { |
2477 request->logging_function (gftp_logging_error, request, | 2474 request->logging_function (gftp_logging_error, request, |
2511 request->port = port; | 2508 request->port = port; |
2512 } | 2509 } |
2513 | 2510 |
2514 remote_address.sin_port = htons (port); | 2511 remote_address.sin_port = htons (port); |
2515 | 2512 |
2516 if (request->hostp == NULL) | 2513 request->logging_function (gftp_logging_misc, request, |
2517 { | 2514 _("Looking up %s\n"), connect_host); |
2518 request->logging_function (gftp_logging_misc, request, | 2515 |
2519 _("Looking up %s\n"), connect_host); | 2516 if (!(hostp = r_gethostbyname (connect_host, &host, NULL))) |
2520 if (!(request->hostp = r_gethostbyname (connect_host, &request->host, | 2517 { |
2521 NULL))) | 2518 request->logging_function (gftp_logging_error, request, |
2522 { | 2519 _("Cannot look up hostname %s: %s\n"), |
2523 request->logging_function (gftp_logging_error, request, | 2520 connect_host, g_strerror (errno)); |
2524 _("Cannot look up hostname %s: %s\n"), | 2521 close (sock); |
2525 connect_host, g_strerror (errno)); | 2522 return (GFTP_ERETRYABLE); |
2526 close (sock); | |
2527 return (GFTP_ERETRYABLE); | |
2528 } | |
2529 } | 2523 } |
2530 | 2524 |
2531 disphost = NULL; | 2525 disphost = NULL; |
2532 for (request->curhost = 0; | 2526 for (curhost = 0; |
2533 request->host.h_addr_list[request->curhost] != NULL; | 2527 host.h_addr_list[curhost] != NULL; |
2534 request->curhost++) | 2528 curhost++) |
2535 { | 2529 { |
2536 disphost = request->host.h_name; | 2530 disphost = host.h_name; |
2537 memcpy (&remote_address.sin_addr, | 2531 memcpy (&remote_address.sin_addr, |
2538 request->host.h_addr_list[request->curhost], | 2532 host.h_addr_list[curhost], |
2539 request->host.h_length); | 2533 host.h_length); |
2540 request->logging_function (gftp_logging_misc, request, | 2534 request->logging_function (gftp_logging_misc, request, |
2541 _("Trying %s:%d\n"), | 2535 _("Trying %s:%d\n"), |
2542 request->host.h_name, port); | 2536 host.h_name, port); |
2543 | 2537 |
2544 if (connect (sock, (struct sockaddr *) &remote_address, | 2538 if (connect (sock, (struct sockaddr *) &remote_address, |
2545 sizeof (remote_address)) == -1) | 2539 sizeof (remote_address)) == -1) |
2546 { | 2540 { |
2547 request->logging_function (gftp_logging_error, request, | 2541 request->logging_function (gftp_logging_error, request, |
2549 connect_host, g_strerror (errno)); | 2543 connect_host, g_strerror (errno)); |
2550 } | 2544 } |
2551 break; | 2545 break; |
2552 } | 2546 } |
2553 | 2547 |
2554 if (request->host.h_addr_list[request->curhost] == NULL) | 2548 if (host.h_addr_list[curhost] == NULL) |
2555 { | 2549 { |
2556 close (sock); | 2550 close (sock); |
2557 return (GFTP_ERETRYABLE); | 2551 return (GFTP_ERETRYABLE); |
2558 } | 2552 } |
2559 #endif /* HAVE_GETADDRINFO */ | 2553 |
2554 return (sock); | |
2555 } | |
2556 | |
2557 | |
2558 int | |
2559 gftp_connect_server (gftp_request * request, char *service, | |
2560 char *proxy_hostname, unsigned int proxy_port) | |
2561 { | |
2562 int sock; | |
2563 | |
2564 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) | |
2565 sock = gftp_connect_server_with_getaddr (request, service, proxy_hostname, | |
2566 proxy_port); | |
2567 #else | |
2568 sock = gftp_connect_server_legacy (request, service, proxy_hostname, | |
2569 proxy_port); | |
2570 #endif | |
2571 | |
2572 if (sock < 0) | |
2573 return (sock); | |
2560 | 2574 |
2561 if (fcntl (sock, F_SETFD, 1) == -1) | 2575 if (fcntl (sock, F_SETFD, 1) == -1) |
2562 { | 2576 { |
2563 request->logging_function (gftp_logging_error, request, | 2577 request->logging_function (gftp_logging_error, request, |
2564 _("Error: Cannot set close on exec flag: %s\n"), | 2578 _("Error: Cannot set close on exec flag: %s\n"), |
2565 g_strerror (errno)); | 2579 g_strerror (errno)); |
2566 | 2580 close (sock); |
2567 return (GFTP_ERETRYABLE); | 2581 return (GFTP_ERETRYABLE); |
2568 } | 2582 } |
2569 | |
2570 request->logging_function (gftp_logging_misc, request, | |
2571 _("Connected to %s:%d\n"), connect_host, port); | |
2572 | 2583 |
2573 if (gftp_fd_set_sockblocking (request, sock, 1) < 0) | 2584 if (gftp_fd_set_sockblocking (request, sock, 1) < 0) |
2574 { | 2585 { |
2575 close (sock); | 2586 close (sock); |
2576 return (GFTP_ERETRYABLE); | 2587 return (GFTP_ERETRYABLE); |