You are not logged in.

#1 2009-08-07 17:15:59

Shapeshifter
Member
Registered: 2008-03-11
Posts: 230

"samba-discovery". An automounter script for windows shares

Hi.

At the last lan party I found it quite annoying to mount samba shares by hand all the time (as I don't use a smb capable browser with fuse like dolphin or the like). So here's what I've come up with. Explenations on how it works are at the start of the script. You can also download it directly from here. Basically you run it and anything available on the lan will be tidily mounted to /mnt/samba-discovery/*.

#!/bin/bash

# Hi and welcome to this samba/windows share automounting script.
#
# It will:
# - Scan the network for windows/samba hosts.
# - Mount all their available guest shares
# - If rerun it will check if all shares are still accesible
# - Unmount everything if you use the -u option
#
# It will not:
# - Work on password protected shares. No idea what will happen,
#   I guess mount.cifs will spit an error but the script will continue
#
# Run it without options to mount/rescan, use -u to unmount everything.
#
# Before running it please specify the options below.
#
# Post questions on the Archlinux forum: http://bbs.archlinux.org/viewtopic.php?pid=596979#p596979
#
# MOST IMPORTANTLY: If it eats all your files for breakfast, it's none
# of my responsibility! It should be quite safe though because it's 
# always checking if a dir is empty before deleting it. 



### Options

# Specify the name of your network adapter (e.g. eth0):
netiface='eth0'
# Specify which range of IPs you're interested in (less is faster)
lowend=1
highend=20



### Code

# Prepare samba-discovery folder
if [[ ! -d /mnt/samba-discovery/ ]]; then
    mkdir /mnt/samba-discovery
fi

# Unmount all shares and clean up directories using -u
umountcount=0
uhostcount=0
if [[ $1 == "-u" ]]; then
    shopt -s nullglob dotglob
    dirs=(/mnt/samba-discovery/*)
    (( ${#dirs[@]} )) || sharefolders=1
    shopt -u nullglob dotglob
    if [[ ! $sharefolders == 1 ]]; then
        for i in /mnt/samba-discovery/*/*; do
            umount "$i" 2>/dev/null
            cd "$i" 2>/dev/null
            shopt -s nullglob dotglob
            files=(*)
            (( ${#files[*]} )) || dirempty=1
            shopt -u nullglob dotglob
            if [[ ! $dirempty == 1 ]]; then
                echo ">>> warning: target directory not empty although share unmounted"
                echo ">>> aborting. please investigate directory:"
                echo "    $i"
                exit 1
            else
                dirempty=0
                rm -R "$i"
                echo "  share on $i unmounted, folder removed."
                ((umountcount++))
            fi
        done
        for i in /mnt/samba-discovery/*; do
            umount "$i" 2>/dev/null
            cd "$i" 2>/dev/null
            shopt -s nullglob dotglob
            files=(*)
            (( ${#files[*]} )) || dirempty=1
            shopt -u nullglob dotglob
            if [[ ! $dirempty == 1 ]]; then
                echo ">>> warning: target directory not empty although all shares unmounted"
                echo ">>> aborting. please investigate directory:"
                echo "    $i"
                exit 1
            else
                dirempty=0
                rm -R "$i"
                echo "  parent folder $i removed."
                ((uhostcount++))
            fi
        done
        echo "-> Removed $umountcount shares and $uhostcount parent folders" 
        exit 0
    else
        echo "no parent folder found, nothing to unmount"
        exit 0
    fi
fi

# Normal run. Scan for shares which are no longer on the network...
if [[ ! $1 == "" ]]; then
    echo "Invalid option. Aborted"
    exit 1
fi
shopt -s nullglob dotglob
dirs=(/mnt/samba-discovery/*)
(( ${#dirs[@]} )) || sharefolders=1
shopt -u nullglob dotglob
if [[ ! $sharefolders == 1 ]]; then
    echo ':: Cleaning up orphaned shares...'
    cleancount=0
    for i in /mnt/samba-discovery/*/*; do 
        if [[ ! $(ls $i 2>/dev/null) ]]; then
            umount "$i" 2>/dev/null
            cd "$i" 2>/dev/null
            shopt -s nullglob dotglob
            files=(*)
            (( ${#files[*]} )) || dirempty=1
            shopt -u nullglob dotglob
            if [[ ! $dirempty == 1 ]]; then
                echo ">>> warning: target directory not empty although share unmounted"
                echo ">>> aborting. please investigate directory:"
                echo "    $i"
                exit 1
            else
                dirempty=0
                rm -R "$i"
                echo "  share on $i no longer accesible, removed."
                ((cleancount++))
            fi
        else
            if [[ ! $(cat /proc/mounts | grep "cifs" | awk '{print $2}' | grep $i) ]]; then
                cd "$i" 2>/dev/null
                shopt -s nullglob dotglob
                files=(*)
                (( ${#files[*]} )) || dirempty=1
                shopt -u nullglob dotglob
                if [[ ! $dirempty == 1 ]]; then
                    echo ">>> warning: target directory not empty although nothing mounted there"
                    echo ">>> aborting. please investigate directory:"
                    echo "    $i"
                    exit 1
                else
                    dirempty=0
                    rm -R "$i"
                    echo "  nothing mounted on $i, removed."
                    ((cleancount++))
                fi
            fi
        fi
    done
    echo "-> Cleaned out $cleancount shares" 
fi

# ... and then scan for new hosts and mount shares
echo ':: Scanning for new hosts and shares...'
netaddr=$(ifconfig eth0 | grep "inet addr" | awk '{print $2}' | awk -F ":" '{print $2}' | awk -F "." '{print $1"."$2"."$3}')
hostcount=0
sharecount=0
for ((ip=$lowend; ip<=$highend; ip++)); do
    printf " scanning $netaddr.$ip...\r"
    if (( $(nmap -PN -p139,445 "$netaddr.$ip" | grep -e "139/tcp open" -e "445/tcp open" | wc -l) == 2 )); then
        hostwinname="$( nmblookup -A $netaddr.$ip | grep "<00>" | grep -v "<GROUP>" | awk '{print $1}')"
        hostdirname="$(echo $hostwinname | tr [:upper:] [:lower:])"
        echo " found $hostwinname on $netaddr.$ip"
        IFS=$'\n' shares=($(smbclient -N -gL \\\\$netaddr.$ip\\ 2>&1 | grep -e "Disk|" | grep -v '\$' | awk -F "|" '{print $2}'))
        for share in ${shares[*]}; do
            sharedir="$(echo $share | sed s/\ /_/g | tr [:upper:] [:lower:])"
            if [[ "$(cat /proc/mounts | grep ",unc=\\\\\\\\$netaddr.$ip\\\\$share,")" ]]; then
                echo "  share "$share" already mounted in /mnt/samba-discovery/$hostdirname/$sharedir"
            else
                if [[ ! -d "/mnt/samba-discovery/$hostdirname" ]]; then
                    mkdir "/mnt/samba-discovery/$hostdirname"
                    #echo "$hostwinname:$hostdirname:$netaddr.$ip" >> /mnt/samba-discovery/$hostdirname/ip.txt
                fi
                if [[ ! -d "/mnt/samba-discovery/$hostdirname/$sharedir" ]]; then
                    mkdir "/mnt/samba-discovery/$hostdirname/$sharedir"
                else
                    cd "/mnt/samba-discovery/$hostdirname/$sharedir"
                    shopt -s nullglob dotglob
                    files=(*)
                    (( ${#files[*]} )) || dirempty=1
                    shopt -u nullglob dotglob
                    if [[ ! $dirempty == 1 ]]; then
                        echo ">>> warning: mounting directory not empty although share not mounted!"
                        echo ">>> aborting. please investigate directory:"
                        echo "    /mnt/samba-discovery/$hostdirname/$sharedir"
                        exit 1
                    fi
                    dirempty=0
                fi
                mount "//192.168.1.$ip/$share" "/mnt/samba-discovery/$hostdirname/$sharedir" -o guest 2>/dev/null
                echo "  mounted "$share" in /mnt/samba-discovery/$hostdirname/$sharedir"
                ((sharecount++))
            fi
        done
        ((hostcount++))
    fi
done
echo "-> Mounted $sharecount shares from $hostcount hosts."

# Remove samba-discovery folder if it is empty
if [[ -d /mnt/samba-discovery/ ]]; then
    cd "/mnt/samba-discovery/"
    shopt -s nullglob dotglob
    files=(*)
    (( ${#files[*]} )) || sambadirempty=1
    shopt -u nullglob dotglob
    if [[ sambadirempty == 1 ]]; then
        rm -R /mnt/samba-discovery/
    fi
fi

Here's some sample output of how it will look, including one orphaned share and a new one on a rerun of the script:

[root@Mothership samba-discovery]# /home/medja/scripts/samba-discovery
:: Cleaning up orphaned shares...
  share on /mnt/samba-discovery/blackrabbit/conflict_denied_ops no longer accesible, removed.
-> Cleaned out 1 shares
:: Scanning for new hosts and shares...
 found BLACKRABBIT on 192.168.1.2
  share CD-Images already mounted in /mnt/samba-discovery/blackrabbit/cd-images
  share CD-Images2 already mounted in /mnt/samba-discovery/blackrabbit/cd-images2
  share Filme already mounted in /mnt/samba-discovery/blackrabbit/filme
  share Filme2 already mounted in /mnt/samba-discovery/blackrabbit/filme2
  mounted Music Library in /mnt/samba-discovery/blackrabbit/music_library
 found MOTHERSHIP on 192.168.1.4
  share space already mounted in /mnt/samba-discovery/mothership/space
 found EEE on 192.168.1.5
  share SharedDocs already mounted in /mnt/samba-discovery/eee/shareddocs
-> Mounted 1 shares from 3 hosts.

Last edited by Shapeshifter (2009-08-07 18:51:05)

Offline

#2 2009-08-07 21:42:36

Heller_Barde
Member
Registered: 2008-04-01
Posts: 245

Re: "samba-discovery". An automounter script for windows shares

thanks a lot, i wanted to write that script for a long time, but never got around. one thing though, you shouldn't mount stuff in a subfolder of /mnt because /mnt itself should be kept for such purposes (unix file hierarchy standards, afaik)

but that should be easily fixed by myself smile

cheers
Phil

Last edited by Heller_Barde (2009-08-07 21:42:46)

Offline

#3 2009-08-07 21:53:15

Shapeshifter
Member
Registered: 2008-03-11
Posts: 230

Re: "samba-discovery". An automounter script for windows shares

Huh? Should I use /media/ instead? Or what folder?

Offline

#4 2009-08-07 22:31:40

fukawi2
Ex-Administratorino
From: .vic.au
Registered: 2007-09-28
Posts: 6,217
Website

Re: "samba-discovery". An automounter script for windows shares

Looks good, Heller_Barde is saying you should mount everything directly in /mnt instead of in /mnt/samba-discovery but IMHO I don't see any problems with doing it the way you've done - you are still mounting in /mnt.

You could make it a configuration option for where to mount it:

MOUNT_DIR='/mnt/samba-discovery'

Then replace all instances of /mnt/samba-discovery with $MOUNT_DIR

Offline

#5 2009-08-07 22:33:36

Shapeshifter
Member
Registered: 2008-03-11
Posts: 230

Re: "samba-discovery". An automounter script for windows shares

Ah I see. Will do that.

Offline

#6 2013-02-03 00:25:53

MOCKBA
Member
Registered: 2013-02-02
Posts: 2

Re: "samba-discovery". An automounter script for windows shares

I can see line as
netiface='eth0'

However below I can see

netaddr=$(ifconfig eth0 | grep "inet addr" | awk '{print $2}' | awk -F ":" '{print $2}' | awk -F "." '{print $1"."$2"."$3}')

So you have eth0 hardcoded. Is it okay, it is as it supposed to work or you meant $netiface?

Is it any way to discover current connection too, if it is only one. For example I have wlan0 most time and it is only one, so I would like to avoid any changing script.

Offline

Board footer

Powered by FluxBB