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 mc_timespec_t atime, mtime;
340
341 vfs_get_timespecs_from_timesbuf (times, &atime, &mtime);
342 rc = sftpfs_utime (vpath, atime.tv_sec, mtime.tv_sec, &mcerror);
343
344 mc_error_message (&mcerror, NULL);
345 return rc;
346 }
347
348
349
350
351
352
353
354
355
356
357 static int
358 sftpfs_cb_symlink (const vfs_path_t *vpath1, const vfs_path_t *vpath2)
359 {
360 int rc;
361 GError *mcerror = NULL;
362
363 rc = sftpfs_symlink (vpath1, vpath2, &mcerror);
364 mc_error_message (&mcerror, NULL);
365 return rc;
366 }
367
368
369
370
371
372
373
374
375
376
377
378 static int
379 sftpfs_cb_mknod (const vfs_path_t *vpath, mode_t mode, dev_t dev)
380 {
381 (void) vpath;
382 (void) mode;
383 (void) dev;
384
385 return 0;
386 }
387
388
389
390
391
392
393
394
395
396
397 static int
398 sftpfs_cb_link (const vfs_path_t *vpath1, const vfs_path_t *vpath2)
399 {
400 (void) vpath1;
401 (void) vpath2;
402
403 return 0;
404 }
405
406
407
408
409
410
411
412
413
414
415
416 static int
417 sftpfs_cb_chown (const vfs_path_t *vpath, uid_t owner, gid_t group)
418 {
419 (void) vpath;
420 (void) owner;
421 (void) group;
422
423 return 0;
424 }
425
426
427
428
429
430
431
432
433
434
435
436 static ssize_t
437 sftpfs_cb_read (void *data, char *buffer, size_t count)
438 {
439 int rc;
440 GError *mcerror = NULL;
441 vfs_file_handler_t *fh = VFS_FILE_HANDLER (data);
442
443 if (tty_got_interrupt ())
444 {
445 tty_disable_interrupt_key ();
446 return 0;
447 }
448
449 rc = sftpfs_read_file (fh, buffer, count, &mcerror);
450 mc_error_message (&mcerror, NULL);
451 return rc;
452 }
453
454
455
456
457
458
459
460
461
462
463
464 static ssize_t
465 sftpfs_cb_write (void *data, const char *buf, size_t nbyte)
466 {
467 int rc;
468 GError *mcerror = NULL;
469 vfs_file_handler_t *fh = VFS_FILE_HANDLER (data);
470
471 rc = sftpfs_write_file (fh, buf, nbyte, &mcerror);
472 mc_error_message (&mcerror, NULL);
473 return rc;
474 }
475
476
477
478
479
480
481
482
483
484 static int
485 sftpfs_cb_close (void *data)
486 {
487 int rc;
488 GError *mcerror = NULL;
489 struct vfs_s_super *super = VFS_FILE_HANDLER_SUPER (data);
490 vfs_file_handler_t *fh = VFS_FILE_HANDLER (data);
491
492 super->fd_usage--;
493 if (super->fd_usage == 0)
494 vfs_stamp_create (vfs_sftpfs_ops, super);
495
496 rc = sftpfs_close_file (fh, &mcerror);
497 mc_error_message (&mcerror, NULL);
498
499 if (fh->handle != -1)
500 close (fh->handle);
501
502 vfs_s_free_inode (vfs_sftpfs_ops, fh->ino);
503
504 return rc;
505 }
506
507
508
509
510
511
512
513
514
515
516 static int
517 sftpfs_cb_chmod (const vfs_path_t *vpath, mode_t mode)
518 {
519 int rc;
520 GError *mcerror = NULL;
521
522 rc = sftpfs_chmod (vpath, mode, &mcerror);
523 mc_error_message (&mcerror, NULL);
524 return rc;
525 }
526
527
528
529
530
531
532
533
534
535
536 static int
537 sftpfs_cb_mkdir (const vfs_path_t *vpath, mode_t mode)
538 {
539 int rc;
540 GError *mcerror = NULL;
541
542 rc = sftpfs_mkdir (vpath, mode, &mcerror);
543 mc_error_message (&mcerror, NULL);
544 return rc;
545 }
546
547
548
549
550
551
552
553
554
555 static int
556 sftpfs_cb_rmdir (const vfs_path_t *vpath)
557 {
558 int rc;
559 GError *mcerror = NULL;
560
561 rc = sftpfs_rmdir (vpath, &mcerror);
562 mc_error_message (&mcerror, NULL);
563 return rc;
564 }
565
566
567
568
569
570
571
572
573
574
575
576 static off_t
577 sftpfs_cb_lseek (void *data, off_t offset, int whence)
578 {
579 off_t ret_offset;
580 vfs_file_handler_t *fh = VFS_FILE_HANDLER (data);
581 GError *mcerror = NULL;
582
583 ret_offset = sftpfs_lseek (fh, offset, whence, &mcerror);
584 mc_error_message (&mcerror, NULL);
585 return ret_offset;
586 }
587
588
589
590
591
592
593
594
595
596 static int
597 sftpfs_cb_unlink (const vfs_path_t *vpath)
598 {
599 int rc;
600 GError *mcerror = NULL;
601
602 rc = sftpfs_unlink (vpath, &mcerror);
603 mc_error_message (&mcerror, NULL);
604 return rc;
605 }
606
607
608
609
610
611
612
613
614
615
616 static int
617 sftpfs_cb_rename (const vfs_path_t *vpath1, const vfs_path_t *vpath2)
618 {
619 int rc;
620 GError *mcerror = NULL;
621
622 rc = sftpfs_rename (vpath1, vpath2, &mcerror);
623 mc_error_message (&mcerror, NULL);
624 return rc;
625 }
626
627
628
629
630
631
632
633
634
635 static int
636 sftpfs_cb_errno (struct vfs_class *me)
637 {
638 (void) me;
639
640 return errno;
641 }
642
643
644
645
646
647
648
649
650
651
652 static void
653 sftpfs_cb_fill_names (struct vfs_class *me, fill_names_f func)
654 {
655 GList *iter;
656
657 (void) me;
658
659 for (iter = sftpfs_subclass.supers; iter != NULL; iter = g_list_next (iter))
660 {
661 const struct vfs_s_super *super = (const struct vfs_s_super *) iter->data;
662 GString *name;
663
664 name = vfs_path_element_build_pretty_path_str (super->path_element);
665
666 func (name->str);
667 g_string_free (name, TRUE);
668 }
669 }
670
671
672
673
674
675
676
677
678
679
680
681
682 static gboolean
683 sftpfs_archive_same (const vfs_path_element_t *vpath_element, struct vfs_s_super *super,
684 const vfs_path_t *vpath, void *cookie)
685 {
686 int result;
687 vfs_path_element_t *orig_connect_info;
688
689 (void) vpath;
690 (void) cookie;
691
692 orig_connect_info = SFTP_SUPER (super)->original_connection_info;
693
694 result = ((g_strcmp0 (vpath_element->host, orig_connect_info->host) == 0)
695 && (g_strcmp0 (vpath_element->user, orig_connect_info->user) == 0)
696 && (vpath_element->port == orig_connect_info->port));
697
698 return result;
699 }
700
701
702
703 static struct vfs_s_super *
704 sftpfs_new_archive (struct vfs_class *me)
705 {
706 sftpfs_super_t *arch;
707
708 arch = g_new0 (sftpfs_super_t, 1);
709 arch->base.me = me;
710 arch->base.name = g_strdup (PATH_SEP_STR);
711 arch->auth_type = NONE;
712 arch->config_auth_type = NONE;
713 arch->socket_handle = LIBSSH2_INVALID_SOCKET;
714
715 return VFS_SUPER (arch);
716 }
717
718
719
720
721
722
723
724
725
726
727
728 static int
729 sftpfs_open_archive (struct vfs_s_super *super, const vfs_path_t *vpath,
730 const vfs_path_element_t *vpath_element)
731 {
732 GError *mcerror = NULL;
733 sftpfs_super_t *sftpfs_super = SFTP_SUPER (super);
734 int ret_value;
735
736 (void) vpath;
737
738 if (vpath_element->host == NULL || *vpath_element->host == '\0')
739 {
740 vfs_print_message ("%s", _("sftp: Invalid host name."));
741 vpath_element->class->verrno = EPERM;
742 return -1;
743 }
744
745 sftpfs_super->original_connection_info = vfs_path_element_clone (vpath_element);
746 super->path_element = vfs_path_element_clone (vpath_element);
747
748 sftpfs_fill_connection_data_from_config (super, &mcerror);
749 if (mc_error_message (&mcerror, &ret_value))
750 {
751 vpath_element->class->verrno = ret_value;
752 return -1;
753 }
754
755 super->root =
756 vfs_s_new_inode (vpath_element->class, super,
757 vfs_s_default_stat (vpath_element->class, S_IFDIR | 0755));
758
759 ret_value = sftpfs_open_connection (super, &mcerror);
760 mc_error_message (&mcerror, NULL);
761 return ret_value;
762 }
763
764
765
766
767
768
769
770
771
772 static void
773 sftpfs_free_archive (struct vfs_class *me, struct vfs_s_super *super)
774 {
775 GError *mcerror = NULL;
776
777 (void) me;
778
779 sftpfs_close_connection (super, "Normal Shutdown", &mcerror);
780
781 vfs_path_element_free (SFTP_SUPER (super)->original_connection_info);
782
783 mc_error_message (&mcerror, NULL);
784 }
785
786
787
788
789
790
791
792
793
794
795
796 static int
797 sftpfs_cb_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, const char *remote_path)
798 {
799 (void) me;
800 (void) dir;
801 (void) remote_path;
802
803 return 0;
804 }
805
806
807
808
809
810
811
812
813 void
814 vfs_init_sftpfs (void)
815 {
816 tcp_init ();
817
818 vfs_init_subclass (&sftpfs_subclass, "sftpfs", VFSF_NOLINKS | VFSF_REMOTE, "sftp");
819
820 vfs_sftpfs_ops->init = sftpfs_cb_init;
821 vfs_sftpfs_ops->done = sftpfs_cb_done;
822
823 vfs_sftpfs_ops->fill_names = sftpfs_cb_fill_names;
824
825 vfs_sftpfs_ops->opendir = sftpfs_cb_opendir;
826 vfs_sftpfs_ops->readdir = sftpfs_cb_readdir;
827 vfs_sftpfs_ops->closedir = sftpfs_cb_closedir;
828 vfs_sftpfs_ops->mkdir = sftpfs_cb_mkdir;
829 vfs_sftpfs_ops->rmdir = sftpfs_cb_rmdir;
830
831 vfs_sftpfs_ops->stat = sftpfs_cb_stat;
832 vfs_sftpfs_ops->lstat = sftpfs_cb_lstat;
833 vfs_sftpfs_ops->fstat = sftpfs_cb_fstat;
834 vfs_sftpfs_ops->readlink = sftpfs_cb_readlink;
835 vfs_sftpfs_ops->symlink = sftpfs_cb_symlink;
836 vfs_sftpfs_ops->link = sftpfs_cb_link;
837 vfs_sftpfs_ops->utime = sftpfs_cb_utime;
838 vfs_sftpfs_ops->mknod = sftpfs_cb_mknod;
839 vfs_sftpfs_ops->chown = sftpfs_cb_chown;
840 vfs_sftpfs_ops->chmod = sftpfs_cb_chmod;
841
842 vfs_sftpfs_ops->open = sftpfs_cb_open;
843 vfs_sftpfs_ops->read = sftpfs_cb_read;
844 vfs_sftpfs_ops->write = sftpfs_cb_write;
845 vfs_sftpfs_ops->close = sftpfs_cb_close;
846 vfs_sftpfs_ops->lseek = sftpfs_cb_lseek;
847 vfs_sftpfs_ops->unlink = sftpfs_cb_unlink;
848 vfs_sftpfs_ops->rename = sftpfs_cb_rename;
849 vfs_sftpfs_ops->ferrno = sftpfs_cb_errno;
850
851 sftpfs_subclass.archive_same = sftpfs_archive_same;
852 sftpfs_subclass.new_archive = sftpfs_new_archive;
853 sftpfs_subclass.open_archive = sftpfs_open_archive;
854 sftpfs_subclass.free_archive = sftpfs_free_archive;
855 sftpfs_subclass.fh_new = sftpfs_fh_new;
856 sftpfs_subclass.dir_load = sftpfs_cb_dir_load;
857
858 vfs_register_class (vfs_sftpfs_ops);
859 }
860
861