root/src/vfs/sftpfs/dir.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. sftpfs_opendir
  2. sftpfs_readdir
  3. sftpfs_closedir
  4. sftpfs_mkdir
  5. sftpfs_rmdir

   1 /* Virtual File System: SFTP file system.
   2    The internal functions: dirs
   3 
   4    Copyright (C) 2011-2022
   5    Free Software Foundation, Inc.
   6 
   7    Written by:
   8    Ilia Maslakov <il.smind@gmail.com>, 2011
   9    Slava Zanko <slavazanko@gmail.com>, 2011, 2012
  10 
  11    This file is part of the Midnight Commander.
  12 
  13    The Midnight Commander is free software: you can redistribute it
  14    and/or modify it under the terms of the GNU General Public License as
  15    published by the Free Software Foundation, either version 3 of the License,
  16    or (at your option) any later version.
  17 
  18    The Midnight Commander is distributed in the hope that it will be useful,
  19    but WITHOUT ANY WARRANTY; without even the implied warranty of
  20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21    GNU General Public License for more details.
  22 
  23    You should have received a copy of the GNU General Public License
  24    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  25  */
  26 
  27 #include <config.h>
  28 
  29 #include <libssh2.h>
  30 #include <libssh2_sftp.h>
  31 
  32 #include "lib/global.h"
  33 #include "lib/util.h"
  34 
  35 #include "internal.h"
  36 
  37 /*** global variables ****************************************************************************/
  38 
  39 /*** file scope macro definitions ****************************************************************/
  40 
  41 /*** file scope type declarations ****************************************************************/
  42 
  43 typedef struct
  44 {
  45     LIBSSH2_SFTP_HANDLE *handle;
  46     sftpfs_super_t *super;
  47 } sftpfs_dir_data_t;
  48 
  49 /*** file scope variables ************************************************************************/
  50 
  51 /*** file scope functions ************************************************************************/
  52 /* --------------------------------------------------------------------------------------------- */
  53 
  54 /* --------------------------------------------------------------------------------------------- */
  55 /*** public functions ****************************************************************************/
  56 /* --------------------------------------------------------------------------------------------- */
  57 /**
  58  * Open a directory stream corresponding to the directory name.
  59  *
  60  * @param vpath   path to directory
  61  * @param mcerror pointer to the error handler
  62  * @return directory data handler if success, NULL otherwise
  63  */
  64 
  65 void *
  66 sftpfs_opendir (const vfs_path_t * vpath, GError ** mcerror)
     /* [previous][next][first][last][top][bottom][index][help]  */
  67 {
  68     sftpfs_dir_data_t *sftpfs_dir;
  69     struct vfs_s_super *super;
  70     sftpfs_super_t *sftpfs_super;
  71     const vfs_path_element_t *path_element;
  72     LIBSSH2_SFTP_HANDLE *handle;
  73     const GString *fixfname;
  74 
  75     mc_return_val_if_error (mcerror, NULL);
  76 
  77     path_element = vfs_path_get_by_index (vpath, -1);
  78 
  79     if (vfs_s_get_path (vpath, &super, 0) == NULL)
  80         return NULL;
  81 
  82     sftpfs_super = SFTP_SUPER (super);
  83 
  84     fixfname = sftpfs_fix_filename (path_element->path);
  85 
  86     while (TRUE)
  87     {
  88         int libssh_errno;
  89 
  90         handle =
  91             libssh2_sftp_open_ex (sftpfs_super->sftp_session, fixfname->str, fixfname->len, 0, 0,
  92                                   LIBSSH2_SFTP_OPENDIR);
  93         if (handle != NULL)
  94             break;
  95 
  96         libssh_errno = libssh2_session_last_errno (sftpfs_super->session);
  97         if (!sftpfs_waitsocket (sftpfs_super, libssh_errno, mcerror))
  98             return NULL;
  99     }
 100 
 101     sftpfs_dir = g_new0 (sftpfs_dir_data_t, 1);
 102     sftpfs_dir->handle = handle;
 103     sftpfs_dir->super = sftpfs_super;
 104 
 105     return (void *) sftpfs_dir;
 106 }
 107 
 108 /* --------------------------------------------------------------------------------------------- */
 109 /**
 110  * Get a pointer to a structure representing the next directory entry.
 111  *
 112  * @param data    directory data handler
 113  * @param mcerror pointer to the error handler
 114  * @return information about direntry if success, NULL otherwise
 115  */
 116 
 117 struct vfs_dirent *
 118 sftpfs_readdir (void *data, GError ** mcerror)
     /* [previous][next][first][last][top][bottom][index][help]  */
 119 {
 120     char mem[BUF_MEDIUM];
 121     LIBSSH2_SFTP_ATTRIBUTES attrs;
 122     sftpfs_dir_data_t *sftpfs_dir = (sftpfs_dir_data_t *) data;
 123     int rc;
 124 
 125     mc_return_val_if_error (mcerror, NULL);
 126 
 127     do
 128     {
 129         rc = libssh2_sftp_readdir (sftpfs_dir->handle, mem, sizeof (mem), &attrs);
 130         if (rc >= 0)
 131             break;
 132 
 133         if (!sftpfs_waitsocket (sftpfs_dir->super, rc, mcerror))
 134             return NULL;
 135     }
 136     while (rc == LIBSSH2_ERROR_EAGAIN);
 137 
 138     return (rc != 0 ? vfs_dirent_init (NULL, mem, 0) : NULL);   /* FIXME: inode */
 139 }
 140 
 141 /* --------------------------------------------------------------------------------------------- */
 142 /**
 143  * Close the directory stream.
 144  *
 145  * @param data    directory data handler
 146  * @param mcerror pointer to the error handler
 147  * @return 0 if success, negative value otherwise
 148  */
 149 
 150 int
 151 sftpfs_closedir (void *data, GError ** mcerror)
     /* [previous][next][first][last][top][bottom][index][help]  */
 152 {
 153     int rc;
 154     sftpfs_dir_data_t *sftpfs_dir = (sftpfs_dir_data_t *) data;
 155 
 156     mc_return_val_if_error (mcerror, -1);
 157 
 158     rc = libssh2_sftp_closedir (sftpfs_dir->handle);
 159     g_free (sftpfs_dir);
 160     return rc;
 161 }
 162 
 163 /* --------------------------------------------------------------------------------------------- */
 164 /**
 165  * Create a new directory.
 166  *
 167  * @param vpath   path directory
 168  * @param mode    mode (see man 2 open)
 169  * @param mcerror pointer to the error handler
 170  * @return 0 if success, negative value otherwise
 171  */
 172 
 173 int
 174 sftpfs_mkdir (const vfs_path_t * vpath, mode_t mode, GError ** mcerror)
     /* [previous][next][first][last][top][bottom][index][help]  */
 175 {
 176     int res;
 177     struct vfs_s_super *super;
 178     sftpfs_super_t *sftpfs_super;
 179     const vfs_path_element_t *path_element;
 180     const GString *fixfname;
 181 
 182     mc_return_val_if_error (mcerror, -1);
 183 
 184     path_element = vfs_path_get_by_index (vpath, -1);
 185 
 186     if (vfs_s_get_path (vpath, &super, 0) == NULL)
 187         return -1;
 188 
 189     if (super == NULL)
 190         return -1;
 191 
 192     sftpfs_super = SFTP_SUPER (super);
 193     if (sftpfs_super->sftp_session == NULL)
 194         return -1;
 195 
 196     fixfname = sftpfs_fix_filename (path_element->path);
 197 
 198     do
 199     {
 200         res =
 201             libssh2_sftp_mkdir_ex (sftpfs_super->sftp_session, fixfname->str, fixfname->len, mode);
 202         if (res >= 0)
 203             break;
 204 
 205         if (!sftpfs_waitsocket (sftpfs_super, res, mcerror))
 206             return -1;
 207     }
 208     while (res == LIBSSH2_ERROR_EAGAIN);
 209 
 210     return res;
 211 }
 212 
 213 /* --------------------------------------------------------------------------------------------- */
 214 /**
 215  * Remove a directory.
 216  *
 217  * @param vpath   path directory
 218  * @param mcerror pointer to the error handler
 219  * @return 0 if success, negative value otherwise
 220  */
 221 
 222 int
 223 sftpfs_rmdir (const vfs_path_t * vpath, GError ** mcerror)
     /* [previous][next][first][last][top][bottom][index][help]  */
 224 {
 225     int res;
 226     struct vfs_s_super *super;
 227     sftpfs_super_t *sftpfs_super;
 228     const vfs_path_element_t *path_element;
 229     const GString *fixfname;
 230 
 231     mc_return_val_if_error (mcerror, -1);
 232 
 233     path_element = vfs_path_get_by_index (vpath, -1);
 234 
 235     if (vfs_s_get_path (vpath, &super, 0) == NULL)
 236         return -1;
 237 
 238     if (super == NULL)
 239         return -1;
 240 
 241     sftpfs_super = SFTP_SUPER (super);
 242     if (sftpfs_super->sftp_session == NULL)
 243         return -1;
 244 
 245     fixfname = sftpfs_fix_filename (path_element->path);
 246 
 247     do
 248     {
 249         res = libssh2_sftp_rmdir_ex (sftpfs_super->sftp_session, fixfname->str, fixfname->len);
 250         if (res >= 0)
 251             break;
 252 
 253         if (!sftpfs_waitsocket (sftpfs_super, res, mcerror))
 254             return -1;
 255     }
 256     while (res == LIBSSH2_ERROR_EAGAIN);
 257 
 258     return res;
 259 }
 260 
 261 /* --------------------------------------------------------------------------------------------- */

/* [previous][next][first][last][top][bottom][index][help]  */