#!/usr/bin/python

# (c) 2006 - Oliver Grawert (Canonical Ltd.)
# (c) 2006 - Scott Balneaves
#
# cdpinger - a cdrom monitoring script for ltsp local devices
#
# This software is distributed under the terms and conditions of the
# GNU General Public License. See file GPL for the full text of the license.
#

import sys
import fcntl
import os
import CDROM
import time

def make_mountpoint(mountpoint):
    mountpoint_exists=os.access(mountpoint, 0)
    if not mountpoint_exists:
        os.mkdir(mountpoint)

def remove_mountpoint(mountpoint):
    mountpoint_exists=os.access(mountpoint, 0)
    if mountpoint_exists:
        os.rmdir(mountpoint)

def manage_fstab(device, mountpoint, option):
    fd = open('/var/run/ltspfs_fstab', 'r')
    fstablines = fd.readlines()
    fd.close()
    if option=='add':
        fstablines.append(device + " " + mountpoint + " auto defaults 0 0\n")
        fd = open("/var/run/ltspfs_fstab", 'w')
        fd.writelines(fstablines)
        fd.close()
    elif option=='remove':
        for i in range(len(fstablines)):
            if fstablines[i].find(device) >= 0:
                del fstablines[i]
                fd = open("/var/run/ltspfs_fstab", 'w')
                fd.writelines(fstablines)
                fd.close()
                break

def do_ltspmount(mountpoint, option):
    fd = open('/var/run/ltspfs_fstab', 'r')
    if fd.read().find(mountpoint) > 0:
        files = os.listdir('/var/run')
        ldmsocks = [f for f in files if f.find('ldm_socket_') == 0]
        for sock in ldmsocks:
            call(['/usr/bin/ssh', '-X', '-S', sock, sock.split("_")[-1],
                  '/usr/sbin/ltspfsmounter', mountpoint, option])
    fd.close()

def main():
    devicename=sys.argv[1]
    mountpointname=devicename

    # merge default paths
    mountpoint="/var/run/drives/"+mountpointname
    device="/dev/"+devicename
    flag=False

    while True:
        if os.path.islink(device):
            make_mountpoint(mountpoint)
            f=os.open(device, os.O_RDONLY|os.O_NONBLOCK)
            fcntl.ioctl(f, CDROM.CDROM_LOCKDOOR, 0)
            stat = fcntl.ioctl(f, CDROM.CDROM_DRIVE_STATUS, 0)
            if stat == CDROM.CDS_NO_DISC or stat == CDROM.CDS_TRAY_OPEN:
                do_ltspmount(mountpoint, 'remove')
                manage_fstab(device, mountpoint, 'remove')
                flag=False
            elif stat == CDROM.CDS_DISC_OK:
                if fcntl.ioctl(f, CDROM.CDROM_MEDIA_CHANGED, 0):
                    manage_fstab(device, mountpoint, 'add')
                    do_ltspmount(mountpoint, 'add')
                    flag=True
            os.close(f)
        else:
            # clean up if necessary
            if flag:
                do_ltspmount(mountpoint, 'remove')
                flag=False
        time.sleep(3)

if __name__ == "__main__":
    # do the UNIX double-fork magic, see Stevens' "Advanced
    # Programming in the UNIX Environment" for details (ISBN 0201563177)
    try:
        pid = os.fork()
        if pid > 0:
            # exit first parent
            sys.exit(0)
    except OSError, e:
        print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror)
        sys.exit(1)

    # decouple from parent environment
    os.chdir("/")
    os.setsid()
    os.umask(0)

    # do second fork
    try:
        pid = os.fork()
        if pid > 0:
            sys.exit(0)
    except OSError, e:
        print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror)
        sys.exit(1)

    # start the daemon main loop
    main()
