#!/usr/bin/python2

from os import execvp, fork, getlogin, kill, path, wait, waitpid
from os import P_NOWAIT
from re import compile

config_files = ('/etc/ssh/ssh_config', '~/.ssh/config')
config_files = map(path.expanduser, config_files)
config_files = filter(path.exists, config_files)
option_regex = compile('^\s*(\w+)\s+(.+)\s*$')
publications = []

class Host:
    def __init__(self, name):
        self.alias = name
        self.name = name
        self.port = 22
        self.user = getlogin()
        self.pid = 0

    def __str__(self):
        return "ssh://%(user)s@%(name)s:%(port)d/"%vars(self)

    def publish(self):
        if self.pid and 0 != waitpid(self.pid, P_NOWAIT):
            raise Exception('Published already: %s'%self)

        self.pid = fork()

        if 0 == self.pid:
            args = (
                'avahi-publish-service', 
                'Remote Terminal on %s'%self.alias,
                '_ssh._tcp', str(self.port),
                '--host=%s'%self.name, 
                'u=%s'%self.user
            )

            execvp(args[0], args)

    def unpublish(self):
        if 0 == self.pid:
            raise Exception('Not published yet: %s'%self)

        kill(self.pid, 3)

try:
    for filename in config_files:
        file = open(filename)
        host = None

        try:
            for line in file:
                match = option_regex.match(line)
                if not match: continue

                key, value = match.group(1, 2)

                if 'Host' == key:
                    if '*' != value:
                        if host: publications+= [host]

                        host = Host(value)

                elif host:
                    if 'HostName' == key:
                        host.name = value
                    elif 'Port' == key:
                        host.port = int(value)
                    elif 'User' == key:
                        host.user = value
        
            if host: publications+= [host]

        finally:
                file.close()

    if len(publications):
        for host in publications: 
            host.publish()

        try:
            wait()

        finally:
            for host in publications:
                if host.pid: host.unpublish()

except KeyboardInterrupt:
    pass

# vim: sw=4 sta et
