1 |
mszeredi |
4 |
#!/usr/bin/perl |
2 |
|
|
|
3 |
|
|
use strict; |
4 |
|
|
use Net::SSH 'sshopen2'; |
5 |
|
|
use IPC::Open2; |
6 |
|
|
use Fuse; |
7 |
|
|
use Data::Dumper; |
8 |
|
|
|
9 |
|
|
my ($host, $dir, $mount) = @ARGV; |
10 |
|
|
if(!defined($mount)) { |
11 |
|
|
$mount = $dir; |
12 |
|
|
if($host =~ /^(.*):(.*)$/) { |
13 |
|
|
($host,$dir) = ($1,$2); |
14 |
|
|
} else { |
15 |
|
|
die "usage: $0 user\@host remotedir mountpoint\n". |
16 |
|
|
"or : $0 user\@host:remotedir mountpoint\n"; |
17 |
|
|
} |
18 |
|
|
} |
19 |
|
|
|
20 |
|
|
`umount $mount` unless -d $mount; |
21 |
|
|
die "mountpoint $mount isn't a directory!\n" unless -d $mount; |
22 |
|
|
|
23 |
|
|
my (%args) = (mountpoint => $mount); |
24 |
|
|
|
25 |
|
|
map { my ($str) = $_; $args{$str} = sub { netlink($str,@_) } } |
26 |
|
|
qw(getattr getdir open read write readlink unlink rmdir |
27 |
|
|
symlink rename link chown chmod truncate utime mkdir |
28 |
|
|
rmdir mknod statfs); |
29 |
|
|
|
30 |
|
|
sub connect_remote { |
31 |
|
|
sshopen2($host, *READER, *WRITER, "./rmount_remote.pl $dir") |
32 |
|
|
or die "ssh: $!\n"; |
33 |
|
|
select WRITER; |
34 |
|
|
$| = 1; |
35 |
|
|
select STDOUT; |
36 |
|
|
} |
37 |
|
|
|
38 |
|
|
$SIG{CHLD} = sub { |
39 |
|
|
use POSIX ":sys_wait_h"; |
40 |
|
|
my $kid; |
41 |
|
|
do { |
42 |
|
|
$kid = waitpid(-1,WNOHANG); |
43 |
|
|
} until $kid < 1; |
44 |
|
|
}; |
45 |
|
|
|
46 |
|
|
connect_remote; |
47 |
|
|
|
48 |
|
|
sub netlink { |
49 |
|
|
my ($str) = Dumper(\@_)."\n"; |
50 |
|
|
$str = sprintf("%08i\n%s",length($str),$str); |
51 |
|
|
while(1) { # retry as necessary |
52 |
|
|
my ($sig) = $SIG{ALRM}; |
53 |
|
|
my ($VAR1); |
54 |
|
|
$VAR1 = undef; |
55 |
|
|
eval { |
56 |
|
|
$SIG{ALRM} = sub { die "timeout\n" }; |
57 |
|
|
alarm 10; |
58 |
|
|
print WRITER $str; |
59 |
|
|
my ($len, $data); |
60 |
|
|
if(read(READER,$len,9) == 9) { |
61 |
|
|
read(READER,$data,$len-length($data),length($data)) |
62 |
|
|
while(length($data) < $len); |
63 |
|
|
eval $data; |
64 |
|
|
} |
65 |
|
|
}; |
66 |
|
|
alarm 0; |
67 |
|
|
$SIG{ALRM} = $sig; |
68 |
|
|
if(defined $VAR1) { |
69 |
|
|
return wantarray ? @{$VAR1} : $$VAR1[0]; |
70 |
|
|
} |
71 |
|
|
print STDERR "failed to send command; reconnecting ssh\n"; |
72 |
|
|
close(READER); |
73 |
|
|
close(WRITER); |
74 |
|
|
connect_remote(); |
75 |
|
|
} |
76 |
|
|
} |
77 |
|
|
|
78 |
|
|
Fuse::main(%args); |
79 |
|
|
|
80 |
|
|
netlink("bye"); |
81 |
|
|
close(READER); |
82 |
|
|
close(WRITER); |