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
65
66 static int
67 sftpfs_cb_init (struct vfs_class *me)
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
82
83
84
85
86 static void
87 sftpfs_cb_done (struct vfs_class *me)
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
99
100
101
102
103
104
105
106 static void *
107 sftpfs_cb_open (const vfs_path_t * vpath, int flags, mode_t mode)
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
174
175
176
177
178
179 static void *
180 sftpfs_cb_opendir (const vfs_path_t * vpath)
181 {
182 GError *mcerror = NULL;
183 void *ret_value;
184
185
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
196
197
198
199
200
201 static struct vfs_dirent *
202 sftpfs_cb_readdir (void *data)
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
228
229
230
231
232
233 static int
234 sftpfs_cb_closedir (void *data)
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
247
248
249
250
251
252
253 static int
254 sftpfs_cb_lstat (const vfs_path_t * vpath, struct stat *buf)
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
267
268
269
270
271
272
273 static int
274 sftpfs_cb_stat (const vfs_path_t * vpath, struct stat *buf)
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
287
288
289
290
291
292
293 static int
294 sftpfs_cb_fstat (void *data, struct stat *buf)
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
307
308
309
310
311
312
313
314 static int
315 sftpfs_cb_readlink (const vfs_path_t * vpath, char *buf, size_t size)
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
328
329
330
331
332
333
334 static int
335 sftpfs_cb_utime (const vfs_path_t * vpath, mc_timesbuf_t * times)
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
356
357
358
359
360
361
362 static int
363 sftpfs_cb_symlink (const vfs_path_t * vpath1, const vfs_path_t * vpath2)
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
376
377
378
379
380
381
382
383 static int
384 sftpfs_cb_mknod (const vfs_path_t * vpath, mode_t mode, dev_t dev)
385 {
386 (void) vpath;
387 (void) mode;
388 (void) dev;
389
390 return 0;
391 }
392
393
394
395
396
397
398
399
400
401
402 static int
403 sftpfs_cb_link (const vfs_path_t * vpath1, const vfs_path_t * vpath2)
404 {
405 (void) vpath1;
406 (void) vpath2;
407
408 return 0;
409 }
410
411
412
413
414
415
416
417
418
419
420
421 static int
422 sftpfs_cb_chown (const vfs_path_t * vpath, uid_t owner, gid_t group)
423 {
424 (void) vpath;
425 (void) owner;
426 (void) group;
427
428 return 0;
429 }
430
431
432
433
434
435
436
437
438
439
440
441 static ssize_t
442 sftpfs_cb_read (void *data, char *buffer, size_t count)
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
462
463
464
465
466
467
468
469 static ssize_t
470 sftpfs_cb_write (void *data, const char *buf, size_t nbyte)
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
484
485
486
487
488
489 static int
490 sftpfs_cb_close (void *data)
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
515
516
517
518
519
520
521 static int
522 sftpfs_cb_chmod (const vfs_path_t * vpath, mode_t mode)
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
535
536
537
538
539
540
541 static int
542 sftpfs_cb_mkdir (const vfs_path_t * vpath, mode_t mode)
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
555
556
557
558
559
560 static int
561 sftpfs_cb_rmdir (const vfs_path_t * vpath)
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
574
575
576
577
578
579
580
581 static off_t
582 sftpfs_cb_lseek (void *data, off_t offset, int whence)
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
596
597
598
599
600
601 static int
602 sftpfs_cb_unlink (const vfs_path_t * vpath)
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
615
616
617
618
619
620
621 static int
622 sftpfs_cb_rename (const vfs_path_t * vpath1, const vfs_path_t * vpath2)
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
635
636
637
638
639
640 static int
641 sftpfs_cb_errno (struct vfs_class *me)
642 {
643 (void) me;
644
645 return errno;
646 }
647
648
649
650
651
652
653
654
655
656
657 static void
658 sftpfs_cb_fill_names (struct vfs_class *me, fill_names_f func)
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
679
680
681
682
683
684
685
686
687 static gboolean
688 sftpfs_archive_same (const vfs_path_element_t * vpath_element, struct vfs_s_super *super,
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)
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
726
727
728
729
730
731
732
733 static int
734 sftpfs_open_archive (struct vfs_s_super *super, const vfs_path_t * vpath,
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
772
773
774
775
776
777 static void
778 sftpfs_free_archive (struct vfs_class *me, struct vfs_s_super *super)
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
794
795
796
797
798
799
800
801 static int
802 sftpfs_cb_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, const char *remote_path)
803 {
804 (void) me;
805 (void) dir;
806 (void) remote_path;
807
808 return 0;
809 }
810
811
812
813
814
815
816
817
818 void
819 vfs_init_sftpfs (void)
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