ssize_t sftpfs_write_file (vfs_file_handler_t * file_handler, const char *buffer, size_t count, GError ** error) { ssize_t rc; sftpfs_file_handler_data_t *file_handler_data; sftpfs_super_data_t *super_data; file_handler_data = (sftpfs_file_handler_data_t *) file_handler->data; super_data = (sftpfs_super_data_t *) file_handler->ino->super->data; file_handler->pos = (off_t) libssh2_sftp_tell64 (file_handler_data->handle); do { rc = libssh2_sftp_write (file_handler_data->handle, buffer, count); if (rc >= 0) break; if (rc != LIBSSH2_ERROR_EAGAIN) { sftpfs_ssherror_to_gliberror (super_data, rc, error); return -1; } sftpfs_waitsocket (super_data, error); if (error != NULL && *error != NULL) return -1; } while (rc == LIBSSH2_ERROR_EAGAIN); return rc; }
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; }
void * sftpfs_readdir (void *data, GError ** error) { char mem[BUF_MEDIUM]; LIBSSH2_SFTP_ATTRIBUTES attrs; sftpfs_dir_data_t *sftpfs_dir = (sftpfs_dir_data_t *) data; static union vfs_dirent sftpfs_dirent; int rc; do { rc = libssh2_sftp_readdir (sftpfs_dir->handle, mem, sizeof (mem), &attrs); if (rc >= 0) break; if (rc != LIBSSH2_ERROR_EAGAIN) { sftpfs_ssherror_to_gliberror (sftpfs_dir->super_data, rc, error); return NULL; } sftpfs_waitsocket (sftpfs_dir->super_data, error); if (error != NULL && *error != NULL) return NULL; } while (rc == LIBSSH2_ERROR_EAGAIN); if (rc == 0) return NULL; g_strlcpy (sftpfs_dirent.dent.d_name, mem, BUF_MEDIUM); compute_namelen (&sftpfs_dirent.dent); return &sftpfs_dirent; }
int sftpfs_fstat (void *data, struct stat *buf, GError ** mcerror) { int res; LIBSSH2_SFTP_ATTRIBUTES attrs; vfs_file_handler_t *fh = (vfs_file_handler_t *) data; sftpfs_file_handler_data_t *sftpfs_fh = fh->data; struct vfs_s_super *super = fh->ino->super; sftpfs_super_data_t *super_data = (sftpfs_super_data_t *) super->data; mc_return_val_if_error (mcerror, -1); if (sftpfs_fh->handle == NULL) return -1; do { res = libssh2_sftp_fstat_ex (sftpfs_fh->handle, &attrs, 0); 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) { 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; }
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; }
ssize_t sftpfs_read_file (vfs_file_handler_t * file_handler, char *buffer, size_t count, GError ** mcerror) { ssize_t rc; sftpfs_file_handler_data_t *file_handler_data; sftpfs_super_data_t *super_data; mc_return_val_if_error (mcerror, -1); if (file_handler == NULL || file_handler->data == NULL) { mc_propagate_error (mcerror, -1, "%s", _("sftp: No file handler data present for reading file")); return -1; } file_handler_data = file_handler->data; super_data = (sftpfs_super_data_t *) file_handler->ino->super->data; do { rc = libssh2_sftp_read (file_handler_data->handle, buffer, count); if (rc >= 0) break; if (rc != LIBSSH2_ERROR_EAGAIN) { sftpfs_ssherror_to_gliberror (super_data, rc, mcerror); return -1; } sftpfs_waitsocket (super_data, mcerror); mc_return_val_if_error (mcerror, -1); } while (rc == LIBSSH2_ERROR_EAGAIN); file_handler->pos = (off_t) libssh2_sftp_tell64 (file_handler_data->handle); return rc; }
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; }