]>
git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/quotas.c
2 * Quota routines for the CUPS scheduler.
4 * Copyright 2007-2011 by Apple Inc.
5 * Copyright 1997-2007 by Easy Software Products.
7 * These coded instructions, statements, and computer programs are the
8 * property of Apple Inc. and are protected by Federal copyright
9 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
10 * which should have been included with this file. If this file is
11 * file is missing or damaged, see the license at "http://www.cups.org/".
15 * Include necessary headers...
25 static cupsd_quota_t
*add_quota(cupsd_printer_t
*p
, const char *username
);
26 static int compare_quotas(const cupsd_quota_t
*q1
,
27 const cupsd_quota_t
*q2
);
31 * 'cupsdFindQuota()' - Find a quota record.
34 cupsd_quota_t
* /* O - Quota data */
36 cupsd_printer_t
*p
, /* I - Printer */
37 const char *username
) /* I - User */
39 cupsd_quota_t
*q
, /* Quota data pointer */
40 match
; /* Search data */
41 char *ptr
; /* Pointer into username */
47 strlcpy(match
.username
, username
, sizeof(match
.username
));
48 if ((ptr
= strchr(match
.username
, '@')) != NULL
)
49 *ptr
= '\0'; /* Strip @domain/@KDC */
51 if ((q
= (cupsd_quota_t
*)cupsArrayFind(p
->quotas
, &match
)) != NULL
)
54 return (add_quota(p
, username
));
59 * 'cupsdFreeQuotas()' - Free quotas for a printer.
63 cupsdFreeQuotas(cupsd_printer_t
*p
) /* I - Printer */
65 cupsd_quota_t
*q
; /* Current quota record */
71 for (q
= (cupsd_quota_t
*)cupsArrayFirst(p
->quotas
);
73 q
= (cupsd_quota_t
*)cupsArrayNext(p
->quotas
))
76 cupsArrayDelete(p
->quotas
);
83 * 'cupsdUpdateQuota()' - Update quota data for the specified printer and user.
86 cupsd_quota_t
* /* O - Quota data */
88 cupsd_printer_t
*p
, /* I - Printer */
89 const char *username
, /* I - User */
90 int pages
, /* I - Number of pages */
91 int k
) /* I - Number of kilobytes */
93 cupsd_quota_t
*q
; /* Quota data */
94 cupsd_job_t
*job
; /* Current job */
95 time_t curtime
; /* Current time */
96 ipp_attribute_t
*attr
; /* Job attribute */
102 if (!p
->k_limit
&& !p
->page_limit
)
105 if ((q
= cupsdFindQuota(p
, username
)) == NULL
)
108 cupsdLogMessage(CUPSD_LOG_DEBUG
,
109 "cupsdUpdateQuota: p=%s username=%s pages=%d k=%d",
110 p
->name
, username
, pages
, k
);
112 curtime
= time(NULL
);
114 if (curtime
< q
->next_update
)
116 q
->page_count
+= pages
;
123 curtime
-= p
->quota_period
;
131 for (job
= (cupsd_job_t
*)cupsArrayFirst(Jobs
);
133 job
= (cupsd_job_t
*)cupsArrayNext(Jobs
))
136 * We only care about the current printer/class and user...
139 if (_cups_strcasecmp(job
->dest
, p
->name
) != 0 ||
140 _cups_strcasecmp(job
->username
, q
->username
) != 0)
144 * Make sure attributes are loaded; we always call cupsdLoadJob() to ensure
145 * the access_time member is updated so the job isn't unloaded right away...
148 if (!cupsdLoadJob(job
))
151 if ((attr
= ippFindAttribute(job
->attrs
, "time-at-completion",
152 IPP_TAG_INTEGER
)) == NULL
)
153 if ((attr
= ippFindAttribute(job
->attrs
, "time-at-processing",
154 IPP_TAG_INTEGER
)) == NULL
)
155 attr
= ippFindAttribute(job
->attrs
, "time-at-creation",
158 if (attr
->values
[0].integer
< curtime
)
161 * This job is too old to count towards the quota, ignore it...
164 if (JobAutoPurge
&& !job
->printer
&& job
->state_value
> IPP_JOB_STOPPED
)
165 cupsdDeleteJob(job
, CUPSD_JOB_PURGE
);
170 if (q
->next_update
== 0)
171 q
->next_update
= attr
->values
[0].integer
+ p
->quota_period
;
173 if ((attr
= ippFindAttribute(job
->attrs
, "job-media-sheets-completed",
174 IPP_TAG_INTEGER
)) != NULL
)
175 q
->page_count
+= attr
->values
[0].integer
;
177 if ((attr
= ippFindAttribute(job
->attrs
, "job-k-octets",
178 IPP_TAG_INTEGER
)) != NULL
)
179 q
->k_count
+= attr
->values
[0].integer
;
187 * 'add_quota()' - Add a quota record for this printer and user.
190 static cupsd_quota_t
* /* O - Quota data */
191 add_quota(cupsd_printer_t
*p
, /* I - Printer */
192 const char *username
) /* I - User */
194 cupsd_quota_t
*q
; /* New quota data */
195 char *ptr
; /* Pointer into username */
202 p
->quotas
= cupsArrayNew((cups_array_func_t
)compare_quotas
, NULL
);
207 if ((q
= calloc(1, sizeof(cupsd_quota_t
))) == NULL
)
210 strlcpy(q
->username
, username
, sizeof(q
->username
));
211 if ((ptr
= strchr(q
->username
, '@')) != NULL
)
212 *ptr
= '\0'; /* Strip @domain/@KDC */
214 cupsArrayAdd(p
->quotas
, q
);
221 * 'compare_quotas()' - Compare two quota records...
224 static int /* O - Result of comparison */
225 compare_quotas(const cupsd_quota_t
*q1
, /* I - First quota record */
226 const cupsd_quota_t
*q2
) /* I - Second quota record */
228 return (_cups_strcasecmp(q1
->username
, q2
->username
));