summaryrefslogtreecommitdiff
path: root/contrib/mount
blob: e4a743722b102323bc8b87a8680c3938410128cd (plain)
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# mount(8) completion. This will pull a list of possible mounts out of
# /etc/{,v}fstab, unless the word being completed contains a ':', which
# would indicate the specification of an NFS server. In that case, we
# query the server for a list of all available exports and complete on
# that instead.
#
have mount &&
{

# Just like COMPREPLY=(`compgen -W "${COMPREPLY[*]}" -- "$cur"`), only better!
#
# This will correctly escape special characters in COMPREPLY.
_reply_compgen_array()
{
    # Create the argument for compgen -W by escaping twice.
    #
    # One round of escape is because we want to reply with escaped arguments. A
    # second round is required because compgen -W will helpfully expand it's
    # argument.
    local i wlist
    for i in ${!COMPREPLY[*]}; do
        local q=$(quote "$(printf %q "${COMPREPLY[$i]}")")
        wlist+=$q$'\n'
    done

    # We also have to add another round of escaping to $cur.
    local ecur="$cur"
    ecur="${ecur//\\/\\\\}"
    ecur="${ecur//\'/\'}"

    # Actually generate completions.
    local oldifs=$IFS
    IFS=$'\n' eval 'COMPREPLY=(`compgen -W "$wlist" -- "${ecur}"`)'
    IFS=$oldifs
}

# Unescape strings in the linux fstab(5) format (with octal escapes).
__linux_fstab_unescape() {
    eval $1="'${!1//\'/\047}'"
    eval $1="'${!1/%\\/\\\\}'"
    eval "$1=$'${!1}'"
}

# Complete linux fstab entries.
#
# Reads a file from stdin in the linux fstab(5) format; as used by /etc/fstab
# and /proc/mounts.
_linux_fstab()
{
    COMPREPLY=()

    # Read and unescape values into COMPREPLY
    local fs_spec fs_file fs_other
    while read -r fs_spec fs_file fs_other; do
        __linux_fstab_unescape fs_spec
        __linux_fstab_unescape fs_file
        if [[ $fs_spec = [#]* ]]; then continue; fi
        local oldifs="$IFS"
        IFS=$'\0'
        [[ $fs_spec = */* ]] && COMPREPLY+=("$fs_spec");
        [[ $fs_file = */* ]] && COMPREPLY+=("$fs_file");
        IFS="$oldifs"
    done

    _reply_compgen_array
}

_mount()
{
    local cur sm host prev

    COMPREPLY=()
    cur=`_get_cword ':'`
    prev=`_get_pword ':'`
    [[ "$cur" == \\ ]] && cur="/"

    if [[ "$cur" == *:* ]]; then
        for sm in $(type -P showmount) {,/usr}/{,s}bin/showmount; do
            [ -x "$sm" ] || continue
            COMPREPLY=( $( compgen -W "$( "$sm" -e ${cur%%:*} | \
                awk 'NR>1 {print $1}' )" -- "${cur#*:}" ) )
            return 0
        done
    fi

    if [[ "$cur" == //* ]]; then
        host=${cur#//}
        host=${host%%/*}
        if [ -n "$host" ]; then
            COMPREPLY=( $( compgen -P "//$host" -W \
                "$( smbclient -d 0 -NL $host 2>/dev/null |
                sed -ne '/^['"$'\t '"']*Sharename/,/^$/p' |
                sed -ne '3,$s|^[^A-Za-z]*\([^'"$'\t '"']*\).*$|/\1|p' )" \
                    -- "${cur#//$host}" ) )
        fi
    elif [ -r /etc/vfstab ]; then
        # Solaris
        COMPREPLY=( $( compgen -W "$( awk '! /^[ \t]*#/ {if ($3 ~ /\//) print $3}' /etc/vfstab )" -- "$cur" ) )
    elif [ ! -e /etc/fstab ]; then
        # probably Cygwin
        COMPREPLY=( $( compgen -W "$( mount | awk '! /^[ \t]*#/ {if ($3 ~ /\//) print $3}' )" -- "$cur" ) )
    else
        # probably Linux
        if [ $prev = -L ]; then
            COMPREPLY=( $( compgen -W '$(sed -ne "s/^[[:space:]]*LABEL=\([^[:space:]]*\).*/\1/p" /etc/fstab )' -- "$cur" ) )
        elif [ $prev = -U ]; then
            COMPREPLY=( $( compgen -W '$(sed -ne "s/^[[:space:]]*UUID=\([^[:space:]]*\).*/\1/p" /etc/fstab )' -- "$cur" ) )
        else
            _linux_fstab < /etc/fstab
        fi
    fi

    return 0
} &&
complete -F _mount -o default -o dirnames mount

# umount(8) completion. This relies on the mount point being the third
# space-delimited field in the output of mount(8)
#
have umount &&
_umount()
{
    local cur IFS=$'\n'

    COMPREPLY=()
    cur=`_get_cword`

    COMPREPLY=( $( compgen -W '$( mount | cut -d" " -f 3 )' -- "$cur" ) )

    return 0
} &&
complete -F _umount -o dirnames umount

}

# Local variables:
# mode: shell-script
# sh-basic-offset: 4
# sh-indent-comment: t
# indent-tabs-mode: nil
# End:
# ex: ts=4 sw=4 et filetype=sh