]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 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 | */ |