]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | /* |
bc44d920 | 2 | * "$Id: quotas.c 6649 2007-07-11 21:46:42Z 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 */ | |
51 | ||
52 | ||
53 | if (!p || !username) | |
54 | return (NULL); | |
55 | ||
56 | strlcpy(match.username, username, sizeof(match.username)); | |
57 | ||
58 | if ((q = (cupsd_quota_t *)cupsArrayFind(p->quotas, &match)) != NULL) | |
59 | return (q); | |
60 | else | |
61 | return (add_quota(p, username)); | |
62 | } | |
ef416fc2 | 63 | |
64 | ||
65 | /* | |
66 | * 'cupsdFreeQuotas()' - Free quotas for a printer. | |
67 | */ | |
68 | ||
69 | void | |
fa73b229 | 70 | cupsdFreeQuotas(cupsd_printer_t *p) /* I - Printer */ |
ef416fc2 | 71 | { |
fa73b229 | 72 | cupsd_quota_t *q; /* Current quota record */ |
73 | ||
74 | ||
ef416fc2 | 75 | if (!p) |
76 | return; | |
77 | ||
fa73b229 | 78 | for (q = (cupsd_quota_t *)cupsArrayFirst(p->quotas); |
79 | q; | |
80 | q = (cupsd_quota_t *)cupsArrayNext(p->quotas)) | |
81 | free(q); | |
82 | ||
83 | cupsArrayDelete(p->quotas); | |
ef416fc2 | 84 | |
fa73b229 | 85 | p->quotas = NULL; |
ef416fc2 | 86 | } |
87 | ||
88 | ||
89 | /* | |
90 | * 'cupsdUpdateQuota()' - Update quota data for the specified printer and user. | |
91 | */ | |
92 | ||
93 | cupsd_quota_t * /* O - Quota data */ | |
94 | cupsdUpdateQuota( | |
95 | cupsd_printer_t *p, /* I - Printer */ | |
96 | const char *username, /* I - User */ | |
97 | int pages, /* I - Number of pages */ | |
98 | int k) /* I - Number of kilobytes */ | |
99 | { | |
100 | cupsd_quota_t *q; /* Quota data */ | |
101 | cupsd_job_t *job; /* Current job */ | |
102 | time_t curtime; /* Current time */ | |
103 | ipp_attribute_t *attr; /* Job attribute */ | |
104 | ||
105 | ||
106 | if (!p || !username) | |
107 | return (NULL); | |
108 | ||
109 | if (!p->k_limit && !p->page_limit) | |
110 | return (NULL); | |
111 | ||
3d8365b8 | 112 | if ((q = cupsdFindQuota(p, username)) == NULL) |
ef416fc2 | 113 | return (NULL); |
114 | ||
115 | cupsdLogMessage(CUPSD_LOG_DEBUG, | |
116 | "cupsdUpdateQuota: p=%s username=%s pages=%d k=%d", | |
117 | p->name, username, pages, k); | |
118 | ||
7594b224 | 119 | #if defined(__APPLE__) && defined(HAVE_DLFCN_H) |
120 | /* | |
121 | * Use Apple PrintService quota enforcement if installed (X Server only) | |
122 | */ | |
123 | ||
124 | if (AppleQuotas && PSQUpdateQuotaProc) | |
125 | { | |
126 | q->page_count = (*PSQUpdateQuotaProc)(p->name, p->info, username, pages, 0); | |
127 | ||
128 | return (q); | |
129 | } | |
130 | #endif /* __APPLE__ && HAVE_DLFCN_H */ | |
131 | ||
ef416fc2 | 132 | curtime = time(NULL); |
133 | ||
134 | if (curtime < q->next_update) | |
135 | { | |
136 | q->page_count += pages; | |
137 | q->k_count += k; | |
138 | ||
139 | return (q); | |
140 | } | |
141 | ||
142 | if (p->quota_period) | |
143 | curtime -= p->quota_period; | |
144 | else | |
145 | curtime = 0; | |
146 | ||
147 | q->next_update = 0; | |
148 | q->page_count = 0; | |
149 | q->k_count = 0; | |
150 | ||
151 | for (job = (cupsd_job_t *)cupsArrayFirst(Jobs); | |
152 | job; | |
153 | job = (cupsd_job_t *)cupsArrayNext(Jobs)) | |
154 | { | |
155 | if (strcasecmp(job->dest, p->name) != 0 || | |
156 | strcasecmp(job->username, q->username) != 0) | |
157 | continue; | |
158 | ||
159 | if ((attr = ippFindAttribute(job->attrs, "time-at-completion", | |
160 | IPP_TAG_INTEGER)) == NULL) | |
161 | if ((attr = ippFindAttribute(job->attrs, "time-at-processing", | |
162 | IPP_TAG_INTEGER)) == NULL) | |
163 | attr = ippFindAttribute(job->attrs, "time-at-creation", | |
164 | IPP_TAG_INTEGER); | |
165 | ||
166 | if (attr == NULL) | |
167 | break; | |
168 | ||
169 | if (attr->values[0].integer < curtime) | |
170 | { | |
171 | if (JobAutoPurge) | |
07725fee | 172 | cupsdCancelJob(job, 1, IPP_JOB_CANCELED); |
ef416fc2 | 173 | |
174 | continue; | |
175 | } | |
176 | ||
177 | if (q->next_update == 0) | |
178 | q->next_update = attr->values[0].integer + p->quota_period; | |
179 | ||
180 | if ((attr = ippFindAttribute(job->attrs, "job-media-sheets-completed", | |
181 | IPP_TAG_INTEGER)) != NULL) | |
182 | q->page_count += attr->values[0].integer; | |
183 | ||
184 | if ((attr = ippFindAttribute(job->attrs, "job-k-octets", | |
185 | IPP_TAG_INTEGER)) != NULL) | |
186 | q->k_count += attr->values[0].integer; | |
187 | } | |
188 | ||
189 | return (q); | |
190 | } | |
191 | ||
192 | ||
e1d6a774 | 193 | /* |
194 | * 'add_quota()' - Add a quota record for this printer and user. | |
195 | */ | |
196 | ||
07725fee | 197 | static cupsd_quota_t * /* O - Quota data */ |
e1d6a774 | 198 | add_quota(cupsd_printer_t *p, /* I - Printer */ |
199 | const char *username) /* I - User */ | |
200 | { | |
201 | cupsd_quota_t *q; /* New quota data */ | |
202 | ||
203 | ||
204 | if (!p || !username) | |
205 | return (NULL); | |
206 | ||
207 | if (!p->quotas) | |
208 | p->quotas = cupsArrayNew((cups_array_func_t)compare_quotas, NULL); | |
209 | ||
210 | if (!p->quotas) | |
211 | return (NULL); | |
212 | ||
213 | if ((q = calloc(1, sizeof(cupsd_quota_t))) == NULL) | |
214 | return (NULL); | |
215 | ||
216 | strlcpy(q->username, username, sizeof(q->username)); | |
217 | ||
218 | cupsArrayAdd(p->quotas, q); | |
219 | ||
220 | return (q); | |
221 | } | |
222 | ||
223 | ||
ef416fc2 | 224 | /* |
fa73b229 | 225 | * 'compare_quotas()' - Compare two quota records... |
ef416fc2 | 226 | */ |
227 | ||
228 | static int /* O - Result of comparison */ | |
fa73b229 | 229 | compare_quotas(const cupsd_quota_t *q1, /* I - First quota record */ |
230 | const cupsd_quota_t *q2) /* I - Second quota record */ | |
ef416fc2 | 231 | { |
232 | return (strcasecmp(q1->username, q2->username)); | |
233 | } | |
234 | ||
235 | ||
236 | /* | |
bc44d920 | 237 | * End of "$Id: quotas.c 6649 2007-07-11 21:46:42Z mike $". |
ef416fc2 | 238 | */ |