• 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  * 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