1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1985-2011 AT&T Intellectual Property          *
5 *                      and is licensed under the                       *
6 *                 Eclipse Public License, Version 1.0                  *
7 *                    by AT&T Intellectual Property                     *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *          http://www.eclipse.org/org/documents/epl-v10.html           *
11 *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12 *                                                                      *
13 *              Information and Software Systems Research               *
14 *                            AT&T Research                             *
15 *                           Florham Park NJ                            *
16 *                                                                      *
17 *                 Glenn Fowler <gsf@research.att.com>                  *
18 *                  David Korn <dgk@research.att.com>                   *
19 *                   Phong Vo <kpv@research.att.com>                    *
20 *                                                                      *
21 ***********************************************************************/
22 #pragma prototyped
23 
24 /*
25  * catopen intercept
26  * the ast catalogs are checked first
27  * the ast mc* and native cat* routines do all the work
28  * catalogs found by mcfind() are converted from utf to ucs
29  *
30  * nl_catd is cast to void*
31  * this is either an Mc_t* (Mc_t.set != 0)
32  * or a Cc_t* where Cc_t.cat is the native nl_catd
33  */
34 
35 #include <ast.h>
36 #include <mc.h>
37 #include <nl_types.h>
38 #include <iconv.h>
39 
40 #ifndef DEBUG_trace
41 #define DEBUG_trace		0
42 #endif
43 #if DEBUG_trace
44 #undef setlocale
45 #endif
46 
47 #if _lib_catopen
48 
49 #undef	nl_catd
50 #undef	catopen
51 #undef	catgets
52 #undef	catclose
53 
54 typedef struct
55 {
56 	Mcset_t*	set;
57 	nl_catd		cat;
58 	iconv_t		cvt;
59 	Sfio_t*		tmp;
60 } Cc_t;
61 
62 #else
63 
64 #define _ast_nl_catd	nl_catd
65 #define _ast_catopen	catopen
66 #define _ast_catgets	catgets
67 #define _ast_catclose	catclose
68 
69 #endif
70 
71 _ast_nl_catd
_ast_catopen(const char * name,int flag)72 _ast_catopen(const char* name, int flag)
73 {
74 	Mc_t*		mc;
75 	char*		s;
76 	Sfio_t*		ip;
77 	char		path[PATH_MAX];
78 
79 	/*
80 	 * first try the ast catalogs
81 	 */
82 
83 #if DEBUG_trace
84 sfprintf(sfstderr, "AHA#%d:%s %s LC_MESSAGES=%s:%s\n", __LINE__, __FILE__, name, _ast_setlocale(LC_MESSAGES, 0), setlocale(LC_MESSAGES, 0));
85 #endif
86 	if ((s = mcfind(NiL, name, LC_MESSAGES, flag, path, sizeof(path))) && (ip = sfopen(NiL, s, "r")))
87 	{
88 #if DEBUG_trace
89 sfprintf(sfstderr, "AHA#%d:%s %s\n", __LINE__, __FILE__, s);
90 #endif
91 		mc = mcopen(ip);
92 		sfclose(ip);
93 		if (mc)
94 			return (_ast_nl_catd)mc;
95 	}
96 #if _lib_catopen
97 	if (strcmp(setlocale(LC_MESSAGES, NiL), "debug"))
98 	{
99 		Cc_t*		cc;
100 		nl_catd		d;
101 
102 		/*
103 		 * now the native catalogs
104 		 */
105 
106 		if (s && (d = catopen(s, flag)) != (nl_catd)(-1) || !(s = 0) && (d = catopen(name, flag)) != (nl_catd)(-1))
107 		{
108 			if (!(cc = newof(0, Cc_t, 1, 0)))
109 			{
110 				catclose(d);
111 				return (_ast_nl_catd)(-1);
112 			}
113 			cc->cat = d;
114 			if ((s || *name == '/') && (ast.locale.set & (1<<AST_LC_MESSAGES)))
115 			{
116 				if ((cc->cvt = iconv_open("", "utf")) == (iconv_t)(-1) || !(cc->tmp = sfstropen()))
117 				{
118 					catclose(d);
119 					free(cc);
120 					return (_ast_nl_catd)(-1);
121 				}
122 			}
123 			else
124 				cc->cvt = (iconv_t)(-1);
125 #if DEBUG_trace
126 sfprintf(sfstderr, "AHA#%d:%s %s %s native %p\n", __LINE__, __FILE__, s, name, cc->cat);
127 #endif
128 			return (_ast_nl_catd)cc;
129 		}
130 	}
131 #endif
132 
133 	/*
134 	 * loser
135 	 */
136 
137 	return (_ast_nl_catd)(-1);
138 }
139 
140 char*
_ast_catgets(_ast_nl_catd cat,int set,int num,const char * msg)141 _ast_catgets(_ast_nl_catd cat, int set, int num, const char* msg)
142 {
143 	if (cat == (_ast_nl_catd)(-1))
144 		return (char*)msg;
145 #if _lib_catopen
146 	if (!((Cc_t*)cat)->set)
147 	{
148 		char*	s;
149 		size_t	n;
150 
151 		msg = (char*)catgets(((Cc_t*)cat)->cat, set, num, msg);
152 		if (((Cc_t*)cat)->cvt != (iconv_t)(-1))
153 		{
154 			s = (char*)msg;
155 			n = strlen(s);
156 			iconv_write(((Cc_t*)cat)->cvt, ((Cc_t*)cat)->tmp, &s, &n, NiL);
157 			if (s = sfstruse(((Cc_t*)cat)->tmp))
158 				return s;
159 		}
160 		return (char*)msg;
161 	}
162 #endif
163 	return mcget((Mc_t*)cat, set, num, msg);
164 }
165 
166 int
_ast_catclose(_ast_nl_catd cat)167 _ast_catclose(_ast_nl_catd cat)
168 {
169 	if (cat == (_ast_nl_catd)(-1))
170 		return -1;
171 #if _lib_catopen
172 	if (!((Cc_t*)cat)->set)
173 	{
174 		if (((Cc_t*)cat)->cvt != (iconv_t)(-1))
175 			iconv_close(((Cc_t*)cat)->cvt);
176 		if (((Cc_t*)cat)->tmp)
177 			sfclose(((Cc_t*)cat)->tmp);
178 		return catclose(((Cc_t*)cat)->cat);
179 	}
180 #endif
181 	return mcclose((Mc_t*)cat);
182 }
183