/*
- * "$Id: printers.c,v 1.93.2.13 2002/01/29 21:18:16 mike Exp $"
+ * "$Id: printers.c,v 1.93.2.46 2003/04/03 03:33:41 mike Exp $"
*
* Printer routines for the Common UNIX Printing System (CUPS).
*
- * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ * Copyright 1997-2003 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
*
* AddPrinter() - Add a printer to the system.
* AddPrinterFilter() - Add a MIME filter for a printer.
+ * AddPrinterHistory() - Add the current printer state to the history.
* AddPrinterUser() - Add a user to the ACL.
* DeleteAllPrinters() - Delete all printers from the system.
* DeletePrinter() - Delete a printer from the system.
* LoadAllPrinters() - Load printers from the printers.conf file.
* SaveAllPrinters() - Save all printer definitions to the printers.conf
* SetPrinterAttrs() - Set printer attributes based upon the PPD file.
+ * SetPrinterReasons() - Set/update the reasons strings.
* SetPrinterState() - Update the current state of a printer.
* SortPrinters() - Sort the printer list when a printer name is
* changed.
* StopPrinter() - Stop a printer from printing any jobs...
* ValidateDest() - Validate a printer/class destination.
+ * WritePrintcap() - Write a pseudo-printcap file for older
+ * applications that need it...
+ * write_irix_config() - Update the config files used by the IRIX
+ * desktop tools.
* write_irix_state() - Update the status files used by IRIX printing
* desktop tools.
- * write_printcap() - Write a pseudo-printcap file for older
- * applications that need it...
*/
/*
* Local functions...
*/
-static void write_printcap(void);
#ifdef __sgi
static void write_irix_state(printer_t *p);
#endif /* __sgi */
*prev; /* Previous printer in list */
- DEBUG_printf(("AddPrinter(\"%s\")\n", name));
-
/*
* Range check input...
*/
+ LogMessage(L_DEBUG2, "AddPrinter(\"%s\")", name ? name : "(null)");
+
if (name == NULL)
return (NULL);
*/
if ((p = calloc(1, sizeof(printer_t))) == NULL)
+ {
+ LogMessage(L_ERROR, "Unable to allocate memory for printer - %s",
+ strerror(errno));
return (NULL);
+ }
- strncpy(p->name, name, sizeof(p->name) - 1);
- strncpy(p->hostname, ServerName, sizeof(p->hostname) - 1);
+ SetString(&p->name, name);
+ SetString(&p->info, name);
+ SetString(&p->hostname, ServerName);
#ifdef AF_INET6
if (Listeners[0].address.addr.sa_family == AF_INET6)
- snprintf(p->uri, sizeof(p->uri), "ipp://%s:%d/printers/%s", ServerName,
- ntohs(Listeners[0].address.ipv6.sin6_port), name);
+ SetStringf(&p->uri, "ipp://%s:%d/printers/%s", ServerName,
+ ntohs(Listeners[0].address.ipv6.sin6_port), name);
else
#endif /* AF_INET6 */
- snprintf(p->uri, sizeof(p->uri), "ipp://%s:%d/printers/%s", ServerName,
- ntohs(Listeners[0].address.ipv4.sin_port), name);
+ SetStringf(&p->uri, "ipp://%s:%d/printers/%s", ServerName,
+ ntohs(Listeners[0].address.ipv4.sin_port), name);
+ SetStringf(&p->device_uri, "file:/dev/null");
p->state = IPP_PRINTER_STOPPED;
p->accepting = 0;
p->filetype = mimeAddType(MimeDatabase, "printer", name);
- strcpy(p->job_sheets[0], "none");
- strcpy(p->job_sheets[1], "none");
-
- /*
- * Setup required filters and IPP attributes...
- */
-
- SetPrinterAttrs(p);
+ SetString(&p->job_sheets[0], "none");
+ SetString(&p->job_sheets[1], "none");
+
+ if (MaxPrinterHistory)
+ p->history = calloc(MaxPrinterHistory, sizeof(ipp_t *));
/*
* Insert the printer in the printer list alphabetically...
* Write a new /etc/printcap or /var/spool/lp/pstatus file.
*/
- write_printcap();
+ WritePrintcap();
return (p);
}
* Range check input...
*/
- if (p == NULL || filter == NULL)
+ if (p == NULL || p->filetype == NULL || filter == NULL)
return;
/*
for (temptype = MimeDatabase->types, i = MimeDatabase->num_types;
i > 0;
i --, temptype ++)
- if (((super[0] == '*' && strcmp((*temptype)->super, "printer") != 0) ||
- strcmp((*temptype)->super, super) == 0) &&
- (type[0] == '*' || strcmp((*temptype)->type, type) == 0))
+ if (((super[0] == '*' && strcasecmp((*temptype)->super, "printer") != 0) ||
+ strcasecmp((*temptype)->super, super) == 0) &&
+ (type[0] == '*' || strcasecmp((*temptype)->type, type) == 0))
{
LogMessage(L_DEBUG2, "Adding filter %s/%s %s/%s %d %s",
(*temptype)->super, (*temptype)->type,
}
+/*
+ * 'AddPrinterHistory()' - Add the current printer state to the history.
+ */
+
+void
+AddPrinterHistory(printer_t *p) /* I - Printer */
+{
+ ipp_t *history; /* History collection */
+
+
+ /*
+ * Stop early if we aren't keeping history data...
+ */
+
+ if (MaxPrinterHistory <= 0)
+ return;
+
+ /*
+ * Retire old history data as needed...
+ */
+
+ if (p->num_history >= MaxPrinterHistory)
+ {
+ p->num_history --;
+ ippDelete(p->history[0]);
+ memmove(p->history, p->history + 1, p->num_history * sizeof(ipp_t *));
+ }
+
+ /*
+ * Create a collection containing the current printer-state, printer-up-time,
+ * printer-state-message, and printer-state-reasons attributes.
+ */
+
+ history = ippNew();
+ ippAddInteger(history, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
+ p->state);
+ ippAddString(history, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-state-message",
+ NULL, p->state_message);
+ if (p->num_reasons == 0)
+ ippAddString(history, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "printer-state-reasons", NULL,
+ p->state == IPP_PRINTER_STOPPED ? "paused" : "none");
+ else
+ ippAddStrings(history, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "printer-state-reasons", p->num_reasons, NULL,
+ (const char * const *)p->reasons);
+ ippAddInteger(history, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state-time",
+ p->state_time);
+
+ p->history[p->num_history] = history;
+ p->num_history ++;
+}
+
+
/*
* 'AddPrinterUser()' - Add a user to the ACL.
*/
if (!(p->type & CUPS_PRINTER_CLASS))
DeletePrinter(p);
}
+
+ if (CommonData)
+ {
+ ippDelete(CommonData);
+ CommonData = NULL;
+ }
}
void
DeletePrinter(printer_t *p) /* I - Printer to delete */
{
+ int i; /* Looping var */
printer_t *current, /* Current printer in list */
*prev; /* Previous printer in list */
#ifdef __sgi
{
DefaultPrinter = Printers;
-#ifdef __sgi
- if (DefaultPrinter)
- write_irix_state(DefaultPrinter);
-#endif /* __sgi */
+ WritePrintcap();
}
/*
if (p->printers != NULL)
free(p->printers);
+ if (MaxPrinterHistory)
+ {
+ for (i = 0; i < p->num_history; i ++)
+ ippDelete(p->history[i]);
+
+ free(p->history);
+ }
+
+ for (i = 0; i < p->num_reasons; i ++)
+ free(p->reasons[i]);
+
ippDelete(p->attrs);
DeletePrinterFilters(p);
FreePrinterUsers(p);
FreeQuotas(p);
+ ClearString(&p->uri);
+ ClearString(&p->hostname);
+ ClearString(&p->name);
+ ClearString(&p->location);
+ ClearString(&p->make_model);
+ ClearString(&p->info);
+ ClearString(&p->job_sheets[0]);
+ ClearString(&p->job_sheets[1]);
+ ClearString(&p->device_uri);
+
free(p);
/*
* Write a new /etc/printcap file...
*/
- write_printcap();
+ WritePrintcap();
}
}
+/*
+ * 'FindDest()' - Find a destination in the list.
+ */
+
+printer_t * /* O - Destination in list */
+FindDest(const char *name) /* I - Name of printer or class to find */
+{
+ printer_t *p; /* Current destination */
+ int diff; /* Difference */
+
+
+ for (p = Printers; p != NULL; p = p->next)
+ if ((diff = strcasecmp(name, p->name)) == 0)/* name == p->name */
+ return (p);
+ else if (diff < 0) /* name < p->name */
+ return (NULL);
+
+ return (NULL);
+}
+
+
/*
* 'FindPrinter()' - Find a printer in the list.
*/
FindPrinter(const char *name) /* I - Name of printer to find */
{
printer_t *p; /* Current printer */
+ int diff; /* Difference */
for (p = Printers; p != NULL; p = p->next)
- switch (strcasecmp(name, p->name))
- {
- case 0 : /* name == p->name */
- if (!(p->type & CUPS_PRINTER_CLASS))
- return (p);
- case 1 : /* name > p->name */
- break;
- case -1 : /* name < p->name */
- return (NULL);
- }
+ if ((diff = strcasecmp(name, p->name)) == 0 &&
+ !(p->type & CUPS_PRINTER_CLASS)) /* name == p->name */
+ return (p);
+ else if (diff < 0) /* name < p->name */
+ return (NULL);
return (NULL);
}
void
LoadAllPrinters(void)
{
- FILE *fp; /* printers.conf file */
+ cups_file_t *fp; /* printers.conf file */
int linenum; /* Current line number */
int len; /* Length of line */
char line[1024], /* Line from file */
*/
snprintf(line, sizeof(line), "%s/printers.conf", ServerRoot);
- if ((fp = fopen(line, "r")) == NULL)
+ if ((fp = cupsFileOpen(line, "r")) == NULL)
+ {
+ LogMessage(L_ERROR, "LoadAllPrinters: Unable to open %s - %s", line,
+ strerror(errno));
return;
+ }
/*
* Read printer configurations until we hit EOF...
linenum = 0;
p = NULL;
- while (fgets(line, sizeof(line), fp) != NULL)
+ while (cupsFileGets(fp, line, sizeof(line)) != NULL)
{
linenum ++;
line[len - 1] = '\0';
+ LogMessage(L_DEBUG, "LoadAllPrinters: Loading printer %s...", value);
+
p = AddPrinter(value);
p->accepting = 1;
p->state = IPP_PRINTER_IDLE;
if (p != NULL)
{
SetPrinterAttrs(p);
+ AddPrinterHistory(p);
p = NULL;
}
else
return;
}
else if (strcmp(name, "Info") == 0)
- strncpy(p->info, value, sizeof(p->info) - 1);
+ SetString(&p->info, value);
else if (strcmp(name, "Location") == 0)
- strncpy(p->location, value, sizeof(p->location) - 1);
+ SetString(&p->location, value);
else if (strcmp(name, "DeviceURI") == 0)
- strncpy(p->device_uri, value, sizeof(p->device_uri) - 1);
+ SetString(&p->device_uri, value);
else if (strcmp(name, "State") == 0)
{
/*
while (isspace(*value))
value ++;
- strncpy(p->state_message, value, sizeof(p->state_message) - 1);
+ strlcpy(p->state_message, value, sizeof(p->state_message));
}
else if (strcmp(name, "Accepting") == 0)
{
if (*valueptr)
*valueptr++ = '\0';
- strncpy(p->job_sheets[0], value, sizeof(p->job_sheets[0]) - 1);
+ SetString(&p->job_sheets[0], value);
while (isspace(*valueptr))
valueptr ++;
if (*valueptr)
*valueptr++ = '\0';
- strncpy(p->job_sheets[1], value, sizeof(p->job_sheets[1]) - 1);
+ SetString(&p->job_sheets[1], value);
}
}
else if (strcmp(name, "AllowUser") == 0)
}
}
- fclose(fp);
+ cupsFileClose(fp);
}
SaveAllPrinters(void)
{
int i; /* Looping var */
- FILE *fp; /* printers.conf file */
+ cups_file_t *fp; /* printers.conf file */
char temp[1024]; /* Temporary string */
char backup[1024]; /* printers.conf.O file */
printer_t *printer; /* Current printer class */
if (rename(temp, backup))
LogMessage(L_ERROR, "Unable to backup printers.conf - %s", strerror(errno));
- if ((fp = fopen(temp, "w")) == NULL)
+ if ((fp = cupsFileOpen(temp, "w")) == NULL)
{
LogMessage(L_ERROR, "Unable to save printers.conf - %s", strerror(errno));
* Restrict access to the file...
*/
- fchown(fileno(fp), User, Group);
- fchmod(fileno(fp), 0600);
+ fchown(cupsFileNumber(fp), User, Group);
+ fchmod(cupsFileNumber(fp), ConfigFilePerm);
/*
* Write a small header to the file...
curdate = gmtime(&curtime);
strftime(temp, sizeof(temp) - 1, CUPS_STRFTIME_FORMAT, curdate);
- fputs("# Printer configuration file for " CUPS_SVERSION "\n", fp);
- fprintf(fp, "# Written by cupsd on %s\n", temp);
+ cupsFilePuts(fp, "# Printer configuration file for " CUPS_SVERSION "\n");
+ cupsFilePrintf(fp, "# Written by cupsd on %s\n", temp);
/*
* Write each local printer known to the system...
*/
if (printer == DefaultPrinter)
- fprintf(fp, "<DefaultPrinter %s>\n", printer->name);
+ cupsFilePrintf(fp, "<DefaultPrinter %s>\n", printer->name);
else
- fprintf(fp, "<Printer %s>\n", printer->name);
+ cupsFilePrintf(fp, "<Printer %s>\n", printer->name);
- if (printer->info[0])
- fprintf(fp, "Info %s\n", printer->info);
+ if (printer->info)
+ cupsFilePrintf(fp, "Info %s\n", printer->info);
- if (printer->location[0])
- fprintf(fp, "Location %s\n", printer->location);
+ if (printer->location)
+ cupsFilePrintf(fp, "Location %s\n", printer->location);
- if (printer->device_uri[0])
- fprintf(fp, "DeviceURI %s\n", printer->device_uri);
+ if (printer->device_uri)
+ cupsFilePrintf(fp, "DeviceURI %s\n", printer->device_uri);
if (printer->state == IPP_PRINTER_STOPPED)
{
- fputs("State Stopped\n", fp);
- fprintf(fp, "StateMessage %s\n", printer->state_message);
+ cupsFilePuts(fp, "State Stopped\n");
+ cupsFilePrintf(fp, "StateMessage %s\n", printer->state_message);
}
else
- fputs("State Idle\n", fp);
+ cupsFilePuts(fp, "State Idle\n");
if (printer->accepting)
- fputs("Accepting Yes\n", fp);
+ cupsFilePuts(fp, "Accepting Yes\n");
else
- fputs("Accepting No\n", fp);
+ cupsFilePuts(fp, "Accepting No\n");
- fprintf(fp, "JobSheets %s %s\n", printer->job_sheets[0],
+ cupsFilePrintf(fp, "JobSheets %s %s\n", printer->job_sheets[0],
printer->job_sheets[1]);
- fprintf(fp, "QuotaPeriod %d\n", printer->quota_period);
- fprintf(fp, "PageLimit %d\n", printer->page_limit);
- fprintf(fp, "KLimit %d\n", printer->k_limit);
+ 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 ++)
- fprintf(fp, "%sUser %s\n", printer->deny_users ? "Deny" : "Allow",
+ cupsFilePrintf(fp, "%sUser %s\n", printer->deny_users ? "Deny" : "Allow",
printer->users[i]);
- fputs("</Printer>\n", fp);
+ cupsFilePuts(fp, "</Printer>\n");
+
#ifdef __sgi
/*
* Make IRIX desktop & printer status happy
*/
write_irix_state(printer);
-
#endif /* __sgi */
}
- fclose(fp);
+ cupsFileClose(fp);
}
ppd_option_t *input_slot, /* InputSlot options */
*media_type, /* MediaType options */
*page_size, /* PageSize options */
- *output_bin; /* OutputBin options */
+ *output_bin, /* OutputBin options */
+ *media_quality; /* EFMediaQualityMode options */
+ ppd_attr_t *ppdattr; /* PPD attribute */
ipp_attribute_t *attr; /* Attribute data */
ipp_value_t *val; /* Attribute value */
- int nups[3] = /* number-up-supported values */
- { 1, 2, 4 };
+ int nups[] = /* number-up-supported values */
+ { 1, 2, 4, 6, 9, 16 };
ipp_orient_t orients[4] = /* orientation-requested-supported values */
{
IPP_PORTRAIT,
"koi8-r",
"koi8-u",
};
+ const char *compressions[] =
+ {
+#ifdef HAVE_LIBZ
+ "none",
+ "gzip"
+#else
+ "none"
+#endif /* HAVE_LIBZ */
+ };
int num_finishings;
ipp_finish_t finishings[5];
const char *multiple_document_handling[] =
"separate-documents-collated-copies"
};
#ifdef __sgi
- FILE *fp; /* Interface script file */
+ cups_file_t *fp; /* Interface script file */
#endif /* __sgi */
DEBUG_printf(("SetPrinterAttrs: entering name = %s, type = %x\n", p->name,
p->type));
+ /*
+ * Make sure that we have the common attributes defined...
+ */
+
+ if (!CommonData)
+ {
+ CommonData = ippNew();
+
+ ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "pdl-override-supported", NULL, "not-attempted");
+ ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "ipp-versions-supported", sizeof(versions) / sizeof(versions[0]),
+ NULL, versions);
+ ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_ENUM, "operations-supported",
+ sizeof(ops) / sizeof(ops[0]) + JobFiles - 1, (int *)ops);
+ ippAddBoolean(CommonData, IPP_TAG_PRINTER, "multiple-document-jobs-supported", 1);
+ ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "multiple-operation-time-out", 60);
+ ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "multiple-document-handling-supported",
+ sizeof(multiple_document_handling) /
+ sizeof(multiple_document_handling[0]), NULL,
+ multiple_document_handling);
+ ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_CHARSET, "charset-configured",
+ NULL, DefaultCharset);
+ ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_CHARSET, "charset-supported",
+ sizeof(charsets) / sizeof(charsets[0]), NULL, charsets);
+ ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
+ "natural-language-configured", NULL, DefaultLanguage);
+ ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
+ "generated-natural-language-supported", NULL, DefaultLanguage);
+ ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE,
+ "document-format-default", NULL, "application/octet-stream");
+ ippAddStrings(CommonData, IPP_TAG_PRINTER,
+ (ipp_tag_t)(IPP_TAG_MIMETYPE | IPP_TAG_COPY),
+ "document-format-supported", NumMimeTypes, NULL, MimeTypes);
+ ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "compression-supported",
+ sizeof(compressions) / sizeof(compressions[0]),
+ NULL, compressions);
+ ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "job-priority-supported", 100);
+ ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "job-priority-default", 50);
+ ippAddRange(CommonData, IPP_TAG_PRINTER, "copies-supported", 1, MaxCopies);
+ ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "copies-default", 1);
+ ippAddBoolean(CommonData, IPP_TAG_PRINTER, "page-ranges-supported", 1);
+ ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "number-up-supported", sizeof(nups) / sizeof(nups[0]), nups);
+ ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "number-up-default", 1);
+ ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_ENUM,
+ "orientation-requested-supported", 4, (int *)orients);
+ ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_ENUM,
+ "orientation-requested-default", IPP_PORTRAIT);
+
+ if (NumBanners > 0)
+ {
+ /*
+ * Setup the job-sheets-supported and job-sheets-default attributes...
+ */
+
+ if (Classification && !ClassifyOverride)
+ attr = ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "job-sheets-supported", NULL, Classification);
+ else
+ attr = ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "job-sheets-supported", NumBanners + 1, NULL, NULL);
+
+ if (attr == NULL)
+ LogMessage(L_EMERG, "SetPrinterAttrs: Unable to allocate memory for "
+ "job-sheets-supported attribute: %s!",
+ strerror(errno));
+ else if (!Classification || ClassifyOverride)
+ {
+ attr->values[0].string.text = strdup("none");
+
+ for (i = 0; i < NumBanners; i ++)
+ attr->values[i + 1].string.text = strdup(Banners[i].name);
+ }
+ }
+ }
+
/*
* Clear out old filters and add a filter from application/vnd.cups-raw to
* printer/name to handle "raw" printing by users.
ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME, "printer-name", NULL,
p->name);
ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location",
- NULL, p->location);
+ NULL, p->location ? p->location : "");
ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info",
- NULL, p->info);
+ NULL, p->info ? p->info : "");
ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-more-info",
NULL, p->uri);
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
- "pdl-override-supported", NULL, "not-attempted");
- ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
- "ipp-versions-supported", sizeof(versions) / sizeof(versions[0]),
- NULL, versions);
- ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "operations-supported",
- sizeof(ops) / sizeof(ops[0]) + JobFiles - 1, (int *)ops);
- ippAddBoolean(p->attrs, IPP_TAG_PRINTER, "multiple-document-jobs-supported", 1);
- ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
- "multiple-operation-time-out", 60);
- ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
- "multiple-document-handling-supported",
- sizeof(multiple_document_handling) /
- sizeof(multiple_document_handling[0]), NULL,
- multiple_document_handling);
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_CHARSET, "charset-configured",
- NULL, DefaultCharset);
- ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_CHARSET, "charset-supported",
- sizeof(charsets) / sizeof(charsets[0]), NULL, charsets);
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
- "natural-language-configured", NULL, DefaultLanguage);
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
- "generated-natural-language-supported", NULL, DefaultLanguage);
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE,
- "document-format-default", NULL, "application/octet-stream");
- ippAddStrings(p->attrs, IPP_TAG_PRINTER,
- (ipp_tag_t)(IPP_TAG_MIMETYPE | IPP_TAG_COPY),
- "document-format-supported", NumMimeTypes, NULL, MimeTypes);
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
- "compression-supported", NULL, "none");
- ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
- "job-priority-supported", 100);
- ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
- "job-priority-default", 50);
- ippAddRange(p->attrs, IPP_TAG_PRINTER, "copies-supported", 1, 65535);
- ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
- "copies-default", 1);
- ippAddBoolean(p->attrs, IPP_TAG_PRINTER, "page-ranges-supported", 1);
- ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
- "number-up-supported", 3, nups);
- ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
- "number-up-default", 1);
- ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
- "orientation-requested-supported", 4, (int *)orients);
- ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
- "orientation-requested-default", IPP_PORTRAIT);
if (p->num_users)
{
ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
"job-page-limit", p->page_limit);
- if (NumBanners > 0)
+ if (NumBanners > 0 && !(p->type & CUPS_PRINTER_REMOTE))
{
/*
- * Setup the job-sheets-supported and job-sheets-default attributes...
+ * Setup the job-sheets-default attribute...
*/
- if (Classification[0] && !ClassifyOverride)
- attr = ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
- "job-sheets-supported", NULL, Classification);
- else
- attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
- "job-sheets-supported", NumBanners + 1, NULL, NULL);
-
- if (attr == NULL)
- LogMessage(L_EMERG, "SetPrinterAttrs: Unable to allocate memory for "
- "job-sheets-supported attribute: %s!",
- strerror(errno));
- else if (!Classification[0] || ClassifyOverride)
- {
- attr->values[0].string.text = strdup("none");
-
- for (i = 0; i < NumBanners; i ++)
- attr->values[i + 1].string.text = strdup(Banners[i].name);
- }
+ attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "job-sheets-default", 2, NULL, NULL);
- if (!(p->type & CUPS_PRINTER_REMOTE))
+ if (attr != NULL)
{
- attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
- "job-sheets-default", 2, NULL, NULL);
-
- if (attr != NULL)
- {
- attr->values[0].string.text = strdup(Classification[0] ?
- Classification : p->job_sheets[0]);
- attr->values[1].string.text = strdup(Classification[0] ?
- Classification : p->job_sheets[1]);
- }
+ attr->values[0].string.text = strdup(Classification ?
+ Classification : p->job_sheets[0]);
+ attr->values[1].string.text = strdup(Classification ?
+ Classification : p->job_sheets[1]);
}
}
printer_type = p->type;
+ p->raw = 0;
+
if (p->type & CUPS_PRINTER_REMOTE)
{
/*
ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
"printer-make-and-model", NULL, p->make_model);
+
+ p->raw = 1;
}
else
{
* URI so it doesn't have a username or password in it...
*/
- if (strstr(p->device_uri, "://") != NULL)
+ if (!p->device_uri)
+ strcpy(uri, "file:/dev/null");
+ else if (strstr(p->device_uri, "://") != NULL)
{
/*
* http://..., ipp://..., etc.
* file:..., serial:..., etc.
*/
- strcpy(uri, p->device_uri);
+ strlcpy(uri, p->device_uri, sizeof(uri));
}
ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL,
p->type |= CUPS_PRINTER_VARIABLE;
if (!ppd->manual_copies)
p->type |= CUPS_PRINTER_COPIES;
+ if ((ppdattr = ppdFindAttr(ppd, "cupsFax", NULL)) != NULL)
+ if (ppdattr->value && !strcasecmp(ppdattr->value, "true"))
+ p->type |= CUPS_PRINTER_FAX;
ippAddBoolean(p->attrs, IPP_TAG_PRINTER, "color-supported",
ppd->color_device);
if (ppd->throughput)
ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
"pages-per-minute", ppd->throughput);
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
- "printer-make-and-model", NULL, ppd->nickname);
if (ppd->nickname)
- strncpy(p->make_model, ppd->nickname, sizeof(p->make_model) - 1);
+ SetString(&p->make_model, ppd->nickname);
else if (ppd->modelname)
- strncpy(p->make_model, ppd->modelname, sizeof(p->make_model) - 1);
+ SetString(&p->make_model, ppd->modelname);
else
- strcpy(p->make_model, "Bad PPD File");
+ SetString(&p->make_model, "Bad PPD File");
+
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+ "printer-make-and-model", NULL, p->make_model);
/*
* Add media options from the PPD file...
if ((page_size = ppdFindOption(ppd, "PageSize")) != NULL)
num_media += page_size->num_choices;
- attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
- "media-supported", num_media, NULL, NULL);
- if (attr != NULL)
- {
- val = attr->values;
-
- if (input_slot != NULL)
- for (i = 0; i < input_slot->num_choices; i ++, val ++)
- val->string.text = strdup(input_slot->choices[i].choice);
-
- if (media_type != NULL)
- for (i = 0; i < media_type->num_choices; i ++, val ++)
- val->string.text = strdup(media_type->choices[i].choice);
+ if ((media_quality = ppdFindOption(ppd, "EFMediaQualityMode")) != NULL)
+ num_media += media_quality->num_choices;
- if (page_size != NULL)
+ if (num_media == 0)
+ {
+ LogMessage(L_CRIT, "SetPrinterAttrs: The PPD file for printer %s "
+ "contains no media options and is therefore "
+ "invalid!", p->name);
+ }
+ else
+ {
+ attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "media-supported", num_media, NULL, NULL);
+ if (attr != NULL)
{
- for (i = 0; i < page_size->num_choices; i ++, val ++)
- val->string.text = strdup(page_size->choices[i].choice);
-
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
- NULL, page_size->defchoice);
+ val = attr->values;
+
+ if (input_slot != NULL)
+ for (i = 0; i < input_slot->num_choices; i ++, val ++)
+ val->string.text = strdup(input_slot->choices[i].choice);
+
+ if (media_type != NULL)
+ for (i = 0; i < media_type->num_choices; i ++, val ++)
+ val->string.text = strdup(media_type->choices[i].choice);
+
+ if (media_quality != NULL)
+ for (i = 0; i < media_quality->num_choices; i ++, val ++)
+ val->string.text = strdup(media_quality->choices[i].choice);
+
+ if (page_size != NULL)
+ {
+ for (i = 0; i < page_size->num_choices; i ++, val ++)
+ val->string.text = strdup(page_size->choices[i].choice);
+
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
+ NULL, page_size->defchoice);
+ }
+ else if (input_slot != NULL)
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
+ NULL, input_slot->defchoice);
+ else if (media_type != NULL)
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
+ NULL, media_type->defchoice);
+ else if (media_quality != NULL)
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
+ NULL, media_quality->defchoice);
+ else
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
+ NULL, "none");
}
- else if (input_slot != NULL)
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
- NULL, input_slot->defchoice);
- else if (media_type != NULL)
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
- NULL, media_type->defchoice);
- else
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
- NULL, "none");
}
/*
}
else if (access(filename, 0) == 0)
{
+ int pline; /* PPD line number */
+ ppd_status_t pstatus; /* PPD load status */
+
+
+ pstatus = ppdLastError(&pline);
+
LogMessage(L_ERROR, "PPD file for %s cannot be loaded!", p->name);
+ if (pstatus <= PPD_ALLOC_ERROR)
+ LogMessage(L_ERROR, "%s", strerror(errno));
+ else
+ LogMessage(L_ERROR, "%s on line %d.", ppdErrorString(pstatus),
+ pline);
+
+ LogMessage(L_INFO, "Hint: Run \"cupstestppd %s\" and fix any errors.",
+ filename);
+
AddPrinterFilter(p, "application/vnd.cups-postscript 0 -");
}
else
ServerRoot, p->name);
AddPrinterFilter(p, filename);
}
- else if (strncmp(p->device_uri, "ipp://", 6) == 0 &&
+ else if (p->device_uri &&
+ strncmp(p->device_uri, "ipp://", 6) == 0 &&
(strstr(p->device_uri, "/printers/") != NULL ||
strstr(p->device_uri, "/classes/") != NULL))
{
* Print all files directly...
*/
- AddPrinterFilter(p, "*/* 0 -");
+ p->raw = 1;
}
else
{
ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
"printer-make-and-model", NULL, "Local Raw Printer");
- AddPrinterFilter(p, "*/* 0 -");
+ p->raw = 1;
}
}
#ifdef __sgi
/*
- * Add dummy interface and GUI scripts to fool SGI's "challenged" printing
- * tools. First the interface script that tells the tools what kind of
- * printer we have...
+ * Write the IRIX printer config and status files...
*/
- snprintf(filename, sizeof(filename), "/var/spool/lp/interface/%s", p->name);
+ write_irix_config(p);
+ write_irix_state(p);
+#endif /* __sgi */
+}
- if ((fp = fopen(filename, "w")) != NULL)
- {
- fputs("#!/bin/sh\n", fp);
- if ((attr = ippFindAttribute(p->attrs, "printer-make-and-model",
- IPP_TAG_TEXT)) != NULL)
- fprintf(fp, "NAME=\"%s\"\n", attr->values[0].string.text);
- else if (p->type & CUPS_PRINTER_CLASS)
- fputs("NAME=\"Printer Class\"\n", fp);
- else
- fputs("NAME=\"Remote Destination\"\n", fp);
+/*
+ * 'SetPrinterReasons()' - Set/update the reasons strings.
+ */
- if (p->type & CUPS_PRINTER_COLOR)
- fputs("TYPE=ColorPostScript\n", fp);
- else
- fputs("TYPE=MonoPostScript\n", fp);
+void
+SetPrinterReasons(printer_t *p, /* I - Printer */
+ const char *s) /* I - Reasons strings */
+{
+ int i; /* Looping var */
+ const char *sptr; /* Pointer into reasons */
+ char reason[255], /* Reason string */
+ *rptr; /* Pointer into reason */
- fprintf(fp, "HOSTNAME=%s\n", ServerName);
- fprintf(fp, "HOSTPRINTER=%s\n", p->name);
- fclose(fp);
+ if (s[0] == '-' || s[0] == '+')
+ {
+ /*
+ * Add/remove reasons...
+ */
- chmod(filename, 0755);
- chown(filename, User, Group);
+ sptr = s + 1;
}
-
- /*
- * Then the member file that tells which device file the queue is connected
- * to... Networked printers use "/dev/null" in this file, so that's what
- * we use (the actual device URI can confuse some apps...)
- */
-
- snprintf(filename, sizeof(filename), "/var/spool/lp/member/%s", p->name);
- if ((fp = fopen(filename, "w")) != NULL)
+ else
{
- fputs("/dev/null\n", fp);
+ /*
+ * Replace reasons...
+ */
- fclose(fp);
+ sptr = s;
- chmod(filename, 0644);
- chown(filename, User, Group);
+ for (i = 0; i < p->num_reasons; i ++)
+ free(p->reasons[i]);
+
+ p->num_reasons = 0;
}
/*
- * The gui_interface file is a script or program that launches a GUI
- * option panel for the printer, using options specified on the
- * command-line in the third argument. The option panel must send
- * any printing options to stdout on a single line when the user
- * accepts them, or nothing if the user cancels the dialog.
- *
- * The default options panel program is /usr/bin/glpoptions, from
- * the ESP Print Pro software. You can select another using the
- * PrintcapGUI option.
+ * Loop through all of the reasons...
*/
- snprintf(filename, sizeof(filename), "/var/spool/lp/gui_interface/ELF/%s.gui", p->name);
-
- if ((fp = fopen(filename, "w")) != NULL)
+ while (*sptr)
{
- fputs("#!/bin/sh\n", fp);
- fprintf(fp, "%s -d %s -o \"$3\"\n", PrintcapGUI, p->name);
+ /*
+ * Skip leading whitespace and commas...
+ */
- fclose(fp);
+ while (isspace(*sptr) || *sptr == ',')
+ sptr ++;
- chmod(filename, 0755);
- chown(filename, User, Group);
- }
+ for (rptr = reason; *sptr && !isspace(*sptr) && *sptr != ','; sptr ++)
+ if (rptr < (reason + sizeof(reason) - 1))
+ *rptr++ = *sptr;
- /*
- * The POD config file is needed by the printstatus command to show
- * the printer location and device.
- */
+ if (rptr == reason)
+ break;
- snprintf(filename, sizeof(filename), "/var/spool/lp/pod/%s.config", p->name);
- if ((fp = fopen(filename, "w")) != NULL)
- {
- fprintf(fp, "Printer Class | %s\n",
- (p->type & CUPS_PRINTER_COLOR) ? "ColorPostScript" : "MonoPostScript");
- fprintf(fp, "Printer Model | %s\n", p->make_model);
- fprintf(fp, "Location Code | %s\n", p->location);
- fprintf(fp, "Physical Location | %s\n", p->info);
- fprintf(fp, "Port Path | %s\n", p->device_uri);
- fprintf(fp, "Config Path | /var/spool/lp/pod/%s.config\n", p->name);
- fprintf(fp, "Active Status Path | /var/spool/lp/pod/%s.status\n", p->name);
- fputs("Status Update Wait | 10 seconds\n", fp);
+ *rptr = '\0';
- fclose(fp);
+ if (s[0] == '-')
+ {
+ /*
+ * Remove reason...
+ */
- chmod(filename, 0664);
- chown(filename, User, Group);
- }
+ for (i = 0; i < p->num_reasons; i ++)
+ if (!strcasecmp(reason, p->reasons[i]))
+ {
+ /*
+ * Found a match, so remove it...
+ */
- /*
- * Write the IRIX printer status files...
- */
+ p->num_reasons --;
+ free(p->reasons[i]);
- write_irix_state(p);
-#endif /* __sgi */
+ if (i < p->num_reasons)
+ memmove(p->reasons + i, p->reasons + i + 1,
+ (p->num_reasons - i) * sizeof(char *));
+
+ i --;
+ }
+ }
+ else if (s[0] == '+' &&
+ p->num_reasons < (int)(sizeof(p->reasons) / sizeof(p->reasons[0])))
+ {
+ /*
+ * Add reason...
+ */
+
+ for (i = 0; i < p->num_reasons; i ++)
+ if (!strcasecmp(reason, p->reasons[i]))
+ break;
+
+ if (i >= p->num_reasons)
+ {
+ p->reasons[i] = strdup(reason);
+ p->num_reasons ++;
+ }
+ }
+ }
}
* Set the new state...
*/
- old_state = p->state;
- p->state = s;
- p->state_time = time(NULL);
+ old_state = p->state;
+ p->state = s;
if (old_state != s)
{
+ p->state_time = time(NULL);
p->browse_time = 0;
#ifdef __sgi
#endif /* __sgi */
}
+ AddPrinterHistory(p);
+
/*
* Save the printer configuration if a printer goes from idle or processing
* to stopped (or visa-versa)...
if ((old_state == IPP_PRINTER_STOPPED) != (s == IPP_PRINTER_STOPPED))
SaveAllPrinters();
-
- /*
- * Check to see if any pending jobs can now be printed...
- */
-
- CheckJobs();
}
job_t *job; /* Active print job */
+ /*
+ * Set the printer state...
+ */
+
+ p->state = IPP_PRINTER_STOPPED;
+
/*
* See if we have a job printing on this printer...
*/
SaveJob(job->id);
}
-
- p->state = IPP_PRINTER_STOPPED;
}
return (NULL);
else if (p != NULL)
{
- *dtype = p->type & CUPS_PRINTER_CLASS;
+ *dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT |
+ CUPS_PRINTER_REMOTE);
return (p->name);
}
if (strcasecmp(hostname, "localhost") == 0)
hostname = ServerName;
- strncpy(localname, hostname, sizeof(localname) - 1);
- localname[sizeof(localname) - 1] = '\0';
+ strlcpy(localname, hostname, sizeof(localname));
if (strcasecmp(hostname, ServerName) != 0)
{
if (strcasecmp(p->hostname, localname) == 0 &&
strcasecmp(p->name, resource) == 0)
{
- *dtype = p->type & CUPS_PRINTER_CLASS;
+ *dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT |
+ CUPS_PRINTER_REMOTE);
return (p->name);
}
/*
- * 'write_printcap()' - Write a pseudo-printcap file for older applications
- * that need it...
+ * 'WritePrintcap()' - Write a pseudo-printcap file for older applications
+ * that need it...
*/
-static void
-write_printcap(void)
+void
+WritePrintcap(void)
{
- FILE *fp; /* printcap file */
+ cups_file_t *fp; /* printcap file */
printer_t *p; /* Current printer */
+#ifdef __sgi
+ /*
+ * Update the IRIX printer state for the default printer; if
+ * no printers remain, then the default printer file will be
+ * removed...
+ */
+
+ write_irix_state(DefaultPrinter);
+#endif /* __sgi */
+
/*
* See if we have a printcap file; if not, don't bother writing it.
*/
* Open the printcap file...
*/
- if ((fp = fopen(Printcap, "w")) == NULL)
+ if ((fp = cupsFileOpen(Printcap, "w")) == NULL)
return;
+ /*
+ * Put a comment header at the top so that users will know where the
+ * data has come from...
+ */
+
+ 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");
+
/*
* Write a new printcap with the current list of printers.
*/
* PrinterN:
*/
+ if (DefaultPrinter)
+ cupsFilePrintf(fp, "%s|%s:rm=%s:rp=%s:\n", DefaultPrinter->name,
+ DefaultPrinter->info, ServerName, DefaultPrinter->name);
+
for (p = Printers; p != NULL; p = p->next)
- fprintf(fp, "%s:\n", p->name);
+ if (p != DefaultPrinter)
+ cupsFilePrintf(fp, "%s|%s:rm=%s:rp=%s:\n", p->name, p->info,
+ ServerName, p->name);
break;
case PRINTCAP_SOLARIS:
*
* _all:all=Printer1,Printer2,Printer3,...,PrinterN
* _default:use=DefaultPrinter
- * Printer1:
+ * Printer1:\
+ * :bsdaddr=ServerName,Printer1:\
+ * :description=Description:
* Printer2:
+ * :bsdaddr=ServerName,Printer2:\
+ * :description=Description:
* Printer3:
+ * :bsdaddr=ServerName,Printer3:\
+ * :description=Description:
* ...
* PrinterN:
+ * :bsdaddr=ServerName,PrinterN:\
+ * :description=Description:
*/
- fputs("_all:all=", fp);
+ cupsFilePuts(fp, "_all:all=");
for (p = Printers; p != NULL; p = p->next)
- fprintf(fp, "%s%c", p->name, p->next ? ',' : '\n');
+ cupsFilePrintf(fp, "%s%c", p->name, p->next ? ',' : '\n');
if (DefaultPrinter)
- fprintf(fp, "_default:use=%s\n", DefaultPrinter->name);
+ cupsFilePrintf(fp, "_default:use=%s\n", DefaultPrinter->name);
for (p = Printers; p != NULL; p = p->next)
- fprintf(fp, "%s:\n", p->name);
+ cupsFilePrintf(fp, "%s:\\\n"
+ "\t:bsdaddr=%s,%s:\\\n"
+ "\t:description=%s:\n",
+ p->name, ServerName, p->name, p->info ? p->info : "");
break;
}
* Close the file...
*/
- fclose(fp);
+ cupsFileClose(fp);
}
#ifdef __sgi
/*
- * 'write_irix_state()' - Update the status files used by IRIX printing
- * desktop tools.
+ * 'write_irix_config()' - Update the config files used by the IRIX
+ * desktop tools.
*/
static void
-write_irix_state(printer_t *p) /* I - Printer to update */
+write_irix_config(printer_t *p) /* I - Printer to update */
{
- char filename[1024]; /* Interface script filename */
- FILE *fp; /* Interface script file */
- int tag; /* Status tag value */
+ char filename[1024]; /* Interface script filename */
+ cups_file_t *fp; /* Interface script file */
+ int tag; /* Status tag value */
+
/*
- * The POD status file is needed for the printstatus window to
- * provide the current status of the printer.
+ * Add dummy interface and GUI scripts to fool SGI's "challenged" printing
+ * tools. First the interface script that tells the tools what kind of
+ * printer we have...
*/
- snprintf(filename, sizeof(filename), "/var/spool/lp/pod/%s.status", p->name);
+ snprintf(filename, sizeof(filename), "/var/spool/lp/interface/%s", p->name);
- if ((fp = fopen(filename, "w")) != NULL)
+ if (p->type & CUPS_PRINTER_CLASS)
+ unlink(filename);
+ else if ((fp = cupsFileOpen(filename, "w")) != NULL)
{
- fprintf(fp, "Operational Status | %s\n",
- (p->state == IPP_PRINTER_IDLE) ? "Idle" :
- (p->state == IPP_PRINTER_PROCESSING) ? "Busy" :
- "Faulted");
- fprintf(fp, "Information | 01 00 00 | %s\n", CUPS_SVERSION);
- fprintf(fp, "Information | 02 00 00 | Device URI: %s\n", p->device_uri);
- fprintf(fp, "Information | 03 00 00 | %s jobs\n",
- p->accepting ? "Accepting" : "Not accepting");
- fprintf(fp, "Information | 04 00 00 | %s\n", p->state_message);
-
- fclose(fp);
+ cupsFilePuts(fp, "#!/bin/sh\n");
- chmod(filename, 0664);
+ if ((attr = ippFindAttribute(p->attrs, "printer-make-and-model",
+ IPP_TAG_TEXT)) != NULL)
+ cupsFilePrintf(fp, "NAME=\"%s\"\n", attr->values[0].string.text);
+ else if (p->type & CUPS_PRINTER_CLASS)
+ cupsFilePuts(fp, "NAME=\"Printer Class\"\n");
+ else
+ cupsFilePuts(fp, "NAME=\"Remote Destination\"\n");
+
+ if (p->type & CUPS_PRINTER_COLOR)
+ cupsFilePuts(fp, "TYPE=ColorPostScript\n");
+ else
+ cupsFilePuts(fp, "TYPE=MonoPostScript\n");
+
+ cupsFilePrintf(fp, "HOSTNAME=%s\n", ServerName);
+ cupsFilePrintf(fp, "HOSTPRINTER=%s\n", p->name);
+
+ cupsFileClose(fp);
+
+ chmod(filename, 0755);
chown(filename, User, Group);
}
/*
- * The activeicons file is needed to provide desktop icons for printers:
- *
- * [ quoted from /usr/lib/print/tagit ]
- *
- * --- Type of printer tags (base values)
- *
- * Dumb=66048 # 0x10200
- * DumbColor=66080 # 0x10220
- * Raster=66112 # 0x10240
- * ColorRaster=66144 # 0x10260
- * Plotter=66176 # 0x10280
- * PostScript=66208 # 0x102A0
- * ColorPostScript=66240 # 0x102C0
- * MonoPostScript=66272 # 0x102E0
- *
- * --- Printer state modifiers for local printers
- *
- * Idle=0 # 0x0
- * Busy=1 # 0x1
- * Faulted=2 # 0x2
- * Unknown=3 # 0x3 (Faulted due to unknown reason)
- *
- * --- Printer state modifiers for network printers
- *
- * NetIdle=8 # 0x8
- * NetBusy=9 # 0x9
- * NetFaulted=10 # 0xA
- * NetUnknown=11 # 0xB (Faulted due to unknown reason)
+ * Then the member file that tells which device file the queue is connected
+ * to... Networked printers use "/dev/null" in this file, so that's what
+ * we use (the actual device URI can confuse some apps...)
*/
- snprintf(filename, sizeof(filename), "/var/spool/lp/activeicons/%s", p->name);
+ snprintf(filename, sizeof(filename), "/var/spool/lp/member/%s", p->name);
- if ((fp = fopen(filename, "w")) != NULL)
+ if (p->type & CUPS_PRINTER_CLASS)
+ unlink(filename);
+ else if ((fp = cupsFileOpen(filename, "w")) != NULL)
{
- if (p->type & CUPS_PRINTER_COLOR)
- tag = 66240;
- else
- tag = 66272;
+ cupsFilePuts(fp, "/dev/null\n");
- if (p->type & CUPS_PRINTER_REMOTE)
- tag |= 8;
+ cupsFileClose(fp);
- if (p->state == IPP_PRINTER_PROCESSING)
- tag |= 1;
+ chmod(filename, 0644);
+ chown(filename, User, Group);
+ }
- else if (p->state == IPP_PRINTER_STOPPED)
- tag |= 2;
+ /*
+ * The gui_interface file is a script or program that launches a GUI
+ * option panel for the printer, using options specified on the
+ * command-line in the third argument. The option panel must send
+ * any printing options to stdout on a single line when the user
+ * accepts them, or nothing if the user cancels the dialog.
+ *
+ * The default options panel program is /usr/bin/glpoptions, from
+ * the ESP Print Pro software. You can select another using the
+ * PrintcapGUI option.
+ */
- fputs("#!/bin/sh\n", fp);
- fprintf(fp, "#Tag %d\n", tag);
+ snprintf(filename, sizeof(filename), "/var/spool/lp/gui_interface/ELF/%s.gui", p->name);
- fclose(fp);
+ if (p->type & CUPS_PRINTER_CLASS)
+ unlink(filename);
+ else if ((fp = cupsFileOpen(filename, "w")) != NULL)
+ {
+ cupsFilePuts(fp, "#!/bin/sh\n");
+ cupsFilePrintf(fp, "%s -d %s -o \"$3\"\n", PrintcapGUI, p->name);
+
+ cupsFileClose(fp);
chmod(filename, 0755);
chown(filename, User, Group);
}
+ /*
+ * The POD config file is needed by the printstatus command to show
+ * the printer location and device.
+ */
+
+ snprintf(filename, sizeof(filename), "/var/spool/lp/pod/%s.config", p->name);
+
+ if (p->type & CUPS_PRINTER_CLASS)
+ unlink(filename);
+ else if ((fp = cupsFileOpen(filename, "w")) != NULL)
+ {
+ cupsFilePrintf(fp, "Printer Class | %s\n",
+ (p->type & CUPS_PRINTER_COLOR) ? "ColorPostScript" : "MonoPostScript");
+ cupsFilePrintf(fp, "Printer Model | %s\n", p->make_model ? p->make_model : "");
+ cupsFilePrintf(fp, "Location Code | %s\n", p->location ? p->location : "");
+ cupsFilePrintf(fp, "Physical Location | %s\n", p->info ? p->info : "");
+ cupsFilePrintf(fp, "Port Path | %s\n", p->device_uri ? p->device_uri : "");
+ cupsFilePrintf(fp, "Config Path | /var/spool/lp/pod/%s.config\n", p->name);
+ cupsFilePrintf(fp, "Active Status Path | /var/spool/lp/pod/%s.status\n", p->name);
+ cupsFilePuts(fp, "Status Update Wait | 10 seconds\n");
+
+ cupsFileClose(fp);
+
+ chmod(filename, 0664);
+ chown(filename, User, Group);
+ }
+
+
+/*
+ * 'write_irix_state()' - Update the status files used by IRIX printing
+ * desktop tools.
+ */
+
+static void
+write_irix_state(printer_t *p) /* I - Printer to update */
+{
+ char filename[1024]; /* Interface script filename */
+ cups_file_t *fp; /* Interface script file */
+ int tag; /* Status tag value */
+
+
+ if (p)
+ {
+ /*
+ * The POD status file is needed for the printstatus window to
+ * provide the current status of the printer.
+ */
+
+ snprintf(filename, sizeof(filename), "/var/spool/lp/pod/%s.status", p->name);
+
+ if (p->type & CUPS_PRINTER_CLASS)
+ unlink(filename);
+ else if ((fp = cupsFileOpen(filename, "w")) != NULL)
+ {
+ cupsFilePrintf(fp, "Operational Status | %s\n",
+ (p->state == IPP_PRINTER_IDLE) ? "Idle" :
+ (p->state == IPP_PRINTER_PROCESSING) ? "Busy" :
+ "Faulted");
+ cupsFilePrintf(fp, "Information | 01 00 00 | %s\n", CUPS_SVERSION);
+ cupsFilePrintf(fp, "Information | 02 00 00 | Device URI: %s\n",
+ p->device_uri ? p->device_uri : "");
+ cupsFilePrintf(fp, "Information | 03 00 00 | %s jobs\n",
+ p->accepting ? "Accepting" : "Not accepting");
+ cupsFilePrintf(fp, "Information | 04 00 00 | %s\n", p->state_message);
+
+ cupsFileClose(fp);
+
+ chmod(filename, 0664);
+ chown(filename, User, Group);
+ }
+
+ /*
+ * The activeicons file is needed to provide desktop icons for printers:
+ *
+ * [ quoted from /usr/lib/print/tagit ]
+ *
+ * --- Type of printer tags (base values)
+ *
+ * Dumb=66048 # 0x10200
+ * DumbColor=66080 # 0x10220
+ * Raster=66112 # 0x10240
+ * ColorRaster=66144 # 0x10260
+ * Plotter=66176 # 0x10280
+ * PostScript=66208 # 0x102A0
+ * ColorPostScript=66240 # 0x102C0
+ * MonoPostScript=66272 # 0x102E0
+ *
+ * --- Printer state modifiers for local printers
+ *
+ * Idle=0 # 0x0
+ * Busy=1 # 0x1
+ * Faulted=2 # 0x2
+ * Unknown=3 # 0x3 (Faulted due to unknown reason)
+ *
+ * --- Printer state modifiers for network printers
+ *
+ * NetIdle=8 # 0x8
+ * NetBusy=9 # 0x9
+ * NetFaulted=10 # 0xA
+ * NetUnknown=11 # 0xB (Faulted due to unknown reason)
+ */
+
+ snprintf(filename, sizeof(filename), "/var/spool/lp/activeicons/%s", p->name);
+
+ if (p->type & CUPS_PRINTER_CLASS)
+ unlink(filename);
+ else if ((fp = cupsFileOpen(filename, "w")) != NULL)
+ {
+ if (p->type & CUPS_PRINTER_COLOR)
+ tag = 66240;
+ else
+ tag = 66272;
+
+ if (p->type & CUPS_PRINTER_REMOTE)
+ tag |= 8;
+
+ if (p->state == IPP_PRINTER_PROCESSING)
+ tag |= 1;
+
+ else if (p->state == IPP_PRINTER_STOPPED)
+ tag |= 2;
+
+ cupsFilePuts(fp, "#!/bin/sh\n");
+ cupsFilePrintf(fp, "#Tag %d\n", tag);
+
+ cupsFileClose(fp);
+
+ chmod(filename, 0755);
+ chown(filename, User, Group);
+ }
+ }
+
/*
* The default file is needed by the printers window to show
* the default printer.
if (DefaultPrinter != NULL)
{
- if ((fp = fopen(filename, "w")) != NULL)
+ if ((fp = cupsFileOpen(filename, "w")) != NULL)
{
- fprintf(fp, "%s\n", DefaultPrinter->name);
+ cupsFilePrintf(fp, "%s\n", DefaultPrinter->name);
- fclose(fp);
+ cupsFileClose(fp);
chmod(filename, 0644);
chown(filename, User, Group);
/*
- * End of "$Id: printers.c,v 1.93.2.13 2002/01/29 21:18:16 mike Exp $".
+ * End of "$Id: printers.c,v 1.93.2.46 2003/04/03 03:33:41 mike Exp $".
*/