| /* |
| * Localized printf/puts functions for CUPS. |
| * |
| * Copyright 2007-2014 by Apple Inc. |
| * Copyright 2002-2007 by Easy Software Products. |
| * |
| * These coded instructions, statements, and computer programs are the |
| * property of Apple Inc. and are protected by Federal copyright |
| * law. Distribution and use rights are outlined in the file "LICENSE.txt" |
| * which should have been included with this file. If this file is |
| * missing or damaged, see the license at "http://www.cups.org/". |
| * |
| * This file is subject to the Apple OS-Developed Software exception. |
| */ |
| |
| /* |
| * Include necessary headers... |
| */ |
| |
| #include "cups-private.h" |
| |
| |
| /* |
| * '_cupsLangPrintError()' - Print a message followed by a standard error. |
| */ |
| |
| void |
| _cupsLangPrintError(const char *prefix, /* I - Non-localized message prefix */ |
| const char *message)/* I - Message */ |
| { |
| ssize_t bytes; /* Number of bytes formatted */ |
| int last_errno; /* Last error */ |
| char buffer[2048], /* Message buffer */ |
| *bufptr, /* Pointer into buffer */ |
| output[8192]; /* Output buffer */ |
| _cups_globals_t *cg; /* Global data */ |
| |
| |
| /* |
| * Range check... |
| */ |
| |
| if (!message) |
| return; |
| |
| /* |
| * Save the errno value... |
| */ |
| |
| last_errno = errno; |
| |
| /* |
| * Get the message catalog... |
| */ |
| |
| cg = _cupsGlobals(); |
| |
| if (!cg->lang_default) |
| cg->lang_default = cupsLangDefault(); |
| |
| /* |
| * Format the message... |
| */ |
| |
| if (prefix) |
| { |
| snprintf(buffer, sizeof(buffer), "%s:", prefix); |
| bufptr = buffer + strlen(buffer); |
| } |
| else |
| bufptr = buffer; |
| |
| snprintf(bufptr, sizeof(buffer) - (size_t)(bufptr - buffer), |
| /* TRANSLATORS: Message is "subject: error" */ |
| _cupsLangString(cg->lang_default, _("%s: %s")), |
| _cupsLangString(cg->lang_default, message), strerror(last_errno)); |
| strlcat(buffer, "\n", sizeof(buffer)); |
| |
| /* |
| * Convert and write to stderr... |
| */ |
| |
| bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output), |
| cg->lang_default->encoding); |
| |
| if (bytes > 0) |
| fwrite(output, 1, (size_t)bytes, stderr); |
| } |
| |
| |
| /* |
| * '_cupsLangPrintFilter()' - Print a formatted filter message string to a file. |
| */ |
| |
| int /* O - Number of bytes written */ |
| _cupsLangPrintFilter( |
| FILE *fp, /* I - File to write to */ |
| const char *prefix, /* I - Non-localized message prefix */ |
| const char *message, /* I - Message string to use */ |
| ...) /* I - Additional arguments as needed */ |
| { |
| ssize_t bytes; /* Number of bytes formatted */ |
| char temp[2048], /* Temporary format buffer */ |
| buffer[2048], /* Message buffer */ |
| output[8192]; /* Output buffer */ |
| va_list ap; /* Pointer to additional arguments */ |
| _cups_globals_t *cg; /* Global data */ |
| |
| |
| /* |
| * Range check... |
| */ |
| |
| if (!fp || !message) |
| return (-1); |
| |
| cg = _cupsGlobals(); |
| |
| if (!cg->lang_default) |
| cg->lang_default = cupsLangDefault(); |
| |
| /* |
| * Format the string... |
| */ |
| |
| va_start(ap, message); |
| snprintf(temp, sizeof(temp), "%s: %s\n", prefix, |
| _cupsLangString(cg->lang_default, message)); |
| vsnprintf(buffer, sizeof(buffer), temp, ap); |
| va_end(ap); |
| |
| /* |
| * Transcode to the destination charset... |
| */ |
| |
| bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output), |
| cg->lang_default->encoding); |
| |
| /* |
| * Write the string and return the number of bytes written... |
| */ |
| |
| if (bytes > 0) |
| return ((int)fwrite(output, 1, (size_t)bytes, fp)); |
| else |
| return ((int)bytes); |
| } |
| |
| |
| /* |
| * '_cupsLangPrintf()' - Print a formatted message string to a file. |
| */ |
| |
| int /* O - Number of bytes written */ |
| _cupsLangPrintf(FILE *fp, /* I - File to write to */ |
| const char *message, /* I - Message string to use */ |
| ...) /* I - Additional arguments as needed */ |
| { |
| ssize_t bytes; /* Number of bytes formatted */ |
| char buffer[2048], /* Message buffer */ |
| output[8192]; /* Output buffer */ |
| va_list ap; /* Pointer to additional arguments */ |
| _cups_globals_t *cg; /* Global data */ |
| |
| |
| /* |
| * Range check... |
| */ |
| |
| if (!fp || !message) |
| return (-1); |
| |
| cg = _cupsGlobals(); |
| |
| if (!cg->lang_default) |
| cg->lang_default = cupsLangDefault(); |
| |
| /* |
| * Format the string... |
| */ |
| |
| va_start(ap, message); |
| vsnprintf(buffer, sizeof(buffer) - 1, |
| _cupsLangString(cg->lang_default, message), ap); |
| va_end(ap); |
| |
| strlcat(buffer, "\n", sizeof(buffer)); |
| |
| /* |
| * Transcode to the destination charset... |
| */ |
| |
| bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output), |
| cg->lang_default->encoding); |
| |
| /* |
| * Write the string and return the number of bytes written... |
| */ |
| |
| if (bytes > 0) |
| return ((int)fwrite(output, 1, (size_t)bytes, fp)); |
| else |
| return ((int)bytes); |
| } |
| |
| |
| /* |
| * '_cupsLangPuts()' - Print a static message string to a file. |
| */ |
| |
| int /* O - Number of bytes written */ |
| _cupsLangPuts(FILE *fp, /* I - File to write to */ |
| const char *message) /* I - Message string to use */ |
| { |
| ssize_t bytes; /* Number of bytes formatted */ |
| char output[8192]; /* Message buffer */ |
| _cups_globals_t *cg; /* Global data */ |
| |
| |
| /* |
| * Range check... |
| */ |
| |
| if (!fp || !message) |
| return (-1); |
| |
| cg = _cupsGlobals(); |
| |
| if (!cg->lang_default) |
| cg->lang_default = cupsLangDefault(); |
| |
| /* |
| * Transcode to the destination charset... |
| */ |
| |
| bytes = cupsUTF8ToCharset(output, |
| (cups_utf8_t *)_cupsLangString(cg->lang_default, |
| message), |
| sizeof(output) - 4, cg->lang_default->encoding); |
| bytes += cupsUTF8ToCharset(output + bytes, (cups_utf8_t *)"\n", (int)(sizeof(output) - (size_t)bytes), cg->lang_default->encoding); |
| |
| /* |
| * Write the string and return the number of bytes written... |
| */ |
| |
| if (bytes > 0) |
| return ((int)fwrite(output, 1, (size_t)bytes, fp)); |
| else |
| return ((int)bytes); |
| } |
| |
| |
| /* |
| * '_cupsSetLocale()' - Set the current locale and transcode the command-line. |
| */ |
| |
| void |
| _cupsSetLocale(char *argv[]) /* IO - Command-line arguments */ |
| { |
| int i; /* Looping var */ |
| char buffer[8192]; /* Command-line argument buffer */ |
| _cups_globals_t *cg; /* Global data */ |
| #ifdef LC_TIME |
| const char *lc_time; /* Current LC_TIME value */ |
| char new_lc_time[255], /* New LC_TIME value */ |
| *charset; /* Pointer to character set */ |
| #endif /* LC_TIME */ |
| |
| |
| /* |
| * Set the locale so that times, etc. are displayed properly. |
| * |
| * Unfortunately, while we need the localized time value, we *don't* |
| * want to use the localized charset for the time value, so we need |
| * to set LC_TIME to the locale name with .UTF-8 on the end (if |
| * the locale includes a character set specifier...) |
| */ |
| |
| setlocale(LC_ALL, ""); |
| |
| #ifdef LC_TIME |
| if ((lc_time = setlocale(LC_TIME, NULL)) == NULL) |
| lc_time = setlocale(LC_ALL, NULL); |
| |
| if (lc_time) |
| { |
| strlcpy(new_lc_time, lc_time, sizeof(new_lc_time)); |
| if ((charset = strchr(new_lc_time, '.')) == NULL) |
| charset = new_lc_time + strlen(new_lc_time); |
| |
| strlcpy(charset, ".UTF-8", sizeof(new_lc_time) - (size_t)(charset - new_lc_time)); |
| } |
| else |
| strlcpy(new_lc_time, "C", sizeof(new_lc_time)); |
| |
| setlocale(LC_TIME, new_lc_time); |
| #endif /* LC_TIME */ |
| |
| /* |
| * Initialize the default language info... |
| */ |
| |
| cg = _cupsGlobals(); |
| |
| if (!cg->lang_default) |
| cg->lang_default = cupsLangDefault(); |
| |
| /* |
| * Transcode the command-line arguments from the locale charset to |
| * UTF-8... |
| */ |
| |
| if (cg->lang_default->encoding != CUPS_US_ASCII && |
| cg->lang_default->encoding != CUPS_UTF8) |
| { |
| for (i = 1; argv[i]; i ++) |
| { |
| /* |
| * Try converting from the locale charset to UTF-8... |
| */ |
| |
| if (cupsCharsetToUTF8((cups_utf8_t *)buffer, argv[i], sizeof(buffer), |
| cg->lang_default->encoding) < 0) |
| continue; |
| |
| /* |
| * Save the new string if it differs from the original... |
| */ |
| |
| if (strcmp(buffer, argv[i])) |
| argv[i] = strdup(buffer); |
| } |
| } |
| } |