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);