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