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