int 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; const vfs_path_element_t *path_element1; const vfs_path_element_t *path_element2; char *tmp_path; int res; mc_return_val_if_error (mcerror, -1); 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; tmp_path = g_strdup_printf ("%c%s", PATH_SEP, path_element2->path); path_element1 = vfs_path_get_by_index (vpath1, -1); do { const char *fixfname; fixfname = sftpfs_fix_filename (path_element1->path); res = libssh2_sftp_symlink_ex (super_data->sftp_session, fixfname, sftpfs_filename_buffer->len, tmp_path, strlen (tmp_path), LIBSSH2_SFTP_SYMLINK); if (res >= 0) break; if (res != LIBSSH2_ERROR_EAGAIN) { 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); return -1; } } while (res == LIBSSH2_ERROR_EAGAIN); g_free (tmp_path); return 0; }
int sftpfs_unlink (const vfs_path_t * vpath, GError ** mcerror) { struct vfs_s_super *super; sftpfs_super_data_t *super_data; int res; const vfs_path_element_t *path_element; mc_return_val_if_error (mcerror, -1); 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; fixfname = sftpfs_fix_filename (path_element->path); res = libssh2_sftp_unlink_ex (super_data->sftp_session, fixfname, sftpfs_filename_buffer->len); 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); return res; }
int sftpfs_mkdir (const vfs_path_t * vpath, mode_t mode, GError ** error) { int res; struct vfs_s_super *super; sftpfs_super_data_t *super_data; const vfs_path_element_t *path_element; 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; fixfname = sftpfs_fix_filename (path_element->path); res = libssh2_sftp_mkdir_ex (super_data->sftp_session, fixfname, sftpfs_filename_buffer->len, mode); if (res >= 0) break; if (res != LIBSSH2_ERROR_EAGAIN) { sftpfs_ssherror_to_gliberror (super_data, res, error); return -1; } sftpfs_waitsocket (super_data, error); if (error != NULL && *error != NULL) return -1; } while (res == LIBSSH2_ERROR_EAGAIN); return res; }
void * sftpfs_opendir (const vfs_path_t * vpath, GError ** error) { sftpfs_dir_data_t *sftpfs_dir; struct vfs_s_super *super; sftpfs_super_data_t *super_data; const vfs_path_element_t *path_element; LIBSSH2_SFTP_HANDLE *handle; path_element = vfs_path_get_by_index (vpath, -1); if (vfs_s_get_path (vpath, &super, 0) == NULL) return NULL; super_data = (sftpfs_super_data_t *) super->data; while (TRUE) { int libssh_errno; handle = libssh2_sftp_opendir (super_data->sftp_session, sftpfs_fix_filename (path_element->path)); if (handle != NULL) break; libssh_errno = libssh2_session_last_errno (super_data->session); if (libssh_errno != LIBSSH2_ERROR_EAGAIN) { sftpfs_ssherror_to_gliberror (super_data, libssh_errno, error); return NULL; } sftpfs_waitsocket (super_data, error); if (error != NULL && *error != NULL) return NULL; } sftpfs_dir = g_new0 (sftpfs_dir_data_t, 1); sftpfs_dir->handle = handle; sftpfs_dir->super_data = super_data; return (void *) sftpfs_dir; }
static struct vfs_s_inode * vfs_s_inode_from_path (struct vfs_class *me, const char *name, int flags) { struct vfs_s_super *super; struct vfs_s_inode *ino; char *q; if (!(q = vfs_s_get_path (me, name, &super, 0))) return NULL; ino = vfs_s_find_inode (me, super, q, flags & FL_FOLLOW ? LINK_FOLLOW : LINK_NO_FOLLOW, flags & ~FL_FOLLOW); if ((!ino) && (!*q)) /* We are asking about / directory of ftp server: assume it exists */ ino = vfs_s_find_inode (me, super, q, flags & FL_FOLLOW ? LINK_FOLLOW : LINK_NO_FOLLOW, FL_DIR | (flags & ~FL_FOLLOW)); g_free (q); return ino; }
int sftpfs_chmod (const vfs_path_t * vpath, mode_t mode, GError ** mcerror) { struct vfs_s_super *super; sftpfs_super_data_t *super_data; LIBSSH2_SFTP_ATTRIBUTES attrs; int res; const vfs_path_element_t *path_element; mc_return_val_if_error (mcerror, -1); 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; fixfname = sftpfs_fix_filename (path_element->path); res = libssh2_sftp_stat_ex (super_data->sftp_session, fixfname, sftpfs_filename_buffer->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; do { const char *fixfname; fixfname = sftpfs_fix_filename (path_element->path); res = libssh2_sftp_stat_ex (super_data->sftp_session, fixfname, sftpfs_filename_buffer->len, LIBSSH2_SFTP_SETSTAT, &attrs); if (res >= 0) break; else 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); return res; }
int sftpfs_stat (const vfs_path_t * vpath, struct stat *buf, GError ** mcerror) { struct vfs_s_super *super; sftpfs_super_data_t *super_data; LIBSSH2_SFTP_ATTRIBUTES attrs; int res; const vfs_path_element_t *path_element; mc_return_val_if_error (mcerror, -1); 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; fixfname = sftpfs_fix_filename (path_element->path); res = libssh2_sftp_stat_ex (super_data->sftp_session, fixfname, sftpfs_filename_buffer->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) { buf->st_atime = attrs.atime; buf->st_mtime = attrs.mtime; buf->st_ctime = attrs.mtime; } if ((attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) != 0) buf->st_size = attrs.filesize; if ((attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) != 0) buf->st_mode = attrs.permissions; return 0; }