/*
- * "$Id: ipp.c,v 1.38.2.24 2003/02/20 03:50:33 mike Exp $"
+ * "$Id: ipp.c,v 1.38.2.25 2003/03/24 21:30:07 mike Exp $"
*
* IPP backend for the Common UNIX Printing System (CUPS).
*
* password_cb() - Disable the password prompt for
* cupsDoFileRequest().
* report_printer_state() - Report the printer state.
+ * run_pictwps_filter() - Convert PICT files to PostScript when printing
+ * remotely.
+ * sigterm_handler() - Handle 'terminate' signals that stop the backend.
*/
/*
#include <sys/wait.h>
+/*
+ * Globals...
+ */
+
+static char tmpfilename[1024] = ""; /* Temporary spool file name */
+
+
/*
* Some OS's don't have hstrerror(), most notably Solaris...
*/
#ifdef __APPLE__
int run_pictwps_filter(char **argv, char *filename, int length);
#endif /* __APPLE__ */
+static void sigterm_handler(int sig);
/*
char method[255], /* Method in URI */
hostname[1024], /* Hostname */
username[255], /* Username info */
- resource[1024], /* Resource info (printer name) */
- filename[1024]; /* File to print */
+ resource[1024]; /* Resource info (printer name) */
+ const char *filename; /* File to print */
int port; /* Port number (not used) */
char uri[HTTP_MAX_URI];/* Updated URI without user/pass */
ipp_status_t ipp_status; /* Status of IPP request */
*supported; /* get-printer-attributes response */
ipp_attribute_t *job_id_attr; /* job-id attribute */
int job_id; /* job-id value */
+ ipp_attribute_t *job_sheets; /* job-media-sheets-completed attribute */
ipp_attribute_t *job_state; /* job-state attribute */
ipp_attribute_t *copies_sup; /* copies-supported attribute */
ipp_attribute_t *charset_sup; /* charset-supported attribute */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
int version; /* IPP version */
int reasons; /* Number of printer-state-reasons shown */
+ static const char * const pattrs[] =
+ { /* Printer attributes we want */
+ "copies-supported",
+ "charset-supported",
+ "document-format-supported",
+ "printer-is-accepting-jobs",
+ "printer-state",
+ "printer-state-reasons",
+ };
+ static const char * const jattrs[] =
+ { /* Job attributes we want */
+ "job-media-sheets-completed",
+ "job-state"
+ };
/*
setbuf(stderr, NULL);
/*
- * Ignore SIGPIPE signals...
+ * Ignore SIGPIPE and catch SIGTERM signals...
*/
#ifdef HAVE_SIGSET
sigset(SIGPIPE, SIG_IGN);
+ sigset(SIGTERM, sigterm_handler);
#elif defined(HAVE_SIGACTION)
memset(&action, 0, sizeof(action));
action.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &action, NULL);
+
+ sigemptyset(&action.sa_mask);
+ sigaddset(&action.sa_mask, SIGTERM);
+ action.sa_handler = sigterm_handler;
+ sigaction(SIGTERM, &action, NULL);
#else
signal(SIGPIPE, SIG_IGN);
+ signal(SIGTERM, sigterm_handler);
#endif /* HAVE_SIGSET */
/*
int bytes; /* Number of bytes read */
- if ((fd = cupsTempFd(filename, sizeof(filename))) < 0)
+ if ((fd = cupsTempFd(tmpfilename, sizeof(tmpfilename))) < 0)
{
perror("ERROR: unable to create temporary file");
return (1);
{
perror("ERROR: unable to write to temporary file");
close(fd);
- unlink(filename);
+ unlink(tmpfilename);
return (1);
}
close(fd);
+ filename = tmpfilename;
}
else
- strlcpy(filename, argv[6], sizeof(filename));
+ filename = argv[6];
/*
* Extract the hostname and printer name from the URI...
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, uri);
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]),
+ NULL, pattrs);
+
/*
* Do the request...
*/
}
}
- /*
- * Now that we are "connected" to the port, ignore SIGTERM so that we
- * can finish out any page data the driver sends (e.g. to eject the
- * current page... Only ignore SIGTERM if we are printing data from
- * stdin (otherwise you can't cancel raw jobs...)
- */
-
- if (argc < 7)
- {
-#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
- sigset(SIGTERM, SIG_IGN);
-#elif defined(HAVE_SIGACTION)
- memset(&action, 0, sizeof(action));
-
- sigemptyset(&action.sa_mask);
- action.sa_handler = SIG_IGN;
- sigaction(SIGTERM, &action, NULL);
-#else
- signal(SIGTERM, SIG_IGN);
-#endif /* HAVE_SIGSET */
- }
-
/*
* See if the printer supports multiple copies...
*/
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
NULL, argv[2]);
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
- "requested-attributes", NULL, "job-state");
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", sizeof(jattrs) / sizeof(jattrs[0]),
+ NULL, jattrs);
/*
* Do the request...
break;
}
}
- else if ((job_state = ippFindAttribute(response, "job-state", IPP_TAG_ENUM)) != NULL)
+
+ if (response != NULL)
{
- /*
- * Stop polling if the job is finished or pending-held...
- */
+ if ((job_sheets = ippFindAttribute(response, "job-media-sheets-completed",
+ IPP_TAG_INTEGER)) != NULL)
+ fprintf(stderr, "PAGE: total %d\n", job_sheets->values[0].integer);
- if (job_state->values[0].integer > IPP_JOB_PROCESSING ||
- job_state->values[0].integer == IPP_JOB_HELD)
+ if ((job_state = ippFindAttribute(response, "job-state",
+ IPP_TAG_ENUM)) != NULL)
{
- ippDelete(response);
- break;
+ /*
+ * Stop polling if the job is finished or pending-held...
+ */
+
+ if (job_state->values[0].integer > IPP_JOB_PROCESSING ||
+ job_state->values[0].integer == IPP_JOB_HELD)
+ {
+ ippDelete(response);
+ break;
+ }
}
}
ippDelete(supported);
/*
- * Close and remove the temporary file if necessary...
+ * Remove the temporary file if necessary...
*/
- if (argc == 6 || strcmp(filename, argv[6]))
- unlink(filename);
+ if (tmpfilename[6])
+ unlink(tmpfilename);
/*
* Return the queue status...
int i; /* Looping var */
int count; /* Count of reasons shown... */
ipp_attribute_t *reasons; /* printer-state-reasons */
+ const char *reason; /* Current reason */
const char *message; /* Message to show */
char unknown[1024]; /* Unknown message string */
+ const char *prefix; /* Prefix for STATE: line */
+ char state[1024]; /* State string */
if ((reasons = ippFindAttribute(ipp, "printer-state-reasons",
IPP_TAG_KEYWORD)) == NULL)
return (0);
+ state[0] = '\0';
+ prefix = "STATE: ";
+
for (i = 0, count = 0; i < reasons->num_values; i ++)
{
+ reason = reasons->values[i].string.text;
+
+ strlcat(state, prefix, sizeof(state));
+ strlcat(state, reason, sizeof(state));
+
+ prefix = ",";
message = NULL;
- if (strncmp(reasons->values[i].string.text, "media-needed", 12) == 0)
+ if (strncmp(reason, "media-needed", 12) == 0)
message = "Media tray needs to be filled.";
- else if (strncmp(reasons->values[i].string.text, "media-jam", 9) == 0)
+ else if (strncmp(reason, "media-jam", 9) == 0)
message = "Media jam!";
- else if (strncmp(reasons->values[i].string.text, "moving-to-paused", 16) == 0 ||
- strncmp(reasons->values[i].string.text, "paused", 6) == 0 ||
- strncmp(reasons->values[i].string.text, "shutdown", 8) == 0)
+ else if (strncmp(reason, "moving-to-paused", 16) == 0 ||
+ strncmp(reason, "paused", 6) == 0 ||
+ strncmp(reason, "shutdown", 8) == 0)
message = "Printer off-line.";
- else if (strncmp(reasons->values[i].string.text, "toner-low", 9) == 0)
+ else if (strncmp(reason, "toner-low", 9) == 0)
message = "Toner low.";
- else if (strncmp(reasons->values[i].string.text, "toner-empty", 11) == 0)
+ else if (strncmp(reason, "toner-empty", 11) == 0)
message = "Out of toner!";
- else if (strncmp(reasons->values[i].string.text, "cover-open", 10) == 0)
+ else if (strncmp(reason, "cover-open", 10) == 0)
message = "Cover open.";
- else if (strncmp(reasons->values[i].string.text, "interlock-open", 14) == 0)
+ else if (strncmp(reason, "interlock-open", 14) == 0)
message = "Interlock open.";
- else if (strncmp(reasons->values[i].string.text, "door-open", 9) == 0)
+ else if (strncmp(reason, "door-open", 9) == 0)
message = "Door open.";
- else if (strncmp(reasons->values[i].string.text, "input-tray-missing", 18) == 0)
+ else if (strncmp(reason, "input-tray-missing", 18) == 0)
message = "Media tray missing!";
- else if (strncmp(reasons->values[i].string.text, "media-low", 9) == 0)
+ else if (strncmp(reason, "media-low", 9) == 0)
message = "Media tray almost empty.";
- else if (strncmp(reasons->values[i].string.text, "media-empty", 11) == 0)
+ else if (strncmp(reason, "media-empty", 11) == 0)
message = "Media tray empty!";
- else if (strncmp(reasons->values[i].string.text, "output-tray-missing", 19) == 0)
+ else if (strncmp(reason, "output-tray-missing", 19) == 0)
message = "Output tray missing!";
- else if (strncmp(reasons->values[i].string.text, "output-area-almost-full", 23) == 0)
+ else if (strncmp(reason, "output-area-almost-full", 23) == 0)
message = "Output bin almost full.";
- else if (strncmp(reasons->values[i].string.text, "output-area-full", 16) == 0)
+ else if (strncmp(reason, "output-area-full", 16) == 0)
message = "Output bin full!";
- else if (strncmp(reasons->values[i].string.text, "marker-supply-low", 17) == 0)
+ else if (strncmp(reason, "marker-supply-low", 17) == 0)
message = "Ink/toner almost empty.";
- else if (strncmp(reasons->values[i].string.text, "marker-supply-empty", 19) == 0)
+ else if (strncmp(reason, "marker-supply-empty", 19) == 0)
message = "Ink/toner empty!";
- else if (strncmp(reasons->values[i].string.text, "marker-waste-almost-full", 24) == 0)
+ else if (strncmp(reason, "marker-waste-almost-full", 24) == 0)
message = "Ink/toner waste bin almost full.";
- else if (strncmp(reasons->values[i].string.text, "marker-waste-full", 17) == 0)
+ else if (strncmp(reason, "marker-waste-full", 17) == 0)
message = "Ink/toner waste bin full!";
- else if (strncmp(reasons->values[i].string.text, "fuser-over-temp", 15) == 0)
+ else if (strncmp(reason, "fuser-over-temp", 15) == 0)
message = "Fuser temperature high!";
- else if (strncmp(reasons->values[i].string.text, "fuser-under-temp", 16) == 0)
+ else if (strncmp(reason, "fuser-under-temp", 16) == 0)
message = "Fuser temperature low!";
- else if (strncmp(reasons->values[i].string.text, "opc-near-eol", 12) == 0)
+ else if (strncmp(reason, "opc-near-eol", 12) == 0)
message = "OPC almost at end-of-life.";
- else if (strncmp(reasons->values[i].string.text, "opc-life-over", 13) == 0)
+ else if (strncmp(reason, "opc-life-over", 13) == 0)
message = "OPC at end-of-life!";
- else if (strncmp(reasons->values[i].string.text, "developer-low", 13) == 0)
+ else if (strncmp(reason, "developer-low", 13) == 0)
message = "Developer almost empty.";
- else if (strncmp(reasons->values[i].string.text, "developer-empty", 15) == 0)
+ else if (strncmp(reason, "developer-empty", 15) == 0)
message = "Developer empty!";
- else if (strstr(reasons->values[i].string.text, "error") != NULL)
+ else if (strstr(reason, "error") != NULL)
{
message = unknown;
snprintf(unknown, sizeof(unknown), "Unknown printer error (%s)!",
- reasons->values[i].string.text);
+ reason);
}
if (message)
}
}
+ fprintf(stderr, "%s\n", state);
+
return (count);
}
/*
- * End of "$Id: ipp.c,v 1.38.2.24 2003/02/20 03:50:33 mike Exp $".
+ * 'sigterm_handler()' - Handle 'terminate' signals that stop the backend.
+ */
+
+static void
+sigterm_handler(int sig) /* I - Signal */
+{
+ (void)sig; /* remove compiler warnings... */
+
+ /*
+ * Remove the temporary file if necessary...
+ */
+
+ if (tmpfilename[0])
+ unlink(tmpfilename);
+
+ exit(1);
+}
+
+
+/*
+ * End of "$Id: ipp.c,v 1.38.2.25 2003/03/24 21:30:07 mike Exp $".
*/