1 /* 2 * Copyright 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * Copyright 2013 The Netty Project 19 * 20 * The Netty Project licenses this file to you under the Apache License, 21 * version 2.0 (the "License"); you may not use this file except in compliance 22 * with the License. You may obtain a copy of the License at: 23 * 24 * http://www.apache.org/licenses/LICENSE-2.0 25 * 26 * Unless required by applicable law or agreed to in writing, software 27 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 28 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 29 * License for the specific language governing permissions and limitations 30 * under the License. 31 */ 32 33 package org.conscrypt; 34 35 import java.io.File; 36 import java.util.Locale; 37 import java.util.logging.Level; 38 import java.util.logging.Logger; 39 40 /** 41 * Utilities for interacting with properties of the host being run on. 42 */ 43 @Internal 44 class HostProperties { 45 private static final Logger logger = Logger.getLogger(HostProperties.class.getName()); 46 47 private static final String TEMP_DIR_PROPERTY_NAME = "org.conscrypt.tmpdir"; 48 49 static final OperatingSystem OS; 50 static final Architecture ARCH; 51 52 static { 53 OS = getOperatingSystem(System.getProperty("os.name", "")); 54 ARCH = getArchitecture(System.getProperty("os.arch", "")); 55 } 56 57 /** 58 * Enumeration of operating systems. 59 */ 60 enum OperatingSystem { 61 AIX, 62 HPUX, 63 OS400, 64 LINUX, 65 OSX, 66 FREEBSD, 67 OPENBSD, 68 NETBSD, 69 SUNOS, 70 WINDOWS, 71 UNKNOWN; 72 73 /** 74 * Returns the value to use when building filenames for this OS. 75 */ getFileComponent()76 public String getFileComponent() { 77 return name().toLowerCase(); 78 } 79 } 80 81 /** 82 * Enumeration of architectures. 83 */ 84 enum Architecture { 85 X86_64, 86 X86_32 { getFileComponent()87 @Override public String getFileComponent() { 88 return "x86"; 89 } 90 }, 91 ITANIUM_64, 92 SPARC_32, 93 SPARC_64, 94 ARM_32, 95 AARCH_64, 96 PPC_32, 97 PPC_64, 98 PPCLE_64, 99 S390_32, 100 S390_64, 101 UNKNOWN; 102 103 /** 104 * Returns the value to use when building filenames for this architecture. 105 */ getFileComponent()106 public String getFileComponent() { 107 return name().toLowerCase(); 108 } 109 } 110 isWindows()111 static boolean isWindows() { 112 return OS == OperatingSystem.WINDOWS; 113 } 114 isOSX()115 static boolean isOSX() { 116 return OS == OperatingSystem.OSX; 117 } 118 getTempDir()119 static File getTempDir() { 120 File f; 121 try { 122 // First, see if the application specified a temp dir for conscrypt. 123 f = toDirectory(System.getProperty(TEMP_DIR_PROPERTY_NAME)); 124 if (f != null) { 125 return f; 126 } 127 128 // Use the Java system property if available. 129 f = toDirectory(System.getProperty("java.io.tmpdir")); 130 if (f != null) { 131 return f; 132 } 133 134 // This shouldn't happen, but just in case .. 135 if (isWindows()) { 136 f = toDirectory(System.getenv("TEMP")); 137 if (f != null) { 138 return f; 139 } 140 141 String userprofile = System.getenv("USERPROFILE"); 142 if (userprofile != null) { 143 f = toDirectory(userprofile + "\\AppData\\Local\\Temp"); 144 if (f != null) { 145 return f; 146 } 147 148 f = toDirectory(userprofile + "\\Local Settings\\Temp"); 149 if (f != null) { 150 return f; 151 } 152 } 153 } else { 154 f = toDirectory(System.getenv("TMPDIR")); 155 if (f != null) { 156 return f; 157 } 158 } 159 } catch (Exception ignored) { 160 // Environment variable inaccessible 161 } 162 163 // Last resort. 164 if (isWindows()) { 165 f = new File("C:\\Windows\\Temp"); 166 } else { 167 f = new File("/tmp"); 168 } 169 170 logger.log(Level.WARNING, 171 "Failed to get the temporary directory; falling back to: {0}", f); 172 return f; 173 } 174 175 @SuppressWarnings("ResultOfMethodCallIgnored") toDirectory(String path)176 private static File toDirectory(String path) { 177 if (path == null) { 178 return null; 179 } 180 181 File f = new File(path); 182 f.mkdirs(); 183 184 if (!f.isDirectory()) { 185 return null; 186 } 187 188 try { 189 return f.getAbsoluteFile(); 190 } catch (Exception ignored) { 191 return f; 192 } 193 } 194 normalize(String value)195 private static String normalize(String value) { 196 return value.toLowerCase(Locale.US).replaceAll("[^a-z0-9]+", ""); 197 } 198 199 /** 200 * Normalizes the os.name value into the value used by the Maven os plugin 201 * (https://github.com/trustin/os-maven-plugin). This plugin is used to generate 202 * platform-specific 203 * classifiers for artifacts. 204 */ getOperatingSystem(String value)205 private static OperatingSystem getOperatingSystem(String value) { 206 value = normalize(value); 207 if (value.startsWith("aix")) { 208 return OperatingSystem.AIX; 209 } 210 if (value.startsWith("hpux")) { 211 return OperatingSystem.HPUX; 212 } 213 if (value.startsWith("os400")) { 214 // Avoid the names such as os4000 215 if (value.length() <= 5 || !Character.isDigit(value.charAt(5))) { 216 return OperatingSystem.OS400; 217 } 218 } 219 if (value.startsWith("linux")) { 220 return OperatingSystem.LINUX; 221 } 222 if (value.startsWith("macosx") || value.startsWith("osx")) { 223 return OperatingSystem.OSX; 224 } 225 if (value.startsWith("freebsd")) { 226 return OperatingSystem.FREEBSD; 227 } 228 if (value.startsWith("openbsd")) { 229 return OperatingSystem.OPENBSD; 230 } 231 if (value.startsWith("netbsd")) { 232 return OperatingSystem.NETBSD; 233 } 234 if (value.startsWith("solaris") || value.startsWith("sunos")) { 235 return OperatingSystem.SUNOS; 236 } 237 if (value.startsWith("windows")) { 238 return OperatingSystem.WINDOWS; 239 } 240 241 return OperatingSystem.UNKNOWN; 242 } 243 244 /** 245 * Normalizes the os.arch value into the value used by the Maven os plugin 246 * (https://github.com/trustin/os-maven-plugin). This plugin is used to generate 247 * platform-specific 248 * classifiers for artifacts. 249 */ getArchitecture(String value)250 private static Architecture getArchitecture(String value) { 251 value = normalize(value); 252 if (value.matches("^(x8664|amd64|ia32e|em64t|x64)$")) { 253 return Architecture.X86_64; 254 } 255 if (value.matches("^(x8632|x86|i[3-6]86|ia32|x32)$")) { 256 return Architecture.X86_32; 257 } 258 if (value.matches("^(ia64|itanium64)$")) { 259 return Architecture.ITANIUM_64; 260 } 261 if (value.matches("^(sparc|sparc32)$")) { 262 return Architecture.SPARC_32; 263 } 264 if (value.matches("^(sparcv9|sparc64)$")) { 265 return Architecture.SPARC_64; 266 } 267 if (value.matches("^(arm|arm32)$")) { 268 return Architecture.ARM_32; 269 } 270 if ("aarch64".equals(value)) { 271 return Architecture.AARCH_64; 272 } 273 if (value.matches("^(ppc|ppc32)$")) { 274 return Architecture.PPC_32; 275 } 276 if ("ppc64".equals(value)) { 277 return Architecture.PPC_64; 278 } 279 if ("ppc64le".equals(value)) { 280 return Architecture.PPCLE_64; 281 } 282 if ("s390".equals(value)) { 283 return Architecture.S390_32; 284 } 285 if ("s390x".equals(value)) { 286 return Architecture.S390_64; 287 } 288 289 return Architecture.UNKNOWN; 290 } 291 HostProperties()292 private HostProperties() {} 293 294 } 295