1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 package org.apache.commons.crypto;
19
20 import java.io.File;
21 import java.io.IOException;
22 import java.util.HashMap;
23 import java.util.Locale;
24
25 /**
26 * Provides OS name and architecture name. Used by the JNI make process to get
27 * information from the build environment.
28 */
29 final class OsInfo {
30
31 private final static HashMap<String, String> archMapping = new HashMap<>();
32
33 /**
34 * The constant string represents for X86 architecture, the value is:
35 * {@value #X86}.
36 */
37 static final String X86 = "x86";
38
39 /**
40 * The constant string represents for X86_64 architecture, the value is:
41 * {@value #X86_64}.
42 */
43 static final String X86_64 = "x86_64";
44
45 /**
46 * The constant string represents for IA64_32 architecture, the value is:
47 * {@value #IA64_32}.
48 */
49 static final String IA64_32 = "ia64_32";
50
51 /**
52 * The constant string represents for IA64 architecture, the value is:
53 * {@value #IA64}.
54 */
55 static final String IA64 = "ia64";
56
57 /**
58 * The constant string represents for PPC architecture, the value is:
59 * {@value #PPC}.
60 */
61 static final String PPC = "ppc";
62
63 /**
64 * The constant string represents for PPC64 architecture, the value is:
65 * {@value #PPC64}.
66 */
67 static final String PPC64 = "ppc64";
68
69 static {
70 // x86 mappings
71 archMapping.put(X86, X86);
72 archMapping.put("i386", X86);
73 archMapping.put("i486", X86);
74 archMapping.put("i586", X86);
75 archMapping.put("i686", X86);
76 archMapping.put("pentium", X86);
77
78 // x86_64 mappings
79 archMapping.put(X86_64, X86_64);
80 archMapping.put("amd64", X86_64);
81 archMapping.put("em64t", X86_64);
82 archMapping.put("universal", X86_64); // Needed for openjdk7 in Mac
83
84 // Itanium 64-bit mappings
85 archMapping.put(IA64, IA64);
86 archMapping.put("ia64w", IA64);
87
88 // Itanium 32-bit mappings, usually an HP-UX construct
89 archMapping.put(IA64_32, IA64_32);
90 archMapping.put("ia64n", IA64_32);
91
92 // PowerPC mappings
93 archMapping.put(PPC, PPC);
94 archMapping.put("power", PPC);
95 archMapping.put("powerpc", PPC);
96 archMapping.put("power_pc", PPC);
97 archMapping.put("power_rs", PPC);
98
99 // PowerPC 64bit mappings
100 archMapping.put(PPC64, PPC64);
101 archMapping.put("power64", PPC64);
102 archMapping.put("powerpc64", PPC64);
103 archMapping.put("power_pc64", PPC64);
104 archMapping.put("power_rs64", PPC64);
105 }
106
107 /**
108 * Gets the architecture name.
109 *
110 * @return the architecture name.
111 */
112 static String getArchName() {
113 // if running Linux on ARM, need to determine ABI of JVM
114 final String osArch = System.getProperty("os.arch");
115 if (osArch.startsWith("arm") && getOsNameProperty().contains("Linux")) {
116 final String javaHome = System.getProperty("java.home");
117 try {
118 // determine if first JVM found uses ARM hard-float ABI
119 final String[] cmdarray = { "/bin/sh", "-c",
120 "find '" + javaHome + "' -name 'libjvm.so' | head -1 | xargs readelf -A | grep 'Tag_ABI_VFP_args: VFP registers'" };
121 final int exitCode = Runtime.getRuntime().exec(cmdarray).waitFor();
122 if (exitCode == 0) {
123 return "armhf";
124 }
125 } catch (final IOException | InterruptedException e) { // NOPMD
126 // ignored: fall back to "arm" arch (soft-float ABI)
127 }
128 } else {
129 final String string = archMapping.get(osArch.toLowerCase(Locale.US));
130 if (string != null) {
131 return string;
132 }
133 }
134 return translateArchNameToFolderName(osArch);
135 }
136
137 /**
138 * Gets the native lib folder.
139 *
140 * @return the current OS's native lib folder.
141 */
142 static String getNativeLibFolderPathForCurrentOS() {
143 return getOSName() + File.separator + getArchName();
144 }
145
146 /**
147 * Gets the OS name.
148 *
149 * @return the OS name.
150 */
151 static String getOSName() {
152 return translateOSNameToFolderName(getOsNameProperty());
153 }
154
155 static String getOsNameProperty() {
156 return System.getProperty("os.name");
157 }
158
159 /**
160 * The main method. This is used by the JNI make processing in Makefile.common
161 *
162 * @param args the argv.
163 */
164 public static void main(final String[] args) {
165 if (args.length >= 1) {
166 if ("--os".equals(args[0])) {
167 System.out.println(getOSName());
168 return;
169 }
170 if ("--arch".equals(args[0])) {
171 System.out.println(getArchName());
172 return;
173 }
174 }
175
176 System.out.println(getNativeLibFolderPathForCurrentOS());
177 }
178
179 /**
180 * Translates the architecture name to folder name.
181 *
182 * @param archName the architecture name.
183 * @return the folder name.
184 */
185 private static String translateArchNameToFolderName(final String archName) {
186 return archName.replaceAll("\\W", "");
187 }
188
189 /**
190 * Translates the OS name to folder name.
191 *
192 * @param osName the OS name.
193 * @return the folder name.
194 */
195 private static String translateOSNameToFolderName(final String osName) {
196 if (osName.contains("Windows")) {
197 return "Windows";
198 }
199 if (osName.contains("Mac")) {
200 return "Mac";
201 }
202 if (osName.contains("Linux")) {
203 return "Linux";
204 }
205 if (osName.contains("AIX")) {
206 return "AIX";
207 }
208 return osName.replaceAll("\\W", "");
209 }
210
211 /**
212 * The private constructor of {@link OsInfo}.
213 */
214 private OsInfo() {
215 }
216 }