elif plat == VER_PLATFORM_WIN32_NT: regkey = 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion' if maj <= 4: release = 'NT' elif maj == 5: if min == 0: release = '2000' elif min == 1: release = 'XP' elif min == 2: release = '2003Server' else: release = 'post2003' else: if not release: # E.g. Win3.1 with win32s release = '%i.%i' % (maj,min) return release,version,csd,ptype # Open the registry key try: keyCurVer = RegOpenKeyEx(HKEY_LOCAL_MACHINE,regkey) # Get a value to make sure the key exists... RegQueryValueEx(keyCurVer,'SystemRoot') except: return release,version,csd,ptype # Parse values #subversion = _win32_getvalue(keyCurVer, # 'SubVersionNumber', # ('',1))[0] #if subversion: # release = release + subversion # 95a, 95b, etc. build = _win32_getvalue(keyCurVer, 'CurrentBuildNumber', ('',1))[0] ptype = _win32_getvalue(keyCurVer, 'CurrentType', (ptype,1))[0] # Normalize version version = _norm_version(version,build) # Close key RegCloseKey(keyCurVer) return release,version,csd,ptype def _mac_ver_lookup(selectors,default=None): from gestalt import gestalt import MacOS l = [] append = l.append for selector in selectors: try: append(gestalt(selector)) except (RuntimeError, MacOS.Error): append(default) return l def _bcd2str(bcd): return hex(bcd)[2:] def mac_ver(release='',versioninfo=('','',''),machine=''): """ Get MacOS version information and return it as tuple (release, versioninfo, machine) with versioninfo being a tuple (version, dev_stage, non_release_version). Entries which cannot be determined are set to the paramter values which default to ''. All tuple entries are strings. Thanks to Mark R. Levinson for mailing documentation links and code examples for this function. Documentation for the gestalt() API is available online at: http://www.rgaros.nl/gestalt/ """ # Check whether the version info module is available try: import gestalt import MacOS except ImportError: return release,versioninfo,machine # Get the infos sysv,sysu,sysa = _mac_ver_lookup(('sysv','sysu','sysa')) # Decode the infos if sysv: major = (sysv & 0xFF00) >> 8 minor = (sysv & 0x00F0) >> 4 patch = (sysv & 0x000F) release = '%s.%i.%i' % (_bcd2str(major),minor,patch) if sysu: major = int((sysu & 0xFF000000L) >> 24) minor = (sysu & 0x00F00000) >> 20 bugfix = (sysu & 0x000F0000) >> 16 stage = (sysu & 0x0000FF00) >> 8 nonrel = (sysu & 0x000000FF) version = '%s.%i.%i' % (_bcd2str(major),minor,bugfix) nonrel = _bcd2str(nonrel) stage = {0x20:'development', 0x40:'alpha', 0x60:'beta', 0x80:'final'}.get(stage,'') versioninfo = (version,stage,nonrel) if sysa: machine = {0x1: '68k', 0x2: 'PowerPC', 0xa: 'i386'}.get(sysa,'') return release,versioninfo,machine def _java_getprop(name,default): from java.lang import System try: return System.getProperty(name) except: return default def java_ver(release='',vendor='',vminfo=('','',''),osinfo=('','','')): """ Version interface for Jython. Returns a tuple (release,vendor,vminfo,osinfo) with vminfo being a tuple (vm_name,vm_release,vm_vendor) and osinfo being a tuple (os_name,os_version,os_arch). Values which cannot be determined are set to the defaults given as parameters (which all default to ''). """ # Import the needed APIs try: import java.lang except ImportError: return release,vendor,vminfo,osinfo vendor = _java_getprop('java.vendor',vendor) release = _java_getprop('java.version',release) vm_name,vm_release,vm_vendor = vminfo vm_name = _java_getprop('java.vm.name',vm_name) vm_vendor = _java_getprop('java.vm.vendor',vm_vendor) vm_release = _java_getprop('java.vm.version',vm_release) vminfo = vm_name,vm_release,vm_vendor os_name,os_version,os_arch = osinfo os_arch = _java_getprop('java.os.arch',os_arch) os_name = _java_getprop('java.os.name',os_name) os_version = _java_getprop('java.os.version',os_version) osinfo = os_name,os_version,os_arch return release,vendor,vminfo,osinfo ### System name aliasing def system_alias(system,release,version): """ Returns (system,release,version) aliased to common marketing names used for some systems. It also does some reordering of the information in some cases where it would otherwise cause confusion. """ if system == 'Rhapsody': # Apple's BSD derivative # XXX How can we determine the marketing release number ? return 'MacOS X Server',system+release,version elif system == 'SunOS': # Sun's OS if release < '5': # These releases use the old name SunOS return system,release,version # Modify release (marketing release = SunOS release - 3) l = string.split(release,'.') if l: try: major = int(l[0]) except ValueError: pass else: major = major - 3 l[0] = str(major) release = string.join(l,'.') if release < '6': system = 'Solaris' else: # XXX Whatever the new SunOS marketing name is... system = 'Solaris' elif system == 'IRIX64': # IRIX reports IRIX64 on platforms with 64-bit support; yet it # is really a version and not a different platform, since 32-bit # apps are also supported.. system = 'IRIX' if version: version = version + ' (64bit)' else: version = '64bit' elif system in ('win32','win16'): # In case one of the other tricks system = 'Windows' return system,release,version ### Various internal helpers def _platform(*args): """ Helper to format the platform string in a filename compatible format e.g. "system-version-machine". """ # Format the platform string platform = string.join( map(string.strip, filter(len,args)), '-') # Cleanup some possible filename obstacles... replace = string.replace platform = replace(platform,' ','_') platform = replace(platform,'/','-') platform = replace(platform,'\\','-') platform = replace(platform,':','-') platform = replace(platform,';','-') platform = replace(platform,'"','-') platform = replace(platform,'(','-') platform = replace(platform,')','-') # No need to report 'unknown' information... platform = replace(platform,'unknown','') # Fold '--'s and remove trailing '-' while 1: cleaned = replace(platform,'--','-') if cleaned == platform: break platform = cleaned while platform[-1] == '-': platform = platform[:-1] return platform def _node(default=''): """ Helper to determine the node name of this machine. """ try: import socket except ImportError: # No sockets... return default try: return socket.gethostname() except socket.error: # Still not working... return default # os.path.abspath is new in Python 1.5.2:if not hasattr(os.path,'abspath'): def _abspath(path, isabs=os.path.isabs,join=os.path.join,getcwd=os.getcwd, normpath=os.path.normpath): if not isabs(path): path = join(getcwd(), path) return normpath(path) else: _abspath = os.path.abspath def _follow_symlinks(filepath): """ In case filepath is a symlink, follow it until a real file is reached. """ filepath = _abspath(filepath) while os.path.islink(filepath): filepath = os.path.normpath( os.path.join(filepath,os.readlink(filepath))) return filepath def _syscmd_uname(option,default=''): """ Interface to the system's uname command. """ if sys.platform in ('dos','win32','win16','os2'): # XXX Others too ? return default try: f = os.popen('uname %s 2> /dev/null' % option) except (AttributeError,os.error): return default output = string.strip(f.read()) rc = f.close() if not output or rc: return default else: return output def _syscmd_file(target,default=''): """ Interface to the system's file command. The function uses the -b option of the file command to have it ommit the filename in its output and if possible the -L option to have the command follow symlinks. It returns default in case the command should fail. """ target = _follow_symlinks(target) try: f = os.popen('file %s 2> /dev/null' % target) except (AttributeError,os.error): return default output = string.strip(f.read()) rc = f.close() if not output or rc: return default else: return output ### Information about the used architecture # Default values for architecture; non-empty strings override the# defaults given as parameters_default_architecture = { 'win32': ('','WindowsPE'), 'win16': ('','Windows'), 'dos': ('','MSDOS'),} _architecture_split = re.compile(r'[\s,]').split def architecture(executable=sys.executable,bits='',linkage=''): """ Queries the given executable (defaults to the Python interpreter binary) for various architecture information. Returns a tuple (bits,linkage) which contains information about the bit architecture and the linkage format used for the executable. Both values are returned as strings. Values that cannot be determined are returned as given by the parameter presets. If bits is given as '', the sizeof(pointer) (or sizeof(long) on Python version < 1.5.2) is used as indicator for the supported pointer size. The function relies on the system's "file" command to do the actual work. This is available on most if not all Unix platforms. On some non-Unix platforms where the "file" command does not exist and the executable is set to the Python interpreter binary defaults from _default_architecture are used. """ # Use the sizeof(pointer) as default number of bits if nothing # else is given as default. if not bits: import struct try: size = struct.calcsize('P') except struct.error: # Older installations can only query longs size = struct.calcsize('l') bits = str(size*8) + 'bit' # Get data from the 'file' system command output = _syscmd_file(executable,'') if not output and \ executable == sys.executable: # "file" command did not return anything; we'll try to provide # some sensible defaults then... if _default_architecture.has_key(sys.platform): b,l = _default_architecture[sys.platform] if b: bits = b if l: linkage = l return bits,linkage # Split the output into a list of strings omitting the filename fileout = _architecture_split(output)[1:] if 'executable' not in fileout: # Format not supported return bits,linkage # Bits if '32-bit' in fileout: bits = '32bit' elif 'N32' in fileout: # On Irix only bits = 'n32bit' elif '64-bit' in fileout: bits = '64bit' # Linkage if 'ELF' in fileout: linkage = 'ELF' elif 'PE' in fileout: # E.g. Windows uses this format if 'Windows' in fileout: linkage = 'WindowsPE' else: linkage = 'PE' elif 'COFF' in fileout: linkage = 'COFF' elif 'MS-DOS' in fileout: linkage = 'MSDOS' else: # XXX the A.OUT format also falls under this class... pass return bits,linkage ### Portable uname() interface _uname_cache = None def uname(): """ Fairly portable uname interface. Returns a tuple of strings (system,node,release,version,machine,processor) identifying the underlying platform. Note that unlike the os.uname function this also returns possible processor information as an additional tuple entry. Entries which cannot be determined are set to ''. """ global _uname_cache if _uname_cache is not None: return _uname_cache # Get some infos from the builtin os.uname API... try: system,node,release,version,machine = os.uname() except AttributeError: # Hmm, no uname... we'll have to poke around the system then. system = sys.platform release = '' version = '' node = _node() machine = '' processor = '' use_syscmd_ver = 1 # Try win32_ver() on win32 platforms if system == 'win32': release,version,csd,ptype = win32_ver() if release and version: use_syscmd_ver = 0 # Try the 'ver' system command available on some # platforms if use_syscmd_ver: system,release,version = _syscmd_ver(system) # Normalize system to what win32_ver() normally returns # (_syscmd_ver() tends to return the vendor name as well) if system == 'Microsoft Windows': system = 'Windows' # In case we still don't know anything useful, we'll try to # help ourselves if system in ('win32','win16'): if not version: if system == 'win32': version = '32bit' else: version = '16bit' system = 'Windows' elif system[:4] == 'java': release,vendor,vminfo,osinfo = java_ver() system = 'Java' version = string.join(vminfo,', ') if not version: version = vendor elif os.name == 'mac': release,(version,stage,nonrel),machine = mac_ver() system = 'MacOS' else: # System specific extensions if system == 'OpenVMS': # OpenVMS seems to have release and version mixed up if not release or release == '0': release = version version = ''Lines 501–1000 of 1254. Previous lines Load more
elif plat == VER_PLATFORM_WIN32_NT: regkey = 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion' if maj <= 4: release = 'NT' elif maj == 5: if min == 0: release = '2000' elif min == 1: release = 'XP' elif min == 2: release = '2003Server' else: release = 'post2003' else: if not release: # E.g. Win3.1 with win32s release = '%i.%i' % (maj,min) return release,version,csd,ptype # Open the registry key try: keyCurVer = RegOpenKeyEx(HKEY_LOCAL_MACHINE,regkey) # Get a value to make sure the key exists... RegQueryValueEx(keyCurVer,'SystemRoot') except: return release,version,csd,ptype # Parse values #subversion = _win32_getvalue(keyCurVer, # 'SubVersionNumber', # ('',1))[0] #if subversion: # release = release + subversion # 95a, 95b, etc. build = _win32_getvalue(keyCurVer, 'CurrentBuildNumber', ('',1))[0] ptype = _win32_getvalue(keyCurVer, 'CurrentType', (ptype,1))[0] # Normalize version version = _norm_version(version,build) # Close key RegCloseKey(keyCurVer) return release,version,csd,ptype def _mac_ver_lookup(selectors,default=None): from gestalt import gestalt import MacOS l = [] append = l.append for selector in selectors: try: append(gestalt(selector)) except (RuntimeError, MacOS.Error): append(default) return l def _bcd2str(bcd): return hex(bcd)[2:] def mac_ver(release='',versioninfo=('','',''),machine=''): """ Get MacOS version information and return it as tuple (release, versioninfo, machine) with versioninfo being a tuple (version, dev_stage, non_release_version). Entries which cannot be determined are set to the paramter values which default to ''. All tuple entries are strings. Thanks to Mark R. Levinson for mailing documentation links and code examples for this function. Documentation for the gestalt() API is available online at: http://www.rgaros.nl/gestalt/ """ # Check whether the version info module is available try: import gestalt import MacOS except ImportError: return release,versioninfo,machine # Get the infos sysv,sysu,sysa = _mac_ver_lookup(('sysv','sysu','sysa')) # Decode the infos if sysv: major = (sysv & 0xFF00) >> 8 minor = (sysv & 0x00F0) >> 4 patch = (sysv & 0x000F) release = '%s.%i.%i' % (_bcd2str(major),minor,patch) if sysu: major = int((sysu & 0xFF000000L) >> 24) minor = (sysu & 0x00F00000) >> 20 bugfix = (sysu & 0x000F0000) >> 16 stage = (sysu & 0x0000FF00) >> 8 nonrel = (sysu & 0x000000FF) version = '%s.%i.%i' % (_bcd2str(major),minor,bugfix) nonrel = _bcd2str(nonrel) stage = {0x20:'development', 0x40:'alpha', 0x60:'beta', 0x80:'final'}.get(stage,'') versioninfo = (version,stage,nonrel) if sysa: machine = {0x1: '68k', 0x2: 'PowerPC', 0xa: 'i386'}.get(sysa,'') return release,versioninfo,machine def _java_getprop(name,default): from java.lang import System try: return System.getProperty(name) except: return default def java_ver(release='',vendor='',vminfo=('','',''),osinfo=('','','')): """ Version interface for Jython. Returns a tuple (release,vendor,vminfo,osinfo) with vminfo being a tuple (vm_name,vm_release,vm_vendor) and osinfo being a tuple (os_name,os_version,os_arch). Values which cannot be determined are set to the defaults given as parameters (which all default to ''). """ # Import the needed APIs try: import java.lang except ImportError: return release,vendor,vminfo,osinfo vendor = _java_getprop('java.vendor',vendor) release = _java_getprop('java.version',release) vm_name,vm_release,vm_vendor = vminfo vm_name = _java_getprop('java.vm.name',vm_name) vm_vendor = _java_getprop('java.vm.vendor',vm_vendor) vm_release = _java_getprop('java.vm.version',vm_release) vminfo = vm_name,vm_release,vm_vendor os_name,os_version,os_arch = osinfo os_arch = _java_getprop('java.os.arch',os_arch) os_name = _java_getprop('java.os.name',os_name) os_version = _java_getprop('java.os.version',os_version) osinfo = os_name,os_version,os_arch return release,vendor,vminfo,osinfo ### System name aliasing def system_alias(system,release,version): """ Returns (system,release,version) aliased to common marketing names used for some systems. It also does some reordering of the information in some cases where it would otherwise cause confusion. """ if system == 'Rhapsody': # Apple's BSD derivative # XXX How can we determine the marketing release number ? return 'MacOS X Server',system+release,version elif system == 'SunOS': # Sun's OS if release < '5': # These releases use the old name SunOS return system,release,version # Modify release (marketing release = SunOS release - 3) l = string.split(release,'.') if l: try: major = int(l[0]) except ValueError: pass else: major = major - 3 l[0] = str(major) release = string.join(l,'.') if release < '6': system = 'Solaris' else: # XXX Whatever the new SunOS marketing name is... system = 'Solaris' elif system == 'IRIX64': # IRIX reports IRIX64 on platforms with 64-bit support; yet it # is really a version and not a different platform, since 32-bit # apps are also supported.. system = 'IRIX' if version: version = version + ' (64bit)' else: version = '64bit' elif system in ('win32','win16'): # In case one of the other tricks system = 'Windows' return system,release,version ### Various internal helpers def _platform(*args): """ Helper to format the platform string in a filename compatible format e.g. "system-version-machine". """ # Format the platform string platform = string.join( map(string.strip, filter(len,args)), '-') # Cleanup some possible filename obstacles... replace = string.replace platform = replace(platform,' ','_') platform = replace(platform,'/','-') platform = replace(platform,'\\','-') platform = replace(platform,':','-') platform = replace(platform,';','-') platform = replace(platform,'"','-') platform = replace(platform,'(','-') platform = replace(platform,')','-') # No need to report 'unknown' information... platform = replace(platform,'unknown','') # Fold '--'s and remove trailing '-' while 1: cleaned = replace(platform,'--','-') if cleaned == platform: break platform = cleaned while platform[-1] == '-': platform = platform[:-1] return platform def _node(default=''): """ Helper to determine the node name of this machine. """ try: import socket except ImportError: # No sockets... return default try: return socket.gethostname() except socket.error: # Still not working... return default # os.path.abspath is new in Python 1.5.2: if not hasattr(os.path,'abspath'): def _abspath(path, isabs=os.path.isabs,join=os.path.join,getcwd=os.getcwd, normpath=os.path.normpath): if not isabs(path): path = join(getcwd(), path) return normpath(path) else: _abspath = os.path.abspath def _follow_symlinks(filepath): """ In case filepath is a symlink, follow it until a real file is reached. """ filepath = _abspath(filepath) while os.path.islink(filepath): filepath = os.path.normpath( os.path.join(filepath,os.readlink(filepath))) return filepath def _syscmd_uname(option,default=''): """ Interface to the system's uname command. """ if sys.platform in ('dos','win32','win16','os2'): # XXX Others too ? return default try: f = os.popen('uname %s 2> /dev/null' % option) except (AttributeError,os.error): return default output = string.strip(f.read()) rc = f.close() if not output or rc: return default else: return output def _syscmd_file(target,default=''): """ Interface to the system's file command. The function uses the -b option of the file command to have it ommit the filename in its output and if possible the -L option to have the command follow symlinks. It returns default in case the command should fail. """ target = _follow_symlinks(target) try: f = os.popen('file %s 2> /dev/null' % target) except (AttributeError,os.error): return default output = string.strip(f.read()) rc = f.close() if not output or rc: return default else: return output ### Information about the used architecture # Default values for architecture; non-empty strings override the # defaults given as parameters _default_architecture = { 'win32': ('','WindowsPE'), 'win16': ('','Windows'), 'dos': ('','MSDOS'), } _architecture_split = re.compile(r'[\s,]').split def architecture(executable=sys.executable,bits='',linkage=''): """ Queries the given executable (defaults to the Python interpreter binary) for various architecture information. Returns a tuple (bits,linkage) which contains information about the bit architecture and the linkage format used for the executable. Both values are returned as strings. Values that cannot be determined are returned as given by the parameter presets. If bits is given as '', the sizeof(pointer) (or sizeof(long) on Python version < 1.5.2) is used as indicator for the supported pointer size. The function relies on the system's "file" command to do the actual work. This is available on most if not all Unix platforms. On some non-Unix platforms where the "file" command does not exist and the executable is set to the Python interpreter binary defaults from _default_architecture are used. """ # Use the sizeof(pointer) as default number of bits if nothing # else is given as default. if not bits: import struct try: size = struct.calcsize('P') except struct.error: # Older installations can only query longs size = struct.calcsize('l') bits = str(size*8) + 'bit' # Get data from the 'file' system command output = _syscmd_file(executable,'') if not output and \ executable == sys.executable: # "file" command did not return anything; we'll try to provide # some sensible defaults then... if _default_architecture.has_key(sys.platform): b,l = _default_architecture[sys.platform] if b: bits = b if l: linkage = l return bits,linkage # Split the output into a list of strings omitting the filename fileout = _architecture_split(output)[1:] if 'executable' not in fileout: # Format not supported return bits,linkage # Bits if '32-bit' in fileout: bits = '32bit' elif 'N32' in fileout: # On Irix only bits = 'n32bit' elif '64-bit' in fileout: bits = '64bit' # Linkage if 'ELF' in fileout: linkage = 'ELF' elif 'PE' in fileout: # E.g. Windows uses this format if 'Windows' in fileout: linkage = 'WindowsPE' else: linkage = 'PE' elif 'COFF' in fileout: linkage = 'COFF' elif 'MS-DOS' in fileout: linkage = 'MSDOS' else: # XXX the A.OUT format also falls under this class... pass return bits,linkage ### Portable uname() interface _uname_cache = None def uname(): """ Fairly portable uname interface. Returns a tuple of strings (system,node,release,version,machine,processor) identifying the underlying platform. Note that unlike the os.uname function this also returns possible processor information as an additional tuple entry. Entries which cannot be determined are set to ''. """ global _uname_cache if _uname_cache is not None: return _uname_cache # Get some infos from the builtin os.uname API... try: system,node,release,version,machine = os.uname() except AttributeError: # Hmm, no uname... we'll have to poke around the system then. system = sys.platform release = '' version = '' node = _node() machine = '' processor = '' use_syscmd_ver = 1 # Try win32_ver() on win32 platforms if system == 'win32': release,version,csd,ptype = win32_ver() if release and version: use_syscmd_ver = 0 # Try the 'ver' system command available on some # platforms if use_syscmd_ver: system,release,version = _syscmd_ver(system) # Normalize system to what win32_ver() normally returns # (_syscmd_ver() tends to return the vendor name as well) if system == 'Microsoft Windows': system = 'Windows' # In case we still don't know anything useful, we'll try to # help ourselves if system in ('win32','win16'): if not version: if system == 'win32': version = '32bit' else: version = '16bit' system = 'Windows' elif system[:4] == 'java': release,vendor,vminfo,osinfo = java_ver() system = 'Java' version = string.join(vminfo,', ') if not version: version = vendor elif os.name == 'mac': release,(version,stage,nonrel),machine = mac_ver() system = 'MacOS' else: # System specific extensions if system == 'OpenVMS': # OpenVMS seems to have release and version mixed up if not release or release == '0': release = version version = ''