Mercurial > gftp.yaz
comparison lib/protocols.c @ 122:76e2b58a9440
2003-4-5 Brian Masney <masneyb@gftp.org>
* lib/config_file.c lib/options.h lib/gftp.h lib/rfc959.c
lib/rfc2068.c lib/ssh.c - added new internal configuration interface.
Rather than having a global variable for each option, I have a global
hash table (gftp_global_options_htable) that I can look up option names
by name using gftp_lookup_global_option(). I also an options hash
associated with a request structure, so I will be able to call
gftp_lookup_request_option(). I will be able to override options with
bookmarks or while transfers are in progress very easily now. Also, all
options no longer have to appear in config_file.c, the per protocol
options can appear inside their own file
* lib/gftp.h lib/bookmarks.c lib/local.c lib/rfc959.c lib/rfc2068.c -
remove set_data_type and protocol name from struct gftp_request
* lib/rfc959.c - renamed all firewall_* variables to ftp_proxy_* in
the config file
* lib/gftp.h lib/protocols.c lib/rfc959.c - renamed all GFTP_TYPE_*
vars to GFTP_DIRTYPE_*
* lib/gftp.h - removed ascii field and renamed the node pointer to
user_data in struct gftp_file. In gftp_request, removed any setting
that is now stored in the global/local hash tables. Added
register_module() pointer that will be called whenever the protocol is
first loaded into gftp
* lib/rfc959.c src/text/gftp-text.c - moved the ascii/binary
translation to rfc959.c. Also, moved any instance of automatically
setting the data type to rfc959.c as well.
* lib/misc.c lib/sshv2.c - moved all ssh functions from misc.c to
sshv2.c. I had these origionally in misc.c because I used to have 2
different SSH protocols
* lib/protocols.c src/text/gftp-text.c - added gftp_calc_kbs() to
protocols.c. This no longer needs to be in the different ports
* src/text/gftp-text.c - read/write options based on new configuration
interface
* Use new configuration interface in all source files
* Updated copyright dates on all source files
* Note: GTK+ port is completely broken at the moment. I'll upload
those changes whenever I get them done
author | masneyb |
---|---|
date | Sat, 05 Apr 2003 16:30:45 +0000 |
parents | 982e3890e7fe |
children | 65048c959029 |
comparison
equal
deleted
inserted
replaced
121:1b41e6945e9d | 122:76e2b58a9440 |
---|---|
1 /*****************************************************************************/ | 1 /*****************************************************************************/ |
2 /* protocols.c - Skeleton functions for the protocols gftp supports */ | 2 /* protocols.c - Skeleton functions for the protocols gftp supports */ |
3 /* Copyright (C) 1998-2002 Brian Masney <masneyb@gftp.org> */ | 3 /* Copyright (C) 1998-2003 Brian Masney <masneyb@gftp.org> */ |
4 /* */ | 4 /* */ |
5 /* This program is free software; you can redistribute it and/or modify */ | 5 /* This program is free software; you can redistribute it and/or modify */ |
6 /* it under the terms of the GNU General Public License as published by */ | 6 /* it under the terms of the GNU General Public License as published by */ |
7 /* the Free Software Foundation; either version 2 of the License, or */ | 7 /* the Free Software Foundation; either version 2 of the License, or */ |
8 /* (at your option) any later version. */ | 8 /* (at your option) any later version. */ |
18 /*****************************************************************************/ | 18 /*****************************************************************************/ |
19 | 19 |
20 #include "gftp.h" | 20 #include "gftp.h" |
21 static const char cvsid[] = "$Id$"; | 21 static const char cvsid[] = "$Id$"; |
22 | 22 |
23 /* {{{ gftp_request_new */ | |
23 gftp_request * | 24 gftp_request * |
24 gftp_request_new (void) | 25 gftp_request_new (void) |
25 { | 26 { |
26 gftp_request *request; | 27 gftp_request *request; |
27 | 28 |
28 request = g_malloc0 (sizeof (*request)); | 29 request = g_malloc0 (sizeof (*request)); |
29 request->sockfd = -1; | 30 request->sockfd = -1; |
30 request->datafd = -1; | 31 request->datafd = -1; |
31 request->cachefd = -1; | 32 request->cachefd = -1; |
32 request->data_type = GFTP_TYPE_BINARY; | 33 request->server_type = GFTP_DIRTYPE_OTHER; |
33 request->server_type = GFTP_TYPE_OTHER; | |
34 return (request); | 34 return (request); |
35 } | 35 } |
36 | 36 /* }}} */ |
37 | 37 |
38 void | 38 void |
39 gftp_request_destroy (gftp_request * request, int free_request) | 39 gftp_request_destroy (gftp_request * request, int free_request) |
40 { | 40 { |
41 g_return_if_fail (request != NULL); | 41 g_return_if_fail (request != NULL); |
59 memset (request->account, 0, strlen (request->account)); | 59 memset (request->account, 0, strlen (request->account)); |
60 g_free (request->account); | 60 g_free (request->account); |
61 } | 61 } |
62 if (request->directory) | 62 if (request->directory) |
63 g_free (request->directory); | 63 g_free (request->directory); |
64 if (request->proxy_config) | |
65 g_free (request->proxy_config); | |
66 if (request->proxy_hostname) | |
67 g_free (request->proxy_hostname); | |
68 if (request->proxy_username) | |
69 g_free (request->proxy_username); | |
70 if (request->proxy_password) | |
71 g_free (request->proxy_password); | |
72 if (request->proxy_account) | |
73 g_free (request->proxy_account); | |
74 if (request->last_ftp_response) | 64 if (request->last_ftp_response) |
75 g_free (request->last_ftp_response); | 65 g_free (request->last_ftp_response); |
76 if (request->protocol_data) | 66 if (request->protocol_data) |
77 g_free (request->protocol_data); | 67 g_free (request->protocol_data); |
78 if (request->sftpserv_path) | |
79 g_free (request->sftpserv_path); | |
80 | 68 |
81 memset (request, 0, sizeof (*request)); | 69 memset (request, 0, sizeof (*request)); |
82 | 70 |
83 if (free_request) | 71 if (free_request) |
84 g_free (request); | 72 g_free (request); |
85 else | 73 else |
86 { | 74 { |
87 request->sockfd = -1; | 75 request->sockfd = -1; |
88 request->datafd = -1; | 76 request->datafd = -1; |
89 request->cachefd = -1; | 77 request->cachefd = -1; |
90 request->data_type = GFTP_TYPE_BINARY; | 78 } |
91 } | 79 /* FIXME - free local_options */ |
92 } | 80 } |
93 | 81 |
94 | 82 |
95 void | 83 void |
96 gftp_file_destroy (gftp_file * file) | 84 gftp_file_destroy (gftp_file * file) |
134 if (request->hostp) | 122 if (request->hostp) |
135 freeaddrinfo (request->hostp); | 123 freeaddrinfo (request->hostp); |
136 #endif | 124 #endif |
137 request->hostp = NULL; | 125 request->hostp = NULL; |
138 | 126 |
139 if (request->sftpserv_path != NULL) | |
140 { | |
141 g_free (request->sftpserv_path); | |
142 request->sftpserv_path = NULL; | |
143 } | |
144 | |
145 request->cached = 0; | 127 request->cached = 0; |
146 if (request->disconnect == NULL) | 128 if (request->disconnect == NULL) |
147 return; | 129 return; |
148 request->disconnect (request); | 130 request->disconnect (request); |
149 } | 131 } |
151 | 133 |
152 off_t | 134 off_t |
153 gftp_get_file (gftp_request * request, const char *filename, int fd, | 135 gftp_get_file (gftp_request * request, const char *filename, int fd, |
154 size_t startsize) | 136 size_t startsize) |
155 { | 137 { |
138 float maxkbs; | |
139 | |
156 g_return_val_if_fail (request != NULL, GFTP_EFATAL); | 140 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
141 | |
142 gftp_lookup_request_option (request, "maxkbs", &maxkbs); | |
143 if (maxkbs > 0) | |
144 { | |
145 request->logging_function (gftp_logging_misc, request->user_data, | |
146 _("File transfer will be throttled to %.2f KB/s\n"), | |
147 maxkbs); | |
148 } | |
157 | 149 |
158 request->cached = 0; | 150 request->cached = 0; |
159 if (request->get_file == NULL) | 151 if (request->get_file == NULL) |
160 return (GFTP_EFATAL); | 152 return (GFTP_EFATAL); |
161 return (request->get_file (request, filename, fd, startsize)); | 153 return (request->get_file (request, filename, fd, startsize)); |
164 | 156 |
165 int | 157 int |
166 gftp_put_file (gftp_request * request, const char *filename, int fd, | 158 gftp_put_file (gftp_request * request, const char *filename, int fd, |
167 size_t startsize, size_t totalsize) | 159 size_t startsize, size_t totalsize) |
168 { | 160 { |
161 float maxkbs; | |
162 | |
169 g_return_val_if_fail (request != NULL, GFTP_EFATAL); | 163 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
164 | |
165 gftp_lookup_request_option (request, "maxkbs", &maxkbs); | |
166 | |
167 if (maxkbs > 0) | |
168 { | |
169 request->logging_function (gftp_logging_misc, request->user_data, | |
170 _("File transfer will be throttled to %.2f KB/s\n"), | |
171 maxkbs); | |
172 } | |
170 | 173 |
171 request->cached = 0; | 174 request->cached = 0; |
172 if (request->put_file == NULL) | 175 if (request->put_file == NULL) |
173 return (GFTP_EFATAL); | 176 return (GFTP_EFATAL); |
174 return (request->put_file (request, filename, fd, startsize, totalsize)); | 177 return (request->put_file (request, filename, fd, startsize, totalsize)); |
375 | 378 |
376 int | 379 int |
377 gftp_parse_bookmark (gftp_request * request, const char * bookmark) | 380 gftp_parse_bookmark (gftp_request * request, const char * bookmark) |
378 { | 381 { |
379 gftp_logging_func logging_function; | 382 gftp_logging_func logging_function; |
380 gftp_bookmarks * tempentry; | 383 gftp_bookmarks_var * tempentry; |
384 char *default_protocol; | |
381 int i; | 385 int i; |
382 | 386 |
383 g_return_val_if_fail (request != NULL, GFTP_EFATAL); | 387 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
384 g_return_val_if_fail (bookmark != NULL, GFTP_EFATAL); | 388 g_return_val_if_fail (bookmark != NULL, GFTP_EFATAL); |
385 | 389 |
386 logging_function = request->logging_function; | 390 logging_function = request->logging_function; |
387 gftp_request_destroy (request, 0); | 391 gftp_request_destroy (request, 0); |
388 request->logging_function = logging_function; | 392 request->logging_function = logging_function; |
389 | 393 |
390 if ((tempentry = g_hash_table_lookup (bookmarks_htable, bookmark)) == NULL) | 394 if ((tempentry = g_hash_table_lookup (gftp_bookmarks_htable, |
395 bookmark)) == NULL) | |
391 { | 396 { |
392 request->logging_function (gftp_logging_error, request->user_data, | 397 request->logging_function (gftp_logging_error, request->user_data, |
393 _("Error: Could not find bookmark %s\n"), | 398 _("Error: Could not find bookmark %s\n"), |
394 bookmark); | 399 bookmark); |
395 return (GFTP_EFATAL); | 400 return (GFTP_EFATAL); |
403 | 408 |
404 if (tempentry->user != NULL) | 409 if (tempentry->user != NULL) |
405 gftp_set_username (request, tempentry->user); | 410 gftp_set_username (request, tempentry->user); |
406 | 411 |
407 if (tempentry->pass != NULL) | 412 if (tempentry->pass != NULL) |
408 { | 413 gftp_set_password (request, tempentry->pass); |
409 if (strncmp (tempentry->pass, "@EMAIL@", 7) == 0) | |
410 gftp_set_password (request, emailaddr); | |
411 else | |
412 gftp_set_password (request, tempentry->pass); | |
413 } | |
414 | 414 |
415 if (tempentry->acct != NULL) | 415 if (tempentry->acct != NULL) |
416 gftp_set_account (request, tempentry->acct); | 416 gftp_set_account (request, tempentry->acct); |
417 | 417 |
418 gftp_set_hostname (request, tempentry->hostname); | 418 gftp_set_hostname (request, tempentry->hostname); |
419 gftp_set_directory (request, tempentry->remote_dir); | 419 gftp_set_directory (request, tempentry->remote_dir); |
420 gftp_set_port (request, tempentry->port); | 420 gftp_set_port (request, tempentry->port); |
421 gftp_set_sftpserv_path (request, tempentry->sftpserv_path); | |
422 | 421 |
423 for (i = 0; gftp_protocols[i].name; i++) | 422 for (i = 0; gftp_protocols[i].name; i++) |
424 { | 423 { |
425 if (strcmp (gftp_protocols[i].name, tempentry->protocol) == 0) | 424 if (strcmp (gftp_protocols[i].name, tempentry->protocol) == 0) |
426 { | 425 { |
427 gftp_protocols[i].init (request); | 426 gftp_protocols[i].init (request); |
428 break; | 427 break; |
429 } | 428 } |
430 } | 429 } |
431 | 430 |
432 if (!gftp_protocols[i].name) | 431 if (gftp_protocols[i].name == NULL) |
433 { | 432 { |
434 for (i = 0; gftp_protocols[i].url_prefix; i++) | 433 gftp_lookup_request_option (request, "default_protocol", |
435 { | 434 &default_protocol); |
436 if (strcmp (gftp_protocols[i].name, default_protocol) == 0) | 435 |
437 break; | 436 if (*default_protocol != '\0') |
437 { | |
438 for (i = 0; gftp_protocols[i].url_prefix; i++) | |
439 { | |
440 if (strcmp (gftp_protocols[i].name, default_protocol) == 0) | |
441 break; | |
442 } | |
438 } | 443 } |
439 | 444 |
440 if (gftp_protocols[i].url_prefix == NULL) | 445 if (gftp_protocols[i].url_prefix == NULL) |
441 i = GFTP_FTP_NUM; | 446 i = GFTP_FTP_NUM; |
442 } | 447 } |
447 | 452 |
448 | 453 |
449 int | 454 int |
450 gftp_parse_url (gftp_request * request, const char *url) | 455 gftp_parse_url (gftp_request * request, const char *url) |
451 { | 456 { |
452 char *pos, *endpos, *endhostpos, *str, tempchar; | 457 char *pos, *endpos, *endhostpos, *str, tempchar, *default_protocol; |
453 gftp_logging_func logging_function; | 458 gftp_logging_func logging_function; |
454 const char *stpos; | 459 const char *stpos; |
455 int len, i; | 460 int len, i; |
456 | 461 |
457 g_return_val_if_fail (request != NULL, GFTP_EFATAL); | 462 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
461 gftp_request_destroy (request, 0); | 466 gftp_request_destroy (request, 0); |
462 request->logging_function = logging_function; | 467 request->logging_function = logging_function; |
463 | 468 |
464 for (stpos = url; *stpos == ' '; stpos++); | 469 for (stpos = url; *stpos == ' '; stpos++); |
465 | 470 |
471 i = GFTP_FTP_NUM; | |
472 | |
466 if ((pos = strstr (stpos, "://")) != NULL) | 473 if ((pos = strstr (stpos, "://")) != NULL) |
467 { | 474 { |
468 *pos = '\0'; | 475 *pos = '\0'; |
469 | 476 |
470 for (i = 0; gftp_protocols[i].url_prefix; i++) | 477 for (i = 0; gftp_protocols[i].url_prefix; i++) |
477 return (GFTP_EFATAL); | 484 return (GFTP_EFATAL); |
478 *pos = ':'; | 485 *pos = ':'; |
479 } | 486 } |
480 else | 487 else |
481 { | 488 { |
482 for (i = 0; gftp_protocols[i].url_prefix; i++) | 489 gftp_lookup_request_option (request, "default_protocol", |
483 { | 490 &default_protocol); |
484 if (strcmp (gftp_protocols[i].name, default_protocol) == 0) | 491 |
485 break; | 492 if (*default_protocol != '\0') |
486 } | 493 { |
487 | 494 for (i = 0; gftp_protocols[i].url_prefix; i++) |
488 if (gftp_protocols[i].url_prefix == NULL) | 495 { |
489 i = GFTP_FTP_NUM; | 496 if (strcmp (gftp_protocols[i].name, default_protocol) == 0) |
490 } | 497 break; |
498 } | |
499 } | |
500 } | |
501 | |
502 if (gftp_protocols[i].url_prefix == NULL) | |
503 i = GFTP_FTP_NUM; | |
491 | 504 |
492 gftp_protocols[i].init (request); | 505 gftp_protocols[i].init (request); |
493 | 506 |
494 if (request->parse_url != NULL) | 507 if (request->parse_url != NULL) |
495 return (request->parse_url (request, url)); | 508 return (request->parse_url (request, url)); |
560 g_free (str); | 573 g_free (str); |
561 return (0); | 574 return (0); |
562 } | 575 } |
563 | 576 |
564 | 577 |
565 int | |
566 gftp_set_data_type (gftp_request * request, int data_type) | |
567 { | |
568 g_return_val_if_fail (request != NULL, GFTP_EFATAL); | |
569 | |
570 if (request->set_data_type == NULL) | |
571 return (0); | |
572 return (request->set_data_type (request, data_type)); | |
573 } | |
574 | |
575 | |
576 void | 578 void |
577 gftp_set_hostname (gftp_request * request, const char *hostname) | 579 gftp_set_hostname (gftp_request * request, const char *hostname) |
578 { | 580 { |
579 g_return_if_fail (request != NULL); | 581 g_return_if_fail (request != NULL); |
580 g_return_if_fail (hostname != NULL); | 582 g_return_if_fail (hostname != NULL); |
656 | 658 |
657 request->port = port; | 659 request->port = port; |
658 } | 660 } |
659 | 661 |
660 | 662 |
661 void | |
662 gftp_set_proxy_hostname (gftp_request * request, const char *hostname) | |
663 { | |
664 g_return_if_fail (request != NULL); | |
665 g_return_if_fail (hostname != NULL); | |
666 | |
667 if (request->proxy_hostname) | |
668 g_free (request->proxy_hostname); | |
669 request->proxy_hostname = g_malloc (strlen (hostname) + 1); | |
670 strcpy (request->proxy_hostname, hostname); | |
671 } | |
672 | |
673 | |
674 void | |
675 gftp_set_proxy_username (gftp_request * request, const char *username) | |
676 { | |
677 g_return_if_fail (request != NULL); | |
678 g_return_if_fail (username != NULL); | |
679 | |
680 if (request->proxy_username) | |
681 g_free (request->proxy_username); | |
682 request->proxy_username = g_malloc (strlen (username) + 1); | |
683 strcpy (request->proxy_username, username); | |
684 } | |
685 | |
686 | |
687 void | |
688 gftp_set_proxy_password (gftp_request * request, const char *password) | |
689 { | |
690 g_return_if_fail (request != NULL); | |
691 g_return_if_fail (password != NULL); | |
692 | |
693 if (request->proxy_password) | |
694 g_free (request->proxy_password); | |
695 request->proxy_password = g_malloc (strlen (password) + 1); | |
696 strcpy (request->proxy_password, password); | |
697 } | |
698 | |
699 | |
700 void | |
701 gftp_set_proxy_account (gftp_request * request, const char *account) | |
702 { | |
703 g_return_if_fail (request != NULL); | |
704 g_return_if_fail (account != NULL); | |
705 | |
706 if (request->proxy_account) | |
707 g_free (request->proxy_account); | |
708 request->proxy_account = g_malloc (strlen (account) + 1); | |
709 strcpy (request->proxy_account, account); | |
710 } | |
711 | |
712 | |
713 void | |
714 gftp_set_proxy_port (gftp_request * request, unsigned int port) | |
715 { | |
716 g_return_if_fail (request != NULL); | |
717 | |
718 request->proxy_port = port; | |
719 } | |
720 | |
721 | |
722 int | 663 int |
723 gftp_remove_directory (gftp_request * request, const char *directory) | 664 gftp_remove_directory (gftp_request * request, const char *directory) |
724 { | 665 { |
725 g_return_val_if_fail (request != NULL, GFTP_EFATAL); | 666 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
726 | 667 |
795 return (GFTP_EFATAL); | 736 return (GFTP_EFATAL); |
796 return (request->site (request, command)); | 737 return (request->site (request, command)); |
797 } | 738 } |
798 | 739 |
799 | 740 |
800 void | |
801 gftp_set_proxy_config (gftp_request * request, const char *proxy_config) | |
802 { | |
803 int len; | |
804 | |
805 g_return_if_fail (request != NULL); | |
806 | |
807 if (request->proxy_config != NULL) | |
808 g_free (request->proxy_config); | |
809 | |
810 if (proxy_config == NULL) | |
811 { | |
812 request->proxy_config = NULL; | |
813 return; | |
814 } | |
815 | |
816 len = strlen (proxy_config); | |
817 | |
818 if (len > 0 && (proxy_config[len - 1] != 'n' || | |
819 proxy_config[len - 2] != '%')) | |
820 len += 2; | |
821 | |
822 request->proxy_config = g_malloc (len + 1); | |
823 strcpy (request->proxy_config, proxy_config); | |
824 if (len != strlen (proxy_config)) | |
825 { | |
826 request->proxy_config[len - 2] = '%'; | |
827 request->proxy_config[len - 1] = 'n'; | |
828 request->proxy_config[len] = '\0'; | |
829 } | |
830 } | |
831 | |
832 | |
833 off_t | 741 off_t |
834 gftp_get_file_size (gftp_request * request, const char *filename) | 742 gftp_get_file_size (gftp_request * request, const char *filename) |
835 { | 743 { |
836 g_return_val_if_fail (request != NULL, 0); | 744 g_return_val_if_fail (request != NULL, 0); |
837 | 745 |
839 return (0); | 747 return (0); |
840 return (request->get_file_size (request, filename)); | 748 return (request->get_file_size (request, filename)); |
841 } | 749 } |
842 | 750 |
843 | 751 |
844 int | 752 static int |
845 gftp_need_proxy (gftp_request * request, char *service) | 753 gftp_need_proxy (gftp_request * request, char *service, char *proxy_hostname, |
846 { | 754 int proxy_port) |
755 { | |
756 gftp_config_list_vars * proxy_hosts; | |
847 gftp_proxy_hosts * hostname; | 757 gftp_proxy_hosts * hostname; |
848 unsigned char addy[4]; | 758 unsigned char addy[4]; |
849 struct sockaddr *addr; | 759 struct sockaddr *addr; |
850 GList * templist; | 760 GList * templist; |
851 gint32 netaddr; | 761 gint32 netaddr; |
852 char *pos; | 762 char *pos; |
853 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) | 763 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) |
854 struct addrinfo hints; | 764 struct addrinfo hints; |
855 int port, errnum; | 765 int port, errnum; |
856 char serv[8]; | 766 char serv[8]; |
767 #endif | |
768 | |
769 gftp_lookup_global_option ("ext", &proxy_hosts); | |
770 | |
771 if (proxy_hostname == NULL || *proxy_hostname == '\0') | |
772 return (0); | |
773 else if (proxy_hosts->list == NULL) | |
774 return (proxy_hostname != NULL && | |
775 *proxy_hostname != '\0'); | |
857 | 776 |
858 request->hostp = NULL; | 777 request->hostp = NULL; |
859 if (proxy_hosts == NULL) | 778 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) |
860 return (request->proxy_hostname != NULL | |
861 && *request->proxy_hostname != '\0' | |
862 && request->proxy_config != NULL | |
863 && *request->proxy_config != '\0'); | |
864 | |
865 memset (&hints, 0, sizeof (hints)); | 779 memset (&hints, 0, sizeof (hints)); |
866 hints.ai_flags = AI_CANONNAME; | 780 hints.ai_flags = AI_CANONNAME; |
867 hints.ai_family = AF_INET; | 781 hints.ai_family = AF_INET; |
868 hints.ai_socktype = SOCK_STREAM; | 782 hints.ai_socktype = SOCK_STREAM; |
869 | 783 |
870 port = request->use_proxy ? request->proxy_port : request->port; | 784 port = request->use_proxy ? proxy_port : request->port; |
871 if (port == 0) | 785 if (port == 0) |
872 strcpy (serv, service); | 786 strcpy (serv, service); |
873 else | 787 else |
874 snprintf (serv, sizeof (serv), "%d", port); | 788 snprintf (serv, sizeof (serv), "%d", port); |
875 | 789 |
886 } | 800 } |
887 | 801 |
888 addr = request->hostp->ai_addr; | 802 addr = request->hostp->ai_addr; |
889 | 803 |
890 #else /* !HAVE_GETADDRINFO */ | 804 #else /* !HAVE_GETADDRINFO */ |
891 | |
892 request->hostp = NULL; | |
893 if (proxy_hosts == NULL) | |
894 return (request->proxy_hostname != NULL | |
895 && *request->proxy_hostname != '\0' | |
896 && request->proxy_config != NULL | |
897 && *request->proxy_config != '\0'); | |
898 | |
899 request->logging_function (gftp_logging_misc, request->user_data, | 805 request->logging_function (gftp_logging_misc, request->user_data, |
900 _("Looking up %s\n"), request->hostname); | 806 _("Looking up %s\n"), request->hostname); |
901 | 807 |
902 if (!(request->hostp = r_gethostbyname (request->hostname, &request->host, | 808 if (!(request->hostp = r_gethostbyname (request->hostname, &request->host, |
903 NULL))) | 809 NULL))) |
910 | 816 |
911 addr = (struct sockaddr *) request->host.h_addr_list[0]; | 817 addr = (struct sockaddr *) request->host.h_addr_list[0]; |
912 | 818 |
913 #endif /* HAVE_GETADDRINFO */ | 819 #endif /* HAVE_GETADDRINFO */ |
914 | 820 |
915 templist = proxy_hosts; | 821 templist = proxy_hosts->list; |
916 while (templist != NULL) | 822 while (templist != NULL) |
917 { | 823 { |
918 hostname = templist->data; | 824 hostname = templist->data; |
919 if (hostname->domain && | 825 if (hostname->domain && |
920 strlen (request->hostname) > strlen (hostname->domain)) | 826 strlen (request->hostname) > strlen (hostname->domain)) |
935 if (netaddr == hostname->ipv4_network_address) | 841 if (netaddr == hostname->ipv4_network_address) |
936 return (0); | 842 return (0); |
937 } | 843 } |
938 templist = templist->next; | 844 templist = templist->next; |
939 } | 845 } |
940 return (request->proxy_hostname != NULL && *request->proxy_hostname != '\0' | 846 |
941 && request->proxy_config != NULL && *request->proxy_config != '\0'); | 847 return (proxy_hostname != NULL && *proxy_hostname != '\0'); |
942 } | |
943 | |
944 | |
945 char * | |
946 gftp_convert_ascii (char *buf, ssize_t *len, int direction) | |
947 { | |
948 ssize_t i, j, newsize; | |
949 char *tempstr; | |
950 | |
951 if (direction == GFTP_DIRECTION_DOWNLOAD) | |
952 { | |
953 for (i = 0, j = 0; i < *len; i++) | |
954 { | |
955 if (buf[i] != '\r') | |
956 buf[j++] = buf[i]; | |
957 else | |
958 --*len; | |
959 } | |
960 tempstr = buf; | |
961 } | |
962 else | |
963 { | |
964 newsize = 0; | |
965 for (i = 0; i < *len; i++) | |
966 { | |
967 newsize++; | |
968 if (i > 0 && buf[i] == '\n' && buf[i - 1] != '\r') | |
969 newsize++; | |
970 } | |
971 tempstr = g_malloc (newsize); | |
972 | |
973 for (i = 0, j = 0; i < *len; i++) | |
974 { | |
975 if (i > 0 && buf[i] == '\n' && buf[i - 1] != '\r') | |
976 tempstr[j++] = '\r'; | |
977 tempstr[j++] = buf[i]; | |
978 } | |
979 *len = newsize; | |
980 } | |
981 return (tempstr); | |
982 } | 848 } |
983 | 849 |
984 | 850 |
985 static char * | 851 static char * |
986 copy_token (char **dest, char *source) | 852 copy_token (char **dest, char *source) |
1126 } | 992 } |
1127 | 993 |
1128 fle->file = g_strdup (str); | 994 fle->file = g_strdup (str); |
1129 | 995 |
1130 curpos = goto_next_token (curpos + 1); | 996 curpos = goto_next_token (curpos + 1); |
1131 fle->size = strtol (curpos, NULL, 10) * 512; /* FIXME - Is this correct? */ | 997 fle->size = strtol (curpos, NULL, 10) * 512; /* Is this correct? */ |
1132 curpos = goto_next_token (curpos); | 998 curpos = goto_next_token (curpos); |
1133 | 999 |
1134 if ((fle->datetime = parse_time (curpos, &curpos)) == 0) | 1000 if ((fle->datetime = parse_time (curpos, &curpos)) == 0) |
1135 return (GFTP_EFATAL); | 1001 return (GFTP_EFATAL); |
1136 | 1002 |
1262 strcpy (fle->user, _("unknown")); | 1128 strcpy (fle->user, _("unknown")); |
1263 } | 1129 } |
1264 startpos = goto_next_token (startpos); | 1130 startpos = goto_next_token (startpos); |
1265 } | 1131 } |
1266 | 1132 |
1267 /* FIXME - make this GFTP_TYPE_CRAY */ | 1133 /* FIXME - make this GFTP_DIRTYPE_CRAY */ |
1268 if (request->server_type != GFTP_TYPE_UNIX) | 1134 if (request->server_type != GFTP_DIRTYPE_UNIX) |
1269 { | 1135 { |
1270 /* See if this is a Cray directory listing. It has the following format: | 1136 /* See if this is a Cray directory listing. It has the following format: |
1271 drwx------ 2 feiliu g913 DK common 4096 Sep 24 2001 wv */ | 1137 drwx------ 2 feiliu g913 DK common 4096 Sep 24 2001 wv */ |
1272 if (cols == 11 && strstr (str, "->") == NULL) | 1138 if (cols == 11 && strstr (str, "->") == NULL) |
1273 { | 1139 { |
1417 if (len > 0 && str[len - 1] == '\r') | 1283 if (len > 0 && str[len - 1] == '\r') |
1418 str[--len] = '\0'; | 1284 str[--len] = '\0'; |
1419 | 1285 |
1420 switch (request->server_type) | 1286 switch (request->server_type) |
1421 { | 1287 { |
1422 case GFTP_TYPE_UNIX: | 1288 case GFTP_DIRTYPE_CRAY: |
1423 result = gftp_parse_ls_unix (request, str, fle); | 1289 case GFTP_DIRTYPE_UNIX: |
1290 result = gftp_parse_ls_unix (request, str, fle); | |
1424 break; | 1291 break; |
1425 case GFTP_TYPE_EPLF: | 1292 case GFTP_DIRTYPE_EPLF: |
1426 result = gftp_parse_ls_eplf (str, fle); | 1293 result = gftp_parse_ls_eplf (str, fle); |
1427 break; | 1294 break; |
1428 case GFTP_TYPE_NOVELL: | 1295 case GFTP_DIRTYPE_NOVELL: |
1429 result = gftp_parse_ls_novell (str, fle); | 1296 result = gftp_parse_ls_novell (str, fle); |
1430 break; | 1297 break; |
1431 case GFTP_TYPE_DOS: | 1298 case GFTP_DIRTYPE_DOS: |
1432 result = gftp_parse_ls_nt (str, fle); | 1299 result = gftp_parse_ls_nt (str, fle); |
1433 break; | 1300 break; |
1434 case GFTP_TYPE_VMS: | 1301 case GFTP_DIRTYPE_VMS: |
1435 result = gftp_parse_ls_vms (str, fle); | 1302 result = gftp_parse_ls_vms (str, fle); |
1436 break; | 1303 break; |
1437 default: /* autodetect */ | 1304 default: /* autodetect */ |
1438 if (*lsoutput == '+') | 1305 if (*lsoutput == '+') |
1439 result = gftp_parse_ls_eplf (str, fle); | 1306 result = gftp_parse_ls_eplf (str, fle); |
1671 transfer->fromreq->directory = oldfromdir; | 1538 transfer->fromreq->directory = oldfromdir; |
1672 if (transfer->toreq) | 1539 if (transfer->toreq) |
1673 transfer->toreq->directory = oldtodir; | 1540 transfer->toreq->directory = oldtodir; |
1674 } | 1541 } |
1675 else | 1542 else |
1676 { | 1543 transfer->numfiles++; |
1677 curfle->ascii = gftp_get_file_transfer_mode (curfle->file, | |
1678 transfer->fromreq->data_type) == GFTP_TYPE_ASCII; | |
1679 transfer->numfiles++; | |
1680 } | |
1681 } | 1544 } |
1682 | 1545 |
1683 if (forcecd) | 1546 if (forcecd) |
1684 gftp_set_directory (transfer->fromreq, transfer->fromreq->directory); | 1547 gftp_set_directory (transfer->fromreq, transfer->fromreq->directory); |
1685 if (remotechanged && transfer->toreq) | 1548 if (remotechanged && transfer->toreq) |
1692 } | 1555 } |
1693 return (0); | 1556 return (0); |
1694 } | 1557 } |
1695 | 1558 |
1696 | 1559 |
1697 int | |
1698 gftp_get_file_transfer_mode (char *filename, int def) | |
1699 { | |
1700 gftp_file_extensions * tempext; | |
1701 GList * templist; | |
1702 int stlen, ret; | |
1703 | |
1704 ret = def; | |
1705 stlen = strlen (filename); | |
1706 for (templist = registered_exts; templist != NULL; templist = templist->next) | |
1707 { | |
1708 tempext = templist->data; | |
1709 | |
1710 if (stlen >= tempext->stlen && | |
1711 strcmp (&filename[stlen - tempext->stlen], tempext->ext) == 0) | |
1712 { | |
1713 if (toupper (*tempext->ascii_binary == 'A')) | |
1714 ret = GFTP_TYPE_ASCII; | |
1715 else if (toupper (*tempext->ascii_binary == 'B')) | |
1716 ret = GFTP_TYPE_BINARY; | |
1717 break; | |
1718 } | |
1719 } | |
1720 | |
1721 return (ret); | |
1722 } | |
1723 | |
1724 | |
1725 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) | 1560 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) |
1726 int | 1561 static int |
1727 get_port (struct addrinfo *addr) | 1562 get_port (struct addrinfo *addr) |
1728 { | 1563 { |
1729 struct sockaddr_in * saddr; | 1564 struct sockaddr_in * saddr; |
1730 int port; | 1565 int port; |
1731 | 1566 |
1741 } | 1576 } |
1742 #endif | 1577 #endif |
1743 | 1578 |
1744 | 1579 |
1745 int | 1580 int |
1746 gftp_connect_server (gftp_request * request, char *service) | 1581 gftp_connect_server (gftp_request * request, char *service, |
1582 char *proxy_hostname, int proxy_port) | |
1747 { | 1583 { |
1748 char *connect_host, *disphost; | 1584 char *connect_host, *disphost; |
1749 int port, sock; | 1585 int port, sock; |
1750 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) | 1586 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) |
1751 struct addrinfo hints, *res; | 1587 struct addrinfo hints, *res; |
1752 char serv[8]; | 1588 char serv[8]; |
1753 int errnum; | 1589 int errnum; |
1754 | 1590 |
1755 if ((request->use_proxy = gftp_need_proxy (request, service)) < 0) | 1591 if ((request->use_proxy = gftp_need_proxy (request, service, |
1592 proxy_hostname, proxy_port)) < 0) | |
1756 return (request->use_proxy); | 1593 return (request->use_proxy); |
1757 else if (request->use_proxy == 1) | 1594 else if (request->use_proxy == 1) |
1758 request->hostp = NULL; | 1595 request->hostp = NULL; |
1759 | 1596 |
1760 memset (&hints, 0, sizeof (hints)); | 1597 memset (&hints, 0, sizeof (hints)); |
1761 hints.ai_flags = AI_CANONNAME; | 1598 hints.ai_flags = AI_CANONNAME; |
1762 hints.ai_family = AF_INET; | 1599 hints.ai_family = AF_INET; |
1763 hints.ai_socktype = SOCK_STREAM; | 1600 hints.ai_socktype = SOCK_STREAM; |
1764 | 1601 |
1765 connect_host = request->use_proxy ? request->proxy_hostname : | 1602 if (request->use_proxy) |
1766 request->hostname; | 1603 { |
1767 port = request->use_proxy ? request->proxy_port : request->port; | 1604 connect_host = proxy_hostname; |
1605 port = proxy_port; | |
1606 } | |
1607 else | |
1608 { | |
1609 connect_host = request->hostname; | |
1610 port = request->port; | |
1611 } | |
1768 | 1612 |
1769 if (request->hostp == NULL) | 1613 if (request->hostp == NULL) |
1770 { | 1614 { |
1771 if (port == 0) | 1615 if (port == 0) |
1772 strcpy (serv, service); | 1616 strcpy (serv, service); |
1829 #else /* !HAVE_GETADDRINFO */ | 1673 #else /* !HAVE_GETADDRINFO */ |
1830 struct sockaddr_in remote_address; | 1674 struct sockaddr_in remote_address; |
1831 struct servent serv_struct; | 1675 struct servent serv_struct; |
1832 int curhost; | 1676 int curhost; |
1833 | 1677 |
1834 if ((request->use_proxy = gftp_need_proxy (request, service)) < 0) | 1678 if ((request->use_proxy = gftp_need_proxy (request, service, |
1679 proxy_hostname, proxy_port)) < 0) | |
1835 return (request->use_proxy); | 1680 return (request->use_proxy); |
1836 else if (request->use_proxy == 1) | 1681 else if (request->use_proxy == 1) |
1837 request->hostp = NULL; | 1682 request->hostp = NULL; |
1838 | 1683 |
1839 if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) | 1684 if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) |
1845 } | 1690 } |
1846 | 1691 |
1847 memset (&remote_address, 0, sizeof (remote_address)); | 1692 memset (&remote_address, 0, sizeof (remote_address)); |
1848 remote_address.sin_family = AF_INET; | 1693 remote_address.sin_family = AF_INET; |
1849 | 1694 |
1850 connect_host = request->use_proxy ? request->proxy_hostname : | 1695 if (request->use_proxy) |
1851 request->hostname; | 1696 { |
1852 port = htons (request->use_proxy ? request->proxy_port : request->port); | 1697 connect_host = proxy_hostname; |
1698 port = proxy_port; | |
1699 } | |
1700 else | |
1701 { | |
1702 connect_host = request->hostname; | |
1703 port = request->port; | |
1704 } | |
1853 | 1705 |
1854 if (port == 0) | 1706 if (port == 0) |
1855 { | 1707 { |
1856 if (!r_getservbyname (service, "tcp", &serv_struct, NULL)) | 1708 if (!r_getservbyname (service, "tcp", &serv_struct, NULL)) |
1857 { | 1709 { |
1858 port = htons (21); | 1710 request->logging_function (gftp_logging_error, request->user_data, |
1859 request->port = 21; | 1711 _("Cannot look up service name %s/tcp. Please check your services file\n"), |
1712 service); | |
1713 close (sock); | |
1714 return (GFTP_EFATAL); | |
1860 } | 1715 } |
1861 else | 1716 else |
1862 { | 1717 { |
1863 port = serv_struct.s_port; | 1718 port = serv_struct.s_port; |
1864 request->port = ntohs (serv_struct.s_port); | 1719 request->port = ntohs (serv_struct.s_port); |
1926 | 1781 |
1927 | 1782 |
1928 void | 1783 void |
1929 gftp_set_config_options (gftp_request * request) | 1784 gftp_set_config_options (gftp_request * request) |
1930 { | 1785 { |
1931 request->network_timeout = network_timeout; | |
1932 request->retries = retries; | |
1933 request->sleep_time = sleep_time; | |
1934 request->maxkbs = maxkbs; | |
1935 | |
1936 if (request->set_config_options != NULL) | 1786 if (request->set_config_options != NULL) |
1937 request->set_config_options (request); | 1787 request->set_config_options (request); |
1938 } | |
1939 | |
1940 | |
1941 void | |
1942 gftp_set_sftpserv_path (gftp_request * request, char *path) | |
1943 { | |
1944 g_return_if_fail (request != NULL); | |
1945 | |
1946 if (request->sftpserv_path) | |
1947 g_free (request->sftpserv_path); | |
1948 | |
1949 if (path != NULL && *path != '\0') | |
1950 { | |
1951 request->sftpserv_path = g_malloc (strlen (path) + 1); | |
1952 strcpy (request->sftpserv_path, path); | |
1953 } | |
1954 else | |
1955 request->sftpserv_path = NULL; | |
1956 } | 1788 } |
1957 | 1789 |
1958 | 1790 |
1959 void | 1791 void |
1960 print_file_list (GList * list) | 1792 print_file_list (GList * list) |
2094 | 1926 |
2095 | 1927 |
2096 ssize_t | 1928 ssize_t |
2097 gftp_read (gftp_request * request, void *ptr, size_t size, int fd) | 1929 gftp_read (gftp_request * request, void *ptr, size_t size, int fd) |
2098 { | 1930 { |
1931 long network_timeout; | |
2099 struct timeval tv; | 1932 struct timeval tv; |
2100 fd_set fset; | 1933 fd_set fset; |
2101 ssize_t ret; | 1934 ssize_t ret; |
2102 | 1935 |
1936 gftp_lookup_request_option (request, "network_timeout", &network_timeout); | |
1937 | |
2103 errno = 0; | 1938 errno = 0; |
2104 ret = 0; | 1939 ret = 0; |
2105 do | 1940 do |
2106 { | 1941 { |
2107 FD_ZERO (&fset); | 1942 FD_ZERO (&fset); |
2108 FD_SET (fd, &fset); | 1943 FD_SET (fd, &fset); |
2109 if (request != NULL) | 1944 tv.tv_sec = network_timeout; |
2110 tv.tv_sec = request->network_timeout; | |
2111 else | |
2112 tv.tv_sec = network_timeout; | |
2113 tv.tv_usec = 0; | 1945 tv.tv_usec = 0; |
2114 ret = select (fd + 1, &fset, NULL, NULL, &tv); | 1946 ret = select (fd + 1, &fset, NULL, NULL, &tv); |
2115 if (ret == -1 && errno == EINTR) | 1947 if (ret == -1 && errno == EINTR) |
2116 { | 1948 { |
2117 if (request && request->cancel) | 1949 if (request && request->cancel) |
2164 | 1996 |
2165 | 1997 |
2166 ssize_t | 1998 ssize_t |
2167 gftp_write (gftp_request * request, const char *ptr, size_t size, int fd) | 1999 gftp_write (gftp_request * request, const char *ptr, size_t size, int fd) |
2168 { | 2000 { |
2001 long network_timeout; | |
2169 struct timeval tv; | 2002 struct timeval tv; |
2170 size_t ret, w_ret; | 2003 size_t ret, w_ret; |
2171 fd_set fset; | 2004 fd_set fset; |
2172 | 2005 |
2006 gftp_lookup_request_option (request, "network_timeout", &network_timeout); | |
2007 | |
2173 errno = 0; | 2008 errno = 0; |
2174 ret = 0; | 2009 ret = 0; |
2175 do | 2010 do |
2176 { | 2011 { |
2177 FD_ZERO (&fset); | 2012 FD_ZERO (&fset); |
2178 FD_SET (fd, &fset); | 2013 FD_SET (fd, &fset); |
2179 if (request != NULL) | 2014 tv.tv_sec = network_timeout; |
2180 tv.tv_sec = request->network_timeout; | |
2181 else | |
2182 tv.tv_sec = network_timeout; | |
2183 tv.tv_usec = 0; | 2015 tv.tv_usec = 0; |
2184 ret = select (fd + 1, NULL, &fset, NULL, &tv); | 2016 ret = select (fd + 1, NULL, &fset, NULL, &tv); |
2185 if (ret == -1 && errno == EINTR) | 2017 if (ret == -1 && errno == EINTR) |
2186 { | 2018 { |
2187 if (request != NULL && request->cancel) | 2019 if (request != NULL && request->cancel) |
2305 | 2137 |
2306 if (dest->swap_socks) | 2138 if (dest->swap_socks) |
2307 dest->swap_socks (dest, source); | 2139 dest->swap_socks (dest, source); |
2308 } | 2140 } |
2309 | 2141 |
2142 | |
2143 void | |
2144 gftp_calc_kbs (gftp_transfer * tdata, ssize_t num_read) | |
2145 { | |
2146 unsigned long waitusecs; | |
2147 double difftime, curkbs; | |
2148 gftp_file * tempfle; | |
2149 unsigned long toadd; | |
2150 struct timeval tv; | |
2151 float maxkbs; | |
2152 | |
2153 gftp_lookup_request_option (tdata->fromreq, "maxkbs", &maxkbs); | |
2154 | |
2155 gettimeofday (&tv, NULL); | |
2156 if (g_thread_supported ()) | |
2157 g_static_mutex_lock (&tdata->statmutex); | |
2158 | |
2159 tempfle = tdata->curfle->data; | |
2160 tdata->trans_bytes += num_read; | |
2161 tdata->curtrans += num_read; | |
2162 tdata->stalled = 0; | |
2163 | |
2164 difftime = (tv.tv_sec - tdata->starttime.tv_sec) + ((double) (tv.tv_usec - tdata->starttime.tv_usec) / 1000000.0); | |
2165 if (difftime <= 0) | |
2166 tdata->kbs = (double) tdata->trans_bytes / 1024.0; | |
2167 else | |
2168 tdata->kbs = (double) tdata->trans_bytes / 1024.0 / difftime; | |
2169 | |
2170 difftime = (tv.tv_sec - tdata->lasttime.tv_sec) + ((double) (tv.tv_usec - tdata->lasttime.tv_usec) / 1000000.0); | |
2171 | |
2172 if (difftime <= 0) | |
2173 curkbs = (double) (num_read / 1024.0); | |
2174 else | |
2175 curkbs = (double) (num_read / 1024.0 / difftime); | |
2176 | |
2177 if (maxkbs > 0 && curkbs > maxkbs) | |
2178 { | |
2179 waitusecs = (double) num_read / 1024.0 / maxkbs * 1000000.0 - difftime; | |
2180 | |
2181 if (waitusecs > 0) | |
2182 { | |
2183 if (g_thread_supported ()) | |
2184 g_static_mutex_unlock (&tdata->statmutex); | |
2185 | |
2186 difftime += ((double) waitusecs / 1000000.0); | |
2187 usleep (waitusecs); | |
2188 | |
2189 if (g_thread_supported ()) | |
2190 g_static_mutex_lock (&tdata->statmutex); | |
2191 } | |
2192 } | |
2193 | |
2194 /* I don't call gettimeofday (&tdata->lasttime) here because this will use | |
2195 less system resources. This will be close enough for what we need */ | |
2196 difftime += tdata->lasttime.tv_usec / 1000000.0; | |
2197 toadd = (long) difftime; | |
2198 difftime -= toadd; | |
2199 tdata->lasttime.tv_sec += toadd; | |
2200 tdata->lasttime.tv_usec = difftime * 1000000.0; | |
2201 | |
2202 if (g_thread_supported ()) | |
2203 g_static_mutex_unlock (&tdata->statmutex); | |
2204 } | |
2205 |