2 * Copyright (c) 2008 Apple 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-2007, Apple Inc. All rights reserved.
27 #if !defined(__COREFOUNDATION_CFSTRINGDEFAULTENCODING__)
28 #define __COREFOUNDATION_CFSTRINGDEFAULTENCODING__ 1
30 /* This file defines static inline functions used both by CarbonCore & CF. */
32 #include <CoreFoundation/CFBase.h>
38 #include <sys/param.h>
46 #define __kCFUserEncodingEnvVariableName ("__CF_USER_TEXT_ENCODING")
47 #define __kCFMaxDefaultEncodingFileLength (24)
48 #define __kCFUserEncodingFileName ("/.CFUserTextEncoding")
50 /* This function is used to obtain users' default script/region code.
51 The function first looks at environment variable __kCFUserEncodingEnvVariableName, then, reads the configuration file in user's home directory.
53 CF_INLINE
void __CFStringGetUserDefaultEncoding(UInt32
*oScriptValue
, UInt32
*oRegionValue
) {
55 char buffer
[__kCFMaxDefaultEncodingFileLength
];
58 if ((stringValue
= getenv(__kCFUserEncodingEnvVariableName
)) != NULL
) {
59 if ((uid
== strtol_l(stringValue
, &stringValue
, 0, NULL
)) && (':' == *stringValue
)) {
66 if ((stringValue
== NULL
) && ((uid
> 0) || getenv("HOME"))) {
67 struct passwd
*passwdp
;
69 if ((passwdp
= getpwuid((uid_t
)uid
))) {
70 char filename
[MAXPATHLEN
+ 1];
72 const char *path
= NULL
;
74 path
= getenv("CFFIXED_USER_HOME");
77 path
= passwdp
->pw_dir
;
80 strlcpy(filename
, path
, sizeof(filename
));
81 strlcat(filename
, __kCFUserEncodingFileName
, sizeof(filename
));
83 int no_hang_fd
= open("/dev/autofs_nowait", 0);
84 int fd
= open(filename
, O_RDONLY
, 0);
86 // Cannot open the file. Let's fallback to smRoman/verUS
87 snprintf(filename
, sizeof(filename
), "0x%X:0:0", uid
);
88 setenv(__kCFUserEncodingEnvVariableName
, filename
, 1);
92 // cjk: We do not turn on F_NOCACHE on the fd here, because
93 // many processes read this file on startup, and caching the
94 // is probably a good thing, for the system as a whole.
95 readSize
= read(fd
, buffer
, __kCFMaxDefaultEncodingFileLength
- 1);
96 buffer
[(readSize
< 0 ? 0 : readSize
)] = '\0';
100 // Well, we already have a buffer, let's reuse it
101 snprintf(filename
, sizeof(filename
), "0x%X:%s", uid
, buffer
);
102 setenv(__kCFUserEncodingEnvVariableName
, filename
, 1);
109 *oScriptValue
= strtol_l(stringValue
, &stringValue
, 0, NULL
);
110 if (*stringValue
== ':') {
111 if (oRegionValue
) *oRegionValue
= strtol_l(++stringValue
, NULL
, 0, NULL
);
117 *oScriptValue
= 0; // smRoman
118 if (oRegionValue
) *oRegionValue
= 0; // verUS
121 CF_INLINE
uint32_t __CFStringGetInstallationRegion() {
122 char *stringValue
= NULL
;
123 char buffer
[__kCFMaxDefaultEncodingFileLength
];
124 struct passwd
*passwdp
;
126 if ((passwdp
= getpwuid((uid_t
)0))) {
127 char filename
[MAXPATHLEN
+ 1];
129 const char *path
= NULL
;
131 path
= getenv("CFFIXED_USER_HOME");
134 path
= passwdp
->pw_dir
;
137 strlcpy(filename
, path
, sizeof(filename
));
138 strlcat(filename
, __kCFUserEncodingFileName
, sizeof(filename
));
140 int no_hang_fd
= open("/dev/autofs_nowait", 0);
141 int fd
= open(filename
, O_RDONLY
, 0);
145 // cjk: We do not turn on F_NOCACHE on the fd here, because
146 // many processes read this file on startup, and caching the
147 // is probably a good thing, for the system as a whole.
148 readSize
= read(fd
, buffer
, __kCFMaxDefaultEncodingFileLength
- 1);
149 buffer
[(readSize
< 0 ? 0 : readSize
)] = '\0';
151 stringValue
= buffer
;
157 (void)strtol_l(stringValue
, &stringValue
, 0, NULL
);
158 if (*stringValue
== ':') return strtol_l(++stringValue
, NULL
, 0, NULL
);
164 CF_INLINE
void __CFStringGetInstallationEncodingAndRegion(uint32_t *encoding
, uint32_t *region
) {
165 char *stringValue
= NULL
;
166 char buffer
[__kCFMaxDefaultEncodingFileLength
];
167 struct passwd
*passwdp
;
169 *encoding
= 0; *region
= 0;
171 if ((passwdp
= getpwuid((uid_t
)0))) {
172 char filename
[MAXPATHLEN
+ 1];
174 const char *path
= NULL
;
176 path
= getenv("CFFIXED_USER_HOME");
179 path
= passwdp
->pw_dir
;
182 strlcpy(filename
, path
, sizeof(filename
));
183 strlcat(filename
, __kCFUserEncodingFileName
, sizeof(filename
));
185 int no_hang_fd
= open("/dev/autofs_nowait", 0);
186 int fd
= open(filename
, O_RDONLY
, 0);
190 readSize
= read(fd
, buffer
, __kCFMaxDefaultEncodingFileLength
- 1);
191 buffer
[(readSize
< 0 ? 0 : readSize
)] = '\0';
193 stringValue
= buffer
;
199 *encoding
= strtol_l(stringValue
, &stringValue
, 0, NULL
);
200 if (*stringValue
== ':') *region
= strtol_l(++stringValue
, NULL
, 0, NULL
);
204 CF_INLINE
void __CFStringSaveUserDefaultEncoding(UInt32 iScriptValue
, UInt32 iRegionValue
) {
205 struct passwd
*passwdp
;
207 if ((passwdp
= getpwuid(getuid()))) {
208 char filename
[MAXPATHLEN
+ 1];
210 const char *path
= NULL
;
212 path
= getenv("CFFIXED_USER_HOME");
215 path
= passwdp
->pw_dir
;
218 strlcpy(filename
, path
, sizeof(filename
));
219 strlcat(filename
, __kCFUserEncodingFileName
, sizeof(filename
));
221 int no_hang_fd
= open("/dev/autofs_nowait", 0);
222 (void)unlink(filename
); // In case, file exists
223 int fd
= open(filename
, O_WRONLY
|O_CREAT
, 0400);
225 char buffer
[__kCFMaxDefaultEncodingFileLength
];
226 unsigned int writeSize
;
228 writeSize
= snprintf(buffer
, __kCFMaxDefaultEncodingFileLength
, "0x%X:0x%X", (unsigned int)iScriptValue
, (unsigned int)iRegionValue
);
229 (void)write(fd
, buffer
, (writeSize
> __kCFMaxDefaultEncodingFileLength
? __kCFMaxDefaultEncodingFileLength
: writeSize
));
240 #endif /* ! __COREFOUNDATION_CFSTRINGDEFAULTENCODING__ */