]> git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/quotas.c
Load cups into easysw/current.
[thirdparty/cups.git] / scheduler / quotas.c
1 /*
2 * "$Id: quotas.c 6649 2007-07-11 21:46:42Z mike $"
3 *
4 * Quota routines for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 2007 by Apple Inc.
7 * Copyright 1997-2007 by Easy Software Products.
8 *
9 * These coded instructions, statements, and computer programs are the
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/".
14 *
15 * Contents:
16 *
17 * cupsdFindQuota() - Find a quota record.
18 * cupsdFreeQuotas() - Free quotas for a printer.
19 * cupsdUpdateQuota() - Update quota data for the specified printer and user.
20 * add_quota() - Add a quota record for this printer and user.
21 * compare_quotas() - Compare two quota records...
22 */
23
24 /*
25 * Include necessary headers...
26 */
27
28 #include "cupsd.h"
29
30
31 /*
32 * Local functions...
33 */
34
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);
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 }
63
64
65 /*
66 * 'cupsdFreeQuotas()' - Free quotas for a printer.
67 */
68
69 void
70 cupsdFreeQuotas(cupsd_printer_t *p) /* I - Printer */
71 {
72 cupsd_quota_t *q; /* Current quota record */
73
74
75 if (!p)
76 return;
77
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);
84
85 p->quotas = NULL;
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
112 if ((q = cupsdFindQuota(p, username)) == NULL)
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
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
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)
172 cupsdCancelJob(job, 1, IPP_JOB_CANCELED);
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
193 /*
194 * 'add_quota()' - Add a quota record for this printer and user.
195 */
196
197 static cupsd_quota_t * /* O - Quota data */
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
224 /*
225 * 'compare_quotas()' - Compare two quota records...
226 */
227
228 static int /* O - Result of comparison */
229 compare_quotas(const cupsd_quota_t *q1, /* I - First quota record */
230 const cupsd_quota_t *q2) /* I - Second quota record */
231 {
232 return (strcasecmp(q1->username, q2->username));
233 }
234
235
236 /*
237 * End of "$Id: quotas.c 6649 2007-07-11 21:46:42Z mike $".
238 */