4 * Destination localization support for CUPS.
6 * Copyright 2012-2013 by Apple Inc.
8 * These coded instructions, statements, and computer programs are the
9 * property of Apple Inc. and are protected by Federal copyright
10 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
11 * which should have been included with this file. If this file is
12 * file is missing or damaged, see the license at "http://www.cups.org/".
14 * This file is subject to the Apple OS-Developed Software exception.
18 * cupsLocalizeDestOption() - Get the localized string for a destination
20 * cupsLocalizeDestValue() - Get the localized string for a destination
22 * cups_create_localizations() - Create the localizations array for a
24 * cups_read_strings() - Read a pair of strings from a .strings file.
25 * cups_scan_strings() - Scan a quoted string.
29 * Include necessary headers...
32 #include "cups-private.h"
39 static void cups_create_localizations(http_t
*http
, cups_dinfo_t
*dinfo
);
40 static int cups_read_strings(cups_file_t
*fp
, char *buffer
, size_t bufsize
,
41 char **id
, char **str
);
42 static char *cups_scan_strings(char *buffer
);
46 * 'cupsLocalizeDestOption()' - Get the localized string for a destination
49 * The returned string is stored in the destination information and will become
50 * invalid if the destination information is deleted.
52 * @since CUPS 1.6/OS X 10.8@
55 const char * /* O - Localized string */
56 cupsLocalizeDestOption(
57 http_t
*http
, /* I - Connection to destination */
58 cups_dest_t
*dest
, /* I - Destination */
59 cups_dinfo_t
*dinfo
, /* I - Destination information */
60 const char *option
) /* I - Option to localize */
62 _cups_message_t key
, /* Search key */
63 *match
; /* Matching entry */
66 if (!http
|| !dest
|| !dinfo
)
69 if (!dinfo
->localizations
)
70 cups_create_localizations(http
, dinfo
);
72 if (cupsArrayCount(dinfo
->localizations
) == 0)
75 key
.id
= (char *)option
;
76 if ((match
= (_cups_message_t
*)cupsArrayFind(dinfo
->localizations
,
85 * 'cupsLocalizeDestValue()' - Get the localized string for a destination
88 * The returned string is stored in the destination information and will become
89 * invalid if the destination information is deleted.
91 * @since CUPS 1.6/OS X 10.8@
94 const char * /* O - Localized string */
95 cupsLocalizeDestValue(
96 http_t
*http
, /* I - Connection to destination */
97 cups_dest_t
*dest
, /* I - Destination */
98 cups_dinfo_t
*dinfo
, /* I - Destination information */
99 const char *option
, /* I - Option to localize */
100 const char *value
) /* I - Value to localize */
102 _cups_message_t key
, /* Search key */
103 *match
; /* Matching entry */
104 char pair
[256]; /* option.value pair */
107 if (!http
|| !dest
|| !dinfo
)
110 if (!dinfo
->localizations
)
111 cups_create_localizations(http
, dinfo
);
113 if (cupsArrayCount(dinfo
->localizations
) == 0)
116 snprintf(pair
, sizeof(pair
), "%s.%s", option
, value
);
118 if ((match
= (_cups_message_t
*)cupsArrayFind(dinfo
->localizations
,
127 * 'cups_create_localizations()' - Create the localizations array for a
132 cups_create_localizations(
133 http_t
*http
, /* I - Connection to destination */
134 cups_dinfo_t
*dinfo
) /* I - Destination informations */
136 http_t
*http2
; /* Connection for strings file */
137 http_status_t status
; /* Request status */
138 ipp_attribute_t
*attr
; /* "printer-strings-uri" attribute */
139 char scheme
[32], /* URI scheme */
140 userpass
[256], /* Username/password info */
141 hostname
[256], /* Hostname */
142 resource
[1024], /* Resource */
144 /* Hostname of connection */
145 tempfile
[1024]; /* Temporary filename */
146 int port
; /* Port number */
147 http_encryption_t encryption
; /* Encryption to use */
148 cups_file_t
*temp
; /* Temporary file */
152 * Create an empty message catalog...
155 dinfo
->localizations
= _cupsMessageNew(NULL
);
158 * See if there are any localizations...
161 if ((attr
= ippFindAttribute(dinfo
->attrs
, "printer-strings-uri",
162 IPP_TAG_URI
)) == NULL
)
168 DEBUG_puts("4cups_create_localizations: No printer-strings-uri (uri) "
174 * Pull apart the URI and determine whether we need to try a different
178 if (httpSeparateURI(HTTP_URI_CODING_ALL
, attr
->values
[0].string
.text
,
179 scheme
, sizeof(scheme
), userpass
, sizeof(userpass
),
180 hostname
, sizeof(hostname
), &port
, resource
,
181 sizeof(resource
)) < HTTP_URI_STATUS_OK
)
183 DEBUG_printf(("4cups_create_localizations: Bad printer-strings-uri value "
184 "\"%s\".", attr
->values
[0].string
.text
));
188 httpGetHostname(http
, http_hostname
, sizeof(http_hostname
));
190 if (!_cups_strcasecmp(http_hostname
, hostname
) &&
191 port
== httpAddrPort(http
->hostaddr
))
194 * Use the same connection...
202 * Connect to the alternate host...
205 if (!strcmp(scheme
, "https"))
206 encryption
= HTTP_ENCRYPTION_ALWAYS
;
208 encryption
= HTTP_ENCRYPTION_IF_REQUESTED
;
210 if ((http2
= httpConnect2(hostname
, port
, NULL
, AF_UNSPEC
, encryption
, 1,
211 30000, NULL
)) == NULL
)
213 DEBUG_printf(("4cups_create_localizations: Unable to connect to "
214 "%s:%d: %s", hostname
, port
, cupsLastErrorString()));
220 * Get a temporary file...
223 if ((temp
= cupsTempFile2(tempfile
, sizeof(tempfile
))) == NULL
)
225 DEBUG_printf(("4cups_create_localizations: Unable to create temporary "
226 "file: %s", cupsLastErrorString()));
232 status
= cupsGetFd(http2
, resource
, cupsFileNumber(temp
));
234 DEBUG_printf(("4cups_create_localizations: GET %s = %s", resource
,
235 httpStatus(status
)));
237 if (status
== HTTP_STATUS_OK
)
240 * Got the file, read it...
243 char buffer
[8192], /* Message buffer */
245 *str
; /* Translated message */
246 _cups_message_t
*m
; /* Current message */
248 lseek(cupsFileNumber(temp
), 0, SEEK_SET
);
250 while (cups_read_strings(temp
, buffer
, sizeof(buffer
), &id
, &str
))
252 if ((m
= malloc(sizeof(_cups_message_t
))) == NULL
)
256 m
->str
= strdup(str
);
259 cupsArrayAdd(dinfo
->localizations
, m
);
274 DEBUG_printf(("4cups_create_localizations: %d messages loaded.",
275 cupsArrayCount(dinfo
->localizations
)));
290 * 'cups_read_strings()' - Read a pair of strings from a .strings file.
293 static int /* O - 1 on success, 0 on failure */
294 cups_read_strings(cups_file_t
*strings
, /* I - .strings file */
295 char *buffer
, /* I - Line buffer */
296 size_t bufsize
, /* I - Size of line buffer */
297 char **id
, /* O - Pointer to ID string */
298 char **str
) /* O - Pointer to translation string */
300 char *bufptr
; /* Pointer into buffer */
303 while (cupsFileGets(strings
, buffer
, bufsize
))
305 if (buffer
[0] != '\"')
309 bufptr
= cups_scan_strings(buffer
);
316 while (*bufptr
&& *bufptr
!= '\"')
323 bufptr
= cups_scan_strings(bufptr
);
338 * 'cups_scan_strings()' - Scan a quoted string.
341 static char * /* O - End of string */
342 cups_scan_strings(char *buffer
) /* I - Start of string */
344 char *bufptr
; /* Pointer into string */
347 for (bufptr
= buffer
+ 1; *bufptr
&& *bufptr
!= '\"'; bufptr
++)
351 if (bufptr
[1] >= '0' && bufptr
[1] <= '3' &&
352 bufptr
[2] >= '0' && bufptr
[2] <= '7' &&
353 bufptr
[3] >= '0' && bufptr
[3] <= '7')
356 * Decode \nnn octal escape...
359 *bufptr
= ((((bufptr
[1] - '0') << 3) | (bufptr
[2] - '0')) << 3) |
361 _cups_strcpy(bufptr
+ 1, bufptr
+ 4);
366 * Decode \C escape...
369 _cups_strcpy(bufptr
, bufptr
+ 1);
372 else if (*bufptr
== 'r')
374 else if (*bufptr
== 't')