Mercurial > gftp.yaz
diff src/uicommon/gftpui.c @ 367:d5409bf03ff1
2003-1-18 Brian Masney <masneyb@gftp.org>
* lib/protocols.c (gftp_parse_url) - if the URL is the local filesystem, skip over the whitespace at the beginning.
* lib/rfc959.c (rfc959_syst) - allow the string MVS and OS/MVS for the
MVS directory listings.
* src/gtk/gtkui_transfer.c src/gtk/transfer.c src/gtk/gftpui.c -
started to move the transfer functionality into the uicommon directory.
Added the text and GTK+ UI specific transfer functions.
* src/gtk/Makefile.am po/POTFILES.in - added gtkui_transfer.c
* src/gtk/dnd.c src/gtk/gtkui_transfer.c src/gtk/view_dialog.c -
s/add_file_transfer/gtkui_common_add_file_transfer/
* src/gtk/gftp-gtk.c src/gtk/gftp-gtk.h - removed transfer_mutex
* src/gtk/gtkui.c src/text/textui.c - added
gftpui_add_file_to_transfer()
* src/uicommon/gftpui_callbacks.c src/uicommon/gftpui.c - in all of the
thread callback functions, don't alter the return value in the function. Return it as is.
author | masneyb |
---|---|
date | Sun, 18 Jan 2004 20:09:28 +0000 |
parents | 7cb3327f96f7 |
children | af541d789f4c |
line wrap: on
line diff
--- a/src/uicommon/gftpui.c Sun Jan 18 19:56:01 2004 +0000 +++ b/src/uicommon/gftpui.c Sun Jan 18 20:09:28 2004 +0000 @@ -24,7 +24,9 @@ volatile int gftpui_common_use_jmp_environment = 0; static void *gftpui_common_local_uidata, *gftpui_common_remote_uidata; -static gftp_request * gftpui_common_local_request, * gftpui_common_remote_request; +static gftp_request * gftpui_common_local_request, + * gftpui_common_remote_request; +GStaticMutex gftpui_common_transfer_mutex = G_STATIC_MUTEX_INIT; static gftp_logging_func @@ -40,26 +42,39 @@ static void * _gftpui_common_thread_callback (void * data) { + intptr_t network_timeout, sleep_time; gftpui_callback_data * cdata; - intptr_t network_timeout; int success, sj; cdata = data; gftp_lookup_request_option (cdata->request, "network_timeout", &network_timeout); + gftp_lookup_request_option (cdata->request, "sleep_time", + &sleep_time); sj = sigsetjmp (gftpui_common_jmp_environment, 1); gftpui_common_use_jmp_environment = 1; - success = 0; + success = GFTP_ERETRYABLE; if (sj == 0) { - if (network_timeout > 0) - alarm (network_timeout); + while (1) + { + if (network_timeout > 0) + alarm (network_timeout); + success = cdata->run_function (cdata); + alarm (0); - success = cdata->run_function (cdata); + if (success == GFTP_EFATAL || success == 0 || cdata->retries == 0) + break; - alarm (0); + cdata->request->logging_function (gftp_logging_misc, cdata->request, + _("Waiting %d seconds until trying to connect again\n"), + sleep_time); + alarm (sleep_time); + pause (); + cdata->retries--; + } } else { @@ -88,10 +103,10 @@ else ret = GPOINTER_TO_INT (cdata->run_function (cdata)); - if (ret && cdata->run_function != gftpui_common_run_ls) + if (ret == 0 && cdata->run_function != gftpui_common_run_ls) gftpui_refresh (cdata->uidata); - return (ret); + return (ret == 0); } @@ -545,9 +560,11 @@ } -static int +int gftpui_common_cmd_open (void *uidata, gftp_request * request, char *command) { + gftpui_callback_data * cdata; + intptr_t retries; char *tempstr; if (GFTP_IS_CONNECTED (request)) @@ -555,15 +572,18 @@ gftp_disconnect (request); /* FIXME */ } - if (*command == '\0') + if (command != NULL) { - request->logging_function (gftp_logging_error, request, - _("usage: open " GFTP_URL_USAGE "\n")); - return (1); + if (*command == '\0') + { + request->logging_function (gftp_logging_error, request, + _("usage: open " GFTP_URL_USAGE "\n")); + return (1); + } + + if (gftp_parse_url (request, command) < 0) + return (1); } - - if (gftp_parse_url (request, command) < 0) - return (1); if (request->need_userpass) { @@ -589,7 +609,17 @@ } } - /* FIXME gftp_connect (request); */ + gftp_lookup_request_option (request, "retries", &retries); + + cdata = g_malloc0 (sizeof (*cdata)); + cdata->request = request; + cdata->uidata = uidata; + cdata->run_function = gftpui_common_run_connect; + cdata->retries = retries; + + gftpui_common_run_callback_function (cdata); + + g_free (cdata); return (1); } @@ -918,3 +948,373 @@ return (ret); } + +gftp_transfer * +gftpui_common_add_file_transfer (gftp_request * fromreq, gftp_request * toreq, + void *fromuidata, void *touidata, + GList * files) +{ + intptr_t append_transfers, one_transfer; + GList * templist, *curfle; + gftp_transfer * tdata; + gftp_file * tempfle; + int show_dialog; + char *pos; + + for (templist = files; templist != NULL; templist = templist->next) + { + tempfle = templist->data; + if (tempfle->startsize > 0) + break; + } + show_dialog = templist != NULL; + + gftp_lookup_request_option (fromreq, "append_transfers", + &append_transfers); + gftp_lookup_request_option (fromreq, "one_transfer", + &one_transfer); + + tdata = NULL; + if (append_transfers && one_transfer && !show_dialog) + { + if (g_thread_supported ()) + g_static_mutex_lock (&gftpui_common_transfer_mutex); + + for (templist = gftp_file_transfers; + templist != NULL; + templist = templist->next) + { + tdata = templist->data; + + if (g_thread_supported ()) + g_static_mutex_lock (&tdata->structmutex); + + if (!compare_request (tdata->fromreq, fromreq, 0) || + !compare_request (tdata->toreq, toreq, 0) || + tdata->curfle == NULL) + { + if (g_thread_supported ()) + g_static_mutex_unlock (&tdata->structmutex); + + continue; + } + + tdata->files = g_list_concat (tdata->files, files); + + for (curfle = files; curfle != NULL; curfle = curfle->next) + { + tempfle = curfle->data; + + if (tempfle->isdir) + tdata->numdirs++; + else + tdata->numfiles++; + + if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP) + tdata->total_bytes += tempfle->size; + + if ((pos = strrchr (tempfle->file, '/')) == NULL) + pos = tempfle->file; + else + pos++; + + gftpui_add_file_to_transfer (tdata, curfle, pos); + } + + if (g_thread_supported ()) + g_static_mutex_unlock (&tdata->structmutex); + + break; + } + + if (g_thread_supported ()) + g_static_mutex_unlock (&gftpui_common_transfer_mutex); + } + else + templist = NULL; + + if (templist == NULL) + { + tdata = gftp_tdata_new (); + tdata->fromreq = copy_request (fromreq, 0); + tdata->toreq = copy_request (toreq, 0); + + tdata->fromwdata = fromuidata; + tdata->towdata = touidata; + + if (!show_dialog) + tdata->show = tdata->ready = 1; + + tdata->files = files; + for (curfle = files; curfle != NULL; curfle = curfle->next) + { + tempfle = curfle->data; + if (tempfle->isdir) + tdata->numdirs++; + else + tdata->numfiles++; + + if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP) + tdata->total_bytes += tempfle->size; + } + + if (g_thread_supported ()) + g_static_mutex_lock (&gftpui_common_transfer_mutex); + + gftp_file_transfers = g_list_append (gftp_file_transfers, tdata); + + if (g_thread_supported ()) + g_static_mutex_unlock (&gftpui_common_transfer_mutex); + + if (show_dialog) + gftpui_ask_transfer (tdata); + } + + return (tdata); +} + + +static void +_gftpui_common_setup_fds (gftp_transfer * tdata, gftp_file * curfle, + int *fromfd, int *tofd) +{ + *tofd = -1; + *fromfd = -1; + + if (curfle->is_fd) + { + if (tdata->toreq->protonum == GFTP_LOCAL_NUM) + *tofd = curfle->fd; + else if (tdata->fromreq->protonum == GFTP_LOCAL_NUM) + *fromfd = curfle->fd; + } +} + + +static void +_gftpui_common_done_with_fds (gftp_transfer * tdata, gftp_file * curfle) +{ + if (curfle->is_fd) + { + if (tdata->toreq->protonum == GFTP_LOCAL_NUM) + tdata->toreq->datafd = -1; + else + tdata->fromreq->datafd = -1; + } +} + + +int +gftpui_common_transfer_files (gftp_transfer * tdata) +{ + int i, mode, tofd, fromfd; + intptr_t preserve_permissions; + char buf[8192]; + off_t fromsize, total; + gftp_file * curfle; + ssize_t num_read, ret; + + tdata->curfle = tdata->files; + gettimeofday (&tdata->starttime, NULL); + memcpy (&tdata->lasttime, &tdata->starttime, + sizeof (tdata->lasttime)); + + gftp_lookup_request_option (tdata->fromreq, "preserve_permissions", + &preserve_permissions); + + while (tdata->curfle != NULL) + { + num_read = -1; + + if (g_thread_supported ()) + g_static_mutex_lock (&tdata->structmutex); + + curfle = tdata->curfle->data; + tdata->current_file_number++; + + if (g_thread_supported ()) + g_static_mutex_unlock (&tdata->structmutex); + + if (curfle->transfer_action == GFTP_TRANS_ACTION_SKIP) + { + if (g_thread_supported ()) + g_static_mutex_lock (&tdata->structmutex); + + tdata->next_file = 1; + tdata->curfle = tdata->curfle->next; + + if (g_thread_supported ()) + g_static_mutex_unlock (&tdata->structmutex); + continue; + } + + fromsize = -1; + if (gftp_connect (tdata->fromreq) == 0 && + gftp_connect (tdata->toreq) == 0) + { + if (curfle->isdir) + { + if (tdata->toreq->mkdir != NULL) + { + tdata->toreq->mkdir (tdata->toreq, curfle->destfile); + if (!GFTP_IS_CONNECTED (tdata->toreq)) + break; + } + + if (g_thread_supported ()) + g_static_mutex_lock (&tdata->structmutex); + + tdata->next_file = 1; + tdata->curfle = tdata->curfle->next; + + if (g_thread_supported ()) + g_static_mutex_unlock (&tdata->structmutex); + continue; + } + + _gftpui_common_setup_fds (tdata, curfle, &fromfd, &tofd); + + if (curfle->size == 0) + { + curfle->size = gftp_get_file_size (tdata->fromreq, curfle->file); + tdata->total_bytes += curfle->size; + } + + if (GFTP_IS_CONNECTED (tdata->fromreq) && + GFTP_IS_CONNECTED (tdata->toreq)) + { + fromsize = gftp_transfer_file (tdata->fromreq, curfle->file, + fromfd, + curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ? + curfle->startsize : 0, + tdata->toreq, curfle->destfile, tofd, + curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ? + curfle->startsize : 0); + } + } + + if (!GFTP_IS_CONNECTED (tdata->fromreq) || + !GFTP_IS_CONNECTED (tdata->toreq)) + { + tdata->fromreq->logging_function (gftp_logging_misc, + tdata->fromreq, + _("Error: Remote site disconnected after trying to tdata file\n")); + } + else if (fromsize < 0) + { + if (g_thread_supported ()) + g_static_mutex_lock (&tdata->structmutex); + + curfle->transfer_action = GFTP_TRANS_ACTION_SKIP; + tdata->next_file = 1; + tdata->curfle = tdata->curfle->next; + + if (g_thread_supported ()) + g_static_mutex_unlock (&tdata->structmutex); + continue; + } + else + { + if (g_thread_supported ()) + g_static_mutex_lock (&tdata->structmutex); + + tdata->curtrans = 0; + tdata->curresumed = curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ? curfle->startsize : 0; + tdata->resumed_bytes += tdata->curresumed; + + if (g_thread_supported ()) + g_static_mutex_unlock (&tdata->structmutex); + + total = 0; + i = 0; + while (!tdata->cancel && + (num_read = gftp_get_next_file_chunk (tdata->fromreq, + buf, sizeof (buf))) > 0) + { + total += num_read; + gftp_calc_kbs (tdata, num_read); + + if ((ret = gftp_put_next_file_chunk (tdata->toreq, buf, + num_read)) < 0) + { + num_read = (int) ret; + break; + } + } + } + + if (tdata->cancel) + { + if (gftp_abort_transfer (tdata->fromreq) != 0) + gftp_disconnect (tdata->fromreq); + + if (gftp_abort_transfer (tdata->toreq) != 0) + gftp_disconnect (tdata->toreq); + } + else if (num_read < 0) + { + tdata->fromreq->logging_function (gftp_logging_misc, + tdata->fromreq, + _("Could not download %s from %s\n"), + curfle->file, + tdata->fromreq->hostname); + + if (gftp_get_transfer_status (tdata, num_read) == GFTP_ERETRYABLE) + continue; + + break; + } + else + { + _gftpui_common_done_with_fds (tdata, curfle); + if (gftp_end_transfer (tdata->fromreq) != 0) + { + if (gftp_get_transfer_status (tdata, -1) == GFTP_ERETRYABLE) + continue; + + break; + } + gftp_end_transfer (tdata->toreq); + + tdata->fromreq->logging_function (gftp_logging_misc, + tdata->fromreq, + _("Successfully tdatared %s at %.2f KB/s\n"), + curfle->file, tdata->kbs); + } + + if (!curfle->is_fd && preserve_permissions) + { + if (curfle->attribs) + { + mode = gftp_parse_attribs (curfle->attribs); + if (mode != 0) + gftp_chmod (tdata->toreq, curfle->destfile, mode); + } + + if (curfle->datetime != 0) + gftp_set_file_time (tdata->toreq, curfle->destfile, + curfle->datetime); + } + + if (g_thread_supported ()) + g_static_mutex_lock (&tdata->structmutex); + + tdata->curtrans = 0; + tdata->next_file = 1; + curfle->transfer_done = 1; + tdata->curfle = tdata->curfle->next; + + if (g_thread_supported ()) + g_static_mutex_unlock (&tdata->structmutex); + + if (tdata->cancel && !tdata->skip_file) + break; + tdata->cancel = 0; + tdata->fromreq->cancel = 0; + tdata->toreq->cancel = 0; + } + tdata->done = 1; + + return (1); /* FIXME */ +} +