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