#!/usr/bin/env python import getopt import sys import os import posix import getpass # the default root to mount ssh sources # its a good idea not to place this in ~ directly DEFAULTMOUNTROOT= os.environ.get ("HOME") + os.sep + "mnt" class mnt: def __init__(self, argv): self.read_mountroot_cfg () if not os.path.exists (self.mountroot): os.mkdir (self.mountroot) print "Creating mountroot in %s" % self.mountroot self.argv = argv self.uid = os.getuid() def usage(self, short=True): if short: print """%s [-u mountpoint] [-p port] [-m mountpoint] <-a|-l|-h|user@host:path>""" % sys.argv[0] else: print """%s [OPTIONS] SOURCE OPTIONS -a Unmount all sshfs-mounts -u <mountpoint> Unmount mount -p <port> Use specified port -m <mountpoint> Don't select mountpoint automatically -l List all mounts -h This help page SOURCE is any ssh address. mnt will use the current user if no username is given. If the Path is ommitted mnt will mount the home directory. Mountpoint is always without directories, see .mntrc EXAMPLES mnt sven@deepblue mnt sven@deepblue:/home mnt -m dbroot sven@deepblue:/ mnt -p 2345 sven@deepblue mnt -u deepblue mnt -a """ % sys.argv[0] def _get_mounted_fs (self): """ _get_mounted_fs() -> [[source, mountpoint, filesystem, options, p1, p2],...] reads mtab and returns a list of mounted sshfs filesystems. """ try: lines = [line.strip("\n").split(" ") for line in open ("/etc/mtab", "r").readlines()] return [mount for mount in lines if mount[2]=="fuse.sshfs"] except: print "Could not read mtab" def read_mountroot_cfg(self): rcfile = os.environ.get ("HOME") + os.sep + ".mntrc" if os.path.exists (rcfile): try: for line in open (rcfile, "r").readlines(): if line.startswith ('mountroot='): self.mountroot = line.rsplit ("=")[1].strip("\n") except: print "Conffile existant but not readable." else: try: self.mountroot = DEFAULTMOUNTROOT open (rcfile, "w").writelines ("mountroot=%s" % DEFAULTMOUNTROOT) print "Writing default mountroot %s to .mntrc" % DEFAULTMOUNTROOT except: print "Could not write .mntrc (%s)" % rcfile def _split_ssh_source (self,source): """_split_ssh_source(source) -> (user, host, path) split the values of a ssh source, guess the missing parts of user@host:path""" try: user,hostpart = source.split("@") except ValueError: user = getpass.getuser() try: host, path = source.split(":") except: path = "." host = source else: try: host, path = hostpart.split(":") except: path = "." host = hostpart return (user, host, path) def _get_possible_mountpoint (self, user, host): """_get_possible_mountpoint (user, host) -> mountpoint guesses a possible free mountpoint and returns it.""" if not self.mountpoint: self.mountpoint = user + "-" + host mp = self.mountroot + os.path.sep + self.mountpoint return mp def do_mount (self,source): """do_mount(source) mount ssh source as local filesystem by calling sshfs""" user, host, path = self._split_ssh_source (source) mp = self._get_possible_mountpoint (user, host) if not os.path.exists (mp): os.mkdir (mp) sshfs = "%s@%s:%s" % (user, host, path) status = os.system ('sshfs -p %d -o uid=%d "%s" "%s"' % (self.port, self.uid, sshfs, mp)) if status == 0: print "%s mounted as %s" % (sshfs, self.mountpoint) else: os.rmdir (mp) def do_umount_all(self): for src,mp,fs,opts,p1,p2 in self._get_mounted_fs(): self.do_umount (mp.rsplit (os.path.sep)[-1]) def do_umount (self, mountpoint): if os.path.exists (self.mountroot + os.path.sep + mountpoint): os.system ("fusermount -u " + self.mountroot + os.path.sep + mountpoint) os.rmdir (self.mountroot + os.path.sep + mountpoint) def do_list(self): for src,mp,fs,opts,p1,p2 in self._get_mounted_fs(): print "%25s mounted on %s" % (src,mp) def main(self): try: opts, args = getopt.getopt(self.argv, "au:lp:m:h", ["all", "unmount", "list", "port", "mountpoint", "help"]) except getopt.GetoptError: self.usage() sys.exit (2) self.mountpoint=None self.port=22 for opt, arg in opts: if opt in ("-u", "--umount"): self.do_umount(arg) sys.exit(0) elif opt in ("-l", "--list"): self.do_list() sys.exit(0) elif opt in ("-h", "--help"): self.usage(short=False) sys.exit(1) elif opt in ("-a", "--all"): self.do_umount_all() sys.exit(0) elif opt in ("-p", "--port"): self.port=arg elif opt in ("-m", "--mountpoint"): self.mountpoint=arg self.do_mount (args[0]) if __name__ == '__main__': m = mnt(sys.argv[1:]) m.main()