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*                  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#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
54typedef 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
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
84sfprintf(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
89sfprintf(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					return (_ast_nl_catd)(-1);
120				}
121			}
122			else
123				cc->cvt = (iconv_t)(-1);
124#if DEBUG_trace
125sfprintf(sfstderr, "AHA#%d:%s %s %s native %p\n", __LINE__, __FILE__, s, name, cc->cat);
126#endif
127			return (_ast_nl_catd)cc;
128		}
129	}
130#endif
131
132	/*
133	 * loser
134	 */
135
136	return (_ast_nl_catd)(-1);
137}
138
139char*
140_ast_catgets(_ast_nl_catd cat, int set, int num, const char* msg)
141{
142	if (cat == (_ast_nl_catd)(-1))
143		return (char*)msg;
144#if _lib_catopen
145	if (!((Cc_t*)cat)->set)
146	{
147		char*	s;
148		size_t	n;
149
150		msg = (char*)catgets(((Cc_t*)cat)->cat, set, num, msg);
151		if (((Cc_t*)cat)->cvt != (iconv_t)(-1))
152		{
153			s = (char*)msg;
154			n = strlen(s);
155			iconv_write(((Cc_t*)cat)->cvt, ((Cc_t*)cat)->tmp, &s, &n, NiL);
156			if (s = sfstruse(((Cc_t*)cat)->tmp))
157				return s;
158		}
159		return (char*)msg;
160	}
161#endif
162	return mcget((Mc_t*)cat, set, num, msg);
163}
164
165int
166_ast_catclose(_ast_nl_catd cat)
167{
168	if (cat == (_ast_nl_catd)(-1))
169		return -1;
170#if _lib_catopen
171	if (!((Cc_t*)cat)->set)
172	{
173		if (((Cc_t*)cat)->cvt != (iconv_t)(-1))
174			iconv_close(((Cc_t*)cat)->cvt);
175		if (((Cc_t*)cat)->tmp)
176			sfclose(((Cc_t*)cat)->tmp);
177		return catclose(((Cc_t*)cat)->cat);
178	}
179#endif
180	return mcclose((Mc_t*)cat);
181}
182