package org.limewire.util; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.util.HashMap; import java.util.Locale; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.limewire.inspection.Inspectable; import org.limewire.inspection.InspectionPoint; /** * Provides methods to get operating system properties, resources and versions, * and determine operating system criteria. */ public class OSUtils { private static final Log LOG = LogFactory.getLog(OSUtils.class); static { setOperatingSystems(); } /** * Variable for whether or not we're on Windows. */ private static boolean _isWindows; /** * Variable for whether or not we're on Windows NT. */ private static boolean _isWindowsNT; /** * Variable for whether or not we're on Windows XP. */ private static boolean _isWindowsXP; /** * Variable for whether or not we're on Windows 7. */ private static boolean _isWindows7; /** * Variable for whether or not we're on Windows 95. */ private static boolean _isWindows95; /** * Variable for whether or not we're on Windows 98. */ private static boolean _isWindows98; /** * Variable for whether or not we're on Windows Me. */ private static boolean _isWindowsMe; /** * Variable for whether or not we're on Windows Vista. */ private static boolean _isWindowsVista; /** * Variable for whether or not we're on Windows Vista SP2 or higher. */ private static boolean _isSlightlyLessBrokenVersionOfWindowsVista; /** * Variable for whether or not the operating system allows the * application to be reduced to the system tray. */ private static boolean _supportsTray; /** * Variable for whether or not we're on Mac OS X. */ private static boolean _isMacOSX; /** * Variable for whether or not we're on Linux. */ private static boolean _isLinux; /** * Variable for whether or not we're on Solaris. */ private static boolean _isSolaris; /** * Variable for whether or not we're on OS/2. */ private static boolean _isOS2; /** Operating System information */ @SuppressWarnings("unused") @InspectionPoint("os_info") private static final Inspectable osInspect = new OSInspecter(); /** * Sets the operating system variables. */ public static void setOperatingSystems() { _isWindows = false; _isWindowsVista = false; _isSlightlyLessBrokenVersionOfWindowsVista = false; _isWindowsNT = false; _isWindowsXP = false; _isWindows7 = false; _isWindows95 = false; _isWindows98 = false; _isWindowsMe = false; _isSolaris = false; _isLinux = false; _isOS2 = false; _isMacOSX = false; String os = System.getProperty("os.name").toLowerCase(Locale.US); String version = System.getProperty("os.version").toLowerCase(Locale.US); // set the operating system variables _isWindows = os.indexOf("windows") != -1; if (os.indexOf("windows nt") != -1) { _isWindowsNT = true; } else if (os.indexOf("windows xp") != -1) { _isWindowsXP = true; } else if(os.indexOf("windows 7") != -1) { _isWindows7 = true; } else if (os.indexOf("windows vista") != -1 && version.startsWith("6.1")) { //In jdk 1.6 before update 14 the os.name system property still returns Windows Vista //The version number is set to 6.1 however, so we can check for that and windows vista //together to determine if it is windows 7 _isWindows7 = true; } else if (os.indexOf("windows vista") != -1) { _isWindowsVista = true; } else if(os.indexOf("windows 95") != -1) { _isWindows95 = true; } else if(os.indexOf("windows 98") != -1) { _isWindows98 = true; } else if(os.indexOf("windows me") != -1) { _isWindowsMe = true; } else if(os.indexOf("solaris") != -1) { _isSolaris = true; } else if(os.indexOf("linux") != -1) { _isLinux = true; } else if(os.indexOf("os/2") != -1) { _isOS2 = true; } if(_isWindows || _isLinux) _supportsTray = true; if(os.startsWith("mac os")) { if(os.endsWith("x")) { _isMacOSX = true; } } // If this is Windows Vista, try to find out whether SP2 (or higher) // is installed, which removes the half-open TCP connection limit. if(_isWindowsVista) { BufferedReader br = null; try { // Execute reg.exe to query a registry key Process p = Runtime.getRuntime().exec(new String[] { "reg", "query", "HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion", "/v", "CSDVersion" }); // Parse the output br = new BufferedReader( new InputStreamReader(p.getInputStream())); String line = null; while((line = br.readLine()) != null) { if(line.matches(".*CSDVersion.*")) break; } // Assume there won't be more than 9 service packs for Vista if(line != null && line.matches(".*Service Pack [2-9]")) { LOG.debug("Slightly less broken version of Windows Vista"); _isSlightlyLessBrokenVersionOfWindowsVista = true; } } catch(Throwable t) { LOG.debug("Failed to determine Windows version", t); } finally { if(br != null) { try { br.close(); } catch(IOException ignored) {} } } } } /** * Returns the operating system. */ public static String getOS() { return System.getProperty("os.name"); } /** * Returns the operating system version. */ public static String getOSVersion() { return System.getProperty("os.version"); } /** * Returns the operating system architecture. */ public static String getOSArch() { return System.getProperty("os.arch"); } /** * Returns true if this is Windows NT or Windows 2000 and * hence can support a system tray feature. */ public static boolean supportsTray() { return _supportsTray; } /** * Returns whether or not the OS is some version of Windows. * * @return <tt>true</tt> if the application is running on some Windows * version, <tt>false</tt> otherwise */ public static boolean isWindows() { return _isWindows; } /** * Returns whether or not the OS is WinXP. * * @return <tt>true</tt> if the application is running on WinXP, * <tt>false</tt> otherwise */ public static boolean isWindowsXP() { return _isWindowsXP; } /** * Returns whether or not the OS is Windows 7.. * * @return <tt>true</tt> if the application is running on Windows 7, * <tt>false</tt> otherwise */ public static boolean isWindows7() { return _isWindows7; } /** * @return true if the application is running on Windows NT */ public static boolean isWindowsNT() { return _isWindowsNT; } /** * @return true if the application is running on Windows 95 */ public static boolean isWindows95() { return _isWindows95; } /** * @return true if the application is running on Windows 98 */ public static boolean isWindows98() { return _isWindows98; } /** * @return true if the application is running on Windows ME */ public static boolean isWindowsMe() { return _isWindowsMe; } /** * @return true if the application is running on Windows Vista */ public static boolean isWindowsVista() { return _isWindowsVista; } /** * @return true if the application is running on a windows with * the 10 socket limit. */ public static boolean isSocketChallengedWindows() { return _isWindowsXP || (_isWindowsVista && !_isSlightlyLessBrokenVersionOfWindowsVista); } /** * Returns whether or not the OS is OS/2. * * @return <tt>true</tt> if the application is running on OS/2, * <tt>false</tt> otherwise */ public static boolean isOS2() { return _isOS2; } /** * Returns whether or not the OS is Mac OS X. * * @return <tt>true</tt> if the application is running on Mac OS X, * <tt>false</tt> otherwise */ public static boolean isMacOSX() { return _isMacOSX; } /** * Returns whether or not the OS is Solaris. * * @return <tt>true</tt> if the application is running on Solaris, * <tt>false</tt> otherwise */ public static boolean isSolaris() { return _isSolaris; } /** * Returns whether or not the OS is Linux. * * @return <tt>true</tt> if the application is running on Linux, * <tt>false</tt> otherwise */ public static boolean isLinux() { return _isLinux; } /** * Returns whether or not the OS is some version of * Unix, defined here as only Solaris or Linux. */ public static boolean isUnix() { return _isLinux || _isSolaris; } /** * Returns whether the OS is POSIX-like. */ public static boolean isPOSIX() { return _isLinux || _isSolaris || _isMacOSX; } /** * Returns whether or not this operating system is considered * capable of meeting the requirements of a high load server. * * @return <tt>true</tt> if this OS meets high load server requirements, * <tt>false</tt> otherwise */ public static boolean isHighLoadOS() { return !(_isWindows98 || _isWindows95 || _isWindowsMe || _isWindowsNT); } /** * @return true if this is a well-supported version of windows. * (not 95, 98, nt or me) */ public static boolean isGoodWindows() { return isWindows() && isHighLoadOS(); } /** * Return whether the current operating system supports moving files * to the trash. */ public static boolean supportsTrash() { return isWindows() || isMacOSX(); } /** * Returns the maximum path system of file system of the current OS * or a conservative approximation. */ public static int getMaxPathLength() { if (isWindows()) { // From Windows NT onwards, Windows applications can create or // manipulate path lengths of 260 characters, where 259 are // actual characters + 1 NULL character. Where path is denoted // by the path, filename and extension plus 1 null character. // // NTFS can actually support 32767 characters in the paths // but one must prepend \\?\ to the file paths. This tells the // APIs to not to enforce 260 character limit. return 259; } else if (isLinux()) { return 4096 - 1; } else { return 1024 - 1; } } public static boolean supportsTLS() { return true; } private static class OSInspecter implements Inspectable { @Override public Object inspect() { Map<String, Object> data = new HashMap<String, Object>(); data.put("os_name", getOS()); data.put("os_ver", getOSVersion()); data.put("os_arch", getOSArch()); data.put("num_cpus", Runtime.getRuntime().availableProcessors()); return data; } } }