Mercurial > gftp.yaz
diff src/gtk/transfer.c @ 48:e5f6054590b5
2002-11-5 Brian Masney <masneyb@gftp.org>
* lib/*.c src/gtk/*.c - removed function declarations for the static
functions from the top of the file. I had to rearrange the order of a
bunch of functions to avoid compiler warnings
* lib/gftp.h - include sys/sysmacros.h. If major() and minor() isn't
defined, give a compiler warning and define our own
* lib/local.c (local_get_next_file) - if this file is a device, store
the major/minor number in the file size
* src/gtk/misc-gtk.c (add_file_listbox) - if this file is a device,
use the major() and minor() macros to display the major and minor number
author | masneyb |
---|---|
date | Wed, 06 Nov 2002 02:20:25 +0000 |
parents | 311e29c40ed6 |
children | 0fec02fb9e54 |
line wrap: on
line diff
--- a/src/gtk/transfer.c Tue Nov 05 20:36:11 2002 +0000 +++ b/src/gtk/transfer.c Wed Nov 06 02:20:25 2002 +0000 @@ -20,104 +20,53 @@ #include <gftp-gtk.h> static const char cvsid[] = "$Id$"; -static void *getdir_thread ( void *data ); -static void *connect_thread ( void *data ); -static void on_next_transfer ( gftp_transfer * tdata ); -static void show_transfer ( gftp_transfer * tdata ); -static void transfer_done ( GList * node ); -static void create_transfer ( gftp_transfer * tdata ); -static void update_file_status ( gftp_transfer * tdata ); -static void trans_selectall ( GtkWidget * widget, - gpointer data ); -static void trans_unselectall ( GtkWidget * widget, - gpointer data ); -static void overwrite ( GtkWidget * widget, - gpointer data ); -static void resume ( GtkWidget * widget, - gpointer data ); -static void skip ( GtkWidget * widget, - gpointer data ); -static void ok ( GtkWidget * widget, - gpointer data ); -static void cancel ( GtkWidget * widget, - gpointer data ); -static void gftp_gtk_calc_kbs ( gftp_transfer * tdata, - ssize_t num_read ); -static void check_done_process ( void ); -static void do_upload ( gftp_viewedit_data * ve_proc, - gftp_dialog_data * ddata ); -static void dont_upload ( gftp_viewedit_data * ve_proc, - gftp_dialog_data * ddata ); -static void free_edit_data ( gftp_viewedit_data *ve_proc ); -static int get_status ( gftp_transfer * tdata, - ssize_t num_read ); -static void wakeup_main_thread ( gpointer data, - gint source, - GdkInputCondition condition ); -static gint setup_wakeup_main_thread ( gftp_request * request ); -static void teardown_wakeup_main_thread ( gftp_request * request, - gint handler ); -static mode_t parse_attribs ( char *attribs ); -static void remove_file ( char *filename ); - static GtkWidget * dialog; -int -ftp_list_files (gftp_window_data * wdata, int usecache) +static void +wakeup_main_thread (gpointer data, gint source, GdkInputCondition condition) { - guint handler; - void *success; - - gtk_label_set (GTK_LABEL (wdata->hoststxt), _("Receiving file names...")); - if (gftp_is_started) - fix_display (); + gftp_request * request; + char c; + + request = data; + if (request->wakeup_main_thread[0] > 0) + read (request->wakeup_main_thread[0], &c, 1); +} - wdata->show_selected = 0; - if (wdata->files == NULL) - { - if (check_reconnect (wdata) < 0) - return (0); - gtk_clist_freeze (GTK_CLIST (wdata->listbox)); - wdata->request->stopable = 1; - if (wdata->request->use_threads) - { - gtk_widget_set_sensitive (stop_btn, 1); +static gint +setup_wakeup_main_thread (gftp_request * request) +{ + gint handler; - handler = setup_wakeup_main_thread (wdata->request); - pthread_create (&wdata->tid, NULL, getdir_thread, wdata->request); - while (wdata->request->stopable) - { - GDK_THREADS_LEAVE (); -#if GTK_MAJOR_VERSION == 1 - g_main_iteration (TRUE); -#else - g_main_context_iteration (NULL, TRUE); -#endif - } - teardown_wakeup_main_thread (wdata->request, handler); + if (socketpair (AF_UNIX, SOCK_STREAM, 0, request->wakeup_main_thread) == 0) + { + /* FIXME - depreciated in GDK 2.0 */ + handler = gdk_input_add (request->wakeup_main_thread[0], + GDK_INPUT_READ, wakeup_main_thread, request); + } + else + { + request->wakeup_main_thread[0] = 0; + request->wakeup_main_thread[1] = 0; + handler = 0; + } + return (handler); +} - pthread_join (wdata->tid, &success); - gtk_widget_set_sensitive (stop_btn, 0); - } - else - success = getdir_thread (wdata->request); - wdata->files = success; - gtk_clist_thaw (GTK_CLIST (wdata->listbox)); - memset (&wdata->tid, 0, sizeof (wdata->tid)); + +static void +teardown_wakeup_main_thread (gftp_request * request, gint handler) +{ + if (request->wakeup_main_thread[0] > 0 && request->wakeup_main_thread[1] > 0) + { + /* FIXME - depreciated in GDK 2.0 */ + gdk_input_remove (handler); + close (request->wakeup_main_thread[0]); + close (request->wakeup_main_thread[1]); + request->wakeup_main_thread[0] = 0; + request->wakeup_main_thread[1] = 0; } - - if (wdata->files == NULL || !GFTP_IS_CONNECTED (wdata->request)) - { - disconnect (wdata); - return (0); - } - - wdata->sorted = 0; - sortrows (GTK_CLIST (wdata->listbox), *wdata->sortcol, (gpointer) wdata); - if (IS_NONE_SELECTED (wdata)) - gtk_clist_select_row (GTK_CLIST (wdata->listbox), 0, 0); - return (1); } @@ -214,6 +163,65 @@ } +int +ftp_list_files (gftp_window_data * wdata, int usecache) +{ + guint handler; + void *success; + + gtk_label_set (GTK_LABEL (wdata->hoststxt), _("Receiving file names...")); + if (gftp_is_started) + fix_display (); + + wdata->show_selected = 0; + if (wdata->files == NULL) + { + if (check_reconnect (wdata) < 0) + return (0); + + gtk_clist_freeze (GTK_CLIST (wdata->listbox)); + wdata->request->stopable = 1; + if (wdata->request->use_threads) + { + gtk_widget_set_sensitive (stop_btn, 1); + + handler = setup_wakeup_main_thread (wdata->request); + pthread_create (&wdata->tid, NULL, getdir_thread, wdata->request); + while (wdata->request->stopable) + { + GDK_THREADS_LEAVE (); +#if GTK_MAJOR_VERSION == 1 + g_main_iteration (TRUE); +#else + g_main_context_iteration (NULL, TRUE); +#endif + } + teardown_wakeup_main_thread (wdata->request, handler); + + pthread_join (wdata->tid, &success); + gtk_widget_set_sensitive (stop_btn, 0); + } + else + success = getdir_thread (wdata->request); + wdata->files = success; + gtk_clist_thaw (GTK_CLIST (wdata->listbox)); + memset (&wdata->tid, 0, sizeof (wdata->tid)); + } + + if (wdata->files == NULL || !GFTP_IS_CONNECTED (wdata->request)) + { + disconnect (wdata); + return (0); + } + + wdata->sorted = 0; + sortrows (GTK_CLIST (wdata->listbox), *wdata->sortcol, (gpointer) wdata); + if (IS_NONE_SELECTED (wdata)) + gtk_clist_select_row (GTK_CLIST (wdata->listbox), 0, 0); + return (1); +} + + static void try_connect_again (gftp_request * request, gftp_dialog_data * ddata) { @@ -229,6 +237,63 @@ } +static void * +connect_thread (void *data) +{ + static int conn_num; + gftp_request * request; + int ret, sj; + + request = data; + request->user_data = (void *) 0x1; + + conn_num = 0; + if (request->use_threads) + { + sj = sigsetjmp (jmp_environment, 1); + use_jmp_environment = 1; + } + else + sj = 0; + + ret = 0; + if (sj != 0) + { + ret = 0; + gftp_disconnect (request); + } + + while (sj != 1 && (request->retries == 0 || conn_num < request->retries)) + { + conn_num++; + if (request->network_timeout > 0) + alarm (request->network_timeout); + ret = gftp_connect (request) == 0; + alarm (0); + + if (ret) + break; + else if (request->retries == 0 || conn_num < request->retries) + { + request->logging_function (gftp_logging_misc, request->user_data, + _("Waiting %d seconds until trying to connect again\n"), + request->sleep_time); + alarm (request->sleep_time); + pause (); + } + } + + if (request->use_threads) + use_jmp_environment = 0; + + request->user_data = NULL; + request->stopable = 0; + if (request->wakeup_main_thread[1] > 0) + write (request->wakeup_main_thread[1], " ", 1); + return ((void *) ret); +} + + int ftp_connect (gftp_window_data * wdata, gftp_request * request, int getdir) { @@ -316,63 +381,6 @@ } -static void * -connect_thread (void *data) -{ - static int conn_num; - gftp_request * request; - int ret, sj; - - request = data; - request->user_data = (void *) 0x1; - - conn_num = 0; - if (request->use_threads) - { - sj = sigsetjmp (jmp_environment, 1); - use_jmp_environment = 1; - } - else - sj = 0; - - ret = 0; - if (sj != 0) - { - ret = 0; - gftp_disconnect (request); - } - - while (sj != 1 && (request->retries == 0 || conn_num < request->retries)) - { - conn_num++; - if (request->network_timeout > 0) - alarm (request->network_timeout); - ret = gftp_connect (request) == 0; - alarm (0); - - if (ret) - break; - else if (request->retries == 0 || conn_num < request->retries) - { - request->logging_function (gftp_logging_misc, request->user_data, - _("Waiting %d seconds until trying to connect again\n"), - request->sleep_time); - alarm (request->sleep_time); - pause (); - } - } - - if (request->use_threads) - use_jmp_environment = 0; - - request->user_data = NULL; - request->stopable = 0; - if (request->wakeup_main_thread[1] > 0) - write (request->wakeup_main_thread[1], " ", 1); - return ((void *) ret); -} - - void get_files (gpointer data) { @@ -544,6 +552,193 @@ } +static void +gftp_gtk_calc_kbs (gftp_transfer * tdata, ssize_t num_read) +{ + unsigned long waitusecs; + double difftime, curkbs; + gftp_file * tempfle; + struct timeval tv; + unsigned long toadd; + + gettimeofday (&tv, NULL); + pthread_mutex_lock (tdata->statmutex); + + tempfle = tdata->curfle->data; + tdata->trans_bytes += num_read; + tdata->curtrans += num_read; + tdata->stalled = 0; + + difftime = (tv.tv_sec - tdata->starttime.tv_sec) + ((double) (tv.tv_usec - tdata->starttime.tv_usec) / 1000000.0); + if (difftime <= 0) + tdata->kbs = (double) tdata->trans_bytes / 1024.0; + else + tdata->kbs = (double) tdata->trans_bytes / 1024.0 / difftime; + + difftime = (tv.tv_sec - tdata->lasttime.tv_sec) + ((double) (tv.tv_usec - tdata->lasttime.tv_usec) / 1000000.0); + + if (difftime <= 0) + curkbs = (double) (num_read / 1024.0); + else + curkbs = (double) (num_read / 1024.0 / difftime); + + if (tdata->fromreq->maxkbs > 0 && + curkbs > tdata->fromreq->maxkbs) + { + waitusecs = (double) num_read / 1024.0 / tdata->fromreq->maxkbs * 1000000.0 - difftime; + + if (waitusecs > 0) + { + pthread_mutex_unlock (tdata->statmutex); + difftime += ((double) waitusecs / 1000000.0); + usleep (waitusecs); + pthread_mutex_lock (tdata->statmutex); + } + } + + /* I don't call gettimeofday (&tdata->lasttime) here because this will use + less system resources. This will be close enough for what we need */ + difftime += tdata->lasttime.tv_usec / 1000000.0; + toadd = (long) difftime; + difftime -= toadd; + tdata->lasttime.tv_sec += toadd; + tdata->lasttime.tv_usec = difftime * 1000000.0; + + pthread_mutex_unlock (tdata->statmutex); +} + + +static int +get_status (gftp_transfer * tdata, ssize_t num_read) +{ + gftp_file * tempfle; + struct timeval tv; + + pthread_mutex_lock (tdata->structmutex); + if (tdata->curfle == NULL) + { + pthread_mutex_unlock (tdata->structmutex); + return (-1); + } + tempfle = tdata->curfle->data; + pthread_mutex_unlock (tdata->structmutex); + + gftp_disconnect (tdata->fromreq); + gftp_disconnect (tdata->toreq); + if (num_read < 0 || tdata->skip_file) + { + if (tdata->fromreq->retries != 0 && tdata->current_file_retries >= tdata->fromreq->retries) + { + tdata->fromreq->logging_function (gftp_logging_error, + tdata->fromreq->user_data, + _("Error: Remote site %s disconnected. Max retries reached...giving up\n"), + tdata->fromreq->hostname != NULL ? + tdata->fromreq->hostname : tdata->toreq->hostname); + return (-1); + } + else + { + tdata->fromreq->logging_function (gftp_logging_error, + tdata->fromreq->user_data, + _("Error: Remote site %s disconnected. Will reconnect in %d seconds\n"), + tdata->fromreq->hostname != NULL ? + tdata->fromreq->hostname : tdata->toreq->hostname, + tdata->fromreq->sleep_time); + } + + while (tdata->fromreq->retries == 0 || + tdata->current_file_retries <= tdata->fromreq->retries) + { + if (!tdata->skip_file) + { + tv.tv_sec = tdata->fromreq->sleep_time; + tv.tv_usec = 0; + select (0, NULL, NULL, NULL, &tv); + } + + if (gftp_connect (tdata->fromreq) == 0 && + gftp_connect (tdata->toreq) == 0) + { + pthread_mutex_lock (tdata->structmutex); + tdata->resumed_bytes = tdata->resumed_bytes + tdata->trans_bytes - tdata->curresumed - tdata->curtrans; + tdata->trans_bytes = 0; + if (tdata->skip_file) + { + tdata->total_bytes -= tempfle->size; + tdata->curtrans = 0; + + tdata->curfle = tdata->curfle->next; + tdata->next_file = 1; + tdata->skip_file = 0; + tdata->cancel = 0; + tdata->fromreq->cancel = 0; + tdata->toreq->cancel = 0; + } + else + { + tempfle->transfer_action = GFTP_TRANS_ACTION_RESUME; + tempfle->startsize = tdata->curtrans + tdata->curresumed; + /* We decrement this here because it will be incremented in + the loop again */ + tdata->curresumed = 0; + tdata->current_file_number--; /* Decrement this because it + will be incremented when we + continue in the loop */ + } + gettimeofday (&tdata->starttime, NULL); + pthread_mutex_unlock (tdata->structmutex); + return (1); + } + else + tdata->current_file_retries++; + } + } + else if (tdata->cancel) + return (-1); + + return (0); +} + + +static mode_t +parse_attribs (char *attribs) +{ + mode_t mode; + int cur; + + cur = 0; + if (attribs[1] == 'r') + cur += 4; + if (attribs[2] == 'w') + cur += 2; + if (attribs[3] == 'x' || + attribs[3] == 's') + cur += 1; + mode = cur; + + cur = 0; + if (attribs[4] == 'r') + cur += 4; + if (attribs[5] == 'w') + cur += 2; + if (attribs[6] == 'x' || + attribs[6] == 's') + cur += 1; + mode = (mode * 10) + cur; + + cur = 0; + if (attribs[7] == 'r') + cur += 4; + if (attribs[8] == 'w') + cur += 2; + if (attribs[9] == 'x' || + attribs[9] == 's') + cur += 1; + mode = (mode * 10) + cur; + + return (mode); +} + void * gftp_gtk_transfer_files (void *data) @@ -925,70 +1120,126 @@ } -gint -update_downloads (gpointer data) +static void +remove_file (char *filename) +{ + if (unlink (filename) == 0) + ftp_log (gftp_logging_misc, NULL, _("Successfully removed %s\n"), + filename); + else + ftp_log (gftp_logging_error, NULL, + _("Error: Could not remove file %s: %s\n"), filename, + g_strerror (errno)); +} + + +static void +free_edit_data (gftp_viewedit_data * ve_proc) +{ + int i; + + if (ve_proc->filename) + g_free (ve_proc->filename); + if (ve_proc->remote_filename) + g_free (ve_proc->remote_filename); + for (i = 0; ve_proc->argv[i] != NULL; i++) + g_free (ve_proc->argv[i]); + g_free (ve_proc->argv); + g_free (ve_proc); +} + + +static void +dont_upload (gftp_viewedit_data * ve_proc, gftp_dialog_data * ddata) { - char tempstr[50], temp1str[127]; - GList * templist, * next; - gftp_transfer * tdata; + remove_file (ve_proc->filename); + free_edit_data (ve_proc); +} + + +static void +do_upload (gftp_viewedit_data * ve_proc, gftp_dialog_data * ddata) +{ + gftp_file * tempfle; + GList * newfile; - if (file_transfer_logs != NULL) - display_cached_logs (); + tempfle = g_malloc0 (sizeof (*tempfle)); + tempfle->destfile = ve_proc->remote_filename; + ve_proc->remote_filename = NULL; + tempfle->file = ve_proc->filename; + ve_proc->filename = NULL; + tempfle->done_rm = 1; + newfile = g_list_append (NULL, tempfle); + add_file_transfer (ve_proc->fromwdata->request, ve_proc->towdata->request, + ve_proc->fromwdata, ve_proc->towdata, newfile, 1); + free_edit_data (ve_proc); +} + - if (window2.request->gotbytes != 0) +static void +check_done_process (void) +{ + gftp_viewedit_data * ve_proc; + GList * curdata, *deldata; + struct stat st; + int ret; + char *str; + pid_t pid; + + viewedit_process_done = 0; + while ((pid = waitpid (-1, &ret, WNOHANG)) > 0) { - if (window2.request->gotbytes == -1) - { - update_window_info (); - window2.request->gotbytes = 0; - } - else - { - insert_commas (window2.request->gotbytes, tempstr, sizeof (tempstr)); - g_snprintf (temp1str, sizeof (temp1str), - _("Retrieving file names...%s bytes"), tempstr); - gtk_label_set (GTK_LABEL (window2.hoststxt), temp1str); + curdata = viewedit_processes; + while (curdata != NULL) + { + ve_proc = curdata->data; + deldata = curdata; + curdata = curdata->next; + if (ve_proc->pid == pid) + { + viewedit_processes = g_list_remove_link (viewedit_processes, + deldata); + if (ret != 0) + ftp_log (gftp_logging_error, NULL, + _("Error: Child %d returned %d\n"), pid, ret); + else + ftp_log (gftp_logging_misc, NULL, + _("Child %d returned successfully\n"), pid); + + if (!ve_proc->view && !ve_proc->dontupload) + { + /* We was editing the file. Upload it */ + if (stat (ve_proc->filename, &st) == -1) + ftp_log (gftp_logging_error, NULL, + _("Error: Cannot get information about file %s: %s\n"), + ve_proc->filename, g_strerror (errno)); + else if (st.st_mtime == ve_proc->st.st_mtime) + { + ftp_log (gftp_logging_misc, NULL, + _("File %s was not changed\n"), + ve_proc->filename); + remove_file (ve_proc->filename); + } + else + { + memcpy (&ve_proc->st, &st, sizeof (ve_proc->st)); + str = g_strdup_printf ( + _("File %s has changed.\nWould you like to upload it?"), + ve_proc->remote_filename); + + MakeYesNoDialog (_("Edit File"), str, + do_upload, ve_proc, + dont_upload, ve_proc); + g_free (str); + continue; + } + } + + free_edit_data (ve_proc); + continue; + } } } - - if (viewedit_process_done) - check_done_process (); - - for (templist = file_transfers; templist != NULL;) - { - tdata = templist->data; - if (tdata->ready) - { - pthread_mutex_lock (tdata->structmutex); - - if (tdata->next_file) - on_next_transfer (tdata); - else if (tdata->show) - show_transfer (tdata); - else if (tdata->done) - { - next = templist->next; - transfer_done (templist); - templist = next; - continue; - } - - if (tdata->curfle != NULL) - { - if (!tdata->started && start_file_transfers && - (transfer_in_progress == 0 || !do_one_transfer_at_a_time)) - create_transfer (tdata); - - if (tdata->started) - update_file_status (tdata); - } - pthread_mutex_unlock (tdata->structmutex); - } - templist = templist->next; - } - - gtk_timeout_add (500, update_downloads, NULL); - return (0); } @@ -1331,6 +1582,73 @@ } +gint +update_downloads (gpointer data) +{ + char tempstr[50], temp1str[127]; + GList * templist, * next; + gftp_transfer * tdata; + + if (file_transfer_logs != NULL) + display_cached_logs (); + + if (window2.request->gotbytes != 0) + { + if (window2.request->gotbytes == -1) + { + update_window_info (); + window2.request->gotbytes = 0; + } + else + { + insert_commas (window2.request->gotbytes, tempstr, sizeof (tempstr)); + g_snprintf (temp1str, sizeof (temp1str), + _("Retrieving file names...%s bytes"), tempstr); + gtk_label_set (GTK_LABEL (window2.hoststxt), temp1str); + } + } + + if (viewedit_process_done) + check_done_process (); + + for (templist = file_transfers; templist != NULL;) + { + tdata = templist->data; + if (tdata->ready) + { + pthread_mutex_lock (tdata->structmutex); + + if (tdata->next_file) + on_next_transfer (tdata); + else if (tdata->show) + show_transfer (tdata); + else if (tdata->done) + { + next = templist->next; + transfer_done (templist); + templist = next; + continue; + } + + if (tdata->curfle != NULL) + { + if (!tdata->started && start_file_transfers && + (transfer_in_progress == 0 || !do_one_transfer_at_a_time)) + create_transfer (tdata); + + if (tdata->started) + update_file_status (tdata); + } + pthread_mutex_unlock (tdata->structmutex); + } + templist = templist->next; + } + + gtk_timeout_add (500, update_downloads, NULL); + return (0); +} + + void start_transfer (gpointer data) { @@ -1600,6 +1918,132 @@ } +static void +trans_selectall (GtkWidget * widget, gpointer data) +{ + gftp_transfer * tdata; + tdata = data; + + gtk_clist_select_all (GTK_CLIST (tdata->clist)); +} + + +static void +trans_unselectall (GtkWidget * widget, gpointer data) +{ + gftp_transfer * tdata; + tdata = data; + + gtk_clist_unselect_all (GTK_CLIST (tdata->clist)); +} + + +static void +overwrite (GtkWidget * widget, gpointer data) +{ + GList * templist, * filelist; + gftp_transfer * tdata; + gftp_file * tempfle; + int curpos; + + tdata = data; + curpos = 0; + filelist = tdata->files; + templist = GTK_CLIST (tdata->clist)->selection; + while (templist != NULL) + { + templist = get_next_selection (templist, &filelist, &curpos); + tempfle = filelist->data; + tempfle->transfer_action = GFTP_TRANS_ACTION_OVERWRITE; + gtk_clist_set_text (GTK_CLIST (tdata->clist), curpos, 3, _("Overwrite")); + } +} + + +static void +resume (GtkWidget * widget, gpointer data) +{ + GList * templist, * filelist; + gftp_transfer * tdata; + gftp_file * tempfle; + int curpos; + + tdata = data; + curpos = 0; + filelist = tdata->files; + templist = GTK_CLIST (tdata->clist)->selection; + while (templist != NULL) + { + templist = get_next_selection (templist, &filelist, &curpos); + tempfle = filelist->data; + tempfle->transfer_action = GFTP_TRANS_ACTION_RESUME; + gtk_clist_set_text (GTK_CLIST (tdata->clist), curpos, 3, _("Resume")); + } +} + + +static void +skip (GtkWidget * widget, gpointer data) +{ + GList * templist, * filelist; + gftp_transfer * tdata; + gftp_file * tempfle; + int curpos; + + tdata = data; + curpos = 0; + filelist = tdata->files; + templist = GTK_CLIST (tdata->clist)->selection; + while (templist != NULL) + { + templist = get_next_selection (templist, &filelist, &curpos); + tempfle = filelist->data; + tempfle->transfer_action = GFTP_TRANS_ACTION_SKIP; + gtk_clist_set_text (GTK_CLIST (tdata->clist), curpos, 3, _("Skip")); + } +} + + +static void +ok (GtkWidget * widget, gpointer data) +{ + gftp_transfer * tdata; + gftp_file * tempfle; + GList * templist; + + tdata = data; + pthread_mutex_lock ((pthread_mutex_t *) tdata->structmutex); + for (templist = tdata->files; templist != NULL; templist = templist->next) + { + tempfle = templist->data; + if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP) + break; + } + + if (templist == NULL) + { + tdata->show = 0; + tdata->ready = tdata->done = 1; + } + else + tdata->show = tdata->ready = 1; + pthread_mutex_unlock ((pthread_mutex_t *) tdata->structmutex); +} + + +static void +cancel (GtkWidget * widget, gpointer data) +{ + gftp_transfer * tdata; + + tdata = data; + pthread_mutex_lock ((pthread_mutex_t *) tdata->structmutex); + tdata->show = 0; + tdata->done = tdata->ready = 1; + pthread_mutex_unlock ((pthread_mutex_t *) tdata->structmutex); +} + + void gftp_gtk_ask_transfer (gftp_transfer * tdata) { @@ -1784,488 +2228,3 @@ dialog = NULL; } - -static void -trans_selectall (GtkWidget * widget, gpointer data) -{ - gftp_transfer * tdata; - tdata = data; - - gtk_clist_select_all (GTK_CLIST (tdata->clist)); -} - - -static void -trans_unselectall (GtkWidget * widget, gpointer data) -{ - gftp_transfer * tdata; - tdata = data; - - gtk_clist_unselect_all (GTK_CLIST (tdata->clist)); -} - - -static void -overwrite (GtkWidget * widget, gpointer data) -{ - GList * templist, * filelist; - gftp_transfer * tdata; - gftp_file * tempfle; - int curpos; - - tdata = data; - curpos = 0; - filelist = tdata->files; - templist = GTK_CLIST (tdata->clist)->selection; - while (templist != NULL) - { - templist = get_next_selection (templist, &filelist, &curpos); - tempfle = filelist->data; - tempfle->transfer_action = GFTP_TRANS_ACTION_OVERWRITE; - gtk_clist_set_text (GTK_CLIST (tdata->clist), curpos, 3, _("Overwrite")); - } -} - - -static void -resume (GtkWidget * widget, gpointer data) -{ - GList * templist, * filelist; - gftp_transfer * tdata; - gftp_file * tempfle; - int curpos; - - tdata = data; - curpos = 0; - filelist = tdata->files; - templist = GTK_CLIST (tdata->clist)->selection; - while (templist != NULL) - { - templist = get_next_selection (templist, &filelist, &curpos); - tempfle = filelist->data; - tempfle->transfer_action = GFTP_TRANS_ACTION_RESUME; - gtk_clist_set_text (GTK_CLIST (tdata->clist), curpos, 3, _("Resume")); - } -} - - -static void -skip (GtkWidget * widget, gpointer data) -{ - GList * templist, * filelist; - gftp_transfer * tdata; - gftp_file * tempfle; - int curpos; - - tdata = data; - curpos = 0; - filelist = tdata->files; - templist = GTK_CLIST (tdata->clist)->selection; - while (templist != NULL) - { - templist = get_next_selection (templist, &filelist, &curpos); - tempfle = filelist->data; - tempfle->transfer_action = GFTP_TRANS_ACTION_SKIP; - gtk_clist_set_text (GTK_CLIST (tdata->clist), curpos, 3, _("Skip")); - } -} - - -static void -ok (GtkWidget * widget, gpointer data) -{ - gftp_transfer * tdata; - gftp_file * tempfle; - GList * templist; - - tdata = data; - pthread_mutex_lock ((pthread_mutex_t *) tdata->structmutex); - for (templist = tdata->files; templist != NULL; templist = templist->next) - { - tempfle = templist->data; - if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP) - break; - } - - if (templist == NULL) - { - tdata->show = 0; - tdata->ready = tdata->done = 1; - } - else - tdata->show = tdata->ready = 1; - pthread_mutex_unlock ((pthread_mutex_t *) tdata->structmutex); -} - - -static void -cancel (GtkWidget * widget, gpointer data) -{ - gftp_transfer * tdata; - - tdata = data; - pthread_mutex_lock ((pthread_mutex_t *) tdata->structmutex); - tdata->show = 0; - tdata->done = tdata->ready = 1; - pthread_mutex_unlock ((pthread_mutex_t *) tdata->structmutex); -} - - -static void -gftp_gtk_calc_kbs (gftp_transfer * tdata, ssize_t num_read) -{ - unsigned long waitusecs; - double difftime, curkbs; - gftp_file * tempfle; - struct timeval tv; - unsigned long toadd; - - gettimeofday (&tv, NULL); - pthread_mutex_lock (tdata->statmutex); - - tempfle = tdata->curfle->data; - tdata->trans_bytes += num_read; - tdata->curtrans += num_read; - tdata->stalled = 0; - - difftime = (tv.tv_sec - tdata->starttime.tv_sec) + ((double) (tv.tv_usec - tdata->starttime.tv_usec) / 1000000.0); - if (difftime <= 0) - tdata->kbs = (double) tdata->trans_bytes / 1024.0; - else - tdata->kbs = (double) tdata->trans_bytes / 1024.0 / difftime; - - difftime = (tv.tv_sec - tdata->lasttime.tv_sec) + ((double) (tv.tv_usec - tdata->lasttime.tv_usec) / 1000000.0); - - if (difftime <= 0) - curkbs = (double) (num_read / 1024.0); - else - curkbs = (double) (num_read / 1024.0 / difftime); - - if (tdata->fromreq->maxkbs > 0 && - curkbs > tdata->fromreq->maxkbs) - { - waitusecs = (double) num_read / 1024.0 / tdata->fromreq->maxkbs * 1000000.0 - difftime; - - if (waitusecs > 0) - { - pthread_mutex_unlock (tdata->statmutex); - difftime += ((double) waitusecs / 1000000.0); - usleep (waitusecs); - pthread_mutex_lock (tdata->statmutex); - } - } - - /* I don't call gettimeofday (&tdata->lasttime) here because this will use - less system resources. This will be close enough for what we need */ - difftime += tdata->lasttime.tv_usec / 1000000.0; - toadd = (long) difftime; - difftime -= toadd; - tdata->lasttime.tv_sec += toadd; - tdata->lasttime.tv_usec = difftime * 1000000.0; - - pthread_mutex_unlock (tdata->statmutex); -} - - -static void -check_done_process (void) -{ - gftp_viewedit_data * ve_proc; - GList * curdata, *deldata; - struct stat st; - int ret; - char *str; - pid_t pid; - - viewedit_process_done = 0; - while ((pid = waitpid (-1, &ret, WNOHANG)) > 0) - { - curdata = viewedit_processes; - while (curdata != NULL) - { - ve_proc = curdata->data; - deldata = curdata; - curdata = curdata->next; - if (ve_proc->pid == pid) - { - viewedit_processes = g_list_remove_link (viewedit_processes, - deldata); - if (ret != 0) - ftp_log (gftp_logging_error, NULL, - _("Error: Child %d returned %d\n"), pid, ret); - else - ftp_log (gftp_logging_misc, NULL, - _("Child %d returned successfully\n"), pid); - - if (!ve_proc->view && !ve_proc->dontupload) - { - /* We was editing the file. Upload it */ - if (stat (ve_proc->filename, &st) == -1) - ftp_log (gftp_logging_error, NULL, - _("Error: Cannot get information about file %s: %s\n"), - ve_proc->filename, g_strerror (errno)); - else if (st.st_mtime == ve_proc->st.st_mtime) - { - ftp_log (gftp_logging_misc, NULL, - _("File %s was not changed\n"), - ve_proc->filename); - remove_file (ve_proc->filename); - } - else - { - memcpy (&ve_proc->st, &st, sizeof (ve_proc->st)); - str = g_strdup_printf ( - _("File %s has changed.\nWould you like to upload it?"), - ve_proc->remote_filename); - - MakeYesNoDialog (_("Edit File"), str, - do_upload, ve_proc, - dont_upload, ve_proc); - g_free (str); - continue; - } - } - - free_edit_data (ve_proc); - continue; - } - } - } -} - - -static void -do_upload (gftp_viewedit_data * ve_proc, gftp_dialog_data * ddata) -{ - gftp_file * tempfle; - GList * newfile; - - tempfle = g_malloc0 (sizeof (*tempfle)); - tempfle->destfile = ve_proc->remote_filename; - ve_proc->remote_filename = NULL; - tempfle->file = ve_proc->filename; - ve_proc->filename = NULL; - tempfle->done_rm = 1; - newfile = g_list_append (NULL, tempfle); - add_file_transfer (ve_proc->fromwdata->request, ve_proc->towdata->request, - ve_proc->fromwdata, ve_proc->towdata, newfile, 1); - free_edit_data (ve_proc); -} - - -static void -dont_upload (gftp_viewedit_data * ve_proc, gftp_dialog_data * ddata) -{ - remove_file (ve_proc->filename); - free_edit_data (ve_proc); -} - - -static void -free_edit_data (gftp_viewedit_data * ve_proc) -{ - int i; - - if (ve_proc->filename) - g_free (ve_proc->filename); - if (ve_proc->remote_filename) - g_free (ve_proc->remote_filename); - for (i = 0; ve_proc->argv[i] != NULL; i++) - g_free (ve_proc->argv[i]); - g_free (ve_proc->argv); - g_free (ve_proc); -} - - -static int -get_status (gftp_transfer * tdata, ssize_t num_read) -{ - gftp_file * tempfle; - struct timeval tv; - - pthread_mutex_lock (tdata->structmutex); - if (tdata->curfle == NULL) - { - pthread_mutex_unlock (tdata->structmutex); - return (-1); - } - tempfle = tdata->curfle->data; - pthread_mutex_unlock (tdata->structmutex); - - gftp_disconnect (tdata->fromreq); - gftp_disconnect (tdata->toreq); - if (num_read < 0 || tdata->skip_file) - { - if (tdata->fromreq->retries != 0 && tdata->current_file_retries >= tdata->fromreq->retries) - { - tdata->fromreq->logging_function (gftp_logging_error, - tdata->fromreq->user_data, - _("Error: Remote site %s disconnected. Max retries reached...giving up\n"), - tdata->fromreq->hostname != NULL ? - tdata->fromreq->hostname : tdata->toreq->hostname); - return (-1); - } - else - { - tdata->fromreq->logging_function (gftp_logging_error, - tdata->fromreq->user_data, - _("Error: Remote site %s disconnected. Will reconnect in %d seconds\n"), - tdata->fromreq->hostname != NULL ? - tdata->fromreq->hostname : tdata->toreq->hostname, - tdata->fromreq->sleep_time); - } - - while (tdata->fromreq->retries == 0 || - tdata->current_file_retries <= tdata->fromreq->retries) - { - if (!tdata->skip_file) - { - tv.tv_sec = tdata->fromreq->sleep_time; - tv.tv_usec = 0; - select (0, NULL, NULL, NULL, &tv); - } - - if (gftp_connect (tdata->fromreq) == 0 && - gftp_connect (tdata->toreq) == 0) - { - pthread_mutex_lock (tdata->structmutex); - tdata->resumed_bytes = tdata->resumed_bytes + tdata->trans_bytes - tdata->curresumed - tdata->curtrans; - tdata->trans_bytes = 0; - if (tdata->skip_file) - { - tdata->total_bytes -= tempfle->size; - tdata->curtrans = 0; - - tdata->curfle = tdata->curfle->next; - tdata->next_file = 1; - tdata->skip_file = 0; - tdata->cancel = 0; - tdata->fromreq->cancel = 0; - tdata->toreq->cancel = 0; - } - else - { - tempfle->transfer_action = GFTP_TRANS_ACTION_RESUME; - tempfle->startsize = tdata->curtrans + tdata->curresumed; - /* We decrement this here because it will be incremented in - the loop again */ - tdata->curresumed = 0; - tdata->current_file_number--; /* Decrement this because it - will be incremented when we - continue in the loop */ - } - gettimeofday (&tdata->starttime, NULL); - pthread_mutex_unlock (tdata->structmutex); - return (1); - } - else - tdata->current_file_retries++; - } - } - else if (tdata->cancel) - return (-1); - - return (0); -} - - -static void -wakeup_main_thread (gpointer data, gint source, GdkInputCondition condition) -{ - gftp_request * request; - char c; - - request = data; - if (request->wakeup_main_thread[0] > 0) - read (request->wakeup_main_thread[0], &c, 1); -} - - -static gint -setup_wakeup_main_thread (gftp_request * request) -{ - gint handler; - - if (socketpair (AF_UNIX, SOCK_STREAM, 0, request->wakeup_main_thread) == 0) - { - /* FIXME - depreciated in GDK 2.0 */ - handler = gdk_input_add (request->wakeup_main_thread[0], - GDK_INPUT_READ, wakeup_main_thread, request); - } - else - { - request->wakeup_main_thread[0] = 0; - request->wakeup_main_thread[1] = 0; - handler = 0; - } - return (handler); -} - - -static void -teardown_wakeup_main_thread (gftp_request * request, gint handler) -{ - if (request->wakeup_main_thread[0] > 0 && request->wakeup_main_thread[1] > 0) - { - /* FIXME - depreciated in GDK 2.0 */ - gdk_input_remove (handler); - close (request->wakeup_main_thread[0]); - close (request->wakeup_main_thread[1]); - request->wakeup_main_thread[0] = 0; - request->wakeup_main_thread[1] = 0; - } -} - - -static mode_t -parse_attribs (char *attribs) -{ - mode_t mode; - int cur; - - cur = 0; - if (attribs[1] == 'r') - cur += 4; - if (attribs[2] == 'w') - cur += 2; - if (attribs[3] == 'x' || - attribs[3] == 's') - cur += 1; - mode = cur; - - cur = 0; - if (attribs[4] == 'r') - cur += 4; - if (attribs[5] == 'w') - cur += 2; - if (attribs[6] == 'x' || - attribs[6] == 's') - cur += 1; - mode = (mode * 10) + cur; - - cur = 0; - if (attribs[7] == 'r') - cur += 4; - if (attribs[8] == 'w') - cur += 2; - if (attribs[9] == 'x' || - attribs[9] == 's') - cur += 1; - mode = (mode * 10) + cur; - - return (mode); -} - - -static void -remove_file (char *filename) -{ - if (unlink (filename) == 0) - ftp_log (gftp_logging_misc, NULL, _("Successfully removed %s\n"), - filename); - else - ftp_log (gftp_logging_error, NULL, - _("Error: Could not remove file %s: %s\n"), filename, - g_strerror (errno)); -} -