]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | /* |
2e4ff8af | 2 | * "$Id: quotas.c 6947 2007-09-12 21:09:49Z mike $" |
ef416fc2 | 3 | * |
4 | * Quota routines for the Common UNIX Printing System (CUPS). | |
5 | * | |
bc44d920 | 6 | * Copyright 2007 by Apple Inc. |
7594b224 | 7 | * Copyright 1997-2007 by Easy Software Products. |
ef416fc2 | 8 | * |
9 | * These coded instructions, statements, and computer programs are the | |
bc44d920 | 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/". | |
ef416fc2 | 14 | * |
15 | * Contents: | |
16 | * | |
3d8365b8 | 17 | * cupsdFindQuota() - Find a quota record. |
ef416fc2 | 18 | * cupsdFreeQuotas() - Free quotas for a printer. |
19 | * cupsdUpdateQuota() - Update quota data for the specified printer and user. | |
e1d6a774 | 20 | * add_quota() - Add a quota record for this printer and user. |
fa73b229 | 21 | * compare_quotas() - Compare two quota records... |
ef416fc2 | 22 | */ |
23 | ||
24 | /* | |
25 | * Include necessary headers... | |
26 | */ | |
27 | ||
28 | #include "cupsd.h" | |
29 | ||
30 | ||
31 | /* | |
32 | * Local functions... | |
33 | */ | |
34 | ||
e1d6a774 | 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); | |
3d8365b8 | 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 */ | |
db1f069b | 51 | char *ptr; /* Pointer into username */ |
3d8365b8 | 52 | |
53 | ||
54 | if (!p || !username) | |
55 | return (NULL); | |
56 | ||
57 | strlcpy(match.username, username, sizeof(match.username)); | |
db1f069b MS |
58 | if ((ptr = strchr(match.username, '@')) != NULL) |
59 | *ptr = '\0'; /* Strip @domain/@KDC */ | |
3d8365b8 | 60 | |
61 | if ((q = (cupsd_quota_t *)cupsArrayFind(p->quotas, &match)) != NULL) | |
62 | return (q); | |
63 | else | |
64 | return (add_quota(p, username)); | |
65 | } | |
ef416fc2 | 66 | |
67 | ||
68 | /* | |
69 | * 'cupsdFreeQuotas()' - Free quotas for a printer. | |
70 | */ | |
71 | ||
72 | void | |
fa73b229 | 73 | cupsdFreeQuotas(cupsd_printer_t *p) /* I - Printer */ |
ef416fc2 | 74 | { |
fa73b229 | 75 | cupsd_quota_t *q; /* Current quota record */ |
76 | ||
77 | ||
ef416fc2 | 78 | if (!p) |
79 | return; | |
80 | ||
fa73b229 | 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); | |
ef416fc2 | 87 | |
fa73b229 | 88 | p->quotas = NULL; |
ef416fc2 | 89 | } |
90 | ||
91 | ||
92 | /* | |
93 | * 'cupsdUpdateQuota()' - Update quota data for the specified printer and user. | |
94 | */ | |
95 | ||
96 | cupsd_quota_t * /* O - Quota data */ | |
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 */ | |
102 | { | |
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 */ | |
107 | ||
108 | ||
109 | if (!p || !username) | |
110 | return (NULL); | |
111 | ||
112 | if (!p->k_limit && !p->page_limit) | |
113 | return (NULL); | |
114 | ||
3d8365b8 | 115 | if ((q = cupsdFindQuota(p, username)) == NULL) |
ef416fc2 | 116 | return (NULL); |
117 | ||
118 | cupsdLogMessage(CUPSD_LOG_DEBUG, | |
119 | "cupsdUpdateQuota: p=%s username=%s pages=%d k=%d", | |
120 | p->name, username, pages, k); | |
121 | ||
7594b224 | 122 | #if defined(__APPLE__) && defined(HAVE_DLFCN_H) |
123 | /* | |
124 | * Use Apple PrintService quota enforcement if installed (X Server only) | |
125 | */ | |
126 | ||
127 | if (AppleQuotas && PSQUpdateQuotaProc) | |
128 | { | |
129 | q->page_count = (*PSQUpdateQuotaProc)(p->name, p->info, username, pages, 0); | |
130 | ||
131 | return (q); | |
132 | } | |
133 | #endif /* __APPLE__ && HAVE_DLFCN_H */ | |
134 | ||
ef416fc2 | 135 | curtime = time(NULL); |
136 | ||
137 | if (curtime < q->next_update) | |
138 | { | |
139 | q->page_count += pages; | |
140 | q->k_count += k; | |
141 | ||
142 | return (q); | |
143 | } | |
144 | ||
145 | if (p->quota_period) | |
146 | curtime -= p->quota_period; | |
147 | else | |
148 | curtime = 0; | |
149 | ||
150 | q->next_update = 0; | |
151 | q->page_count = 0; | |
152 | q->k_count = 0; | |
153 | ||
154 | for (job = (cupsd_job_t *)cupsArrayFirst(Jobs); | |
155 | job; | |
156 | job = (cupsd_job_t *)cupsArrayNext(Jobs)) | |
157 | { | |
158 | if (strcasecmp(job->dest, p->name) != 0 || | |
159 | strcasecmp(job->username, q->username) != 0) | |
160 | continue; | |
161 | ||
162 | if ((attr = ippFindAttribute(job->attrs, "time-at-completion", | |
163 | IPP_TAG_INTEGER)) == NULL) | |
164 | if ((attr = ippFindAttribute(job->attrs, "time-at-processing", | |
165 | IPP_TAG_INTEGER)) == NULL) | |
166 | attr = ippFindAttribute(job->attrs, "time-at-creation", | |
167 | IPP_TAG_INTEGER); | |
168 | ||
169 | if (attr == NULL) | |
170 | break; | |
171 | ||
172 | if (attr->values[0].integer < curtime) | |
173 | { | |
174 | if (JobAutoPurge) | |
07725fee | 175 | cupsdCancelJob(job, 1, IPP_JOB_CANCELED); |
ef416fc2 | 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 | ||
e1d6a774 | 196 | /* |
197 | * 'add_quota()' - Add a quota record for this printer and user. | |
198 | */ | |
199 | ||
07725fee | 200 | static cupsd_quota_t * /* O - Quota data */ |
e1d6a774 | 201 | add_quota(cupsd_printer_t *p, /* I - Printer */ |
202 | const char *username) /* I - User */ | |
203 | { | |
204 | cupsd_quota_t *q; /* New quota data */ | |
db1f069b | 205 | char *ptr; /* Pointer into username */ |
e1d6a774 | 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)); | |
db1f069b MS |
221 | if ((ptr = strchr(q->username, '@')) != NULL) |
222 | *ptr = '\0'; /* Strip @domain/@KDC */ | |
e1d6a774 | 223 | |
224 | cupsArrayAdd(p->quotas, q); | |
225 | ||
226 | return (q); | |
227 | } | |
228 | ||
229 | ||
ef416fc2 | 230 | /* |
fa73b229 | 231 | * 'compare_quotas()' - Compare two quota records... |
ef416fc2 | 232 | */ |
233 | ||
234 | static int /* O - Result of comparison */ | |
fa73b229 | 235 | compare_quotas(const cupsd_quota_t *q1, /* I - First quota record */ |
236 | const cupsd_quota_t *q2) /* I - Second quota record */ | |
ef416fc2 | 237 | { |
238 | return (strcasecmp(q1->username, q2->username)); | |
239 | } | |
240 | ||
241 | ||
242 | /* | |
2e4ff8af | 243 | * End of "$Id: quotas.c 6947 2007-09-12 21:09:49Z mike $". |
ef416fc2 | 244 | */ |