183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#!/usr/bin/env python
283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh""" This module tries to retrieve as much platform-identifying data as
483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    possible. It makes this information available via function APIs.
583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    If called from the command line, it prints the platform
783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    information concatenated as single string to stdout. The output
883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    format is useable as part of a filename.
983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
1083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh"""
1183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    This module is maintained by Marc-Andre Lemburg <mal@egenix.com>.
1283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    If you find problems, please submit bug reports/patches via the
1383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    Python bug tracker (http://bugs.python.org) and assign them to "lemburg".
1483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#
1583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    Note: Please keep this module compatible to Python 1.5.2.
1683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#
1783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    Still needed:
1883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    * more support for WinCE
1983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    * support for MS-DOS (PythonDX ?)
2083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    * support for Amiga and other still unsupported platforms running Python
2183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    * support for additional Linux distributions
2283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#
2383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    Many thanks to all those who helped adding platform-specific
2483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    checks (in no particular order):
2583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#
2683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#      Charles G Waldman, David Arnold, Gordon McMillan, Ben Darnell,
2783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#      Jeff Bauer, Cliff Crawford, Ivan Van Laningham, Josef
2883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#      Betancourt, Randall Hopper, Karl Putland, John Farrell, Greg
2983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#      Andruk, Just van Rossum, Thomas Heller, Mark R. Levinson, Mark
3083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#      Hammond, Bill Tutt, Hans Nowak, Uwe Zessin (OpenVMS support),
3183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#      Colin Kong, Trent Mick, Guido van Rossum, Anthony Baxter
3283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#
3383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    History:
3483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#
3583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    <see CVS and SVN checkin messages for history>
3683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#
3783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    1.0.7 - added DEV_NULL
3883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    1.0.6 - added linux_distribution()
3983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    1.0.5 - fixed Java support to allow running the module on Jython
4083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    1.0.4 - added IronPython support
4183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    1.0.3 - added normalization of Windows system name
4283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    1.0.2 - added more Windows support
4383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    1.0.1 - reformatted to make doc.py happy
4483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    1.0.0 - reformatted a bit and checked into Python CVS
4583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.8.0 - added sys.version parser and various new access
4683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#            APIs (python_version(), python_compiler(), etc.)
4783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.7.2 - fixed architecture() to use sizeof(pointer) where available
4883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.7.1 - added support for Caldera OpenLinux
4983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.7.0 - some fixes for WinCE; untabified the source file
5083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.6.2 - support for OpenVMS - requires version 1.5.2-V006 or higher and
5183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#            vms_lib.getsyi() configured
5283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.6.1 - added code to prevent 'uname -p' on platforms which are
5383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#            known not to support it
5483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.6.0 - fixed win32_ver() to hopefully work on Win95,98,NT and Win2k;
5583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#            did some cleanup of the interfaces - some APIs have changed
5683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.5.5 - fixed another type in the MacOS code... should have
5783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#            used more coffee today ;-)
5883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.5.4 - fixed a few typos in the MacOS code
5983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.5.3 - added experimental MacOS support; added better popen()
6083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#            workarounds in _syscmd_ver() -- still not 100% elegant
6183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#            though
6283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.5.2 - fixed uname() to return '' instead of 'unknown' in all
6383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#            return values (the system uname command tends to return
6483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#            'unknown' instead of just leaving the field emtpy)
6583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.5.1 - included code for slackware dist; added exception handlers
6683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#            to cover up situations where platforms don't have os.popen
6783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#            (e.g. Mac) or fail on socket.gethostname(); fixed libc
6883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#            detection RE
6983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.5.0 - changed the API names referring to system commands to *syscmd*;
7083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#            added java_ver(); made syscmd_ver() a private
7183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#            API (was system_ver() in previous versions) -- use uname()
7283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#            instead; extended the win32_ver() to also return processor
7383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#            type information
7483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.4.0 - added win32_ver() and modified the platform() output for WinXX
7583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.3.4 - fixed a bug in _follow_symlinks()
7683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.3.3 - fixed popen() and "file" command invokation bugs
7783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.3.2 - added architecture() API and support for it in platform()
7883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.3.1 - fixed syscmd_ver() RE to support Windows NT
7983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.3.0 - added system alias support
8083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.2.3 - removed 'wince' again... oh well.
8183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.2.2 - added 'wince' to syscmd_ver() supported platforms
8283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.2.1 - added cache logic and changed the platform string format
8383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.2.0 - changed the API to use functions instead of module globals
8483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#            since some action take too long to be run on module import
8583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    0.1.0 - first release
8683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#
8783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    You can always get the latest version of this module at:
8883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#
8983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#             http://www.egenix.com/files/python/platform.py
9083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#
9183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#    If that URL should fail, try contacting the author.
9283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
9383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh__copyright__ = """
9483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    Copyright (c) 1999-2000, Marc-Andre Lemburg; mailto:mal@lemburg.com
9583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    Copyright (c) 2000-2010, eGenix.com Software GmbH; mailto:info@egenix.com
9683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
9783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    Permission to use, copy, modify, and distribute this software and its
9883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    documentation for any purpose and without fee or royalty is hereby granted,
9983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    provided that the above copyright notice appear in all copies and that
10083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    both that copyright notice and this permission notice appear in
10183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    supporting documentation or portions thereof, including modifications,
10283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    that you make.
10383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
10483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    EGENIX.COM SOFTWARE GMBH DISCLAIMS ALL WARRANTIES WITH REGARD TO
10583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
10683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
10783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
10883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
10983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
11083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    WITH THE USE OR PERFORMANCE OF THIS SOFTWARE !
11183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
11283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh"""
11383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
11483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh__version__ = '1.0.7'
11583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
11683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport sys,string,os,re
11783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
11883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh### Globals & Constants
11983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
12083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Determine the platform's /dev/null device
12183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehtry:
12283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    DEV_NULL = os.devnull
12383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehexcept AttributeError:
12483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # os.devnull was added in Python 2.4, so emulate it for earlier
12583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Python versions
12683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if sys.platform in ('dos','win32','win16','os2'):
12783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Use the old CP/M NUL as device name
12883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        DEV_NULL = 'NUL'
12983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    else:
13083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Standard Unix uses /dev/null
13183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        DEV_NULL = '/dev/null'
13283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
13383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh### Platform specific APIs
13483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
13583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh_libc_search = re.compile(r'(__libc_init)'
13683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          '|'
13783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          '(GLIBC_([0-9.]+))'
13883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          '|'
13983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          '(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)')
14083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
14183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef libc_ver(executable=sys.executable,lib='',version='',
14283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
14383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             chunksize=2048):
14483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
14583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Tries to determine the libc version that the file executable
14683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        (which defaults to the Python interpreter) is linked against.
14783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
14883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Returns a tuple of strings (lib,version) which default to the
14983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        given parameters in case the lookup fails.
15083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
15183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Note that the function has intimate knowledge of how different
15283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        libc versions add symbols to the executable and thus is probably
15383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        only useable for executables compiled using gcc.
15483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
15583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        The file is read and scanned in chunks of chunksize bytes.
15683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
15783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
15883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if hasattr(os.path, 'realpath'):
15983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Python 2.2 introduced os.path.realpath(); it is used
16083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # here to work around problems with Cygwin not being
16183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # able to open symlinks for reading
16283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        executable = os.path.realpath(executable)
16383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    f = open(executable,'rb')
16483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    binary = f.read(chunksize)
16583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    pos = 0
16683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    while 1:
16783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m = _libc_search.search(binary,pos)
16883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if not m:
16983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            binary = f.read(chunksize)
17083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if not binary:
17183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                break
17283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            pos = 0
17383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            continue
17483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        libcinit,glibc,glibcversion,so,threads,soversion = m.groups()
17583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if libcinit and not lib:
17683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            lib = 'libc'
17783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        elif glibc:
17883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if lib != 'glibc':
17983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                lib = 'glibc'
18083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                version = glibcversion
18183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            elif glibcversion > version:
18283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                version = glibcversion
18383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        elif so:
18483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if lib != 'glibc':
18583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                lib = 'libc'
18683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                if soversion and soversion > version:
18783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    version = soversion
18883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                if threads and version[-len(threads):] != threads:
18983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    version = version + threads
19083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        pos = m.end()
19183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    f.close()
19283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return lib,version
19383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
19483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _dist_try_harder(distname,version,id):
19583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
19683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Tries some special tricks to get the distribution
19783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        information in case the default method fails.
19883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
19983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Currently supports older SuSE Linux, Caldera OpenLinux and
20083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Slackware Linux distributions.
20183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
20283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
20383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if os.path.exists('/var/adm/inst-log/info'):
20483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # SuSE Linux stores distribution information in that file
20583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        info = open('/var/adm/inst-log/info').readlines()
20683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        distname = 'SuSE'
20783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for line in info:
20883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            tv = string.split(line)
20983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if len(tv) == 2:
21083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                tag,value = tv
21183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            else:
21283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                continue
21383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if tag == 'MIN_DIST_VERSION':
21483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                version = string.strip(value)
21583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            elif tag == 'DIST_IDENT':
21683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                values = string.split(value,'-')
21783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                id = values[2]
21883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return distname,version,id
21983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
22083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if os.path.exists('/etc/.installed'):
22183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Caldera OpenLinux has some infos in that file (thanks to Colin Kong)
22283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        info = open('/etc/.installed').readlines()
22383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for line in info:
22483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            pkg = string.split(line,'-')
22583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if len(pkg) >= 2 and pkg[0] == 'OpenLinux':
22683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # XXX does Caldera support non Intel platforms ? If yes,
22783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                #     where can we find the needed id ?
22883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                return 'OpenLinux',pkg[1],id
22983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
23083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if os.path.isdir('/usr/lib/setup'):
23183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Check for slackware verson tag file (thanks to Greg Andruk)
23283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        verfiles = os.listdir('/usr/lib/setup')
23383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for n in range(len(verfiles)-1, -1, -1):
23483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if verfiles[n][:14] != 'slack-version-':
23583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                del verfiles[n]
23683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if verfiles:
23783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            verfiles.sort()
23883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            distname = 'slackware'
23983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            version = verfiles[-1][14:]
24083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            return distname,version,id
24183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
24283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return distname,version,id
24383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
24483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh_release_filename = re.compile(r'(\w+)[-_](release|version)')
24583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh_lsb_release_version = re.compile(r'(.+)'
24683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                   ' release '
24783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                   '([\d.]+)'
24883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                   '[^(]*(?:\((.+)\))?')
24983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh_release_version = re.compile(r'([^0-9]+)'
25083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                               '(?: release )?'
25183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                               '([\d.]+)'
25283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                               '[^(]*(?:\((.+)\))?')
25383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
25483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# See also http://www.novell.com/coolsolutions/feature/11251.html
25583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# and http://linuxmafia.com/faq/Admin/release-files.html
25683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# and http://data.linux-ntfs.org/rpm/whichrpm
25783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# and http://www.die.net/doc/linux/man/man1/lsb_release.1.html
25883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
25983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh_supported_dists = (
26083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    'SuSE', 'debian', 'fedora', 'redhat', 'centos',
26183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    'mandrake', 'mandriva', 'rocks', 'slackware', 'yellowdog', 'gentoo',
26283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    'UnitedLinux', 'turbolinux')
26383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
26483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _parse_release_file(firstline):
26583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
26683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Default to empty 'version' and 'id' strings.  Both defaults are used
26783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # when 'firstline' is empty.  'id' defaults to empty when an id can not
26883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # be deduced.
26983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    version = ''
27083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    id = ''
27183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
27283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Parse the first line
27383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    m = _lsb_release_version.match(firstline)
27483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if m is not None:
27583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # LSB format: "distro release x.x (codename)"
27683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return tuple(m.groups())
27783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
27883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Pre-LSB format: "distro x.x (codename)"
27983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    m = _release_version.match(firstline)
28083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if m is not None:
28183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return tuple(m.groups())
28283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
28383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Unkown format... take the first two words
28483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    l = string.split(string.strip(firstline))
28583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if l:
28683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        version = l[0]
28783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if len(l) > 1:
28883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            id = l[1]
28983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return '', version, id
29083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
29183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef linux_distribution(distname='', version='', id='',
29283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
29383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                       supported_dists=_supported_dists,
29483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                       full_distribution_name=1):
29583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
29683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Tries to determine the name of the Linux OS distribution name.
29783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
29883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        The function first looks for a distribution release file in
29983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        /etc and then reverts to _dist_try_harder() in case no
30083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        suitable files are found.
30183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
30283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        supported_dists may be given to define the set of Linux
30383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        distributions to look for. It defaults to a list of currently
30483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        supported Linux distributions identified by their release file
30583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        name.
30683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
30783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        If full_distribution_name is true (default), the full
30883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        distribution read from the OS is returned. Otherwise the short
30983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        name taken from supported_dists is used.
31083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
31183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Returns a tuple (distname,version,id) which default to the
31283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        args given as parameters.
31383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
31483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
31583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    try:
31683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        etc = os.listdir('/etc')
31783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    except os.error:
31883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Probably not a Unix system
31983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return distname,version,id
32083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    etc.sort()
32183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    for file in etc:
32283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        m = _release_filename.match(file)
32383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if m is not None:
32483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            _distname,dummy = m.groups()
32583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if _distname in supported_dists:
32683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                distname = _distname
32783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                break
32883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    else:
32983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return _dist_try_harder(distname,version,id)
33083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
33183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Read the first line
33283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    f = open('/etc/'+file, 'r')
33383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    firstline = f.readline()
33483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    f.close()
33583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    _distname, _version, _id = _parse_release_file(firstline)
33683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
33783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if _distname and full_distribution_name:
33883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        distname = _distname
33983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if _version:
34083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        version = _version
34183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if _id:
34283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        id = _id
34383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return distname, version, id
34483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
34583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# To maintain backwards compatibility:
34683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
34783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef dist(distname='',version='',id='',
34883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
34983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh         supported_dists=_supported_dists):
35083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
35183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Tries to determine the name of the Linux OS distribution name.
35283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
35383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        The function first looks for a distribution release file in
35483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        /etc and then reverts to _dist_try_harder() in case no
35583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        suitable files are found.
35683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
35783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Returns a tuple (distname,version,id) which default to the
35883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        args given as parameters.
35983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
36083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
36183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return linux_distribution(distname, version, id,
36283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                              supported_dists=supported_dists,
36383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                              full_distribution_name=0)
36483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
36583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass _popen:
36683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
36783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Fairly portable (alternative) popen implementation.
36883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
36983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        This is mostly needed in case os.popen() is not available, or
37083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        doesn't work as advertised, e.g. in Win9X GUI programs like
37183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        PythonWin or IDLE.
37283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
37383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Writing to the pipe is currently not supported.
37483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
37583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
37683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    tmpfile = ''
37783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    pipe = None
37883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    bufsize = None
37983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    mode = 'r'
38083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
38183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __init__(self,cmd,mode='r',bufsize=None):
38283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
38383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if mode != 'r':
38483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            raise ValueError,'popen()-emulation only supports read mode'
38583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        import tempfile
38683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.tmpfile = tmpfile = tempfile.mktemp()
38783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        os.system(cmd + ' > %s' % tmpfile)
38883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.pipe = open(tmpfile,'rb')
38983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.bufsize = bufsize
39083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.mode = mode
39183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
39283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def read(self):
39383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
39483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return self.pipe.read()
39583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
39683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def readlines(self):
39783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
39883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if self.bufsize is not None:
39983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            return self.pipe.readlines()
40083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
40183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def close(self,
40283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
40383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh              remove=os.unlink,error=os.error):
40483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
40583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if self.pipe:
40683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            rc = self.pipe.close()
40783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
40883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            rc = 255
40983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if self.tmpfile:
41083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
41183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                remove(self.tmpfile)
41283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except error:
41383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                pass
41483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return rc
41583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
41683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Alias
41783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    __del__ = close
41883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
41983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef popen(cmd, mode='r', bufsize=None):
42083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
42183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Portable popen() interface.
42283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
42383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Find a working popen implementation preferring win32pipe.popen
42483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # over os.popen over _popen
42583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    popen = None
42683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if os.environ.get('OS','') == 'Windows_NT':
42783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # On NT win32pipe should work; on Win9x it hangs due to bugs
42883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # in the MS C lib (see MS KnowledgeBase article Q150956)
42983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
43083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            import win32pipe
43183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except ImportError:
43283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            pass
43383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
43483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            popen = win32pipe.popen
43583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if popen is None:
43683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if hasattr(os,'popen'):
43783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            popen = os.popen
43883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Check whether it works... it doesn't in GUI programs
43983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # on Windows platforms
44083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if sys.platform == 'win32': # XXX Others too ?
44183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                try:
44283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    popen('')
44383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                except os.error:
44483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    popen = _popen
44583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
44683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            popen = _popen
44783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if bufsize is None:
44883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return popen(cmd,mode)
44983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    else:
45083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return popen(cmd,mode,bufsize)
45183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
45283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _norm_version(version, build=''):
45383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
45483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Normalize the version and build strings and return a single
45583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        version string using the format major.minor.build (or patchlevel).
45683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
45783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    l = string.split(version,'.')
45883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if build:
45983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        l.append(build)
46083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    try:
46183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        ints = map(int,l)
46283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    except ValueError:
46383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        strings = l
46483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    else:
46583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        strings = map(str,ints)
46683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    version = string.join(strings[:3],'.')
46783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return version
46883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
46983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh_ver_output = re.compile(r'(?:([\w ]+) ([\w.]+) '
47083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                         '.*'
47183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                         '\[.* ([\d.]+)\])')
47283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
47383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Examples of VER command output:
47483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#
47583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#   Windows 2000:  Microsoft Windows 2000 [Version 5.00.2195]
47683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#   Windows XP:    Microsoft Windows XP [Version 5.1.2600]
47783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#   Windows Vista: Microsoft Windows [Version 6.0.6002]
47883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#
47983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Note that the "Version" string gets localized on different
48083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Windows versions.
48183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
48283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _syscmd_ver(system='', release='', version='',
48383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
48483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh               supported_platforms=('win32','win16','dos','os2')):
48583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
48683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Tries to figure out the OS version used and returns
48783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        a tuple (system,release,version).
48883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
48983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        It uses the "ver" shell command for this which is known
49083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        to exists on Windows, DOS and OS/2. XXX Others too ?
49183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
49283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        In case this fails, the given parameters are used as
49383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        defaults.
49483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
49583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
49683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if sys.platform not in supported_platforms:
49783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return system,release,version
49883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
49983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Try some common cmd strings
50083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    for cmd in ('ver','command /c ver','cmd /c ver'):
50183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
50283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            pipe = popen(cmd)
50383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            info = pipe.read()
50483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if pipe.close():
50583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                raise os.error,'command failed'
50683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # XXX How can I suppress shell errors from being written
50783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            #     to stderr ?
50883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except os.error,why:
50983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            #print 'Command %s failed: %s' % (cmd,why)
51083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            continue
51183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except IOError,why:
51283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            #print 'Command %s failed: %s' % (cmd,why)
51383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            continue
51483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
51583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            break
51683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    else:
51783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return system,release,version
51883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
51983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Parse the output
52083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    info = string.strip(info)
52183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    m = _ver_output.match(info)
52283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if m is not None:
52383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        system,release,version = m.groups()
52483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Strip trailing dots from version and release
52583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if release[-1] == '.':
52683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            release = release[:-1]
52783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if version[-1] == '.':
52883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            version = version[:-1]
52983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Normalize the version and build strings (eliminating additional
53083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # zeros)
53183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        version = _norm_version(version)
53283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return system,release,version
53383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
53483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _win32_getvalue(key,name,default=''):
53583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
53683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Read a value for name from the registry key.
53783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
53883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        In case this fails, default is returned.
53983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
54083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
54183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    try:
54283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Use win32api if available
54383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        from win32api import RegQueryValueEx
54483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    except ImportError:
54583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # On Python 2.0 and later, emulate using _winreg
54683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        import _winreg
54783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        RegQueryValueEx = _winreg.QueryValueEx
54883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    try:
54983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return RegQueryValueEx(key,name)
55083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    except:
55183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return default
55283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
55383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef win32_ver(release='',version='',csd='',ptype=''):
55483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
55583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Get additional version information from the Windows Registry
55683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        and return a tuple (version,csd,ptype) referring to version
55783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        number, CSD level (service pack), and OS type (multi/single
55883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        processor).
55983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
56083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        As a hint: ptype returns 'Uniprocessor Free' on single
56183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        processor NT machines and 'Multiprocessor Free' on multi
56283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        processor machines. The 'Free' refers to the OS version being
56383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        free of debugging code. It could also state 'Checked' which
56483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        means the OS version uses debugging code, i.e. code that
56583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        checks arguments, ranges, etc. (Thomas Heller).
56683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
56783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Note: this function works best with Mark Hammond's win32
56883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        package installed, but also on Python 2.3 and later. It
56983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        obviously only runs on Win32 compatible platforms.
57083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
57183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
57283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # XXX Is there any way to find out the processor type on WinXX ?
57383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # XXX Is win32 available on Windows CE ?
57483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    #
57583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Adapted from code posted by Karl Putland to comp.lang.python.
57683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    #
57783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # The mappings between reg. values and release names can be found
57883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # here: http://msdn.microsoft.com/library/en-us/sysinfo/base/osversioninfo_str.asp
57983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
58083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Import the needed APIs
58183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    try:
58283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        import win32api
58383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        from win32api import RegQueryValueEx, RegOpenKeyEx, \
58483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             RegCloseKey, GetVersionEx
58583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        from win32con import HKEY_LOCAL_MACHINE, VER_PLATFORM_WIN32_NT, \
58683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             VER_PLATFORM_WIN32_WINDOWS, VER_NT_WORKSTATION
58783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    except ImportError:
58883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Emulate the win32api module using Python APIs
58983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
59083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            sys.getwindowsversion
59183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except AttributeError:
59283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # No emulation possible, so return the defaults...
59383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            return release,version,csd,ptype
59483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
59583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Emulation using _winreg (added in Python 2.0) and
59683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # sys.getwindowsversion() (added in Python 2.3)
59783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            import _winreg
59883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            GetVersionEx = sys.getwindowsversion
59983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            RegQueryValueEx = _winreg.QueryValueEx
60083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            RegOpenKeyEx = _winreg.OpenKeyEx
60183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            RegCloseKey = _winreg.CloseKey
60283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            HKEY_LOCAL_MACHINE = _winreg.HKEY_LOCAL_MACHINE
60383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            VER_PLATFORM_WIN32_WINDOWS = 1
60483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            VER_PLATFORM_WIN32_NT = 2
60583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            VER_NT_WORKSTATION = 1
60683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            VER_NT_SERVER = 3
60783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            REG_SZ = 1
60883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
60983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Find out the registry key and some general version infos
61083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    winver = GetVersionEx()
61183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    maj,min,buildno,plat,csd = winver
61283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    version = '%i.%i.%i' % (maj,min,buildno & 0xFFFF)
61383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if hasattr(winver, "service_pack"):
61483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if winver.service_pack != "":
61583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            csd = 'SP%s' % winver.service_pack_major
61683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    else:
61783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if csd[:13] == 'Service Pack ':
61883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            csd = 'SP' + csd[13:]
61983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
62083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if plat == VER_PLATFORM_WIN32_WINDOWS:
62183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        regkey = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion'
62283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Try to guess the release name
62383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if maj == 4:
62483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if min == 0:
62583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                release = '95'
62683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            elif min == 10:
62783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                release = '98'
62883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            elif min == 90:
62983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                release = 'Me'
63083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            else:
63183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                release = 'postMe'
63283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        elif maj == 5:
63383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            release = '2000'
63483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
63583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    elif plat == VER_PLATFORM_WIN32_NT:
63683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        regkey = 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion'
63783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if maj <= 4:
63883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            release = 'NT'
63983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        elif maj == 5:
64083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if min == 0:
64183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                release = '2000'
64283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            elif min == 1:
64383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                release = 'XP'
64483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            elif min == 2:
64583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                release = '2003Server'
64683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            else:
64783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                release = 'post2003'
64883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        elif maj == 6:
64983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if hasattr(winver, "product_type"):
65083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                product_type = winver.product_type
65183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            else:
65283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                product_type = VER_NT_WORKSTATION
65383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # Without an OSVERSIONINFOEX capable sys.getwindowsversion(),
65483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # or help from the registry, we cannot properly identify
65583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # non-workstation versions.
65683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                try:
65783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    key = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regkey)
65883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    name, type = RegQueryValueEx(key, "ProductName")
65983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    # Discard any type that isn't REG_SZ
66083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    if type == REG_SZ and name.find("Server") != -1:
66183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        product_type = VER_NT_SERVER
66283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                except WindowsError:
66383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    # Use default of VER_NT_WORKSTATION
66483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    pass
66583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
66683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if min == 0:
66783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                if product_type == VER_NT_WORKSTATION:
66883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    release = 'Vista'
66983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                else:
67083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    release = '2008Server'
67183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            elif min == 1:
67283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                if product_type == VER_NT_WORKSTATION:
67383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    release = '7'
67483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                else:
67583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    release = '2008ServerR2'
67683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            elif min == 2:
67783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                if product_type == VER_NT_WORKSTATION:
67883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    release = '8'
67983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                else:
68083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    release = '2012Server'
68183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            else:
68283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                release = 'post2012Server'
68383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
68483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    else:
68583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if not release:
68683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # E.g. Win3.1 with win32s
68783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            release = '%i.%i' % (maj,min)
68883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return release,version,csd,ptype
68983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
69083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Open the registry key
69183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    try:
69283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        keyCurVer = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regkey)
69383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Get a value to make sure the key exists...
69483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        RegQueryValueEx(keyCurVer, 'SystemRoot')
69583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    except:
69683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return release,version,csd,ptype
69783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
69883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Parse values
69983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    #subversion = _win32_getvalue(keyCurVer,
70083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    #                            'SubVersionNumber',
70183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    #                            ('',1))[0]
70283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    #if subversion:
70383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    #   release = release + subversion # 95a, 95b, etc.
70483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    build = _win32_getvalue(keyCurVer,
70583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                            'CurrentBuildNumber',
70683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                            ('',1))[0]
70783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    ptype = _win32_getvalue(keyCurVer,
70883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                           'CurrentType',
70983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                           (ptype,1))[0]
71083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
71183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Normalize version
71283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    version = _norm_version(version,build)
71383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
71483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Close key
71583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    RegCloseKey(keyCurVer)
71683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return release,version,csd,ptype
71783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
71883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _mac_ver_lookup(selectors,default=None):
71983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
72083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    from gestalt import gestalt
72183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    import MacOS
72283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    l = []
72383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    append = l.append
72483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    for selector in selectors:
72583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
72683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            append(gestalt(selector))
72783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except (RuntimeError, MacOS.Error):
72883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            append(default)
72983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return l
73083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
73183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _bcd2str(bcd):
73283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
73383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return hex(bcd)[2:]
73483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
73583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _mac_ver_gestalt():
73683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
73783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Thanks to Mark R. Levinson for mailing documentation links and
73883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        code examples for this function. Documentation for the
73983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        gestalt() API is available online at:
74083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
74183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh           http://www.rgaros.nl/gestalt/
74283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
74383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Check whether the version info module is available
74483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    try:
74583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        import gestalt
74683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        import MacOS
74783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    except ImportError:
74883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return None
74983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Get the infos
75083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    sysv,sysa = _mac_ver_lookup(('sysv','sysa'))
75183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Decode the infos
75283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if sysv:
75383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        major = (sysv & 0xFF00) >> 8
75483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        minor = (sysv & 0x00F0) >> 4
75583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        patch = (sysv & 0x000F)
75683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
75783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if (major, minor) >= (10, 4):
75883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # the 'sysv' gestald cannot return patchlevels
75983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # higher than 9. Apple introduced 3 new
76083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # gestalt codes in 10.4 to deal with this
76183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # issue (needed because patch levels can
76283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # run higher than 9, such as 10.4.11)
76383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            major,minor,patch = _mac_ver_lookup(('sys1','sys2','sys3'))
76483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            release = '%i.%i.%i' %(major, minor, patch)
76583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
76683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            release = '%s.%i.%i' % (_bcd2str(major),minor,patch)
76783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
76883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if sysa:
76983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        machine = {0x1: '68k',
77083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                   0x2: 'PowerPC',
77183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                   0xa: 'i386'}.get(sysa,'')
77283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
77383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    versioninfo=('', '', '')
77483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return release,versioninfo,machine
77583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
77683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _mac_ver_xml():
77783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    fn = '/System/Library/CoreServices/SystemVersion.plist'
77883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if not os.path.exists(fn):
77983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return None
78083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
78183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    try:
78283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        import plistlib
78383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    except ImportError:
78483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return None
78583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
78683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    pl = plistlib.readPlist(fn)
78783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    release = pl['ProductVersion']
78883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    versioninfo=('', '', '')
78983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    machine = os.uname()[4]
79083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if machine in ('ppc', 'Power Macintosh'):
79183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # for compatibility with the gestalt based code
79283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        machine = 'PowerPC'
79383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
79483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return release,versioninfo,machine
79583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
79683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
79783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef mac_ver(release='',versioninfo=('','',''),machine=''):
79883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
79983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Get MacOS version information and return it as tuple (release,
80083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        versioninfo, machine) with versioninfo being a tuple (version,
80183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        dev_stage, non_release_version).
80283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
80383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Entries which cannot be determined are set to the paramter values
80483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        which default to ''. All tuple entries are strings.
80583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
80683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
80783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # First try reading the information from an XML file which should
80883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # always be present
80983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    info = _mac_ver_xml()
81083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if info is not None:
81183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return info
81283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
81383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # If that doesn't work for some reason fall back to reading the
81483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # information using gestalt calls.
81583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    info = _mac_ver_gestalt()
81683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if info is not None:
81783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return info
81883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
81983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # If that also doesn't work return the default values
82083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return release,versioninfo,machine
82183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
82283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _java_getprop(name,default):
82383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
82483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    from java.lang import System
82583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    try:
82683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        value = System.getProperty(name)
82783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if value is None:
82883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            return default
82983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return value
83083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    except AttributeError:
83183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return default
83283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
83383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef java_ver(release='',vendor='',vminfo=('','',''),osinfo=('','','')):
83483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
83583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Version interface for Jython.
83683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
83783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Returns a tuple (release,vendor,vminfo,osinfo) with vminfo being
83883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        a tuple (vm_name,vm_release,vm_vendor) and osinfo being a
83983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        tuple (os_name,os_version,os_arch).
84083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
84183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Values which cannot be determined are set to the defaults
84283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        given as parameters (which all default to '').
84383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
84483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
84583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Import the needed APIs
84683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    try:
84783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        import java.lang
84883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    except ImportError:
84983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return release,vendor,vminfo,osinfo
85083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
85183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    vendor = _java_getprop('java.vendor', vendor)
85283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    release = _java_getprop('java.version', release)
85383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    vm_name, vm_release, vm_vendor = vminfo
85483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    vm_name = _java_getprop('java.vm.name', vm_name)
85583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    vm_vendor = _java_getprop('java.vm.vendor', vm_vendor)
85683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    vm_release = _java_getprop('java.vm.version', vm_release)
85783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    vminfo = vm_name, vm_release, vm_vendor
85883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    os_name, os_version, os_arch = osinfo
85983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    os_arch = _java_getprop('java.os.arch', os_arch)
86083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    os_name = _java_getprop('java.os.name', os_name)
86183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    os_version = _java_getprop('java.os.version', os_version)
86283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    osinfo = os_name, os_version, os_arch
86383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
86483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return release, vendor, vminfo, osinfo
86583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
86683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh### System name aliasing
86783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
86883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef system_alias(system,release,version):
86983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
87083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Returns (system,release,version) aliased to common
87183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        marketing names used for some systems.
87283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
87383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        It also does some reordering of the information in some cases
87483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        where it would otherwise cause confusion.
87583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
87683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
87783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if system == 'Rhapsody':
87883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Apple's BSD derivative
87983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # XXX How can we determine the marketing release number ?
88083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return 'MacOS X Server',system+release,version
88183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
88283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    elif system == 'SunOS':
88383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Sun's OS
88483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if release < '5':
88583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # These releases use the old name SunOS
88683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            return system,release,version
88783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Modify release (marketing release = SunOS release - 3)
88883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        l = string.split(release,'.')
88983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if l:
89083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
89183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                major = int(l[0])
89283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except ValueError:
89383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                pass
89483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            else:
89583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                major = major - 3
89683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                l[0] = str(major)
89783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                release = string.join(l,'.')
89883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if release < '6':
89983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            system = 'Solaris'
90083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
90183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # XXX Whatever the new SunOS marketing name is...
90283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            system = 'Solaris'
90383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
90483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    elif system == 'IRIX64':
90583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # IRIX reports IRIX64 on platforms with 64-bit support; yet it
90683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # is really a version and not a different platform, since 32-bit
90783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # apps are also supported..
90883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        system = 'IRIX'
90983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if version:
91083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            version = version + ' (64bit)'
91183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
91283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            version = '64bit'
91383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
91483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    elif system in ('win32','win16'):
91583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # In case one of the other tricks
91683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        system = 'Windows'
91783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
91883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return system,release,version
91983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
92083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh### Various internal helpers
92183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
92283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _platform(*args):
92383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
92483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Helper to format the platform string in a filename
92583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        compatible format e.g. "system-version-machine".
92683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
92783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Format the platform string
92883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    platform = string.join(
92983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        map(string.strip,
93083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            filter(len, args)),
93183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        '-')
93283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
93383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Cleanup some possible filename obstacles...
93483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    replace = string.replace
93583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    platform = replace(platform,' ','_')
93683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    platform = replace(platform,'/','-')
93783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    platform = replace(platform,'\\','-')
93883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    platform = replace(platform,':','-')
93983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    platform = replace(platform,';','-')
94083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    platform = replace(platform,'"','-')
94183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    platform = replace(platform,'(','-')
94283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    platform = replace(platform,')','-')
94383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
94483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # No need to report 'unknown' information...
94583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    platform = replace(platform,'unknown','')
94683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
94783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Fold '--'s and remove trailing '-'
94883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    while 1:
94983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        cleaned = replace(platform,'--','-')
95083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if cleaned == platform:
95183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            break
95283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        platform = cleaned
95383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    while platform[-1] == '-':
95483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        platform = platform[:-1]
95583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
95683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return platform
95783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
95883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _node(default=''):
95983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
96083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Helper to determine the node name of this machine.
96183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
96283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    try:
96383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        import socket
96483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    except ImportError:
96583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # No sockets...
96683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return default
96783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    try:
96883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return socket.gethostname()
96983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    except socket.error:
97083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Still not working...
97183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return default
97283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
97383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# os.path.abspath is new in Python 1.5.2:
97483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehif not hasattr(os.path,'abspath'):
97583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
97683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def _abspath(path,
97783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
97883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                 isabs=os.path.isabs,join=os.path.join,getcwd=os.getcwd,
97983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                 normpath=os.path.normpath):
98083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
98183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if not isabs(path):
98283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            path = join(getcwd(), path)
98383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return normpath(path)
98483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
98583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehelse:
98683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
98783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    _abspath = os.path.abspath
98883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
98983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _follow_symlinks(filepath):
99083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
99183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ In case filepath is a symlink, follow it until a
99283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        real file is reached.
99383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
99483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    filepath = _abspath(filepath)
99583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    while os.path.islink(filepath):
99683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        filepath = os.path.normpath(
99783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            os.path.join(os.path.dirname(filepath),os.readlink(filepath)))
99883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return filepath
99983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
100083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _syscmd_uname(option,default=''):
100183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
100283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Interface to the system's uname command.
100383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
100483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if sys.platform in ('dos','win32','win16','os2'):
100583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # XXX Others too ?
100683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return default
100783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    try:
100883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = os.popen('uname %s 2> %s' % (option, DEV_NULL))
100983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    except (AttributeError,os.error):
101083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return default
101183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    output = string.strip(f.read())
101283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    rc = f.close()
101383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if not output or rc:
101483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return default
101583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    else:
101683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return output
101783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
101883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _syscmd_file(target,default=''):
101983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
102083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Interface to the system's file command.
102183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
102283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        The function uses the -b option of the file command to have it
102383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        ommit the filename in its output and if possible the -L option
102483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        to have the command follow symlinks. It returns default in
102583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        case the command should fail.
102683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
102783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
102883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
102983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # We do the import here to avoid a bootstrap issue.
103083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # See c73b90b6dadd changeset.
103183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    #
103283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # [..]
103383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # ranlib libpython2.7.a
103483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # gcc   -o python \
103583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    #        Modules/python.o \
103683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    #        libpython2.7.a -lsocket -lnsl -ldl    -lm
103783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Traceback (most recent call last):
103883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    #  File "./setup.py", line 8, in <module>
103983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    #    from platform import machine as platform_machine
104083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    #  File "[..]/build/Lib/platform.py", line 116, in <module>
104183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    #    import sys,string,os,re,subprocess
104283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    #  File "[..]/build/Lib/subprocess.py", line 429, in <module>
104383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    #    import select
104483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # ImportError: No module named select
104583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
104683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    import subprocess
104783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
104883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if sys.platform in ('dos','win32','win16','os2'):
104983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # XXX Others too ?
105083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return default
105183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    target = _follow_symlinks(target)
105283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    try:
105383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        proc = subprocess.Popen(['file', target],
105483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
105583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
105683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    except (AttributeError,os.error):
105783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return default
105883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    output = proc.communicate()[0]
105983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    rc = proc.wait()
106083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if not output or rc:
106183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return default
106283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    else:
106383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return output
106483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
106583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh### Information about the used architecture
106683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
106783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Default values for architecture; non-empty strings override the
106883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# defaults given as parameters
106983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh_default_architecture = {
107083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    'win32': ('','WindowsPE'),
107183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    'win16': ('','Windows'),
107283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    'dos': ('','MSDOS'),
107383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh}
107483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
107583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh_architecture_split = re.compile(r'[\s,]').split
107683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
107783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef architecture(executable=sys.executable,bits='',linkage=''):
107883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
107983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Queries the given executable (defaults to the Python interpreter
108083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        binary) for various architecture information.
108183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
108283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Returns a tuple (bits,linkage) which contains information about
108383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        the bit architecture and the linkage format used for the
108483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        executable. Both values are returned as strings.
108583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
108683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Values that cannot be determined are returned as given by the
108783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        parameter presets. If bits is given as '', the sizeof(pointer)
108883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        (or sizeof(long) on Python version < 1.5.2) is used as
108983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        indicator for the supported pointer size.
109083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
109183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        The function relies on the system's "file" command to do the
109283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        actual work. This is available on most if not all Unix
109383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        platforms. On some non-Unix platforms where the "file" command
109483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        does not exist and the executable is set to the Python interpreter
109583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        binary defaults from _default_architecture are used.
109683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
109783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
109883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Use the sizeof(pointer) as default number of bits if nothing
109983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # else is given as default.
110083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if not bits:
110183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        import struct
110283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
110383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            size = struct.calcsize('P')
110483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except struct.error:
110583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Older installations can only query longs
110683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            size = struct.calcsize('l')
110783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        bits = str(size*8) + 'bit'
110883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
110983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Get data from the 'file' system command
111083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if executable:
111183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        output = _syscmd_file(executable, '')
111283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    else:
111383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        output = ''
111483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
111583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if not output and \
111683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh       executable == sys.executable:
111783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # "file" command did not return anything; we'll try to provide
111883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # some sensible defaults then...
111983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if sys.platform in _default_architecture:
112083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            b, l = _default_architecture[sys.platform]
112183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if b:
112283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                bits = b
112383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if l:
112483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                linkage = l
112583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return bits, linkage
112683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
112783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Split the output into a list of strings omitting the filename
112883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    fileout = _architecture_split(output)[1:]
112983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
113083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if 'executable' not in fileout:
113183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Format not supported
113283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return bits,linkage
113383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
113483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Bits
113583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if '32-bit' in fileout:
113683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        bits = '32bit'
113783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    elif 'N32' in fileout:
113883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # On Irix only
113983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        bits = 'n32bit'
114083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    elif '64-bit' in fileout:
114183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        bits = '64bit'
114283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
114383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Linkage
114483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if 'ELF' in fileout:
114583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        linkage = 'ELF'
114683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    elif 'PE' in fileout:
114783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # E.g. Windows uses this format
114883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if 'Windows' in fileout:
114983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            linkage = 'WindowsPE'
115083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
115183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            linkage = 'PE'
115283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    elif 'COFF' in fileout:
115383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        linkage = 'COFF'
115483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    elif 'MS-DOS' in fileout:
115583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        linkage = 'MSDOS'
115683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    else:
115783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # XXX the A.OUT format also falls under this class...
115883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        pass
115983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
116083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return bits,linkage
116183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
116283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh### Portable uname() interface
116383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
116483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh_uname_cache = None
116583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
116683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef uname():
116783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
116883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Fairly portable uname interface. Returns a tuple
116983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        of strings (system,node,release,version,machine,processor)
117083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        identifying the underlying platform.
117183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
117283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Note that unlike the os.uname function this also returns
117383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        possible processor information as an additional tuple entry.
117483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
117583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Entries which cannot be determined are set to ''.
117683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
117783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
117883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    global _uname_cache
117983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    no_os_uname = 0
118083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
118183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if _uname_cache is not None:
118283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return _uname_cache
118383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
118483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    processor = ''
118583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
118683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Get some infos from the builtin os.uname API...
118783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    try:
118883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        system,node,release,version,machine = os.uname()
118983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    except AttributeError:
119083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        no_os_uname = 1
119183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
119283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if no_os_uname or not filter(None, (system, node, release, version, machine)):
119383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Hmm, no there is either no uname or uname has returned
119483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        #'unknowns'... we'll have to poke around the system then.
119583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if no_os_uname:
119683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            system = sys.platform
119783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            release = ''
119883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            version = ''
119983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            node = _node()
120083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            machine = ''
120183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
120283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        use_syscmd_ver = 1
120383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
120483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Try win32_ver() on win32 platforms
120583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if system == 'win32':
120683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            release,version,csd,ptype = win32_ver()
120783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if release and version:
120883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                use_syscmd_ver = 0
120983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Try to use the PROCESSOR_* environment variables
121083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # available on Win XP and later; see
121183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # http://support.microsoft.com/kb/888731 and
121283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # http://www.geocities.com/rick_lively/MANUALS/ENV/MSWIN/PROCESSI.HTM
121383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if not machine:
121483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # WOW64 processes mask the native architecture
121583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                if "PROCESSOR_ARCHITEW6432" in os.environ:
121683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    machine = os.environ.get("PROCESSOR_ARCHITEW6432", '')
121783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                else:
121883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    machine = os.environ.get('PROCESSOR_ARCHITECTURE', '')
121983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if not processor:
122083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                processor = os.environ.get('PROCESSOR_IDENTIFIER', machine)
122183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
122283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Try the 'ver' system command available on some
122383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # platforms
122483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if use_syscmd_ver:
122583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            system,release,version = _syscmd_ver(system)
122683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Normalize system to what win32_ver() normally returns
122783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # (_syscmd_ver() tends to return the vendor name as well)
122883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if system == 'Microsoft Windows':
122983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                system = 'Windows'
123083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            elif system == 'Microsoft' and release == 'Windows':
123183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # Under Windows Vista and Windows Server 2008,
123283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # Microsoft changed the output of the ver command. The
123383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # release is no longer printed.  This causes the
123483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                # system and release to be misidentified.
123583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                system = 'Windows'
123683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                if '6.0' == version[:3]:
123783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    release = 'Vista'
123883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                else:
123983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    release = ''
124083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
124183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # In case we still don't know anything useful, we'll try to
124283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # help ourselves
124383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if system in ('win32','win16'):
124483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if not version:
124583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                if system == 'win32':
124683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    version = '32bit'
124783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                else:
124883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    version = '16bit'
124983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            system = 'Windows'
125083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
125183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        elif system[:4] == 'java':
125283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            release,vendor,vminfo,osinfo = java_ver()
125383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            system = 'Java'
125483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            version = string.join(vminfo,', ')
125583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if not version:
125683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                version = vendor
125783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
125883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # System specific extensions
125983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if system == 'OpenVMS':
126083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # OpenVMS seems to have release and version mixed up
126183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if not release or release == '0':
126283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            release = version
126383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            version = ''
126483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Get processor information
126583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
126683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            import vms_lib
126783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except ImportError:
126883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            pass
126983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
127083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            csid, cpu_number = vms_lib.getsyi('SYI$_CPU',0)
127183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if (cpu_number >= 128):
127283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                processor = 'Alpha'
127383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            else:
127483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                processor = 'VAX'
127583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if not processor:
127683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Get processor information from the uname system command
127783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        processor = _syscmd_uname('-p','')
127883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
127983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    #If any unknowns still exist, replace them with ''s, which are more portable
128083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if system == 'unknown':
128183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        system = ''
128283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if node == 'unknown':
128383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        node = ''
128483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if release == 'unknown':
128583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        release = ''
128683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if version == 'unknown':
128783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        version = ''
128883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if machine == 'unknown':
128983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        machine = ''
129083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if processor == 'unknown':
129183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        processor = ''
129283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
129383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    #  normalize name
129483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if system == 'Microsoft' and release == 'Windows':
129583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        system = 'Windows'
129683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        release = 'Vista'
129783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
129883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    _uname_cache = system,node,release,version,machine,processor
129983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return _uname_cache
130083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
130183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh### Direct interfaces to some of the uname() return values
130283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
130383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef system():
130483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
130583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'.
130683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
130783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        An empty string is returned if the value cannot be determined.
130883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
130983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
131083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return uname()[0]
131183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
131283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef node():
131383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
131483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Returns the computer's network name (which may not be fully
131583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        qualified)
131683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
131783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        An empty string is returned if the value cannot be determined.
131883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
131983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
132083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return uname()[1]
132183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
132283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef release():
132383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
132483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Returns the system's release, e.g. '2.2.0' or 'NT'
132583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
132683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        An empty string is returned if the value cannot be determined.
132783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
132883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
132983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return uname()[2]
133083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
133183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef version():
133283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
133383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Returns the system's release version, e.g. '#3 on degas'
133483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
133583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        An empty string is returned if the value cannot be determined.
133683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
133783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
133883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return uname()[3]
133983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
134083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef machine():
134183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
134283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Returns the machine type, e.g. 'i386'
134383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
134483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        An empty string is returned if the value cannot be determined.
134583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
134683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
134783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return uname()[4]
134883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
134983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef processor():
135083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
135183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Returns the (true) processor name, e.g. 'amdk6'
135283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
135383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        An empty string is returned if the value cannot be
135483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        determined. Note that many platforms do not provide this
135583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        information or simply return the same value as for machine(),
135683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        e.g.  NetBSD does this.
135783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
135883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
135983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return uname()[5]
136083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
136183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh### Various APIs for extracting information from sys.version
136283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
136383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh_sys_version_parser = re.compile(
136483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    r'([\w.+]+)\s*'
136583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    '\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*'
136683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    '\[([^\]]+)\]?')
136783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
136883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh_ironpython_sys_version_parser = re.compile(
136983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    r'IronPython\s*'
137083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    '([\d\.]+)'
137183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    '(?: \(([\d\.]+)\))?'
137283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    ' on (.NET [\d\.]+)')
137383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
137483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh_pypy_sys_version_parser = re.compile(
137583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    r'([\w.+]+)\s*'
137683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    '\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*'
137783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    '\[PyPy [^\]]+\]?')
137883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
137983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh_sys_version_cache = {}
138083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
138183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef _sys_version(sys_version=None):
138283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
138383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Returns a parsed version of Python's sys.version as tuple
138483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        (name, version, branch, revision, buildno, builddate, compiler)
138583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        referring to the Python implementation name, version, branch,
138683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        revision, build number, build date/time as string and the compiler
138783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        identification string.
138883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
138983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Note that unlike the Python sys.version, the returned value
139083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for the Python version will always include the patchlevel (it
139183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        defaults to '.0').
139283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
139383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        The function returns empty strings for tuple entries that
139483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        cannot be determined.
139583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
139683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        sys_version may be given to parse an alternative version
139783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        string, e.g. if the version was read from a different Python
139883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        interpreter.
139983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
140083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
140183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Get the Python version
140283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if sys_version is None:
140383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        sys_version = sys.version
140483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
140583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Try the cache first
140683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    result = _sys_version_cache.get(sys_version, None)
140783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if result is not None:
140883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return result
140983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
141083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Parse it
141183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if sys_version[:10] == 'IronPython':
141283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # IronPython
141383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        name = 'IronPython'
141483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        match = _ironpython_sys_version_parser.match(sys_version)
141583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if match is None:
141683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            raise ValueError(
141783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                'failed to parse IronPython sys.version: %s' %
141883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                repr(sys_version))
141983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        version, alt_version, compiler = match.groups()
142083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        buildno = ''
142183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        builddate = ''
142283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
142383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    elif sys.platform[:4] == 'java':
142483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Jython
142583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        name = 'Jython'
142683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        match = _sys_version_parser.match(sys_version)
142783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if match is None:
142883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            raise ValueError(
142983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                'failed to parse Jython sys.version: %s' %
143083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                repr(sys_version))
143183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        version, buildno, builddate, buildtime, _ = match.groups()
143283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        compiler = sys.platform
143383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
143483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    elif "PyPy" in sys_version:
143583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # PyPy
143683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        name = "PyPy"
143783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        match = _pypy_sys_version_parser.match(sys_version)
143883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if match is None:
143983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            raise ValueError("failed to parse PyPy sys.version: %s" %
144083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                             repr(sys_version))
144183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        version, buildno, builddate, buildtime = match.groups()
144283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        compiler = ""
144383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
144483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    else:
144583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # CPython
144683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        match = _sys_version_parser.match(sys_version)
144783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if match is None:
144883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            raise ValueError(
144983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                'failed to parse CPython sys.version: %s' %
145083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                repr(sys_version))
145183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        version, buildno, builddate, buildtime, compiler = \
145283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh              match.groups()
145383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        name = 'CPython'
145483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        builddate = builddate + ' ' + buildtime
145583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
145683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if hasattr(sys, 'subversion'):
145783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # sys.subversion was added in Python 2.5
145883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        _, branch, revision = sys.subversion
145983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    else:
146083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        branch = ''
146183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        revision = ''
146283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
146383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Add the patchlevel version if missing
146483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    l = string.split(version, '.')
146583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if len(l) == 2:
146683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        l.append('0')
146783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        version = string.join(l, '.')
146883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
146983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Build and cache the result
147083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    result = (name, version, branch, revision, buildno, builddate, compiler)
147183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    _sys_version_cache[sys_version] = result
147283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return result
147383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
147483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef python_implementation():
147583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
147683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Returns a string identifying the Python implementation.
147783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
147883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Currently, the following implementations are identified:
147983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh          'CPython' (C implementation of Python),
148083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh          'IronPython' (.NET implementation of Python),
148183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh          'Jython' (Java implementation of Python),
148283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh          'PyPy' (Python implementation of Python).
148383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
148483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
148583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return _sys_version()[0]
148683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
148783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef python_version():
148883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
148983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Returns the Python version as string 'major.minor.patchlevel'
149083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
149183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Note that unlike the Python sys.version, the returned value
149283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        will always include the patchlevel (it defaults to 0).
149383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
149483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
149583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return _sys_version()[1]
149683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
149783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef python_version_tuple():
149883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
149983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Returns the Python version as tuple (major, minor, patchlevel)
150083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        of strings.
150183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
150283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Note that unlike the Python sys.version, the returned value
150383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        will always include the patchlevel (it defaults to 0).
150483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
150583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
150683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return tuple(string.split(_sys_version()[1], '.'))
150783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
150883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef python_branch():
150983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
151083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Returns a string identifying the Python implementation
151183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        branch.
151283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
151383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        For CPython this is the Subversion branch from which the
151483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Python binary was built.
151583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
151683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        If not available, an empty string is returned.
151783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
151883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
151983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
152083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return _sys_version()[2]
152183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
152283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef python_revision():
152383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
152483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Returns a string identifying the Python implementation
152583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        revision.
152683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
152783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        For CPython this is the Subversion revision from which the
152883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Python binary was built.
152983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
153083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        If not available, an empty string is returned.
153183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
153283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
153383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return _sys_version()[3]
153483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
153583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef python_build():
153683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
153783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Returns a tuple (buildno, builddate) stating the Python
153883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        build number and date as strings.
153983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
154083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
154183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return _sys_version()[4:6]
154283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
154383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef python_compiler():
154483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
154583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Returns a string identifying the compiler used for compiling
154683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Python.
154783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
154883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
154983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return _sys_version()[6]
155083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
155183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh### The Opus Magnum of platform strings :-)
155283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
155383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh_platform_cache = {}
155483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
155583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef platform(aliased=0, terse=0):
155683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
155783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Returns a single string identifying the underlying platform
155883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with as much useful information as possible (but no more :).
155983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
156083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        The output is intended to be human readable rather than
156183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        machine parseable. It may look different on different
156283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        platforms and this is intended.
156383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
156483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        If "aliased" is true, the function will use aliases for
156583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        various platforms that report system names which differ from
156683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        their common names, e.g. SunOS will be reported as
156783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Solaris. The system_alias() function is used to implement
156883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        this.
156983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
157083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Setting terse to true causes the function to return only the
157183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        absolute minimum information needed to identify the platform.
157283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
157383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
157483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    result = _platform_cache.get((aliased, terse), None)
157583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if result is not None:
157683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return result
157783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
157883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Get uname information and then apply platform specific cosmetics
157983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # to it...
158083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    system,node,release,version,machine,processor = uname()
158183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if machine == processor:
158283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        processor = ''
158383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if aliased:
158483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        system,release,version = system_alias(system,release,version)
158583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
158683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if system == 'Windows':
158783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # MS platforms
158883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        rel,vers,csd,ptype = win32_ver(version)
158983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if terse:
159083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            platform = _platform(system,release)
159183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
159283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            platform = _platform(system,release,version,csd)
159383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
159483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    elif system in ('Linux',):
159583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Linux based systems
159683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        distname,distversion,distid = dist('')
159783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if distname and not terse:
159883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            platform = _platform(system,release,machine,processor,
159983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                 'with',
160083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                 distname,distversion,distid)
160183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
160283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # If the distribution name is unknown check for libc vs. glibc
160383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            libcname,libcversion = libc_ver(sys.executable)
160483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            platform = _platform(system,release,machine,processor,
160583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                 'with',
160683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                 libcname+libcversion)
160783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    elif system == 'Java':
160883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Java platforms
160983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        r,v,vminfo,(os_name,os_version,os_arch) = java_ver()
161083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if terse or not os_name:
161183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            platform = _platform(system,release,version)
161283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
161383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            platform = _platform(system,release,version,
161483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                 'on',
161583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                 os_name,os_version,os_arch)
161683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
161783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    elif system == 'MacOS':
161883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # MacOS platforms
161983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if terse:
162083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            platform = _platform(system,release)
162183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
162283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            platform = _platform(system,release,machine)
162383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
162483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    else:
162583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Generic handler
162683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if terse:
162783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            platform = _platform(system,release)
162883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
162983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            bits,linkage = architecture(sys.executable)
163083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            platform = _platform(system,release,machine,processor,bits,linkage)
163183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
163283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    _platform_cache[(aliased, terse)] = platform
163383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return platform
163483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
163583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh### Command line interface
163683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
163783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehif __name__ == '__main__':
163883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Default is to print the aliased verbose platform string
163983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    terse = ('terse' in sys.argv or '--terse' in sys.argv)
164083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    aliased = (not 'nonaliased' in sys.argv and not '--nonaliased' in sys.argv)
164183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    print platform(aliased,terse)
164283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    sys.exit(0)
1643