CHANGES IN CUPS V1.1.19
+ - Added support for STATE: messages
+ (printer-state-reasons), printer-state-history, and
+ printer-state-time to the scheduler.
- When using RunAsUser, the scheduler would initially
start any previously queued (pending) jobs with
RunAsUser disabled - all backends would be running as
/*
- * "$Id: conf.c,v 1.77.2.32 2003/03/17 20:13:51 mike Exp $"
+ * "$Id: conf.c,v 1.77.2.33 2003/03/19 06:07:40 mike Exp $"
*
* Configuration routines for the Common UNIX Printing System (CUPS).
*
{ "MaxJobsPerPrinter", &MaxJobsPerPrinter, VAR_INTEGER },
{ "MaxJobsPerUser", &MaxJobsPerUser, VAR_INTEGER },
{ "MaxLogSize", &MaxLogSize, VAR_INTEGER },
+ { "MaxPrinterHistory", &MaxPrinterHistory, VAR_INTEGER },
{ "MaxRequestSize", &MaxRequestSize, VAR_INTEGER },
{ "PageLog", &PageLog, VAR_STRING },
{ "PreserveJobFiles", &JobFiles, VAR_BOOLEAN },
MaxClients = 100;
MaxClientsPerHost = 0;
MaxLogSize = 1024 * 1024;
+ MaxPrinterHistory = 10;
MaxRequestSize = 0;
RootCertDuration = 300;
RunAsUser = FALSE;
/*
- * End of "$Id: conf.c,v 1.77.2.32 2003/03/17 20:13:51 mike Exp $".
+ * End of "$Id: conf.c,v 1.77.2.33 2003/03/19 06:07:40 mike Exp $".
*/
/*
- * "$Id: conf.h,v 1.36.2.15 2003/02/04 05:45:26 mike Exp $"
+ * "$Id: conf.h,v 1.36.2.16 2003/03/19 06:07:42 mike Exp $"
*
* Configuration file definitions for the Common UNIX Printing System (CUPS)
* scheduler.
* Log levels...
*/
+#define L_STATE -2 /* Used internally for state-reasons */
#define L_PAGE -1 /* Used internally for page logging */
#define L_NONE 0
#define L_EMERG 1 /* Emergency issues */
/* Maximum number of copies per job */
MaxLogSize VALUE(1024 * 1024),
/* Maximum size of log files */
+ MaxPrinterHistory VALUE(10),
+ /* Maximum printer state history */
MaxRequestSize VALUE(0),
/* Maximum size of IPP requests */
HostNameLookups VALUE(FALSE),
/*
- * End of "$Id: conf.h,v 1.36.2.15 2003/02/04 05:45:26 mike Exp $".
+ * End of "$Id: conf.h,v 1.36.2.16 2003/03/19 06:07:42 mike Exp $".
*/
/*
- * "$Id: ipp.c,v 1.127.2.49 2003/03/13 03:35:00 mike Exp $"
+ * "$Id: ipp.c,v 1.127.2.50 2003/03/19 06:07:42 mike Exp $"
*
* IPP routines for the Common UNIX Printing System (CUPS) scheduler.
*
LogMessage(L_DEBUG2, "add_printer_state_reasons(%d, %s)\n", con->http.fd,
p->name);
- switch (p->state)
- {
- case IPP_PRINTER_STOPPED :
- ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
- "printer-state-reasons", NULL, "paused");
- break;
-
- default :
- ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
- "printer-state-reasons", NULL, "none");
- break;
- }
+ if (p->num_reasons == 0)
+ ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "printer-state-reasons", NULL,
+ p->state == IPP_PRINTER_STOPPED ? "paused" : "none");
+ else
+ ippAddStrings(con->response, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "printer-state-reasons", p->num_reasons, NULL,
+ (const char * const *)p->reasons);
}
}
break;
- default :
+ case IPP_TAG_BEGIN_COLLECTION :
+ toattr = ippAddCollections(to, attr->group_tag, attr->name,
+ attr->num_values, NULL);
+
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ toattr->values[i].collection = ippNew();
+ copy_attrs(toattr->values[i].collection, attr->values[i].collection,
+ NULL, IPP_TAG_ZERO, 0);
+ }
+ break;
+
+ default :
toattr = ippAddIntegers(to, attr->group_tag, attr->value_tag,
attr->name, attr->num_values, NULL);
int port; /* Port portion of URI */
printer_t *printer; /* Printer/class */
time_t curtime; /* Current time */
+ int i; /* Looping var */
+ ipp_attribute_t *requested, /* requested-attributes */
+ *history; /* History collection */
LogMessage(L_DEBUG2, "get_printer_attrs(%d, %s)\n", con->http.fd,
ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
"printer-up-time", curtime);
+ ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "printer-state-time", printer->state_time);
ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time",
ippTimeToDate(curtime));
add_queued_job_count(con, printer);
- copy_attrs(con->response, printer->attrs,
- ippFindAttribute(con->request, "requested-attributes",
- IPP_TAG_KEYWORD), IPP_TAG_ZERO, 0);
+ requested = ippFindAttribute(con->request, "requested-attributes",
+ IPP_TAG_KEYWORD);
- copy_attrs(con->response, CommonData,
- ippFindAttribute(con->request, "requested-attributes",
- IPP_TAG_KEYWORD), IPP_TAG_ZERO, IPP_TAG_COPY);
+ copy_attrs(con->response, printer->attrs, requested, IPP_TAG_ZERO, 0);
+ copy_attrs(con->response, CommonData, requested, IPP_TAG_ZERO, IPP_TAG_COPY);
- con->response->request.status.status_code = IPP_OK;
+ if (MaxPrinterHistory > 0 && printer->num_history > 0)
+ {
+ history = ippAddCollections(con->response, IPP_TAG_PRINTER,
+ "printer-state-history",
+ printer->num_history, NULL);
+
+ for (i = 0; i < printer->num_history; i ++)
+ copy_attrs(history->values[i].collection = ippNew(), printer->history[i],
+ NULL, IPP_TAG_ZERO, 0);
+ }
+
+ con->response->request.status.status_code = requested ? IPP_OK_SUBST : IPP_OK;
}
get_printers(client_t *con, /* I - Client connection */
int type) /* I - 0 or CUPS_PRINTER_CLASS */
{
- ipp_attribute_t *attr, /* Current attribute */
- *requested; /* Requested attributes */
+ int i; /* Looping var */
+ ipp_attribute_t *requested, /* requested-attributes */
+ *history, /* History collection */
+ *attr; /* Current attribute */
int limit; /* Maximum number of printers to return */
int count; /* Number of printers that match */
printer_t *printer; /* Current printer pointer */
ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
"printer-up-time", curtime);
+ ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "printer-state-time", printer->state_time);
ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time",
ippTimeToDate(curtime));
copy_attrs(con->response, CommonData, requested, IPP_TAG_ZERO,
IPP_TAG_COPY);
+
+ if (MaxPrinterHistory > 0 && printer->num_history > 0)
+ {
+ history = ippAddCollections(con->response, IPP_TAG_PRINTER,
+ "printer-state-history",
+ printer->num_history, NULL);
+
+ for (i = 0; i < printer->num_history; i ++)
+ copy_attrs(history->values[i].collection = ippNew(),
+ printer->history[i], NULL, IPP_TAG_ZERO, 0);
+ }
}
- con->response->request.status.status_code = IPP_OK;
+ con->response->request.status.status_code = requested ? IPP_OK_SUBST : IPP_OK;
}
/*
- * End of "$Id: ipp.c,v 1.127.2.49 2003/03/13 03:35:00 mike Exp $".
+ * End of "$Id: ipp.c,v 1.127.2.50 2003/03/19 06:07:42 mike Exp $".
*/
/*
- * "$Id: job.c,v 1.124.2.55 2003/03/17 14:17:31 mike Exp $"
+ * "$Id: job.c,v 1.124.2.56 2003/03/19 06:07:48 mike Exp $"
*
* Job management routines for the Common UNIX Printing System (CUPS).
*
loglevel = L_PAGE;
message = job->buffer + 5;
}
+ else if (strncmp(job->buffer, "STATE:", 6) == 0)
+ {
+ loglevel = L_STATE;
+ message = job->buffer + 6;
+ }
else
{
loglevel = L_DEBUG;
LogPage(job, message);
}
+ else if (loglevel == L_STATE)
+ SetPrinterReasons(job->printer, message);
else
{
/*
/*
- * End of "$Id: job.c,v 1.124.2.55 2003/03/17 14:17:31 mike Exp $".
+ * End of "$Id: job.c,v 1.124.2.56 2003/03/19 06:07:48 mike Exp $".
*/
/*
- * "$Id: printers.c,v 1.93.2.40 2003/03/10 21:22:23 mike Exp $"
+ * "$Id: printers.c,v 1.93.2.41 2003/03/19 06:07:50 mike Exp $"
*
* Printer routines for the Common UNIX Printing System (CUPS).
*
*
* 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.
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...
}
+/*
+ * '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.
*/
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
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);
}
+/*
+ * 'SetPrinterReasons()' - Set/update the reasons strings.
+ */
+
+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 */
+
+
+ if (s[0] == '-' || s[0] == '+')
+ {
+ /*
+ * Add/remove reasons...
+ */
+
+ sptr = s + 1;
+ }
+ else
+ {
+ /*
+ * Replace reasons...
+ */
+
+ sptr = s;
+
+ for (i = 0; i < p->num_reasons; i ++)
+ free(p->reasons[i]);
+
+ p->num_reasons = 0;
+ }
+
+ /*
+ * Loop through all of the reasons...
+ */
+
+ while (*sptr)
+ {
+ /*
+ * Skip leading whitespace and commas...
+ */
+
+ while (isspace(*sptr) || *sptr == ',')
+ sptr ++;
+
+ for (rptr = reason; *sptr && !isspace(*sptr) && *sptr != ','; sptr ++)
+ if (rptr < (reason + sizeof(reason) - 1))
+ *rptr++ = *sptr;
+
+ if (rptr == reason)
+ break;
+
+ *rptr = '\0';
+
+ if (s[0] == '-')
+ {
+ /*
+ * Remove reason...
+ */
+
+ for (i = 0; i < p->num_reasons; i ++)
+ if (!strcasecmp(reason, p->reasons[i]))
+ {
+ /*
+ * Found a match, so remove it...
+ */
+
+ p->num_reasons --;
+ free(p->reasons[i]);
+
+ 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 ++;
+ }
+ }
+ }
+}
+
+
/*
* 'SetPrinterState()' - Update the current state of a printer.
*/
* 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)...
/*
- * End of "$Id: printers.c,v 1.93.2.40 2003/03/10 21:22:23 mike Exp $".
+ * End of "$Id: printers.c,v 1.93.2.41 2003/03/19 06:07:50 mike Exp $".
*/
/*
- * "$Id: printers.h,v 1.22.2.10 2003/03/10 21:05:32 mike Exp $"
+ * "$Id: printers.h,v 1.22.2.11 2003/03/19 06:07:52 mike Exp $"
*
* Printer definitions for the Common UNIX Printing System (CUPS) scheduler.
*
int accepting; /* Accepting jobs? */
ipp_pstate_t state; /* Printer state */
char state_message[1024]; /* Printer state message */
- ipp_attribute_t *state_reasons; /* Printer state reasons */
+ int num_reasons; /* Number of printer-state-reasons */
+ char *reasons[16]; /* printer-state-reasons strings */
time_t state_time; /* Time at this state */
char *job_sheets[2]; /* Banners/job sheets */
cups_ptype_t type; /* Printer type (color, small, etc.) */
int deny_users, /* 1 = deny, 0 = allow */
num_users; /* Number of allowed/denied users */
const char **users; /* Allowed/denied users */
+ int num_history; /* Number of history collections */
+ ipp_t **history; /* History data */
} printer_t;
extern printer_t *AddPrinter(const char *name);
extern void AddPrinterFilter(printer_t *p, const char *filter);
+extern void AddPrinterHistory(printer_t *p);
extern void AddPrinterUser(printer_t *p, const char *username);
extern quota_t *AddQuota(printer_t *p, const char *username);
extern void DeleteAllPrinters(void);
extern void LoadAllPrinters(void);
extern void SaveAllPrinters(void);
extern void SetPrinterAttrs(printer_t *p);
+extern void SetPrinterReasons(printer_t *p, const char *s);
extern void SetPrinterState(printer_t *p, ipp_pstate_t s);
extern void SortPrinters(void);
#define StartPrinter(p) SetPrinterState((p), IPP_PRINTER_IDLE)
/*
- * End of "$Id: printers.h,v 1.22.2.10 2003/03/10 21:05:32 mike Exp $".
+ * End of "$Id: printers.h,v 1.22.2.11 2003/03/19 06:07:52 mike Exp $".
*/