#!/usr/bin/env python
"""
ajaxWM - the free web based window manager for remote terminals
Copyright (C) 2007 Dennis Felsing, Andreas Waidler

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

$Id: ajaxwm.py 76 2007-12-15 11:26:24Z r0q $
"""

#{{{ Imports
# Psyco really speeds up ajaxWM (well, any script written in Python), but it
# is only available for x86 and will likely _not_ get ported.
try:
    import psyco
    psyco.full()
except ImportError:
    pass

import sys
import optparse
import os
import commands

from Ssh import Ssh
import qweb
#}}}
ENCODING = 'UTF-8'
XMLSTRING = u'<?xml version="1.0" encoding="%s"?>' % ENCODING
# All themes between these two versions (including them) are valid for this
# version.
VALID_THEMES = ([0,1,0], [0,3,0])
def read(fd):#{{{
    try:
        content = os.read(fd, 65536)
        return unicode(content, ENCODING)
    except OSError:
        return u''
#}}}
def main(argv=None):#{{{
    # filling the default dynamically, because the default argument of main() 
    # is calculated right at the definition and won't get updated
    if argv is None:
        argv = sys.argv
    
    parser = optparse.OptionParser()
    parser.add_option('-d', 
                      '--daemon', 
                      dest = 'daemon', 
                      action = 'store_true',
                      help = 'run in background')
    parser.add_option('-p', 
                      '--port', 
                      dest = 'port', 
                      default = '8022', 
                      help = 'set the TCP port (default: 8022)')
    parser.add_option('-l', 
                      '--log', 
                      action = 'store_true', 
                      dest = 'log', 
                      default = 0, 
                      help = 'log requests to stderr (default: quiet mode)')
    parser.add_option('-P', 
                      '--pidfile', 
                      dest = 'pidfile', 
                      default = '/var/run/ajaxwm.pid',
                      help = 'set the pidfile (default: /var/run/ajaxwm.pid)')
    parser.add_option('-U', 
                      '--uid', 
                      dest = 'uid', 
                      help = 'set the user id')
    parser.add_option('-u', 
                      '--uncompressed', 
                      action = 'store_true',
                      dest = 'gzip', 
                      help = 'responds not compressed ' + \
                             '(lower system load, higher network load)')
    parser.add_option('-s', 
                      '--sshcmd', 
                      dest = 'sshCmd', 
                      default = 'ssh',
                      help = 'ssh client to use')
    (options, arguments) = parser.parse_args()

    ssh = Ssh(options.sshCmd) 
    if not ssh.tryCmd():
        return
       
    if options.daemon:
        # Fork a child process, so the parent (this process) can exit.
        pid = os.fork()
        
        # Child process
        if pid == 0:
            # Make the child process a session leader. (own group)
            os.setpgrp()
            
            # don't output and input anything as a daemon
            io_null = file('/dev/null', 'rw')
            os.dup2(io_null.fileno(), sys.stdin.fileno())
            os.dup2(io_null.fileno(), sys.stdout.fileno())
            os.dup2(io_null.fileno(), sys.stderr.fileno())
            
            # Running as root, but not supposed to.
            if os.getuid() == 0 and options.uid:
                try:
                    # User id really is an id.
                    os.setuid(int(options.uid))
                except:
                    # User name instead of id.
                    os.setuid(pwd.getpwnam(options.uid).pw_uid)
        
        # Parent process
        else:
            print 'http://localhost:%s/ PID: %s' % (options.port, pid)
            
            try:
                # Try to write pid to file.
                file(options.pidfile,'w+').write(str(pid)+'\n')
            except:
                # But just ignore if it's not working (permissions, space, ...)
                pass
            
            # Exit the parent process, child stays alive as daemon.
            return 0
    
    print 'http://localhost:%s/' % options.port
    
    from Server import Server
    ajaxwm = Server(not options.gzip)
    
    try:
        qweb.QWebWSGIServer(ajaxwm, ip = 'localhost',
                            port = int(options.port), threaded = 0,
                            log = options.log).serve_forever()
    except KeyboardInterrupt, e:
        print 'keyboard interrupt'
    except qweb.SocketServer.socket.error:
        print 'port %s already in use' % options.port
    
#}}}
if __name__ == '__main__':#{{{
    # sys.exit here and the return in main allows running main() in the 
    # interactive prompt without having the prompt killed with main by an 
    # exit-call, useful for testing and debugging.
    sys.exit(main())
#}}}

#------------------------------------------------------------------------------
# vim: fdm=marker ts=4 sw=4 expandtab 
