mirror of
https://github.com/MidnightCommander/mc
synced 2025-03-13 03:13:08 +03:00
Merge branch '3406_sftp_error_31'
* 3406_sftp_error_31: (panel_operate_init_totals): fix directory size calculation. (panel_operate_init_totals): change the 'source' argument type... sftpfs: handle file operation errors. (sftpfs_close_file): return actual result of sftp file close operation. (sftpfs_waitsocket): refactor and use it for file and directory operations. Clarify usage of sftpfs_internal_stat() return value. sftpfs: refactoring: move initialization of sftp stat operations to separate function. sftpfs: refactoring: move initialization of sftp operation to separate function. (sftpfs_waitsocket): handle socket errors. sftpfs: refactoring: move handling of socket errors to separate function. (sftpfs_fstat): use sftpfs_attr_to_stat(). sftpfs: refactoring: move obtaining of stat info from sftp attributes to separate function. sftpfs: refactoring: move error check to separate function. Fix sftp error 31 (proto 4 and 2) sftp handle LIBSSH2_FX_PERMISSION_DENIED as EACCES. Ticket #3406: sftpfs: fix -31 SFTP Protocol Error when transferring file via SFTP Link.
This commit is contained in:
commit
79b6a772fe
@ -1325,7 +1325,8 @@ panel_compute_totals (const WPanel * panel, dirsize_status_msg_t * sm, size_t *
|
|||||||
|
|
||||||
/** Initialize variables for progress bars */
|
/** Initialize variables for progress bars */
|
||||||
static FileProgressStatus
|
static FileProgressStatus
|
||||||
panel_operate_init_totals (const WPanel * panel, const char *source, file_op_context_t * ctx,
|
panel_operate_init_totals (const WPanel * panel, const vfs_path_t * source,
|
||||||
|
const struct stat *source_stat, file_op_context_t * ctx,
|
||||||
filegui_dialog_type_t dialog_type)
|
filegui_dialog_type_t dialog_type)
|
||||||
{
|
{
|
||||||
FileProgressStatus status;
|
FileProgressStatus status;
|
||||||
@ -1350,15 +1351,18 @@ panel_operate_init_totals (const WPanel * panel, const char *source, file_op_con
|
|||||||
if (source == NULL)
|
if (source == NULL)
|
||||||
status = panel_compute_totals (panel, &dsm, &ctx->progress_count, &ctx->progress_bytes,
|
status = panel_compute_totals (panel, &dsm, &ctx->progress_count, &ctx->progress_bytes,
|
||||||
ctx->follow_links);
|
ctx->follow_links);
|
||||||
else
|
else if (S_ISDIR (source_stat->st_mode))
|
||||||
{
|
{
|
||||||
vfs_path_t *p;
|
|
||||||
size_t dir_count = 0;
|
size_t dir_count = 0;
|
||||||
|
|
||||||
p = vfs_path_from_str (source);
|
status = compute_dir_size (source, &dsm, &dir_count, &ctx->progress_count,
|
||||||
status = compute_dir_size (p, &dsm, &dir_count, &ctx->progress_count,
|
|
||||||
&ctx->progress_bytes, ctx->follow_links);
|
&ctx->progress_bytes, ctx->follow_links);
|
||||||
vfs_path_free (p);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ctx->progress_count++;
|
||||||
|
ctx->progress_bytes += (uintmax_t) source_stat->st_size;
|
||||||
|
status = FILE_CONT;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_msg_deinit (STATUS_MSG (&dsm));
|
status_msg_deinit (STATUS_MSG (&dsm));
|
||||||
@ -2864,8 +2868,8 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl
|
|||||||
else
|
else
|
||||||
source_with_vpath = vfs_path_append_new (panel->cwd_vpath, source, (char *) NULL);
|
source_with_vpath = vfs_path_append_new (panel->cwd_vpath, source, (char *) NULL);
|
||||||
#endif /* WITH_FULL_PATHS */
|
#endif /* WITH_FULL_PATHS */
|
||||||
if (panel_operate_init_totals (panel, vfs_path_as_str (source_with_vpath), ctx, dialog_type)
|
if (panel_operate_init_totals (panel, source_with_vpath, &src_stat, ctx, dialog_type) ==
|
||||||
== FILE_CONT)
|
FILE_CONT)
|
||||||
{
|
{
|
||||||
if (operation == OP_DELETE)
|
if (operation == OP_DELETE)
|
||||||
{
|
{
|
||||||
@ -2958,7 +2962,7 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl
|
|||||||
goto clean_up;
|
goto clean_up;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (panel_operate_init_totals (panel, NULL, ctx, dialog_type) == FILE_CONT)
|
if (panel_operate_init_totals (panel, NULL, NULL, ctx, dialog_type) == FILE_CONT)
|
||||||
{
|
{
|
||||||
/* Loop for every file, perform the actual copy operation */
|
/* Loop for every file, perform the actual copy operation */
|
||||||
for (i = 0; i < panel->dir.len; i++)
|
for (i = 0; i < panel->dir.len; i++)
|
||||||
|
@ -95,14 +95,8 @@ sftpfs_opendir (const vfs_path_t * vpath, GError ** mcerror)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
libssh_errno = libssh2_session_last_errno (super_data->session);
|
libssh_errno = libssh2_session_last_errno (super_data->session);
|
||||||
if (libssh_errno != LIBSSH2_ERROR_EAGAIN)
|
if (!sftpfs_waitsocket (super_data, libssh_errno, mcerror))
|
||||||
{
|
|
||||||
sftpfs_ssherror_to_gliberror (super_data, libssh_errno, mcerror);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
sftpfs_waitsocket (super_data, mcerror);
|
|
||||||
|
|
||||||
mc_return_val_if_error (mcerror, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sftpfs_dir = g_new0 (sftpfs_dir_data_t, 1);
|
sftpfs_dir = g_new0 (sftpfs_dir_data_t, 1);
|
||||||
@ -138,14 +132,8 @@ sftpfs_readdir (void *data, GError ** mcerror)
|
|||||||
if (rc >= 0)
|
if (rc >= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (rc != LIBSSH2_ERROR_EAGAIN)
|
if (!sftpfs_waitsocket (sftpfs_dir->super_data, rc, mcerror))
|
||||||
{
|
|
||||||
sftpfs_ssherror_to_gliberror (sftpfs_dir->super_data, rc, mcerror);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
sftpfs_waitsocket (sftpfs_dir->super_data, mcerror);
|
|
||||||
mc_return_val_if_error (mcerror, NULL);
|
|
||||||
}
|
}
|
||||||
while (rc == LIBSSH2_ERROR_EAGAIN);
|
while (rc == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
|
||||||
@ -221,14 +209,8 @@ sftpfs_mkdir (const vfs_path_t * vpath, mode_t mode, GError ** mcerror)
|
|||||||
if (res >= 0)
|
if (res >= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (res != LIBSSH2_ERROR_EAGAIN)
|
if (!sftpfs_waitsocket (super_data, res, mcerror))
|
||||||
{
|
|
||||||
sftpfs_ssherror_to_gliberror (super_data, res, mcerror);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
sftpfs_waitsocket (super_data, mcerror);
|
|
||||||
mc_return_val_if_error (mcerror, -1);
|
|
||||||
}
|
}
|
||||||
while (res == LIBSSH2_ERROR_EAGAIN);
|
while (res == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
|
||||||
@ -277,14 +259,8 @@ sftpfs_rmdir (const vfs_path_t * vpath, GError ** mcerror)
|
|||||||
if (res >= 0)
|
if (res >= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (res != LIBSSH2_ERROR_EAGAIN)
|
if (!sftpfs_waitsocket (super_data, res, mcerror))
|
||||||
{
|
|
||||||
sftpfs_ssherror_to_gliberror (super_data, res, mcerror);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
sftpfs_waitsocket (super_data, mcerror);
|
|
||||||
mc_return_val_if_error (mcerror, -1);
|
|
||||||
}
|
}
|
||||||
while (res == LIBSSH2_ERROR_EAGAIN);
|
while (res == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
@ -49,6 +50,7 @@ typedef struct
|
|||||||
|
|
||||||
/*** file scope variables ************************************************************************/
|
/*** file scope variables ************************************************************************/
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
/*** file scope functions ************************************************************************/
|
/*** file scope functions ************************************************************************/
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
/**
|
/**
|
||||||
@ -74,6 +76,23 @@ sftpfs_reopen (vfs_file_handler_t * file_handler, GError ** mcerror)
|
|||||||
sftpfs_open_file (file_handler, flags, mode, mcerror);
|
sftpfs_open_file (file_handler, flags, mode, mcerror);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static int
|
||||||
|
sftpfs_file__handle_error (sftpfs_super_data_t * super_data, int sftp_res, GError ** mcerror)
|
||||||
|
{
|
||||||
|
if (sftpfs_is_sftp_error (super_data->sftp_session, sftp_res, LIBSSH2_FX_PERMISSION_DENIED))
|
||||||
|
return -EACCES;
|
||||||
|
|
||||||
|
if (sftpfs_is_sftp_error (super_data->sftp_session, sftp_res, LIBSSH2_FX_NO_SUCH_FILE))
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
if (!sftpfs_waitsocket (super_data, sftp_res, mcerror))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
/*** public functions ****************************************************************************/
|
/*** public functions ****************************************************************************/
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -204,46 +223,19 @@ sftpfs_fstat (void *data, struct stat *buf, GError ** mcerror)
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
res = libssh2_sftp_fstat_ex (sftpfs_fh->handle, &attrs, 0);
|
res = libssh2_sftp_fstat_ex (sftpfs_fh->handle, &attrs, 0);
|
||||||
if (res >= 0)
|
if (res >= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (res != LIBSSH2_ERROR_EAGAIN)
|
err = sftpfs_file__handle_error (super_data, res, mcerror);
|
||||||
{
|
if (err < 0)
|
||||||
sftpfs_ssherror_to_gliberror (super_data, res, mcerror);
|
return err;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sftpfs_waitsocket (super_data, mcerror);
|
|
||||||
mc_return_val_if_error (mcerror, -1);
|
|
||||||
}
|
}
|
||||||
while (res == LIBSSH2_ERROR_EAGAIN);
|
while (res == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
|
||||||
if ((attrs.flags & LIBSSH2_SFTP_ATTR_UIDGID) != 0)
|
sftpfs_attr_to_stat (&attrs, buf);
|
||||||
{
|
|
||||||
buf->st_uid = attrs.uid;
|
|
||||||
buf->st_gid = attrs.gid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((attrs.flags & LIBSSH2_SFTP_ATTR_ACMODTIME) != 0)
|
|
||||||
{
|
|
||||||
buf->st_atime = attrs.atime;
|
|
||||||
buf->st_mtime = attrs.mtime;
|
|
||||||
buf->st_ctime = attrs.mtime;
|
|
||||||
#ifdef HAVE_STRUCT_STAT_ST_MTIM
|
|
||||||
buf->st_atim.tv_nsec = buf->st_mtim.tv_nsec = buf->st_ctim.tv_nsec = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) != 0)
|
|
||||||
{
|
|
||||||
buf->st_size = attrs.filesize;
|
|
||||||
sftpfs_blksize (buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) != 0)
|
|
||||||
buf->st_mode = attrs.permissions;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -281,18 +273,15 @@ sftpfs_read_file (vfs_file_handler_t * file_handler, char *buffer, size_t count,
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
rc = libssh2_sftp_read (file_handler_data->handle, buffer, count);
|
rc = libssh2_sftp_read (file_handler_data->handle, buffer, count);
|
||||||
if (rc >= 0)
|
if (rc >= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (rc != LIBSSH2_ERROR_EAGAIN)
|
err = sftpfs_file__handle_error (super_data, (int) rc, mcerror);
|
||||||
{
|
if (err < 0)
|
||||||
sftpfs_ssherror_to_gliberror (super_data, rc, mcerror);
|
return err;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sftpfs_waitsocket (super_data, mcerror);
|
|
||||||
mc_return_val_if_error (mcerror, -1);
|
|
||||||
}
|
}
|
||||||
while (rc == LIBSSH2_ERROR_EAGAIN);
|
while (rc == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
|
||||||
@ -331,18 +320,15 @@ sftpfs_write_file (vfs_file_handler_t * file_handler, const char *buffer, size_t
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
rc = libssh2_sftp_write (file_handler_data->handle, buffer, count);
|
rc = libssh2_sftp_write (file_handler_data->handle, buffer, count);
|
||||||
if (rc >= 0)
|
if (rc >= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (rc != LIBSSH2_ERROR_EAGAIN)
|
err = sftpfs_file__handle_error (super_data, (int) rc, mcerror);
|
||||||
{
|
if (err < 0)
|
||||||
sftpfs_ssherror_to_gliberror (super_data, rc, mcerror);
|
return err;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sftpfs_waitsocket (super_data, mcerror);
|
|
||||||
mc_return_val_if_error (mcerror, -1);
|
|
||||||
}
|
}
|
||||||
while (rc == LIBSSH2_ERROR_EAGAIN);
|
while (rc == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
|
||||||
@ -364,17 +350,18 @@ int
|
|||||||
sftpfs_close_file (vfs_file_handler_t * file_handler, GError ** mcerror)
|
sftpfs_close_file (vfs_file_handler_t * file_handler, GError ** mcerror)
|
||||||
{
|
{
|
||||||
sftpfs_file_handler_data_t *file_handler_data;
|
sftpfs_file_handler_data_t *file_handler_data;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
mc_return_val_if_error (mcerror, -1);
|
mc_return_val_if_error (mcerror, -1);
|
||||||
|
|
||||||
file_handler_data = (sftpfs_file_handler_data_t *) file_handler->data;
|
file_handler_data = (sftpfs_file_handler_data_t *) file_handler->data;
|
||||||
if (file_handler_data == NULL)
|
if (file_handler_data != NULL)
|
||||||
return -1;
|
{
|
||||||
|
ret = libssh2_sftp_close (file_handler_data->handle);
|
||||||
|
g_free (file_handler_data);
|
||||||
|
}
|
||||||
|
|
||||||
libssh2_sftp_close (file_handler_data->handle);
|
return ret;
|
||||||
|
|
||||||
g_free (file_handler_data);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
@ -42,11 +42,156 @@ GString *sftpfs_filename_buffer = NULL;
|
|||||||
|
|
||||||
/*** file scope variables ************************************************************************/
|
/*** file scope variables ************************************************************************/
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
/*** file scope functions ************************************************************************/
|
/*** file scope functions ************************************************************************/
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Adjust block size and number of blocks */
|
||||||
|
|
||||||
|
static void
|
||||||
|
sftpfs_blksize (struct stat *s)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
|
||||||
|
s->st_blksize = LIBSSH2_CHANNEL_WINDOW_DEFAULT; /* FIXME */
|
||||||
|
#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
|
||||||
|
vfs_adjust_stat (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* Awaiting for any activity on socket.
|
||||||
|
*
|
||||||
|
* @param super_data extra data for SFTP connection
|
||||||
|
* @param mcerror pointer to the error object
|
||||||
|
* @return 0 if success, negative value otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
sftpfs_internal_waitsocket (sftpfs_super_data_t * super_data, GError ** mcerror)
|
||||||
|
{
|
||||||
|
struct timeval timeout = { 10, 0 };
|
||||||
|
fd_set fd;
|
||||||
|
fd_set *writefd = NULL;
|
||||||
|
fd_set *readfd = NULL;
|
||||||
|
int dir, ret;
|
||||||
|
|
||||||
|
mc_return_val_if_error (mcerror, -1);
|
||||||
|
|
||||||
|
FD_ZERO (&fd);
|
||||||
|
FD_SET (super_data->socket_handle, &fd);
|
||||||
|
|
||||||
|
/* now make sure we wait in the correct direction */
|
||||||
|
dir = libssh2_session_block_directions (super_data->session);
|
||||||
|
|
||||||
|
if ((dir & LIBSSH2_SESSION_BLOCK_INBOUND) != 0)
|
||||||
|
readfd = &fd;
|
||||||
|
|
||||||
|
if ((dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) != 0)
|
||||||
|
writefd = &fd;
|
||||||
|
|
||||||
|
ret = select (super_data->socket_handle + 1, readfd, writefd, NULL, &timeout);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
int my_errno = errno;
|
||||||
|
|
||||||
|
mc_propagate_error (mcerror, my_errno, _("sftp: socket error: %s"),
|
||||||
|
unix_error_string (my_errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
sftpfs_op_init (sftpfs_super_data_t ** super_data, const vfs_path_element_t ** path_element,
|
||||||
|
const vfs_path_t * vpath, GError ** mcerror)
|
||||||
|
{
|
||||||
|
struct vfs_s_super *super = NULL;
|
||||||
|
|
||||||
|
mc_return_val_if_error (mcerror, FALSE);
|
||||||
|
|
||||||
|
if (vfs_s_get_path (vpath, &super, 0) == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (super == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
*super_data = (sftpfs_super_data_t *) super->data;
|
||||||
|
|
||||||
|
if ((*super_data)->sftp_session == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
*path_element = vfs_path_get_by_index (vpath, -1);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static int
|
||||||
|
sftpfs_stat_init (sftpfs_super_data_t ** super_data, const vfs_path_element_t ** path_element,
|
||||||
|
const vfs_path_t * vpath, GError ** mcerror, int stat_type,
|
||||||
|
LIBSSH2_SFTP_ATTRIBUTES * attrs)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (!sftpfs_op_init (super_data, path_element, vpath, mcerror))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
const char *fixfname;
|
||||||
|
unsigned int fixfname_len;
|
||||||
|
|
||||||
|
fixfname = sftpfs_fix_filename ((*path_element)->path, &fixfname_len);
|
||||||
|
|
||||||
|
res = libssh2_sftp_stat_ex ((*super_data)->sftp_session, fixfname, fixfname_len,
|
||||||
|
stat_type, attrs);
|
||||||
|
if (res >= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (sftpfs_is_sftp_error ((*super_data)->sftp_session, res, LIBSSH2_FX_PERMISSION_DENIED))
|
||||||
|
return -EACCES;
|
||||||
|
|
||||||
|
if (sftpfs_is_sftp_error ((*super_data)->sftp_session, res, LIBSSH2_FX_NO_SUCH_FILE))
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
if (!sftpfs_waitsocket (*super_data, res, mcerror))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
while (res == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
/*** public functions ****************************************************************************/
|
/*** public functions ****************************************************************************/
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
sftpfs_waitsocket (sftpfs_super_data_t * super_data, int sftp_res, GError ** mcerror)
|
||||||
|
{
|
||||||
|
if (sftp_res != LIBSSH2_ERROR_EAGAIN)
|
||||||
|
{
|
||||||
|
sftpfs_ssherror_to_gliberror (super_data, sftp_res, mcerror);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
sftpfs_internal_waitsocket (super_data, mcerror);
|
||||||
|
|
||||||
|
return (mcerror == NULL || *mcerror == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
sftpfs_is_sftp_error (LIBSSH2_SFTP * sftp_session, int sftp_res, int sftp_error)
|
||||||
|
{
|
||||||
|
return (sftp_res == LIBSSH2_ERROR_SFTP_PROTOCOL &&
|
||||||
|
libssh2_sftp_last_error (sftp_session) == (unsigned long) sftp_error);
|
||||||
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
/**
|
/**
|
||||||
* Convert libssh error to GError object.
|
* Convert libssh error to GError object.
|
||||||
@ -65,7 +210,11 @@ sftpfs_ssherror_to_gliberror (sftpfs_super_data_t * super_data, int libssh_errno
|
|||||||
mc_return_if_error (mcerror);
|
mc_return_if_error (mcerror);
|
||||||
|
|
||||||
libssh2_session_last_error (super_data->session, &err, &err_len, 1);
|
libssh2_session_last_error (super_data->session, &err, &err_len, 1);
|
||||||
mc_propagate_error (mcerror, libssh_errno, "%s", err);
|
if (libssh_errno == LIBSSH2_ERROR_SFTP_PROTOCOL && super_data->sftp_session != NULL)
|
||||||
|
mc_propagate_error (mcerror, libssh_errno, "%s %lu", err,
|
||||||
|
libssh2_sftp_last_error (super_data->sftp_session));
|
||||||
|
else
|
||||||
|
mc_propagate_error (mcerror, libssh_errno, "%s", err);
|
||||||
g_free (err);
|
g_free (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,51 +237,34 @@ sftpfs_fix_filename (const char *file_name, unsigned int *length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
/**
|
|
||||||
* Awaiting for any activity on socket.
|
|
||||||
*
|
|
||||||
* @param super_data extra data for SFTP connection
|
|
||||||
* @param mcerror pointer to the error object
|
|
||||||
* @return 0 if success, negative value otherwise
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
sftpfs_waitsocket (sftpfs_super_data_t * super_data, GError ** mcerror)
|
|
||||||
{
|
|
||||||
struct timeval timeout = { 10, 0 };
|
|
||||||
fd_set fd;
|
|
||||||
fd_set *writefd = NULL;
|
|
||||||
fd_set *readfd = NULL;
|
|
||||||
int dir;
|
|
||||||
|
|
||||||
mc_return_val_if_error (mcerror, -1);
|
|
||||||
|
|
||||||
FD_ZERO (&fd);
|
|
||||||
FD_SET (super_data->socket_handle, &fd);
|
|
||||||
|
|
||||||
/* now make sure we wait in the correct direction */
|
|
||||||
dir = libssh2_session_block_directions (super_data->session);
|
|
||||||
|
|
||||||
if ((dir & LIBSSH2_SESSION_BLOCK_INBOUND) != 0)
|
|
||||||
readfd = &fd;
|
|
||||||
|
|
||||||
if ((dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) != 0)
|
|
||||||
writefd = &fd;
|
|
||||||
|
|
||||||
return select (super_data->socket_handle + 1, readfd, writefd, NULL, &timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* Adjust block size and number of blocks */
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sftpfs_blksize (struct stat *s)
|
sftpfs_attr_to_stat (const LIBSSH2_SFTP_ATTRIBUTES * attrs, struct stat *s)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
|
if ((attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) != 0)
|
||||||
s->st_blksize = LIBSSH2_CHANNEL_WINDOW_DEFAULT; /* FIXME */
|
{
|
||||||
#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
|
s->st_uid = attrs->uid;
|
||||||
vfs_adjust_stat (s);
|
s->st_gid = attrs->gid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) != 0)
|
||||||
|
{
|
||||||
|
s->st_atime = attrs->atime;
|
||||||
|
s->st_mtime = attrs->mtime;
|
||||||
|
s->st_ctime = attrs->mtime;
|
||||||
|
#ifdef HAVE_STRUCT_STAT_ST_MTIM
|
||||||
|
s->st_atim.tv_nsec = s->st_mtim.tv_nsec = s->st_ctim.tv_nsec = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) != 0)
|
||||||
|
{
|
||||||
|
s->st_size = attrs->filesize;
|
||||||
|
sftpfs_blksize (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) != 0)
|
||||||
|
s->st_mode = attrs->permissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -148,76 +280,19 @@ sftpfs_blksize (struct stat *s)
|
|||||||
int
|
int
|
||||||
sftpfs_lstat (const vfs_path_t * vpath, struct stat *buf, GError ** mcerror)
|
sftpfs_lstat (const vfs_path_t * vpath, struct stat *buf, GError ** mcerror)
|
||||||
{
|
{
|
||||||
struct vfs_s_super *super;
|
sftpfs_super_data_t *super_data = NULL;
|
||||||
sftpfs_super_data_t *super_data;
|
const vfs_path_element_t *path_element = NULL;
|
||||||
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
||||||
int res;
|
int res;
|
||||||
const vfs_path_element_t *path_element;
|
|
||||||
|
|
||||||
mc_return_val_if_error (mcerror, -1);
|
res = sftpfs_stat_init (&super_data, &path_element, vpath, mcerror, LIBSSH2_SFTP_LSTAT, &attrs);
|
||||||
|
if (res >= 0)
|
||||||
path_element = vfs_path_get_by_index (vpath, -1);
|
|
||||||
|
|
||||||
if (vfs_s_get_path (vpath, &super, 0) == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (super == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
super_data = (sftpfs_super_data_t *) super->data;
|
|
||||||
if (super_data->sftp_session == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
const char *fixfname;
|
sftpfs_attr_to_stat (&attrs, buf);
|
||||||
unsigned int fixfname_len = 0;
|
res = 0;
|
||||||
|
|
||||||
fixfname = sftpfs_fix_filename (path_element->path, &fixfname_len);
|
|
||||||
|
|
||||||
res =
|
|
||||||
libssh2_sftp_stat_ex (super_data->sftp_session, fixfname, fixfname_len,
|
|
||||||
LIBSSH2_SFTP_LSTAT, &attrs);
|
|
||||||
if (res >= 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (res != LIBSSH2_ERROR_EAGAIN)
|
|
||||||
{
|
|
||||||
sftpfs_ssherror_to_gliberror (super_data, res, mcerror);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sftpfs_waitsocket (super_data, mcerror);
|
|
||||||
mc_return_val_if_error (mcerror, -1);
|
|
||||||
}
|
|
||||||
while (res == LIBSSH2_ERROR_EAGAIN);
|
|
||||||
|
|
||||||
if ((attrs.flags & LIBSSH2_SFTP_ATTR_UIDGID) != 0)
|
|
||||||
{
|
|
||||||
buf->st_uid = attrs.uid;
|
|
||||||
buf->st_gid = attrs.gid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((attrs.flags & LIBSSH2_SFTP_ATTR_ACMODTIME) != 0)
|
return res;
|
||||||
{
|
|
||||||
buf->st_atime = attrs.atime;
|
|
||||||
buf->st_mtime = attrs.mtime;
|
|
||||||
buf->st_ctime = attrs.mtime;
|
|
||||||
#ifdef HAVE_STRUCT_STAT_ST_MTIM
|
|
||||||
buf->st_atim.tv_nsec = buf->st_mtim.tv_nsec = buf->st_ctim.tv_nsec = 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) != 0)
|
|
||||||
{
|
|
||||||
buf->st_size = attrs.filesize;
|
|
||||||
sftpfs_blksize (buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) != 0)
|
|
||||||
buf->st_mode = attrs.permissions;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -233,77 +308,20 @@ sftpfs_lstat (const vfs_path_t * vpath, struct stat *buf, GError ** mcerror)
|
|||||||
int
|
int
|
||||||
sftpfs_stat (const vfs_path_t * vpath, struct stat *buf, GError ** mcerror)
|
sftpfs_stat (const vfs_path_t * vpath, struct stat *buf, GError ** mcerror)
|
||||||
{
|
{
|
||||||
struct vfs_s_super *super;
|
sftpfs_super_data_t *super_data = NULL;
|
||||||
sftpfs_super_data_t *super_data;
|
const vfs_path_element_t *path_element = NULL;
|
||||||
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
||||||
int res;
|
int res;
|
||||||
const vfs_path_element_t *path_element;
|
|
||||||
|
|
||||||
mc_return_val_if_error (mcerror, -1);
|
res = sftpfs_stat_init (&super_data, &path_element, vpath, mcerror, LIBSSH2_SFTP_STAT, &attrs);
|
||||||
|
if (res >= 0)
|
||||||
path_element = vfs_path_get_by_index (vpath, -1);
|
|
||||||
|
|
||||||
if (vfs_s_get_path (vpath, &super, 0) == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (super == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
super_data = (sftpfs_super_data_t *) super->data;
|
|
||||||
if (super_data->sftp_session == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
const char *fixfname;
|
buf->st_nlink = 1;
|
||||||
unsigned int fixfname_len = 0;
|
sftpfs_attr_to_stat (&attrs, buf);
|
||||||
|
res = 0;
|
||||||
fixfname = sftpfs_fix_filename (path_element->path, &fixfname_len);
|
|
||||||
|
|
||||||
res =
|
|
||||||
libssh2_sftp_stat_ex (super_data->sftp_session, fixfname, fixfname_len,
|
|
||||||
LIBSSH2_SFTP_STAT, &attrs);
|
|
||||||
if (res >= 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (res != LIBSSH2_ERROR_EAGAIN)
|
|
||||||
{
|
|
||||||
sftpfs_ssherror_to_gliberror (super_data, res, mcerror);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sftpfs_waitsocket (super_data, mcerror);
|
|
||||||
mc_return_val_if_error (mcerror, -1);
|
|
||||||
}
|
|
||||||
while (res == LIBSSH2_ERROR_EAGAIN);
|
|
||||||
|
|
||||||
buf->st_nlink = 1;
|
|
||||||
if ((attrs.flags & LIBSSH2_SFTP_ATTR_UIDGID) != 0)
|
|
||||||
{
|
|
||||||
buf->st_uid = attrs.uid;
|
|
||||||
buf->st_gid = attrs.gid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((attrs.flags & LIBSSH2_SFTP_ATTR_ACMODTIME) != 0)
|
return res;
|
||||||
{
|
|
||||||
buf->st_atime = attrs.atime;
|
|
||||||
buf->st_mtime = attrs.mtime;
|
|
||||||
buf->st_ctime = attrs.mtime;
|
|
||||||
#ifdef HAVE_STRUCT_STAT_ST_MTIM
|
|
||||||
buf->st_atim.tv_nsec = buf->st_mtim.tv_nsec = buf->st_ctim.tv_nsec = 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) != 0)
|
|
||||||
{
|
|
||||||
buf->st_size = attrs.filesize;
|
|
||||||
sftpfs_blksize (buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) != 0)
|
|
||||||
buf->st_mode = attrs.permissions;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -320,23 +338,11 @@ sftpfs_stat (const vfs_path_t * vpath, struct stat *buf, GError ** mcerror)
|
|||||||
int
|
int
|
||||||
sftpfs_readlink (const vfs_path_t * vpath, char *buf, size_t size, GError ** mcerror)
|
sftpfs_readlink (const vfs_path_t * vpath, char *buf, size_t size, GError ** mcerror)
|
||||||
{
|
{
|
||||||
struct vfs_s_super *super;
|
sftpfs_super_data_t *super_data = NULL;
|
||||||
sftpfs_super_data_t *super_data;
|
const vfs_path_element_t *path_element = NULL;
|
||||||
int res;
|
int res;
|
||||||
const vfs_path_element_t *path_element;
|
|
||||||
|
|
||||||
mc_return_val_if_error (mcerror, -1);
|
if (!sftpfs_op_init (&super_data, &path_element, vpath, mcerror))
|
||||||
|
|
||||||
path_element = vfs_path_get_by_index (vpath, -1);
|
|
||||||
|
|
||||||
if (vfs_s_get_path (vpath, &super, 0) == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (super == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
super_data = (sftpfs_super_data_t *) super->data;
|
|
||||||
if (super_data->sftp_session == NULL)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
do
|
do
|
||||||
@ -352,14 +358,8 @@ sftpfs_readlink (const vfs_path_t * vpath, char *buf, size_t size, GError ** mce
|
|||||||
if (res >= 0)
|
if (res >= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (res != LIBSSH2_ERROR_EAGAIN)
|
if (!sftpfs_waitsocket (super_data, res, mcerror))
|
||||||
{
|
|
||||||
sftpfs_ssherror_to_gliberror (super_data, res, mcerror);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
sftpfs_waitsocket (super_data, mcerror);
|
|
||||||
mc_return_val_if_error (mcerror, -1);
|
|
||||||
}
|
}
|
||||||
while (res == LIBSSH2_ERROR_EAGAIN);
|
while (res == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
|
||||||
@ -379,26 +379,14 @@ sftpfs_readlink (const vfs_path_t * vpath, char *buf, size_t size, GError ** mce
|
|||||||
int
|
int
|
||||||
sftpfs_symlink (const vfs_path_t * vpath1, const vfs_path_t * vpath2, GError ** mcerror)
|
sftpfs_symlink (const vfs_path_t * vpath1, const vfs_path_t * vpath2, GError ** mcerror)
|
||||||
{
|
{
|
||||||
struct vfs_s_super *super;
|
sftpfs_super_data_t *super_data = NULL;
|
||||||
sftpfs_super_data_t *super_data;
|
|
||||||
const vfs_path_element_t *path_element1;
|
const vfs_path_element_t *path_element1;
|
||||||
const vfs_path_element_t *path_element2;
|
const vfs_path_element_t *path_element2 = NULL;
|
||||||
char *tmp_path;
|
char *tmp_path;
|
||||||
unsigned int tmp_path_len;
|
unsigned int tmp_path_len;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
mc_return_val_if_error (mcerror, -1);
|
if (!sftpfs_op_init (&super_data, &path_element2, vpath2, mcerror))
|
||||||
|
|
||||||
path_element2 = vfs_path_get_by_index (vpath2, -1);
|
|
||||||
|
|
||||||
if (vfs_s_get_path (vpath2, &super, 0) == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (super == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
super_data = (sftpfs_super_data_t *) super->data;
|
|
||||||
if (super_data->sftp_session == NULL)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
tmp_path = (char *) sftpfs_fix_filename (path_element2->path, &tmp_path_len);
|
tmp_path = (char *) sftpfs_fix_filename (path_element2->path, &tmp_path_len);
|
||||||
@ -419,15 +407,7 @@ sftpfs_symlink (const vfs_path_t * vpath1, const vfs_path_t * vpath2, GError **
|
|||||||
if (res >= 0)
|
if (res >= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (res != LIBSSH2_ERROR_EAGAIN)
|
if (!sftpfs_waitsocket (super_data, res, mcerror))
|
||||||
{
|
|
||||||
sftpfs_ssherror_to_gliberror (super_data, res, mcerror);
|
|
||||||
g_free (tmp_path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sftpfs_waitsocket (super_data, mcerror);
|
|
||||||
if (mcerror != NULL && *mcerror != NULL)
|
|
||||||
{
|
{
|
||||||
g_free (tmp_path);
|
g_free (tmp_path);
|
||||||
return -1;
|
return -1;
|
||||||
@ -452,49 +432,14 @@ sftpfs_symlink (const vfs_path_t * vpath1, const vfs_path_t * vpath2, GError **
|
|||||||
int
|
int
|
||||||
sftpfs_chmod (const vfs_path_t * vpath, mode_t mode, GError ** mcerror)
|
sftpfs_chmod (const vfs_path_t * vpath, mode_t mode, GError ** mcerror)
|
||||||
{
|
{
|
||||||
struct vfs_s_super *super;
|
sftpfs_super_data_t *super_data = NULL;
|
||||||
sftpfs_super_data_t *super_data;
|
const vfs_path_element_t *path_element = NULL;
|
||||||
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
||||||
int res;
|
int res;
|
||||||
const vfs_path_element_t *path_element;
|
|
||||||
|
|
||||||
mc_return_val_if_error (mcerror, -1);
|
res = sftpfs_stat_init (&super_data, &path_element, vpath, mcerror, LIBSSH2_SFTP_LSTAT, &attrs);
|
||||||
|
if (res < 0)
|
||||||
path_element = vfs_path_get_by_index (vpath, -1);
|
return res;
|
||||||
|
|
||||||
if (vfs_s_get_path (vpath, &super, 0) == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (super == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
super_data = (sftpfs_super_data_t *) super->data;
|
|
||||||
if (super_data->sftp_session == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
const char *fixfname;
|
|
||||||
unsigned int fixfname_len = 0;
|
|
||||||
|
|
||||||
fixfname = sftpfs_fix_filename (path_element->path, &fixfname_len);
|
|
||||||
|
|
||||||
res =
|
|
||||||
libssh2_sftp_stat_ex (super_data->sftp_session, fixfname, fixfname_len,
|
|
||||||
LIBSSH2_SFTP_LSTAT, &attrs);
|
|
||||||
if (res >= 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (res != LIBSSH2_ERROR_EAGAIN)
|
|
||||||
{
|
|
||||||
sftpfs_ssherror_to_gliberror (super_data, res, mcerror);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sftpfs_waitsocket (super_data, mcerror);
|
|
||||||
mc_return_val_if_error (mcerror, -1);
|
|
||||||
}
|
|
||||||
while (res == LIBSSH2_ERROR_EAGAIN);
|
|
||||||
|
|
||||||
attrs.permissions = mode;
|
attrs.permissions = mode;
|
||||||
|
|
||||||
@ -511,16 +456,20 @@ sftpfs_chmod (const vfs_path_t * vpath, mode_t mode, GError ** mcerror)
|
|||||||
if (res >= 0)
|
if (res >= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (res != LIBSSH2_ERROR_EAGAIN)
|
if (sftpfs_is_sftp_error (super_data->sftp_session, res, LIBSSH2_FX_NO_SUCH_FILE))
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
if (sftpfs_is_sftp_error (super_data->sftp_session, res, LIBSSH2_FX_FAILURE))
|
||||||
{
|
{
|
||||||
sftpfs_ssherror_to_gliberror (super_data, res, mcerror);
|
res = 0; /* need something like ftpfs_ignore_chattr_errors */
|
||||||
return -1;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sftpfs_waitsocket (super_data, mcerror);
|
if (!sftpfs_waitsocket (super_data, res, mcerror))
|
||||||
mc_return_val_if_error (mcerror, -1);
|
return -1;
|
||||||
}
|
}
|
||||||
while (res == LIBSSH2_ERROR_EAGAIN);
|
while (res == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,23 +485,11 @@ sftpfs_chmod (const vfs_path_t * vpath, mode_t mode, GError ** mcerror)
|
|||||||
int
|
int
|
||||||
sftpfs_unlink (const vfs_path_t * vpath, GError ** mcerror)
|
sftpfs_unlink (const vfs_path_t * vpath, GError ** mcerror)
|
||||||
{
|
{
|
||||||
struct vfs_s_super *super;
|
sftpfs_super_data_t *super_data = NULL;
|
||||||
sftpfs_super_data_t *super_data;
|
const vfs_path_element_t *path_element = NULL;
|
||||||
int res;
|
int res;
|
||||||
const vfs_path_element_t *path_element;
|
|
||||||
|
|
||||||
mc_return_val_if_error (mcerror, -1);
|
if (!sftpfs_op_init (&super_data, &path_element, vpath, mcerror))
|
||||||
|
|
||||||
path_element = vfs_path_get_by_index (vpath, -1);
|
|
||||||
|
|
||||||
if (vfs_s_get_path (vpath, &super, 0) == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (super == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
super_data = (sftpfs_super_data_t *) super->data;
|
|
||||||
if (super_data->sftp_session == NULL)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
do
|
do
|
||||||
@ -566,14 +503,8 @@ sftpfs_unlink (const vfs_path_t * vpath, GError ** mcerror)
|
|||||||
if (res >= 0)
|
if (res >= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (res != LIBSSH2_ERROR_EAGAIN)
|
if (!sftpfs_waitsocket (super_data, res, mcerror))
|
||||||
{
|
|
||||||
sftpfs_ssherror_to_gliberror (super_data, res, mcerror);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
sftpfs_waitsocket (super_data, mcerror);
|
|
||||||
mc_return_val_if_error (mcerror, -1);
|
|
||||||
}
|
}
|
||||||
while (res == LIBSSH2_ERROR_EAGAIN);
|
while (res == LIBSSH2_ERROR_EAGAIN);
|
||||||
|
|
||||||
@ -593,25 +524,14 @@ sftpfs_unlink (const vfs_path_t * vpath, GError ** mcerror)
|
|||||||
int
|
int
|
||||||
sftpfs_rename (const vfs_path_t * vpath1, const vfs_path_t * vpath2, GError ** mcerror)
|
sftpfs_rename (const vfs_path_t * vpath1, const vfs_path_t * vpath2, GError ** mcerror)
|
||||||
{
|
{
|
||||||
struct vfs_s_super *super;
|
sftpfs_super_data_t *super_data = NULL;
|
||||||
sftpfs_super_data_t *super_data;
|
|
||||||
const vfs_path_element_t *path_element1;
|
const vfs_path_element_t *path_element1;
|
||||||
const vfs_path_element_t *path_element2;
|
const vfs_path_element_t *path_element2 = NULL;
|
||||||
char *tmp_path;
|
char *tmp_path;
|
||||||
unsigned int tmp_path_len;
|
unsigned int tmp_path_len;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
mc_return_val_if_error (mcerror, -1);
|
if (!sftpfs_op_init (&super_data, &path_element2, vpath2, mcerror))
|
||||||
path_element2 = vfs_path_get_by_index (vpath2, -1);
|
|
||||||
|
|
||||||
if (vfs_s_get_path (vpath2, &super, 0) == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (super == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
super_data = (sftpfs_super_data_t *) super->data;
|
|
||||||
if (super_data->sftp_session == NULL)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
tmp_path = (char *) sftpfs_fix_filename (path_element2->path, &tmp_path_len);
|
tmp_path = (char *) sftpfs_fix_filename (path_element2->path, &tmp_path_len);
|
||||||
@ -632,15 +552,7 @@ sftpfs_rename (const vfs_path_t * vpath1, const vfs_path_t * vpath2, GError ** m
|
|||||||
if (res >= 0)
|
if (res >= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (res != LIBSSH2_ERROR_EAGAIN)
|
if (!sftpfs_waitsocket (super_data, res, mcerror))
|
||||||
{
|
|
||||||
sftpfs_ssherror_to_gliberror (super_data, res, mcerror);
|
|
||||||
g_free (tmp_path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sftpfs_waitsocket (super_data, mcerror);
|
|
||||||
if (mcerror != NULL && *mcerror != NULL)
|
|
||||||
{
|
{
|
||||||
g_free (tmp_path);
|
g_free (tmp_path);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -66,12 +66,13 @@ void sftpfs_init_subclass_callbacks (void);
|
|||||||
void sftpfs_init_config_variables_patterns (void);
|
void sftpfs_init_config_variables_patterns (void);
|
||||||
void sftpfs_deinit_config_variables_patterns (void);
|
void sftpfs_deinit_config_variables_patterns (void);
|
||||||
|
|
||||||
|
gboolean sftpfs_is_sftp_error (LIBSSH2_SFTP * sftp_session, int sftp_res, int sftp_error);
|
||||||
void sftpfs_ssherror_to_gliberror (sftpfs_super_data_t * super_data, int libssh_errno,
|
void sftpfs_ssherror_to_gliberror (sftpfs_super_data_t * super_data, int libssh_errno,
|
||||||
GError ** mcerror);
|
GError ** mcerror);
|
||||||
int sftpfs_waitsocket (sftpfs_super_data_t * super_data, GError ** mcerror);
|
gboolean sftpfs_waitsocket (sftpfs_super_data_t * super_data, int sftp_res, GError ** mcerror);
|
||||||
|
|
||||||
const char *sftpfs_fix_filename (const char *file_name, unsigned int *length);
|
const char *sftpfs_fix_filename (const char *file_name, unsigned int *length);
|
||||||
void sftpfs_blksize (struct stat *s);
|
void sftpfs_attr_to_stat (const LIBSSH2_SFTP_ATTRIBUTES * attrs, struct stat *s);
|
||||||
int sftpfs_lstat (const vfs_path_t * vpath, struct stat *buf, GError ** mcerror);
|
int sftpfs_lstat (const vfs_path_t * vpath, struct stat *buf, GError ** mcerror);
|
||||||
int sftpfs_stat (const vfs_path_t * vpath, struct stat *buf, GError ** mcerror);
|
int sftpfs_stat (const vfs_path_t * vpath, struct stat *buf, GError ** mcerror);
|
||||||
int sftpfs_readlink (const vfs_path_t * vpath, char *buf, size_t size, GError ** mcerror);
|
int sftpfs_readlink (const vfs_path_t * vpath, char *buf, size_t size, GError ** mcerror);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user