001/*-------------------------------------------------------------------------- 002 * Copyright 2008 Taro L. Saito 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 *--------------------------------------------------------------------------*/ 016package org.fusesource.jansi.internal; 017 018import java.io.ByteArrayOutputStream; 019import java.io.IOException; 020import java.io.InputStream; 021import java.util.HashMap; 022import java.util.Locale; 023 024/** 025 * Provides OS name and architecture name. 026 * 027 * @author leo 028 */ 029public class OSInfo { 030 031 public static final String X86 = "x86"; 032 public static final String X86_64 = "x86_64"; 033 public static final String IA64_32 = "ia64_32"; 034 public static final String IA64 = "ia64"; 035 public static final String PPC = "ppc"; 036 public static final String PPC64 = "ppc64"; 037 public static final String ARM64 = "arm64"; 038 039 private static final HashMap<String, String> archMapping = new HashMap<String, String>(); 040 static { 041 // x86 mappings 042 archMapping.put(X86, X86); 043 archMapping.put("i386", X86); 044 archMapping.put("i486", X86); 045 archMapping.put("i586", X86); 046 archMapping.put("i686", X86); 047 archMapping.put("pentium", X86); 048 049 // x86_64 mappings 050 archMapping.put(X86_64, X86_64); 051 archMapping.put("amd64", X86_64); 052 archMapping.put("em64t", X86_64); 053 archMapping.put("universal", X86_64); // Needed for openjdk7 in Mac 054 055 // Itenium 64-bit mappings 056 archMapping.put(IA64, IA64); 057 archMapping.put("ia64w", IA64); 058 059 // Itenium 32-bit mappings, usually an HP-UX construct 060 archMapping.put(IA64_32, IA64_32); 061 archMapping.put("ia64n", IA64_32); 062 063 // PowerPC mappings 064 archMapping.put(PPC, PPC); 065 archMapping.put("power", PPC); 066 archMapping.put("powerpc", PPC); 067 archMapping.put("power_pc", PPC); 068 archMapping.put("power_rs", PPC); 069 070 // TODO: PowerPC 64bit mappings 071 archMapping.put(PPC64, PPC64); 072 archMapping.put("power64", PPC64); 073 archMapping.put("powerpc64", PPC64); 074 archMapping.put("power_pc64", PPC64); 075 archMapping.put("power_rs64", PPC64); 076 077 // aarch64 mappings 078 archMapping.put("aarch64", ARM64); 079 } 080 081 082 public static void main(String[] args) { 083 if (args.length >= 1) { 084 if ("--os".equals(args[0])) { 085 System.out.print(getOSName()); 086 return; 087 } else if ("--arch".equals(args[0])) { 088 System.out.print(getArchName()); 089 return; 090 } 091 } 092 093 System.out.print(getNativeLibFolderPathForCurrentOS()); 094 } 095 096 public static String getNativeLibFolderPathForCurrentOS() { 097 return getOSName() + "/" + getArchName(); 098 } 099 100 public static String getOSName() { 101 return translateOSNameToFolderName(System.getProperty("os.name")); 102 } 103 104 public static boolean isAndroid() { 105 return System.getProperty("java.runtime.name", "").toLowerCase().contains("android"); 106 } 107 108 public static boolean isAlpine() { 109 try { 110 Process p = Runtime.getRuntime().exec("cat /etc/os-release | grep ^ID"); 111 p.waitFor(); 112 113 InputStream in = p.getInputStream(); 114 try { 115 return readFully(in).toLowerCase().contains("alpine"); 116 } finally { 117 in.close(); 118 } 119 120 } catch (Throwable e) { 121 return false; 122 } 123 124 } 125 126 static String getHardwareName() { 127 try { 128 Process p = Runtime.getRuntime().exec("uname -m"); 129 p.waitFor(); 130 131 InputStream in = p.getInputStream(); 132 try { 133 return readFully(in); 134 } finally { 135 in.close(); 136 } 137 } catch (Throwable e) { 138 System.err.println("Error while running uname -m: " + e.getMessage()); 139 return "unknown"; 140 } 141 } 142 143 private static String readFully(InputStream in) throws IOException { 144 int readLen = 0; 145 ByteArrayOutputStream b = new ByteArrayOutputStream(); 146 byte[] buf = new byte[32]; 147 while ((readLen = in.read(buf, 0, buf.length)) >= 0) { 148 b.write(buf, 0, readLen); 149 } 150 return b.toString(); 151 } 152 153 static String resolveArmArchType() { 154 if (System.getProperty("os.name").contains("Linux")) { 155 String armType = getHardwareName(); 156 // armType (uname -m) can be armv5t, armv5te, armv5tej, armv5tejl, armv6, armv7, armv7l, aarch64, i686 157 if (armType.startsWith("armv6")) { 158 // Raspberry PI 159 return "armv6"; 160 } else if (armType.startsWith("armv7")) { 161 // Generic 162 return "armv7"; 163 } else if (armType.startsWith("armv5")) { 164 // Use armv5, soft-float ABI 165 return "arm"; 166 } else if (armType.equals("aarch64")) { 167 // Use arm64 168 return "arm64"; 169 } 170 171 // Java 1.8 introduces a system property to determine armel or armhf 172 // http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8005545 173 String abi = System.getProperty("sun.arch.abi"); 174 if (abi != null && abi.startsWith("gnueabihf")) { 175 return "armv7"; 176 } 177 } 178 // Use armv5, soft-float ABI 179 return "arm"; 180 } 181 182 public static String getArchName() { 183 String osArch = System.getProperty("os.arch"); 184 // For Android 185 if (isAndroid()) { 186 return "android-arm"; 187 } 188 189 if (osArch.startsWith("arm")) { 190 osArch = resolveArmArchType(); 191 } else { 192 String lc = osArch.toLowerCase(Locale.US); 193 if (archMapping.containsKey(lc)) 194 return archMapping.get(lc); 195 } 196 return translateArchNameToFolderName(osArch); 197 } 198 199 static String translateOSNameToFolderName(String osName) { 200 if (osName.contains("Windows")) { 201 return "Windows"; 202 } else if (osName.contains("Mac") || osName.contains("Darwin")) { 203 return "Mac"; 204// } else if (isAlpine()) { 205// return "Linux-Alpine"; 206 } else if (osName.contains("Linux")) { 207 return "Linux"; 208 } else if (osName.contains("AIX")) { 209 return "AIX"; 210 } else { 211 return osName.replaceAll("\\W", ""); 212 } 213 } 214 215 static String translateArchNameToFolderName(String archName) { 216 return archName.replaceAll("\\W", ""); 217 } 218}