/*
- * "$Id: quotas.c 4729 2005-09-30 17:46:19Z mike $"
+ * Quota routines for the CUPS scheduler.
*
- * Quota routines for the Common UNIX Printing System (CUPS).
+ * Copyright 2007-2011 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products.
*
- * Copyright 1997-2005 by Easy Software Products.
- *
- * These coded instructions, statements, and computer programs are the
- * property of Easy Software Products and are protected by Federal
- * copyright law. Distribution and use rights are outlined in the file
- * "LICENSE.txt" which should have been included with this file. If this
- * file is missing or damaged please contact Easy Software Products
- * at:
- *
- * Attn: CUPS Licensing Information
- * Easy Software Products
- * 44141 Airport View Drive, Suite 204
- * Hollywood, Maryland 20636 USA
- *
- * Voice: (301) 373-9600
- * EMail: cups-info@cups.org
- * WWW: http://www.cups.org
- *
- * Contents:
- *
- * cupsdAddQuota() - Add a quota record for this printer and user.
- * cupsdFindQuota() - Find a quota record.
- * cupsdFreeQuotas() - Free quotas for a printer.
- * cupsdUpdateQuota() - Update quota data for the specified printer and user.
- * compare() - Compare two quota records...
+ * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
*/
/*
* Local functions...
*/
-static int compare(const cupsd_quota_t *q1, const cupsd_quota_t *q2);
-
-
-/*
- * 'cupsdAddQuota()' - Add a quota record for this printer and user.
- */
-
-cupsd_quota_t * /* O - Quota data */
-cupsdAddQuota(cupsd_printer_t *p, /* I - Printer */
- const char *username)/* I - User */
-{
- cupsd_quota_t *q; /* New quota data */
-
-
- if (!p || !username)
- return (NULL);
-
- if (p->num_quotas == 0)
- q = malloc(sizeof(cupsd_quota_t));
- else
- q = realloc(p->quotas, sizeof(cupsd_quota_t) * (p->num_quotas + 1));
-
- if (!q)
- return (NULL);
-
- p->quotas = q;
- q += p->num_quotas;
- p->num_quotas ++;
-
- memset(q, 0, sizeof(cupsd_quota_t));
- strlcpy(q->username, username, sizeof(q->username));
-
- if (p->num_quotas > 1)
- qsort(p->quotas, p->num_quotas, sizeof(cupsd_quota_t),
- (int (*)(const void *, const void *))compare);
-
- return (cupsdFindQuota(p, username));
-}
+static cupsd_quota_t *add_quota(cupsd_printer_t *p, const char *username);
+static int compare_quotas(const cupsd_quota_t *q1,
+ const cupsd_quota_t *q2);
/*
{
cupsd_quota_t *q, /* Quota data pointer */
match; /* Search data */
+ char *ptr; /* Pointer into username */
if (!p || !username)
return (NULL);
- if (p->num_quotas == 0)
- q = NULL;
- else
- {
- strlcpy(match.username, username, sizeof(match.username));
-
- q = bsearch(&match, p->quotas, p->num_quotas, sizeof(cupsd_quota_t),
- (int(*)(const void *, const void *))compare);
- }
+ strlcpy(match.username, username, sizeof(match.username));
+ if ((ptr = strchr(match.username, '@')) != NULL)
+ *ptr = '\0'; /* Strip @domain/@KDC */
- if (q)
+ if ((q = (cupsd_quota_t *)cupsArrayFind(p->quotas, &match)) != NULL)
return (q);
else
- return (cupsdAddQuota(p, username));
+ return (add_quota(p, username));
}
*/
void
-cupsdFreeQuotas(cupsd_printer_t *p) /* I - Printer */
+cupsdFreeQuotas(cupsd_printer_t *p) /* I - Printer */
{
+ cupsd_quota_t *q; /* Current quota record */
+
+
if (!p)
return;
- if (p->num_quotas)
- free(p->quotas);
+ for (q = (cupsd_quota_t *)cupsArrayFirst(p->quotas);
+ q;
+ q = (cupsd_quota_t *)cupsArrayNext(p->quotas))
+ free(q);
+
+ cupsArrayDelete(p->quotas);
- p->num_quotas = 0;
- p->quotas = NULL;
+ p->quotas = NULL;
}
job;
job = (cupsd_job_t *)cupsArrayNext(Jobs))
{
- if (strcasecmp(job->dest, p->name) != 0 ||
- strcasecmp(job->username, q->username) != 0)
+ /*
+ * We only care about the current printer/class and user...
+ */
+
+ if (_cups_strcasecmp(job->dest, p->name) != 0 ||
+ _cups_strcasecmp(job->username, q->username) != 0)
+ continue;
+
+ /*
+ * Make sure attributes are loaded; we always call cupsdLoadJob() to ensure
+ * the access_time member is updated so the job isn't unloaded right away...
+ */
+
+ if (!cupsdLoadJob(job))
continue;
if ((attr = ippFindAttribute(job->attrs, "time-at-completion",
attr = ippFindAttribute(job->attrs, "time-at-creation",
IPP_TAG_INTEGER);
- if (attr == NULL)
- break;
-
if (attr->values[0].integer < curtime)
{
- if (JobAutoPurge)
- cupsdCancelJob(job, 1);
+ /*
+ * This job is too old to count towards the quota, ignore it...
+ */
+
+ if (JobAutoPurge && !job->printer && job->state_value > IPP_JOB_STOPPED)
+ cupsdDeleteJob(job, CUPSD_JOB_PURGE);
continue;
}
/*
- * 'compare()' - Compare two quota records...
+ * 'add_quota()' - Add a quota record for this printer and user.
*/
-static int /* O - Result of comparison */
-compare(const cupsd_quota_t *q1, /* I - First quota record */
- const cupsd_quota_t *q2) /* I - Second quota record */
+static cupsd_quota_t * /* O - Quota data */
+add_quota(cupsd_printer_t *p, /* I - Printer */
+ const char *username) /* I - User */
{
- return (strcasecmp(q1->username, q2->username));
+ cupsd_quota_t *q; /* New quota data */
+ char *ptr; /* Pointer into username */
+
+
+ if (!p || !username)
+ return (NULL);
+
+ if (!p->quotas)
+ p->quotas = cupsArrayNew((cups_array_func_t)compare_quotas, NULL);
+
+ if (!p->quotas)
+ return (NULL);
+
+ if ((q = calloc(1, sizeof(cupsd_quota_t))) == NULL)
+ return (NULL);
+
+ strlcpy(q->username, username, sizeof(q->username));
+ if ((ptr = strchr(q->username, '@')) != NULL)
+ *ptr = '\0'; /* Strip @domain/@KDC */
+
+ cupsArrayAdd(p->quotas, q);
+
+ return (q);
}
/*
- * End of "$Id: quotas.c 4729 2005-09-30 17:46:19Z mike $".
+ * 'compare_quotas()' - Compare two quota records...
*/
+
+static int /* O - Result of comparison */
+compare_quotas(const cupsd_quota_t *q1, /* I - First quota record */
+ const cupsd_quota_t *q2) /* I - Second quota record */
+{
+ return (_cups_strcasecmp(q1->username, q2->username));
+}