/*
- * "$Id: ipp.c 7014 2007-10-10 21:57:43Z mike $"
+ * "$Id: ipp.c 7682 2008-06-21 00:06:02Z mike $"
*
* IPP routines for the Common UNIX Printing System (CUPS) scheduler.
*
* 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);
* Yes...
*/
- cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Adding end banner page \"%s\".",
- job->id, attr->values[1].string.text);
+ cupsdLogJob(job, CUPSD_LOG_INFO, "Adding end banner page \"%s\".",
+ attr->values[1].string.text);
if ((kbytes = copy_banner(NULL, job, attr->values[1].string.text)) < 0)
return (-1);
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);
cupsdSetString(&attr->values[0].string.text, Classification);
- cupsdLogMessage(CUPSD_LOG_NOTICE, "[Job %d] CLASSIFICATION FORCED "
- "job-sheets=\"%s,none\", "
- "job-originating-user-name=\"%s\"",
- job->id, Classification, job->username);
+ cupsdLogJob(job, CUPSD_LOG_NOTICE, "CLASSIFICATION FORCED "
+ "job-sheets=\"%s,none\", "
+ "job-originating-user-name=\"%s\"",
+ Classification, job->username);
}
else if (attr->num_values == 2 &&
strcmp(attr->values[0].string.text,
cupsdSetString(&attr->values[1].string.text, attr->values[0].string.text);
- cupsdLogMessage(CUPSD_LOG_NOTICE, "[Job %d] CLASSIFICATION FORCED "
- "job-sheets=\"%s,%s\", "
- "job-originating-user-name=\"%s\"",
- job->id, attr->values[0].string.text,
- attr->values[1].string.text, job->username);
+ cupsdLogJob(job, CUPSD_LOG_NOTICE, "CLASSIFICATION FORCED "
+ "job-sheets=\"%s,%s\", "
+ "job-originating-user-name=\"%s\"",
+ attr->values[0].string.text,
+ attr->values[1].string.text, job->username);
}
else if (strcmp(attr->values[0].string.text, Classification) &&
strcmp(attr->values[0].string.text, "none") &&
strcmp(attr->values[1].string.text, "none"))))
{
if (attr->num_values == 1)
- cupsdLogMessage(CUPSD_LOG_NOTICE,
- "[Job %d] CLASSIFICATION OVERRIDDEN "
- "job-sheets=\"%s\", "
- "job-originating-user-name=\"%s\"",
- job->id, attr->values[0].string.text, job->username);
+ cupsdLogJob(job, CUPSD_LOG_NOTICE,
+ "CLASSIFICATION OVERRIDDEN "
+ "job-sheets=\"%s\", "
+ "job-originating-user-name=\"%s\"",
+ attr->values[0].string.text, job->username);
else
- cupsdLogMessage(CUPSD_LOG_NOTICE,
- "[Job %d] CLASSIFICATION OVERRIDDEN "
- "job-sheets=\"%s,%s\",fffff "
- "job-originating-user-name=\"%s\"",
- job->id, attr->values[0].string.text,
- attr->values[1].string.text, job->username);
+ cupsdLogJob(job, CUPSD_LOG_NOTICE,
+ "CLASSIFICATION OVERRIDDEN "
+ "job-sheets=\"%s,%s\",fffff "
+ "job-originating-user-name=\"%s\"",
+ attr->values[0].string.text,
+ attr->values[1].string.text, job->username);
}
}
else if (strcmp(attr->values[0].string.text, Classification) &&
}
if (attr->num_values > 1)
- cupsdLogMessage(CUPSD_LOG_NOTICE,
- "[Job %d] CLASSIFICATION FORCED "
- "job-sheets=\"%s,%s\", "
- "job-originating-user-name=\"%s\"",
- job->id, attr->values[0].string.text,
- attr->values[1].string.text, job->username);
+ cupsdLogJob(job, CUPSD_LOG_NOTICE,
+ "CLASSIFICATION FORCED "
+ "job-sheets=\"%s,%s\", "
+ "job-originating-user-name=\"%s\"",
+ attr->values[0].string.text,
+ attr->values[1].string.text, job->username);
else
- cupsdLogMessage(CUPSD_LOG_NOTICE,
- "[Job %d] CLASSIFICATION FORCED "
- "job-sheets=\"%s\", "
- "job-originating-user-name=\"%s\"",
- job->id, Classification, job->username);
+ cupsdLogJob(job, CUPSD_LOG_NOTICE,
+ "CLASSIFICATION FORCED "
+ "job-sheets=\"%s\", "
+ "job-originating-user-name=\"%s\"",
+ Classification, job->username);
}
}
if (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)))
{
- cupsdLogMessage(CUPSD_LOG_INFO,
- "[Job %d] Adding start banner page \"%s\".",
- job->id, attr->values[0].string.text);
+ cupsdLogJob(job, CUPSD_LOG_INFO, "Adding start banner page \"%s\".",
+ 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)
{
language = (char *)cupsArrayNext(languages))
{
if (iccfile)
- attr = _ppdLocalizedAttr(ppd, "cupsICCProfile", name, language);
+ {
+ if ((attr = _ppdLocalizedAttr(ppd, "cupsICCProfile", name,
+ language)) == NULL)
+ attr = _ppdLocalizedAttr(ppd, "APTiogaProfile", name, language);
+ }
else
attr = _ppdLocalizedAttr(ppd, "ColorModel", name, language);
selector[PPD_MAX_NAME];
/* Profile selection string */
ppd_file_t *ppd; /* PPD file */
- ppd_attr_t *attr, /* cupsICCProfile attributes */
- *profileid_attr;/* cupsProfileID attribute */
+ ppd_attr_t *attr, /* Profile attributes */
+ *profileid_attr,/* cupsProfileID attribute */
+ *q1_attr, /* ColorModel (or other) qualifier */
+ *q2_attr, /* MediaType (or other) qualifier */
+ *q3_attr; /* Resolution (or other) qualifier */
+ char q_keyword[PPD_MAX_NAME];
+ /* Qualifier keyword */
+ const char *q1_choice, /* ColorModel (or other) choice */
+ *q2_choice, /* MediaType (or other) choice */
+ *q3_choice; /* Resolution (or other) choice */
+ const char *profile_key; /* Profile keyword */
ppd_option_t *cm_option; /* Color model option */
- ppd_choice_t *cm_choice, /* Color model choice */
- *q1_choice, /* ColorModel (or other) qualifier */
- *q2_choice, /* MediaType (or other) qualifier */
- *q3_choice; /* Resolution (or other) qualifier */
+ ppd_choice_t *cm_choice; /* Color model choice */
int num_profiles; /* Number of profiles */
CMError error; /* Last error */
unsigned device_id, /* Printer device ID */
if ((ppd = ppdOpenFile(ppdfile)) == NULL)
return;
- ppdMarkDefaults(ppd);
-
/*
* See if we have any profiles...
*/
- for (num_profiles = 0, attr = ppdFindAttr(ppd, "cupsICCProfile", NULL);
- attr;
- attr = ppdFindNextAttr(ppd, "cupsICCProfile", NULL))
+ if ((attr = ppdFindAttr(ppd, "APTiogaProfile", NULL)) != NULL)
+ profile_key = "APTiogaProfile";
+ else
+ {
+ attr = ppdFindAttr(ppd, "cupsICCProfile", NULL);
+ profile_key = "cupsICCProfile";
+ }
+
+ for (num_profiles = 0; attr; attr = ppdFindNextAttr(ppd, profile_key, NULL))
if (attr->spec[0] && attr->value && attr->value[0])
{
if (attr->value[0] != '/')
num_profiles ++;
}
+
/*
* If we have profiles, add them...
*/
if (num_profiles > 0)
{
- /*
- * Figure out the default profile selectors...
- */
+ if (profile_key[0] == 'A')
+ {
+ /*
+ * For Tioga PPDs, get the default profile using the DefaultAPTiogaProfile
+ * attribute...
+ */
- if ((attr = ppdFindAttr(ppd, "cupsICCQualifier1", NULL)) != NULL &&
- attr->value && attr->value[0])
- q1_choice = ppdFindMarkedChoice(ppd, attr->value);
- else
- q1_choice = ppdFindMarkedChoice(ppd, "ColorModel");
+ if ((attr = ppdFindAttr(ppd, "DefaultAPTiogaProfile", NULL)) != NULL &&
+ attr->value)
+ default_profile_id = atoi(attr->value);
- if ((attr = ppdFindAttr(ppd, "cupsICCQualifier2", NULL)) != NULL &&
- attr->value && attr->value[0])
- q2_choice = ppdFindMarkedChoice(ppd, attr->value);
+ q1_choice = q2_choice = q3_choice = NULL;
+ }
else
- q2_choice = ppdFindMarkedChoice(ppd, "MediaType");
+ {
+ /*
+ * For CUPS PPDs, figure out the default profile selector values...
+ */
- if ((attr = ppdFindAttr(ppd, "cupsICCQualifier3", NULL)) != NULL &&
- attr->value && attr->value[0])
- q3_choice = ppdFindMarkedChoice(ppd, attr->value);
- else
- q3_choice = ppdFindMarkedChoice(ppd, "Resolution");
+ if ((attr = ppdFindAttr(ppd, "cupsICCQualifier1", NULL)) != NULL &&
+ attr->value && attr->value[0])
+ {
+ snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value);
+ q1_attr = ppdFindAttr(ppd, q_keyword, NULL);
+ }
+ else if ((q1_attr = ppdFindAttr(ppd, "DefaultColorModel", NULL)) == NULL)
+ q1_attr = ppdFindAttr(ppd, "DefaultColorSpace", NULL);
+
+ if (q1_attr && q1_attr->value && q1_attr->value[0])
+ q1_choice = q1_attr->value;
+ else
+ q1_choice = "";
+
+ if ((attr = ppdFindAttr(ppd, "cupsICCQualifier2", NULL)) != NULL &&
+ attr->value && attr->value[0])
+ {
+ snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value);
+ q2_attr = ppdFindAttr(ppd, q_keyword, NULL);
+ }
+ else
+ q2_attr = ppdFindAttr(ppd, "DefaultMediaType", NULL);
+
+ if (q2_attr && q2_attr->value && q2_attr->value[0])
+ q2_choice = q2_attr->value;
+ else
+ q2_choice = NULL;
+
+ if ((attr = ppdFindAttr(ppd, "cupsICCQualifier3", NULL)) != NULL &&
+ attr->value && attr->value[0])
+ {
+ snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value);
+ q3_attr = ppdFindAttr(ppd, q_keyword, NULL);
+ }
+ else
+ q3_attr = ppdFindAttr(ppd, "DefaultResolution", NULL);
+
+ if (q3_attr && q3_attr->value && q3_attr->value[0])
+ q3_choice = q3_attr->value;
+ else
+ q3_choice = NULL;
+ }
/*
* Build the array of profiles...
languages = _ppdGetLanguages(ppd);
for (profile = profiles->profiles,
- attr = ppdFindAttr(ppd, "cupsICCProfile", NULL);
+ attr = ppdFindAttr(ppd, profile_key, NULL);
attr;
- attr = ppdFindNextAttr(ppd, "cupsICCProfile", NULL))
+ attr = ppdFindNextAttr(ppd, profile_key, NULL))
if (attr->spec[0] && attr->value && attr->value[0])
{
/*
if (access(iccfile, 0))
continue;
- cupsArraySave(ppd->sorted_attrs);
+ if (profile_key[0] == 'c')
+ {
+ cupsArraySave(ppd->sorted_attrs);
- if ((profileid_attr = ppdFindAttr(ppd, "cupsProfileID",
- attr->spec)) != NULL &&
- profileid_attr->value && isdigit(profileid_attr->value[0] & 255))
- profile_id = (unsigned)strtoul(profileid_attr->value, NULL, 10);
- else
- profile_id = _ppdHashName(attr->spec);
+ if ((profileid_attr = ppdFindAttr(ppd, "cupsProfileID",
+ attr->spec)) != NULL &&
+ profileid_attr->value && isdigit(profileid_attr->value[0] & 255))
+ profile_id = (unsigned)strtoul(profileid_attr->value, NULL, 10);
+ else
+ profile_id = _ppdHashName(attr->spec);
- cupsArrayRestore(ppd->sorted_attrs);
+ cupsArrayRestore(ppd->sorted_attrs);
+ }
+ else
+ profile_id = atoi(attr->spec);
apple_init_profile(ppd, languages, profile, profile_id, attr->spec,
attr->text[0] ? attr->text : attr->spec, iccfile);
* See if this is the default profile...
*/
- if (!default_profile_id && q1_choice)
+ if (!default_profile_id)
{
if (q2_choice)
{
if (q3_choice)
{
snprintf(selector, sizeof(selector), "%s.%s.%s",
- q1_choice->choice, q2_choice->choice, q3_choice->choice);
+ q1_choice, q2_choice, q3_choice);
if (!strcmp(selector, attr->spec))
default_profile_id = profile_id;
}
if (!default_profile_id)
{
- snprintf(selector, sizeof(selector), "%s.%s.", q1_choice->choice,
- q2_choice->choice);
+ snprintf(selector, sizeof(selector), "%s.%s.", q1_choice,
+ q2_choice);
if (!strcmp(selector, attr->spec))
default_profile_id = profile_id;
}
if (!default_profile_id && q3_choice)
{
- snprintf(selector, sizeof(selector), "%s..%s", q1_choice->choice,
- q3_choice->choice);
+ snprintf(selector, sizeof(selector), "%s..%s", q1_choice,
+ q3_choice);
if (!strcmp(selector, attr->spec))
default_profile_id = profile_id;
}
if (!default_profile_id)
{
- snprintf(selector, sizeof(selector), "%s..", q1_choice->choice);
+ snprintf(selector, sizeof(selector), "%s..", q1_choice);
if (!strcmp(selector, attr->spec))
default_profile_id = profile_id;
}
cupsdReleaseJob(job);
- cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Authenticated by \"%s\".", jobid,
- con->username);
+ cupsdLogJob(job, CUPSD_LOG_INFO, "Authenticated by \"%s\".", con->username);
}
if (purge)
cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Purged by \"%s\".", jobid,
- username);
+ username);
else
cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Canceled by \"%s\".", jobid,
- username);
+ username);
con->response->request.status.status_code = IPP_OK;
}
}
+/*
+ * '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.
*/
*/
#ifdef HAVE_MBR_UID_TO_UUID
- if ((mbr_err = mbr_group_name_to_uuid((char *)p->users[i] + 1,
- grp_uuid)) != 0)
+ if (p->users[i][1] == '#')
+ {
+ if (uuid_parse((char *)p->users[i] + 2, grp_uuid))
+ uuid_clear(grp_uuid);
+ }
+ else if ((mbr_err = mbr_group_name_to_uuid((char *)p->users[i] + 1,
+ grp_uuid)) != 0)
{
/*
* Invalid ACL entries are ignored for matching; just record a
"Access control entry \"%s\" not a valid group name; "
"entry ignored", p->users[i]);
}
- else
- {
- if ((mbr_err = mbr_check_membership(usr_uuid, grp_uuid,
- &is_member)) != 0)
- {
- /*
- * At this point, there should be no errors, but check anyways...
- */
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "check_quotas: group \"%s\" membership check "
- "failed (err=%d)", p->users[i] + 1, mbr_err);
- is_member = 0;
- }
-
- /*
- * Stop if we found a match...
+ if ((mbr_err = mbr_check_membership(usr_uuid, grp_uuid,
+ &is_member)) != 0)
+ {
+ /*
+ * At this point, there should be no errors, but check anyways...
*/
- if (is_member)
- break;
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "check_quotas: group \"%s\" membership check "
+ "failed (err=%d)", p->users[i] + 1, mbr_err);
+ is_member = 0;
}
+
+ /*
+ * Stop if we found a match...
+ */
+
+ if (is_member)
+ break;
+
#else
if (cupsdCheckGroup(username, pw, p->users[i] + 1))
break;
#ifdef HAVE_MBR_UID_TO_UUID
else
{
- if ((mbr_err = mbr_user_name_to_uuid((char *)p->users[i],
- usr2_uuid)) != 0)
+ if (p->users[i][0] == '#')
+ {
+ if (uuid_parse((char *)p->users[i] + 1, usr2_uuid))
+ uuid_clear(usr2_uuid);
+ }
+ else if ((mbr_err = mbr_user_name_to_uuid((char *)p->users[i],
+ usr2_uuid)) != 0)
{
/*
* Invalid ACL entries are ignored for matching; just record a
"Access control entry \"%s\" not a valid user name; "
"entry ignored", p->users[i]);
}
- else
- {
- if ((mbr_err = mbr_check_membership(usr_uuid, usr2_uuid,
- &is_member)) != 0)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "check_quotas: User \"%s\" identity check failed "
- "(err=%d)", p->users[i], mbr_err);
- is_member = 0;
- }
- if (is_member)
- break;
+ if ((mbr_err = mbr_check_membership(usr_uuid, usr2_uuid,
+ &is_member)) != 0)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "check_quotas: User \"%s\" identity check failed "
+ "(err=%d)", p->users[i], mbr_err);
+ is_member = 0;
}
+
+ if (is_member)
+ break;
}
#else
else if (!strcasecmp(username, p->users[i]))
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);
ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
"marker-change-time", printer->marker_time);
+ if (printer->num_printers > 0 &&
+ (!ra || cupsArrayFind(ra, "member-uris")))
+ {
+ ipp_attribute_t *member_uris; /* member-uris attribute */
+ cupsd_printer_t *p2; /* Printer in class */
+ ipp_attribute_t *p2_uri; /* printer-uri-supported for class printer */
+
+
+ if ((member_uris = ippAddStrings(con->response, IPP_TAG_PRINTER,
+ IPP_TAG_URI, "member-uris",
+ printer->num_printers, NULL,
+ NULL)) != NULL)
+ {
+ for (i = 0; i < printer->num_printers; i ++)
+ {
+ p2 = printer->printers[i];
+
+ if ((p2_uri = ippFindAttribute(p2->attrs, "printer-uri-supported",
+ IPP_TAG_URI)) != NULL)
+ member_uris->values[i].string.text =
+ _cupsStrAlloc(p2_uri->values[0].string.text);
+ else
+ {
+ httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri,
+ sizeof(printer_uri), "ipp", NULL, con->servername,
+ con->serverport,
+ (p2->type & CUPS_PRINTER_CLASS) ?
+ "/classes/%s" : "/printers/%s", p2->name);
+ member_uris->values[i].string.text = _cupsStrAlloc(printer_uri);
+ }
+ }
+ }
+ }
+
if (printer->alert && (!ra || cupsArrayFind(ra, "printer-alert")))
ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_STRING,
"printer-alert", NULL, printer->alert);
* Save and log the job...
*/
- cupsdSaveJob(job);
-
- cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Queued on \"%s\" by \"%s\".",
- job->id, job->dest, job->username);
+ cupsdLogJob(job, CUPSD_LOG_INFO, "Queued on \"%s\" by \"%s\".",
+ job->dest, job->username);
}
cupsArrayAdd(ra, "pdl-override-supported");
cupsArrayAdd(ra, "printer-alert");
cupsArrayAdd(ra, "printer-alert-description");
+ cupsArrayAdd(ra, "printer-commands");
cupsArrayAdd(ra, "printer-current-time");
cupsArrayAdd(ra, "printer-driver-installer");
+ cupsArrayAdd(ra, "printer-dns-sd-name");
cupsArrayAdd(ra, "printer-info");
cupsArrayAdd(ra, "printer-is-accepting-jobs");
cupsArrayAdd(ra, "printer-location");
cupsArrayAdd(ra, "printer-state");
cupsArrayAdd(ra, "printer-state-message");
cupsArrayAdd(ra, "printer-state-reasons");
+ cupsArrayAdd(ra, "printer-type");
cupsArrayAdd(ra, "printer-up-time");
cupsArrayAdd(ra, "printer-uri-supported");
cupsArrayAdd(ra, "queued-job-count");
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))
{
/*
* access...
*/
- if (printer->num_users && username && !user_allowed(printer, username))
+ if (!(printer->type & CUPS_PRINTER_AUTHENTICATED) &&
+ printer->num_users && username && !user_allowed(printer, username))
continue;
/*
cupsdHoldJob(job);
- cupsdAddEvent(CUPSD_EVENT_JOB_STATE, job->printer, job,
+ cupsdAddEvent(CUPSD_EVENT_JOB_STATE, cupsdFindDest(job->dest), job,
"Job held by user.");
if ((newattr = ippFindAttribute(con->request, "job-hold-until",
cupsdSetJobHoldUntil(job, attr->values[0].string.text);
- cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, job->printer, job,
+ cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, cupsdFindDest(job->dest), job,
"Job job-hold-until value changed by user.");
}
- cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Held by \"%s\".", jobid,
- username);
+ cupsdLogJob(job, CUPSD_LOG_INFO, "Held by \"%s\".", username);
con->response->request.status.status_code = IPP_OK;
}
ipp_attribute_t *doc_name; /* document-name attribute */
- cupsdLogMessage(CUPSD_LOG_DEBUG, "print_job: auto-typing file...");
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Job ???] Auto-typing file...");
doc_name = ippFindAttribute(con->request, "document-name", IPP_TAG_NAME);
filetype = mimeFileType(MimeDatabase, con->filename,
if (!filetype)
filetype = mimeType(MimeDatabase, super, type);
+
+ cupsdLogMessage(CUPSD_LOG_INFO, "[Job ???] Request file type is %s/%s.",
+ filetype->super, filetype->type);
}
else
filetype = mimeType(MimeDatabase, super, type);
if ((job = add_job(con, printer, filetype)) == NULL)
return;
- cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Adding job file of type %s/%s.",
- job->id, filetype->super, filetype->type);
-
/*
* Update quota data...
*/
* Log and save the job...
*/
- cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Queued on \"%s\" by \"%s\".",
- job->id, job->dest, job->username);
- cupsdLogMessage(CUPSD_LOG_DEBUG, "[Job %d] hold_until = %d", job->id,
- (int)job->hold_until);
-
- cupsdSaveJob(job);
+ cupsdLogJob(job, CUPSD_LOG_INFO,
+ "File of type %s/%s queued by \"%s\".",
+ filetype->super, filetype->type, job->username);
+ cupsdLogJob(job, CUPSD_LOG_DEBUG, "hold_until=%d", (int)job->hold_until);
/*
* 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));
attr->value_tag = IPP_TAG_KEYWORD;
attr->values[0].string.text = _cupsStrAlloc("no-hold");
- cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, job->printer, job,
+ cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, cupsdFindDest(job->dest), job,
"Job job-hold-until value changed by user.");
}
cupsdReleaseJob(job);
- cupsdAddEvent(CUPSD_EVENT_JOB_STATE, job->printer, job,
+ cupsdAddEvent(CUPSD_EVENT_JOB_STATE, cupsdFindDest(job->dest), job,
"Job released by user.");
- cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Released by \"%s\".", jobid,
- username);
+ cupsdLogJob(job, CUPSD_LOG_INFO, "Released by \"%s\".", username);
con->response->request.status.status_code = IPP_OK;
}
sub->expire = sub->lease ? time(NULL) + sub->lease : 0;
- cupsdSaveAllSubscriptions();
+ cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS);
con->response->request.status.status_code = IPP_OK;
cupsdRestartJob(job);
- cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Restarted by \"%s\".", jobid,
- username);
+ cupsdLogJob(job, CUPSD_LOG_INFO, "Restarted by \"%s\".", username);
con->response->request.status.status_code = IPP_OK;
}
cupsdSetStringf(&(job->ccname), "KRB5CCNAME=FILE:%s",
krb5_cc_get_name(KerberosContext, job->ccache));
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "[Job %d] save_krb5_creds: %s", job->id,
- job->ccname);
+ cupsdLogJob(job, CUPSD_LOG_DEBUG2, "save_krb5_creds: %s", job->ccname);
# endif /* HAVE_KRB5_CC_NEW_UNIQUE || HAVE_HEIMDAL */
}
#endif /* HAVE_GSSAPI && HAVE_KRB5_H */
ipp_attribute_t *uri) /* I - Printer URI */
{
ipp_attribute_t *attr; /* Current attribute */
- ipp_attribute_t *format; /* Document-format attribute */
+ ipp_attribute_t *format; /* Request's document-format attribute */
+ ipp_attribute_t *jformat; /* Job's document-format attribute */
const char *default_format;/* document-format-default value */
int jobid; /* Job ID number */
cupsd_job_t *job; /* Current job */
struct stat fileinfo; /* File information */
int kbytes; /* Size of file */
int compression; /* Type of compression */
+ int start_job; /* Start the job? */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "send_document(%p[%d], %s)", con,
ipp_attribute_t *doc_name; /* document-name attribute */
- cupsdLogMessage(CUPSD_LOG_DEBUG, "send_document: auto-typing file...");
+ cupsdLogJob(job, CUPSD_LOG_DEBUG, "Auto-typing file...");
doc_name = ippFindAttribute(con->request, "document-name", IPP_TAG_NAME);
filetype = mimeFileType(MimeDatabase, con->filename,
if (!filetype)
filetype = mimeType(MimeDatabase, super, type);
+
+ cupsdLogJob(job, CUPSD_LOG_DEBUG, "Request file type is %s/%s.",
+ filetype->super, filetype->type);
}
else
filetype = mimeType(MimeDatabase, super, type);
+ jformat = ippFindAttribute(job->attrs, "document-format", IPP_TAG_MIMETYPE);
+
if (filetype &&
- (!format ||
+ (!jformat ||
(!strcmp(super, "application") && !strcmp(type, "octet-stream"))))
{
/*
snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super,
filetype->type);
- if (format)
+ if (jformat)
{
- _cupsStrFree(format->values[0].string.text);
+ _cupsStrFree(jformat->values[0].string.text);
- format->values[0].string.text = _cupsStrAlloc(mimetype);
+ jformat->values[0].string.text = _cupsStrAlloc(mimetype);
}
else
- ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE,
+ ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_MIMETYPE,
"document-format", NULL, mimetype);
}
else if (!filetype)
return;
}
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "send_document: request file type is %s/%s.",
- filetype->super, filetype->type);
-
/*
* Add the file to the job...
*/
cupsdClearString(&con->filename);
- cupsdLogMessage(CUPSD_LOG_INFO,
- "File of type %s/%s queued in job #%d by \"%s\".",
- filetype->super, filetype->type, job->id, job->username);
+ cupsdLogJob(job, CUPSD_LOG_INFO, "File of type %s/%s queued by \"%s\".",
+ filetype->super, filetype->type, job->username);
/*
* Start the job if this is the last document...
}
}
- cupsdSaveJob(job);
-
- /*
- * Start the job if possible... Since cupsdCheckJobs() can cancel a
- * job if it doesn't print, we need to re-find the job afterwards...
- */
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
- jobid = job->id;
-
- cupsdCheckJobs();
-
- job = cupsdFindJob(jobid);
+ start_job = 1;
}
else
{
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);
}
+
+ start_job = 0;
}
/*
ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", jobid);
ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_ENUM, "job-state",
- job ? job->state_value : IPP_JOB_CANCELED);
+ job->state_value);
add_job_state_reasons(con, job);
con->response->request.status.status_code = IPP_OK;
+
+ /*
+ * Start the job if necessary...
+ */
+
+ if (start_job)
+ cupsdCheckJobs();
}
{
http_status_t status; /* Policy status */
cups_ptype_t dtype; /* Destination type (printer/class) */
- cupsd_printer_t *printer; /* Printer */
+ cupsd_printer_t *printer, /* Printer */
+ *oldprinter; /* Old default printer */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "set_default(%p[%d], %s)", con,
* Set it as the default...
*/
+ oldprinter = DefaultPrinter;
DefaultPrinter = printer;
- cupsdSaveAllPrinters();
- cupsdSaveAllClasses();
+ if (oldprinter)
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, oldprinter, NULL,
+ "%s is no longer the default printer.", oldprinter->name);
- cupsdWritePrintcap();
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL,
+ "%s is now the default printer.", printer->name);
+
+ 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...
*/
if (event & CUPSD_EVENT_PRINTER_QUEUE_ORDER_CHANGED)
- cupsdAddEvent(CUPSD_EVENT_PRINTER_QUEUE_ORDER_CHANGED, job->printer, job,
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_QUEUE_ORDER_CHANGED,
+ cupsdFindDest(job->dest), job,
"Job priority changed by user.");
if (event & CUPSD_EVENT_JOB_STATE)
- cupsdAddEvent(CUPSD_EVENT_JOB_STATE, job->printer, job,
+ cupsdAddEvent(CUPSD_EVENT_JOB_STATE, cupsdFindDest(job->dest), job,
job->state_value == IPP_JOB_HELD ?
"Job held by user." : "Job restarted by user.");
if (event & CUPSD_EVENT_JOB_CONFIG_CHANGED)
- cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, job->printer, job,
+ cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, cupsdFindDest(job->dest), job,
"Job options changed by user.");
/*
if (cupsdCheckGroup(username, pw, p->users[i] + 1))
break;
}
+ else if (p->users[i][0] == '#')
+ {
+ /*
+ * Check UUID...
+ */
+
+ if (cupsdCheckGroup(username, pw, p->users[i]))
+ break;
+ }
else if (!strcasecmp(username, p->users[i]))
break;
}
/*
- * End of "$Id: ipp.c 7014 2007-10-10 21:57:43Z mike $".
+ * End of "$Id: ipp.c 7682 2008-06-21 00:06:02Z mike $".
*/