# HG changeset patch # User masneyb # Date 1067825645 0 # Node ID 3b9d5797050feff5c86e4823766e4efaee6f4aaa # Parent 14c0f5c3893c67ef913b710d73f563d46558dcf5 2003-11-2 Brian Masney * lib/rfc2068.c (rfc2068_chunked_read) - more improvements to this function so that it will parse more chunked file transfers correctly. * lib/misc.c lib/gftp.h lib/rfc2068.c src/gtk/bookmarks.c src/gtk/dnd.c - removed remove_double_slashes(). Call gftp_build_path() to build the paths. This now allows Novell directory listings with //server * lib/protocols.c src/gtk/transfer.c lib/gftp.h - added variable conn_error_no_timeout to gftp_transfer structure. If this is enabled, if the remote connection to the server timed out, don't wait and immediately reconnect. So far, the only time this is used is when the user was editing a file and it is to be uploaded back to the server. * src/gtk/gftp-gtk.h src/gtk/transfer.c - add_file_transfer() now returns the struct gftp_transfer that was just added. * src/gtk/misc-gtk.c (update_directory_download_progress) - don't make the window a popup and remove the window decorations * src/text/gftp-text.c - don't populate the transfer_direction variable in struct gftp_transfer. This is only needed by the GTK+ port and will hopefully be taken out soon. * lib/gftp.h - remove gftp_transfer_type enum. It wasn't used anymore. diff -r 14c0f5c3893c -r 3b9d5797050f ChangeLog --- a/ChangeLog Thu Oct 30 22:26:40 2003 +0000 +++ b/ChangeLog Mon Nov 03 02:14:05 2003 +0000 @@ -1,3 +1,30 @@ +2003-11-2 Brian Masney + * lib/rfc2068.c (rfc2068_chunked_read) - more improvements to this + function so that it will parse more chunked file transfers correctly. + + * lib/misc.c lib/gftp.h lib/rfc2068.c src/gtk/bookmarks.c + src/gtk/dnd.c - removed remove_double_slashes(). Call gftp_build_path() + to build the paths. This now allows Novell directory listings with + //server + + * lib/protocols.c src/gtk/transfer.c lib/gftp.h - added variable + conn_error_no_timeout to gftp_transfer structure. If this is enabled, + if the remote connection to the server timed out, don't wait and + immediately reconnect. So far, the only time this is used is when the + user was editing a file and it is to be uploaded back to the server. + + * src/gtk/gftp-gtk.h src/gtk/transfer.c - add_file_transfer() now + returns the struct gftp_transfer that was just added. + + * src/gtk/misc-gtk.c (update_directory_download_progress) - don't + make the window a popup and remove the window decorations + + * src/text/gftp-text.c - don't populate the transfer_direction variable + in struct gftp_transfer. This is only needed by the GTK+ port and will + hopefully be taken out soon. + + * lib/gftp.h - remove gftp_transfer_type enum. It wasn't used anymore. + 2003-10-27 Brian Masney * lib/rfc959.c (gftp_get_next_file_chunk) - fixed ASCII file corruption bug. @@ -1645,7 +1672,7 @@ * cvsclean - added this script - * *.[ch] - added $Id: ChangeLog,v 1.163 2003/10/27 23:21:50 masneyb Exp $ tags + * *.[ch] - added $Id: ChangeLog,v 1.164 2003/11/03 02:11:16 masneyb Exp $ tags * debian/* - updated files from Debian maintainer diff -r 14c0f5c3893c -r 3b9d5797050f lib/gftp.h --- a/lib/gftp.h Thu Oct 30 22:26:40 2003 +0000 +++ b/lib/gftp.h Mon Nov 03 02:14:05 2003 +0000 @@ -149,13 +149,6 @@ #define LOG_FILE BASE_CONF_DIR "/gftp.log" #define MAX_HIST_LEN 10 -typedef enum gftp_transfer_type_tag -{ - gftp_transfer_passive, - gftp_transfer_active -} gftp_transfer_type; - - typedef enum gftp_logging_level_tag { gftp_logging_send, @@ -216,7 +209,7 @@ typedef struct gftp_proxy_hosts_tag { - /* FIXME - add IPV4 stuff here */ + /* FIXME - add IPV6 stuff here */ gint32 ipv4_network_address, ipv4_netmask; @@ -452,6 +445,7 @@ done : 1, show : 1, stalled : 1, + conn_error_no_timeout : 1, next_file : 1, skip_file : 1; @@ -662,8 +656,6 @@ char *expand_path ( const char *src ); -void remove_double_slashes ( char *string ); - void make_nonnull ( char **str ); int copyfile ( char *source, diff -r 14c0f5c3893c -r 3b9d5797050f lib/httpcommon.h --- a/lib/httpcommon.h Thu Oct 30 22:26:40 2003 +0000 +++ b/lib/httpcommon.h Mon Nov 03 02:14:05 2003 +0000 @@ -31,6 +31,7 @@ void *ptr, size_t size, int fd ); + int read_ref_cnt; char * extra_read_buffer; size_t extra_read_buffer_len; diff -r 14c0f5c3893c -r 3b9d5797050f lib/misc.c --- a/lib/misc.c Thu Oct 30 22:26:40 2003 +0000 +++ b/lib/misc.c Mon Nov 03 02:14:05 2003 +0000 @@ -246,29 +246,6 @@ void -remove_double_slashes (char *string) -{ - char *newpos, *oldpos; - size_t len; - - oldpos = newpos = string; - while (*oldpos != '\0') - { - *newpos++ = *oldpos++; - if (*oldpos == '\0') - break; - while (*(newpos - 1) == '/' && *(oldpos) == '/') - oldpos++; - } - *newpos = '\0'; - - len = strlen (string); - if (string[len - 1] == '/') - string[len - 1] = '\0'; -} - - -void make_nonnull (char **str) { if (*str == NULL) diff -r 14c0f5c3893c -r 3b9d5797050f lib/protocols.c --- a/lib/protocols.c Thu Oct 30 22:26:40 2003 +0000 +++ b/lib/protocols.c Mon Nov 03 02:14:05 2003 +0000 @@ -2503,33 +2503,38 @@ { if (num_read == GFTP_EFATAL) return (GFTP_EFATAL); - else if (retries != 0 && - tdata->current_file_retries >= retries) + else if (!tdata->conn_error_no_timeout) { - tdata->fromreq->logging_function (gftp_logging_error, tdata->fromreq, - _("Error: Remote site %s disconnected. Max retries reached...giving up\n"), - tdata->fromreq->hostname != NULL ? - tdata->fromreq->hostname : tdata->toreq->hostname); - return (GFTP_EFATAL); - } - else - { - tdata->fromreq->logging_function (gftp_logging_error, tdata->fromreq, - _("Error: Remote site %s disconnected. Will reconnect in %d seconds\n"), - tdata->fromreq->hostname != NULL ? - tdata->fromreq->hostname : tdata->toreq->hostname, - sleep_time); + if (retries != 0 && + tdata->current_file_retries >= retries) + { + tdata->fromreq->logging_function (gftp_logging_error, tdata->fromreq, + _("Error: Remote site %s disconnected. Max retries reached...giving up\n"), + tdata->fromreq->hostname != NULL ? + tdata->fromreq->hostname : tdata->toreq->hostname); + return (GFTP_EFATAL); + } + else + { + tdata->fromreq->logging_function (gftp_logging_error, tdata->fromreq, + _("Error: Remote site %s disconnected. Will reconnect in %d seconds\n"), + tdata->fromreq->hostname != NULL ? + tdata->fromreq->hostname : tdata->toreq->hostname, + sleep_time); + } } while (retries == 0 || tdata->current_file_retries <= retries) { - if (!tdata->skip_file) + if (!tdata->conn_error_no_timeout && !tdata->skip_file) { tv.tv_sec = sleep_time; tv.tv_usec = 0; select (0, NULL, NULL, NULL, &tv); } + else + tdata->conn_error_no_timeout = 0; if ((ret1 = gftp_connect (tdata->fromreq)) == 0 && (ret2 = gftp_connect (tdata->toreq)) == 0) diff -r 14c0f5c3893c -r 3b9d5797050f lib/rfc2068.c --- a/lib/rfc2068.c Thu Oct 30 22:26:40 2003 +0000 +++ b/lib/rfc2068.c Mon Nov 03 02:14:05 2003 +0000 @@ -272,7 +272,7 @@ rfc2068_get_file (gftp_request * request, const char *filename, int fd, off_t startsize) { - char *tempstr, *oldstr, *pos; + char *tempstr, *oldstr, *hf; int restarted, use_http11; rfc2068_params * params; off_t size; @@ -288,19 +288,17 @@ if (fd > 0) request->datafd = fd; + hf = gftp_build_path (request->hostname, filename, NULL); + if (request->username == NULL || *request->username == '\0') - tempstr = g_strconcat ("GET ", request->url_prefix, "://", - request->hostname, "/", filename, + tempstr = g_strconcat ("GET ", request->url_prefix, "://", hf, use_http11 ? " HTTP/1.1\n" : " HTTP/1.0\n", NULL); else tempstr = g_strconcat ("GET ", request->url_prefix, "://", - request->username, "@", request->hostname, "/", filename, + request->username, "@", hf, use_http11 ? " HTTP/1.1\n" : " HTTP/1.0\n", NULL); - if ((pos = strstr (tempstr, "://")) != NULL) - remove_double_slashes (pos + 3); - else - remove_double_slashes (tempstr); + g_free (hf); if (use_http11 && startsize > 0) { @@ -391,7 +389,7 @@ rfc2068_list_files (gftp_request * request) { rfc2068_params *params; - char *tempstr, *pos; + char *tempstr, *hd; int use_http11; off_t ret; @@ -401,20 +399,17 @@ params = request->protocol_data; gftp_lookup_request_option (request, "use_http11", &use_http11); + hd = gftp_build_path (request->hostname, request->directory, NULL); + if (request->username == NULL || *request->username == '\0') - tempstr = g_strconcat ("GET ", request->url_prefix, "://", - request->hostname, "/", request->directory, + tempstr = g_strconcat ("GET ", request->url_prefix, "://", hd, use_http11 ? "/ HTTP/1.1\n" : "/ HTTP/1.0\n", NULL); else tempstr = g_strconcat ("GET ", request->url_prefix, "://", - request->username, "@", request->hostname, "/", - request->directory, + request->username, "@", hd, use_http11 ? "/ HTTP/1.1\n" : "/ HTTP/1.0\n", NULL); - if ((pos = strstr (tempstr, "://")) != NULL) - remove_double_slashes (pos + 3); - else - remove_double_slashes (tempstr); + g_free (hd); ret = rfc2068_send_command (request, tempstr, strlen (tempstr)); g_free (tempstr); @@ -440,7 +435,7 @@ rfc2068_get_file_size (gftp_request * request, const char *filename) { rfc2068_params *params; - char *tempstr, *pos; + char *tempstr, *hf; int use_http11; off_t size; @@ -451,20 +446,17 @@ params = request->protocol_data; gftp_lookup_request_option (request, "use_http11", &use_http11); + hf = gftp_build_path (request->hostname, filename, NULL); + if (request->username == NULL || *request->username == '\0') - tempstr = g_strconcat ("HEAD ", request->url_prefix, "://", - request->hostname, "/", filename, + tempstr = g_strconcat ("HEAD ", request->url_prefix, "://", hf, use_http11 ? " HTTP/1.1\n" : " HTTP/1.0\n", NULL); else tempstr = g_strconcat ("HEAD ", request->url_prefix, "://", - request->username, "@", request->hostname, "/", - filename, + request->username, "@", hf, use_http11 ? " HTTP/1.1\n" : " HTTP/1.0\n", NULL); - if ((pos = strstr (tempstr, "://")) != NULL) - remove_double_slashes (pos + 3); - else - remove_double_slashes (tempstr); + g_free (hf); size = rfc2068_send_command (request, tempstr, strlen (tempstr)); g_free (tempstr); @@ -716,13 +708,14 @@ static ssize_t rfc2068_chunked_read (gftp_request * request, void *ptr, size_t size, int fd) { - size_t read_size, begin_ptr_len, current_size; + size_t read_size, begin_ptr_len, current_size, crlfsize; + rfc2068_params * params; char *stpos, *crlfpos; - rfc2068_params * params; void *read_ptr_pos; ssize_t retval; params = request->protocol_data; + params->read_ref_cnt++; if (params->extra_read_buffer != NULL) { @@ -752,7 +745,10 @@ if (params->content_length > 0) { if (params->content_length == params->read_bytes) - return (0); + { + params->read_ref_cnt--; + return (0); + } if (read_size + params->read_bytes > params->content_length) read_size = params->content_length - params->read_bytes; @@ -768,16 +764,21 @@ read_size--; /* decrement by one so that we can put the NUL character in the buffer */ - retval = params->real_read_function (request, read_ptr_pos, read_size, fd); + retval = params->real_read_function (request, read_ptr_pos, read_size, + fd); - if (retval > 0) + if (retval <= 0) + { + params->read_ref_cnt--; + return (retval); + } + else if (retval > 0) params->read_bytes += retval; - else if (retval == 0) - return (retval); - if (params->chunk_size > 0 && retval > 0) + if (params->chunk_size > 0) { params->chunk_size -= retval; + params->read_ref_cnt--; return (retval); } @@ -788,14 +789,25 @@ ((char *) ptr)[retval] = '\0'; - if (!params->chunked_transfer || retval <= 0) - return (retval); + if (!params->chunked_transfer) + { + params->read_ref_cnt--; + return (retval); + } stpos = (char *) ptr; while (params->chunk_size == 0) { current_size = retval - (stpos - (char *) ptr); - if (current_size < 5) + if (current_size == 0) + break; + + if (*stpos == '\r' && *(stpos + 1) == '\n') + crlfpos = strstr (stpos + 2, "\r\n"); + else + crlfpos = NULL; + + if (crlfpos == NULL) { /* The current chunk size is split between multiple packets. Save this chunk and read the next */ @@ -807,25 +819,23 @@ retval -= current_size; if (retval == 0) - return (rfc2068_chunked_read (request, ptr, size, fd)); - else - return (retval); - } + { + /* Don't let a hostile web server send us in an infinite recursive + loop */ - if (*stpos != '\r' || *(stpos + 1) != '\n') - { - request->logging_function (gftp_logging_recv, request, - _("Received wrong response from server, disconnecting\nExpecting a carriage return and line feed before the chunk size in the server response\n")); - gftp_disconnect (request); - return (GFTP_EFATAL); - } + if (params->read_ref_cnt > 2) + { + request->logging_function (gftp_logging_error, request, _("Received wrong response from server, disconnecting\n")); + gftp_disconnect (request); + params->read_ref_cnt--; + return (GFTP_EFATAL); + } - if ((crlfpos = strstr (stpos + 2, "\r\n")) == NULL) - { - request->logging_function (gftp_logging_recv, request, - _("Received wrong response from server, disconnecting\nExpecting a carriage return and line feed after the chunk size in the server response\n")); - gftp_disconnect (request); - return (GFTP_EFATAL); + retval = rfc2068_chunked_read (request, ptr, size, fd); + } + + params->read_ref_cnt--; + return (retval); } *crlfpos = '\0'; @@ -837,31 +847,39 @@ _("Received wrong response from server, disconnecting\nInvalid chunk size '%s' returned by the remote server\n"), stpos + 2); gftp_disconnect (request); + params->read_ref_cnt--; return (GFTP_EFATAL); } - retval -= crlfpos - (char *) stpos + 1; - current_size -= crlfpos - (char *) stpos + 1; + crlfsize = crlfpos - (char *) stpos + 1; + retval -= crlfsize; + current_size -= crlfsize; if (params->chunk_size == 0) { if (params->eof) - return (0); + { + params->read_ref_cnt--; + return (0); + } params->eof = 1; + params->read_ref_cnt--; return (retval); } - memmove (stpos, crlfpos + 1, current_size); + memmove (stpos, crlfpos + 1, current_size + 1); - params->chunk_size -= retval; - if (params->chunk_size < 0) + if (params->chunk_size < current_size) { - stpos += retval + params->chunk_size; /* chunk size is negative */ + stpos += params->chunk_size; params->chunk_size = 0; } + else + params->chunk_size -= current_size; } + params->read_ref_cnt--; return (retval); } diff -r 14c0f5c3893c -r 3b9d5797050f src/gtk/bookmarks.c --- a/src/gtk/bookmarks.c Thu Oct 30 22:26:40 2003 +0000 +++ b/src/gtk/bookmarks.c Mon Nov 03 02:14:05 2003 +0000 @@ -692,9 +692,9 @@ tempchar = *pos; *pos = '\0'; } - origpath = newpath = g_strconcat (entry->path, "/", - gtk_entry_get_text (GTK_ENTRY (bm_pathedit)), NULL); - remove_double_slashes (newpath); + + origpath = newpath = gftp_build_path (entry->path, gtk_entry_get_text (GTK_ENTRY (bm_pathedit)), NULL); + for (; *newpath == '/'; newpath++); *pos = tempchar; @@ -757,9 +757,7 @@ while (tempentry != NULL) { g_hash_table_remove (new_bookmarks_htable, tempentry->path); - tempstr = g_strconcat (newpath, "/", tempentry->path + oldpathlen, - NULL); - remove_double_slashes (tempstr); + tempstr = gftp_build_path (newpath, tempentry->path + oldpathlen, NULL); g_free (tempentry->path); tempentry->path = tempstr; g_hash_table_insert (new_bookmarks_htable, tempentry->path, diff -r 14c0f5c3893c -r 3b9d5797050f src/gtk/dnd.c --- a/src/gtk/dnd.c Thu Oct 30 22:26:40 2003 +0000 +++ b/src/gtk/dnd.c Mon Nov 03 02:14:05 2003 +0000 @@ -118,7 +118,7 @@ gpointer data) { GList * templist, * filelist; - char *tempstr, *str, *pos; + char *tempstr, *str, *df; gftp_window_data * wdata; size_t totlen, oldlen; gftp_file * tempfle; @@ -142,40 +142,32 @@ continue; oldlen = totlen; + df = gftp_build_path (wdata->request->directory, tempfle->file, NULL); + if (wdata->request->hostname == NULL || wdata->request->protonum == GFTP_LOCAL_NUM) { - tempstr = g_strdup_printf ("%s://%s/%s ", - wdata->request->url_prefix, - wdata->request->directory, - tempfle->file); + tempstr = g_strdup_printf ("%s://%s ", + wdata->request->url_prefix, df); } - else if (wdata->request->username == NULL - || *wdata->request->username == '\0') + else if (wdata->request->username == NULL || + *wdata->request->username == '\0') { - tempstr = g_strdup_printf ("%s://%s:%d%s/%s ", + tempstr = g_strdup_printf ("%s://%s:%d%s ", wdata->request->url_prefix, wdata->request->hostname, - wdata->request->port, - wdata->request->directory, - tempfle->file); + wdata->request->port, df); } else { - tempstr = g_strdup_printf ("%s://%s@%s:%d%s/%s ", + tempstr = g_strdup_printf ("%s://%s@%s:%d%s ", wdata->request->url_prefix, wdata->request->username, wdata->request->hostname, - wdata->request->port, - wdata->request->directory, - tempfle->file); + wdata->request->port, df); } - if ((pos = strchr (tempstr, ':')) != NULL) - pos += 3; - else - pos = tempstr; - remove_double_slashes (pos); + g_free (df); /* Note, I am allocating memory for this byte above. Note the extra space at the end of the g_strdup_printf() format argument */ diff -r 14c0f5c3893c -r 3b9d5797050f src/gtk/gftp-gtk.h --- a/src/gtk/gftp-gtk.h Thu Oct 30 22:26:40 2003 +0000 +++ b/src/gtk/gftp-gtk.h Mon Nov 03 02:14:05 2003 +0000 @@ -407,7 +407,7 @@ void *do_getdir_thread ( void * data ); -void add_file_transfer ( gftp_request * fromreq, +gftp_transfer * add_file_transfer ( gftp_request * fromreq, gftp_request * toreq, gftp_window_data * fromwdata, gftp_window_data * towdata, diff -r 14c0f5c3893c -r 3b9d5797050f src/gtk/misc-gtk.c --- a/src/gtk/misc-gtk.c Thu Oct 30 22:26:40 2003 +0000 +++ b/src/gtk/misc-gtk.c Mon Nov 03 02:14:05 2003 +0000 @@ -1119,7 +1119,10 @@ if (dialog == NULL) { - dialog = gtk_window_new (GTK_WINDOW_POPUP); + dialog = gtk_window_new (GTK_WINDOW_TOPLEVEL); +#if GTK_MAJOR_VERSION > 1 + gtk_window_set_decorated (GTK_WINDOW (dialog), 0); +#endif gtk_grab_add (dialog); gtk_signal_connect (GTK_OBJECT (dialog), "delete_event", GTK_SIGNAL_FUNC (delete_event), NULL); diff -r 14c0f5c3893c -r 3b9d5797050f src/gtk/transfer.c --- a/src/gtk/transfer.c Thu Oct 30 22:26:40 2003 +0000 +++ b/src/gtk/transfer.c Mon Nov 03 02:14:05 2003 +0000 @@ -772,7 +772,7 @@ } -void +gftp_transfer * add_file_transfer (gftp_request * fromreq, gftp_request * toreq, gftp_window_data * fromwdata, gftp_window_data * towdata, GList * files, int copy_req) @@ -795,6 +795,7 @@ gftp_lookup_request_option (fromreq, "append_transfers", &append_transfers); + tdata = NULL; if (append_transfers) { pthread_mutex_lock (&transfer_mutex); @@ -905,6 +906,8 @@ if (dialog) gftp_gtk_ask_transfer (tdata); } + + return (tdata); } @@ -950,6 +953,7 @@ static void do_upload (gftp_viewedit_data * ve_proc, gftp_dialog_data * ddata) { + gftp_transfer * tdata; gftp_file * tempfle; GList * newfile; @@ -961,9 +965,12 @@ ve_proc->filename = NULL; tempfle->done_rm = 1; newfile = g_list_append (NULL, tempfle); - add_file_transfer (ve_proc->fromwdata->request, ve_proc->torequest, - ve_proc->fromwdata, ve_proc->towdata, newfile, 1); + tdata = add_file_transfer (ve_proc->fromwdata->request, ve_proc->torequest, + ve_proc->fromwdata, ve_proc->towdata, newfile, 1); free_edit_data (ve_proc); + + if (tdata != NULL) + tdata->conn_error_no_timeout = 1; } diff -r 14c0f5c3893c -r 3b9d5797050f src/text/gftp-text.c --- a/src/text/gftp-text.c Thu Oct 30 22:26:40 2003 +0000 +++ b/src/text/gftp-text.c Mon Nov 03 02:14:05 2003 +0000 @@ -746,7 +746,6 @@ transfer = gftp_tdata_new (); transfer->fromreq = gftp_text_remreq; transfer->toreq = gftp_text_locreq; - transfer->transfer_direction = GFTP_DIRECTION_DOWNLOAD; /* FIXME - ask whether to resume/skip/overwrite */ if (gftp_list_files (transfer->fromreq) != 0) @@ -820,7 +819,6 @@ transfer = gftp_tdata_new (); transfer->fromreq = gftp_text_locreq; transfer->toreq = gftp_text_remreq; - transfer->transfer_direction = GFTP_DIRECTION_UPLOAD; if (gftp_list_files (transfer->fromreq) != 0) {