This source file includes following definitions.
- sftpfs_cb_init
- sftpfs_cb_done
- sftpfs_cb_open
- sftpfs_cb_opendir
- sftpfs_cb_readdir
- sftpfs_cb_closedir
- sftpfs_cb_lstat
- sftpfs_cb_stat
- sftpfs_cb_fstat
- sftpfs_cb_readlink
- sftpfs_cb_utime
- sftpfs_cb_symlink
- sftpfs_cb_mknod
- sftpfs_cb_link
- sftpfs_cb_chown
- sftpfs_cb_read
- sftpfs_cb_write
- sftpfs_cb_close
- sftpfs_cb_chmod
- sftpfs_cb_mkdir
- sftpfs_cb_rmdir
- sftpfs_cb_lseek
- sftpfs_cb_unlink
- sftpfs_cb_rename
- sftpfs_cb_errno
- sftpfs_cb_fill_names
- sftpfs_archive_same
- sftpfs_new_archive
- sftpfs_open_archive
- sftpfs_free_archive
- sftpfs_cb_dir_load
- vfs_init_sftpfs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #include <config.h>
29 #include <errno.h>
30 #include <stdlib.h>
31 #include <string.h>
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"
39
40 #include "internal.h"
41
42 #include "sftpfs.h"
43
44
45
46 struct vfs_s_subclass sftpfs_subclass;
47 struct vfs_class *vfs_sftpfs_ops = VFS_CLASS (&sftpfs_subclass);
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 static int
65 sftpfs_cb_init (struct vfs_class *me)
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
80
81
82
83
84 static void
85 sftpfs_cb_done (struct vfs_class *me)
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
97
98
99
100
101
102
103
104 static void *
105 sftpfs_cb_open (const vfs_path_t * vpath, int flags, mode_t mode)
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
175
176
177
178
179
180 static void *
181 sftpfs_cb_opendir (const vfs_path_t * vpath)
182 {
183 GError *mcerror = NULL;
184 void *ret_value;
185
186
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
197
198
199
200
201
202 static struct vfs_dirent *
203 sftpfs_cb_readdir (void *data)
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
229
230
231
232
233
234 static int
235 sftpfs_cb_closedir (void *data)
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
248
249
250
251
252
253
254 static int
255 sftpfs_cb_lstat (const vfs_path_t * vpath, struct stat *buf)
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
268
269
270
271
272
273
274 static int
275 sftpfs_cb_stat (const vfs_path_t * vpath, struct stat *buf)
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
288
289
290
291
292
293
294 static int
295 sftpfs_cb_fstat (void *data, struct stat *buf)
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
308
309
310
311
312
313
314
315 static int
316 sftpfs_cb_readlink (const vfs_path_t * vpath, char *buf, size_t size)
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
329
330
331
332
333
334
335 static int
336 sftpfs_cb_utime (const vfs_path_t * vpath, mc_timesbuf_t * times)
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
357
358
359
360
361
362
363 static int
364 sftpfs_cb_symlink (const vfs_path_t * vpath1, const vfs_path_t * vpath2)
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
377
378
379
380
381
382
383
384 static int
385 sftpfs_cb_mknod (const vfs_path_t * vpath, mode_t mode, dev_t dev)
386 {
387 (void) vpath;
388 (void) mode;
389 (void) dev;
390
391 return 0;
392 }
393
394
395
396
397
398
399
400
401
402
403 static int
404 sftpfs_cb_link (const vfs_path_t * vpath1, const vfs_path_t * vpath2)
405 {
406 (void) vpath1;
407 (void) vpath2;
408
409 return 0;
410 }
411
412
413
414
415
416
417
418
419
420
421
422 static int
423 sftpfs_cb_chown (const vfs_path_t * vpath, uid_t owner, gid_t group)
424 {
425 (void) vpath;
426 (void) owner;
427 (void) group;
428
429 return 0;
430 }
431
432
433
434
435
436
437
438
439
440
441
442 static ssize_t
443 sftpfs_cb_read (void *data, char *buffer, size_t count)
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
463
464
465
466
467
468
469
470 static ssize_t
471 sftpfs_cb_write (void *data, const char *buf, size_t nbyte)
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
485
486
487
488
489
490 static int
491 sftpfs_cb_close (void *data)
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
516
517
518
519
520
521
522 static int
523 sftpfs_cb_chmod (const vfs_path_t * vpath, mode_t mode)
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
536
537
538
539
540
541
542 static int
543 sftpfs_cb_mkdir (const vfs_path_t * vpath, mode_t mode)
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
556
557
558
559
560
561 static int
562 sftpfs_cb_rmdir (const vfs_path_t * vpath)
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
575
576
577
578
579
580
581
582 static off_t
583 sftpfs_cb_lseek (void *data, off_t offset, int whence)
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
597
598
599
600
601
602 static int
603 sftpfs_cb_unlink (const vfs_path_t * vpath)
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
616
617
618
619
620
621
622 static int
623 sftpfs_cb_rename (const vfs_path_t * vpath1, const vfs_path_t * vpath2)
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
636
637
638
639
640
641 static int
642 sftpfs_cb_errno (struct vfs_class *me)
643 {
644 (void) me;
645
646 return errno;
647 }
648
649
650
651
652
653
654
655
656
657
658 static void
659 sftpfs_cb_fill_names (struct vfs_class *me, fill_names_f func)
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
680
681
682
683
684
685
686
687
688 static gboolean
689 sftpfs_archive_same (const vfs_path_element_t * vpath_element, struct vfs_s_super *super,
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)
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
727
728
729
730
731
732
733
734 static int
735 sftpfs_open_archive (struct vfs_s_super *super, const vfs_path_t * vpath,
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
773
774
775
776
777
778 static void
779 sftpfs_free_archive (struct vfs_class *me, struct vfs_s_super *super)
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
795
796
797
798
799
800
801
802 static int
803 sftpfs_cb_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, const char *remote_path)
804 {
805 (void) me;
806 (void) dir;
807 (void) remote_path;
808
809 return 0;
810 }
811
812
813
814
815
816
817
818
819 void
820 vfs_init_sftpfs (void)
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