/*
- * "$Id: printers.c 6970 2007-09-17 23:58:28Z mike $"
+ * "$Id: printers.c 7608 2008-05-21 01:37:21Z mike $"
*
* Printer routines for the Common UNIX Printing System (CUPS).
*
break;
}
}
+ else if (!strcasecmp(line, "Attribute") && value)
+ {
+ for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
+
+ if (!*valueptr)
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Syntax error on line %d of printers.conf.", linenum);
+ else
+ {
+ for (; *valueptr && isspace(*valueptr & 255); *valueptr++ = '\0');
+
+ if (!p->attrs)
+ cupsdSetPrinterAttrs(p);
+
+ cupsdSetPrinterAttr(p, value, valueptr);
+
+ if (!strncmp(value, "marker-", 7))
+ p->marker_time = time(NULL);
+ }
+ }
else
{
/*
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 */
/*
cupsFilePrintf(fp, "KLimit %d\n", printer->k_limit);
for (i = 0; i < printer->num_users; i ++)
- cupsFilePrintf(fp, "%sUser %s\n", printer->deny_users ? "Deny" : "Allow",
- printer->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]);
+ }
if (printer->op_policy)
cupsFilePrintf(fp, "OpPolicy %s\n", printer->op_policy);
for (i = printer->num_options, option = printer->options;
i > 0;
i --, option ++)
- cupsFilePrintf(fp, "Option %s %s\n", option->name, option->value);
+ {
+ 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);
+ }
+
+ if ((marker = ippFindAttribute(printer->attrs, "marker-colors",
+ IPP_TAG_NAME)) != NULL)
+ {
+ cupsFilePrintf(fp, "Attribute %s ", marker->name);
+
+ for (i = 0, ptr = NULL; i < marker->num_values; i ++)
+ {
+ if (i)
+ cupsFilePutChar(fp, ',');
+
+ 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);
+ }
+
+ cupsFilePuts(fp, "\n");
+ }
+
+ if ((marker = ippFindAttribute(printer->attrs, "marker-levels",
+ IPP_TAG_INTEGER)) != NULL)
+ {
+ cupsFilePrintf(fp, "Attribute %s %d", marker->name,
+ marker->values[0].integer);
+ for (i = 1; i < marker->num_values; i ++)
+ cupsFilePrintf(fp, ",%d", marker->values[i].integer);
+ cupsFilePuts(fp, "\n");
+ }
+
+ if ((marker = ippFindAttribute(printer->attrs, "marker-names",
+ IPP_TAG_NAME)) != NULL)
+ {
+ cupsFilePrintf(fp, "Attribute %s ", marker->name);
+
+ for (i = 0, ptr = NULL; i < marker->num_values; i ++)
+ {
+ if (i)
+ cupsFilePutChar(fp, ',');
+
+ 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);
+ }
+
+ cupsFilePuts(fp, "\n");
+ }
+
+ if ((marker = ippFindAttribute(printer->attrs, "marker-types",
+ IPP_TAG_KEYWORD)) != NULL)
+ {
+ cupsFilePrintf(fp, "Attribute %s ", marker->name);
+
+ for (i = 0, ptr = NULL; i < marker->num_values; i ++)
+ {
+ if (i)
+ cupsFilePutChar(fp, ',');
+
+ 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);
+ }
+
+ cupsFilePuts(fp, "\n");
+ }
cupsFilePuts(fp, "</Printer>\n");
value = ptr;
}
}
+
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
}
*media_quality, /* EFMediaQualityMode options */
*duplex; /* Duplex options */
ppd_attr_t *ppdattr; /* PPD attribute */
+ ipp_t *oldattrs; /* Old printer attributes */
ipp_attribute_t *attr; /* Attribute data */
ipp_value_t *val; /* Attribute value */
int num_finishings; /* Number of finishings */
{ /* No authentication */
"none"
};
+ static const char * const standard_commands[] =
+ { /* Standard CUPS commands */
+ "AutoConfigure",
+ "Clean",
+ "PrintSelfTestPage",
+ "ReportLevels"
+ };
DEBUG_printf(("cupsdSetPrinterAttrs: entering name = %s, type = %x\n", p->name,
* Create the required IPP attributes for a printer...
*/
- if (p->attrs)
- ippDelete(p->attrs);
-
+ oldattrs = p->attrs;
p->attrs = ippNew();
ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
p->type |= CUPS_PRINTER_COMMANDS;
}
+ else if (!(p->type & CUPS_PRINTER_COMMANDS))
+ {
+ /*
+ * See if this is a PostScript device without a command filter...
+ */
+
+ for (i = 0; i < ppd->num_filters; i ++)
+ if (!strncasecmp(ppd->filters[i],
+ "application/vnd.cups-postscript", 31))
+ break;
+
+ if (i < ppd->num_filters)
+ {
+ /*
+ * Add the generic PostScript command filter...
+ */
+
+ add_printer_filter(p, p->filetype,
+ "application/vnd.cups-command 0 commandtops");
+ p->type |= CUPS_PRINTER_COMMANDS;
+ }
+ }
+
+ if (p->type & CUPS_PRINTER_COMMANDS)
+ {
+ char *commands, /* Copy of commands */
+ *start, /* Start of name */
+ *end; /* End of name */
+ int count; /* Number of commands */
+
+
+ if ((ppdattr = ppdFindAttr(ppd, "cupsCommands", NULL)) != NULL &&
+ ppdattr->value && ppdattr->value[0])
+ {
+ for (count = 0, start = ppdattr->value; *start; count ++)
+ {
+ while (isspace(*start & 255))
+ start ++;
+
+ if (!*start)
+ break;
+
+ while (*start && !isspace(*start & 255))
+ start ++;
+ }
+ }
+ else
+ count = 0;
+
+ if (count > 0)
+ {
+ /*
+ * Make a copy of the commands string and count how many ...
+ */
+
+ attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "printer-commands", count, NULL, NULL);
+
+ commands = strdup(ppdattr->value);
+
+ for (count = 0, start = commands; *start; count ++)
+ {
+ while (isspace(*start & 255))
+ start ++;
+
+ if (!*start)
+ break;
+
+ end = start;
+ while (*end && !isspace(*end & 255))
+ end ++;
+
+ if (*end)
+ *end++ = '\0';
+
+ attr->values[count].string.text = _cupsStrAlloc(start);
+
+ start = end;
+ }
+
+ free(commands);
+ }
+ else
+ {
+ /*
+ * Add the standard list of commands...
+ */
+
+ ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "printer-commands",
+ (int)(sizeof(standard_commands) /
+ sizeof(standard_commands[0])), NULL,
+ standard_commands);
+ }
+ }
+ else
+ {
+ /*
+ * No commands supported...
+ */
+
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "printer-commands", NULL, "none");
+ }
/*
* Show current and available port monitors for this printer...
}
}
+ /*
+ * Copy marker attributes as needed...
+ */
+
+ if (oldattrs)
+ {
+ ipp_attribute_t *oldattr; /* Old attribute */
+
+
+ if ((oldattr = ippFindAttribute(oldattrs, "marker-colors",
+ IPP_TAG_NAME)) != NULL)
+ {
+ if ((attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "marker-colors", oldattr->num_values, NULL,
+ NULL)) != NULL)
+ {
+ for (i = 0; i < oldattr->num_values; i ++)
+ attr->values[i].string.text =
+ _cupsStrAlloc(oldattr->values[i].string.text);
+ }
+ }
+
+ if ((oldattr = ippFindAttribute(oldattrs, "marker-levels",
+ IPP_TAG_INTEGER)) != NULL)
+ {
+ if ((attr = ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "marker-levels", oldattr->num_values,
+ NULL)) != NULL)
+ {
+ for (i = 0; i < oldattr->num_values; i ++)
+ attr->values[i].integer = oldattr->values[i].integer;
+ }
+ }
+
+ if ((oldattr = ippFindAttribute(oldattrs, "marker-names",
+ IPP_TAG_NAME)) != NULL)
+ {
+ if ((attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "marker-names", oldattr->num_values, NULL,
+ NULL)) != NULL)
+ {
+ for (i = 0; i < oldattr->num_values; i ++)
+ attr->values[i].string.text =
+ _cupsStrAlloc(oldattr->values[i].string.text);
+ }
+ }
+
+ if ((oldattr = ippFindAttribute(oldattrs, "marker-types",
+ IPP_TAG_KEYWORD)) != NULL)
+ {
+ if ((attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "marker-types", oldattr->num_values, NULL,
+ NULL)) != NULL)
+ {
+ for (i = 0; i < oldattr->num_values; i ++)
+ attr->values[i].string.text =
+ _cupsStrAlloc(oldattr->values[i].string.text);
+ }
+ }
+
+ ippDelete(oldattrs);
+ }
+
/*
* Force sharing off for remote queues...
*/
/*
- * End of "$Id: printers.c 6970 2007-09-17 23:58:28Z mike $".
+ * End of "$Id: printers.c 7608 2008-05-21 01:37:21Z mike $".
*/