int gftp_fd_set_sockblocking (gftp_request * request, int fd, int non_blocking) { int flags; g_return_val_if_fail (fd >= 0, GFTP_EFATAL); if ((flags = fcntl (fd, F_GETFL, 0)) < 0) { request->logging_function (gftp_logging_error, request, _("Cannot get socket flags: %s\n"), g_strerror (errno)); gftp_disconnect (request); return (GFTP_ERETRYABLE); } if (non_blocking) flags |= O_NONBLOCK; else flags &= ~O_NONBLOCK; if (fcntl (fd, F_SETFL, flags) < 0) { request->logging_function (gftp_logging_error, request, _("Cannot set socket to non-blocking: %s\n"), g_strerror (errno)); gftp_disconnect (request); return (GFTP_ERETRYABLE); } return (0); }
int gftpui_common_transfer_files (gftp_transfer * tdata) { int ret, skipped_files; tdata->curfle = tdata->files; gftpui_common_num_child_threads++; gettimeofday (&tdata->starttime, NULL); memcpy (&tdata->lasttime, &tdata->starttime, sizeof (tdata->lasttime)); skipped_files = 0; while (tdata->curfle != NULL) { ret = _gftpui_common_trans_file_or_dir (tdata); if (tdata->cancel) { if (gftp_abort_transfer (tdata->toreq) != 0) gftp_disconnect (tdata->toreq); if (gftp_abort_transfer (tdata->fromreq) != 0) gftp_disconnect (tdata->fromreq); } else if (ret == GFTP_EFATAL || ret == GFTP_ECANIGNORE) skipped_files++; else if (ret < 0) { if (gftp_get_transfer_status (tdata, ret) == GFTP_ERETRYABLE) continue; break; } _gftpui_common_next_file_in_trans (tdata); if (tdata->cancel) { if (!tdata->skip_file) break; tdata->cancel = 0; tdata->fromreq->cancel = 0; tdata->toreq->cancel = 0; } } if (skipped_files) tdata->fromreq->logging_function (gftp_logging_error, tdata->fromreq, _("There were %d files or directories that could not be transferred. Check the log for which items were not properly transferred."), skipped_files); tdata->done = 1; gftpui_common_num_child_threads--; return (1); }
static int local_put_file (gftp_request * request, const char *filename, off_t startsize, off_t totalsize) { int flags, perms; size_t destlen; char *utf8; g_return_val_if_fail (request != NULL, GFTP_EFATAL); g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); g_return_val_if_fail (filename != NULL, GFTP_EFATAL); flags = O_WRONLY | O_CREAT; if (startsize > 0) flags |= O_APPEND; #if defined (_LARGEFILE_SOURCE) && defined (O_LARGEFILE) flags |= O_LARGEFILE; #endif perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; utf8 = gftp_filename_from_utf8 (request, filename, &destlen); if (utf8 != NULL) { request->datafd = gftp_fd_open (request, utf8, flags, perms); g_free (utf8); } else request->datafd = gftp_fd_open (request, filename, flags, perms); if (request->datafd == -1) return (GFTP_ERETRYABLE); if (ftruncate (request->datafd, startsize) == -1) { request->logging_function (gftp_logging_error, request, _("Error: Cannot truncate local file %s: %s\n"), filename, g_strerror (errno)); gftp_disconnect (request); return (GFTP_ERETRYABLE); } if (lseek (request->datafd, startsize, SEEK_SET) == -1) { request->logging_function (gftp_logging_error, request, _("Error: Cannot seek on file %s: %s\n"), filename, g_strerror (errno)); gftp_disconnect (request); return (GFTP_ERETRYABLE); } return (0); }
static off_t local_get_file (gftp_request * request, const char *filename, off_t startsize) { size_t destlen; char *utf8; off_t size; int flags; g_return_val_if_fail (request != NULL, GFTP_EFATAL); g_return_val_if_fail (request->protonum == GFTP_LOCAL_NUM, GFTP_EFATAL); g_return_val_if_fail (filename != NULL, GFTP_EFATAL); flags = O_RDONLY; #if defined (_LARGEFILE_SOURCE) && defined (O_LARGEFILE) flags |= O_LARGEFILE; #endif utf8 = gftp_filename_from_utf8 (request, filename, &destlen); if (utf8 != NULL) { request->datafd = gftp_fd_open (request, utf8, flags, 0); g_free (utf8); } else request->datafd = gftp_fd_open (request, filename, flags, 0); if (request->datafd == -1) return (GFTP_ERETRYABLE); if ((size = lseek (request->datafd, 0, SEEK_END)) == -1) { request->logging_function (gftp_logging_error, request, _("Error: Cannot seek on file %s: %s\n"), filename, g_strerror (errno)); gftp_disconnect (request); return (GFTP_ERETRYABLE); } if (lseek (request->datafd, startsize, SEEK_SET) == -1) { request->logging_function (gftp_logging_error, request, _("Error: Cannot seek on file %s: %s\n"), filename, g_strerror (errno)); gftp_disconnect (request); return (GFTP_ERETRYABLE); } return (size); }
static void gftpui_gtk_tdata_disconnect (gftpui_callback_data * cdata) { gftp_transfer * tdata; tdata = cdata->user_data; if (tdata->fromreq != NULL) gftp_disconnect (tdata->fromreq); if (tdata->toreq != NULL) gftp_disconnect (tdata->toreq); cdata->request->datafd = -1; }
static int gftpui_common_cmd_close (void *uidata, gftp_request * request, void *other_uidata, gftp_request * other_request, const char *command) { gftp_disconnect (request); return (1); }
static int fsp_put_file (gftp_request * request, const char *filename, off_t startsize, off_t totalsize) { fsp_protocol_data * lpd; g_return_val_if_fail (request != NULL, GFTP_EFATAL); g_return_val_if_fail (request->protonum == GFTP_FSP_NUM, GFTP_EFATAL); g_return_val_if_fail (filename != NULL, GFTP_EFATAL); lpd = request->protocol_data; g_return_val_if_fail (lpd != NULL,GFTP_EFATAL); g_return_val_if_fail (lpd->fsp != NULL,GFTP_EFATAL); if(lpd->file != NULL) { fsp_fclose(lpd->file); lpd->file=NULL; } if(fsp_canupload(lpd->fsp,filename)) { request->logging_function (gftp_logging_error, request, _("Error: Cannot upload file %s\n"), filename ); return (GFTP_ERETRYABLE); } lpd->file=fsp_fopen(lpd->fsp,filename, "wb"); if(lpd->file == NULL) { request->logging_function (gftp_logging_error, request, _("Error: Cannot write to file %s: %s\n"), filename, g_strerror (errno)); return (GFTP_ERETRYABLE); } if (fsp_fseek (lpd->file, startsize, SEEK_SET) == -1) { request->logging_function (gftp_logging_error, request, _("Error: Cannot seek on file %s: %s\n"), filename, g_strerror (errno)); gftp_disconnect (request); return (GFTP_ERETRYABLE); } return (0); }
void gftp_request_destroy (gftp_request * request, int free_request) { g_return_if_fail (request != NULL); gftp_disconnect (request); if (request->destroy != NULL) request->destroy (request); if (request->hostname) g_free (request->hostname); if (request->username) g_free (request->username); if (request->password) g_free (request->password); if (request->account) g_free (request->account); if (request->directory) g_free (request->directory); if (request->last_ftp_response) g_free (request->last_ftp_response); if (request->protocol_data) g_free (request->protocol_data); #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR) if (request->remote_addr != NULL) g_free (request->remote_addr); #endif if (request->local_options_vars != NULL) { gftp_config_free_options (request->local_options_vars, request->local_options_hash, request->num_local_options_vars); } memset (request, 0, sizeof (*request)); if (free_request) g_free (request); else { request->datafd = -1; request->cachefd = -1; request->server_type = GFTP_DIRTYPE_OTHER; } }
static off_t fsp_get_file (gftp_request * request, const char *filename, off_t startsize) { fsp_protocol_data * lpd; struct stat sb; g_return_val_if_fail (request != NULL,GFTP_EFATAL); g_return_val_if_fail (request->protonum == GFTP_FSP_NUM,GFTP_EFATAL); g_return_val_if_fail (filename != NULL, GFTP_EFATAL); lpd = request->protocol_data; g_return_val_if_fail (lpd != NULL,GFTP_EFATAL); g_return_val_if_fail (lpd->fsp != NULL,GFTP_EFATAL); /* CHECK: close prev. opened file, is this needed? */ if(lpd->file != NULL) { fsp_fclose(lpd->file); lpd->file=NULL; } if(fsp_stat(lpd->fsp,filename,&sb)) return (GFTP_ERETRYABLE); if(!S_ISREG(sb.st_mode)) return (GFTP_ERETRYABLE); lpd->file=fsp_fopen(lpd->fsp,filename,"rb"); if (fsp_fseek (lpd->file, startsize, SEEK_SET) == -1) { request->logging_function (gftp_logging_error, request, _("Error: Cannot seek on file %s: %s\n"), filename, g_strerror (errno)); gftp_disconnect (request); return (GFTP_ERETRYABLE); } return (sb.st_size); }
static void transfer_done (GList * node) { gftpui_common_curtrans_data * transdata; gftp_transfer * tdata; gftp_file * tempfle; GList * templist; tdata = node->data; if (tdata->started) { if (GFTP_IS_SAME_HOST_STOP_TRANS ((gftp_window_data *) tdata->fromwdata, tdata->fromreq)) { gftp_copy_param_options (((gftp_window_data *) tdata->fromwdata)->request, tdata->fromreq); gftp_swap_socks (((gftp_window_data *) tdata->fromwdata)->request, tdata->fromreq); } else gftp_disconnect (tdata->fromreq); if (GFTP_IS_SAME_HOST_STOP_TRANS ((gftp_window_data *) tdata->towdata, tdata->toreq)) { gftp_copy_param_options (((gftp_window_data *) tdata->towdata)->request, tdata->toreq); gftp_swap_socks (((gftp_window_data *) tdata->towdata)->request, tdata->toreq); } else gftp_disconnect (tdata->toreq); if (tdata->towdata != NULL && compare_request (tdata->toreq, ((gftp_window_data *) tdata->towdata)->request, 1)) gftpui_refresh (tdata->towdata, 1); num_transfers_in_progress--; } if ((!tdata->show && tdata->started) || (tdata->done && !tdata->started)) { transdata = gtk_ctree_node_get_row_data (GTK_CTREE (dlwdw), tdata->user_data); if (transdata != NULL) g_free (transdata); for (templist = tdata->files; templist != NULL; templist = templist->next) { tempfle = templist->data; transdata = gtk_ctree_node_get_row_data (GTK_CTREE (dlwdw), tempfle->user_data); if (transdata != NULL) g_free (transdata); } gtk_ctree_remove_node (GTK_CTREE (dlwdw), tdata->user_data); } g_static_mutex_lock (&gftpui_common_transfer_mutex); gftp_file_transfers = g_list_remove_link (gftp_file_transfers, node); g_static_mutex_unlock (&gftpui_common_transfer_mutex); gdk_window_set_title (gtk_widget_get_parent_window (GTK_WIDGET(dlwdw)), gftp_version); free_tdata (tdata); }
ssize_t gftp_fd_write (gftp_request * request, const char *ptr, size_t size, int fd) { intptr_t network_timeout; struct timeval tv; int ret, s_ret; ssize_t w_ret; fd_set fset; g_return_val_if_fail (fd >= 0, GFTP_EFATAL); gftp_lookup_request_option (request, "network_timeout", &network_timeout); errno = 0; ret = 0; FD_ZERO (&fset); do { FD_SET (fd, &fset); tv.tv_sec = network_timeout; tv.tv_usec = 0; s_ret = select (fd + 1, NULL, &fset, NULL, &tv); if (s_ret == -1 && (errno == EINTR || errno == EAGAIN)) { if (request != NULL && request->cancel) { gftp_disconnect (request); return (GFTP_ERETRYABLE); } continue; } else if (s_ret <= 0) { if (request != NULL) { request->logging_function (gftp_logging_error, request, _("Connection to %s timed out\n"), request->hostname); gftp_disconnect (request); } return (GFTP_ERETRYABLE); } w_ret = write (fd, ptr, size); if (w_ret < 0) { if (errno == EINTR || errno == EAGAIN) { if (request != NULL && request->cancel) { gftp_disconnect (request); return (GFTP_ERETRYABLE); } continue; } if (request != NULL) { request->logging_function (gftp_logging_error, request, _("Error: Could not write to socket: %s\n"), g_strerror (errno)); gftp_disconnect (request); } return (GFTP_ERETRYABLE); } ptr += w_ret; size -= w_ret; ret += w_ret; } while (size > 0); return (ret); }
int gftp_get_transfer_status (gftp_transfer * tdata, ssize_t num_read) { intptr_t retries, sleep_time; gftp_file * tempfle; int ret1, ret2; gftp_lookup_request_option (tdata->fromreq, "retries", &retries); gftp_lookup_request_option (tdata->fromreq, "sleep_time", &sleep_time); if (g_thread_supported ()) g_static_mutex_lock (&tdata->structmutex); if (tdata->curfle == NULL) { if (g_thread_supported ()) g_static_mutex_unlock (&tdata->structmutex); return (GFTP_EFATAL); } tempfle = tdata->curfle->data; if (g_thread_supported ()) g_static_mutex_unlock (&tdata->structmutex); gftp_disconnect (tdata->fromreq); gftp_disconnect (tdata->toreq); if (tdata->cancel || num_read == GFTP_EFATAL) return (GFTP_EFATAL); else if (num_read >= 0 && !tdata->skip_file) return (0); if (num_read != GFTP_ETIMEDOUT && !tdata->conn_error_no_timeout) { 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) { /* Look up the options in case the user changes them... */ gftp_lookup_request_option (tdata->fromreq, "retries", &retries); gftp_lookup_request_option (tdata->fromreq, "sleep_time", &sleep_time); if (num_read != GFTP_ETIMEDOUT && !tdata->conn_error_no_timeout && !tdata->skip_file) _do_sleep (sleep_time); tdata->current_file_retries++; ret1 = ret2 = 0; if ((ret1 = gftp_connect (tdata->fromreq)) == 0 && (ret2 = gftp_connect (tdata->toreq)) == 0) { if (g_thread_supported ()) g_static_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); if (g_thread_supported ()) g_static_mutex_unlock (&tdata->structmutex); return (GFTP_ERETRYABLE); } else if (ret1 == GFTP_EFATAL || ret2 == GFTP_EFATAL) { gftp_disconnect (tdata->fromreq); gftp_disconnect (tdata->toreq); return (GFTP_EFATAL); } } return (0); }