4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
32 #pragma weak _catopen = catopen
33 #pragma weak _catclose = catclose
37 #include <sys/types.h>
47 #include "../i18n/_loc_path.h"
48 #include "nlspath_checks.h"
54 replace_nls_option(char *, char *, char *, char *, char *, char *, char *);
55 static nl_catd
file_open(const char *, int);
56 static nl_catd
process_nls_path(char *, int);
59 catopen(const char *name
, int oflag
)
63 if (!name
) { /* Null pointer */
66 } else if (!*name
) { /* Empty string */
69 } else if (strchr(name
, '/') != NULL
) {
70 /* If name contains '/', then it is complete file name */
71 p
= file_open(name
, SAFE_F
);
72 } else { /* Normal case */
73 p
= process_nls_path((char *)name
, oflag
);
76 if (p
== NULL
) { /* Opening catalog file failed */
85 * This routine will process NLSPATH environment variable.
86 * It will return catd id whenever it finds valid catalog.
89 process_nls_path(char *name
, int oflag
)
91 char *s
, *s1
, *s2
, *t
;
92 char *nlspath
, *lang
, *territory
, *codeset
, *locale
;
93 char pathname
[PATH_MAX
+ 1];
97 * locale=language_territory.codeset
98 * XPG4 uses LC_MESSAGES.
100 * From the following two lines, choose one depending on XPG3 or 4.
102 * Chose XPG4. If oflag == NL_CAT_LOCALE, use LC_MESSAGES.
104 if (oflag
== NL_CAT_LOCALE
) {
105 locale_t loc
= uselocale(NULL
);
106 locale
= current_locale(loc
, LC_MESSAGES
);
108 locale
= getenv("LANG");
111 nlspath
= getenv("NLSPATH");
117 * extract lang, territory and codeset from locale name
120 lang
= s
= libc_strdup(locale
);
130 } else if (*s
== '.') {
141 * March through NLSPATH until finds valid cat file
146 /* unqualified pathname is unsafe */
147 p
= file_open(name
, UNSAFE_F
);
157 /* replace Substitution field */
158 s
= replace_nls_option(s
, name
, pathname
, locale
,
159 lang
, territory
, codeset
);
161 p
= file_open(pathname
, UNSAFE_F
);
172 /* lang is not used any more, free it */
177 * Implementation dependent default location of XPG3.
178 * We use /usr/lib/locale/<locale>/LC_MESSAGES/%N.
179 * If C locale, do not translate message.
181 if (locale
== NULL
) {
183 } else if (locale
[0] == 'C' && locale
[1] == '\0') {
184 p
= libc_malloc(sizeof (struct _nl_catd_struct
));
201 while (*s
&& t
< pathname
+ PATH_MAX
)
204 while (*s
&& t
< pathname
+ PATH_MAX
)
207 while (*s
&& t
< pathname
+ PATH_MAX
)
210 return (file_open(pathname
, SAFE_F
));
215 * This routine will replace substitution parameters in NLSPATH
216 * with appropiate values. Returns expanded pathname.
219 replace_nls_option(char *s
, char *name
, char *pathname
, char *locale
,
220 char *lang
, char *territory
, char *codeset
)
225 while (*s
&& *s
!= ':') {
226 if (t
< pathname
+ PATH_MAX
) {
228 * %% is considered a single % character (XPG).
229 * %L : LC_MESSAGES (XPG4) LANG(XPG3)
230 * %l : The language element from the current locale.
235 else if (*++s
== 'N') {
237 while (*u
&& t
< pathname
+ PATH_MAX
)
239 } else if (*s
== 'L') {
242 while (*u
&& t
< pathname
+ PATH_MAX
)
245 } else if (*s
== 'l') {
248 while (*u
&& *u
!= '_' &&
249 t
< pathname
+ PATH_MAX
)
252 } else if (*s
== 't') {
255 while (*u
&& *u
!= '.' &&
256 t
< pathname
+ PATH_MAX
)
259 } else if (*s
== 'c') {
262 while (*u
&& t
< pathname
+ PATH_MAX
)
266 if (t
< pathname
+ PATH_MAX
)
277 * This routine will open file, mmap it, and return catd id.
280 file_open(const char *name
, int safe
)
283 struct stat64 statbuf
;
285 struct _cat_hdr
*tmp
;
289 fd
= nls_safe_open(name
, &statbuf
, &trust
, safe
);
295 addr
= mmap(NULL
, (size_t)statbuf
.st_size
, PROT_READ
, MAP_SHARED
, fd
, 0);
298 if (addr
== MAP_FAILED
) {
302 /* check MAGIC number of catalogue file */
303 tmp
= (struct _cat_hdr
*)addr
;
304 if (tmp
->__hdr_magic
!= _CAT_MAGIC
) {
305 (void) munmap(addr
, (size_t)statbuf
.st_size
);
309 tmp_catd
= libc_malloc(sizeof (struct _nl_catd_struct
));
310 if (tmp_catd
== NULL
) {
312 (void) munmap(addr
, statbuf
.st_size
);
315 tmp_catd
->__content
= addr
;
316 tmp_catd
->__size
= (int)statbuf
.st_size
;
317 tmp_catd
->__trust
= trust
;
323 catclose(nl_catd catd
)
326 catd
!= (nl_catd
)-1) {
327 if (catd
->__content
) {
328 (void) munmap(catd
->__content
, catd
->__size
);
329 catd
->__content
= NULL
;