* cancel_job() - Cancel a print job.
* cancel_subscription() - Cancel a subscription.
* check_quotas() - Check quotas for a printer and user.
+ * check_rss_recipient() - Check that we do not have a duplicate RSS
+ * feed URI.
* copy_attribute() - Copy a single attribute.
* copy_attrs() - Copy attributes from one request to another.
* copy_banner() - Copy a banner file to the requests directory
static void cancel_all_jobs(cupsd_client_t *con, ipp_attribute_t *uri);
static void cancel_job(cupsd_client_t *con, ipp_attribute_t *uri);
static void cancel_subscription(cupsd_client_t *con, int id);
+static int check_rss_recipient(const char *recipient);
static int check_quotas(cupsd_client_t *con, cupsd_printer_t *p);
static ipp_attribute_t *copy_attribute(ipp_t *to, ipp_attribute_t *attr,
int quickcopy);
if (dtype & CUPS_PRINTER_CLASS)
{
- cupsdSaveAllClasses();
+ cupsdMarkDirty(CUPSD_DIRTY_CLASSES);
cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" now accepting jobs (\"%s\").",
printer->name, get_username(con));
}
else
{
- cupsdSaveAllPrinters();
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
cupsdLogMessage(CUPSD_LOG_INFO,
"Printer \"%s\" now accepting jobs (\"%s\").",
*/
cupsdSetPrinterAttrs(pclass);
- cupsdSaveAllClasses();
+ cupsdMarkDirty(CUPSD_DIRTY_CLASSES);
if (need_restart_job && pclass->job)
{
if (need_restart_job)
cupsdCheckJobs();
- cupsdWritePrintcap();
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
if (modify)
{
job->num_files ++;
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
+
return (0);
}
send_http_error(con, status, printer);
return (NULL);
}
- else if ((printer->type & CUPS_PRINTER_AUTHENTICATED) &&
+ else if (printer->num_auth_info_required > 0 &&
+ strcmp(printer->auth_info_required[0], "none") &&
!con->username[0] && !auth_info)
{
send_http_error(con, HTTP_UNAUTHORIZED, printer);
}
}
+ if ((attr = ippFindAttribute(con->request, "job-sheets",
+ IPP_TAG_ZERO)) != NULL)
+ {
+ if (attr->value_tag != IPP_TAG_KEYWORD &&
+ attr->value_tag != IPP_TAG_NAME)
+ {
+ send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-sheets value type!"));
+ return (NULL);
+ }
+
+ if (attr->num_values > 2)
+ {
+ send_ipp_status(con, IPP_BAD_REQUEST,
+ _("Too many job-sheets values (%d > 2)!"),
+ attr->num_values);
+ return (NULL);
+ }
+
+ for (i = 0; i < attr->num_values; i ++)
+ if (strcmp(attr->values[i].string.text, "none") &&
+ !cupsdFindBanner(attr->values[i].string.text))
+ {
+ send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-sheets value \"%s\"!"),
+ attr->values[i].string.text);
+ return (NULL);
+ }
+ }
+
if ((attr = ippFindAttribute(con->request, "number-up",
IPP_TAG_INTEGER)) != NULL)
{
job->dtype = printer->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT |
CUPS_PRINTER_REMOTE);
job->attrs = con->request;
+ job->dirty = 1;
con->request = ippNewRequest(job->attrs->request.op.operation_id);
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
+
add_job_uuid(con, job);
apply_printer_defaults(printer, job);
job->id, attr->values[0].string.text);
if ((kbytes = copy_banner(con, job, attr->values[0].string.text)) < 0)
+ {
+ cupsdDeleteJob(job);
return (NULL);
+ }
cupsdUpdateQuota(printer, job->username, 0, kbytes);
}
{
if (!strcmp(attr->name, "notify-recipient-uri") &&
attr->value_tag == IPP_TAG_URI)
+ {
+ /*
+ * Validate the recipient scheme against the ServerBin/notifier
+ * directory...
+ */
+
+ char notifier[1024], /* Notifier filename */
+ scheme[HTTP_MAX_URI], /* Scheme portion of URI */
+ userpass[HTTP_MAX_URI], /* Username portion of URI */
+ host[HTTP_MAX_URI], /* Host portion of URI */
+ resource[HTTP_MAX_URI]; /* Resource portion of URI */
+ int port; /* Port portion of URI */
+
+
recipient = attr->values[0].string.text;
+
+ if (httpSeparateURI(HTTP_URI_CODING_ALL, recipient,
+ scheme, sizeof(scheme), userpass, sizeof(userpass),
+ host, sizeof(host), &port,
+ resource, sizeof(resource)) < HTTP_URI_OK)
+ {
+ send_ipp_status(con, IPP_NOT_POSSIBLE,
+ _("Bad notify-recipient-uri URI \"%s\"!"), recipient);
+ ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
+ "notify-status-code", IPP_URI_SCHEME);
+ return;
+ }
+
+ snprintf(notifier, sizeof(notifier), "%s/notifier/%s", ServerBin,
+ scheme);
+ if (access(notifier, X_OK))
+ {
+ send_ipp_status(con, IPP_NOT_POSSIBLE,
+ _("notify-recipient-uri URI \"%s\" uses unknown "
+ "scheme!"), recipient);
+ ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
+ "notify-status-code", IPP_URI_SCHEME);
+ return;
+ }
+
+ if (!strcmp(scheme, "rss") && !check_rss_recipient(recipient))
+ {
+ send_ipp_status(con, IPP_NOT_POSSIBLE,
+ _("notify-recipient-uri URI \"%s\" is already used!"),
+ recipient);
+ ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
+ "notify-status-code", IPP_ATTRIBUTES);
+ return;
+ }
+ }
else if (!strcmp(attr->name, "notify-pull-method") &&
attr->value_tag == IPP_TAG_KEYWORD)
+ {
pullmethod = attr->values[0].string.text;
+
+ if (strcmp(pullmethod, "ippget"))
+ {
+ send_ipp_status(con, IPP_NOT_POSSIBLE,
+ _("Bad notify-pull-method \"%s\"!"), pullmethod);
+ ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
+ "notify-status-code", IPP_ATTRIBUTES);
+ return;
+ }
+ }
else if (!strcmp(attr->name, "notify-charset") &&
attr->value_tag == IPP_TAG_CHARSET &&
strcmp(attr->values[0].string.text, "us-ascii") &&
attr = attr->next;
}
- cupsdSaveAllSubscriptions();
+ cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS);
/*
* Remove all of the subscription attributes from the job request...
*/
cupsdSetPrinterAttrs(printer);
- cupsdSaveAllPrinters();
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
if (need_restart_job && printer->job)
{
if (need_restart_job)
cupsdCheckJobs();
- cupsdWritePrintcap();
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
if (modify)
{
}
+/*
+ * 'check_rss_recipient()' - Check that we do not have a duplicate RSS feed URI.
+ */
+
+static int /* O - 1 if OK, 0 if not */
+check_rss_recipient(
+ const char *recipient) /* I - Recipient URI */
+{
+ cupsd_subscription_t *sub; /* Current subscription */
+
+
+ for (sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions);
+ sub;
+ sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions))
+ if (sub->recipient)
+ {
+ /*
+ * Compare the URIs up to the first ?...
+ */
+
+ const char *r1, *r2;
+
+ for (r1 = recipient, r2 = sub->recipient;
+ *r1 == *r2 && *r1 && *r1 != '?' && *r2 && *r2 != '?';
+ r1 ++, r2 ++);
+
+ if (*r1 == *r2)
+ return (0);
+ }
+
+ return (1);
+}
+
+
/*
* 'check_quotas()' - Check quotas for a printer and user.
*/
ipp_attribute_t *attr; /* Attribute */
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_banner(%p[%d], %p[%d], %s)",
+ cupsdLogMessage(CUPSD_LOG_DEBUG2,
+ "copy_banner(con=%p[%d], job=%p[%d], name=\"%s\")",
con, con ? con->http.fd : -1, job, job->id,
name ? name : "(null)");
if ((out = cupsFileOpen(filename, "w")) == NULL)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "copy_banner: Unable to create banner job file %s - %s",
+ "Unable to create banner job file %s - %s",
filename, strerror(errno));
job->num_files --;
return (0);
cupsFileClose(out);
unlink(filename);
cupsdLogMessage(CUPSD_LOG_ERROR,
- "copy_banner: Unable to open banner template file %s - %s",
+ "Unable to open banner template file %s - %s",
filename, strerror(errno));
job->num_files --;
return (0);
* Save and log the job...
*/
- cupsdSaveJob(job);
-
cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Queued on \"%s\" by \"%s\".",
job->id, job->dest, job->username);
}
for (attr = con->request->attrs; attr; attr = attr->next)
{
if (attr->group_tag != IPP_TAG_ZERO)
- cupsdLogMessage(CUPSD_LOG_DEBUG, "g%04x v%04x %s", attr->group_tag,
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "g%04x v%04x %s", attr->group_tag,
attr->value_tag, attr->name);
else
- cupsdLogMessage(CUPSD_LOG_DEBUG, "----SEP----");
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "----SEP----");
}
#endif /* DEBUG */
"notify-status-code", IPP_URI_SCHEME);
return;
}
+
+ if (!strcmp(scheme, "rss") && !check_rss_recipient(recipient))
+ {
+ send_ipp_status(con, IPP_NOT_POSSIBLE,
+ _("notify-recipient-uri URI \"%s\" is already used!"),
+ recipient);
+ ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
+ "notify-status-code", IPP_ATTRIBUTES);
+ return;
+ }
}
else if (!strcmp(attr->name, "notify-pull-method") &&
attr->value_tag == IPP_TAG_KEYWORD)
attr = attr->next;
}
- cupsdSaveAllSubscriptions();
-
+ cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS);
}
printer->name, get_username(con));
cupsdDeletePrinter(printer, 0);
- cupsdSaveAllClasses();
+ cupsdMarkDirty(CUPSD_DIRTY_CLASSES);
}
else
{
printer->name, get_username(con));
cupsdDeletePrinter(printer, 0);
- cupsdSaveAllPrinters();
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
}
- cupsdWritePrintcap();
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
/*
* Return with no errors...
completed = 0;
list = Jobs;
}
+ else if (attr && !strcmp(attr->values[0].string.text, "printing"))
+ {
+ completed = 0;
+ list = PrintingJobs;
+ }
else
{
completed = 0;
IPP_TAG_INTEGER)) != NULL)
limit = attr->values[0].integer;
else
- limit = 1000000;
+ limit = 0;
if ((attr = ippFindAttribute(con->request, "first-job-id",
IPP_TAG_INTEGER)) != NULL)
*/
for (count = 0, job = (cupsd_job_t *)cupsArrayFirst(list);
- count < limit && job;
+ (limit <= 0 || count < limit) && job;
job = (cupsd_job_t *)cupsArrayNext(list))
{
/*
cupsdLogMessage(CUPSD_LOG_DEBUG, "[Job %d] hold_until = %d", job->id,
(int)job->hold_until);
- cupsdSaveJob(job);
-
/*
* Start the job if possible...
*/
if (dtype & CUPS_PRINTER_CLASS)
{
- cupsdSaveAllClasses();
+ cupsdMarkDirty(CUPSD_DIRTY_CLASSES);
cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" rejecting jobs (\"%s\").",
printer->name, get_username(con));
}
else
{
- cupsdSaveAllPrinters();
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" rejecting jobs (\"%s\").",
printer->name, get_username(con));
sub->expire = sub->lease ? time(NULL) + sub->lease : 0;
- cupsdSaveAllSubscriptions();
+ cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS);
con->response->request.status.status_code = IPP_OK;
}
}
- cupsdSaveJob(job);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
/*
* Start the job if possible... Since cupsdCheckJobs() can cancel a
job->state->values[0].integer = IPP_JOB_HELD;
job->state_value = IPP_JOB_HELD;
job->hold_until = time(NULL) + 60;
- cupsdSaveJob(job);
+ job->dirty = 1;
+
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
}
}
DefaultPrinter = printer;
- cupsdSaveAllPrinters();
- cupsdSaveAllClasses();
-
- cupsdWritePrintcap();
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTERS | CUPSD_DIRTY_CLASSES |
+ CUPSD_DIRTY_REMOTE | CUPSD_DIRTY_PRINTCAP);
cupsdLogMessage(CUPSD_LOG_INFO,
"Default destination set to \"%s\" by \"%s\".",
* Save the job...
*/
- cupsdSaveJob(job);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
/*
* Send events as needed...