From 521da18da0b0ef9aeda87ebbfbc81fb49d996029 Mon Sep 17 00:00:00 2001 From: mike Date: Wed, 8 Oct 2008 04:26:38 +0000 Subject: [PATCH] First half of PPD/attributes caching (STR #1293) git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@8026 7a7537e8-13f0-0310-91df-b6672ffda945 --- cups/file.c | 61 +++++++ cups/file.h | 4 +- cups/libcups.exp | 1 + doc/help/ref-printers-conf.html | 71 +++++++- scheduler/classes.c | 109 +++++-------- scheduler/cupsd.h | 3 +- scheduler/dirsvc.c | 38 ++--- scheduler/printers.c | 276 +++++++++++++++++--------------- scheduler/printers.h | 2 + 9 files changed, 342 insertions(+), 223 deletions(-) diff --git a/cups/file.c b/cups/file.c index c07c6cc72e..5c98114898 100644 --- a/cups/file.c +++ b/cups/file.c @@ -1253,6 +1253,67 @@ cupsFilePutChar(cups_file_t *fp, /* I - CUPS file */ } +/* + * 'cupsFilePutConf()' - Write a configuration line. + * + * This function handles any comment escaping of the value. + * + * @since CUPS 1.4@ + */ + +ssize_t /* O - Number of bytes written or -1 on error */ +cupsFilePutConf(cups_file_t *fp, /* I - CUPS file */ + const char *directive, /* I - Directive */ + const char *value) /* I - Value */ +{ + ssize_t bytes, /* Number of bytes written */ + temp; /* Temporary byte count */ + const char *ptr; /* Pointer into value */ + + + if (!fp || !directive || !*directive) + return (-1); + + if ((bytes = cupsFilePuts(fp, directive)) < 0) + return (-1); + + if (cupsFilePutChar(fp, ' ') < 0) + return (-1); + bytes ++; + + if (value && *value) + { + if ((ptr = strchr(value, '#')) != NULL) + { + /* + * Need to quote the first # in the info string... + */ + + if ((temp = cupsFileWrite(fp, value, ptr - value)) < 0) + return (-1); + bytes += temp; + + if (cupsFilePutChar(fp, '\\') < 0) + return (-1); + bytes ++; + + if ((temp = cupsFilePuts(fp, ptr)) < 0) + return (-1); + bytes += temp; + } + else if ((temp = cupsFilePuts(fp, value)) < 0) + return (-1); + else + bytes += temp; + } + + if (cupsFilePutChar(fp, '\n') < 0) + return (-1); + else + return (bytes + 1); +} + + /* * 'cupsFilePuts()' - Write a string. * diff --git a/cups/file.h b/cups/file.h index 805aae3976..770d173a03 100644 --- a/cups/file.h +++ b/cups/file.h @@ -8,7 +8,7 @@ * our own file functions allows us to provide transparent support of * gzip'd print files, PPD files, etc. * - * Copyright 2007 by Apple Inc. + * Copyright 2007-2008 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -87,6 +87,8 @@ __attribute__ ((__format__ (__printf__, 2, 3))) #endif /* __GNUC__ */ _CUPS_API_1_2; extern int cupsFilePutChar(cups_file_t *fp, int c) _CUPS_API_1_2; +extern ssize_t cupsFilePutConf(cups_file_t *fp, const char *directive, + const char *value) _CUPS_API_1_4; extern int cupsFilePuts(cups_file_t *fp, const char *s) _CUPS_API_1_2; extern ssize_t cupsFileRead(cups_file_t *fp, char *buf, size_t bytes) _CUPS_API_1_2; extern off_t cupsFileRewind(cups_file_t *fp) _CUPS_API_1_2; diff --git a/cups/libcups.exp b/cups/libcups.exp index 4908e8bbc3..92d2f9c91d 100644 --- a/cups/libcups.exp +++ b/cups/libcups.exp @@ -120,6 +120,7 @@ _cupsFileOpenFd _cupsFilePeekChar _cupsFilePrintf _cupsFilePutChar +_cupsFilePutConf _cupsFilePuts _cupsFileRead _cupsFileRewind diff --git a/doc/help/ref-printers-conf.html b/doc/help/ref-printers-conf.html index 33397e8b07..e3fb078404 100644 --- a/doc/help/ref-printers-conf.html +++ b/doc/help/ref-printers-conf.html @@ -37,12 +37,12 @@ active.

The Accepting directive defines the initial state of the printer-is-accepting-jobs attribute. This state -is also set by the accept(8) and -reject(8) commands:

+is also set by the cupsaccept(8) and +cupsreject(8) commands:

-/usr/sbin/accept printername
-/usr/sbin/reject printername
+/usr/sbin/cupsaccept printername
+/usr/sbin/cupsreject printername
 

This directive must appear inside a DefaultPrinter section.

+

CUPS 1.4Filter

+ +

Examples

+ +
+<Printer name>
+  ...
+  Filter mime/type 100 program
+</Printer>
+
+ +

Description

+ +

The Filter directive lists a single filter program as defined +in the printer's PPD file.

+ +

This directive must appear inside a +Printer or +DefaultPrinter section.

+ +

Info

Examples

@@ -482,6 +503,27 @@ HREF="#DefaultPrinter">DefaultPrinter section.

+

CUPS 1.4PreFilter

+ +

Examples

+ +
+<Printer name>
+  ...
+  PreFilter mime/type 100 program
+</Printer>
+
+ +

Description

+ +

The PreFilter directive lists a single pre-filter program as +defined in the printer's PPD file.

+ +

This directive must appear inside a +Printer or +DefaultPrinter section.

+ +

Printer

Examples

@@ -503,6 +545,27 @@ command: +

CUPS 1.4Product

+ +

Examples

+ +
+<Printer name>
+  ...
+  Product Acme PaperWriter
+</Printer>
+
+ +

Description

+ +

The Product directive defines the main product string from the +printer's PPD file and is used when advertising the queue via DNS-SD.

+ +

This directive must appear inside a +Printer or +DefaultPrinter section.

+ +

QuotaPeriod

Examples

diff --git a/scheduler/classes.c b/scheduler/classes.c index 07b3381385..5bc4783d5b 100644 --- a/scheduler/classes.c +++ b/scheduler/classes.c @@ -674,14 +674,14 @@ void cupsdSaveAllClasses(void) { cups_file_t *fp; /* classes.conf file */ - char temp[1024]; /* Temporary string */ - char backup[1024]; /* classes.conf.O file */ + char temp[1024], /* Temporary string */ + backup[1024], /* printers.conf.O file */ + value[2048]; /* Value string */ cupsd_printer_t *pclass; /* Current printer class */ int i; /* Looping var */ time_t curtime; /* Current time */ struct tm *curdate; /* Current date */ cups_option_t *option; /* Current option */ - const char *ptr; /* Pointer into info/location */ /* @@ -757,53 +757,38 @@ cupsdSaveAllClasses(void) if (pclass->num_auth_info_required > 0) { - cupsFilePrintf(fp, "AuthInfoRequired %s", pclass->auth_info_required[0]); - for (i = 1; i < pclass->num_auth_info_required; i ++) - cupsFilePrintf(fp, ",%s", pclass->auth_info_required[i]); - cupsFilePutChar(fp, '\n'); - } - - if (pclass->info) - { - if ((ptr = strchr(pclass->info, '#')) != NULL) + switch (pclass->num_auth_info_required) { - /* - * Need to quote the first # in the info string... - */ - - cupsFilePuts(fp, "Info "); - cupsFileWrite(fp, pclass->info, ptr - pclass->info); - cupsFilePutChar(fp, '\\'); - cupsFilePuts(fp, ptr); - cupsFilePutChar(fp, '\n'); + case 1 : + strlcpy(value, pclass->auth_info_required[0], sizeof(value)); + break; + + case 2 : + snprintf(value, sizeof(value), "%s,%s", + pclass->auth_info_required[0], + pclass->auth_info_required[1]); + break; + + case 3 : + default : + snprintf(value, sizeof(value), "%s,%s,%s", + pclass->auth_info_required[0], + pclass->auth_info_required[1], + pclass->auth_info_required[2]); + break; } - else - cupsFilePrintf(fp, "Info %s\n", pclass->info); + + cupsFilePutConf(fp, "AuthInfoRequired", value); } - if (pclass->location) - { - if ((ptr = strchr(pclass->info, '#')) != NULL) - { - /* - * Need to quote the first # in the location string... - */ + if (pclass->info) + cupsFilePutConf(fp, "Info", pclass->info); - cupsFilePuts(fp, "Location "); - cupsFileWrite(fp, pclass->location, ptr - pclass->location); - cupsFilePutChar(fp, '\\'); - cupsFilePuts(fp, ptr); - cupsFilePutChar(fp, '\n'); - } - else - cupsFilePrintf(fp, "Location %s\n", pclass->location); - } + if (pclass->location) + cupsFilePutConf(fp, "Location", pclass->location); if (pclass->state == IPP_PRINTER_STOPPED) - { cupsFilePuts(fp, "State Stopped\n"); - cupsFilePrintf(fp, "StateMessage %s\n", pclass->state_message); - } else cupsFilePuts(fp, "State Idle\n"); @@ -819,46 +804,30 @@ cupsdSaveAllClasses(void) else cupsFilePuts(fp, "Shared No\n"); - cupsFilePrintf(fp, "JobSheets %s %s\n", pclass->job_sheets[0], - pclass->job_sheets[1]); - - for (i = 0; i < pclass->num_users; i ++) - { - if ((ptr = strchr(pclass->users[i], '#')) != NULL) - { - /* - * Need to quote the first # in the user string... - */ - - cupsFilePrintf(fp, "%sUser ", pclass->deny_users ? "Deny" : "Allow"); - cupsFileWrite(fp, pclass->users[i], ptr - pclass->users[i]); - cupsFilePutChar(fp, '\\'); - cupsFilePuts(fp, ptr); - cupsFilePutChar(fp, '\n'); - } - else - cupsFilePrintf(fp, "%sUser %s\n", - pclass->deny_users ? "Deny" : "Allow", - pclass->users[i]); - } + snprintf(value, sizeof(value), "%s %s", pclass->job_sheets[0], + pclass->job_sheets[1]); + cupsFilePutConf(fp, "JobSheets", value); cupsFilePrintf(fp, "QuotaPeriod %d\n", pclass->quota_period); cupsFilePrintf(fp, "PageLimit %d\n", pclass->page_limit); cupsFilePrintf(fp, "KLimit %d\n", pclass->k_limit); for (i = 0; i < pclass->num_users; i ++) - cupsFilePrintf(fp, "%sUser %s\n", pclass->deny_users ? "Deny" : "Allow", - pclass->users[i]); + cupsFilePutConf(fp, pclass->deny_users ? "DenyUser" : "AllowUser", + pclass->users[i]); - if (pclass->op_policy) - cupsFilePrintf(fp, "OpPolicy %s\n", pclass->op_policy); + if (pclass->op_policy) + cupsFilePutConf(fp, "OpPolicy", pclass->op_policy); if (pclass->error_policy) - cupsFilePrintf(fp, "ErrorPolicy %s\n", pclass->error_policy); + cupsFilePutConf(fp, "ErrorPolicy", pclass->error_policy); for (i = pclass->num_options, option = pclass->options; i > 0; i --, option ++) - cupsFilePrintf(fp, "Option %s %s\n", option->name, option->value); + { + snprintf(value, sizeof(value), "%s %s", option->name, option->value); + cupsFilePutConf(fp, "Option", value); + } cupsFilePuts(fp, "\n"); } diff --git a/scheduler/cupsd.h b/scheduler/cupsd.h index 6f83204004..6093eb3d5d 100644 --- a/scheduler/cupsd.h +++ b/scheduler/cupsd.h @@ -3,7 +3,7 @@ * * Main header file for the Common UNIX Printing System (CUPS) scheduler. * - * Copyright 2007 by Apple Inc. + * Copyright 2007-2008 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -235,6 +235,7 @@ extern void cupsdStopSelect(void); extern int cupsdRemoveFile(const char *filename); + /* * End of "$Id$". */ diff --git a/scheduler/dirsvc.c b/scheduler/dirsvc.c index bd8228d5c3..2894d7969d 100644 --- a/scheduler/dirsvc.c +++ b/scheduler/dirsvc.c @@ -696,7 +696,8 @@ cupsdSaveRemoteCache(void) { int i; /* Looping var */ cups_file_t *fp; /* printers.conf file */ - char temp[1024]; /* Temporary string */ + char temp[1024], /* Temporary string */ + value[2048]; /* Value string */ cupsd_printer_t *printer; /* Current printer class */ time_t curtime; /* Current time */ struct tm *curdate; /* Current date */ @@ -765,48 +766,49 @@ cupsdSaveRemoteCache(void) else cupsFilePrintf(fp, "Printer %s>\n", printer->name); - cupsFilePrintf(fp, "Type %d\n", printer->type); - cupsFilePrintf(fp, "BrowseTime %d\n", (int)printer->browse_expire); if (printer->info) - cupsFilePrintf(fp, "Info %s\n", printer->info); - - if (printer->make_model) - cupsFilePrintf(fp, "MakeModel %s\n", printer->make_model); + cupsFilePutConf(fp, "Info", printer->info); if (printer->location) - cupsFilePrintf(fp, "Location %s\n", printer->location); + cupsFilePutConf(fp, "Location", printer->location); + + if (printer->make_model) + cupsFilePutConf(fp, "MakeModel", printer->make_model); - cupsFilePrintf(fp, "DeviceURI %s\n", printer->device_uri); + cupsFilePutConf(fp, "DeviceURI", printer->device_uri); if (printer->state == IPP_PRINTER_STOPPED) - { cupsFilePuts(fp, "State Stopped\n"); - cupsFilePrintf(fp, "StateMessage %s\n", printer->state_message); - } else cupsFilePuts(fp, "State Idle\n"); for (i = 0; i < printer->num_reasons; i ++) - cupsFilePrintf(fp, "Reason %s\n", printer->reasons[i]); + cupsFilePutConf(fp, "Reason", printer->reasons[i]); + + cupsFilePrintf(fp, "Type %d\n", printer->type); if (printer->accepting) cupsFilePuts(fp, "Accepting Yes\n"); else cupsFilePuts(fp, "Accepting No\n"); - cupsFilePrintf(fp, "JobSheets %s %s\n", printer->job_sheets[0], - printer->job_sheets[1]); + snprintf(value, sizeof(value), "%s %s", printer->job_sheets[0], + printer->job_sheets[1]); + cupsFilePutConf(fp, "JobSheets", value); for (i = 0; i < printer->num_users; i ++) - cupsFilePrintf(fp, "%sUser %s\n", printer->deny_users ? "Deny" : "Allow", - printer->users[i]); + cupsFilePutConf(fp, printer->deny_users ? "DenyUser" : "AllowUser", + printer->users[i]); for (i = printer->num_options, option = printer->options; i > 0; i --, option ++) - cupsFilePrintf(fp, "Option %s %s\n", option->name, option->value); + { + snprintf(value, sizeof(value), "%s %s", option->name, option->value); + cupsFilePutConf(fp, "Option", value); + } if (printer->type & CUPS_PRINTER_CLASS) cupsFilePuts(fp, "\n"); diff --git a/scheduler/printers.c b/scheduler/printers.c index 681a4c0d78..492c5a88cd 100644 --- a/scheduler/printers.c +++ b/scheduler/printers.c @@ -1005,6 +1005,11 @@ cupsdLoadAllPrinters(void) if (value) cupsdSetString(&p->info, value); } + else if (!strcasecmp(line, "MakeModel")) + { + if (value) + cupsdSetString(&p->make_model, value); + } else if (!strcasecmp(line, "Location")) { if (value) @@ -1111,6 +1116,52 @@ cupsdLoadAllPrinters(void) cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of printers.conf.", linenum); } + else if (!strcasecmp(line, "Type")) + { + if (value) + p->type = atoi(value); + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "Product")) + { + if (value) + { +#ifdef HAVE_DNSSD + p->product = _cupsStrAlloc(value); +#endif /* HAVE_DNSSD */ + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "Filter")) + { + if (value) + { + if (!p->filters) + p->filters = cupsArrayNew(NULL, NULL); + + cupsArrayAdd(p->filters, _cupsStrAlloc(value)); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "PreFilter")) + { + if (value) + { + if (!p->pre_filters) + p->pre_filters = cupsArrayNew(NULL, NULL); + + cupsArrayAdd(p->pre_filters, _cupsStrAlloc(value)); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } else if (!strcasecmp(line, "Shared")) { /* @@ -1349,13 +1400,14 @@ cupsdSaveAllPrinters(void) { int i; /* Looping var */ cups_file_t *fp; /* printers.conf file */ - char temp[1024]; /* Temporary string */ - char backup[1024]; /* printers.conf.O file */ + char temp[1024], /* Temporary string */ + backup[1024], /* printers.conf.O file */ + value[2048], /* Value string */ + *ptr; /* Pointer into value */ cupsd_printer_t *printer; /* Current printer class */ time_t curtime; /* Current time */ struct tm *curdate; /* Current date */ cups_option_t *option; /* Current option */ - const char *ptr; /* Pointer into info/location */ ipp_attribute_t *marker; /* Current marker attribute */ @@ -1432,56 +1484,50 @@ cupsdSaveAllPrinters(void) if (printer->num_auth_info_required > 0) { - cupsFilePrintf(fp, "AuthInfoRequired %s", printer->auth_info_required[0]); - for (i = 1; i < printer->num_auth_info_required; i ++) - cupsFilePrintf(fp, ",%s", printer->auth_info_required[i]); - cupsFilePutChar(fp, '\n'); - } - - if (printer->info) - { - if ((ptr = strchr(printer->info, '#')) != NULL) + switch (printer->num_auth_info_required) { - /* - * Need to quote the first # in the info string... - */ - - cupsFilePuts(fp, "Info "); - cupsFileWrite(fp, printer->info, ptr - printer->info); - cupsFilePutChar(fp, '\\'); - cupsFilePuts(fp, ptr); - cupsFilePutChar(fp, '\n'); + case 1 : + strlcpy(value, printer->auth_info_required[0], sizeof(value)); + break; + + case 2 : + snprintf(value, sizeof(value), "%s,%s", + printer->auth_info_required[0], + printer->auth_info_required[1]); + break; + + case 3 : + default : + snprintf(value, sizeof(value), "%s,%s,%s", + printer->auth_info_required[0], + printer->auth_info_required[1], + printer->auth_info_required[2]); + break; } - else - cupsFilePrintf(fp, "Info %s\n", printer->info); + + cupsFilePutConf(fp, "AuthInfoRequired", value); } + if (printer->info) + cupsFilePutConf(fp, "Info", printer->info); + if (printer->location) - { - if ((ptr = strchr(printer->info, '#')) != NULL) - { - /* - * Need to quote the first # in the location string... - */ + cupsFilePutConf(fp, "Location", printer->location); - cupsFilePuts(fp, "Location "); - cupsFileWrite(fp, printer->location, ptr - printer->location); - cupsFilePutChar(fp, '\\'); - cupsFilePuts(fp, ptr); - cupsFilePutChar(fp, '\n'); - } - else - cupsFilePrintf(fp, "Location %s\n", printer->location); - } - cupsFilePrintf(fp, "DeviceURI %s\n", printer->device_uri); + if (printer->make_model) + cupsFilePutConf(fp, "MakeModel", printer->make_model); + + cupsFilePutConf(fp, "DeviceURI", printer->device_uri); if (printer->port_monitor) - cupsFilePrintf(fp, "PortMonitor %s\n", printer->port_monitor); + cupsFilePutConf(fp, "PortMonitor", printer->port_monitor); if (printer->state == IPP_PRINTER_STOPPED) { cupsFilePuts(fp, "State Stopped\n"); - cupsFilePrintf(fp, "StateMessage %s\n", printer->state_message); + + if (printer->state_message) + cupsFilePutConf(fp, "StateMessage", printer->state_message); } else cupsFilePuts(fp, "State Idle\n"); @@ -1489,7 +1535,24 @@ cupsdSaveAllPrinters(void) cupsFilePrintf(fp, "StateTime %d\n", (int)printer->state_time); for (i = 0; i < printer->num_reasons; i ++) - cupsFilePrintf(fp, "Reason %s\n", printer->reasons[i]); + cupsFilePutConf(fp, "Reason", printer->reasons[i]); + + cupsFilePrintf(fp, "Type %d", printer->type); + +#ifdef HAVE_DNSSD + if (printer->product) + cupsFilePutConf(fp, "Product", printer->product); +#endif /* HAVE_DNSSD */ + + for (ptr = (char *)cupsArrayFirst(printer->filters); + ptr; + ptr = (char *)cupsArrayNext(printer->filters)) + cupsFilePutConf(fp, "Filter", ptr); + + for (ptr = (char *)cupsArrayFirst(printer->pre_filters); + ptr; + ptr = (char *)cupsArrayNext(printer->pre_filters)) + cupsFilePutConf(fp, "PreFilter", ptr); if (printer->accepting) cupsFilePuts(fp, "Accepting Yes\n"); @@ -1501,80 +1564,50 @@ cupsdSaveAllPrinters(void) else cupsFilePuts(fp, "Shared No\n"); - cupsFilePrintf(fp, "JobSheets %s %s\n", printer->job_sheets[0], - printer->job_sheets[1]); + snprintf(value, sizeof(value), "%s %s", printer->job_sheets[0], + printer->job_sheets[1]); + cupsFilePutConf(fp, "JobSheets", value); cupsFilePrintf(fp, "QuotaPeriod %d\n", printer->quota_period); cupsFilePrintf(fp, "PageLimit %d\n", printer->page_limit); cupsFilePrintf(fp, "KLimit %d\n", printer->k_limit); for (i = 0; i < printer->num_users; i ++) - { - if ((ptr = strchr(printer->users[i], '#')) != NULL) - { - /* - * Need to quote the first # in the user string... - */ - - cupsFilePrintf(fp, "%sUser ", printer->deny_users ? "Deny" : "Allow"); - cupsFileWrite(fp, printer->users[i], ptr - printer->users[i]); - cupsFilePutChar(fp, '\\'); - cupsFilePuts(fp, ptr); - cupsFilePutChar(fp, '\n'); - } - else - cupsFilePrintf(fp, "%sUser %s\n", - printer->deny_users ? "Deny" : "Allow", - printer->users[i]); - } + cupsFilePutConf(fp, printer->deny_users ? "DenyUser" : "AllowUser", + printer->users[i]); if (printer->op_policy) - cupsFilePrintf(fp, "OpPolicy %s\n", printer->op_policy); + cupsFilePutConf(fp, "OpPolicy", printer->op_policy); if (printer->error_policy) - cupsFilePrintf(fp, "ErrorPolicy %s\n", printer->error_policy); + cupsFilePutConf(fp, "ErrorPolicy", printer->error_policy); for (i = printer->num_options, option = printer->options; i > 0; i --, option ++) { - if ((ptr = strchr(option->value, '#')) != NULL) - { - /* - * Need to quote the first # in the option string... - */ - - cupsFilePrintf(fp, "Option %s ", option->name); - cupsFileWrite(fp, option->value, ptr - option->value); - cupsFilePutChar(fp, '\\'); - cupsFilePuts(fp, ptr); - cupsFilePutChar(fp, '\n'); - } - else - cupsFilePrintf(fp, "Option %s %s\n", option->name, option->value); + snprintf(value, sizeof(value), "%s %s", option->name, option->value); + cupsFilePutConf(fp, "Option", value); } if ((marker = ippFindAttribute(printer->attrs, "marker-colors", IPP_TAG_NAME)) != NULL) { - cupsFilePrintf(fp, "Attribute %s ", marker->name); + snprintf(value, sizeof(value), "%s ", marker->name); - for (i = 0, ptr = NULL; i < marker->num_values; i ++) + for (i = 0, ptr = value + strlen(value); + i < marker->num_values && ptr < (value + sizeof(value) - 1); + i ++) { if (i) - cupsFilePutChar(fp, ','); + *ptr++ = ','; - if (!ptr && (ptr = strchr(marker->values[i].string.text, '#')) != NULL) - { - cupsFileWrite(fp, marker->values[i].string.text, - ptr - marker->values[i].string.text); - cupsFilePutChar(fp, '\\'); - cupsFilePuts(fp, ptr); - } - else - cupsFilePuts(fp, marker->values[i].string.text); + strlcpy(ptr, marker->values[i].string.text, + value + sizeof(value) - ptr); + ptr += strlen(ptr); } - cupsFilePuts(fp, "\n"); + *ptr = '\0'; + cupsFilePutConf(fp, "Attribute", value); } if ((marker = ippFindAttribute(printer->attrs, "marker-levels", @@ -1590,67 +1623,52 @@ cupsdSaveAllPrinters(void) if ((marker = ippFindAttribute(printer->attrs, "marker-message", IPP_TAG_TEXT)) != NULL) { - cupsFilePrintf(fp, "Attribute %s ", marker->name); + snprintf(value, sizeof(value), "%s %s", marker->name, + marker->values[0].string.text); - if ((ptr = strchr(marker->values[0].string.text, '#')) != NULL) - { - cupsFileWrite(fp, marker->values[0].string.text, - ptr - marker->values[0].string.text); - cupsFilePutChar(fp, '\\'); - cupsFilePuts(fp, ptr); - } - else - cupsFilePuts(fp, marker->values[0].string.text); - - cupsFilePuts(fp, "\n"); + cupsFilePutConf(fp, "Attribute", value); } if ((marker = ippFindAttribute(printer->attrs, "marker-names", IPP_TAG_NAME)) != NULL) { - cupsFilePrintf(fp, "Attribute %s ", marker->name); + snprintf(value, sizeof(value), "%s ", marker->name); - for (i = 0, ptr = NULL; i < marker->num_values; i ++) + for (i = 0, ptr = value + strlen(value); + i < marker->num_values && ptr < (value + sizeof(value) - 1); + i ++) { if (i) - cupsFilePutChar(fp, ','); + *ptr++ = ','; - if (!ptr && (ptr = strchr(marker->values[i].string.text, '#')) != NULL) - { - cupsFileWrite(fp, marker->values[i].string.text, - ptr - marker->values[i].string.text); - cupsFilePutChar(fp, '\\'); - cupsFilePuts(fp, ptr); - } - else - cupsFilePuts(fp, marker->values[i].string.text); + strlcpy(ptr, marker->values[i].string.text, + value + sizeof(value) - ptr); + ptr += strlen(ptr); } - cupsFilePuts(fp, "\n"); + *ptr = '\0'; + cupsFilePutConf(fp, "Attribute", value); } if ((marker = ippFindAttribute(printer->attrs, "marker-types", IPP_TAG_KEYWORD)) != NULL) { - cupsFilePrintf(fp, "Attribute %s ", marker->name); + snprintf(value, sizeof(value), "%s ", marker->name); - for (i = 0, ptr = NULL; i < marker->num_values; i ++) + for (i = 0, ptr = value + strlen(value); + i < marker->num_values && ptr < (value + sizeof(value) - 1); + i ++) { if (i) - cupsFilePutChar(fp, ','); + *ptr++ = ','; - if (!ptr && (ptr = strchr(marker->values[i].string.text, '#')) != NULL) - { - cupsFileWrite(fp, marker->values[i].string.text, - ptr - marker->values[i].string.text); - cupsFilePutChar(fp, '\\'); - cupsFilePuts(fp, ptr); - } - else - cupsFilePuts(fp, marker->values[i].string.text); + strlcpy(ptr, marker->values[i].string.text, + value + sizeof(value) - ptr); + ptr += strlen(ptr); } - cupsFilePuts(fp, "\n"); + *ptr = '\0'; + cupsFilePutConf(fp, "Attribute", value); } cupsFilePuts(fp, "\n"); diff --git a/scheduler/printers.h b/scheduler/printers.h index 3f76edc722..1c4b49f002 100644 --- a/scheduler/printers.h +++ b/scheduler/printers.h @@ -88,6 +88,8 @@ typedef struct cupsd_printer_s char *alert, /* PSX printer-alert value */ *alert_description; /* PSX printer-alert-description value */ time_t marker_time; /* Last time marker attributes were updated */ + cups_array_t *filters, /* Filters for queue */ + *pre_filters; /* Pre-filters for queue */ #ifdef __APPLE__ char *recoverable; /* com.apple.print.recoverable-message */ -- 2.47.2