From: Michael R Sweet Date: Tue, 19 Dec 2017 19:53:00 +0000 (-0500) Subject: Generate strings files for localizing PPD options (Issue #5194) X-Git-Tag: v2.3b1~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2fa1ba3cc0e02799b739ef0e06efc940a8c5a33e;p=thirdparty%2Fcups.git Generate strings files for localizing PPD options (Issue #5194) cups/language-private.h: - New _cupsMessageAdd and _cupsMessageSave private APIs. cups/language.c: - Implement new _cupsMessageAdd and _cupsMessageSave private APIs. cups/ppd-cache.c: - Generate strings array when loading cache from PPD. - Remove strings_uri (just pulling strings from PPD now). cups/ppd-private.h: - Remove strings_uri and add strings array to cache. scheduler/client.c: - Add support for /strings/NAME.strings - Cleanup implementation of GET/HEAD/POST to files. scheduler/ipp.c: - Return local strings file URI. - Clean up copy_printer_attrs implementation. scheduler/printers.c: - Save strings array to cache file, drop support for strings_uri. scheduler/printers.h: - Add strings filename to cupsd_printer_t structure. --- diff --git a/CHANGES.md b/CHANGES.md index cb56a4a089..376334fb11 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,4 @@ -CHANGES - 2.3b1 - 2017-12-18 +CHANGES - 2.3b1 - 2017-12-19 ============================ @@ -56,3 +56,5 @@ Changes in CUPS v2.3b1 - The scheduler now substitutes default values for invalid job attributes when running in "relaxed conformance" mode (Issue #5186) - The scheduler did not work with older versions of uClibc (Issue #5188) +- The scheduler now generates a strings file for localizing PPD options + (Issue #5194) diff --git a/cups/language-private.h b/cups/language-private.h index 1f69c4edb1..fb42a6b951 100644 --- a/cups/language-private.h +++ b/cups/language-private.h @@ -76,6 +76,7 @@ extern void _cupsMessageFree(cups_array_t *a); extern cups_array_t *_cupsMessageLoad(const char *filename, int flags); extern const char *_cupsMessageLookup(cups_array_t *a, const char *m); extern cups_array_t *_cupsMessageNew(void *context); +extern int _cupsMessageSave(const char *filename, int flags, cups_array_t *a); extern void _cupsSetLocale(char *argv[]); diff --git a/cups/language.c b/cups/language.c index 1f2a125be8..78d7d1573d 100644 --- a/cups/language.c +++ b/cups/language.c @@ -147,6 +147,7 @@ static cups_lang_t *cups_cache_lookup(const char *name, cups_encoding_t encoding static int cups_message_compare(_cups_message_t *m1, _cups_message_t *m2); static void cups_message_free(_cups_message_t *m); static void cups_message_load(cups_lang_t *lang); +static void cups_message_puts(cups_file_t *fp, const char *s); static int cups_read_strings(cups_file_t *fp, int flags, cups_array_t *a); static void cups_unquote(char *d, const char *s); @@ -1225,6 +1226,57 @@ _cupsMessageNew(void *context) /* I - User data */ } +/* + * '_cupsMessageSave()' - Save a message catalog array. + */ + +int /* O - 0 on success, -1 on failure */ +_cupsMessageSave(const char *filename,/* I - Output filename */ + int flags, /* I - Format flags */ + cups_array_t *a) /* I - Message array */ +{ + cups_file_t *fp; /* Output file */ + _cups_message_t *m; /* Current message */ + + + /* + * Output message catalog file... + */ + + if ((fp = cupsFileOpen(filename, "w")) == NULL) + return (-1); + + /* + * Write each message... + */ + + if (flags & _CUPS_MESSAGE_STRINGS) + { + for (m = (_cups_message_t *)cupsArrayFirst(a); m; m = (_cups_message_t *)cupsArrayNext(a)) + { + cupsFilePuts(fp, "\""); + cups_message_puts(fp, m->msg); + cupsFilePuts(fp, "\" = \""); + cups_message_puts(fp, m->str); + cupsFilePuts(fp, "\";\n"); + } + } + else + { + for (m = (_cups_message_t *)cupsArrayFirst(a); m; m = (_cups_message_t *)cupsArrayNext(a)) + { + cupsFilePuts(fp, "msgid \""); + cups_message_puts(fp, m->msg); + cupsFilePuts(fp, "\"\nmsgstr \""); + cups_message_puts(fp, m->str); + cupsFilePuts(fp, "\"\n"); + } + } + + return (cupsFileClose(fp)); +} + + #ifdef __APPLE__ /* * 'appleLangDefault()' - Get the default locale string. @@ -1669,6 +1721,44 @@ cups_message_load(cups_lang_t *lang) /* I - Language */ } +/* + * 'cups_message_puts()' - Write a message string with quoting. + */ + +static void +cups_message_puts(cups_file_t *fp, /* I - File to write to */ + const char *s) /* I - String to write */ +{ + const char *start, /* Start of substring */ + *ptr; /* Pointer into string */ + + + for (start = s, ptr = s; *ptr; ptr ++) + { + if (strchr("\\\"\n\t", *ptr)) + { + if (ptr > start) + { + cupsFileWrite(fp, start, (size_t)(ptr - start)); + start = ptr + 1; + } + + if (*ptr == '\\') + cupsFileWrite(fp, "\\\\", 2); + else if (*ptr == '\"') + cupsFileWrite(fp, "\\\"", 2); + else if (*ptr == '\n') + cupsFileWrite(fp, "\\n", 2); + else /* if (*ptr == '\t') */ + cupsFileWrite(fp, "\\t", 2); + } + } + + if (ptr > start) + cupsFileWrite(fp, start, (size_t)(ptr - start)); +} + + /* * 'cups_read_strings()' - Read a pair of strings from a .strings file. */ diff --git a/cups/ppd-cache.c b/cups/ppd-cache.c index 23e34be4b8..177db7b082 100644 --- a/cups/ppd-cache.c +++ b/cups/ppd-cache.c @@ -28,6 +28,7 @@ static int cups_get_url(http_t **http, const char *url, char *name, size_t namesize); static void pwg_add_finishing(cups_array_t *finishings, ipp_finishings_t template, const char *name, const char *value); +static void pwg_add_message(cups_array_t *a, const char *msg, const char *str); static int pwg_compare_finishings(_pwg_finishings_t *a, _pwg_finishings_t *b); static int pwg_compare_sizes(cups_size_t *a, cups_size_t *b); static cups_size_t *pwg_copy_size(cups_size_t *size); @@ -914,8 +915,6 @@ _ppdCacheCreateWithFile( else pc->mandatory = _cupsArrayNewStrings(value, ' '); } - else if (!_cups_strcasecmp(line, "StringsURI")) - pc->strings_uri = _cupsStrAlloc(value); else if (!_cups_strcasecmp(line, "SupportFile")) { if (!pc->support_files) @@ -1028,6 +1027,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ pwg_size_t *new_size; /* New size to add, if any */ const char *filter; /* Current filter */ _pwg_finishings_t *finishings; /* Current finishings value */ + char msg_id[256]; /* Message identifier */ DEBUG_printf(("_ppdCacheCreateWithPPD(ppd=%p)", ppd)); @@ -1049,6 +1049,8 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ goto create_error; } + pc->strings = _cupsMessageNew(NULL); + /* * Copy and convert size data... */ @@ -1285,6 +1287,13 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ map->pwg = _cupsStrAlloc(pwg_name); map->ppd = _cupsStrAlloc(choice->choice); + + /* + * Add localized text for PWG keyword to message catalog... + */ + + snprintf(msg_id, sizeof(msg_id), "media-source.%s", pwg_name); + pwg_add_message(pc->strings, msg_id, choice->text); } } @@ -1349,6 +1358,13 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ map->pwg = _cupsStrAlloc(pwg_name); map->ppd = _cupsStrAlloc(choice->choice); + + /* + * Add localized text for PWG keyword to message catalog... + */ + + snprintf(msg_id, sizeof(msg_id), "media-type.%s", pwg_name); + pwg_add_message(pc->strings, msg_id, choice->text); } } @@ -1376,6 +1392,13 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ map->pwg = _cupsStrAlloc(pwg_keyword); map->ppd = _cupsStrAlloc(choice->choice); + + /* + * Add localized text for PWG keyword to message catalog... + */ + + snprintf(msg_id, sizeof(msg_id), "output-bin.%s", pwg_name); + pwg_add_message(pc->strings, msg_id, choice->text); } } @@ -1393,6 +1416,17 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ do { + /* + * Add localized text for PWG keyword to message catalog... + */ + + snprintf(msg_id, sizeof(msg_id), "preset-name.%s", ppd_attr->spec); + pwg_add_message(pc->strings, msg_id, ppd_attr->text); + + /* + * Get the options for this preset... + */ + num_options = _ppdParseOptions(ppd_attr->value, 0, &options, _PPD_PARSE_ALL); @@ -1836,7 +1870,16 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ pc->templates = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0, (cups_acopy_func_t)_cupsStrAlloc, (cups_afree_func_t)_cupsStrFree); for (choice = ppd_option->choices, i = ppd_option->num_choices; i > 0; choice ++, i --) + { cupsArrayAdd(pc->templates, (void *)choice->choice); + + /* + * Add localized text for PWG keyword to message catalog... + */ + + snprintf(msg_id, sizeof(msg_id), "finishing-template.%s", choice->choice); + pwg_add_message(pc->strings, msg_id, choice->text); + } } /* @@ -1870,13 +1913,6 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ if ((ppd_attr = ppdFindAttr(ppd, "cupsMandatory", NULL)) != NULL) pc->mandatory = _cupsArrayNewStrings(ppd_attr->value, ' '); - /* - * Strings (remote) file... - */ - - if ((ppd_attr = ppdFindAttr(ppd, "cupsStringsURI", NULL)) != NULL) - pc->strings_uri = _cupsStrAlloc(ppd_attr->value); - /* * Support files... */ @@ -2000,6 +2036,8 @@ _ppdCacheDestroy(_ppd_cache_t *pc) /* I - PPD cache and mapping data */ cupsArrayDelete(pc->support_files); + cupsArrayDelete(pc->strings); + free(pc); } @@ -2947,13 +2985,6 @@ _ppdCacheWriteFile( value = (char *)cupsArrayNext(pc->mandatory)) cupsFilePutConf(fp, "Mandatory", value); - /* - * (Remote) strings file... - */ - - if (pc->strings_uri) - cupsFilePutConf(fp, "StringsURI", pc->strings_uri); - /* * Support files... */ @@ -4613,6 +4644,27 @@ pwg_add_finishing( } +/* + * 'pwg_add_message()' - Add a message to the PPD cached strings. + */ + +static void +pwg_add_message(cups_array_t *a, /* I - Message catalog */ + const char *msg, /* I - Message identifier */ + const char *str) /* I - Localized string */ +{ + _cups_message_t *m; /* New message */ + + + if ((m = calloc(1, sizeof(_cups_message_t))) != NULL) + { + m->msg = strdup(msg); + m->str = strdup(str); + cupsArrayAdd(a, m); + } +} + + /* * 'pwg_compare_finishings()' - Compare two finishings values. */ diff --git a/cups/ppd-private.h b/cups/ppd-private.h index 6cd1683277..21e519ebd1 100644 --- a/cups/ppd-private.h +++ b/cups/ppd-private.h @@ -146,7 +146,7 @@ struct _ppd_cache_s /**** PPD cache and PWG conversion data ****/ char *password; /* cupsJobPassword value */ cups_array_t *mandatory; /* cupsMandatory value */ char *charge_info_uri; /* cupsChargeInfoURI value */ - char *strings_uri; /* cupsStringsURI value */ + cups_array_t *strings; /* Localization strings */ cups_array_t *support_files; /* Support files - ICC profiles, etc. */ }; diff --git a/scheduler/client.c b/scheduler/client.c index 775265a894..f388499dcf 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -556,7 +556,6 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ char buf[1024]; /* Buffer for real filename */ struct stat filestats; /* File information */ mime_type_t *type; /* MIME type of file */ - cupsd_printer_t *p; /* Printer */ static unsigned request_id = 0; /* Request ID for temp files */ @@ -1039,130 +1038,57 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ case HTTP_STATE_GET_SEND : cupsdLogClient(con, CUPSD_LOG_DEBUG, "Processing GET %s", con->uri); - if ((!strncmp(con->uri, "/ppd/", 5) || - !strncmp(con->uri, "/printers/", 10) || - !strncmp(con->uri, "/classes/", 9)) && - !strcmp(con->uri + strlen(con->uri) - 4, ".ppd")) - { - /* - * Send PPD file - get the real printer name since printer - * names are not case sensitive but filenames can be... - */ + if ((filename = get_file(con, &filestats, buf, sizeof(buf))) != NULL) + { + type = mimeFileType(MimeDatabase, filename, NULL, NULL); - con->uri[strlen(con->uri) - 4] = '\0'; /* Drop ".ppd" */ + cupsdLogClient(con, CUPSD_LOG_DEBUG, "filename=\"%s\", type=%s/%s", filename, type ? type->super : "", type ? type->type : ""); - if (!strncmp(con->uri, "/ppd/", 5)) - p = cupsdFindPrinter(con->uri + 5); - else if (!strncmp(con->uri, "/printers/", 10)) - p = cupsdFindPrinter(con->uri + 10); - else + if (is_cgi(con, filename, &filestats, type)) { - p = cupsdFindClass(con->uri + 9); + /* + * Note: con->command and con->options were set by is_cgi()... + */ - if (p) + if (!cupsdSendCommand(con, con->command, con->options, 0)) { - int i; /* Looping var */ - - for (i = 0; i < p->num_printers; i ++) + if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE)) { - if (!(p->printers[i]->type & CUPS_PRINTER_CLASS)) - { - char ppdname[1024];/* PPD filename */ - - snprintf(ppdname, sizeof(ppdname), "%s/ppd/%s.ppd", - ServerRoot, p->printers[i]->name); - if (!access(ppdname, 0)) - { - p = p->printers[i]; - break; - } - } + cupsdCloseClient(con); + return; } + } + else + cupsdLogRequest(con, HTTP_STATUS_OK); - if (i >= p->num_printers) - p = NULL; - } + if (httpGetVersion(con->http) <= HTTP_VERSION_1_0) + httpSetKeepAlive(con->http, HTTP_KEEPALIVE_OFF); + break; } - if (p) - { - snprintf(con->uri, sizeof(con->uri), "/ppd/%s.ppd", p->name); - } - else - { - if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE)) + if (!check_if_modified(con, &filestats)) + { + if (!cupsdSendError(con, HTTP_STATUS_NOT_MODIFIED, CUPSD_AUTH_NONE)) { cupsdCloseClient(con); return; } - - break; } - } - else if ((!strncmp(con->uri, "/icons/", 7) || - !strncmp(con->uri, "/printers/", 10) || - !strncmp(con->uri, "/classes/", 9)) && - !strcmp(con->uri + strlen(con->uri) - 4, ".png")) - { - /* - * Send icon file - get the real queue name since queue names are - * not case sensitive but filenames can be... - */ - - con->uri[strlen(con->uri) - 4] = '\0'; /* Drop ".png" */ - - if (!strncmp(con->uri, "/icons/", 7)) - p = cupsdFindPrinter(con->uri + 7); - else if (!strncmp(con->uri, "/printers/", 10)) - p = cupsdFindPrinter(con->uri + 10); - else + else { - p = cupsdFindClass(con->uri + 9); - - if (p) - { - int i; /* Looping var */ - - for (i = 0; i < p->num_printers; i ++) - { - if (!(p->printers[i]->type & CUPS_PRINTER_CLASS)) - { - char ppdname[1024];/* PPD filename */ - - snprintf(ppdname, sizeof(ppdname), "%s/ppd/%s.ppd", - ServerRoot, p->printers[i]->name); - if (!access(ppdname, 0)) - { - p = p->printers[i]; - break; - } - } - } - - if (i >= p->num_printers) - p = NULL; - } - } + if (type == NULL) + strlcpy(line, "text/plain", sizeof(line)); + else + snprintf(line, sizeof(line), "%s/%s", type->super, type->type); - if (p) - snprintf(con->uri, sizeof(con->uri), "/icons/%s.png", p->name); - else - { - if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE)) + if (!write_file(con, HTTP_STATUS_OK, filename, line, &filestats)) { cupsdCloseClient(con); return; } - - break; } - } - - if ((!strncmp(con->uri, "/admin", 6) && strcmp(con->uri, "/admin/conf/cupsd.conf") && strncmp(con->uri, "/admin/log/", 11)) || - !strncmp(con->uri, "/printers", 9) || - !strncmp(con->uri, "/classes", 8) || - !strncmp(con->uri, "/help", 5) || - !strncmp(con->uri, "/jobs", 5)) + } + else if (!strncmp(con->uri, "/admin", 6) || !strncmp(con->uri, "/printers", 9) || !strncmp(con->uri, "/classes", 8) || !strncmp(con->uri, "/help", 5) || !strncmp(con->uri, "/jobs", 5)) { if (!WebInterface) { @@ -1185,16 +1111,12 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ if (!strncmp(con->uri, "/admin", 6)) { - cupsdSetStringf(&con->command, "%s/cgi-bin/admin.cgi", - ServerBin); - + cupsdSetStringf(&con->command, "%s/cgi-bin/admin.cgi", ServerBin); cupsdSetString(&con->options, strchr(con->uri + 6, '?')); } else if (!strncmp(con->uri, "/printers", 9)) { - cupsdSetStringf(&con->command, "%s/cgi-bin/printers.cgi", - ServerBin); - + cupsdSetStringf(&con->command, "%s/cgi-bin/printers.cgi", ServerBin); if (con->uri[9] && con->uri[10]) cupsdSetString(&con->options, con->uri + 9); else @@ -1202,9 +1124,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ } else if (!strncmp(con->uri, "/classes", 8)) { - cupsdSetStringf(&con->command, "%s/cgi-bin/classes.cgi", - ServerBin); - + cupsdSetStringf(&con->command, "%s/cgi-bin/classes.cgi", ServerBin); if (con->uri[8] && con->uri[9]) cupsdSetString(&con->options, con->uri + 8); else @@ -1212,9 +1132,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ } else if (!strncmp(con->uri, "/jobs", 5)) { - cupsdSetStringf(&con->command, "%s/cgi-bin/jobs.cgi", - ServerBin); - + cupsdSetStringf(&con->command, "%s/cgi-bin/jobs.cgi", ServerBin); if (con->uri[5] && con->uri[6]) cupsdSetString(&con->options, con->uri + 5); else @@ -1222,9 +1140,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ } else { - cupsdSetStringf(&con->command, "%s/cgi-bin/help.cgi", - ServerBin); - + cupsdSetStringf(&con->command, "%s/cgi-bin/help.cgi", ServerBin); if (con->uri[5] && con->uri[6]) cupsdSetString(&con->options, con->uri + 5); else @@ -1245,89 +1161,13 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ if (httpGetVersion(con->http) <= HTTP_VERSION_1_0) httpSetKeepAlive(con->http, HTTP_KEEPALIVE_OFF); } - else if (!strncmp(con->uri, "/admin/log/", 11) && (strchr(con->uri + 11, '/') || strlen(con->uri) == 11)) + else { - /* - * GET can only be done to configuration files directly under - * /admin/conf... - */ - - cupsdLogClient(con, CUPSD_LOG_ERROR, "Request for subdirectory \"%s\".", con->uri); - - if (!cupsdSendError(con, HTTP_STATUS_FORBIDDEN, CUPSD_AUTH_NONE)) + if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE)) { cupsdCloseClient(con); return; } - - break; - } - else - { - /* - * Serve a file... - */ - - if ((filename = get_file(con, &filestats, buf, - sizeof(buf))) == NULL) - { - if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE)) - { - cupsdCloseClient(con); - return; - } - - break; - } - - type = mimeFileType(MimeDatabase, filename, NULL, NULL); - - cupsdLogClient(con, CUPSD_LOG_DEBUG, "filename=\"%s\", type=%s/%s", filename, type ? type->super : "", type ? type->type : ""); - - if (is_cgi(con, filename, &filestats, type)) - { - /* - * Note: con->command and con->options were set by - * is_cgi()... - */ - - if (!cupsdSendCommand(con, con->command, con->options, 0)) - { - if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE)) - { - cupsdCloseClient(con); - return; - } - } - else - cupsdLogRequest(con, HTTP_STATUS_OK); - - if (httpGetVersion(con->http) <= HTTP_VERSION_1_0) - httpSetKeepAlive(con->http, HTTP_KEEPALIVE_OFF); - break; - } - - if (!check_if_modified(con, &filestats)) - { - if (!cupsdSendError(con, HTTP_STATUS_NOT_MODIFIED, CUPSD_AUTH_NONE)) - { - cupsdCloseClient(con); - return; - } - } - else - { - if (type == NULL) - strlcpy(line, "text/plain", sizeof(line)); - else - snprintf(line, sizeof(line), "%s/%s", type->super, type->type); - - if (!write_file(con, HTTP_STATUS_OK, filename, line, &filestats)) - { - cupsdCloseClient(con); - return; - } - } } break; @@ -1337,9 +1177,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ * so check the length against any limits that are set... */ - if (httpGetField(con->http, HTTP_FIELD_CONTENT_LENGTH)[0] && - MaxRequestSize > 0 && - httpGetLength2(con->http) > MaxRequestSize) + if (httpGetField(con->http, HTTP_FIELD_CONTENT_LENGTH)[0] && MaxRequestSize > 0 && httpGetLength2(con->http) > MaxRequestSize) { /* * Request too large... @@ -1373,9 +1211,11 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ * content-type field will be "application/ipp"... */ - if (!strcmp(httpGetField(con->http, HTTP_FIELD_CONTENT_TYPE), - "application/ipp")) + if (!strcmp(httpGetField(con->http, HTTP_FIELD_CONTENT_TYPE), "application/ipp")) + { con->request = ippNew(); + break; + } else if (!WebInterface) { /* @@ -1390,11 +1230,29 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ break; } - else if ((!strncmp(con->uri, "/admin", 6) && strncmp(con->uri, "/admin/log/", 11)) || - !strncmp(con->uri, "/printers", 9) || - !strncmp(con->uri, "/classes", 8) || - !strncmp(con->uri, "/help", 5) || - !strncmp(con->uri, "/jobs", 5)) + + if ((filename = get_file(con, &filestats, buf, sizeof(buf))) != NULL) + { + /* + * POST to a file... + */ + + type = mimeFileType(MimeDatabase, filename, NULL, NULL); + + if (!is_cgi(con, filename, &filestats, type)) + { + /* + * Only POST to CGI's... + */ + + if (!cupsdSendError(con, HTTP_STATUS_UNAUTHORIZED, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + } + } + else if (!strncmp(con->uri, "/admin", 6) || !strncmp(con->uri, "/printers", 9) || !strncmp(con->uri, "/classes", 8) || !strncmp(con->uri, "/help", 5) || !strncmp(con->uri, "/jobs", 5)) { /* * CGI request... @@ -1402,16 +1260,12 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ if (!strncmp(con->uri, "/admin", 6)) { - cupsdSetStringf(&con->command, "%s/cgi-bin/admin.cgi", - ServerBin); - + cupsdSetStringf(&con->command, "%s/cgi-bin/admin.cgi", ServerBin); cupsdSetString(&con->options, strchr(con->uri + 6, '?')); } else if (!strncmp(con->uri, "/printers", 9)) { - cupsdSetStringf(&con->command, "%s/cgi-bin/printers.cgi", - ServerBin); - + cupsdSetStringf(&con->command, "%s/cgi-bin/printers.cgi", ServerBin); if (con->uri[9] && con->uri[10]) cupsdSetString(&con->options, con->uri + 9); else @@ -1419,9 +1273,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ } else if (!strncmp(con->uri, "/classes", 8)) { - cupsdSetStringf(&con->command, "%s/cgi-bin/classes.cgi", - ServerBin); - + cupsdSetStringf(&con->command, "%s/cgi-bin/classes.cgi", ServerBin); if (con->uri[8] && con->uri[9]) cupsdSetString(&con->options, con->uri + 8); else @@ -1429,9 +1281,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ } else if (!strncmp(con->uri, "/jobs", 5)) { - cupsdSetStringf(&con->command, "%s/cgi-bin/jobs.cgi", - ServerBin); - + cupsdSetStringf(&con->command, "%s/cgi-bin/jobs.cgi", ServerBin); if (con->uri[5] && con->uri[6]) cupsdSetString(&con->options, con->uri + 5); else @@ -1439,9 +1289,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ } else { - cupsdSetStringf(&con->command, "%s/cgi-bin/help.cgi", - ServerBin); - + cupsdSetStringf(&con->command, "%s/cgi-bin/help.cgi", ServerBin); if (con->uri[5] && con->uri[6]) cupsdSetString(&con->options, con->uri + 5); else @@ -1453,35 +1301,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ } else { - /* - * POST to a file... - */ - - if ((filename = get_file(con, &filestats, buf, - sizeof(buf))) == NULL) - { - if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE)) - { - cupsdCloseClient(con); - return; - } - - break; - } - - type = mimeFileType(MimeDatabase, filename, NULL, NULL); - - if (!is_cgi(con, filename, &filestats, type)) + if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE)) { - /* - * Only POST to CGI's... - */ - - if (!cupsdSendError(con, HTTP_STATUS_UNAUTHORIZED, CUPSD_AUTH_NONE)) - { - cupsdCloseClient(con); - return; - } + cupsdCloseClient(con); + return; } } break; @@ -1497,8 +1320,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ * PUT can only be done to the cupsd.conf file... */ - cupsdLogClient(con, CUPSD_LOG_ERROR, - "Disallowed PUT request for \"%s\".", con->uri); + cupsdLogClient(con, CUPSD_LOG_ERROR, "Disallowed PUT request for \"%s\".", con->uri); if (!cupsdSendError(con, HTTP_STATUS_FORBIDDEN, CUPSD_AUTH_NONE)) { @@ -1514,9 +1336,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ * so check the length against any limits that are set... */ - if (httpGetField(con->http, HTTP_FIELD_CONTENT_LENGTH)[0] && - MaxRequestSize > 0 && - httpGetLength2(con->http) > MaxRequestSize) + if (httpGetField(con->http, HTTP_FIELD_CONTENT_LENGTH)[0] && MaxRequestSize > 0 && httpGetLength2(con->http) > MaxRequestSize) { /* * Request too large... @@ -1549,15 +1369,12 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ * Open a temporary file to hold the request... */ - cupsdSetStringf(&con->filename, "%s/%08x", RequestRoot, - request_id ++); + cupsdSetStringf(&con->filename, "%s/%08x", RequestRoot, request_id ++); con->file = open(con->filename, O_WRONLY | O_CREAT | O_TRUNC, 0640); if (con->file < 0) { - cupsdLogClient(con, CUPSD_LOG_ERROR, - "Unable to create request file \"%s\": %s", - con->filename, strerror(errno)); + cupsdLogClient(con, CUPSD_LOG_ERROR, "Unable to create request file \"%s\": %s", con->filename, strerror(errno)); if (!cupsdSendError(con, HTTP_STATUS_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE)) { @@ -1578,54 +1395,44 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ return; case HTTP_STATE_HEAD : - if (!strncmp(con->uri, "/printers/", 10) && - !strcmp(con->uri + strlen(con->uri) - 4, ".ppd")) - { - /* - * Send PPD file - get the real printer name since printer - * names are not case sensitive but filenames can be... - */ - - con->uri[strlen(con->uri) - 4] = '\0'; /* Drop ".ppd" */ - - if ((p = cupsdFindPrinter(con->uri + 10)) != NULL) - snprintf(con->uri, sizeof(con->uri), "/ppd/%s.ppd", p->name); - else + if ((filename = get_file(con, &filestats, buf, sizeof(buf))) != NULL) + { + if (!check_if_modified(con, &filestats)) { - if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE)) + if (!cupsdSendError(con, HTTP_STATUS_NOT_MODIFIED, CUPSD_AUTH_NONE)) { cupsdCloseClient(con); return; } - cupsdLogRequest(con, HTTP_STATUS_NOT_FOUND); - break; + cupsdLogRequest(con, HTTP_STATUS_NOT_MODIFIED); } - } - else if (!strncmp(con->uri, "/printers/", 10) && - !strcmp(con->uri + strlen(con->uri) - 4, ".png")) - { - /* - * Send PNG file - get the real printer name since printer - * names are not case sensitive but filenames can be... - */ - - con->uri[strlen(con->uri) - 4] = '\0'; /* Drop ".ppd" */ - - if ((p = cupsdFindPrinter(con->uri + 10)) != NULL) - snprintf(con->uri, sizeof(con->uri), "/icons/%s.png", p->name); else { - if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE)) + /* + * Serve a file... + */ + + type = mimeFileType(MimeDatabase, filename, NULL, NULL); + if (type == NULL) + strlcpy(line, "text/plain", sizeof(line)); + else + snprintf(line, sizeof(line), "%s/%s", type->super, type->type); + + httpClearFields(con->http); + + httpSetField(con->http, HTTP_FIELD_LAST_MODIFIED, httpGetDateString(filestats.st_mtime)); + httpSetLength(con->http, (size_t)filestats.st_size); + + if (!cupsdSendHeader(con, HTTP_STATUS_OK, line, CUPSD_AUTH_NONE)) { cupsdCloseClient(con); return; } - cupsdLogRequest(con, HTTP_STATUS_NOT_FOUND); - break; + cupsdLogRequest(con, HTTP_STATUS_OK); } - } + } else if (!WebInterface) { httpClearFields(con->http); @@ -1640,11 +1447,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ break; } - if ((!strncmp(con->uri, "/admin", 6) && strcmp(con->uri, "/admin/conf/cupsd.conf") && strncmp(con->uri, "/admin/log/", 11)) || - !strncmp(con->uri, "/printers", 9) || - !strncmp(con->uri, "/classes", 8) || - !strncmp(con->uri, "/help", 5) || - !strncmp(con->uri, "/jobs", 5)) + if (!strncmp(con->uri, "/admin", 6) || !strncmp(con->uri, "/printers", 9) || !strncmp(con->uri, "/classes", 8) || !strncmp(con->uri, "/help", 5) || !strncmp(con->uri, "/jobs", 5)) { /* * CGI output... @@ -1660,74 +1463,17 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ cupsdLogRequest(con, HTTP_STATUS_OK); } - else if (!strncmp(con->uri, "/admin/log/", 11) && (strchr(con->uri + 11, '/') || strlen(con->uri) == 11)) - { - /* - * HEAD can only be done to configuration files under - * /admin/conf... - */ - - cupsdLogClient(con, CUPSD_LOG_ERROR, - "Request for subdirectory \"%s\".", con->uri); - - if (!cupsdSendError(con, HTTP_STATUS_FORBIDDEN, CUPSD_AUTH_NONE)) - { - cupsdCloseClient(con); - return; - } - - cupsdLogRequest(con, HTTP_STATUS_FORBIDDEN); - break; - } - else if ((filename = get_file(con, &filestats, buf, - sizeof(buf))) == NULL) - { - httpClearFields(con->http); - - if (!cupsdSendHeader(con, HTTP_STATUS_NOT_FOUND, "text/html", - CUPSD_AUTH_NONE)) - { - cupsdCloseClient(con); - return; - } - - cupsdLogRequest(con, HTTP_STATUS_NOT_FOUND); - } - else if (!check_if_modified(con, &filestats)) - { - if (!cupsdSendError(con, HTTP_STATUS_NOT_MODIFIED, CUPSD_AUTH_NONE)) - { - cupsdCloseClient(con); - return; - } - - cupsdLogRequest(con, HTTP_STATUS_NOT_MODIFIED); - } else { - /* - * Serve a file... - */ - - type = mimeFileType(MimeDatabase, filename, NULL, NULL); - if (type == NULL) - strlcpy(line, "text/plain", sizeof(line)); - else - snprintf(line, sizeof(line), "%s/%s", type->super, type->type); - httpClearFields(con->http); - httpSetField(con->http, HTTP_FIELD_LAST_MODIFIED, - httpGetDateString(filestats.st_mtime)); - httpSetLength(con->http, (size_t)filestats.st_size); - - if (!cupsdSendHeader(con, HTTP_STATUS_OK, line, CUPSD_AUTH_NONE)) + if (!cupsdSendHeader(con, HTTP_STATUS_NOT_FOUND, "text/html", CUPSD_AUTH_NONE)) { cupsdCloseClient(con); return; } - cupsdLogRequest(con, HTTP_STATUS_OK); + cupsdLogRequest(con, HTTP_STATUS_NOT_FOUND); } break; @@ -2936,6 +2682,7 @@ get_file(cupsd_client_t *con, /* I - Client connection */ char language[7], /* Language subdirectory, if any */ dest[1024]; /* Destination name */ int perm_check = 1; /* Do permissions check? */ + cupsd_printer_t *p; /* Printer */ /* @@ -2944,47 +2691,76 @@ get_file(cupsd_client_t *con, /* I - Client connection */ language[0] = '\0'; - if (!strncmp(con->uri, "/ppd/", 5) && !strchr(con->uri + 5, '/')) + if ((!strncmp(con->uri, "/ppd/", 5) || !strncmp(con->uri, "/printers/", 10) || !strncmp(con->uri, "/classes/", 9)) && !strcmp(con->uri + strlen(con->uri) - 4, ".ppd")) { - strlcpy(dest, con->uri + 5, sizeof(dest)); - ptr = dest + strlen(dest) - 4; + strlcpy(dest, strchr(con->uri + 1, '/') + 1, sizeof(dest)); + dest[strlen(dest) - 4] = '\0'; /* Strip .ppd */ - if (ptr <= dest || strcmp(ptr, ".ppd")) + if ((p = cupsdFindDest(dest)) == NULL) { - cupsdLogClient(con, CUPSD_LOG_INFO, "Disallowed path \"%s\".", con->uri); + cupsdLogClient(con, CUPSD_LOG_INFO, "No destination \"%s\" found.", dest); return (NULL); } - *ptr = '\0'; - if (!cupsdFindPrinter(dest)) + if (p->type & CUPS_PRINTER_CLASS) { - cupsdLogClient(con, CUPSD_LOG_INFO, "No printer \"%s\" found.", dest); - return (NULL); - } + int i; /* Looping var */ - snprintf(filename, len, "%s%s", ServerRoot, con->uri); + for (i = 0; i < p->num_printers; i ++) + { + if (!(p->printers[i]->type & CUPS_PRINTER_CLASS)) + { + snprintf(filename, len, "%s/ppd/%s.ppd", ServerRoot, p->printers[i]->name); + if (!access(filename, 0)) + { + p = p->printers[i]; + break; + } + } + } + + if (i >= p->num_printers) + p = NULL; + } + else + snprintf(filename, len, "%s/ppd/%s.ppd", ServerRoot, p->name); perm_check = 0; } - else if (!strncmp(con->uri, "/icons/", 7) && !strchr(con->uri + 7, '/')) + else if ((!strncmp(con->uri, "/icons/", 7) || !strncmp(con->uri, "/printers/", 10) || !strncmp(con->uri, "/classes/", 9)) && !strcmp(con->uri + strlen(con->uri) - 4, ".png")) { - strlcpy(dest, con->uri + 7, sizeof(dest)); - ptr = dest + strlen(dest) - 4; + strlcpy(dest, strchr(con->uri + 1, '/') + 1, sizeof(dest)); + dest[strlen(dest) - 4] = '\0'; /* Strip .png */ - if (ptr <= dest || strcmp(ptr, ".png")) + if ((p = cupsdFindDest(dest)) == NULL) { - cupsdLogClient(con, CUPSD_LOG_INFO, "Disallowed path \"%s\".", con->uri); + cupsdLogClient(con, CUPSD_LOG_INFO, "No destination \"%s\" found.", dest); return (NULL); } - *ptr = '\0'; - if (!cupsdFindDest(dest)) + if (p->type & CUPS_PRINTER_CLASS) { - cupsdLogClient(con, CUPSD_LOG_INFO, "No printer \"%s\" found.", dest); - return (NULL); + int i; /* Looping var */ + + for (i = 0; i < p->num_printers; i ++) + { + if (!(p->printers[i]->type & CUPS_PRINTER_CLASS)) + { + snprintf(filename, len, "%s/images/%s.png", CacheDir, p->printers[i]->name); + if (!access(filename, 0)) + { + p = p->printers[i]; + break; + } + } + } + + if (i >= p->num_printers) + p = NULL; } + else + snprintf(filename, len, "%s/images/%s.png", CacheDir, p->name); - snprintf(filename, len, "%s/%s.png", CacheDir, dest); if (access(filename, F_OK) < 0) snprintf(filename, len, "%s/images/generic.png", DocumentRoot); @@ -2992,6 +2768,27 @@ get_file(cupsd_client_t *con, /* I - Client connection */ } else if (!strncmp(con->uri, "/rss/", 5) && !strchr(con->uri + 5, '/')) snprintf(filename, len, "%s/rss/%s", CacheDir, con->uri + 5); + else if (!strncmp(con->uri, "/strings/", 9) && !strcmp(con->uri + strlen(con->uri) - 8, ".strings")) + { + strlcpy(dest, con->uri + 9, sizeof(dest)); + dest[strlen(dest) - 8] = '\0'; + + if ((p = cupsdFindDest(dest)) == NULL) + { + cupsdLogClient(con, CUPSD_LOG_INFO, "No destination \"%s\" found.", dest); + return (NULL); + } + + if (!p->strings) + { + cupsdLogClient(con, CUPSD_LOG_INFO, "No strings files for \"%s\".", dest); + return (NULL); + } + + strlcpy(filename, p->strings, len); + + perm_check = 0; + } else if (!strcmp(con->uri, "/admin/conf/cupsd.conf")) { strlcpy(filename, ConfigurationFile, len); @@ -3031,6 +2828,7 @@ get_file(cupsd_client_t *con, /* I - Client connection */ strncmp(con->uri, "/icons/", 7) && strncmp(con->uri, "/ppd/", 5) && strncmp(con->uri, "/rss/", 5) && + strncmp(con->uri, "/strings/", 9) && strncmp(con->uri, "/admin/conf/", 12) && strncmp(con->uri, "/admin/log/", 11)) { diff --git a/scheduler/ipp.c b/scheduler/ipp.c index 38afa5f45f..92353a84d5 100644 --- a/scheduler/ipp.c +++ b/scheduler/ipp.c @@ -4912,12 +4912,11 @@ copy_printer_attrs( cupsd_printer_t *printer, /* I - Printer */ cups_array_t *ra) /* I - Requested attributes array */ { - char printer_uri[HTTP_MAX_URI]; - /* Printer URI */ - char printer_icons[HTTP_MAX_URI]; - /* Printer icons */ - time_t curtime; /* Current time */ - int i; /* Looping var */ + char uri[HTTP_MAX_URI]; /* URI value */ + time_t curtime; /* Current time */ + int i; /* Looping var */ + int is_encrypted = httpIsEncrypted(con->http); + /* Is the connection encrypted? */ /* @@ -4928,107 +4927,83 @@ copy_printer_attrs( curtime = time(NULL); if (!ra || cupsArrayFind(ra, "marker-change-time")) - ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, - "marker-change-time", printer->marker_time); + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "marker-change-time", printer->marker_time); - if (printer->num_printers > 0 && - (!ra || cupsArrayFind(ra, "member-uris"))) + if (printer->num_printers > 0 && (!ra || cupsArrayFind(ra, "member-uris"))) { ipp_attribute_t *member_uris; /* member-uris attribute */ cupsd_printer_t *p2; /* Printer in class */ ipp_attribute_t *p2_uri; /* printer-uri-supported for class printer */ - if ((member_uris = ippAddStrings(con->response, IPP_TAG_PRINTER, - IPP_TAG_URI, "member-uris", - printer->num_printers, NULL, - NULL)) != NULL) + if ((member_uris = ippAddStrings(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris", printer->num_printers, NULL, NULL)) != NULL) { for (i = 0; i < printer->num_printers; i ++) { p2 = printer->printers[i]; - if ((p2_uri = ippFindAttribute(p2->attrs, "printer-uri-supported", - IPP_TAG_URI)) != NULL) - member_uris->values[i].string.text = - _cupsStrRetain(p2_uri->values[0].string.text); + if ((p2_uri = ippFindAttribute(p2->attrs, "printer-uri-supported", IPP_TAG_URI)) != NULL) + { + member_uris->values[i].string.text = _cupsStrRetain(p2_uri->values[0].string.text); + } else { - httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, - sizeof(printer_uri), "ipp", NULL, con->clientname, - con->clientport, - (p2->type & CUPS_PRINTER_CLASS) ? - "/classes/%s" : "/printers/%s", p2->name); - member_uris->values[i].string.text = _cupsStrAlloc(printer_uri); + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), is_encrypted ? "ipps" : "ipp", NULL, con->clientname, con->clientport, (p2->type & CUPS_PRINTER_CLASS) ? "/classes/%s" : "/printers/%s", p2->name); + member_uris->values[i].string.text = _cupsStrAlloc(uri); } } } } if (printer->alert && (!ra || cupsArrayFind(ra, "printer-alert"))) - ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_STRING, - "printer-alert", NULL, printer->alert); + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_STRING, "printer-alert", NULL, printer->alert); - if (printer->alert_description && - (!ra || cupsArrayFind(ra, "printer-alert-description"))) - ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT, - "printer-alert-description", NULL, - printer->alert_description); + if (printer->alert_description && (!ra || cupsArrayFind(ra, "printer-alert-description"))) + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-alert-description", NULL, printer->alert_description); if (!ra || cupsArrayFind(ra, "printer-config-change-date-time")) ippAddDate(con->response, IPP_TAG_PRINTER, "printer-config-change-date-time", ippTimeToDate(printer->config_time)); if (!ra || cupsArrayFind(ra, "printer-config-change-time")) - ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, - "printer-config-change-time", printer->config_time); + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "printer-config-change-time", printer->config_time); if (!ra || cupsArrayFind(ra, "printer-current-time")) - ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time", - ippTimeToDate(curtime)); + ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time", ippTimeToDate(curtime)); #if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) if (!ra || cupsArrayFind(ra, "printer-dns-sd-name")) { if (printer->reg_name) - ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME, - "printer-dns-sd-name", NULL, printer->reg_name); + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME, "printer-dns-sd-name", NULL, printer->reg_name); else - ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_NOVALUE, - "printer-dns-sd-name", 0); + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_NOVALUE, "printer-dns-sd-name", 0); } #endif /* HAVE_DNSSD || HAVE_AVAHI */ if (!ra || cupsArrayFind(ra, "printer-error-policy")) - ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME, - "printer-error-policy", NULL, printer->error_policy); + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME, "printer-error-policy", NULL, printer->error_policy); if (!ra || cupsArrayFind(ra, "printer-error-policy-supported")) { static const char * const errors[] =/* printer-error-policy-supported values */ - { - "abort-job", - "retry-current-job", - "retry-job", - "stop-printer" - }; + { + "abort-job", + "retry-current-job", + "retry-job", + "stop-printer" + }; if (printer->type & CUPS_PRINTER_CLASS) - ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME | IPP_TAG_COPY, - "printer-error-policy-supported", NULL, "retry-current-job"); + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME | IPP_TAG_COPY, "printer-error-policy-supported", NULL, "retry-current-job"); else - ippAddStrings(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME | IPP_TAG_COPY, - "printer-error-policy-supported", - sizeof(errors) / sizeof(errors[0]), NULL, errors); + ippAddStrings(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME | IPP_TAG_COPY, "printer-error-policy-supported", sizeof(errors) / sizeof(errors[0]), NULL, errors); } if (!ra || cupsArrayFind(ra, "printer-icons")) { - httpAssembleURIf(HTTP_URI_CODING_ALL, printer_icons, sizeof(printer_icons), - "http", NULL, con->clientname, con->clientport, - "/icons/%s.png", printer->name); - ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-icons", - NULL, printer_icons); - cupsdLogMessage(CUPSD_LOG_DEBUG2, "printer-icons=\"%s\"", printer_icons); + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), is_encrypted ? "https" : "http", NULL, con->clientname, con->clientport, "/icons/%s.png", printer->name); + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-icons", NULL, uri); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "printer-icons=\"%s\"", uri); } if (!ra || cupsArrayFind(ra, "printer-is-accepting-jobs")) @@ -5042,36 +5017,35 @@ copy_printer_attrs( if (!ra || cupsArrayFind(ra, "printer-more-info")) { - httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), - "http", NULL, con->clientname, con->clientport, - (printer->type & CUPS_PRINTER_CLASS) ? - "/classes/%s" : "/printers/%s", printer->name); - ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, - "printer-more-info", NULL, printer_uri); + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), is_encrypted ? "https" : "http", NULL, con->clientname, con->clientport, (printer->type & CUPS_PRINTER_CLASS) ? "/classes/%s" : "/printers/%s", printer->name); + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-more-info", NULL, uri); } if (!ra || cupsArrayFind(ra, "printer-op-policy")) - ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME, - "printer-op-policy", NULL, printer->op_policy); + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME, "printer-op-policy", NULL, printer->op_policy); if (!ra || cupsArrayFind(ra, "printer-state")) - ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state", - printer->state); + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state", printer->state); if (!ra || cupsArrayFind(ra, "printer-state-change-date-time")) ippAddDate(con->response, IPP_TAG_PRINTER, "printer-state-change-date-time", ippTimeToDate(printer->state_time)); if (!ra || cupsArrayFind(ra, "printer-state-change-time")) - ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, - "printer-state-change-time", printer->state_time); + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "printer-state-change-time", printer->state_time); if (!ra || cupsArrayFind(ra, "printer-state-message")) - ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT, - "printer-state-message", NULL, printer->state_message); + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-state-message", NULL, printer->state_message); if (!ra || cupsArrayFind(ra, "printer-state-reasons")) add_printer_state_reasons(con, printer); + if (!ra || cupsArrayFind(ra, "printer-strings-uri")) + { + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), is_encrypted ? "https" : "http", NULL, con->clientname, con->clientport, "/strings/%s.strings", printer->name); + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-strings-uri", NULL, uri); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "printer-strings-uri=\"%s\"", uri); + } + if (!ra || cupsArrayFind(ra, "printer-type")) { cups_ptype_t type; /* printer-type value */ @@ -5095,19 +5069,13 @@ copy_printer_attrs( } if (!ra || cupsArrayFind(ra, "printer-up-time")) - ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, - "printer-up-time", curtime); + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "printer-up-time", curtime); if (!ra || cupsArrayFind(ra, "printer-uri-supported")) { - httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), - "ipp", NULL, con->clientname, con->clientport, - (printer->type & CUPS_PRINTER_CLASS) ? - "/classes/%s" : "/printers/%s", printer->name); - ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, - "printer-uri-supported", NULL, printer_uri); - cupsdLogMessage(CUPSD_LOG_DEBUG2, "printer-uri-supported=\"%s\"", - printer_uri); + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), is_encrypted ? "ipps" : "ipp", NULL, con->clientname, con->clientport, (printer->type & CUPS_PRINTER_CLASS) ? "/classes/%s" : "/printers/%s", printer->name); + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-uri-supported", NULL, uri); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "printer-uri-supported=\"%s\"", uri); } if (!ra || cupsArrayFind(ra, "queued-job-count")) diff --git a/scheduler/printers.c b/scheduler/printers.c index 557d7514f6..c4a009d3dd 100644 --- a/scheduler/printers.c +++ b/scheduler/printers.c @@ -805,6 +805,7 @@ cupsdDeletePrinter( cupsdClearString(&p->port_monitor); cupsdClearString(&p->op_policy); cupsdClearString(&p->error_policy); + cupsdClearString(&p->strings); cupsdClearString(&p->alert); cupsdClearString(&p->alert_description); @@ -3824,6 +3825,7 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */ ppd_file_t *ppd; /* PPD file */ char ppd_name[1024]; /* PPD filename */ struct stat ppd_info; /* PPD file info */ + char strings_name[1024]; /* Strings filename */ int num_media; /* Number of media options */ ppd_size_t *size; /* Current PPD size */ ppd_option_t *duplex, /* Duplex option */ @@ -3882,6 +3884,8 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */ if (stat(ppd_name, &ppd_info)) ppd_info.st_mtime = 1; + snprintf(strings_name, sizeof(strings_name), "%s/%s.strings", CacheDir, p->name); + ippDelete(p->ppd_attrs); p->ppd_attrs = NULL; @@ -4053,8 +4057,13 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */ ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-make-and-model", NULL, p->make_model); - if (p->pc->strings_uri) - ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-strings-uri", NULL, p->pc->strings_uri); + if (p->pc && p->pc->strings) + _cupsMessageSave(strings_name, _CUPS_MESSAGE_STRINGS, p->pc->strings); + + if (!access(strings_name, R_OK)) + cupsdSetString(&p->strings, strings_name); + else + cupsdClearString(&p->strings); /* * Add media options from the PPD file... diff --git a/scheduler/printers.h b/scheduler/printers.h index 6f8afc60f7..4959bf2760 100644 --- a/scheduler/printers.h +++ b/scheduler/printers.h @@ -65,6 +65,7 @@ struct cupsd_printer_s *info, /* Description */ *organization, /* Organization name */ *organizational_unit, /* Organizational unit (department, etc.) */ + *strings, /* Strings file, if any */ *op_policy, /* Operation policy name */ *error_policy; /* Error policy */ cupsd_policy_t *op_policy_ptr; /* Pointer to operation policy */