]> 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 4729 2005-09-30 17:46:19Z mike $"
3 *
4 * Quota routines for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1997-2005 by Easy Software Products.
7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
19 *
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * Contents:
25 *
26 * cupsdAddQuota() - Add a quota record for this printer and user.
27 * cupsdFindQuota() - Find a quota record.
28 * cupsdFreeQuotas() - Free quotas for a printer.
29 * cupsdUpdateQuota() - Update quota data for the specified printer and user.
30 * compare() - Compare two quota records...
31 */
32
33 /*
34 * Include necessary headers...
35 */
36
37 #include "cupsd.h"
38
39
40 /*
41 * Local functions...
42 */
43
44 static int compare(const cupsd_quota_t *q1, const cupsd_quota_t *q2);
45
46
47 /*
48 * 'cupsdAddQuota()' - Add a quota record for this printer and user.
49 */
50
51 cupsd_quota_t * /* O - Quota data */
52 cupsdAddQuota(cupsd_printer_t *p, /* I - Printer */
53 const char *username)/* I - User */
54 {
55 cupsd_quota_t *q; /* New quota data */
56
57
58 if (!p || !username)
59 return (NULL);
60
61 if (p->num_quotas == 0)
62 q = malloc(sizeof(cupsd_quota_t));
63 else
64 q = realloc(p->quotas, sizeof(cupsd_quota_t) * (p->num_quotas + 1));
65
66 if (!q)
67 return (NULL);
68
69 p->quotas = q;
70 q += p->num_quotas;
71 p->num_quotas ++;
72
73 memset(q, 0, sizeof(cupsd_quota_t));
74 strlcpy(q->username, username, sizeof(q->username));
75
76 if (p->num_quotas > 1)
77 qsort(p->quotas, p->num_quotas, sizeof(cupsd_quota_t),
78 (int (*)(const void *, const void *))compare);
79
80 return (cupsdFindQuota(p, username));
81 }
82
83
84 /*
85 * 'cupsdFindQuota()' - Find a quota record.
86 */
87
88 cupsd_quota_t * /* O - Quota data */
89 cupsdFindQuota(
90 cupsd_printer_t *p, /* I - Printer */
91 const char *username) /* I - User */
92 {
93 cupsd_quota_t *q, /* Quota data pointer */
94 match; /* Search data */
95
96
97 if (!p || !username)
98 return (NULL);
99
100 if (p->num_quotas == 0)
101 q = NULL;
102 else
103 {
104 strlcpy(match.username, username, sizeof(match.username));
105
106 q = bsearch(&match, p->quotas, p->num_quotas, sizeof(cupsd_quota_t),
107 (int(*)(const void *, const void *))compare);
108 }
109
110 if (q)
111 return (q);
112 else
113 return (cupsdAddQuota(p, username));
114 }
115
116
117 /*
118 * 'cupsdFreeQuotas()' - Free quotas for a printer.
119 */
120
121 void
122 cupsdFreeQuotas(cupsd_printer_t *p) /* I - Printer */
123 {
124 if (!p)
125 return;
126
127 if (p->num_quotas)
128 free(p->quotas);
129
130 p->num_quotas = 0;
131 p->quotas = NULL;
132 }
133
134
135 /*
136 * 'cupsdUpdateQuota()' - Update quota data for the specified printer and user.
137 */
138
139 cupsd_quota_t * /* O - Quota data */
140 cupsdUpdateQuota(
141 cupsd_printer_t *p, /* I - Printer */
142 const char *username, /* I - User */
143 int pages, /* I - Number of pages */
144 int k) /* I - Number of kilobytes */
145 {
146 cupsd_quota_t *q; /* Quota data */
147 cupsd_job_t *job; /* Current job */
148 time_t curtime; /* Current time */
149 ipp_attribute_t *attr; /* Job attribute */
150
151
152 if (!p || !username)
153 return (NULL);
154
155 if (!p->k_limit && !p->page_limit)
156 return (NULL);
157
158 if ((q = cupsdFindQuota(p, username)) == NULL)
159 return (NULL);
160
161 cupsdLogMessage(CUPSD_LOG_DEBUG,
162 "cupsdUpdateQuota: p=%s username=%s pages=%d k=%d",
163 p->name, username, pages, k);
164
165 curtime = time(NULL);
166
167 if (curtime < q->next_update)
168 {
169 q->page_count += pages;
170 q->k_count += k;
171
172 return (q);
173 }
174
175 if (p->quota_period)
176 curtime -= p->quota_period;
177 else
178 curtime = 0;
179
180 q->next_update = 0;
181 q->page_count = 0;
182 q->k_count = 0;
183
184 for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
185 job;
186 job = (cupsd_job_t *)cupsArrayNext(Jobs))
187 {
188 if (strcasecmp(job->dest, p->name) != 0 ||
189 strcasecmp(job->username, q->username) != 0)
190 continue;
191
192 if ((attr = ippFindAttribute(job->attrs, "time-at-completion",
193 IPP_TAG_INTEGER)) == NULL)
194 if ((attr = ippFindAttribute(job->attrs, "time-at-processing",
195 IPP_TAG_INTEGER)) == NULL)
196 attr = ippFindAttribute(job->attrs, "time-at-creation",
197 IPP_TAG_INTEGER);
198
199 if (attr == NULL)
200 break;
201
202 if (attr->values[0].integer < curtime)
203 {
204 if (JobAutoPurge)
205 cupsdCancelJob(job, 1);
206
207 continue;
208 }
209
210 if (q->next_update == 0)
211 q->next_update = attr->values[0].integer + p->quota_period;
212
213 if ((attr = ippFindAttribute(job->attrs, "job-media-sheets-completed",
214 IPP_TAG_INTEGER)) != NULL)
215 q->page_count += attr->values[0].integer;
216
217 if ((attr = ippFindAttribute(job->attrs, "job-k-octets",
218 IPP_TAG_INTEGER)) != NULL)
219 q->k_count += attr->values[0].integer;
220 }
221
222 return (q);
223 }
224
225
226 /*
227 * 'compare()' - Compare two quota records...
228 */
229
230 static int /* O - Result of comparison */
231 compare(const cupsd_quota_t *q1, /* I - First quota record */
232 const cupsd_quota_t *q2) /* I - Second quota record */
233 {
234 return (strcasecmp(q1->username, q2->username));
235 }
236
237
238 /*
239 * End of "$Id: quotas.c 4729 2005-09-30 17:46:19Z mike $".
240 */