int _gftpui_common_do_transfer_file (gftp_transfer * tdata, gftp_file * curfle) { struct timeval updatetime; intptr_t trans_blksize; ssize_t num_trans; char *buf; int ret; gftp_lookup_request_option (tdata->fromreq, "trans_blksize", &trans_blksize); buf = g_malloc0 (trans_blksize); memset (&updatetime, 0, sizeof (updatetime)); gftpui_start_current_file_in_transfer (tdata); num_trans = 0; while (!tdata->cancel && (num_trans = _do_transfer_block (tdata, curfle, buf, trans_blksize)) > 0) { gftp_calc_kbs (tdata, num_trans); if (tdata->lasttime.tv_sec - updatetime.tv_sec >= 1 || tdata->curtrans >= tdata->tot_file_trans) { gftpui_update_current_file_in_transfer (tdata); memcpy (&updatetime, &tdata->lasttime, sizeof (updatetime)); if (tdata->current_file_retries > 0) tdata->current_file_retries = 0; } } if (num_trans == GFTP_ENOTRANS) num_trans = 0; g_free (buf); gftpui_finish_current_file_in_transfer (tdata); if ((int) num_trans == 0) { if ((ret = gftp_end_transfer (tdata->fromreq)) < 0) return (ret); if ((ret = gftp_end_transfer (tdata->toreq)) < 0) return (ret); tdata->fromreq->logging_function (gftp_logging_misc, tdata->fromreq, _("Successfully transferred %s at %.2f KB/s\n"), curfle->file, tdata->kbs); return (0); } else return ((int) num_trans); }
static GHashTable * gftp_gen_dir_hash (gftp_request * request, int *ret) { GHashTable * dirhash; gftp_file * fle; off_t *newsize; dirhash = g_hash_table_new (string_hash_function, string_hash_compare); *ret = gftp_list_files (request); if (*ret == 0) { fle = g_malloc0 (sizeof (*fle)); while (gftp_get_next_file (request, NULL, fle) > 0) { newsize = g_malloc0 (sizeof (*newsize)); *newsize = fle->size; g_hash_table_insert (dirhash, fle->file, newsize); fle->file = NULL; gftp_file_destroy (fle, 0); } gftp_end_transfer (request); g_free (fle); } else { g_hash_table_destroy (dirhash); dirhash = NULL; } return (dirhash); }
static void _gftpui_common_cmd_transfer_files (void *fromuidata, gftp_request * fromrequest, void *touidata, gftp_request * torequest, const char *cmd, const char *filespec) { gftp_transfer * tdata; gftp_file * fle; if (!GFTP_IS_CONNECTED (fromrequest) || !GFTP_IS_CONNECTED (torequest)) { fromrequest->logging_function (gftp_logging_error, fromrequest, _("Error: Not connected to a remote site\n")); return; } if (*filespec == '\0') { fromrequest->logging_function (gftp_logging_error, fromrequest, _("usage: %s <filespec>\n"), cmd); return; } tdata = gftp_tdata_new (); tdata->fromreq = fromrequest; tdata->toreq = torequest; if (gftp_list_files (tdata->fromreq) != 0) { tdata->fromreq = tdata->toreq = NULL; free_tdata (tdata); return; } fle = g_malloc0 (sizeof (*fle)); while (gftp_get_next_file (tdata->fromreq, filespec, fle) > 0) { if (strcmp (fle->file, ".") == 0 || strcmp (fle->file, "..") == 0) { gftp_file_destroy (fle, 0); continue; } tdata->files = g_list_append (tdata->files, fle); fle = g_malloc0 (sizeof (*fle)); } g_free (fle); gftp_end_transfer (tdata->fromreq); if (tdata->files == NULL) { tdata->fromreq = tdata->toreq = NULL; free_tdata (tdata); return; } if (gftp_get_all_subdirs (tdata, NULL) != 0) { tdata->fromreq = tdata->toreq = NULL; free_tdata (tdata); return; } if (tdata->files == NULL) { tdata->fromreq = tdata->toreq = NULL; free_tdata (tdata); return; } gftpui_common_add_file_transfer (tdata->fromreq, tdata->toreq, fromuidata, touidata, tdata->files); g_free (tdata); return; }
int gftpui_common_run_ls (gftpui_callback_data * cdata) { int got, matched_filespec, have_dotdot, ret; char *sortcol_var, *sortasds_var; intptr_t sortcol, sortasds; gftp_file * fle; ret = gftp_list_files (cdata->request); if (ret < 0) return (ret); have_dotdot = 0; cdata->request->gotbytes = 0; cdata->files = NULL; fle = g_malloc0 (sizeof (*fle)); while ((got = gftp_get_next_file (cdata->request, NULL, fle)) > 0 || got == GFTP_ERETRYABLE) { if (cdata->source_string == NULL) matched_filespec = 1; else matched_filespec = gftp_match_filespec (cdata->request, fle->file, cdata->source_string); if (got < 0 || strcmp (fle->file, ".") == 0 || !matched_filespec) { gftp_file_destroy (fle, 0); continue; } else if (strcmp (fle->file, "..") == 0) have_dotdot = 1; cdata->request->gotbytes += got; cdata->files = g_list_prepend (cdata->files, fle); fle = g_malloc0 (sizeof (*fle)); } g_free (fle); gftp_end_transfer (cdata->request); cdata->request->gotbytes = -1; if (!have_dotdot) { fle = g_malloc0 (sizeof (*fle)); fle->file = g_strdup (".."); fle->user = g_malloc0 (1); fle->group = g_malloc0 (1); fle->st_mode = S_IFDIR | S_IRUSR | S_IWUSR | S_IXUSR; cdata->files = g_list_prepend (cdata->files, fle); } if (cdata->files != NULL) { if (cdata->request->protonum == GFTP_LOCAL_NUM) { sortasds_var = "local_sortasds"; sortcol_var = "local_sortcol"; } else { sortasds_var = "remote_sortasds"; sortcol_var = "remote_sortcol"; } gftp_lookup_global_option (sortcol_var, &sortcol); gftp_lookup_global_option (sortasds_var, &sortasds); cdata->files = gftp_sort_filelist (cdata->files, sortcol, sortasds); } return (1); }
static GList * gftp_get_dir_listing (gftp_transfer * transfer, int getothdir, int *ret) { GHashTable * dirhash; GList * templist; gftp_file * fle; off_t *newsize; char *newname; if (getothdir && transfer->toreq != NULL) { dirhash = gftp_gen_dir_hash (transfer->toreq, ret); if (*ret == GFTP_EFATAL) return (NULL); } else dirhash = NULL; *ret = gftp_list_files (transfer->fromreq); if (*ret < 0) { gftp_destroy_dir_hash (dirhash); return (NULL); } fle = g_malloc0 (sizeof (*fle)); templist = NULL; while (gftp_get_next_file (transfer->fromreq, NULL, fle) > 0) { if (strcmp (fle->file, ".") == 0 || strcmp (fle->file, "..") == 0) { gftp_file_destroy (fle, 0); continue; } if (dirhash && (newsize = g_hash_table_lookup (dirhash, fle->file)) != NULL) { fle->exists_other_side = 1; fle->startsize = *newsize; } else fle->exists_other_side = 0; if (transfer->toreq && fle->destfile == NULL) fle->destfile = gftp_build_path (transfer->toreq, transfer->toreq->directory, fle->file, NULL); if (transfer->fromreq->directory != NULL && *transfer->fromreq->directory != '\0' && *fle->file != '/') { newname = gftp_build_path (transfer->fromreq, transfer->fromreq->directory, fle->file, NULL); g_free (fle->file); fle->file = newname; } templist = g_list_append (templist, fle); fle = g_malloc0 (sizeof (*fle)); } gftp_end_transfer (transfer->fromreq); gftp_file_destroy (fle, 1); gftp_destroy_dir_hash (dirhash); return (templist); }
off_t gftp_transfer_file (gftp_request * fromreq, const char *fromfile, off_t fromsize, gftp_request * toreq, const char *tofile, off_t tosize) { /* Needed for systems that size(float) < size(void *) */ union { intptr_t i; float f; } maxkbs; off_t size; int ret; g_return_val_if_fail (fromreq != NULL, GFTP_EFATAL); g_return_val_if_fail (fromfile != NULL, GFTP_EFATAL); g_return_val_if_fail (toreq != NULL, GFTP_EFATAL); g_return_val_if_fail (tofile != NULL, GFTP_EFATAL); gftp_lookup_request_option (toreq, "maxkbs", &maxkbs.f); if (maxkbs.f > 0) { toreq->logging_function (gftp_logging_misc, toreq, _("File transfer will be throttled to %.2f KB/s\n"), maxkbs.f); } if (fromreq->protonum == toreq->protonum && fromreq->transfer_file != NULL) return (fromreq->transfer_file (fromreq, fromfile, fromsize, toreq, tofile, tosize)); fromreq->cached = 0; toreq->cached = 0; get_file: size = gftp_get_file (fromreq, fromfile, tosize); if (size < 0) { if (size == GFTP_ETIMEDOUT) { ret = gftp_connect (fromreq); if (ret < 0) return (ret); goto get_file; } return (size); } put_file: ret = gftp_put_file (toreq, tofile, tosize, size); if (ret != 0) { if (size == GFTP_ETIMEDOUT) { ret = gftp_connect (fromreq); if (ret < 0) return (ret); goto put_file; } if (gftp_abort_transfer (fromreq) != 0) gftp_end_transfer (fromreq); return (ret); } return (size); }