2  * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. Please obtain a copy of the License at 
  10  * http://www.opensource.apple.com/apsl/ and read it before using this 
  13  * The Original Code and all software distributed under the License are 
  14  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  15  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  16  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  17  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  18  * Please see the License for the specific language governing rights and 
  19  * limitations under the License. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  23 /*      CFStringDefaultEncoding.h 
  24         Copyright (c) 1998-2005, Apple, Inc. All rights reserved. 
  27 /* This file defines static inline functions used both by CarbonCore & CF. */ 
  29 #include <CoreFoundation/CFBase.h> 
  34 #include <sys/param.h> 
  39 #if defined(__cplusplus) 
  43 #define __kCFUserEncodingEnvVariableName ("__CF_USER_TEXT_ENCODING") 
  44 #define __kCFMaxDefaultEncodingFileLength (24) 
  45 #define __kCFUserEncodingFileName ("/.CFUserTextEncoding") 
  47 /* This function is used to obtain users' default script/region code. 
  48    The function first looks at environment variable __kCFUserEncodingEnvVariableName, then, reads the configuration file in user's home directory. 
  50 CF_INLINE 
void __CFStringGetUserDefaultEncoding(UInt32 
*oScriptValue
, UInt32 
*oRegionValue
) { 
  52     char buffer
[__kCFMaxDefaultEncodingFileLength
]; 
  55     if ((stringValue 
= getenv(__kCFUserEncodingEnvVariableName
)) != NULL
) { 
  56         if ((uid 
== strtol(stringValue
, &stringValue
, 0)) && (':' == *stringValue
)) { 
  63     if ((stringValue 
== NULL
) && ((uid 
> 0) || getenv("HOME"))) { 
  64         struct passwd 
*passwdp
; 
  66         if ((passwdp 
= getpwuid((uid_t
)uid
))) { 
  67             char filename
[MAXPATHLEN 
+ 1]; 
  70             strcpy(filename
, passwdp
->pw_dir
); 
  71             strcat(filename
, __kCFUserEncodingFileName
); 
  73             if ((fd 
= open(filename
, O_RDONLY
, 0)) == -1) { 
  74                 // Cannot open the file. Let's fallback to smRoman/verUS 
  75                 snprintf(filename
, sizeof(filename
), "%s=0x%X:0:0", __kCFUserEncodingEnvVariableName
, uid
); 
  80                 // cjk: We do not turn on F_NOCACHE on the fd here, because 
  81                 // many processes read this file on startup, and caching the 
  82                 // is probably a good thing, for the system as a whole. 
  83                 readSize 
= read(fd
, buffer
, __kCFMaxDefaultEncodingFileLength 
- 1); 
  84                 buffer
[(readSize 
< 0 ? 0 : readSize
)] = '\0'; 
  88                 // Well, we already have a buffer, let's reuse it 
  89                 snprintf(filename
, sizeof(filename
), "%s=0x%X:%s", __kCFUserEncodingEnvVariableName
, uid
, buffer
); 
  96         *oScriptValue 
= strtol(stringValue
, &stringValue
, 0); 
  97         if (*stringValue 
== ':') { 
  98             if (oRegionValue
) *oRegionValue 
= strtol(++stringValue
, NULL
, 0); 
 104     *oScriptValue 
= 0; // smRoman 
 105     if (oRegionValue
) *oRegionValue 
= 0; // verUS 
 108 CF_INLINE 
uint32_t __CFStringGetInstallationRegion() { 
 109     char *stringValue 
= NULL
; 
 110     char buffer
[__kCFMaxDefaultEncodingFileLength
]; 
 111     struct passwd 
*passwdp
; 
 113     if ((passwdp 
= getpwuid((uid_t
)0))) { 
 114         char filename
[MAXPATHLEN 
+ 1]; 
 117         strcpy(filename
, passwdp
->pw_dir
); 
 118         strcat(filename
, __kCFUserEncodingFileName
); 
 120         if ((fd 
= open(filename
, O_RDONLY
, 0)) != -1) { 
 123             // cjk: We do not turn on F_NOCACHE on the fd here, because 
 124             // many processes read this file on startup, and caching the 
 125             // is probably a good thing, for the system as a whole. 
 126             readSize 
= read(fd
, buffer
, __kCFMaxDefaultEncodingFileLength 
- 1); 
 127             buffer
[(readSize 
< 0 ? 0 : readSize
)] = '\0'; 
 129             stringValue 
= buffer
; 
 134         (void)strtol(stringValue
, &stringValue
, 0); 
 135         if (*stringValue 
== ':') return strtol(++stringValue
, NULL
, 0); 
 141 CF_INLINE 
void __CFStringGetInstallationEncodingAndRegion(uint32_t *encoding
, uint32_t *region
) { 
 142     char *stringValue 
= NULL
; 
 143     char buffer
[__kCFMaxDefaultEncodingFileLength
]; 
 144     struct passwd 
*passwdp
; 
 146     *encoding 
= 0; *region 
= 0; 
 148     if ((passwdp 
= getpwuid((uid_t
)0))) { 
 149         char filename
[MAXPATHLEN 
+ 1]; 
 152         strcpy(filename
, passwdp
->pw_dir
); 
 153         strcat(filename
, __kCFUserEncodingFileName
); 
 155         if ((fd 
= open(filename
, O_RDONLY
, 0)) != -1) { 
 158             // cjk: We do not turn on F_NOCACHE on the fd here, because 
 159             // many processes read this file on startup, and caching the 
 160             // is probably a good thing, for the system as a whole. 
 161             readSize 
= read(fd
, buffer
, __kCFMaxDefaultEncodingFileLength 
- 1); 
 162             buffer
[(readSize 
< 0 ? 0 : readSize
)] = '\0'; 
 164             stringValue 
= buffer
; 
 169         *encoding 
= strtol(stringValue
, &stringValue
, 0); 
 170         if (*stringValue 
== ':') *region 
= strtol(++stringValue
, NULL
, 0); 
 174 CF_INLINE 
void __CFStringSaveUserDefaultEncoding(UInt32 iScriptValue
, UInt32 iRegionValue
) { 
 175     struct passwd 
*passwdp
; 
 177     if ((passwdp 
= getpwuid(getuid()))) { 
 178         char filename
[MAXPATHLEN 
+ 1]; 
 181         strcpy(filename
, passwdp
->pw_dir
); 
 182         strcat(filename
, __kCFUserEncodingFileName
); 
 184         // In case, file exists 
 185         (void)unlink(filename
); 
 187         if ((fd 
= open(filename
, O_WRONLY
|O_CREAT
, 0400)) != -1) { 
 188             char buffer
[__kCFMaxDefaultEncodingFileLength
]; 
 189             unsigned int writeSize
; 
 191             writeSize 
= snprintf(buffer
, __kCFMaxDefaultEncodingFileLength
, "0x%X:0x%X", (unsigned int)iScriptValue
, (unsigned int)iRegionValue
); 
 192             (void)write(fd
, buffer
, (writeSize 
> __kCFMaxDefaultEncodingFileLength 
? __kCFMaxDefaultEncodingFileLength 
: writeSize
)); 
 198 #if defined(__cplusplus) 
 202 #endif /* __MACH__ */