make getpeername() return the original socket address which before it was intercepted
[hband-tools.git] / execfuse / autosshfs / readdir
blob5ab770d478338f8ad358cb651f0c91d1bf21b3a9
1 #!/bin/bash
3 # Usage:
4 # execfuse ./autosshfs ~/mnt/ssh -o fsname=autosshfs.$USER,allow_root
6 # You have to set this in ~/.ssh/config:
7 # ControlMaster auto
8 # ControlPath ~/.ssh/ctrl/%r@%n(%h):%p.sock
10 shopt -s nullglob
12 operation=${0##*/}
14 connections_subdir=${EXECFUSE_MOUNTPOINT##*/}
15 attr_parentdir="ino=1 mode=drwxr-xr-x nlink=2 uid=0 gid=0 rdev=0 size=0 blksize=512 blocks=2 atime=0 mtime=0 ctime=0"
16 attr_rootdir="ino=1 mode=drwxr-xr-x nlink=2 uid=$UID gid=0 rdev=0 size=0 blksize=512 blocks=2 atime=0 mtime=0 ctime=0"
17 attr_entry="ino=1 mode=drwx------ nlink=1 uid=$UID gid=0 rdev=0 size=0 blksize=512 blocks=2 atime=0 mtime=0 ctime=0"
18 attr_alias="ino=1 mode=drwx------ nlink=1 uid=$UID gid=0 rdev=0 size=0 blksize=512 blocks=2 atime=0 mtime=0 ctime=0"
21 declare -A Conn
22 read_connections()
24 if [ ${#Conn[@]} = 0 ]
25 then
26 reread_connections
29 reread_connections()
31 local file name
32 Conn=()
33 for file in ~/.ssh/ctrl/*.sock
35 name=${file##*/}
36 name=${name%.*}
37 Conn[$name]=1
38 done
40 get_host_alias()
42 if [[ $1 =~ @(.+)\( ]]
43 then
44 echo "${BASH_REMATCH[1]}"
48 lock_nb()
50 _lock -n "$@"
53 lock()
55 _lock '' "$@"
58 _lock()
60 local dir="/tmp/autosshfs.$USER"
61 local flag=$1
62 shift
63 local conn=$1
64 shift
65 mkdir -p -m 0700 "$dir"
66 flock -x $flag "$dir/$conn" "$@"
69 mount_sshfs_async()
71 local conn=$1
72 local port=$2
73 local user=$3
74 local host=$4
75 local hostname=$5
76 local target=$6
77 lock_nb "mount+$conn" setsid sshfs -o Port=$port,ControlMaster=no,transform_symlinks,reconnect,Hostname="$hostname" "$user@$host:/" "$target" >/dev/null 2>&1 &
78 # -o sftp_server='sudo /usr/lib/openssh/sftp-server'
82 if [ "$operation" = getattr ]
83 then
84 if [ "$1" = / ]
85 then
86 printf "$attr_rootdir"
87 exit 0
88 else
89 read_connections
90 for conn in "${!Conn[@]}"
92 if [ "$1" = "/$conn" ]
93 then
94 printf "$attr_entry"
95 exit 0
96 else
97 hostalias=`get_host_alias "$conn"`
98 if [ "$1" = "/$hostalias" ]
99 then
100 printf "$attr_alias"
101 exit 0
104 done
105 exit 1
108 elif [ "$operation" = readdir ]
109 then
110 # first umount all dead connections
111 cat /proc/mounts |\
112 while read -r dev mp rest
114 if [[ $mp =~ ^(.+)/([^/]+)$ ]]
115 then
116 dir=${BASH_REMATCH[1]}
117 subdir=${BASH_REMATCH[2]}
118 if [ "$dir" = "$EXECFUSE_MOUNTPOINT" ]
119 then
120 read_connections
121 if [ -z "${Conn[$subdir]}" ]
122 then
123 lock_nb "umount+$subdir" setsid fusermount -u -z "$mp" >/dev/null 2>&1 &
127 done
129 # list directories to each ssh connection when listing the root directory
130 if [ "$1" = / ]
131 then
132 printf "$attr_rootdir .\0"
133 printf "$attr_parentdir ..\0"
135 read_connections
136 for conn in "${!Conn[@]}"
138 printf "$attr_entry %s\0" "$conn"
139 hostalias=`get_host_alias "$conn"`
140 ln -snf "$connections_subdir/$conn" "$EXECFUSE_MOUNTPOINT/../$hostalias"
141 done
143 exit 0
145 # when listing a subdirectory, mount the corresponding sshfs under it.
146 # and return async, so you need to chdir to the directory again to get the actual content.
147 else
148 printf "$attr_entry .\0"
149 printf "$attr_rootdir ..\0"
151 read_connections
152 for conn in "${!Conn[@]}"
154 if [ "/$conn" = "$1" ]
155 then
156 if [[ $conn =~ ^([^@]+)@([^\(]+)\(([^\)]+)\):([0-9]+) ]]
157 then
158 user=${BASH_REMATCH[1]}
159 host=${BASH_REMATCH[2]}
160 hostname=${BASH_REMATCH[3]}
161 port=${BASH_REMATCH[4]}
163 mount_sshfs_async "$conn" "$port" "$user" "$host" "$hostname" "$EXECFUSE_MOUNTPOINT$1"
164 exit 0
167 done
169 exit 1