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