xref: /titanic_41/usr/src/lib/libast/common/comp/catopen.c (revision ea394cb00fd96864e34d2841b4a22357b621c78f)
1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1985-2009 AT&T Intellectual Property          *
5 *                      and is licensed under the                       *
6 *                  Common Public License, Version 1.0                  *
7 *                    by AT&T Intellectual Property                     *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *            http://www.opensource.org/licenses/cpl1.0.txt             *
11 *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
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 
44 #if _lib_catopen
45 
46 #undef	nl_catd
47 #undef	catopen
48 #undef	catgets
49 #undef	catclose
50 
51 typedef struct
52 {
53 	Mcset_t*	set;
54 	nl_catd		cat;
55 	iconv_t		cvt;
56 	Sfio_t*		tmp;
57 } Cc_t;
58 
59 #else
60 
61 #define _ast_nl_catd	nl_catd
62 #define _ast_catopen	catopen
63 #define _ast_catgets	catgets
64 #define _ast_catclose	catclose
65 
66 #endif
67 
68 _ast_nl_catd
69 _ast_catopen(const char* name, int flag)
70 {
71 	Mc_t*		mc;
72 	char*		s;
73 	Sfio_t*		ip;
74 	char		path[PATH_MAX];
75 
76 	/*
77 	 * first try the ast catalogs
78 	 */
79 
80 #if DEBUG_trace
81 sfprintf(sfstderr, "AHA#%d:%s %s\n", __LINE__, __FILE__, name);
82 #endif
83 	if ((s = mcfind(path, NiL, name, LC_MESSAGES, flag)) && (ip = sfopen(NiL, s, "r")))
84 	{
85 #if DEBUG_trace
86 sfprintf(sfstderr, "AHA#%d:%s %s\n", __LINE__, __FILE__, s);
87 #endif
88 		mc = mcopen(ip);
89 		sfclose(ip);
90 		if (mc)
91 			return (_ast_nl_catd)mc;
92 	}
93 #if _lib_catopen
94 	if (strcmp(setlocale(LC_MESSAGES, NiL), "debug"))
95 	{
96 		Cc_t*		cc;
97 		nl_catd		d;
98 
99 		/*
100 		 * now the native catalogs
101 		 */
102 
103 		if (s && (d = catopen(s, flag)) != (nl_catd)(-1) || !(s = 0) && (d = catopen(name, flag)) != (nl_catd)(-1))
104 		{
105 			if (!(cc = newof(0, Cc_t, 1, 0)))
106 			{
107 				catclose(d);
108 				return (_ast_nl_catd)(-1);
109 			}
110 			cc->cat = d;
111 			if ((s || *name == '/') && (ast.locale.set & (1<<AST_LC_MESSAGES)))
112 			{
113 				if ((cc->cvt = iconv_open("", "utf")) == (iconv_t)(-1) || !(cc->tmp = sfstropen()))
114 				{
115 					catclose(d);
116 					return (_ast_nl_catd)(-1);
117 				}
118 			}
119 			else
120 				cc->cvt = (iconv_t)(-1);
121 #if DEBUG_trace
122 sfprintf(sfstderr, "AHA#%d:%s %s %s native %p\n", __LINE__, __FILE__, s, name, cc->cat);
123 #endif
124 			return (_ast_nl_catd)cc;
125 		}
126 	}
127 #endif
128 
129 	/*
130 	 * loser
131 	 */
132 
133 	return (_ast_nl_catd)(-1);
134 }
135 
136 char*
137 _ast_catgets(_ast_nl_catd cat, int set, int num, const char* msg)
138 {
139 	if (cat == (_ast_nl_catd)(-1))
140 		return (char*)msg;
141 #if _lib_catopen
142 	if (!((Cc_t*)cat)->set)
143 	{
144 		char*	s;
145 		size_t	n;
146 
147 		msg = (char*)catgets(((Cc_t*)cat)->cat, set, num, msg);
148 		if (((Cc_t*)cat)->cvt != (iconv_t)(-1))
149 		{
150 			s = (char*)msg;
151 			n = strlen(s);
152 			iconv_write(((Cc_t*)cat)->cvt, ((Cc_t*)cat)->tmp, &s, &n, NiL);
153 			if (s = sfstruse(((Cc_t*)cat)->tmp))
154 				return s;
155 		}
156 		return (char*)msg;
157 	}
158 #endif
159 	return mcget((Mc_t*)cat, set, num, msg);
160 }
161 
162 int
163 _ast_catclose(_ast_nl_catd cat)
164 {
165 	if (cat == (_ast_nl_catd)(-1))
166 		return -1;
167 #if _lib_catopen
168 	if (!((Cc_t*)cat)->set)
169 	{
170 		if (((Cc_t*)cat)->cvt != (iconv_t)(-1))
171 			iconv_close(((Cc_t*)cat)->cvt);
172 		if (((Cc_t*)cat)->tmp)
173 			sfclose(((Cc_t*)cat)->tmp);
174 		return catclose(((Cc_t*)cat)->cat);
175 	}
176 #endif
177 	return mcclose((Mc_t*)cat);
178 }
179