]>
Commit | Line | Data |
---|---|---|
d7845573 | 1 | /* |
c9d3f842 | 2 | * "$Id$" |
d7845573 | 3 | * |
64252c8e | 4 | * Quota routines for the CUPS scheduler. |
d7845573 | 5 | * |
c6fab96f | 6 | * Copyright 2007-2011 by Apple Inc. |
bb3ff448 | 7 | * Copyright 1997-2007 by Easy Software Products. |
d7845573 | 8 | * |
9 | * These coded instructions, statements, and computer programs are the | |
4e8d321f | 10 | * property of Apple Inc. and are protected by Federal copyright |
11 | * law. Distribution and use rights are outlined in the file "LICENSE.txt" | |
12 | * which should have been included with this file. If this file is | |
13 | * file is missing or damaged, see the license at "http://www.cups.org/". | |
d7845573 | 14 | * |
15 | * Contents: | |
16 | * | |
e576c2d2 | 17 | * cupsdFindQuota() - Find a quota record. |
589eb420 | 18 | * cupsdFreeQuotas() - Free quotas for a printer. |
19 | * cupsdUpdateQuota() - Update quota data for the specified printer and user. | |
bd58a948 | 20 | * add_quota() - Add a quota record for this printer and user. |
f79171d0 | 21 | * compare_quotas() - Compare two quota records... |
d7845573 | 22 | */ |
23 | ||
24 | /* | |
25 | * Include necessary headers... | |
26 | */ | |
27 | ||
28 | #include "cupsd.h" | |
29 | ||
30 | ||
31 | /* | |
32 | * Local functions... | |
33 | */ | |
34 | ||
bd58a948 | 35 | static cupsd_quota_t *add_quota(cupsd_printer_t *p, const char *username); |
36 | static int compare_quotas(const cupsd_quota_t *q1, | |
37 | const cupsd_quota_t *q2); | |
e576c2d2 | 38 | |
39 | ||
40 | /* | |
41 | * 'cupsdFindQuota()' - Find a quota record. | |
42 | */ | |
43 | ||
44 | cupsd_quota_t * /* O - Quota data */ | |
45 | cupsdFindQuota( | |
46 | cupsd_printer_t *p, /* I - Printer */ | |
47 | const char *username) /* I - User */ | |
48 | { | |
49 | cupsd_quota_t *q, /* Quota data pointer */ | |
50 | match; /* Search data */ | |
1c59fce9 | 51 | char *ptr; /* Pointer into username */ |
e576c2d2 | 52 | |
53 | ||
54 | if (!p || !username) | |
55 | return (NULL); | |
56 | ||
57 | strlcpy(match.username, username, sizeof(match.username)); | |
1c59fce9 | 58 | if ((ptr = strchr(match.username, '@')) != NULL) |
59 | *ptr = '\0'; /* Strip @domain/@KDC */ | |
e576c2d2 | 60 | |
61 | if ((q = (cupsd_quota_t *)cupsArrayFind(p->quotas, &match)) != NULL) | |
62 | return (q); | |
63 | else | |
64 | return (add_quota(p, username)); | |
65 | } | |
d7845573 | 66 | |
67 | ||
04d756fc | 68 | /* |
589eb420 | 69 | * 'cupsdFreeQuotas()' - Free quotas for a printer. |
04d756fc | 70 | */ |
71 | ||
72 | void | |
f79171d0 | 73 | cupsdFreeQuotas(cupsd_printer_t *p) /* I - Printer */ |
04d756fc | 74 | { |
f79171d0 | 75 | cupsd_quota_t *q; /* Current quota record */ |
76 | ||
77 | ||
04d756fc | 78 | if (!p) |
79 | return; | |
80 | ||
f79171d0 | 81 | for (q = (cupsd_quota_t *)cupsArrayFirst(p->quotas); |
82 | q; | |
83 | q = (cupsd_quota_t *)cupsArrayNext(p->quotas)) | |
84 | free(q); | |
85 | ||
86 | cupsArrayDelete(p->quotas); | |
04d756fc | 87 | |
f79171d0 | 88 | p->quotas = NULL; |
04d756fc | 89 | } |
90 | ||
91 | ||
d7845573 | 92 | /* |
589eb420 | 93 | * 'cupsdUpdateQuota()' - Update quota data for the specified printer and user. |
d7845573 | 94 | */ |
95 | ||
589eb420 | 96 | cupsd_quota_t * /* O - Quota data */ |
f3e786fc | 97 | cupsdUpdateQuota( |
98 | cupsd_printer_t *p, /* I - Printer */ | |
99 | const char *username, /* I - User */ | |
100 | int pages, /* I - Number of pages */ | |
101 | int k) /* I - Number of kilobytes */ | |
d7845573 | 102 | { |
f3e786fc | 103 | cupsd_quota_t *q; /* Quota data */ |
104 | cupsd_job_t *job; /* Current job */ | |
105 | time_t curtime; /* Current time */ | |
106 | ipp_attribute_t *attr; /* Job attribute */ | |
d7845573 | 107 | |
108 | ||
109 | if (!p || !username) | |
110 | return (NULL); | |
111 | ||
b521f3fc | 112 | if (!p->k_limit && !p->page_limit) |
113 | return (NULL); | |
114 | ||
e576c2d2 | 115 | if ((q = cupsdFindQuota(p, username)) == NULL) |
d7845573 | 116 | return (NULL); |
117 | ||
f3e786fc | 118 | cupsdLogMessage(CUPSD_LOG_DEBUG, |
119 | "cupsdUpdateQuota: p=%s username=%s pages=%d k=%d", | |
120 | p->name, username, pages, k); | |
320115a7 | 121 | |
d7845573 | 122 | curtime = time(NULL); |
123 | ||
124 | if (curtime < q->next_update) | |
125 | { | |
126 | q->page_count += pages; | |
127 | q->k_count += k; | |
128 | ||
129 | return (q); | |
130 | } | |
131 | ||
04d756fc | 132 | if (p->quota_period) |
133 | curtime -= p->quota_period; | |
134 | else | |
135 | curtime = 0; | |
136 | ||
d7845573 | 137 | q->next_update = 0; |
138 | q->page_count = 0; | |
139 | q->k_count = 0; | |
140 | ||
589eb420 | 141 | for (job = (cupsd_job_t *)cupsArrayFirst(Jobs); |
82306f04 | 142 | job; |
589eb420 | 143 | job = (cupsd_job_t *)cupsArrayNext(Jobs)) |
d7845573 | 144 | { |
b3c43050 | 145 | /* |
146 | * We only care about the current printer/class and user... | |
147 | */ | |
148 | ||
c6fab96f | 149 | if (_cups_strcasecmp(job->dest, p->name) != 0 || |
150 | _cups_strcasecmp(job->username, q->username) != 0) | |
d7845573 | 151 | continue; |
152 | ||
b3c43050 | 153 | /* |
154 | * Make sure attributes are loaded; we always call cupsdLoadJob() to ensure | |
155 | * the access_time member is updated so the job isn't unloaded right away... | |
156 | */ | |
157 | ||
158 | if (!cupsdLoadJob(job)) | |
159 | continue; | |
160 | ||
d7845573 | 161 | if ((attr = ippFindAttribute(job->attrs, "time-at-completion", |
162 | IPP_TAG_INTEGER)) == NULL) | |
163 | if ((attr = ippFindAttribute(job->attrs, "time-at-processing", | |
164 | IPP_TAG_INTEGER)) == NULL) | |
165 | attr = ippFindAttribute(job->attrs, "time-at-creation", | |
166 | IPP_TAG_INTEGER); | |
167 | ||
d7845573 | 168 | if (attr->values[0].integer < curtime) |
169 | { | |
b3c43050 | 170 | /* |
171 | * This job is too old to count towards the quota, ignore it... | |
172 | */ | |
173 | ||
fbea61f8 | 174 | if (JobAutoPurge && !job->printer && job->state_value > IPP_JOB_STOPPED) |
79dec4f6 | 175 | cupsdDeleteJob(job, CUPSD_JOB_PURGE); |
d7845573 | 176 | |
177 | continue; | |
178 | } | |
179 | ||
180 | if (q->next_update == 0) | |
181 | q->next_update = attr->values[0].integer + p->quota_period; | |
182 | ||
183 | if ((attr = ippFindAttribute(job->attrs, "job-media-sheets-completed", | |
184 | IPP_TAG_INTEGER)) != NULL) | |
185 | q->page_count += attr->values[0].integer; | |
186 | ||
187 | if ((attr = ippFindAttribute(job->attrs, "job-k-octets", | |
188 | IPP_TAG_INTEGER)) != NULL) | |
189 | q->k_count += attr->values[0].integer; | |
190 | } | |
191 | ||
192 | return (q); | |
193 | } | |
194 | ||
195 | ||
bd58a948 | 196 | /* |
197 | * 'add_quota()' - Add a quota record for this printer and user. | |
198 | */ | |
199 | ||
bb542c36 | 200 | static cupsd_quota_t * /* O - Quota data */ |
bd58a948 | 201 | add_quota(cupsd_printer_t *p, /* I - Printer */ |
202 | const char *username) /* I - User */ | |
203 | { | |
204 | cupsd_quota_t *q; /* New quota data */ | |
1c59fce9 | 205 | char *ptr; /* Pointer into username */ |
bd58a948 | 206 | |
207 | ||
208 | if (!p || !username) | |
209 | return (NULL); | |
210 | ||
211 | if (!p->quotas) | |
212 | p->quotas = cupsArrayNew((cups_array_func_t)compare_quotas, NULL); | |
213 | ||
214 | if (!p->quotas) | |
215 | return (NULL); | |
216 | ||
217 | if ((q = calloc(1, sizeof(cupsd_quota_t))) == NULL) | |
218 | return (NULL); | |
219 | ||
220 | strlcpy(q->username, username, sizeof(q->username)); | |
1c59fce9 | 221 | if ((ptr = strchr(q->username, '@')) != NULL) |
222 | *ptr = '\0'; /* Strip @domain/@KDC */ | |
bd58a948 | 223 | |
224 | cupsArrayAdd(p->quotas, q); | |
225 | ||
226 | return (q); | |
227 | } | |
228 | ||
229 | ||
d7845573 | 230 | /* |
f79171d0 | 231 | * 'compare_quotas()' - Compare two quota records... |
d7845573 | 232 | */ |
233 | ||
234 | static int /* O - Result of comparison */ | |
f79171d0 | 235 | compare_quotas(const cupsd_quota_t *q1, /* I - First quota record */ |
236 | const cupsd_quota_t *q2) /* I - Second quota record */ | |
d7845573 | 237 | { |
c6fab96f | 238 | return (_cups_strcasecmp(q1->username, q2->username)); |
d7845573 | 239 | } |
240 | ||
241 | ||
242 | /* | |
c9d3f842 | 243 | * End of "$Id$". |
d7845573 | 244 | */ |