1/*
2 * "$Id: langprintf.c 11560 2014-02-06 20:10:19Z msweet $"
3 *
4 * Localized printf/puts functions for CUPS.
5 *
6 * Copyright 2007-2014 by Apple Inc.
7 * Copyright 2002-2007 by Easy Software Products.
8 *
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file.  If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
14 *
15 * This file is subject to the Apple OS-Developed Software exception.
16 */
17
18/*
19 * Include necessary headers...
20 */
21
22#include "cups-private.h"
23
24
25/*
26 * '_cupsLangPrintError()' - Print a message followed by a standard error.
27 */
28
29void
30_cupsLangPrintError(const char *prefix,	/* I - Non-localized message prefix */
31                    const char *message)/* I - Message */
32{
33  ssize_t	bytes;			/* Number of bytes formatted */
34  int		last_errno;		/* Last error */
35  char		buffer[2048],		/* Message buffer */
36		*bufptr,		/* Pointer into buffer */
37		output[8192];		/* Output buffer */
38  _cups_globals_t *cg;			/* Global data */
39
40
41 /*
42  * Range check...
43  */
44
45  if (!message)
46    return;
47
48 /*
49  * Save the errno value...
50  */
51
52  last_errno = errno;
53
54 /*
55  * Get the message catalog...
56  */
57
58  cg = _cupsGlobals();
59
60  if (!cg->lang_default)
61    cg->lang_default = cupsLangDefault();
62
63 /*
64  * Format the message...
65  */
66
67  if (prefix)
68  {
69    snprintf(buffer, sizeof(buffer), "%s:", prefix);
70    bufptr = buffer + strlen(buffer);
71  }
72  else
73    bufptr = buffer;
74
75  snprintf(bufptr, sizeof(buffer) - (size_t)(bufptr - buffer),
76	   /* TRANSLATORS: Message is "subject: error" */
77	   _cupsLangString(cg->lang_default, _("%s: %s")),
78	   _cupsLangString(cg->lang_default, message), strerror(last_errno));
79  strlcat(buffer, "\n", sizeof(buffer));
80
81 /*
82  * Convert and write to stderr...
83  */
84
85  bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output),
86                            cg->lang_default->encoding);
87
88  if (bytes > 0)
89    fwrite(output, 1, (size_t)bytes, stderr);
90}
91
92
93/*
94 * '_cupsLangPrintFilter()' - Print a formatted filter message string to a file.
95 */
96
97int					/* O - Number of bytes written */
98_cupsLangPrintFilter(
99    FILE       *fp,			/* I - File to write to */
100    const char *prefix,			/* I - Non-localized message prefix */
101    const char *message,		/* I - Message string to use */
102    ...)				/* I - Additional arguments as needed */
103{
104  ssize_t	bytes;			/* Number of bytes formatted */
105  char		temp[2048],		/* Temporary format buffer */
106		buffer[2048],		/* Message buffer */
107		output[8192];		/* Output buffer */
108  va_list 	ap;			/* Pointer to additional arguments */
109  _cups_globals_t *cg;			/* Global data */
110
111
112 /*
113  * Range check...
114  */
115
116  if (!fp || !message)
117    return (-1);
118
119  cg = _cupsGlobals();
120
121  if (!cg->lang_default)
122    cg->lang_default = cupsLangDefault();
123
124 /*
125  * Format the string...
126  */
127
128  va_start(ap, message);
129  snprintf(temp, sizeof(temp), "%s: %s\n", prefix,
130	   _cupsLangString(cg->lang_default, message));
131  vsnprintf(buffer, sizeof(buffer), temp, ap);
132  va_end(ap);
133
134 /*
135  * Transcode to the destination charset...
136  */
137
138  bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output),
139                            cg->lang_default->encoding);
140
141 /*
142  * Write the string and return the number of bytes written...
143  */
144
145  if (bytes > 0)
146    return ((int)fwrite(output, 1, (size_t)bytes, fp));
147  else
148    return ((int)bytes);
149}
150
151
152/*
153 * '_cupsLangPrintf()' - Print a formatted message string to a file.
154 */
155
156int					/* O - Number of bytes written */
157_cupsLangPrintf(FILE       *fp,		/* I - File to write to */
158		const char *message,	/* I - Message string to use */
159	        ...)			/* I - Additional arguments as needed */
160{
161  ssize_t	bytes;			/* Number of bytes formatted */
162  char		buffer[2048],		/* Message buffer */
163		output[8192];		/* Output buffer */
164  va_list 	ap;			/* Pointer to additional arguments */
165  _cups_globals_t *cg;			/* Global data */
166
167
168 /*
169  * Range check...
170  */
171
172  if (!fp || !message)
173    return (-1);
174
175  cg = _cupsGlobals();
176
177  if (!cg->lang_default)
178    cg->lang_default = cupsLangDefault();
179
180 /*
181  * Format the string...
182  */
183
184  va_start(ap, message);
185  vsnprintf(buffer, sizeof(buffer) - 1,
186	    _cupsLangString(cg->lang_default, message), ap);
187  va_end(ap);
188
189  strlcat(buffer, "\n", sizeof(buffer));
190
191 /*
192  * Transcode to the destination charset...
193  */
194
195  bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output),
196                            cg->lang_default->encoding);
197
198 /*
199  * Write the string and return the number of bytes written...
200  */
201
202  if (bytes > 0)
203    return ((int)fwrite(output, 1, (size_t)bytes, fp));
204  else
205    return ((int)bytes);
206}
207
208
209/*
210 * '_cupsLangPuts()' - Print a static message string to a file.
211 */
212
213int					/* O - Number of bytes written */
214_cupsLangPuts(FILE       *fp,		/* I - File to write to */
215              const char *message)	/* I - Message string to use */
216{
217  ssize_t	bytes;			/* Number of bytes formatted */
218  char		output[8192];		/* Message buffer */
219  _cups_globals_t *cg;			/* Global data */
220
221
222 /*
223  * Range check...
224  */
225
226  if (!fp || !message)
227    return (-1);
228
229  cg = _cupsGlobals();
230
231  if (!cg->lang_default)
232    cg->lang_default = cupsLangDefault();
233
234 /*
235  * Transcode to the destination charset...
236  */
237
238  bytes = cupsUTF8ToCharset(output,
239			    (cups_utf8_t *)_cupsLangString(cg->lang_default,
240							   message),
241			    sizeof(output) - 4, cg->lang_default->encoding);
242  bytes += cupsUTF8ToCharset(output + bytes, (cups_utf8_t *)"\n", (int)(sizeof(output) - (size_t)bytes), cg->lang_default->encoding);
243
244 /*
245  * Write the string and return the number of bytes written...
246  */
247
248  if (bytes > 0)
249    return ((int)fwrite(output, 1, (size_t)bytes, fp));
250  else
251    return ((int)bytes);
252}
253
254
255/*
256 * '_cupsSetLocale()' - Set the current locale and transcode the command-line.
257 */
258
259void
260_cupsSetLocale(char *argv[])		/* IO - Command-line arguments */
261{
262  int		i;			/* Looping var */
263  char		buffer[8192];		/* Command-line argument buffer */
264  _cups_globals_t *cg;			/* Global data */
265#ifdef LC_TIME
266  const char	*lc_time;		/* Current LC_TIME value */
267  char		new_lc_time[255],	/* New LC_TIME value */
268		*charset;		/* Pointer to character set */
269#endif /* LC_TIME */
270
271
272 /*
273  * Set the locale so that times, etc. are displayed properly.
274  *
275  * Unfortunately, while we need the localized time value, we *don't*
276  * want to use the localized charset for the time value, so we need
277  * to set LC_TIME to the locale name with .UTF-8 on the end (if
278  * the locale includes a character set specifier...)
279  */
280
281  setlocale(LC_ALL, "");
282
283#ifdef LC_TIME
284  if ((lc_time = setlocale(LC_TIME, NULL)) == NULL)
285    lc_time = setlocale(LC_ALL, NULL);
286
287  if (lc_time)
288  {
289    strlcpy(new_lc_time, lc_time, sizeof(new_lc_time));
290    if ((charset = strchr(new_lc_time, '.')) == NULL)
291      charset = new_lc_time + strlen(new_lc_time);
292
293    strlcpy(charset, ".UTF-8", sizeof(new_lc_time) - (size_t)(charset - new_lc_time));
294  }
295  else
296    strlcpy(new_lc_time, "C", sizeof(new_lc_time));
297
298  setlocale(LC_TIME, new_lc_time);
299#endif /* LC_TIME */
300
301 /*
302  * Initialize the default language info...
303  */
304
305  cg = _cupsGlobals();
306
307  if (!cg->lang_default)
308    cg->lang_default = cupsLangDefault();
309
310 /*
311  * Transcode the command-line arguments from the locale charset to
312  * UTF-8...
313  */
314
315  if (cg->lang_default->encoding != CUPS_US_ASCII &&
316      cg->lang_default->encoding != CUPS_UTF8)
317  {
318    for (i = 1; argv[i]; i ++)
319    {
320     /*
321      * Try converting from the locale charset to UTF-8...
322      */
323
324      if (cupsCharsetToUTF8((cups_utf8_t *)buffer, argv[i], sizeof(buffer),
325                            cg->lang_default->encoding) < 0)
326        continue;
327
328     /*
329      * Save the new string if it differs from the original...
330      */
331
332      if (strcmp(buffer, argv[i]))
333        argv[i] = strdup(buffer);
334    }
335  }
336}
337
338
339/*
340 * End of "$Id: langprintf.c 11560 2014-02-06 20:10:19Z msweet $".
341 */
342