#
# This file is part of Zaplet
# Copyright 1999 - 2001 Adam Feuer <adamf@pobox.com>
#
# Zaplet is free software; you can redistribute it and/or modify
# it under the terms of the Python License as published by the
# Python Software Foundation, or GNU General Public License as published
# by the Free Software Foundation (either version 2 of the License, or
# (at your option) any later version).
#
# Zaplet 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 Zaplet; see the file COPYING-Zaplet. If not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#
# You should have received a copy of the Python License along
# with Zaplet; see the file COPYING.
#


# platform dependent code
# works on Win32 (WinNT, Win9x) and on Unix

RCS_ID =  '$Id: platform_dependent.py,v 1.6 2001/09/02 04:47:16 adamf Exp $'

import os
import sys
import re
import string


PLATFORM = None

from debug import debug


class signalHandler:
    """class for catching signals- this is for unix only"""
    def __init__(self,handler,arglist=None,message=None):
        self.handler = handler
        self.arglist = arglist
        self.message = message

    def handle_it(self,signal, stackframe):
        if self.message:
            debug.debug(1,self.message)
        if self.handler != None:
            if self.arglist == None:
                self.handler()
            else:
                apply(self.handler,self.arglist)
        return



def getWindowsPlatformName():
    """return the name of the Windows platform we're running on.
    This uses the MS approved method, GetVersionEx(); for info see:
    http://msdn.microsoft.com/

    returns two strings: platform and type.

    Platform:
    
    'NT':      for Windows NT or Windows 2000
    'Windows': for Windows 95 or Windows 98
    'Win32s':  for Windows 3.1

    Type:
    
    'WinNT':   for Windows NT Server or Workstation
    'Win2k':   for Windows 2000

    'Win95':   for Windows 95
    'Win98':   for Windows 98
    """

    import win32con
    import win32api

    majorVersion, minorVersion, buildNumber, platformId, servicePack = win32api.GetVersionEx()

    debug.debug(2,"getWindowsPlatformName: GetVersionEx returns: %d %d %d %d %s" %
                (majorVersion, minorVersion, buildNumber, platformId, servicePack))


    if platformId == win32con.VER_PLATFORM_WIN32_NT:
        SubPlatform = "NT"
        if majorVersion <= 4:
            Type = "WinNT"
        elif majorVersion == 5:
            Type = "Win2k"
        else:
            Type = "UNKNOWN"
    elif platformId == win32con.VER_PLATFORM_WIN32_WINDOWS:
        SubPlatform = "Windows"
        if (majorVersion > 4) or (majorVersion == 4 and minorVersion > 0):
            Type = "Win98"
        else:
            Type = "Win95"
    elif platformId == win32con.VER_PLATFORM_WIN32s:
        SubPlatform = "Win32s"
        Type = ""

    else:
        SubPlatform = "UNKNOWN"
        Type = "UNKNOWN"
        
    debug.debug(2,"getWindowsPlatformName: SubPlatform, Type: %s %s" % (SubPlatform, Type))
    return ("win32", SubPlatform, Type)



def getPlatformInfo():
    """return information about the platform we are on

    returns a 3-tuple:

    Platform, SubPlatform, Type

    Platform == ["unix" | "win32"]

    """

    # what platform are we on? (Win32 or Unix)
    platformName = sys.platform
    debug.debug(2,"platform: %s" % platformName)

    if platformName == "win32":
        # we are on win32
        debug.debug(2, "getnameserver: platform is Win32")
        return(getWindowsPlatformName())
        
    else:
        # we are on Unix (hopefully)
        debug.debug(2, "getnameserver: platform is Unix")
        return ("unix", platformName, None)





def windowsGetNameServer():
    """Windows platform-- return the IP address of the DNS server"""
    # we need to know if it is WinNT or Win9x since the nameserver
    #  IP numbers are in different places

    # Win32 Registry constants
    WinNT_KEYNAME = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"
    Win9x_KEYNAME = "SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP"
    VALUENAME = "NameServer"

    import win32api,win32con

    Platform, SubPlatform, Type = getWindowsPlatformName()
    debug.debug(2, "getNameServer: SubPlatform, Type: %s %s" % (SubPlatform, Type))

    KEYROOT = win32con.HKEY_LOCAL_MACHINE

    if SubPlatform == "NT":
        debug.debug(2, "getnameserver: OS is Windows NT")
        KEYNAME = WinNT_KEYNAME
    elif SubPlatform == "Windows":
        debug.debug(2, "getnameserver: OS is Windows 9x")
        KEYNAME = Win9x_KEYNAME
    elif SubPlatform == "Win32s":
        debug.debug(2, "getnameserver: OS is Win32s")
        return None
    else:
        debug.debug(2, "getnameserver: OS is UNKNOWN")
        return None

    # now get the nameserver out of the Windows registry
    keyRoot = KEYROOT
    keyName = KEYNAME
    valueName = VALUENAME

    hkey = win32api.RegOpenKey(keyRoot,keyName)
    value=''
    try:
        value, type = win32api.RegQueryValueEx(hkey,valueName)
    finally:
        win32api.RegCloseKey(hkey)
        nameservers = string.split(value, ' ')
        return nameservers[0]



def unixGetNameServer():
    """Unix platform-- return the IP address of the DNS server"""

    # see if there is a nameserver in /etc/resolv.conf
    # if so, use it-- it seems to be more reliable than localhost

    debug.debug(4,"getnameserver: osType == Unix, looking for nameserver.")

    # nsip_re = re.compile('^(nameserver)\s((\d)+\.(\d)+\.(\d)+\.(\d)+)(\s*)$')

    # no ending '$' -- conflict with kppp.
    # thanks to Rudolf Leitgeb <leitgeb@crosswinds.net>
    nsip_re = re.compile('^(nameserver)\s((\d)+\.(\d)+\.(\d)+\.(\d)+)(\s*)')
    try:
        f = open('/etc/resolv.conf','r')
        lines = f.readlines()
        f.close
    except:
        debug.debug(4,"getnameserver: file exception.")
        return None

    for l in lines:
        debug.debug(4,"getnameserver: resolv.conf line: %s" % l)
        m = nsip_re.match(l)
        if m != None:
            debug.debug(4,"getnameserver: Nameserver match: %s" % m.group(2))
            return m.group(2)

    debug.debug(4,"getnameserver: No nameserver match.")
    return None


def getNameServer():
    """get the name server IP address"""
    
    # what platform are we on? (Win32 or Unix)

    (platform, subplatform, type) = getPlatformInfo()

    if platform == "win32":
        # we are on win32
        debug.debug(2, "getnameserver: platform is Win32")
        return(windowsGetNameServer())
        
    else:
        # we are on Unix (hopefully)
        debug.debug(2, "getnameserver: platform is Unix")
        return(unixGetNameServer())



def setSighupHandler(handler,arglist=None):
    """create a handler and set it to catch SIGHUP -- only for Unix."""
    if (sys.platform != 'win32'):
        debug.debug(4,"setSighupHandler: on Unix, setting handler.")
        # we are on Unix, hopefully!
        import signal

        # make a new handler object
        h = signalHandler(handler, arglist,"caught SIGHUP")
        signal.signal(signal.SIGHUP,h.handle_it)


if __name__=='__main__':

    nameserver = getNameServer()
    print "nameserver: %s" % nameserver








