]> git.ipfire.org Git - thirdparty/cups.git/blame - scheduler/quotas.c
Fix source file header text duplication text duplication.
[thirdparty/cups.git] / scheduler / quotas.c
CommitLineData
ef416fc2 1/*
503b54c9 2 * Quota routines for the CUPS scheduler.
ef416fc2 3 *
503b54c9
MS
4 * Copyright 2007-2011 by Apple Inc.
5 * Copyright 1997-2007 by Easy Software Products.
ef416fc2 6 *
503b54c9
MS
7 * These coded instructions, statements, and computer programs are the
8 * property of Apple Inc. and are protected by Federal copyright
9 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
10 * which should have been included with this file. If this file is
57b7b66b 11 * missing or damaged, see the license at "http://www.cups.org/".
ef416fc2 12 */
13
14/*
15 * Include necessary headers...
16 */
17
18#include "cupsd.h"
19
20
21/*
22 * Local functions...
23 */
24
e1d6a774 25static cupsd_quota_t *add_quota(cupsd_printer_t *p, const char *username);
26static int compare_quotas(const cupsd_quota_t *q1,
27 const cupsd_quota_t *q2);
3d8365b8 28
29
30/*
31 * 'cupsdFindQuota()' - Find a quota record.
32 */
33
34cupsd_quota_t * /* O - Quota data */
35cupsdFindQuota(
36 cupsd_printer_t *p, /* I - Printer */
37 const char *username) /* I - User */
38{
39 cupsd_quota_t *q, /* Quota data pointer */
40 match; /* Search data */
db1f069b 41 char *ptr; /* Pointer into username */
3d8365b8 42
43
44 if (!p || !username)
45 return (NULL);
46
47 strlcpy(match.username, username, sizeof(match.username));
db1f069b
MS
48 if ((ptr = strchr(match.username, '@')) != NULL)
49 *ptr = '\0'; /* Strip @domain/@KDC */
3d8365b8 50
51 if ((q = (cupsd_quota_t *)cupsArrayFind(p->quotas, &match)) != NULL)
52 return (q);
53 else
54 return (add_quota(p, username));
55}
ef416fc2 56
57
58/*
59 * 'cupsdFreeQuotas()' - Free quotas for a printer.
60 */
61
62void
fa73b229 63cupsdFreeQuotas(cupsd_printer_t *p) /* I - Printer */
ef416fc2 64{
fa73b229 65 cupsd_quota_t *q; /* Current quota record */
66
67
ef416fc2 68 if (!p)
69 return;
70
fa73b229 71 for (q = (cupsd_quota_t *)cupsArrayFirst(p->quotas);
72 q;
73 q = (cupsd_quota_t *)cupsArrayNext(p->quotas))
74 free(q);
75
76 cupsArrayDelete(p->quotas);
ef416fc2 77
fa73b229 78 p->quotas = NULL;
ef416fc2 79}
80
81
82/*
83 * 'cupsdUpdateQuota()' - Update quota data for the specified printer and user.
84 */
85
86cupsd_quota_t * /* O - Quota data */
87cupsdUpdateQuota(
88 cupsd_printer_t *p, /* I - Printer */
89 const char *username, /* I - User */
90 int pages, /* I - Number of pages */
91 int k) /* I - Number of kilobytes */
92{
93 cupsd_quota_t *q; /* Quota data */
94 cupsd_job_t *job; /* Current job */
95 time_t curtime; /* Current time */
96 ipp_attribute_t *attr; /* Job attribute */
97
98
99 if (!p || !username)
100 return (NULL);
101
102 if (!p->k_limit && !p->page_limit)
103 return (NULL);
104
3d8365b8 105 if ((q = cupsdFindQuota(p, username)) == NULL)
ef416fc2 106 return (NULL);
107
108 cupsdLogMessage(CUPSD_LOG_DEBUG,
109 "cupsdUpdateQuota: p=%s username=%s pages=%d k=%d",
110 p->name, username, pages, k);
111
112 curtime = time(NULL);
113
114 if (curtime < q->next_update)
115 {
116 q->page_count += pages;
117 q->k_count += k;
118
119 return (q);
120 }
121
122 if (p->quota_period)
123 curtime -= p->quota_period;
124 else
125 curtime = 0;
126
127 q->next_update = 0;
128 q->page_count = 0;
129 q->k_count = 0;
130
131 for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
132 job;
133 job = (cupsd_job_t *)cupsArrayNext(Jobs))
134 {
dfd5680b
MS
135 /*
136 * We only care about the current printer/class and user...
137 */
138
88f9aafc
MS
139 if (_cups_strcasecmp(job->dest, p->name) != 0 ||
140 _cups_strcasecmp(job->username, q->username) != 0)
ef416fc2 141 continue;
142
dfd5680b
MS
143 /*
144 * Make sure attributes are loaded; we always call cupsdLoadJob() to ensure
145 * the access_time member is updated so the job isn't unloaded right away...
146 */
147
148 if (!cupsdLoadJob(job))
149 continue;
150
ef416fc2 151 if ((attr = ippFindAttribute(job->attrs, "time-at-completion",
152 IPP_TAG_INTEGER)) == NULL)
153 if ((attr = ippFindAttribute(job->attrs, "time-at-processing",
154 IPP_TAG_INTEGER)) == NULL)
155 attr = ippFindAttribute(job->attrs, "time-at-creation",
156 IPP_TAG_INTEGER);
157
ef416fc2 158 if (attr->values[0].integer < curtime)
159 {
dfd5680b
MS
160 /*
161 * This job is too old to count towards the quota, ignore it...
162 */
163
b9faaae1
MS
164 if (JobAutoPurge && !job->printer && job->state_value > IPP_JOB_STOPPED)
165 cupsdDeleteJob(job, CUPSD_JOB_PURGE);
ef416fc2 166
167 continue;
168 }
169
170 if (q->next_update == 0)
171 q->next_update = attr->values[0].integer + p->quota_period;
172
173 if ((attr = ippFindAttribute(job->attrs, "job-media-sheets-completed",
174 IPP_TAG_INTEGER)) != NULL)
175 q->page_count += attr->values[0].integer;
176
177 if ((attr = ippFindAttribute(job->attrs, "job-k-octets",
178 IPP_TAG_INTEGER)) != NULL)
179 q->k_count += attr->values[0].integer;
180 }
181
182 return (q);
183}
184
185
e1d6a774 186/*
187 * 'add_quota()' - Add a quota record for this printer and user.
188 */
189
07725fee 190static cupsd_quota_t * /* O - Quota data */
e1d6a774 191add_quota(cupsd_printer_t *p, /* I - Printer */
192 const char *username) /* I - User */
193{
194 cupsd_quota_t *q; /* New quota data */
db1f069b 195 char *ptr; /* Pointer into username */
e1d6a774 196
197
198 if (!p || !username)
199 return (NULL);
200
201 if (!p->quotas)
202 p->quotas = cupsArrayNew((cups_array_func_t)compare_quotas, NULL);
203
204 if (!p->quotas)
205 return (NULL);
206
207 if ((q = calloc(1, sizeof(cupsd_quota_t))) == NULL)
208 return (NULL);
209
210 strlcpy(q->username, username, sizeof(q->username));
db1f069b
MS
211 if ((ptr = strchr(q->username, '@')) != NULL)
212 *ptr = '\0'; /* Strip @domain/@KDC */
e1d6a774 213
214 cupsArrayAdd(p->quotas, q);
215
216 return (q);
217}
218
219
ef416fc2 220/*
fa73b229 221 * 'compare_quotas()' - Compare two quota records...
ef416fc2 222 */
223
224static int /* O - Result of comparison */
fa73b229 225compare_quotas(const cupsd_quota_t *q1, /* I - First quota record */
226 const cupsd_quota_t *q2) /* I - Second quota record */
ef416fc2 227{
88f9aafc 228 return (_cups_strcasecmp(q1->username, q2->username));
ef416fc2 229}