1 /* 2 * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include <dlfcn.h> 27 #include <sys/socket.h> 28 #include <netinet/in.h> 29 #include <arpa/inet.h> 30 31 #include <Security/AuthSession.h> 32 #include <CoreFoundation/CoreFoundation.h> 33 #include <SystemConfiguration/SystemConfiguration.h> 34 #include <Foundation/Foundation.h> 35 36 #include "java_props_macosx.h" 37 38 // need dlopen/dlsym trick to avoid pulling in JavaRuntimeSupport before libjava.dylib is loaded 39 static void *getJRSFramework() { 40 static void *jrsFwk = NULL; 41 #ifndef STATIC_BUILD 42 // JavaRuntimeSupport doesn't support static Java runtimes 43 if (jrsFwk == NULL) { 44 jrsFwk = dlopen("/System/Library/Frameworks/JavaVM.framework/Frameworks/JavaRuntimeSupport.framework/JavaRuntimeSupport", RTLD_LAZY | RTLD_LOCAL); 45 } 46 #endif 47 return jrsFwk; 48 } 49 50 char *getPosixLocale(int cat) { 51 char *lc = setlocale(cat, NULL); 52 if ((lc == NULL) || (strcmp(lc, "C") == 0)) { 53 lc = getenv("LANG"); 54 } 55 if (lc == NULL) return NULL; 56 return strdup(lc); 57 } 58 59 #define LOCALEIDLENGTH 128 60 char *getMacOSXLocale(int cat) { 61 switch (cat) { 62 case LC_MESSAGES: 63 { 64 void *jrsFwk = getJRSFramework(); 65 if (jrsFwk == NULL) return NULL; 66 67 char *(*JRSCopyPrimaryLanguage)() = dlsym(jrsFwk, "JRSCopyPrimaryLanguage"); 68 char *primaryLanguage = JRSCopyPrimaryLanguage ? JRSCopyPrimaryLanguage() : NULL; 69 if (primaryLanguage == NULL) return NULL; 70 71 char *(*JRSCopyCanonicalLanguageForPrimaryLanguage)(char *) = dlsym(jrsFwk, "JRSCopyCanonicalLanguageForPrimaryLanguage"); 72 char *canonicalLanguage = JRSCopyCanonicalLanguageForPrimaryLanguage ? JRSCopyCanonicalLanguageForPrimaryLanguage(primaryLanguage) : NULL; 73 free (primaryLanguage); 74 75 return canonicalLanguage; 76 } 77 break; 78 default: 79 { 80 char localeString[LOCALEIDLENGTH]; 81 if (CFStringGetCString(CFLocaleGetIdentifier(CFLocaleCopyCurrent()), 82 localeString, LOCALEIDLENGTH, CFStringGetSystemEncoding())) { 83 return strdup(localeString); 84 } 85 } 86 break; 87 } 88 89 return NULL; 90 } 91 92 char *setupMacOSXLocale(int cat) { 93 char * ret = getMacOSXLocale(cat); 94 95 if (cat == LC_MESSAGES && ret != NULL) { 96 void *jrsFwk = getJRSFramework(); 97 if (jrsFwk != NULL) { 98 void (*JRSSetDefaultLocalization)(char *) = dlsym(jrsFwk, "JRSSetDefaultLocalization"); 99 if (JRSSetDefaultLocalization) JRSSetDefaultLocalization(ret); 100 } 101 } 102 103 if (ret == NULL) { 104 return getPosixLocale(cat); 105 } else { 106 return ret; 107 } 108 } 109 110 int isInAquaSession() { 111 // environment variable to bypass the aqua session check 112 char *ev = getenv("AWT_FORCE_HEADFUL"); 113 if (ev && (strncasecmp(ev, "true", 4) == 0)) { 114 // if "true" then tell the caller we're in an Aqua session without actually checking 115 return 1; 116 } 117 // Is the WindowServer available? 118 SecuritySessionId session_id; 119 SessionAttributeBits session_info; 120 OSStatus status = SessionGetInfo(callerSecuritySession, &session_id, &session_info); 121 if (status == noErr) { 122 if (session_info & sessionHasGraphicAccess) { 123 return 1; 124 } 125 } 126 return 0; 127 } 128 129 void setOSNameAndVersion(java_props_t *sprops) { 130 /* Don't rely on JRSCopyOSName because there's no guarantee the value will 131 * remain the same, or even if the JRS functions will continue to be part of 132 * Mac OS X. So hardcode os_name, and fill in os_version if we can. 133 */ 134 sprops->os_name = strdup("Mac OS X"); 135 136 void *jrsFwk = getJRSFramework(); 137 if (jrsFwk != NULL) { 138 char *(*copyOSVersion)() = dlsym(jrsFwk, "JRSCopyOSVersion"); 139 if (copyOSVersion != NULL) { 140 sprops->os_version = copyOSVersion(); 141 return; 142 } 143 } 144 sprops->os_version = strdup("Unknown"); 145 } 146 147 148 static Boolean getProxyInfoForProtocol(CFDictionaryRef inDict, CFStringRef inEnabledKey, CFStringRef inHostKey, CFStringRef inPortKey, CFStringRef *outProxyHost, int *ioProxyPort) { 149 /* See if the proxy is enabled. */ 150 CFNumberRef cf_enabled = CFDictionaryGetValue(inDict, inEnabledKey); 151 if (cf_enabled == NULL) { 152 return false; 153 } 154 155 int isEnabled = false; 156 if (!CFNumberGetValue(cf_enabled, kCFNumberIntType, &isEnabled)) { 157 return isEnabled; 158 } 159 160 if (!isEnabled) return false; 161 *outProxyHost = CFDictionaryGetValue(inDict, inHostKey); 162 163 // If cf_host is null, that means the checkbox is set, 164 // but no host was entered. We'll treat that as NOT ENABLED. | 1 /* 2 * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include <sys/socket.h> 27 #include <netinet/in.h> 28 #include <arpa/inet.h> 29 #include <objc/objc-runtime.h> 30 31 #include <Security/AuthSession.h> 32 #include <CoreFoundation/CoreFoundation.h> 33 #include <SystemConfiguration/SystemConfiguration.h> 34 #include <Foundation/Foundation.h> 35 36 #include "java_props_macosx.h" 37 38 char *getPosixLocale(int cat) { 39 char *lc = setlocale(cat, NULL); 40 if ((lc == NULL) || (strcmp(lc, "C") == 0)) { 41 lc = getenv("LANG"); 42 } 43 if (lc == NULL) return NULL; 44 return strdup(lc); 45 } 46 47 #define LOCALEIDLENGTH 128 48 char *getMacOSXLocale(int cat) { 49 switch (cat) { 50 case LC_MESSAGES: 51 { 52 // get preferred language code 53 CFArrayRef languages = CFLocaleCopyPreferredLanguages(); 54 if (languages == NULL) { 55 return NULL; 56 } 57 if (CFArrayGetCount(languages) <= 0) { 58 CFRelease(languages); 59 return NULL; 60 } 61 62 CFStringRef primaryLanguage = (CFStringRef)CFArrayGetValueAtIndex(languages, 0); 63 if (primaryLanguage == NULL) { 64 CFRelease(languages); 65 return NULL; 66 } 67 char languageString[LOCALEIDLENGTH]; 68 if (CFStringGetCString(primaryLanguage, languageString, 69 LOCALEIDLENGTH, CFStringGetSystemEncoding()) == false) { 70 CFRelease(languages); 71 return NULL; 72 } 73 CFRelease(languages); 74 75 // Language IDs use the language designators and (optional) region 76 // and script designators of BCP 47. So possible formats are: 77 // 78 // "en" (language designator only) 79 // "en-GB" (language with region designator) 80 // "zh-Hans" (language with ISO 15924 script designator) 81 // "zh-Hans_HK" (language with both script and region designator) 82 // 83 // In the case of a region designator (but no script designator), we 84 // convert to ISO 639 by changing '-' to '_'. 85 char* scriptOrRegion = strchr(languageString, '-'); 86 if (scriptOrRegion != NULL) { 87 // If we find '_' later, that indicates a script+region 88 // (e.g. zh-Hans_HK), and we should not convert '-' to '_'. 89 if (!strchr(scriptOrRegion, '_')) { 90 if (strlen(scriptOrRegion) == 3) { 91 // The '-' is followed by a 2 character region designator, 92 // so we should convert '-' to '_'. 93 assert(scriptOrRegion[1] >= 'A' && scriptOrRegion[1] <= 'Z' && 94 scriptOrRegion[2] >= 'A' && scriptOrRegion[2] <= 'Z'); 95 *scriptOrRegion = '_'; // BCP 47 lang-region -> ISO_639-1 96 } 97 // Otherwise, we have a 4-character script designator 98 // (e.g. zh-Hans), and the '-' should be left as is. 99 } 100 } 101 102 const char* retVal = languageString; 103 104 // Special case for Portuguese in Brazil: 105 // The language code needs the "_BR" region code (to distinguish it 106 // from Portuguese in Portugal), but this is missing when using the 107 // "Portuguese (Brazil)" language. 108 // If language is "pt" and the current locale is pt_BR, return pt_BR. 109 char localeString[LOCALEIDLENGTH]; 110 if (strcmp(retVal, "pt") == 0) { 111 if (CFStringGetCString(CFLocaleGetIdentifier(CFLocaleCopyCurrent()), 112 localeString, LOCALEIDLENGTH, CFStringGetSystemEncoding())) { 113 if (strcmp(localeString, "pt_BR") == 0) { 114 retVal = localeString; 115 } 116 } 117 } 118 return strdup(retVal); 119 } 120 break; 121 default: 122 { 123 char localeString[LOCALEIDLENGTH]; 124 if (CFStringGetCString(CFLocaleGetIdentifier(CFLocaleCopyCurrent()), 125 localeString, LOCALEIDLENGTH, CFStringGetSystemEncoding())) { 126 return strdup(localeString); 127 } 128 } 129 break; 130 } 131 132 return NULL; 133 } 134 135 char *setupMacOSXLocale(int cat) { 136 char * ret = getMacOSXLocale(cat); 137 138 if (ret == NULL) { 139 return getPosixLocale(cat); 140 } else { 141 return ret; 142 } 143 } 144 145 int isInAquaSession() { 146 // environment variable to bypass the aqua session check 147 char *ev = getenv("AWT_FORCE_HEADFUL"); 148 if (ev && (strncasecmp(ev, "true", 4) == 0)) { 149 // if "true" then tell the caller we're in an Aqua session without actually checking 150 return 1; 151 } 152 // Is the WindowServer available? 153 SecuritySessionId session_id; 154 SessionAttributeBits session_info; 155 OSStatus status = SessionGetInfo(callerSecuritySession, &session_id, &session_info); 156 if (status == noErr) { 157 if (session_info & sessionHasGraphicAccess) { 158 return 1; 159 } 160 } 161 return 0; 162 } 163 164 // 10.9 SDK does not include the NSOperatingSystemVersion struct. 165 // For now, create our own 166 typedef struct { 167 NSInteger majorVersion; 168 NSInteger minorVersion; 169 NSInteger patchVersion; 170 } OSVerStruct; 171 172 void setOSNameAndVersion(java_props_t *sprops) { 173 // Hardcode os_name, and fill in os_version 174 sprops->os_name = strdup("Mac OS X"); 175 176 char* osVersionCStr = NULL; 177 // Mac OS 10.9 includes the [NSProcessInfo operatingSystemVersion] function, 178 // but it's not in the 10.9 SDK. So, call it via objc_msgSend_stret. 179 if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) { 180 OSVerStruct (*procInfoFn)(id rec, SEL sel) = (OSVerStruct(*)(id, SEL))objc_msgSend_stret; 181 OSVerStruct osVer = procInfoFn([NSProcessInfo processInfo], 182 @selector(operatingSystemVersion)); 183 NSString *nsVerStr = [NSString stringWithFormat:@"%ld.%ld.%ld", 184 (long)osVer.majorVersion, (long)osVer.minorVersion, (long)osVer.patchVersion]; 185 // Copy out the char* 186 osVersionCStr = strdup([nsVerStr UTF8String]); 187 } 188 189 if (osVersionCStr == NULL) { 190 osVersionCStr = strdup("Unknown"); 191 } 192 sprops->os_version = osVersionCStr; 193 } 194 195 196 static Boolean getProxyInfoForProtocol(CFDictionaryRef inDict, CFStringRef inEnabledKey, CFStringRef inHostKey, CFStringRef inPortKey, CFStringRef *outProxyHost, int *ioProxyPort) { 197 /* See if the proxy is enabled. */ 198 CFNumberRef cf_enabled = CFDictionaryGetValue(inDict, inEnabledKey); 199 if (cf_enabled == NULL) { 200 return false; 201 } 202 203 int isEnabled = false; 204 if (!CFNumberGetValue(cf_enabled, kCFNumberIntType, &isEnabled)) { 205 return isEnabled; 206 } 207 208 if (!isEnabled) return false; 209 *outProxyHost = CFDictionaryGetValue(inDict, inHostKey); 210 211 // If cf_host is null, that means the checkbox is set, 212 // but no host was entered. We'll treat that as NOT ENABLED. |