Home | History | Annotate | Download | only in cups
      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
     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 */
     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 */
    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 */
    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
    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