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