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

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