/*
- * "$Id: printers.c 6318 2007-03-06 04:36:55Z mike $"
+ * "$Id: printers.c 6970 2007-09-17 23:58:28Z mike $"
*
* Printer routines for the Common UNIX Printing System (CUPS).
*
+ * 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
- * property of Easy Software Products and are protected by Federal
- * copyright law. Distribution and use rights are outlined in the file
- * "LICENSE.txt" which should have been included with this file. If this
- * file is missing or damaged please contact Easy Software Products
- * at:
- *
- * Attn: CUPS Licensing Information
- * Easy Software Products
- * 44141 Airport View Drive, Suite 204
- * Hollywood, Maryland 20636 USA
- *
- * Voice: (301) 373-9600
- * EMail: cups-info@cups.org
- * WWW: http://www.cups.org
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*
* Contents:
*
* cupsdAddPrinter() - Add a printer to the system.
* cupsdAddPrinterHistory() - Add the current printer state to the history.
* cupsdAddPrinterUser() - Add a user to the ACL.
+ * cupsdCreateCommonData() - Create the common printer data.
* cupsdDeleteAllPrinters() - Delete all printers from the system.
* cupsdDeletePrinter() - Delete a printer from the system.
* cupsdFindPrinter() - Find a printer in the list.
* cupsdRenamePrinter() - Rename a printer.
* cupsdSaveAllPrinters() - Save all printer definitions to the
* printers.conf file.
+ * cupsdSetAuthInfoRequired() - Set the required authentication info.
* cupsdSetPrinterAttrs() - Set printer attributes based upon the PPD
* file.
* cupsdSetPrinterReasons() - Set/update the reasons strings.
cupsdSetString(&p->job_sheets[0], "none");
cupsdSetString(&p->job_sheets[1], "none");
- cupsdSetString(&p->error_policy, "stop-printer");
+ cupsdSetString(&p->error_policy, ErrorPolicy);
cupsdSetString(&p->op_policy, DefaultPolicy);
p->op_policy_ptr = DefaultPolicyPtr;
cups_array_t *notifiers; /* Notifier array */
char filename[1024], /* Filename */
*notifier; /* Current notifier */
+ cupsd_policy_t *p; /* Current policy */
static const int nups[] = /* number-up-supported values */
{ 1, 2, 4, 6, 9, 16 };
- static const ipp_orient_t orients[4] =/* orientation-requested-supported values */
+ static const int orients[4] =/* orientation-requested-supported values */
{
IPP_PORTRAIT,
IPP_LANDSCAPE,
"1.0",
"1.1"
};
- static const ipp_op_t ops[] = /* operations-supported values */
+ static const int ops[] = /* operations-supported values */
{
IPP_PRINT_JOB,
IPP_VALIDATE_JOB,
CUPS_GET_PPDS,
CUPS_MOVE_JOB,
CUPS_AUTHENTICATE_JOB,
+ CUPS_GET_PPD,
+ CUPS_GET_DOCUMENT,
IPP_RESTART_JOB
};
static const char * const charsets[] =/* charset-supported values */
/* copies-supported */
ippAddRange(CommonData, IPP_TAG_PRINTER, "copies-supported", 1, MaxCopies);
+ /* cups-version */
+ ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_TEXT, "cups-version",
+ NULL, CUPS_SVERSION + 6);
+
/* generated-natural-language-supported */
ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
"generated-natural-language-supported", NULL, DefaultLanguage);
/* operations-supported */
ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_ENUM,
"operations-supported",
- sizeof(ops) / sizeof(ops[0]) + JobFiles - 1, (int *)ops);
+ sizeof(ops) / sizeof(ops[0]) + JobFiles - 1, ops);
/* orientation-requested-supported */
ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_ENUM,
- "orientation-requested-supported", 4, (int *)orients);
+ "orientation-requested-supported", 4, orients);
/* page-ranges-supported */
ippAddBoolean(CommonData, IPP_TAG_PRINTER, "page-ranges-supported", 1);
/* printer-op-policy-supported */
attr = ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_NAME,
- "printer-op-policy-supported", NumPolicies, NULL, NULL);
- for (i = 0; i < NumPolicies; i ++)
- attr->values[i].string.text = _cupsStrAlloc(Policies[i]->name);
+ "printer-op-policy-supported", cupsArrayCount(Policies),
+ NULL, NULL);
+ for (i = 0, p = (cupsd_policy_t *)cupsArrayFirst(Policies);
+ p;
+ i ++, p = (cupsd_policy_t *)cupsArrayNext(Policies))
+ attr->values[i].string.text = _cupsStrAlloc(p->name);
+
+ ippAddBoolean(CommonData, IPP_TAG_PRINTER, "server-is-sharing-printers",
+ BrowseLocalProtocols != 0 && Browsing);
}
cupsdClearString(&p->op_policy);
cupsdClearString(&p->error_policy);
+ cupsdClearString(&p->alert);
+ cupsdClearString(&p->alert_description);
+
#ifdef HAVE_DNSSD
cupsdClearString(&p->product);
cupsdClearString(&p->pdl);
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- return;
+ break;
}
}
else if (!strcasecmp(line, "</Printer>"))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- return;
+ break;
}
}
else if (!p)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- return;
+ break;
}
else if (!strcasecmp(line, "AuthInfoRequired"))
{
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- return;
+ break;
}
}
else if (!strcasecmp(line, "Option") && value)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- return;
+ break;
}
}
else if (!strcasecmp(line, "State"))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- return;
+ break;
}
}
else if (!strcasecmp(line, "StateMessage"))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- return;
+ break;
}
}
else if (!strcasecmp(line, "Shared"))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- return;
+ break;
}
}
else if (!strcasecmp(line, "JobSheets"))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- return;
+ break;
}
}
else if (!strcasecmp(line, "AllowUser"))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- return;
+ break;
}
}
else if (!strcasecmp(line, "DenyUser"))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- return;
+ break;
}
}
else if (!strcasecmp(line, "QuotaPeriod"))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- return;
+ break;
}
}
else if (!strcasecmp(line, "PageLimit"))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- return;
+ break;
}
}
else if (!strcasecmp(line, "KLimit"))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- return;
+ break;
}
}
else if (!strcasecmp(line, "OpPolicy"))
{
if (value)
- cupsdSetString(&p->op_policy, value);
+ {
+ cupsd_policy_t *pol; /* Policy */
+
+
+ if ((pol = cupsdFindPolicy(value)) != NULL)
+ {
+ cupsdSetString(&p->op_policy, value);
+ p->op_policy_ptr = pol;
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Bad policy \"%s\" on line %d of printers.conf",
+ value, linenum);
+ }
else
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- return;
+ break;
}
}
else if (!strcasecmp(line, "ErrorPolicy"))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- return;
+ break;
}
}
else
* Skip remote destinations and printer classes...
*/
- if ((printer->type & CUPS_PRINTER_REMOTE) ||
+ if ((printer->type & CUPS_PRINTER_DISCOVERED) ||
(printer->type & CUPS_PRINTER_CLASS) ||
(printer->type & CUPS_PRINTER_IMPLICIT))
continue;
if ((end = strchr(values, ',')) == NULL)
end = values + strlen(values);
- if (!strncmp(values, "none", end - values))
+ if ((end - values) == 4 && !strncmp(values, "none", 4))
{
if (p->num_auth_info_required != 0 || *end)
return (0);
return (1);
}
- else if (!strncmp(values, "domain", end - values))
+ else if ((end - values) == 9 && !strncmp(values, "negotiate", 9))
+ {
+ if (p->num_auth_info_required != 0 || *end)
+ return (0);
+
+ p->auth_info_required[p->num_auth_info_required] = "negotiate";
+ p->num_auth_info_required ++;
+ }
+ else if ((end - values) == 6 && !strncmp(values, "domain", 6))
{
p->auth_info_required[p->num_auth_info_required] = "domain";
p->num_auth_info_required ++;
}
- else if (!strncmp(values, "password", end - values))
+ else if ((end - values) == 8 && !strncmp(values, "password", 8))
{
p->auth_info_required[p->num_auth_info_required] = "password";
p->num_auth_info_required ++;
}
- else if (!strncmp(values, "username", end - values))
+ else if ((end - values) == 8 && !strncmp(values, "username", 8))
{
p->auth_info_required[p->num_auth_info_required] = "username";
p->num_auth_info_required ++;
}
else
return (0);
+
+ values = (*end) ? end + 1 : end;
}
if (p->num_auth_info_required == 0)
p->num_auth_info_required = 1;
}
+ /*
+ * Update the printer-type value as needed...
+ */
+
+ if (p->num_auth_info_required > 1 ||
+ strcmp(p->auth_info_required[0], "none"))
+ p->type |= CUPS_PRINTER_AUTHENTICATED;
+ else
+ p->type &= ~CUPS_PRINTER_AUTHENTICATED;
+
return (1);
}
if (!attr || attr->num_values > 4)
return (0);
+ /*
+ * Update the printer-type value as needed...
+ */
+
+ if (attr->num_values > 1 ||
+ strcmp(attr->values[0].string.text, "none"))
+ p->type |= CUPS_PRINTER_AUTHENTICATED;
+ else
+ p->type &= ~CUPS_PRINTER_AUTHENTICATED;
+
for (i = 0; i < attr->num_values; i ++)
{
if (!strcmp(attr->values[i].string.text, "none"))
return (1);
}
+ else if (!strcmp(attr->values[i].string.text, "negotiate"))
+ {
+ if (p->num_auth_info_required != 0 || attr->num_values != 1)
+ return (0);
+
+ p->auth_info_required[p->num_auth_info_required] = "negotiate";
+ p->num_auth_info_required ++;
+
+ return (1);
+ }
else if (!strcmp(attr->values[i].string.text, "domain"))
{
p->auth_info_required[p->num_auth_info_required] = "domain";
char uri[HTTP_MAX_URI]; /* URI for printer */
char resource[HTTP_MAX_URI]; /* Resource portion of URI */
char filename[1024]; /* Name of PPD file */
+ int num_air; /* Number of auth-info-required values */
+ const char * const *air; /* auth-info-required values */
int num_media; /* Number of media options */
cupsd_location_t *auth; /* Pointer to authentication element */
const char *auth_supported; /* Authentication supported */
- cups_ptype_t printer_type; /* Printer type data */
ppd_file_t *ppd; /* PPD file data */
ppd_option_t *input_slot, /* InputSlot options */
*media_type, /* MediaType options */
ipp_attribute_t *attr; /* Attribute data */
ipp_value_t *val; /* Attribute value */
int num_finishings; /* Number of finishings */
- ipp_finish_t finishings[5]; /* finishings-supported values */
+ int finishings[5]; /* finishings-supported values */
cups_option_t *option; /* Current printer option */
static const char * const sides[3] = /* sides-supported values */
{
"two-sided-long-edge",
"two-sided-short-edge"
};
+ static const char * const air_userpass[] =
+ { /* Basic/Digest authentication */
+ "username",
+ "password"
+ };
+#ifdef HAVE_GSSAPI
+ static const char * const air_negotiate[] =
+ { /* Kerberos authentication */
+ "negotiate"
+ };
+#endif /* HAVE_GSSAPI */
+ static const char * const air_none[] =
+ { /* No authentication */
+ "none"
+ };
DEBUG_printf(("cupsdSetPrinterAttrs: entering name = %s, type = %x\n", p->name,
*/
auth_supported = "requesting-user-name";
- if (!(p->type & CUPS_PRINTER_REMOTE))
+ num_air = 1;
+ air = air_none;
+
+ if (p->num_auth_info_required > 0 && strcmp(p->auth_info_required[0], "none"))
+ {
+ num_air = p->num_auth_info_required;
+ air = p->auth_info_required;
+
+ if (!strcmp(air[0], "username"))
+ auth_supported = "basic";
+ else
+ auth_supported = "negotiate";
+ }
+ else if (!(p->type & CUPS_PRINTER_DISCOVERED))
{
if (p->type & CUPS_PRINTER_CLASS)
snprintf(resource, sizeof(resource), "/classes/%s", p->name);
if (auth)
{
if (auth->type == AUTH_BASIC || auth->type == AUTH_BASICDIGEST)
+ {
auth_supported = "basic";
+ num_air = 2;
+ air = air_userpass;
+ }
else if (auth->type == AUTH_DIGEST)
+ {
auth_supported = "digest";
+ num_air = 2;
+ air = air_userpass;
+ }
+#ifdef HAVE_GSSAPI
+ else if (auth->type == AUTH_NEGOTIATE)
+ {
+ auth_supported = "negotiate";
+ num_air = 1;
+ air = air_negotiate;
+ }
+#endif /* HAVE_GSSAPI */
if (auth->type != AUTH_NONE)
p->type |= CUPS_PRINTER_AUTHENTICATED;
else
p->type &= ~CUPS_PRINTER_AUTHENTICATED;
}
+ else if (p->type & CUPS_PRINTER_AUTHENTICATED)
+ {
+ num_air = 2;
+ air = air_userpass;
+ }
/*
* Create the required IPP attributes for a printer...
"job-k-limit", p->k_limit);
ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
"job-page-limit", p->page_limit);
- if (p->num_auth_info_required)
- ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
- "auth-info-required", p->num_auth_info_required,
- NULL, p->auth_info_required);
- else
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
- "auth-info-required", NULL, "none");
+ ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "auth-info-required", num_air, NULL, air);
- if (cupsArrayCount(Banners) > 0 && !(p->type & CUPS_PRINTER_REMOTE))
+ if (cupsArrayCount(Banners) > 0 && !(p->type & CUPS_PRINTER_DISCOVERED))
{
/*
* Setup the job-sheets-default attribute...
}
}
- printer_type = p->type;
-
p->raw = 0;
p->remote = 0;
- if (p->type & CUPS_PRINTER_REMOTE)
+ if (p->type & CUPS_PRINTER_DISCOVERED)
{
/*
* Tell the client this is a remote printer of some type...
* Show current and available port monitors for this printer...
*/
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "port-monitor",
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME, "port-monitor",
NULL, p->port_monitor ? p->port_monitor : "none");
-
for (i = 1, ppdattr = ppdFindAttr(ppd, "cupsPortMonitor", NULL);
ppdattr;
i ++, ppdattr = ppdFindNextAttr(ppd, "cupsPortMonitor", NULL));
i ++;
}
- attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
"port-monitor-supported", i, NULL, NULL);
attr->values[0].string.text = _cupsStrAlloc("none");
cupsdSetString(&p->product, ppd->product);
#endif /* HAVE_DNSSD */
+ if (ppdFindAttr(ppd, "APRemoteQueueID", NULL))
+ p->type |= CUPS_PRINTER_REMOTE;
+
/*
* Close the PPD and set the type...
*/
ppdClose(ppd);
-
- printer_type = p->type;
}
else if (!access(filename, 0))
{
* Tell the client this is really a hard-wired remote printer.
*/
- printer_type |= CUPS_PRINTER_REMOTE;
+ p->type |= CUPS_PRINTER_REMOTE;
/*
* Point the printer-uri-supported attribute to the
}
ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
- "finishings-supported", num_finishings, (int *)finishings);
+ "finishings-supported", num_finishings, finishings);
ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
"finishings-default", IPP_FINISHINGS_NONE);
}
}
/*
- * Copy the printer options into a browse attributes string we can re-use.
+ * Force sharing off for remote queues...
*/
- if (!(p->type & CUPS_PRINTER_REMOTE))
+ if (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT))
+ p->shared = 0;
+ else
{
+ /*
+ * Copy the printer options into a browse attributes string we can re-use.
+ */
+
const char *valptr; /* Pointer into value */
char *attrptr; /* Pointer into attribute string */
if (BrowseLocalOptions)
length += 12 + strlen(BrowseLocalOptions);
+ if (p->num_auth_info_required > 0)
+ {
+ length += 18; /* auth-info-required */
+
+ for (i = 0; i < p->num_auth_info_required; i ++)
+ length += strlen(p->auth_info_required[i]) + 1;
+ }
+
/*
* Allocate the new string...
*/
}
}
- *attrptr = '\0';
+ if (p->num_auth_info_required > 0)
+ {
+ strcpy(attrptr, "auth-info-required");
+ attrptr += 18;
+
+ for (i = 0; i < p->num_auth_info_required; i ++)
+ {
+ *attrptr++ = i ? ',' : '=';
+ strcpy(attrptr, p->auth_info_required[i]);
+ attrptr += strlen(attrptr);
+ }
+ }
+ else
+ *attrptr = '\0';
}
}
p->num_reasons = 0;
}
+ if (!strcmp(s, "none"))
+ return;
+
/*
* Loop through all of the reasons...
*/
(p->num_reasons - i) * sizeof(char *));
i --;
+
+ if (!strcmp(reason, "paused") && p->state == IPP_PRINTER_STOPPED)
+ cupsdSetPrinterState(p, IPP_PRINTER_IDLE, 1);
}
}
else if (p->num_reasons < (int)(sizeof(p->reasons) / sizeof(p->reasons[0])))
{
p->reasons[i] = strdup(reason);
p->num_reasons ++;
+
+ if (!strcmp(reason, "paused") && p->state != IPP_PRINTER_STOPPED)
+ cupsdSetPrinterState(p, IPP_PRINTER_STOPPED, 1);
}
}
}
* Can't set status of remote printers...
*/
- if (p->type & CUPS_PRINTER_REMOTE)
+ if (p->type & CUPS_PRINTER_DISCOVERED)
return;
/*
if (old_state != s)
{
- cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE_CHANGED, p, NULL,
+ cupsdAddEvent(s == IPP_PRINTER_STOPPED ? CUPSD_EVENT_PRINTER_STOPPED :
+ CUPSD_EVENT_PRINTER_STATE_CHANGED, p, NULL,
"%s \"%s\" state changed.",
(p->type & CUPS_PRINTER_CLASS) ? "Class" : "Printer",
p->name);
* Remove remote printers if we are no longer browsing...
*/
- if (!Browsing && (p->type & (CUPS_PRINTER_IMPLICIT | CUPS_PRINTER_REMOTE)))
+ if (!Browsing &&
+ (p->type & (CUPS_PRINTER_IMPLICIT | CUPS_PRINTER_DISCOVERED)))
{
if (p->type & CUPS_PRINTER_IMPLICIT)
cupsArrayRemove(ImplicitPrinters, p);
* Update printer attributes as needed...
*/
- if (!(p->type & CUPS_PRINTER_REMOTE))
+ if (!(p->type & CUPS_PRINTER_DISCOVERED))
cupsdSetPrinterAttrs(p);
}
}
if (dtype)
*dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT |
- CUPS_PRINTER_REMOTE);
+ CUPS_PRINTER_REMOTE | CUPS_PRINTER_DISCOVERED);
return (p->name);
}
if (dtype)
*dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT |
- CUPS_PRINTER_REMOTE);
+ CUPS_PRINTER_REMOTE | CUPS_PRINTER_DISCOVERED);
return (p->name);
}
* data has come from...
*/
- cupsFilePuts(fp, "# This file was automatically generated by cupsd(8) from the\n");
+ cupsFilePuts(fp,
+ "# This file was automatically generated by cupsd(8) from the\n");
cupsFilePrintf(fp, "# %s/printers.conf file. All changes to this file\n",
ServerRoot);
cupsFilePuts(fp, "# will be lost.\n");
if (DefaultPrinter)
cupsFilePrintf(fp, "%s|%s:rm=%s:rp=%s:\n", DefaultPrinter->name,
- DefaultPrinter->info, ServerName, DefaultPrinter->name);
+ DefaultPrinter->info, ServerName,
+ DefaultPrinter->name);
for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
p;
p = (cupsd_printer_t *)cupsArrayNext(Printers))
if (p != DefaultPrinter)
cupsFilePrintf(fp, "%s|%s:rm=%s:rp=%s:\n", p->name, p->info,
- ServerName, p->name);
+ ServerName, p->name);
break;
case PRINTCAP_SOLARIS:
p;
p = (cupsd_printer_t *)cupsArrayNext(Printers))
cupsFilePrintf(fp, "%s:\\\n"
- "\t:bsdaddr=%s,%s:\\\n"
- "\t:description=%s:\n",
- p->name, ServerName, p->name, p->info ? p->info : "");
+ "\t:bsdaddr=%s,%s:\\\n"
+ "\t:description=%s:\n",
+ p->name, ServerName, p->name,
+ p->info ? p->info : "");
break;
}
}
"number-up-default", 1);
if (!cupsGetOption("orientation-requested", p->num_options, p->options))
- ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
- "orientation-requested-default", IPP_PORTRAIT);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NOVALUE,
+ "orientation-requested-default", NULL, NULL);
if (!cupsGetOption("notify-lease-duration", p->num_options, p->options))
ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
/*
- * End of "$Id: printers.c 6318 2007-03-06 04:36:55Z mike $".
+ * End of "$Id: printers.c 6970 2007-09-17 23:58:28Z mike $".
*/