コード例 #1
0
ファイル: language.c プロジェクト: jianglei12138/cups
static cups_array_t *			/* O - Message catalog */
appleMessageLoad(const char *locale)	/* I - Locale ID */
{
  char			filename[1024],	/* Path to cups.strings file */
			applelang[256],	/* Apple language ID */
			baselang[3];	/* Base language */
  CFURLRef		url;		/* URL to cups.strings file */
  CFReadStreamRef	stream = NULL;	/* File stream */
  CFPropertyListRef	plist = NULL;	/* Localization file */
#ifdef DEBUG
  CFErrorRef		error = NULL;	/* Error when opening file */
#endif /* DEBUG */


  DEBUG_printf(("appleMessageLoad(locale=\"%s\")", locale));

 /*
  * Load the cups.strings file...
  */

  snprintf(filename, sizeof(filename),
           CUPS_BUNDLEDIR "/Resources/%s.lproj/cups.strings",
	   _cupsAppleLanguage(locale, applelang, sizeof(applelang)));

  if (access(filename, 0))
  {
   /*
    * <rdar://problem/22086642>
    *
    * Try with original locale string...
    */

    snprintf(filename, sizeof(filename), CUPS_BUNDLEDIR "/Resources/%s.lproj/cups.strings", locale);
  }

  DEBUG_printf(("1appleMessageLoad: filename=\"%s\"", filename));

  if (access(filename, 0))
  {
   /*
    * Try alternate lproj directory names...
    */

    if (!strncmp(locale, "en", 2))
      locale = "English";
    else if (!strncmp(locale, "nb", 2) || !strncmp(locale, "nl", 2))
      locale = "Dutch";
    else if (!strncmp(locale, "fr", 2))
      locale = "French";
    else if (!strncmp(locale, "de", 2))
      locale = "German";
    else if (!strncmp(locale, "it", 2))
      locale = "Italian";
    else if (!strncmp(locale, "ja", 2))
      locale = "Japanese";
    else if (!strncmp(locale, "es", 2))
      locale = "Spanish";
    else if (!strcmp(locale, "zh_HK"))
    {
     /*
      * <rdar://problem/22130168>
      *
      * Try zh_TW first, then zh...  Sigh...
      */

      if (!access(CUPS_BUNDLEDIR "/Resources/zh_TW.lproj/cups.strings", 0))
        locale = "zh_TW";
      else
        locale = "zh";
    }
    else if (strstr(locale, "_") != NULL || strstr(locale, "-") != NULL)
    {
     /*
      * Drop country code, just try language...
      */

      strlcpy(baselang, locale, sizeof(baselang));
      locale = baselang;
    }

    snprintf(filename, sizeof(filename),
	     CUPS_BUNDLEDIR "/Resources/%s.lproj/cups.strings", locale);
    DEBUG_printf(("1appleMessageLoad: alternate filename=\"%s\"", filename));
  }

  url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
                                                (UInt8 *)filename,
						(CFIndex)strlen(filename), false);
  if (url)
  {
    stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, url);
    if (stream)
    {
     /*
      * Read the property list containing the localization data.
      *
      * NOTE: This code currently generates a clang "potential leak"
      * warning, but the object is released in _cupsMessageFree().
      */

      CFReadStreamOpen(stream);

#ifdef DEBUG
      plist = CFPropertyListCreateWithStream(kCFAllocatorDefault, stream, 0,
                                             kCFPropertyListImmutable, NULL,
                                             &error);
      if (error)
      {
        CFStringRef	msg = CFErrorCopyDescription(error);
    					/* Error message */

        CFStringGetCString(msg, filename, sizeof(filename),
                           kCFStringEncodingUTF8);
        DEBUG_printf(("1appleMessageLoad: %s", filename));

	CFRelease(msg);
        CFRelease(error);
      }

#else
      plist = CFPropertyListCreateWithStream(kCFAllocatorDefault, stream, 0,
                                             kCFPropertyListImmutable, NULL,
                                             NULL);
#endif /* DEBUG */

      if (plist && CFGetTypeID(plist) != CFDictionaryGetTypeID())
      {
         CFRelease(plist);
         plist = NULL;
      }

      CFRelease(stream);
    }

    CFRelease(url);
  }

  DEBUG_printf(("1appleMessageLoad: url=%p, stream=%p, plist=%p", url, stream,
                plist));

 /*
  * Create and return an empty array to act as a cache for messages, passing the
  * plist as the user data.
  */

  return (_cupsMessageNew((void *)plist));
}
コード例 #2
0
ファイル: language.c プロジェクト: jianglei12138/cups
cups_array_t *				/* O - New message array */
_cupsMessageLoad(const char *filename,	/* I - Message catalog to load */
                 int        unquote)	/* I - Unescape \foo in strings? */
{
  cups_file_t		*fp;		/* Message file */
  cups_array_t		*a;		/* Message array */
  _cups_message_t	*m;		/* Current message */
  char			s[4096],	/* String buffer */
			*ptr,		/* Pointer into buffer */
			*temp;		/* New string */
  size_t		length,		/* Length of combined strings */
			ptrlen;		/* Length of string */


  DEBUG_printf(("4_cupsMessageLoad(filename=\"%s\")", filename));

 /*
  * Create an array to hold the messages...
  */

  if ((a = _cupsMessageNew(NULL)) == NULL)
  {
    DEBUG_puts("5_cupsMessageLoad: Unable to allocate array!");
    return (NULL);
  }

 /*
  * Open the message catalog file...
  */

  if ((fp = cupsFileOpen(filename, "r")) == NULL)
  {
    DEBUG_printf(("5_cupsMessageLoad: Unable to open file: %s",
                  strerror(errno)));
    return (a);
  }

 /*
  * Read messages from the catalog file until EOF...
  *
  * The format is the GNU gettext .po format, which is fairly simple:
  *
  *     msgid "some text"
  *     msgstr "localized text"
  *
  * The ID and localized text can span multiple lines using the form:
  *
  *     msgid ""
  *     "some long text"
  *     msgstr ""
  *     "localized text spanning "
  *     "multiple lines"
  */

  m = NULL;

  while (cupsFileGets(fp, s, sizeof(s)) != NULL)
  {
   /*
    * Skip blank and comment lines...
    */

    if (s[0] == '#' || !s[0])
      continue;

   /*
    * Strip the trailing quote...
    */

    if ((ptr = strrchr(s, '\"')) == NULL)
      continue;

    *ptr = '\0';

   /*
    * Find start of value...
    */

    if ((ptr = strchr(s, '\"')) == NULL)
      continue;

    ptr ++;

   /*
    * Unquote the text...
    */

    if (unquote)
      cups_unquote(ptr, ptr);

   /*
    * Create or add to a message...
    */

    if (!strncmp(s, "msgid", 5))
    {
     /*
      * Add previous message as needed...
      */

      if (m)
      {
        if (m->str && m->str[0])
        {
          cupsArrayAdd(a, m);
        }
        else
        {
         /*
          * Translation is empty, don't add it... (STR #4033)
          */

          free(m->id);
          if (m->str)
            free(m->str);
          free(m);
        }
      }

     /*
      * Create a new message with the given msgid string...
      */

      if ((m = (_cups_message_t *)calloc(1, sizeof(_cups_message_t))) == NULL)
      {
        cupsFileClose(fp);
	return (a);
      }

      if ((m->id = strdup(ptr)) == NULL)
      {
        free(m);
        cupsFileClose(fp);
	return (a);
      }
    }
    else if (s[0] == '\"' && m)
    {
     /*
      * Append to current string...
      */

      length = strlen(m->str ? m->str : m->id);
      ptrlen = strlen(ptr);

      if ((temp = realloc(m->str ? m->str : m->id, length + ptrlen + 1)) == NULL)
      {
        if (m->str)
	  free(m->str);
	free(m->id);
        free(m);

	cupsFileClose(fp);
	return (a);
      }

      if (m->str)
      {
       /*
        * Copy the new portion to the end of the msgstr string - safe
	* to use memcpy because the buffer is allocated to the correct
	* size...
	*/

        m->str = temp;

	memcpy(m->str + length, ptr, ptrlen + 1);
      }
      else
      {
       /*
        * Copy the new portion to the end of the msgid string - safe
	* to use memcpy because the buffer is allocated to the correct
	* size...
	*/

        m->id = temp;

	memcpy(m->id + length, ptr, ptrlen + 1);
      }
    }
    else if (!strncmp(s, "msgstr", 6) && m)
    {
     /*
      * Set the string...
      */

      if ((m->str = strdup(ptr)) == NULL)
      {
	free(m->id);
        free(m);

        cupsFileClose(fp);
	return (a);
      }
    }
  }

 /*
  * Add the last message string to the array as needed...
  */

  if (m)
  {
    if (m->str && m->str[0])
    {
      cupsArrayAdd(a, m);
    }
    else
    {
     /*
      * Translation is empty, don't add it... (STR #4033)
      */

      free(m->id);
      if (m->str)
	free(m->str);
      free(m);
    }
  }

 /*
  * Close the message catalog file and return the new array...
  */

  cupsFileClose(fp);

  DEBUG_printf(("5_cupsMessageLoad: Returning %d messages...",
                cupsArrayCount(a)));

  return (a);
}
コード例 #3
0
static void
cups_create_localizations(
    http_t       *http,			/* I - Connection to destination */
    cups_dinfo_t *dinfo)		/* I - Destination informations */
{
  http_t		*http2;		/* Connection for strings file */
  http_status_t		status;		/* Request status */
  ipp_attribute_t	*attr;		/* "printer-strings-uri" attribute */
  char			scheme[32],	/* URI scheme */
  			userpass[256],	/* Username/password info */
  			hostname[256],	/* Hostname */
  			resource[1024],	/* Resource */
  			http_hostname[256],
  					/* Hostname of connection */
			tempfile[1024];	/* Temporary filename */
  int			port;		/* Port number */
  http_encryption_t	encryption;	/* Encryption to use */
  cups_file_t		*temp;		/* Temporary file */


 /*
  * Create an empty message catalog...
  */

  dinfo->localizations = _cupsMessageNew(NULL);

 /*
  * See if there are any localizations...
  */

  if ((attr = ippFindAttribute(dinfo->attrs, "printer-strings-uri",
                               IPP_TAG_URI)) == NULL)
  {
   /*
    * Nope...
    */

    DEBUG_puts("4cups_create_localizations: No printer-strings-uri (uri) "
               "value.");
    return;				/* Nope */
  }

 /*
  * Pull apart the URI and determine whether we need to try a different
  * server...
  */

  if (httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text,
                      scheme, sizeof(scheme), userpass, sizeof(userpass),
                      hostname, sizeof(hostname), &port, resource,
                      sizeof(resource)) < HTTP_URI_OK)
  {
    DEBUG_printf(("4cups_create_localizations: Bad printer-strings-uri value "
                  "\"%s\".", attr->values[0].string.text));
    return;
  }

  httpGetHostname(http, http_hostname, sizeof(http_hostname));

  if (!_cups_strcasecmp(http_hostname, hostname) &&
      port == _httpAddrPort(http->hostaddr))
  {
   /*
    * Use the same connection...
    */

    http2 = http;
  }
  else
  {
   /*
    * Connect to the alternate host...
    */

    if (!strcmp(scheme, "https"))
      encryption = HTTP_ENCRYPT_ALWAYS;
    else
      encryption = HTTP_ENCRYPT_IF_REQUESTED;

    if ((http2 = httpConnectEncrypt(hostname, port, encryption)) == NULL)
    {
      DEBUG_printf(("4cups_create_localizations: Unable to connect to "
                    "%s:%d: %s", hostname, port, cupsLastErrorString()));
      return;
    }
  }

 /*
  * Get a temporary file...
  */

  if ((temp = cupsTempFile2(tempfile, sizeof(tempfile))) == NULL)
  {
    DEBUG_printf(("4cups_create_localizations: Unable to create temporary "
                  "file: %s", cupsLastErrorString()));
    if (http2 != http)
      httpClose(http2);
    return;
  }

  status = cupsGetFd(http2, resource, cupsFileNumber(temp));

  DEBUG_printf(("4cups_create_localizations: GET %s = %s", resource,
                httpStatus(status)));

  if (status == HTTP_OK)
  {
   /*
    * Got the file, read it...
    */

    char		buffer[8192],	/* Message buffer */
    			*id,		/* ID string */
    			*str;		/* Translated message */
    _cups_message_t	*m;		/* Current message */

    lseek(cupsFileNumber(temp), 0, SEEK_SET);

    while (cups_read_strings(temp, buffer, sizeof(buffer), &id, &str))
    {
      if ((m = malloc(sizeof(_cups_message_t))) == NULL)
        break;

      m->id  = strdup(id);
      m->str = strdup(str);

      if (m->id && m->str)
        cupsArrayAdd(dinfo->localizations, m);
      else
      {
        if (m->id)
          free(m->id);

        if (m->str)
          free(m->str);

        free(m);
        break;
      }
    }
  }

  DEBUG_printf(("4cups_create_localizations: %d messages loaded.",
                cupsArrayCount(dinfo->localizations)));

 /*
  * Cleanup...
  */

  unlink(tempfile);
  cupsFileClose(temp);

  if (http2 != http)
    httpClose(http2);
}