root/src/vfs/sftpfs/sftpfs.c

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

DEFINITIONS

This source file includes following definitions.
  1. sftpfs_cb_init
  2. sftpfs_cb_done
  3. sftpfs_cb_open
  4. sftpfs_cb_opendir
  5. sftpfs_cb_readdir
  6. sftpfs_cb_closedir
  7. sftpfs_cb_lstat
  8. sftpfs_cb_stat
  9. sftpfs_cb_fstat
  10. sftpfs_cb_readlink
  11. sftpfs_cb_utime
  12. sftpfs_cb_symlink
  13. sftpfs_cb_mknod
  14. sftpfs_cb_link
  15. sftpfs_cb_chown
  16. sftpfs_cb_read
  17. sftpfs_cb_write
  18. sftpfs_cb_close
  19. sftpfs_cb_chmod
  20. sftpfs_cb_mkdir
  21. sftpfs_cb_rmdir
  22. sftpfs_cb_lseek
  23. sftpfs_cb_unlink
  24. sftpfs_cb_rename
  25. sftpfs_cb_errno
  26. sftpfs_cb_fill_names
  27. sftpfs_archive_same
  28. sftpfs_new_archive
  29. sftpfs_open_archive
  30. sftpfs_free_archive
  31. sftpfs_cb_dir_load
  32. vfs_init_sftpfs

   1 /* Virtual File System: SFTP file system.
   2    The interface function
   3 
   4    Copyright (C) 2011-2024
   5    Free Software Foundation, Inc.
   6 
   7    Written by:
   8    Ilia Maslakov <il.smind@gmail.com>, 2011
   9    Slava Zanko <slavazanko@gmail.com>, 2011-2013
  10    Andrew Borodin <aborodin@vmail.ru>, 2021-2022
  11 
  12    This file is part of the Midnight Commander.
  13 
  14    The Midnight Commander is free software: you can redistribute it
  15    and/or modify it under the terms of the GNU General Public License as
  16    published by the Free Software Foundation, either version 3 of the License,
  17    or (at your option) any later version.
  18 
  19    The Midnight Commander is distributed in the hope that it will be useful,
  20    but WITHOUT ANY WARRANTY; without even the implied warranty of
  21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22    GNU General Public License for more details.
  23 
  24    You should have received a copy of the GNU General Public License
  25    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  26  */
  27 
  28 #include <config.h>
  29 #include <errno.h>
  30 #include <stdlib.h>
  31 #include <string.h>             /* memset() */
  32 
  33 #include "lib/global.h"
  34 #include "lib/vfs/netutil.h"
  35 #include "lib/vfs/utilvfs.h"
  36 #include "lib/vfs/gc.h"
  37 #include "lib/widget.h"
  38 #include "lib/tty/tty.h"        /* tty_enable_interrupt_key () */
  39 
  40 #include "internal.h"
  41 
  42 #include "sftpfs.h"
  43 
  44 /*** global variables ****************************************************************************/
  45 
  46 struct vfs_s_subclass sftpfs_subclass;
  47 struct vfs_class *vfs_sftpfs_ops = VFS_CLASS (&sftpfs_subclass);        /* used in file.c */
  48 
  49 /*** file scope macro definitions ****************************************************************/
  50 
  51 /*** file scope type declarations ****************************************************************/
  52 
  53 /*** forward declarations (file scope functions) *************************************************/
  54 
  55 /*** file scope variables ************************************************************************/
  56 
  57 /* --------------------------------------------------------------------------------------------- */
  58 /*** file scope functions ************************************************************************/
  59 /* --------------------------------------------------------------------------------------------- */
  60 /**
  61  * Callback for VFS-class init action.
  62  *
  63  * @param me structure of VFS class
  64  */
  65 
  66 static int
  67 sftpfs_cb_init (struct vfs_class *me)
     /* [previous][next][first][last][top][bottom][index][help]  */
  68 {
  69     (void) me;
  70 
  71     if (libssh2_init (0) != 0)
  72         return 0;
  73 
  74     sftpfs_filename_buffer = g_string_new ("");
  75     sftpfs_init_config_variables_patterns ();
  76     return 1;
  77 }
  78 
  79 /* --------------------------------------------------------------------------------------------- */
  80 /**
  81  * Callback for VFS-class deinit action.
  82  *
  83  * @param me structure of VFS class
  84  */
  85 
  86 static void
  87 sftpfs_cb_done (struct vfs_class *me)
     /* [previous][next][first][last][top][bottom][index][help]  */
  88 {
  89     (void) me;
  90 
  91     sftpfs_deinit_config_variables_patterns ();
  92     g_string_free (sftpfs_filename_buffer, TRUE);
  93     libssh2_exit ();
  94 }
  95 
  96 /* --------------------------------------------------------------------------------------------- */
  97 /**
  98  * Callback for opening file.
  99  *
 100  * @param vpath path to file
 101  * @param flags flags (see man 2 open)
 102  * @param mode  mode (see man 2 open)
 103  * @return file data handler if success, NULL otherwise
 104  */
 105 
 106 static void *
 107 sftpfs_cb_open (const vfs_path_t * vpath, int flags, mode_t mode)
     /* [previous][next][first][last][top][bottom][index][help]  */
 108 {
 109     vfs_file_handler_t *fh;
 110     struct vfs_class *me;
 111     struct vfs_s_super *super;
 112     const char *path_super;
 113     struct vfs_s_inode *path_inode;
 114     GError *mcerror = NULL;
 115     gboolean is_changed = FALSE;
 116 
 117     path_super = vfs_s_get_path (vpath, &super, 0);
 118     if (path_super == NULL)
 119         return NULL;
 120 
 121     me = VFS_CLASS (vfs_path_get_last_path_vfs (vpath));
 122 
 123     path_inode = vfs_s_find_inode (me, super, path_super, LINK_FOLLOW, FL_NONE);
 124     if (path_inode != NULL && ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)))
 125     {
 126         me->verrno = EEXIST;
 127         return NULL;
 128     }
 129 
 130     if (path_inode == NULL)
 131     {
 132         char *name;
 133         struct vfs_s_entry *ent;
 134         struct vfs_s_inode *dir;
 135 
 136         name = g_path_get_dirname (path_super);
 137         dir = vfs_s_find_inode (me, super, name, LINK_FOLLOW, FL_DIR);
 138         g_free (name);
 139         if (dir == NULL)
 140             return NULL;
 141 
 142         name = g_path_get_basename (path_super);
 143         ent = vfs_s_generate_entry (me, name, dir, 0755);
 144         g_free (name);
 145         path_inode = ent->ino;
 146         vfs_s_insert_entry (me, dir, ent);
 147         is_changed = TRUE;
 148     }
 149 
 150     if (S_ISDIR (path_inode->st.st_mode))
 151     {
 152         me->verrno = EISDIR;
 153         return NULL;
 154     }
 155 
 156     fh = sftpfs_fh_new (path_inode, is_changed);
 157 
 158     if (!sftpfs_open_file (fh, flags, mode, &mcerror))
 159     {
 160         mc_error_message (&mcerror, NULL);
 161         g_free (fh);
 162         return NULL;
 163     }
 164 
 165     vfs_rmstamp (me, (vfsid) super);
 166     super->fd_usage++;
 167     fh->ino->st.st_nlink++;
 168     return fh;
 169 }
 170 
 171 /* --------------------------------------------------------------------------------------------- */
 172 /**
 173  * Callback for opening directory.
 174  *
 175  * @param vpath path to directory
 176  * @return directory data handler if success, NULL otherwise
 177  */
 178 
 179 static void *
 180 sftpfs_cb_opendir (const vfs_path_t * vpath)
     /* [previous][next][first][last][top][bottom][index][help]  */
 181 {
 182     GError *mcerror = NULL;
 183     void *ret_value;
 184 
 185     /* reset interrupt flag */
 186     tty_got_interrupt ();
 187 
 188     ret_value = sftpfs_opendir (vpath, &mcerror);
 189     mc_error_message (&mcerror, NULL);
 190     return ret_value;
 191 }
 192 
 193 /* --------------------------------------------------------------------------------------------- */
 194 /**
 195  * Callback for reading directory entry.
 196  *
 197  * @param data directory data handler
 198  * @return information about direntry if success, NULL otherwise
 199  */
 200 
 201 static struct vfs_dirent *
 202 sftpfs_cb_readdir (void *data)
     /* [previous][next][first][last][top][bottom][index][help]  */
 203 {
 204     GError *mcerror = NULL;
 205     struct vfs_dirent *sftpfs_dirent;
 206 
 207     if (tty_got_interrupt ())
 208     {
 209         tty_disable_interrupt_key ();
 210         return NULL;
 211     }
 212 
 213     sftpfs_dirent = sftpfs_readdir (data, &mcerror);
 214     if (!mc_error_message (&mcerror, NULL))
 215     {
 216         if (sftpfs_dirent != NULL)
 217             vfs_print_message (_("sftp: (Ctrl-G break) Listing... %s"), sftpfs_dirent->d_name);
 218         else
 219             vfs_print_message ("%s", _("sftp: Listing done."));
 220     }
 221 
 222     return sftpfs_dirent;
 223 }
 224 
 225 /* --------------------------------------------------------------------------------------------- */
 226 /**
 227  * Callback for closing directory.
 228  *
 229  * @param data directory data handler
 230  * @return 0 if success, negative value otherwise
 231  */
 232 
 233 static int
 234 sftpfs_cb_closedir (void *data)
     /* [previous][next][first][last][top][bottom][index][help]  */
 235 {
 236     int rc;
 237     GError *mcerror = NULL;
 238 
 239     rc = sftpfs_closedir (data, &mcerror);
 240     mc_error_message (&mcerror, NULL);
 241     return rc;
 242 }
 243 
 244 /* --------------------------------------------------------------------------------------------- */
 245 /**
 246  * Callback for lstat VFS-function.
 247  *
 248  * @param vpath path to file or directory
 249  * @param buf   buffer for store stat-info
 250  * @return 0 if success, negative value otherwise
 251  */
 252 
 253 static int
 254 sftpfs_cb_lstat (const vfs_path_t * vpath, struct stat *buf)
     /* [previous][next][first][last][top][bottom][index][help]  */
 255 {
 256     int rc;
 257     GError *mcerror = NULL;
 258 
 259     rc = sftpfs_lstat (vpath, buf, &mcerror);
 260     mc_error_message (&mcerror, NULL);
 261     return rc;
 262 }
 263 
 264 /* --------------------------------------------------------------------------------------------- */
 265 /**
 266  * Callback for stat VFS-function.
 267  *
 268  * @param vpath path to file or directory
 269  * @param buf   buffer for store stat-info
 270  * @return 0 if success, negative value otherwise
 271  */
 272 
 273 static int
 274 sftpfs_cb_stat (const vfs_path_t * vpath, struct stat *buf)
     /* [previous][next][first][last][top][bottom][index][help]  */
 275 {
 276     int rc;
 277     GError *mcerror = NULL;
 278 
 279     rc = sftpfs_stat (vpath, buf, &mcerror);
 280     mc_error_message (&mcerror, NULL);
 281     return rc;
 282 }
 283 
 284 /* --------------------------------------------------------------------------------------------- */
 285 /**
 286  * Callback for fstat VFS-function.
 287  *
 288  * @param data file data handler
 289  * @param buf  buffer for store stat-info
 290  * @return 0 if success, negative value otherwise
 291  */
 292 
 293 static int
 294 sftpfs_cb_fstat (void *data, struct stat *buf)
     /* [previous][next][first][last][top][bottom][index][help]  */
 295 {
 296     int rc;
 297     GError *mcerror = NULL;
 298 
 299     rc = sftpfs_fstat (data, buf, &mcerror);
 300     mc_error_message (&mcerror, NULL);
 301     return rc;
 302 }
 303 
 304 /* --------------------------------------------------------------------------------------------- */
 305 /**
 306  * Callback for readlink VFS-function.
 307  *
 308  * @param vpath path to file or directory
 309  * @param buf   buffer for store stat-info
 310  * @param size  buffer size
 311  * @return 0 if success, negative value otherwise
 312  */
 313 
 314 static int
 315 sftpfs_cb_readlink (const vfs_path_t * vpath, char *buf, size_t size)
     /* [previous][next][first][last][top][bottom][index][help]  */
 316 {
 317     int rc;
 318     GError *mcerror = NULL;
 319 
 320     rc = sftpfs_readlink (vpath, buf, size, &mcerror);
 321     mc_error_message (&mcerror, NULL);
 322     return rc;
 323 }
 324 
 325 /* --------------------------------------------------------------------------------------------- */
 326 /**
 327  * Callback for utime VFS-function.
 328  *
 329  * @param vpath path to file or directory
 330  * @param times access and modification time to set
 331  * @return 0 if success, negative value otherwise
 332  */
 333 
 334 static int
 335 sftpfs_cb_utime (const vfs_path_t * vpath, mc_timesbuf_t * times)
     /* [previous][next][first][last][top][bottom][index][help]  */
 336 {
 337     int rc;
 338     GError *mcerror = NULL;
 339 
 340 #ifdef HAVE_UTIMENSAT
 341     time_t atime = (*times)[0].tv_sec;
 342     time_t mtime = (*times)[1].tv_sec;
 343 #else
 344     time_t atime = times->actime;
 345     time_t mtime = times->modtime;
 346 #endif
 347 
 348     rc = sftpfs_utime (vpath, atime, mtime, &mcerror);
 349     mc_error_message (&mcerror, NULL);
 350     return rc;
 351 }
 352 
 353 /* --------------------------------------------------------------------------------------------- */
 354 /**
 355  * Callback for symlink VFS-function.
 356  *
 357  * @param vpath1 path to file or directory
 358  * @param vpath2 path to symlink
 359  * @return 0 if success, negative value otherwise
 360  */
 361 
 362 static int
 363 sftpfs_cb_symlink (const vfs_path_t * vpath1, const vfs_path_t * vpath2)
     /* [previous][next][first][last][top][bottom][index][help]  */
 364 {
 365     int rc;
 366     GError *mcerror = NULL;
 367 
 368     rc = sftpfs_symlink (vpath1, vpath2, &mcerror);
 369     mc_error_message (&mcerror, NULL);
 370     return rc;
 371 }
 372 
 373 /* --------------------------------------------------------------------------------------------- */
 374 /**
 375  * Callback for symlink VFS-function.
 376  *
 377  * @param vpath unused
 378  * @param mode  unused
 379  * @param dev   unused
 380  * @return always 0
 381  */
 382 
 383 static int
 384 sftpfs_cb_mknod (const vfs_path_t * vpath, mode_t mode, dev_t dev)
     /* [previous][next][first][last][top][bottom][index][help]  */
 385 {
 386     (void) vpath;
 387     (void) mode;
 388     (void) dev;
 389 
 390     return 0;
 391 }
 392 
 393 /* --------------------------------------------------------------------------------------------- */
 394 /**
 395  * Callback for link VFS-function.
 396  *
 397  * @param vpath1 unused
 398  * @param vpath2 unused
 399  * @return always 0
 400  */
 401 
 402 static int
 403 sftpfs_cb_link (const vfs_path_t * vpath1, const vfs_path_t * vpath2)
     /* [previous][next][first][last][top][bottom][index][help]  */
 404 {
 405     (void) vpath1;
 406     (void) vpath2;
 407 
 408     return 0;
 409 }
 410 
 411 /* --------------------------------------------------------------------------------------------- */
 412 /**
 413  * Callback for chown VFS-function.
 414  *
 415  * @param vpath unused
 416  * @param owner unused
 417  * @param group unused
 418  * @return always 0
 419  */
 420 
 421 static int
 422 sftpfs_cb_chown (const vfs_path_t * vpath, uid_t owner, gid_t group)
     /* [previous][next][first][last][top][bottom][index][help]  */
 423 {
 424     (void) vpath;
 425     (void) owner;
 426     (void) group;
 427 
 428     return 0;
 429 }
 430 
 431 /* --------------------------------------------------------------------------------------------- */
 432 /**
 433  * Callback for reading file content.
 434  *
 435  * @param data   file data handler
 436  * @param buffer buffer for data
 437  * @param count  data size
 438  * @return 0 if success, negative value otherwise
 439  */
 440 
 441 static ssize_t
 442 sftpfs_cb_read (void *data, char *buffer, size_t count)
     /* [previous][next][first][last][top][bottom][index][help]  */
 443 {
 444     int rc;
 445     GError *mcerror = NULL;
 446     vfs_file_handler_t *fh = VFS_FILE_HANDLER (data);
 447 
 448     if (tty_got_interrupt ())
 449     {
 450         tty_disable_interrupt_key ();
 451         return 0;
 452     }
 453 
 454     rc = sftpfs_read_file (fh, buffer, count, &mcerror);
 455     mc_error_message (&mcerror, NULL);
 456     return rc;
 457 }
 458 
 459 /* --------------------------------------------------------------------------------------------- */
 460 /**
 461  * Callback for writing file content.
 462  *
 463  * @param data  file data handler
 464  * @param buf   buffer for data
 465  * @param count data size
 466  * @return 0 if success, negative value otherwise
 467  */
 468 
 469 static ssize_t
 470 sftpfs_cb_write (void *data, const char *buf, size_t nbyte)
     /* [previous][next][first][last][top][bottom][index][help]  */
 471 {
 472     int rc;
 473     GError *mcerror = NULL;
 474     vfs_file_handler_t *fh = VFS_FILE_HANDLER (data);
 475 
 476     rc = sftpfs_write_file (fh, buf, nbyte, &mcerror);
 477     mc_error_message (&mcerror, NULL);
 478     return rc;
 479 }
 480 
 481 /* --------------------------------------------------------------------------------------------- */
 482 /**
 483  * Callback for close file.
 484  *
 485  * @param data file data handler
 486  * @return 0 if success, negative value otherwise
 487  */
 488 
 489 static int
 490 sftpfs_cb_close (void *data)
     /* [previous][next][first][last][top][bottom][index][help]  */
 491 {
 492     int rc;
 493     GError *mcerror = NULL;
 494     struct vfs_s_super *super = VFS_FILE_HANDLER_SUPER (data);
 495     vfs_file_handler_t *fh = VFS_FILE_HANDLER (data);
 496 
 497     super->fd_usage--;
 498     if (super->fd_usage == 0)
 499         vfs_stamp_create (vfs_sftpfs_ops, super);
 500 
 501     rc = sftpfs_close_file (fh, &mcerror);
 502     mc_error_message (&mcerror, NULL);
 503 
 504     if (fh->handle != -1)
 505         close (fh->handle);
 506 
 507     vfs_s_free_inode (vfs_sftpfs_ops, fh->ino);
 508 
 509     return rc;
 510 }
 511 
 512 /* --------------------------------------------------------------------------------------------- */
 513 /**
 514  * Callback for chmod VFS-function.
 515  *
 516  * @param vpath path to file or directory
 517  * @param mode  mode (see man 2 open)
 518  * @return 0 if success, negative value otherwise
 519  */
 520 
 521 static int
 522 sftpfs_cb_chmod (const vfs_path_t * vpath, mode_t mode)
     /* [previous][next][first][last][top][bottom][index][help]  */
 523 {
 524     int rc;
 525     GError *mcerror = NULL;
 526 
 527     rc = sftpfs_chmod (vpath, mode, &mcerror);
 528     mc_error_message (&mcerror, NULL);
 529     return rc;
 530 }
 531 
 532 /* --------------------------------------------------------------------------------------------- */
 533 /**
 534  * Callback for mkdir VFS-function.
 535  *
 536  * @param vpath path directory
 537  * @param mode  mode (see man 2 open)
 538  * @return 0 if success, negative value otherwise
 539  */
 540 
 541 static int
 542 sftpfs_cb_mkdir (const vfs_path_t * vpath, mode_t mode)
     /* [previous][next][first][last][top][bottom][index][help]  */
 543 {
 544     int rc;
 545     GError *mcerror = NULL;
 546 
 547     rc = sftpfs_mkdir (vpath, mode, &mcerror);
 548     mc_error_message (&mcerror, NULL);
 549     return rc;
 550 }
 551 
 552 /* --------------------------------------------------------------------------------------------- */
 553 /**
 554  * Callback for rmdir VFS-function.
 555  *
 556  * @param vpath path directory
 557  * @return 0 if success, negative value otherwise
 558  */
 559 
 560 static int
 561 sftpfs_cb_rmdir (const vfs_path_t * vpath)
     /* [previous][next][first][last][top][bottom][index][help]  */
 562 {
 563     int rc;
 564     GError *mcerror = NULL;
 565 
 566     rc = sftpfs_rmdir (vpath, &mcerror);
 567     mc_error_message (&mcerror, NULL);
 568     return rc;
 569 }
 570 
 571 /* --------------------------------------------------------------------------------------------- */
 572 /**
 573  * Callback for lseek VFS-function.
 574  *
 575  * @param data   file data handler
 576  * @param offset file offset
 577  * @param whence method of seek (at begin, at current, at end)
 578  * @return 0 if success, negative value otherwise
 579  */
 580 
 581 static off_t
 582 sftpfs_cb_lseek (void *data, off_t offset, int whence)
     /* [previous][next][first][last][top][bottom][index][help]  */
 583 {
 584     off_t ret_offset;
 585     vfs_file_handler_t *fh = VFS_FILE_HANDLER (data);
 586     GError *mcerror = NULL;
 587 
 588     ret_offset = sftpfs_lseek (fh, offset, whence, &mcerror);
 589     mc_error_message (&mcerror, NULL);
 590     return ret_offset;
 591 }
 592 
 593 /* --------------------------------------------------------------------------------------------- */
 594 /**
 595  * Callback for unlink VFS-function.
 596  *
 597  * @param vpath path to file or directory
 598  * @return 0 if success, negative value otherwise
 599  */
 600 
 601 static int
 602 sftpfs_cb_unlink (const vfs_path_t * vpath)
     /* [previous][next][first][last][top][bottom][index][help]  */
 603 {
 604     int rc;
 605     GError *mcerror = NULL;
 606 
 607     rc = sftpfs_unlink (vpath, &mcerror);
 608     mc_error_message (&mcerror, NULL);
 609     return rc;
 610 }
 611 
 612 /* --------------------------------------------------------------------------------------------- */
 613 /**
 614  * Callback for rename VFS-function.
 615  *
 616  * @param vpath1 path to source file or directory
 617  * @param vpath2 path to destination file or directory
 618  * @return 0 if success, negative value otherwise
 619  */
 620 
 621 static int
 622 sftpfs_cb_rename (const vfs_path_t * vpath1, const vfs_path_t * vpath2)
     /* [previous][next][first][last][top][bottom][index][help]  */
 623 {
 624     int rc;
 625     GError *mcerror = NULL;
 626 
 627     rc = sftpfs_rename (vpath1, vpath2, &mcerror);
 628     mc_error_message (&mcerror, NULL);
 629     return rc;
 630 }
 631 
 632 /* --------------------------------------------------------------------------------------------- */
 633 /**
 634  * Callback for errno VFS-function.
 635  *
 636  * @param me unused
 637  * @return value of errno global variable
 638  */
 639 
 640 static int
 641 sftpfs_cb_errno (struct vfs_class *me)
     /* [previous][next][first][last][top][bottom][index][help]  */
 642 {
 643     (void) me;
 644 
 645     return errno;
 646 }
 647 
 648 /* --------------------------------------------------------------------------------------------- */
 649 /**
 650  * Callback for fill_names VFS function.
 651  * Add SFTP connections to the 'Active VFS connections'  list
 652  *
 653  * @param me   unused
 654  * @param func callback function for adding SFTP-connection to list of active connections
 655  */
 656 
 657 static void
 658 sftpfs_cb_fill_names (struct vfs_class *me, fill_names_f func)
     /* [previous][next][first][last][top][bottom][index][help]  */
 659 {
 660     GList *iter;
 661 
 662     (void) me;
 663 
 664     for (iter = sftpfs_subclass.supers; iter != NULL; iter = g_list_next (iter))
 665     {
 666         const struct vfs_s_super *super = (const struct vfs_s_super *) iter->data;
 667         GString *name;
 668 
 669         name = vfs_path_element_build_pretty_path_str (super->path_element);
 670 
 671         func (name->str);
 672         g_string_free (name, TRUE);
 673     }
 674 }
 675 
 676 /* --------------------------------------------------------------------------------------------- */
 677 /**
 678  * Callback for checking if connection is equal to existing connection.
 679  *
 680  * @param vpath_element path element with connection data
 681  * @param super         data with exists connection
 682  * @param vpath         unused
 683  * @param cookie        unused
 684  * @return TRUE if connections is equal, FALSE otherwise
 685  */
 686 
 687 static gboolean
 688 sftpfs_archive_same (const vfs_path_element_t * vpath_element, struct vfs_s_super *super,
     /* [previous][next][first][last][top][bottom][index][help]  */
 689                      const vfs_path_t * vpath, void *cookie)
 690 {
 691     int result;
 692     vfs_path_element_t *orig_connect_info;
 693 
 694     (void) vpath;
 695     (void) cookie;
 696 
 697     orig_connect_info = SFTP_SUPER (super)->original_connection_info;
 698 
 699     result = ((g_strcmp0 (vpath_element->host, orig_connect_info->host) == 0)
 700               && (g_strcmp0 (vpath_element->user, orig_connect_info->user) == 0)
 701               && (vpath_element->port == orig_connect_info->port));
 702 
 703     return result;
 704 }
 705 
 706 /* --------------------------------------------------------------------------------------------- */
 707 
 708 static struct vfs_s_super *
 709 sftpfs_new_archive (struct vfs_class *me)
     /* [previous][next][first][last][top][bottom][index][help]  */
 710 {
 711     sftpfs_super_t *arch;
 712 
 713     arch = g_new0 (sftpfs_super_t, 1);
 714     arch->base.me = me;
 715     arch->base.name = g_strdup (PATH_SEP_STR);
 716     arch->auth_type = NONE;
 717     arch->config_auth_type = NONE;
 718     arch->socket_handle = LIBSSH2_INVALID_SOCKET;
 719 
 720     return VFS_SUPER (arch);
 721 }
 722 
 723 /* --------------------------------------------------------------------------------------------- */
 724 /**
 725  * Callback for opening new connection.
 726  *
 727  * @param super         connection data
 728  * @param vpath         unused
 729  * @param vpath_element path element with connection data
 730  * @return 0 if success, -1 otherwise
 731  */
 732 
 733 static int
 734 sftpfs_open_archive (struct vfs_s_super *super, const vfs_path_t * vpath,
     /* [previous][next][first][last][top][bottom][index][help]  */
 735                      const vfs_path_element_t * vpath_element)
 736 {
 737     GError *mcerror = NULL;
 738     sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
 739     int ret_value;
 740 
 741     (void) vpath;
 742 
 743     if (vpath_element->host == NULL || *vpath_element->host == '\0')
 744     {
 745         vfs_print_message ("%s", _("sftp: Invalid host name."));
 746         vpath_element->class->verrno = EPERM;
 747         return -1;
 748     }
 749 
 750     sftpfs_super->original_connection_info = vfs_path_element_clone (vpath_element);
 751     super->path_element = vfs_path_element_clone (vpath_element);
 752 
 753     sftpfs_fill_connection_data_from_config (super, &mcerror);
 754     if (mc_error_message (&mcerror, &ret_value))
 755     {
 756         vpath_element->class->verrno = ret_value;
 757         return -1;
 758     }
 759 
 760     super->root =
 761         vfs_s_new_inode (vpath_element->class, super,
 762                          vfs_s_default_stat (vpath_element->class, S_IFDIR | 0755));
 763 
 764     ret_value = sftpfs_open_connection (super, &mcerror);
 765     mc_error_message (&mcerror, NULL);
 766     return ret_value;
 767 }
 768 
 769 /* --------------------------------------------------------------------------------------------- */
 770 /**
 771  * Callback for closing connection.
 772  *
 773  * @param me    unused
 774  * @param super connection data
 775  */
 776 
 777 static void
 778 sftpfs_free_archive (struct vfs_class *me, struct vfs_s_super *super)
     /* [previous][next][first][last][top][bottom][index][help]  */
 779 {
 780     GError *mcerror = NULL;
 781 
 782     (void) me;
 783 
 784     sftpfs_close_connection (super, "Normal Shutdown", &mcerror);
 785 
 786     vfs_path_element_free (SFTP_SUPER (super)->original_connection_info);
 787 
 788     mc_error_message (&mcerror, NULL);
 789 }
 790 
 791 /* --------------------------------------------------------------------------------------------- */
 792 /**
 793  * Callback for getting directory content.
 794  *
 795  * @param me          unused
 796  * @param dir         unused
 797  * @param remote_path unused
 798  * @return always 0
 799  */
 800 
 801 static int
 802 sftpfs_cb_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, const char *remote_path)
     /* [previous][next][first][last][top][bottom][index][help]  */
 803 {
 804     (void) me;
 805     (void) dir;
 806     (void) remote_path;
 807 
 808     return 0;
 809 }
 810 
 811 /* --------------------------------------------------------------------------------------------- */
 812 /*** public functions ****************************************************************************/
 813 /* --------------------------------------------------------------------------------------------- */
 814 /**
 815  * Initialization of SFTP Virtual File Sysytem.
 816  */
 817 
 818 void
 819 vfs_init_sftpfs (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 820 {
 821     tcp_init ();
 822 
 823     vfs_init_subclass (&sftpfs_subclass, "sftpfs", VFSF_NOLINKS | VFSF_REMOTE, "sftp");
 824 
 825     vfs_sftpfs_ops->init = sftpfs_cb_init;
 826     vfs_sftpfs_ops->done = sftpfs_cb_done;
 827 
 828     vfs_sftpfs_ops->fill_names = sftpfs_cb_fill_names;
 829 
 830     vfs_sftpfs_ops->opendir = sftpfs_cb_opendir;
 831     vfs_sftpfs_ops->readdir = sftpfs_cb_readdir;
 832     vfs_sftpfs_ops->closedir = sftpfs_cb_closedir;
 833     vfs_sftpfs_ops->mkdir = sftpfs_cb_mkdir;
 834     vfs_sftpfs_ops->rmdir = sftpfs_cb_rmdir;
 835 
 836     vfs_sftpfs_ops->stat = sftpfs_cb_stat;
 837     vfs_sftpfs_ops->lstat = sftpfs_cb_lstat;
 838     vfs_sftpfs_ops->fstat = sftpfs_cb_fstat;
 839     vfs_sftpfs_ops->readlink = sftpfs_cb_readlink;
 840     vfs_sftpfs_ops->symlink = sftpfs_cb_symlink;
 841     vfs_sftpfs_ops->link = sftpfs_cb_link;
 842     vfs_sftpfs_ops->utime = sftpfs_cb_utime;
 843     vfs_sftpfs_ops->mknod = sftpfs_cb_mknod;
 844     vfs_sftpfs_ops->chown = sftpfs_cb_chown;
 845     vfs_sftpfs_ops->chmod = sftpfs_cb_chmod;
 846 
 847     vfs_sftpfs_ops->open = sftpfs_cb_open;
 848     vfs_sftpfs_ops->read = sftpfs_cb_read;
 849     vfs_sftpfs_ops->write = sftpfs_cb_write;
 850     vfs_sftpfs_ops->close = sftpfs_cb_close;
 851     vfs_sftpfs_ops->lseek = sftpfs_cb_lseek;
 852     vfs_sftpfs_ops->unlink = sftpfs_cb_unlink;
 853     vfs_sftpfs_ops->rename = sftpfs_cb_rename;
 854     vfs_sftpfs_ops->ferrno = sftpfs_cb_errno;
 855 
 856     sftpfs_subclass.archive_same = sftpfs_archive_same;
 857     sftpfs_subclass.new_archive = sftpfs_new_archive;
 858     sftpfs_subclass.open_archive = sftpfs_open_archive;
 859     sftpfs_subclass.free_archive = sftpfs_free_archive;
 860     sftpfs_subclass.fh_new = sftpfs_fh_new;
 861     sftpfs_subclass.dir_load = sftpfs_cb_dir_load;
 862 
 863     vfs_register_class (vfs_sftpfs_ops);
 864 }
 865 
 866 /* --------------------------------------------------------------------------------------------- */

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