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-2019
   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 
  74     mc_return_val_if_error (mcerror, NULL);
  75 
  76     path_element = vfs_path_get_by_index (vpath, -1);
  77 
  78     if (vfs_s_get_path (vpath, &super, 0) == NULL)
  79         return NULL;
  80 
  81     sftpfs_super = SFTP_SUPER (super);
  82 
  83     while (TRUE)
  84     {
  85         const char *fixfname;
  86         unsigned int fixfname_len = 0;
  87         int libssh_errno;
  88 
  89         fixfname = sftpfs_fix_filename (path_element->path, &fixfname_len);
  90 
  91         handle =
  92             libssh2_sftp_open_ex (sftpfs_super->sftp_session, fixfname, fixfname_len, 0, 0,
  93                                   LIBSSH2_SFTP_OPENDIR);
  94         if (handle != NULL)
  95             break;
  96 
  97         libssh_errno = libssh2_session_last_errno (sftpfs_super->session);
  98         if (!sftpfs_waitsocket (sftpfs_super, libssh_errno, mcerror))
  99             return NULL;
 100     }
 101 
 102     sftpfs_dir = g_new0 (sftpfs_dir_data_t, 1);
 103     sftpfs_dir->handle = handle;
 104     sftpfs_dir->super = sftpfs_super;
 105 
 106     return (void *) sftpfs_dir;
 107 }
 108 
 109 /* --------------------------------------------------------------------------------------------- */
 110 /**
 111  * Get a pointer to a structure representing the next directory entry.
 112  *
 113  * @param data    directory data handler
 114  * @param mcerror pointer to the error handler
 115  * @return information about direntry if success, NULL otherwise
 116  */
 117 
 118 void *
 119 sftpfs_readdir (void *data, GError ** mcerror)
     /* [previous][next][first][last][top][bottom][index][help]  */
 120 {
 121     char mem[BUF_MEDIUM];
 122     LIBSSH2_SFTP_ATTRIBUTES attrs;
 123     sftpfs_dir_data_t *sftpfs_dir = (sftpfs_dir_data_t *) data;
 124     static union vfs_dirent sftpfs_dirent;
 125     int rc;
 126 
 127     mc_return_val_if_error (mcerror, NULL);
 128 
 129     do
 130     {
 131         rc = libssh2_sftp_readdir (sftpfs_dir->handle, mem, sizeof (mem), &attrs);
 132         if (rc >= 0)
 133             break;
 134 
 135         if (!sftpfs_waitsocket (sftpfs_dir->super, rc, mcerror))
 136             return NULL;
 137     }
 138     while (rc == LIBSSH2_ERROR_EAGAIN);
 139 
 140     if (rc == 0)
 141         return NULL;
 142 
 143     g_strlcpy (sftpfs_dirent.dent.d_name, mem, BUF_MEDIUM);
 144     return &sftpfs_dirent;
 145 }
 146 
 147 /* --------------------------------------------------------------------------------------------- */
 148 /**
 149  * Close the directory stream.
 150  *
 151  * @param data    directory data handler
 152  * @param mcerror pointer to the error handler
 153  * @return 0 if success, negative value otherwise
 154  */
 155 
 156 int
 157 sftpfs_closedir (void *data, GError ** mcerror)
     /* [previous][next][first][last][top][bottom][index][help]  */
 158 {
 159     int rc;
 160     sftpfs_dir_data_t *sftpfs_dir = (sftpfs_dir_data_t *) data;
 161 
 162     mc_return_val_if_error (mcerror, -1);
 163 
 164     rc = libssh2_sftp_closedir (sftpfs_dir->handle);
 165     g_free (sftpfs_dir);
 166     return rc;
 167 }
 168 
 169 /* --------------------------------------------------------------------------------------------- */
 170 /**
 171  * Create a new directory.
 172  *
 173  * @param vpath   path directory
 174  * @param mode    mode (see man 2 open)
 175  * @param mcerror pointer to the error handler
 176  * @return 0 if success, negative value otherwise
 177  */
 178 
 179 int
 180 sftpfs_mkdir (const vfs_path_t * vpath, mode_t mode, GError ** mcerror)
     /* [previous][next][first][last][top][bottom][index][help]  */
 181 {
 182     int res;
 183     struct vfs_s_super *super;
 184     sftpfs_super_t *sftpfs_super;
 185     const vfs_path_element_t *path_element;
 186 
 187     mc_return_val_if_error (mcerror, -1);
 188 
 189     path_element = vfs_path_get_by_index (vpath, -1);
 190 
 191     if (vfs_s_get_path (vpath, &super, 0) == NULL)
 192         return -1;
 193 
 194     if (super == NULL)
 195         return -1;
 196 
 197     sftpfs_super = SFTP_SUPER (super);
 198     if (sftpfs_super->sftp_session == NULL)
 199         return -1;
 200 
 201     do
 202     {
 203         const char *fixfname;
 204         unsigned int fixfname_len = 0;
 205 
 206         fixfname = sftpfs_fix_filename (path_element->path, &fixfname_len);
 207 
 208         res = libssh2_sftp_mkdir_ex (sftpfs_super->sftp_session, fixfname, fixfname_len, mode);
 209         if (res >= 0)
 210             break;
 211 
 212         if (!sftpfs_waitsocket (sftpfs_super, res, mcerror))
 213             return -1;
 214     }
 215     while (res == LIBSSH2_ERROR_EAGAIN);
 216 
 217     return res;
 218 }
 219 
 220 /* --------------------------------------------------------------------------------------------- */
 221 /**
 222  * Remove a directory.
 223  *
 224  * @param vpath   path directory
 225  * @param mcerror pointer to the error handler
 226  * @return 0 if success, negative value otherwise
 227  */
 228 
 229 int
 230 sftpfs_rmdir (const vfs_path_t * vpath, GError ** mcerror)
     /* [previous][next][first][last][top][bottom][index][help]  */
 231 {
 232     int res;
 233     struct vfs_s_super *super;
 234     sftpfs_super_t *sftpfs_super;
 235     const vfs_path_element_t *path_element;
 236 
 237     mc_return_val_if_error (mcerror, -1);
 238 
 239     path_element = vfs_path_get_by_index (vpath, -1);
 240 
 241     if (vfs_s_get_path (vpath, &super, 0) == NULL)
 242         return -1;
 243 
 244     if (super == NULL)
 245         return -1;
 246 
 247     sftpfs_super = SFTP_SUPER (super);
 248     if (sftpfs_super->sftp_session == NULL)
 249         return -1;
 250 
 251     do
 252     {
 253         const char *fixfname;
 254         unsigned int fixfname_len = 0;
 255 
 256         fixfname = sftpfs_fix_filename (path_element->path, &fixfname_len);
 257 
 258         res = libssh2_sftp_rmdir_ex (sftpfs_super->sftp_session, fixfname, fixfname_len);
 259         if (res >= 0)
 260             break;
 261 
 262         if (!sftpfs_waitsocket (sftpfs_super, res, mcerror))
 263             return -1;
 264     }
 265     while (res == LIBSSH2_ERROR_EAGAIN);
 266 
 267     return res;
 268 }
 269 
 270 /* --------------------------------------------------------------------------------------------- */

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