1 /*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26 /*
27 * Copyright 2015 Joyent, Inc.
28 */
29
30 #pragma weak _bindtextdomain = bindtextdomain
31 #pragma weak _textdomain = textdomain
32 #pragma weak _gettext = gettext
33 #pragma weak _dgettext = dgettext
34 #pragma weak _dcgettext = dcgettext
35 #pragma weak _ngettext = ngettext
36 #pragma weak _dngettext = dngettext
37 #pragma weak _dcngettext = dcngettext
38 #pragma weak _bind_textdomain_codeset = bind_textdomain_codeset
39
40 #include "lint.h"
41 #include "mtlib.h"
42 #include <errno.h>
43 #include <ctype.h>
44 #include <locale.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <sys/types.h>
48 #include <sys/param.h>
49 #include <libintl.h>
50 #include <thread.h>
51 #include <synch.h>
52 #include "libc.h"
53 #include "_loc_path.h"
54 #include "msgfmt.h"
55 #include "gettext.h"
56
57 #define INIT_GT(def) \
58 if (!global_gt) { \
59 global_gt = (Gettext_t *)calloc(1, sizeof (Gettext_t)); \
60 if (global_gt) \
61 global_gt->cur_domain = (char *)default_domain; \
62 else { \
63 callout_lock_exit(); \
64 return ((def)); \
65 } \
66 }
67
68 const char *defaultbind = DEFAULT_BINDING;
69 const char default_domain[] = DEFAULT_DOMAIN;
70 Gettext_t *global_gt = NULL;
71
72 char *
bindtextdomain(const char * domain,const char * binding)73 bindtextdomain(const char *domain, const char *binding)
74 {
75 char *res;
76
77 callout_lock_enter();
78 INIT_GT(NULL);
79 res = _real_bindtextdomain_u(domain, binding, TP_BINDING);
80 callout_lock_exit();
81 return (res);
82 }
83
84 char *
bind_textdomain_codeset(const char * domain,const char * codeset)85 bind_textdomain_codeset(const char *domain, const char *codeset)
86 {
87 char *res;
88
89 callout_lock_enter();
90 INIT_GT(NULL);
91 res = _real_bindtextdomain_u(domain, codeset, TP_CODESET);
92 callout_lock_exit();
93 return (res);
94 }
95
96 /*
97 * textdomain() sets or queries the name of the current domain of
98 * the active LC_MESSAGES locale category.
99 */
100 char *
textdomain(const char * domain)101 textdomain(const char *domain)
102 {
103 char *res;
104 char tmp_domain[TEXTDOMAINMAX + 1];
105
106 callout_lock_enter();
107 INIT_GT(NULL);
108 res = _textdomain_u(domain, tmp_domain);
109 if (res == NULL) {
110 callout_lock_exit();
111 return (NULL);
112 }
113 callout_lock_exit();
114 return (CURRENT_DOMAIN(global_gt));
115 }
116
117 /*
118 * gettext() is a pass-thru to _real_gettext_u() with a NULL pointer passed
119 * for domain and LC_MESSAGES passed for category.
120 */
121 char *
gettext(const char * msg_id)122 gettext(const char *msg_id)
123 {
124 char *res;
125 int errno_save = errno;
126
127 callout_lock_enter();
128 INIT_GT((char *)msg_id);
129 res = _real_gettext_u(NULL, msg_id, NULL, 0, LC_MESSAGES, 0, NULL);
130 callout_lock_exit();
131 errno = errno_save;
132 return (res);
133 }
134
135
136 /*
137 * In dcgettext() call, domain is valid only for this call.
138 */
139 char *
dgettext(const char * domain,const char * msg_id)140 dgettext(const char *domain, const char *msg_id)
141 {
142 char *res;
143 int errno_save = errno;
144
145 callout_lock_enter();
146 INIT_GT((char *)msg_id);
147 res = _real_gettext_u(domain, msg_id, NULL, 0, LC_MESSAGES, 0, NULL);
148 callout_lock_exit();
149 errno = errno_save;
150 return (res);
151 }
152
153 char *
dgettext_l(const char * domain,const char * msg_id,locale_t loc)154 dgettext_l(const char *domain, const char *msg_id, locale_t loc)
155 {
156 char *res;
157 int errno_save = errno;
158
159 callout_lock_enter();
160 INIT_GT((char *)msg_id);
161 res = _real_gettext_u(domain, msg_id, NULL, 0, LC_MESSAGES, 0, loc);
162 callout_lock_exit();
163 errno = errno_save;
164 return (res);
165 }
166
167 char *
dcgettext(const char * domain,const char * msg_id,const int category)168 dcgettext(const char *domain, const char *msg_id, const int category)
169 {
170 char *res;
171 int errno_save = errno;
172
173 callout_lock_enter();
174 INIT_GT((char *)msg_id);
175 res = _real_gettext_u(domain, msg_id, NULL, 0, category, 0, NULL);
176 callout_lock_exit();
177 errno = errno_save;
178 return (res);
179 }
180
181 char *
ngettext(const char * msgid1,const char * msgid2,unsigned long int n)182 ngettext(const char *msgid1, const char *msgid2, unsigned long int n)
183 {
184 char *res;
185 int errno_save = errno;
186
187 callout_lock_enter();
188 INIT_GT((char *)msgid1);
189 res = _real_gettext_u(NULL, msgid1, msgid2, n, LC_MESSAGES, 1, NULL);
190 callout_lock_exit();
191 errno = errno_save;
192 return (res);
193 }
194
195 char *
dngettext(const char * domain,const char * msgid1,const char * msgid2,unsigned long int n)196 dngettext(const char *domain, const char *msgid1, const char *msgid2,
197 unsigned long int n)
198 {
199 char *res;
200 int errno_save = errno;
201
202 callout_lock_enter();
203 INIT_GT((char *)msgid1);
204 res = _real_gettext_u(domain, msgid1, msgid2, n, LC_MESSAGES, 1, NULL);
205 callout_lock_exit();
206 errno = errno_save;
207 return (res);
208 }
209
210 char *
dcngettext(const char * domain,const char * msgid1,const char * msgid2,unsigned long int n,int category)211 dcngettext(const char *domain, const char *msgid1, const char *msgid2,
212 unsigned long int n, int category)
213 {
214 char *res;
215 int errno_save = errno;
216
217 callout_lock_enter();
218 INIT_GT((char *)msgid1);
219 res = _real_gettext_u(domain, msgid1, msgid2, n, category, 1, NULL);
220 callout_lock_exit();
221 errno = errno_save;
222 return (res);
223 }
224