1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * Printer class routines for the CUPS scheduler.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright 2007-2017 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright 1997-2007 by Easy Software Products, all rights reserved.
6*5e7646d2SAndroid Build Coastguard Worker *
7*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
8*5e7646d2SAndroid Build Coastguard Worker */
9*5e7646d2SAndroid Build Coastguard Worker
10*5e7646d2SAndroid Build Coastguard Worker /*
11*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
12*5e7646d2SAndroid Build Coastguard Worker */
13*5e7646d2SAndroid Build Coastguard Worker
14*5e7646d2SAndroid Build Coastguard Worker #include "cupsd.h"
15*5e7646d2SAndroid Build Coastguard Worker
16*5e7646d2SAndroid Build Coastguard Worker
17*5e7646d2SAndroid Build Coastguard Worker /*
18*5e7646d2SAndroid Build Coastguard Worker * 'cupsdAddClass()' - Add a class to the system.
19*5e7646d2SAndroid Build Coastguard Worker */
20*5e7646d2SAndroid Build Coastguard Worker
21*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t * /* O - New class */
cupsdAddClass(const char * name)22*5e7646d2SAndroid Build Coastguard Worker cupsdAddClass(const char *name) /* I - Name of class */
23*5e7646d2SAndroid Build Coastguard Worker {
24*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *c; /* New class */
25*5e7646d2SAndroid Build Coastguard Worker char uri[1024]; /* Class URI */
26*5e7646d2SAndroid Build Coastguard Worker
27*5e7646d2SAndroid Build Coastguard Worker
28*5e7646d2SAndroid Build Coastguard Worker /*
29*5e7646d2SAndroid Build Coastguard Worker * Add the printer and set the type to "class"...
30*5e7646d2SAndroid Build Coastguard Worker */
31*5e7646d2SAndroid Build Coastguard Worker
32*5e7646d2SAndroid Build Coastguard Worker if ((c = cupsdAddPrinter(name)) != NULL)
33*5e7646d2SAndroid Build Coastguard Worker {
34*5e7646d2SAndroid Build Coastguard Worker /*
35*5e7646d2SAndroid Build Coastguard Worker * Change from a printer to a class...
36*5e7646d2SAndroid Build Coastguard Worker */
37*5e7646d2SAndroid Build Coastguard Worker
38*5e7646d2SAndroid Build Coastguard Worker c->type = CUPS_PRINTER_CLASS;
39*5e7646d2SAndroid Build Coastguard Worker
40*5e7646d2SAndroid Build Coastguard Worker httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
41*5e7646d2SAndroid Build Coastguard Worker ServerName, RemotePort, "/classes/%s", name);
42*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&c->uri, uri);
43*5e7646d2SAndroid Build Coastguard Worker
44*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&c->error_policy, "retry-current-job");
45*5e7646d2SAndroid Build Coastguard Worker }
46*5e7646d2SAndroid Build Coastguard Worker
47*5e7646d2SAndroid Build Coastguard Worker return (c);
48*5e7646d2SAndroid Build Coastguard Worker }
49*5e7646d2SAndroid Build Coastguard Worker
50*5e7646d2SAndroid Build Coastguard Worker
51*5e7646d2SAndroid Build Coastguard Worker /*
52*5e7646d2SAndroid Build Coastguard Worker * 'cupsdAddPrinterToClass()' - Add a printer to a class...
53*5e7646d2SAndroid Build Coastguard Worker */
54*5e7646d2SAndroid Build Coastguard Worker
55*5e7646d2SAndroid Build Coastguard Worker void
cupsdAddPrinterToClass(cupsd_printer_t * c,cupsd_printer_t * p)56*5e7646d2SAndroid Build Coastguard Worker cupsdAddPrinterToClass(
57*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *c, /* I - Class to add to */
58*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *p) /* I - Printer to add */
59*5e7646d2SAndroid Build Coastguard Worker {
60*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
61*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t **temp; /* Pointer to printer array */
62*5e7646d2SAndroid Build Coastguard Worker
63*5e7646d2SAndroid Build Coastguard Worker
64*5e7646d2SAndroid Build Coastguard Worker /*
65*5e7646d2SAndroid Build Coastguard Worker * See if this printer is already a member of the class...
66*5e7646d2SAndroid Build Coastguard Worker */
67*5e7646d2SAndroid Build Coastguard Worker
68*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < c->num_printers; i ++)
69*5e7646d2SAndroid Build Coastguard Worker if (c->printers[i] == p)
70*5e7646d2SAndroid Build Coastguard Worker return;
71*5e7646d2SAndroid Build Coastguard Worker
72*5e7646d2SAndroid Build Coastguard Worker /*
73*5e7646d2SAndroid Build Coastguard Worker * Allocate memory as needed...
74*5e7646d2SAndroid Build Coastguard Worker */
75*5e7646d2SAndroid Build Coastguard Worker
76*5e7646d2SAndroid Build Coastguard Worker if (c->num_printers == 0)
77*5e7646d2SAndroid Build Coastguard Worker temp = malloc(sizeof(cupsd_printer_t *));
78*5e7646d2SAndroid Build Coastguard Worker else
79*5e7646d2SAndroid Build Coastguard Worker temp = realloc(c->printers, sizeof(cupsd_printer_t *) * (size_t)(c->num_printers + 1));
80*5e7646d2SAndroid Build Coastguard Worker
81*5e7646d2SAndroid Build Coastguard Worker if (temp == NULL)
82*5e7646d2SAndroid Build Coastguard Worker {
83*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to add printer %s to class %s!",
84*5e7646d2SAndroid Build Coastguard Worker p->name, c->name);
85*5e7646d2SAndroid Build Coastguard Worker return;
86*5e7646d2SAndroid Build Coastguard Worker }
87*5e7646d2SAndroid Build Coastguard Worker
88*5e7646d2SAndroid Build Coastguard Worker /*
89*5e7646d2SAndroid Build Coastguard Worker * Add the printer to the end of the array and update the number of printers.
90*5e7646d2SAndroid Build Coastguard Worker */
91*5e7646d2SAndroid Build Coastguard Worker
92*5e7646d2SAndroid Build Coastguard Worker c->printers = temp;
93*5e7646d2SAndroid Build Coastguard Worker temp += c->num_printers;
94*5e7646d2SAndroid Build Coastguard Worker c->num_printers ++;
95*5e7646d2SAndroid Build Coastguard Worker
96*5e7646d2SAndroid Build Coastguard Worker *temp = p;
97*5e7646d2SAndroid Build Coastguard Worker }
98*5e7646d2SAndroid Build Coastguard Worker
99*5e7646d2SAndroid Build Coastguard Worker
100*5e7646d2SAndroid Build Coastguard Worker /*
101*5e7646d2SAndroid Build Coastguard Worker * 'cupsdDeletePrinterFromClass()' - Delete a printer from a class.
102*5e7646d2SAndroid Build Coastguard Worker */
103*5e7646d2SAndroid Build Coastguard Worker
104*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 if class changed, 0 otherwise */
cupsdDeletePrinterFromClass(cupsd_printer_t * c,cupsd_printer_t * p)105*5e7646d2SAndroid Build Coastguard Worker cupsdDeletePrinterFromClass(
106*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *c, /* I - Class to delete from */
107*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *p) /* I - Printer to delete */
108*5e7646d2SAndroid Build Coastguard Worker {
109*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
110*5e7646d2SAndroid Build Coastguard Worker
111*5e7646d2SAndroid Build Coastguard Worker
112*5e7646d2SAndroid Build Coastguard Worker /*
113*5e7646d2SAndroid Build Coastguard Worker * See if the printer is in the class...
114*5e7646d2SAndroid Build Coastguard Worker */
115*5e7646d2SAndroid Build Coastguard Worker
116*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < c->num_printers; i ++)
117*5e7646d2SAndroid Build Coastguard Worker if (p == c->printers[i])
118*5e7646d2SAndroid Build Coastguard Worker break;
119*5e7646d2SAndroid Build Coastguard Worker
120*5e7646d2SAndroid Build Coastguard Worker /*
121*5e7646d2SAndroid Build Coastguard Worker * If it is, remove it from the list...
122*5e7646d2SAndroid Build Coastguard Worker */
123*5e7646d2SAndroid Build Coastguard Worker
124*5e7646d2SAndroid Build Coastguard Worker if (i < c->num_printers)
125*5e7646d2SAndroid Build Coastguard Worker {
126*5e7646d2SAndroid Build Coastguard Worker /*
127*5e7646d2SAndroid Build Coastguard Worker * Yes, remove the printer...
128*5e7646d2SAndroid Build Coastguard Worker */
129*5e7646d2SAndroid Build Coastguard Worker
130*5e7646d2SAndroid Build Coastguard Worker c->num_printers --;
131*5e7646d2SAndroid Build Coastguard Worker if (i < c->num_printers)
132*5e7646d2SAndroid Build Coastguard Worker memmove(c->printers + i, c->printers + i + 1,
133*5e7646d2SAndroid Build Coastguard Worker (size_t)(c->num_printers - i) * sizeof(cupsd_printer_t *));
134*5e7646d2SAndroid Build Coastguard Worker }
135*5e7646d2SAndroid Build Coastguard Worker else
136*5e7646d2SAndroid Build Coastguard Worker return (0);
137*5e7646d2SAndroid Build Coastguard Worker
138*5e7646d2SAndroid Build Coastguard Worker /*
139*5e7646d2SAndroid Build Coastguard Worker * Update the IPP attributes (have to do this for member-names)...
140*5e7646d2SAndroid Build Coastguard Worker */
141*5e7646d2SAndroid Build Coastguard Worker
142*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterAttrs(c);
143*5e7646d2SAndroid Build Coastguard Worker
144*5e7646d2SAndroid Build Coastguard Worker return (1);
145*5e7646d2SAndroid Build Coastguard Worker }
146*5e7646d2SAndroid Build Coastguard Worker
147*5e7646d2SAndroid Build Coastguard Worker
148*5e7646d2SAndroid Build Coastguard Worker /*
149*5e7646d2SAndroid Build Coastguard Worker * 'cupsdDeletePrinterFromClasses()' - Delete a printer from all classes.
150*5e7646d2SAndroid Build Coastguard Worker */
151*5e7646d2SAndroid Build Coastguard Worker
152*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 if class changed, 0 otherwise */
cupsdDeletePrinterFromClasses(cupsd_printer_t * p)153*5e7646d2SAndroid Build Coastguard Worker cupsdDeletePrinterFromClasses(
154*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *p) /* I - Printer to delete */
155*5e7646d2SAndroid Build Coastguard Worker {
156*5e7646d2SAndroid Build Coastguard Worker int changed = 0; /* Any class changed? */
157*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *c; /* Pointer to current class */
158*5e7646d2SAndroid Build Coastguard Worker
159*5e7646d2SAndroid Build Coastguard Worker
160*5e7646d2SAndroid Build Coastguard Worker /*
161*5e7646d2SAndroid Build Coastguard Worker * Loop through the printer/class list and remove the printer
162*5e7646d2SAndroid Build Coastguard Worker * from each class listed...
163*5e7646d2SAndroid Build Coastguard Worker */
164*5e7646d2SAndroid Build Coastguard Worker
165*5e7646d2SAndroid Build Coastguard Worker for (c = (cupsd_printer_t *)cupsArrayFirst(Printers);
166*5e7646d2SAndroid Build Coastguard Worker c;
167*5e7646d2SAndroid Build Coastguard Worker c = (cupsd_printer_t *)cupsArrayNext(Printers))
168*5e7646d2SAndroid Build Coastguard Worker if (c->type & CUPS_PRINTER_CLASS)
169*5e7646d2SAndroid Build Coastguard Worker changed |= cupsdDeletePrinterFromClass(c, p);
170*5e7646d2SAndroid Build Coastguard Worker
171*5e7646d2SAndroid Build Coastguard Worker return (changed);
172*5e7646d2SAndroid Build Coastguard Worker }
173*5e7646d2SAndroid Build Coastguard Worker
174*5e7646d2SAndroid Build Coastguard Worker
175*5e7646d2SAndroid Build Coastguard Worker /*
176*5e7646d2SAndroid Build Coastguard Worker * 'cupsdFindAvailablePrinter()' - Find an available printer in a class.
177*5e7646d2SAndroid Build Coastguard Worker */
178*5e7646d2SAndroid Build Coastguard Worker
179*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t * /* O - Available printer or NULL */
cupsdFindAvailablePrinter(const char * name)180*5e7646d2SAndroid Build Coastguard Worker cupsdFindAvailablePrinter(
181*5e7646d2SAndroid Build Coastguard Worker const char *name) /* I - Class to check */
182*5e7646d2SAndroid Build Coastguard Worker {
183*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
184*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *c; /* Printer class */
185*5e7646d2SAndroid Build Coastguard Worker
186*5e7646d2SAndroid Build Coastguard Worker
187*5e7646d2SAndroid Build Coastguard Worker /*
188*5e7646d2SAndroid Build Coastguard Worker * Find the class...
189*5e7646d2SAndroid Build Coastguard Worker */
190*5e7646d2SAndroid Build Coastguard Worker
191*5e7646d2SAndroid Build Coastguard Worker if ((c = cupsdFindClass(name)) == NULL)
192*5e7646d2SAndroid Build Coastguard Worker {
193*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to find class \"%s\"!", name);
194*5e7646d2SAndroid Build Coastguard Worker return (NULL);
195*5e7646d2SAndroid Build Coastguard Worker }
196*5e7646d2SAndroid Build Coastguard Worker
197*5e7646d2SAndroid Build Coastguard Worker if (c->num_printers == 0)
198*5e7646d2SAndroid Build Coastguard Worker return (NULL);
199*5e7646d2SAndroid Build Coastguard Worker
200*5e7646d2SAndroid Build Coastguard Worker /*
201*5e7646d2SAndroid Build Coastguard Worker * Make sure that the last printer is also a valid index into the printer
202*5e7646d2SAndroid Build Coastguard Worker * array. If not, reset the last printer to 0...
203*5e7646d2SAndroid Build Coastguard Worker */
204*5e7646d2SAndroid Build Coastguard Worker
205*5e7646d2SAndroid Build Coastguard Worker if (c->last_printer >= c->num_printers)
206*5e7646d2SAndroid Build Coastguard Worker c->last_printer = 0;
207*5e7646d2SAndroid Build Coastguard Worker
208*5e7646d2SAndroid Build Coastguard Worker /*
209*5e7646d2SAndroid Build Coastguard Worker * Loop through the printers in the class and return the first idle
210*5e7646d2SAndroid Build Coastguard Worker * printer... We keep track of the last printer that we used so that
211*5e7646d2SAndroid Build Coastguard Worker * a "round robin" type of scheduling is realized (otherwise the first
212*5e7646d2SAndroid Build Coastguard Worker * server might be saturated with print jobs...)
213*5e7646d2SAndroid Build Coastguard Worker *
214*5e7646d2SAndroid Build Coastguard Worker * Thanks to Joel Fredrikson for helping us get this right!
215*5e7646d2SAndroid Build Coastguard Worker */
216*5e7646d2SAndroid Build Coastguard Worker
217*5e7646d2SAndroid Build Coastguard Worker for (i = c->last_printer + 1; ; i ++)
218*5e7646d2SAndroid Build Coastguard Worker {
219*5e7646d2SAndroid Build Coastguard Worker if (i >= c->num_printers)
220*5e7646d2SAndroid Build Coastguard Worker i = 0;
221*5e7646d2SAndroid Build Coastguard Worker
222*5e7646d2SAndroid Build Coastguard Worker if (c->printers[i]->accepting &&
223*5e7646d2SAndroid Build Coastguard Worker (c->printers[i]->state == IPP_PRINTER_IDLE ||
224*5e7646d2SAndroid Build Coastguard Worker ((c->printers[i]->type & CUPS_PRINTER_REMOTE) && !c->printers[i]->job)))
225*5e7646d2SAndroid Build Coastguard Worker {
226*5e7646d2SAndroid Build Coastguard Worker c->last_printer = i;
227*5e7646d2SAndroid Build Coastguard Worker return (c->printers[i]);
228*5e7646d2SAndroid Build Coastguard Worker }
229*5e7646d2SAndroid Build Coastguard Worker
230*5e7646d2SAndroid Build Coastguard Worker if (i == c->last_printer)
231*5e7646d2SAndroid Build Coastguard Worker break;
232*5e7646d2SAndroid Build Coastguard Worker }
233*5e7646d2SAndroid Build Coastguard Worker
234*5e7646d2SAndroid Build Coastguard Worker return (NULL);
235*5e7646d2SAndroid Build Coastguard Worker }
236*5e7646d2SAndroid Build Coastguard Worker
237*5e7646d2SAndroid Build Coastguard Worker
238*5e7646d2SAndroid Build Coastguard Worker /*
239*5e7646d2SAndroid Build Coastguard Worker * 'cupsdFindClass()' - Find the named class.
240*5e7646d2SAndroid Build Coastguard Worker */
241*5e7646d2SAndroid Build Coastguard Worker
242*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t * /* O - Matching class or NULL */
cupsdFindClass(const char * name)243*5e7646d2SAndroid Build Coastguard Worker cupsdFindClass(const char *name) /* I - Name of class */
244*5e7646d2SAndroid Build Coastguard Worker {
245*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *c; /* Current class/printer */
246*5e7646d2SAndroid Build Coastguard Worker
247*5e7646d2SAndroid Build Coastguard Worker
248*5e7646d2SAndroid Build Coastguard Worker if ((c = cupsdFindDest(name)) != NULL && (c->type & CUPS_PRINTER_CLASS))
249*5e7646d2SAndroid Build Coastguard Worker return (c);
250*5e7646d2SAndroid Build Coastguard Worker else
251*5e7646d2SAndroid Build Coastguard Worker return (NULL);
252*5e7646d2SAndroid Build Coastguard Worker }
253*5e7646d2SAndroid Build Coastguard Worker
254*5e7646d2SAndroid Build Coastguard Worker
255*5e7646d2SAndroid Build Coastguard Worker /*
256*5e7646d2SAndroid Build Coastguard Worker * 'cupsdLoadAllClasses()' - Load classes from the classes.conf file.
257*5e7646d2SAndroid Build Coastguard Worker */
258*5e7646d2SAndroid Build Coastguard Worker
259*5e7646d2SAndroid Build Coastguard Worker void
cupsdLoadAllClasses(void)260*5e7646d2SAndroid Build Coastguard Worker cupsdLoadAllClasses(void)
261*5e7646d2SAndroid Build Coastguard Worker {
262*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
263*5e7646d2SAndroid Build Coastguard Worker cups_file_t *fp; /* classes.conf file */
264*5e7646d2SAndroid Build Coastguard Worker int linenum; /* Current line number */
265*5e7646d2SAndroid Build Coastguard Worker char line[4096], /* Line from file */
266*5e7646d2SAndroid Build Coastguard Worker *value, /* Pointer to value */
267*5e7646d2SAndroid Build Coastguard Worker *valueptr; /* Pointer into value */
268*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *p, /* Current printer class */
269*5e7646d2SAndroid Build Coastguard Worker *temp; /* Temporary pointer to printer */
270*5e7646d2SAndroid Build Coastguard Worker
271*5e7646d2SAndroid Build Coastguard Worker
272*5e7646d2SAndroid Build Coastguard Worker /*
273*5e7646d2SAndroid Build Coastguard Worker * Open the classes.conf file...
274*5e7646d2SAndroid Build Coastguard Worker */
275*5e7646d2SAndroid Build Coastguard Worker
276*5e7646d2SAndroid Build Coastguard Worker snprintf(line, sizeof(line), "%s/classes.conf", ServerRoot);
277*5e7646d2SAndroid Build Coastguard Worker if ((fp = cupsdOpenConfFile(line)) == NULL)
278*5e7646d2SAndroid Build Coastguard Worker return;
279*5e7646d2SAndroid Build Coastguard Worker
280*5e7646d2SAndroid Build Coastguard Worker /*
281*5e7646d2SAndroid Build Coastguard Worker * Read class configurations until we hit EOF...
282*5e7646d2SAndroid Build Coastguard Worker */
283*5e7646d2SAndroid Build Coastguard Worker
284*5e7646d2SAndroid Build Coastguard Worker linenum = 0;
285*5e7646d2SAndroid Build Coastguard Worker p = NULL;
286*5e7646d2SAndroid Build Coastguard Worker
287*5e7646d2SAndroid Build Coastguard Worker while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
288*5e7646d2SAndroid Build Coastguard Worker {
289*5e7646d2SAndroid Build Coastguard Worker /*
290*5e7646d2SAndroid Build Coastguard Worker * Decode the directive...
291*5e7646d2SAndroid Build Coastguard Worker */
292*5e7646d2SAndroid Build Coastguard Worker
293*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(line, "<Class") ||
294*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(line, "<DefaultClass"))
295*5e7646d2SAndroid Build Coastguard Worker {
296*5e7646d2SAndroid Build Coastguard Worker /*
297*5e7646d2SAndroid Build Coastguard Worker * <Class name> or <DefaultClass name>
298*5e7646d2SAndroid Build Coastguard Worker */
299*5e7646d2SAndroid Build Coastguard Worker
300*5e7646d2SAndroid Build Coastguard Worker if (p == NULL && value)
301*5e7646d2SAndroid Build Coastguard Worker {
302*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG, "Loading class %s...", value);
303*5e7646d2SAndroid Build Coastguard Worker
304*5e7646d2SAndroid Build Coastguard Worker /*
305*5e7646d2SAndroid Build Coastguard Worker * Since prior classes may have implicitly defined this class,
306*5e7646d2SAndroid Build Coastguard Worker * see if it already exists...
307*5e7646d2SAndroid Build Coastguard Worker */
308*5e7646d2SAndroid Build Coastguard Worker
309*5e7646d2SAndroid Build Coastguard Worker if ((p = cupsdFindDest(value)) != NULL)
310*5e7646d2SAndroid Build Coastguard Worker {
311*5e7646d2SAndroid Build Coastguard Worker p->type = CUPS_PRINTER_CLASS;
312*5e7646d2SAndroid Build Coastguard Worker cupsdSetStringf(&p->uri, "ipp://%s:%d/classes/%s", ServerName,
313*5e7646d2SAndroid Build Coastguard Worker LocalPort, value);
314*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&p->error_policy, "retry-job");
315*5e7646d2SAndroid Build Coastguard Worker }
316*5e7646d2SAndroid Build Coastguard Worker else
317*5e7646d2SAndroid Build Coastguard Worker p = cupsdAddClass(value);
318*5e7646d2SAndroid Build Coastguard Worker
319*5e7646d2SAndroid Build Coastguard Worker p->accepting = 1;
320*5e7646d2SAndroid Build Coastguard Worker p->state = IPP_PRINTER_IDLE;
321*5e7646d2SAndroid Build Coastguard Worker
322*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(line, "<DefaultClass"))
323*5e7646d2SAndroid Build Coastguard Worker DefaultPrinter = p;
324*5e7646d2SAndroid Build Coastguard Worker }
325*5e7646d2SAndroid Build Coastguard Worker else
326*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
327*5e7646d2SAndroid Build Coastguard Worker "Syntax error on line %d of classes.conf.", linenum);
328*5e7646d2SAndroid Build Coastguard Worker }
329*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "</Class>") || !_cups_strcasecmp(line, "</DefaultClass>"))
330*5e7646d2SAndroid Build Coastguard Worker {
331*5e7646d2SAndroid Build Coastguard Worker if (p != NULL)
332*5e7646d2SAndroid Build Coastguard Worker {
333*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterAttrs(p);
334*5e7646d2SAndroid Build Coastguard Worker p = NULL;
335*5e7646d2SAndroid Build Coastguard Worker }
336*5e7646d2SAndroid Build Coastguard Worker else
337*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
338*5e7646d2SAndroid Build Coastguard Worker "Syntax error on line %d of classes.conf.", linenum);
339*5e7646d2SAndroid Build Coastguard Worker }
340*5e7646d2SAndroid Build Coastguard Worker else if (!p)
341*5e7646d2SAndroid Build Coastguard Worker {
342*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
343*5e7646d2SAndroid Build Coastguard Worker "Syntax error on line %d of classes.conf.", linenum);
344*5e7646d2SAndroid Build Coastguard Worker }
345*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "PrinterId"))
346*5e7646d2SAndroid Build Coastguard Worker {
347*5e7646d2SAndroid Build Coastguard Worker if (value && (i = atoi(value)) > 0)
348*5e7646d2SAndroid Build Coastguard Worker p->printer_id = i;
349*5e7646d2SAndroid Build Coastguard Worker else
350*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "Bad PrinterId on line %d of classes.conf.", linenum);
351*5e7646d2SAndroid Build Coastguard Worker }
352*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "UUID"))
353*5e7646d2SAndroid Build Coastguard Worker {
354*5e7646d2SAndroid Build Coastguard Worker if (value && !strncmp(value, "urn:uuid:", 9))
355*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&(p->uuid), value);
356*5e7646d2SAndroid Build Coastguard Worker else
357*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
358*5e7646d2SAndroid Build Coastguard Worker "Bad UUID on line %d of classes.conf.", linenum);
359*5e7646d2SAndroid Build Coastguard Worker }
360*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "AuthInfoRequired"))
361*5e7646d2SAndroid Build Coastguard Worker {
362*5e7646d2SAndroid Build Coastguard Worker if (!cupsdSetAuthInfoRequired(p, value, NULL))
363*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
364*5e7646d2SAndroid Build Coastguard Worker "Bad AuthInfoRequired on line %d of classes.conf.",
365*5e7646d2SAndroid Build Coastguard Worker linenum);
366*5e7646d2SAndroid Build Coastguard Worker }
367*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Info"))
368*5e7646d2SAndroid Build Coastguard Worker {
369*5e7646d2SAndroid Build Coastguard Worker if (value)
370*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&p->info, value);
371*5e7646d2SAndroid Build Coastguard Worker }
372*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Location"))
373*5e7646d2SAndroid Build Coastguard Worker {
374*5e7646d2SAndroid Build Coastguard Worker if (value)
375*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&p->location, value);
376*5e7646d2SAndroid Build Coastguard Worker }
377*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Option") && value)
378*5e7646d2SAndroid Build Coastguard Worker {
379*5e7646d2SAndroid Build Coastguard Worker /*
380*5e7646d2SAndroid Build Coastguard Worker * Option name value
381*5e7646d2SAndroid Build Coastguard Worker */
382*5e7646d2SAndroid Build Coastguard Worker
383*5e7646d2SAndroid Build Coastguard Worker for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
384*5e7646d2SAndroid Build Coastguard Worker
385*5e7646d2SAndroid Build Coastguard Worker if (!*valueptr)
386*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
387*5e7646d2SAndroid Build Coastguard Worker "Syntax error on line %d of classes.conf.", linenum);
388*5e7646d2SAndroid Build Coastguard Worker else
389*5e7646d2SAndroid Build Coastguard Worker {
390*5e7646d2SAndroid Build Coastguard Worker for (; *valueptr && isspace(*valueptr & 255); *valueptr++ = '\0');
391*5e7646d2SAndroid Build Coastguard Worker
392*5e7646d2SAndroid Build Coastguard Worker p->num_options = cupsAddOption(value, valueptr, p->num_options,
393*5e7646d2SAndroid Build Coastguard Worker &(p->options));
394*5e7646d2SAndroid Build Coastguard Worker }
395*5e7646d2SAndroid Build Coastguard Worker }
396*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Printer"))
397*5e7646d2SAndroid Build Coastguard Worker {
398*5e7646d2SAndroid Build Coastguard Worker if (!value)
399*5e7646d2SAndroid Build Coastguard Worker {
400*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
401*5e7646d2SAndroid Build Coastguard Worker "Syntax error on line %d of classes.conf.", linenum);
402*5e7646d2SAndroid Build Coastguard Worker continue;
403*5e7646d2SAndroid Build Coastguard Worker }
404*5e7646d2SAndroid Build Coastguard Worker else if ((temp = cupsdFindPrinter(value)) == NULL)
405*5e7646d2SAndroid Build Coastguard Worker {
406*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_WARN,
407*5e7646d2SAndroid Build Coastguard Worker "Unknown printer %s on line %d of classes.conf.",
408*5e7646d2SAndroid Build Coastguard Worker value, linenum);
409*5e7646d2SAndroid Build Coastguard Worker
410*5e7646d2SAndroid Build Coastguard Worker /*
411*5e7646d2SAndroid Build Coastguard Worker * Add the missing remote printer...
412*5e7646d2SAndroid Build Coastguard Worker */
413*5e7646d2SAndroid Build Coastguard Worker
414*5e7646d2SAndroid Build Coastguard Worker if ((temp = cupsdAddPrinter(value)) != NULL)
415*5e7646d2SAndroid Build Coastguard Worker {
416*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&temp->make_model, "Remote Printer on unknown");
417*5e7646d2SAndroid Build Coastguard Worker
418*5e7646d2SAndroid Build Coastguard Worker temp->state = IPP_PRINTER_STOPPED;
419*5e7646d2SAndroid Build Coastguard Worker temp->type |= CUPS_PRINTER_REMOTE;
420*5e7646d2SAndroid Build Coastguard Worker
421*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&temp->location, "Location Unknown");
422*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&temp->info, "No Information Available");
423*5e7646d2SAndroid Build Coastguard Worker temp->hostname[0] = '\0';
424*5e7646d2SAndroid Build Coastguard Worker
425*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterAttrs(temp);
426*5e7646d2SAndroid Build Coastguard Worker }
427*5e7646d2SAndroid Build Coastguard Worker }
428*5e7646d2SAndroid Build Coastguard Worker
429*5e7646d2SAndroid Build Coastguard Worker if (temp)
430*5e7646d2SAndroid Build Coastguard Worker cupsdAddPrinterToClass(p, temp);
431*5e7646d2SAndroid Build Coastguard Worker }
432*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "State"))
433*5e7646d2SAndroid Build Coastguard Worker {
434*5e7646d2SAndroid Build Coastguard Worker /*
435*5e7646d2SAndroid Build Coastguard Worker * Set the initial queue state...
436*5e7646d2SAndroid Build Coastguard Worker */
437*5e7646d2SAndroid Build Coastguard Worker
438*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(value, "idle"))
439*5e7646d2SAndroid Build Coastguard Worker p->state = IPP_PRINTER_IDLE;
440*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(value, "stopped"))
441*5e7646d2SAndroid Build Coastguard Worker {
442*5e7646d2SAndroid Build Coastguard Worker p->state = IPP_PRINTER_STOPPED;
443*5e7646d2SAndroid Build Coastguard Worker
444*5e7646d2SAndroid Build Coastguard Worker for (i = 0 ; i < p->num_reasons; i ++)
445*5e7646d2SAndroid Build Coastguard Worker if (!strcmp("paused", p->reasons[i]))
446*5e7646d2SAndroid Build Coastguard Worker break;
447*5e7646d2SAndroid Build Coastguard Worker
448*5e7646d2SAndroid Build Coastguard Worker if (i >= p->num_reasons &&
449*5e7646d2SAndroid Build Coastguard Worker p->num_reasons < (int)(sizeof(p->reasons) / sizeof(p->reasons[0])))
450*5e7646d2SAndroid Build Coastguard Worker {
451*5e7646d2SAndroid Build Coastguard Worker p->reasons[p->num_reasons] = _cupsStrAlloc("paused");
452*5e7646d2SAndroid Build Coastguard Worker p->num_reasons ++;
453*5e7646d2SAndroid Build Coastguard Worker }
454*5e7646d2SAndroid Build Coastguard Worker }
455*5e7646d2SAndroid Build Coastguard Worker else
456*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
457*5e7646d2SAndroid Build Coastguard Worker "Syntax error on line %d of classes.conf.",
458*5e7646d2SAndroid Build Coastguard Worker linenum);
459*5e7646d2SAndroid Build Coastguard Worker }
460*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "StateMessage"))
461*5e7646d2SAndroid Build Coastguard Worker {
462*5e7646d2SAndroid Build Coastguard Worker /*
463*5e7646d2SAndroid Build Coastguard Worker * Set the initial queue state message...
464*5e7646d2SAndroid Build Coastguard Worker */
465*5e7646d2SAndroid Build Coastguard Worker
466*5e7646d2SAndroid Build Coastguard Worker if (value)
467*5e7646d2SAndroid Build Coastguard Worker strlcpy(p->state_message, value, sizeof(p->state_message));
468*5e7646d2SAndroid Build Coastguard Worker }
469*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "StateTime"))
470*5e7646d2SAndroid Build Coastguard Worker {
471*5e7646d2SAndroid Build Coastguard Worker /*
472*5e7646d2SAndroid Build Coastguard Worker * Set the state time...
473*5e7646d2SAndroid Build Coastguard Worker */
474*5e7646d2SAndroid Build Coastguard Worker
475*5e7646d2SAndroid Build Coastguard Worker if (value)
476*5e7646d2SAndroid Build Coastguard Worker p->state_time = atoi(value);
477*5e7646d2SAndroid Build Coastguard Worker }
478*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Accepting"))
479*5e7646d2SAndroid Build Coastguard Worker {
480*5e7646d2SAndroid Build Coastguard Worker /*
481*5e7646d2SAndroid Build Coastguard Worker * Set the initial accepting state...
482*5e7646d2SAndroid Build Coastguard Worker */
483*5e7646d2SAndroid Build Coastguard Worker
484*5e7646d2SAndroid Build Coastguard Worker if (value &&
485*5e7646d2SAndroid Build Coastguard Worker (!_cups_strcasecmp(value, "yes") ||
486*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(value, "on") ||
487*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(value, "true")))
488*5e7646d2SAndroid Build Coastguard Worker p->accepting = 1;
489*5e7646d2SAndroid Build Coastguard Worker else if (value &&
490*5e7646d2SAndroid Build Coastguard Worker (!_cups_strcasecmp(value, "no") ||
491*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(value, "off") ||
492*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(value, "false")))
493*5e7646d2SAndroid Build Coastguard Worker p->accepting = 0;
494*5e7646d2SAndroid Build Coastguard Worker else
495*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
496*5e7646d2SAndroid Build Coastguard Worker "Syntax error on line %d of classes.conf.",
497*5e7646d2SAndroid Build Coastguard Worker linenum);
498*5e7646d2SAndroid Build Coastguard Worker }
499*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "Shared"))
500*5e7646d2SAndroid Build Coastguard Worker {
501*5e7646d2SAndroid Build Coastguard Worker /*
502*5e7646d2SAndroid Build Coastguard Worker * Set the initial shared state...
503*5e7646d2SAndroid Build Coastguard Worker */
504*5e7646d2SAndroid Build Coastguard Worker
505*5e7646d2SAndroid Build Coastguard Worker if (value &&
506*5e7646d2SAndroid Build Coastguard Worker (!_cups_strcasecmp(value, "yes") ||
507*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(value, "on") ||
508*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(value, "true")))
509*5e7646d2SAndroid Build Coastguard Worker p->shared = 1;
510*5e7646d2SAndroid Build Coastguard Worker else if (value &&
511*5e7646d2SAndroid Build Coastguard Worker (!_cups_strcasecmp(value, "no") ||
512*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(value, "off") ||
513*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(value, "false")))
514*5e7646d2SAndroid Build Coastguard Worker p->shared = 0;
515*5e7646d2SAndroid Build Coastguard Worker else
516*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
517*5e7646d2SAndroid Build Coastguard Worker "Syntax error on line %d of classes.conf.",
518*5e7646d2SAndroid Build Coastguard Worker linenum);
519*5e7646d2SAndroid Build Coastguard Worker }
520*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "JobSheets"))
521*5e7646d2SAndroid Build Coastguard Worker {
522*5e7646d2SAndroid Build Coastguard Worker /*
523*5e7646d2SAndroid Build Coastguard Worker * Set the initial job sheets...
524*5e7646d2SAndroid Build Coastguard Worker */
525*5e7646d2SAndroid Build Coastguard Worker
526*5e7646d2SAndroid Build Coastguard Worker if (value)
527*5e7646d2SAndroid Build Coastguard Worker {
528*5e7646d2SAndroid Build Coastguard Worker for (valueptr = value;
529*5e7646d2SAndroid Build Coastguard Worker *valueptr && !isspace(*valueptr & 255);
530*5e7646d2SAndroid Build Coastguard Worker valueptr ++);
531*5e7646d2SAndroid Build Coastguard Worker
532*5e7646d2SAndroid Build Coastguard Worker if (*valueptr)
533*5e7646d2SAndroid Build Coastguard Worker *valueptr++ = '\0';
534*5e7646d2SAndroid Build Coastguard Worker
535*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&p->job_sheets[0], value);
536*5e7646d2SAndroid Build Coastguard Worker
537*5e7646d2SAndroid Build Coastguard Worker while (isspace(*valueptr & 255))
538*5e7646d2SAndroid Build Coastguard Worker valueptr ++;
539*5e7646d2SAndroid Build Coastguard Worker
540*5e7646d2SAndroid Build Coastguard Worker if (*valueptr)
541*5e7646d2SAndroid Build Coastguard Worker {
542*5e7646d2SAndroid Build Coastguard Worker for (value = valueptr;
543*5e7646d2SAndroid Build Coastguard Worker *valueptr && !isspace(*valueptr & 255);
544*5e7646d2SAndroid Build Coastguard Worker valueptr ++);
545*5e7646d2SAndroid Build Coastguard Worker
546*5e7646d2SAndroid Build Coastguard Worker if (*valueptr)
547*5e7646d2SAndroid Build Coastguard Worker *valueptr = '\0';
548*5e7646d2SAndroid Build Coastguard Worker
549*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&p->job_sheets[1], value);
550*5e7646d2SAndroid Build Coastguard Worker }
551*5e7646d2SAndroid Build Coastguard Worker }
552*5e7646d2SAndroid Build Coastguard Worker else
553*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
554*5e7646d2SAndroid Build Coastguard Worker "Syntax error on line %d of classes.conf.", linenum);
555*5e7646d2SAndroid Build Coastguard Worker }
556*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "AllowUser"))
557*5e7646d2SAndroid Build Coastguard Worker {
558*5e7646d2SAndroid Build Coastguard Worker if (value)
559*5e7646d2SAndroid Build Coastguard Worker {
560*5e7646d2SAndroid Build Coastguard Worker p->deny_users = 0;
561*5e7646d2SAndroid Build Coastguard Worker cupsdAddString(&(p->users), value);
562*5e7646d2SAndroid Build Coastguard Worker }
563*5e7646d2SAndroid Build Coastguard Worker else
564*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
565*5e7646d2SAndroid Build Coastguard Worker "Syntax error on line %d of classes.conf.", linenum);
566*5e7646d2SAndroid Build Coastguard Worker }
567*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "DenyUser"))
568*5e7646d2SAndroid Build Coastguard Worker {
569*5e7646d2SAndroid Build Coastguard Worker if (value)
570*5e7646d2SAndroid Build Coastguard Worker {
571*5e7646d2SAndroid Build Coastguard Worker p->deny_users = 1;
572*5e7646d2SAndroid Build Coastguard Worker cupsdAddString(&(p->users), value);
573*5e7646d2SAndroid Build Coastguard Worker }
574*5e7646d2SAndroid Build Coastguard Worker else
575*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
576*5e7646d2SAndroid Build Coastguard Worker "Syntax error on line %d of classes.conf.", linenum);
577*5e7646d2SAndroid Build Coastguard Worker }
578*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "QuotaPeriod"))
579*5e7646d2SAndroid Build Coastguard Worker {
580*5e7646d2SAndroid Build Coastguard Worker if (value)
581*5e7646d2SAndroid Build Coastguard Worker p->quota_period = atoi(value);
582*5e7646d2SAndroid Build Coastguard Worker else
583*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
584*5e7646d2SAndroid Build Coastguard Worker "Syntax error on line %d of classes.conf.", linenum);
585*5e7646d2SAndroid Build Coastguard Worker }
586*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "PageLimit"))
587*5e7646d2SAndroid Build Coastguard Worker {
588*5e7646d2SAndroid Build Coastguard Worker if (value)
589*5e7646d2SAndroid Build Coastguard Worker p->page_limit = atoi(value);
590*5e7646d2SAndroid Build Coastguard Worker else
591*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
592*5e7646d2SAndroid Build Coastguard Worker "Syntax error on line %d of classes.conf.", linenum);
593*5e7646d2SAndroid Build Coastguard Worker }
594*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "KLimit"))
595*5e7646d2SAndroid Build Coastguard Worker {
596*5e7646d2SAndroid Build Coastguard Worker if (value)
597*5e7646d2SAndroid Build Coastguard Worker p->k_limit = atoi(value);
598*5e7646d2SAndroid Build Coastguard Worker else
599*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
600*5e7646d2SAndroid Build Coastguard Worker "Syntax error on line %d of classes.conf.", linenum);
601*5e7646d2SAndroid Build Coastguard Worker }
602*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "OpPolicy"))
603*5e7646d2SAndroid Build Coastguard Worker {
604*5e7646d2SAndroid Build Coastguard Worker if (value)
605*5e7646d2SAndroid Build Coastguard Worker {
606*5e7646d2SAndroid Build Coastguard Worker cupsd_policy_t *pol; /* Policy */
607*5e7646d2SAndroid Build Coastguard Worker
608*5e7646d2SAndroid Build Coastguard Worker
609*5e7646d2SAndroid Build Coastguard Worker if ((pol = cupsdFindPolicy(value)) != NULL)
610*5e7646d2SAndroid Build Coastguard Worker {
611*5e7646d2SAndroid Build Coastguard Worker cupsdSetString(&p->op_policy, value);
612*5e7646d2SAndroid Build Coastguard Worker p->op_policy_ptr = pol;
613*5e7646d2SAndroid Build Coastguard Worker }
614*5e7646d2SAndroid Build Coastguard Worker else
615*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
616*5e7646d2SAndroid Build Coastguard Worker "Bad policy \"%s\" on line %d of classes.conf",
617*5e7646d2SAndroid Build Coastguard Worker value, linenum);
618*5e7646d2SAndroid Build Coastguard Worker }
619*5e7646d2SAndroid Build Coastguard Worker else
620*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
621*5e7646d2SAndroid Build Coastguard Worker "Syntax error on line %d of classes.conf.", linenum);
622*5e7646d2SAndroid Build Coastguard Worker }
623*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(line, "ErrorPolicy"))
624*5e7646d2SAndroid Build Coastguard Worker {
625*5e7646d2SAndroid Build Coastguard Worker if (value)
626*5e7646d2SAndroid Build Coastguard Worker {
627*5e7646d2SAndroid Build Coastguard Worker if (strcmp(value, "retry-current-job") && strcmp(value, "retry-job"))
628*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_WARN,
629*5e7646d2SAndroid Build Coastguard Worker "ErrorPolicy %s ignored on line %d of classes.conf",
630*5e7646d2SAndroid Build Coastguard Worker value, linenum);
631*5e7646d2SAndroid Build Coastguard Worker }
632*5e7646d2SAndroid Build Coastguard Worker else
633*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
634*5e7646d2SAndroid Build Coastguard Worker "Syntax error on line %d of classes.conf.", linenum);
635*5e7646d2SAndroid Build Coastguard Worker }
636*5e7646d2SAndroid Build Coastguard Worker else
637*5e7646d2SAndroid Build Coastguard Worker {
638*5e7646d2SAndroid Build Coastguard Worker /*
639*5e7646d2SAndroid Build Coastguard Worker * Something else we don't understand...
640*5e7646d2SAndroid Build Coastguard Worker */
641*5e7646d2SAndroid Build Coastguard Worker
642*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
643*5e7646d2SAndroid Build Coastguard Worker "Unknown configuration directive %s on line %d of classes.conf.",
644*5e7646d2SAndroid Build Coastguard Worker line, linenum);
645*5e7646d2SAndroid Build Coastguard Worker }
646*5e7646d2SAndroid Build Coastguard Worker }
647*5e7646d2SAndroid Build Coastguard Worker
648*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
649*5e7646d2SAndroid Build Coastguard Worker }
650*5e7646d2SAndroid Build Coastguard Worker
651*5e7646d2SAndroid Build Coastguard Worker
652*5e7646d2SAndroid Build Coastguard Worker /*
653*5e7646d2SAndroid Build Coastguard Worker * 'cupsdSaveAllClasses()' - Save classes to the classes.conf file.
654*5e7646d2SAndroid Build Coastguard Worker */
655*5e7646d2SAndroid Build Coastguard Worker
656*5e7646d2SAndroid Build Coastguard Worker void
cupsdSaveAllClasses(void)657*5e7646d2SAndroid Build Coastguard Worker cupsdSaveAllClasses(void)
658*5e7646d2SAndroid Build Coastguard Worker {
659*5e7646d2SAndroid Build Coastguard Worker cups_file_t *fp; /* classes.conf file */
660*5e7646d2SAndroid Build Coastguard Worker char filename[1024], /* classes.conf filename */
661*5e7646d2SAndroid Build Coastguard Worker value[2048], /* Value string */
662*5e7646d2SAndroid Build Coastguard Worker *name; /* Current user name */
663*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *pclass; /* Current printer class */
664*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
665*5e7646d2SAndroid Build Coastguard Worker cups_option_t *option; /* Current option */
666*5e7646d2SAndroid Build Coastguard Worker
667*5e7646d2SAndroid Build Coastguard Worker
668*5e7646d2SAndroid Build Coastguard Worker /*
669*5e7646d2SAndroid Build Coastguard Worker * Create the classes.conf file...
670*5e7646d2SAndroid Build Coastguard Worker */
671*5e7646d2SAndroid Build Coastguard Worker
672*5e7646d2SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/classes.conf", ServerRoot);
673*5e7646d2SAndroid Build Coastguard Worker
674*5e7646d2SAndroid Build Coastguard Worker if ((fp = cupsdCreateConfFile(filename, ConfigFilePerm)) == NULL)
675*5e7646d2SAndroid Build Coastguard Worker return;
676*5e7646d2SAndroid Build Coastguard Worker
677*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_INFO, "Saving classes.conf...");
678*5e7646d2SAndroid Build Coastguard Worker
679*5e7646d2SAndroid Build Coastguard Worker /*
680*5e7646d2SAndroid Build Coastguard Worker * Write a small header to the file...
681*5e7646d2SAndroid Build Coastguard Worker */
682*5e7646d2SAndroid Build Coastguard Worker
683*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "# Class configuration file for " CUPS_SVERSION "\n");
684*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "# Written by cupsd\n");
685*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "# DO NOT EDIT THIS FILE WHEN CUPSD IS RUNNING\n");
686*5e7646d2SAndroid Build Coastguard Worker
687*5e7646d2SAndroid Build Coastguard Worker /*
688*5e7646d2SAndroid Build Coastguard Worker * Write each local class known to the system...
689*5e7646d2SAndroid Build Coastguard Worker */
690*5e7646d2SAndroid Build Coastguard Worker
691*5e7646d2SAndroid Build Coastguard Worker for (pclass = (cupsd_printer_t *)cupsArrayFirst(Printers);
692*5e7646d2SAndroid Build Coastguard Worker pclass;
693*5e7646d2SAndroid Build Coastguard Worker pclass = (cupsd_printer_t *)cupsArrayNext(Printers))
694*5e7646d2SAndroid Build Coastguard Worker {
695*5e7646d2SAndroid Build Coastguard Worker /*
696*5e7646d2SAndroid Build Coastguard Worker * Skip remote destinations and regular printers...
697*5e7646d2SAndroid Build Coastguard Worker */
698*5e7646d2SAndroid Build Coastguard Worker
699*5e7646d2SAndroid Build Coastguard Worker if ((pclass->type & CUPS_PRINTER_REMOTE) ||
700*5e7646d2SAndroid Build Coastguard Worker !(pclass->type & CUPS_PRINTER_CLASS))
701*5e7646d2SAndroid Build Coastguard Worker continue;
702*5e7646d2SAndroid Build Coastguard Worker
703*5e7646d2SAndroid Build Coastguard Worker /*
704*5e7646d2SAndroid Build Coastguard Worker * Write printers as needed...
705*5e7646d2SAndroid Build Coastguard Worker */
706*5e7646d2SAndroid Build Coastguard Worker
707*5e7646d2SAndroid Build Coastguard Worker if (pclass == DefaultPrinter)
708*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "<DefaultClass %s>\n", pclass->name);
709*5e7646d2SAndroid Build Coastguard Worker else
710*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "<Class %s>\n", pclass->name);
711*5e7646d2SAndroid Build Coastguard Worker
712*5e7646d2SAndroid Build Coastguard Worker if (pclass->printer_id)
713*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "PrinterId %d\n", pclass->printer_id);
714*5e7646d2SAndroid Build Coastguard Worker
715*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "UUID %s\n", pclass->uuid);
716*5e7646d2SAndroid Build Coastguard Worker
717*5e7646d2SAndroid Build Coastguard Worker if (pclass->num_auth_info_required > 0)
718*5e7646d2SAndroid Build Coastguard Worker {
719*5e7646d2SAndroid Build Coastguard Worker switch (pclass->num_auth_info_required)
720*5e7646d2SAndroid Build Coastguard Worker {
721*5e7646d2SAndroid Build Coastguard Worker case 1 :
722*5e7646d2SAndroid Build Coastguard Worker strlcpy(value, pclass->auth_info_required[0], sizeof(value));
723*5e7646d2SAndroid Build Coastguard Worker break;
724*5e7646d2SAndroid Build Coastguard Worker
725*5e7646d2SAndroid Build Coastguard Worker case 2 :
726*5e7646d2SAndroid Build Coastguard Worker snprintf(value, sizeof(value), "%s,%s",
727*5e7646d2SAndroid Build Coastguard Worker pclass->auth_info_required[0],
728*5e7646d2SAndroid Build Coastguard Worker pclass->auth_info_required[1]);
729*5e7646d2SAndroid Build Coastguard Worker break;
730*5e7646d2SAndroid Build Coastguard Worker
731*5e7646d2SAndroid Build Coastguard Worker case 3 :
732*5e7646d2SAndroid Build Coastguard Worker default :
733*5e7646d2SAndroid Build Coastguard Worker snprintf(value, sizeof(value), "%s,%s,%s",
734*5e7646d2SAndroid Build Coastguard Worker pclass->auth_info_required[0],
735*5e7646d2SAndroid Build Coastguard Worker pclass->auth_info_required[1],
736*5e7646d2SAndroid Build Coastguard Worker pclass->auth_info_required[2]);
737*5e7646d2SAndroid Build Coastguard Worker break;
738*5e7646d2SAndroid Build Coastguard Worker }
739*5e7646d2SAndroid Build Coastguard Worker
740*5e7646d2SAndroid Build Coastguard Worker cupsFilePutConf(fp, "AuthInfoRequired", value);
741*5e7646d2SAndroid Build Coastguard Worker }
742*5e7646d2SAndroid Build Coastguard Worker
743*5e7646d2SAndroid Build Coastguard Worker if (pclass->info)
744*5e7646d2SAndroid Build Coastguard Worker cupsFilePutConf(fp, "Info", pclass->info);
745*5e7646d2SAndroid Build Coastguard Worker
746*5e7646d2SAndroid Build Coastguard Worker if (pclass->location)
747*5e7646d2SAndroid Build Coastguard Worker cupsFilePutConf(fp, "Location", pclass->location);
748*5e7646d2SAndroid Build Coastguard Worker
749*5e7646d2SAndroid Build Coastguard Worker if (pclass->state == IPP_PRINTER_STOPPED)
750*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "State Stopped\n");
751*5e7646d2SAndroid Build Coastguard Worker else
752*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "State Idle\n");
753*5e7646d2SAndroid Build Coastguard Worker
754*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "StateTime %d\n", (int)pclass->state_time);
755*5e7646d2SAndroid Build Coastguard Worker
756*5e7646d2SAndroid Build Coastguard Worker if (pclass->accepting)
757*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "Accepting Yes\n");
758*5e7646d2SAndroid Build Coastguard Worker else
759*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "Accepting No\n");
760*5e7646d2SAndroid Build Coastguard Worker
761*5e7646d2SAndroid Build Coastguard Worker if (pclass->shared)
762*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "Shared Yes\n");
763*5e7646d2SAndroid Build Coastguard Worker else
764*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "Shared No\n");
765*5e7646d2SAndroid Build Coastguard Worker
766*5e7646d2SAndroid Build Coastguard Worker snprintf(value, sizeof(value), "%s %s", pclass->job_sheets[0],
767*5e7646d2SAndroid Build Coastguard Worker pclass->job_sheets[1]);
768*5e7646d2SAndroid Build Coastguard Worker cupsFilePutConf(fp, "JobSheets", value);
769*5e7646d2SAndroid Build Coastguard Worker
770*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < pclass->num_printers; i ++)
771*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "Printer %s\n", pclass->printers[i]->name);
772*5e7646d2SAndroid Build Coastguard Worker
773*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "QuotaPeriod %d\n", pclass->quota_period);
774*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "PageLimit %d\n", pclass->page_limit);
775*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(fp, "KLimit %d\n", pclass->k_limit);
776*5e7646d2SAndroid Build Coastguard Worker
777*5e7646d2SAndroid Build Coastguard Worker for (name = (char *)cupsArrayFirst(pclass->users);
778*5e7646d2SAndroid Build Coastguard Worker name;
779*5e7646d2SAndroid Build Coastguard Worker name = (char *)cupsArrayNext(pclass->users))
780*5e7646d2SAndroid Build Coastguard Worker cupsFilePutConf(fp, pclass->deny_users ? "DenyUser" : "AllowUser", name);
781*5e7646d2SAndroid Build Coastguard Worker
782*5e7646d2SAndroid Build Coastguard Worker if (pclass->op_policy)
783*5e7646d2SAndroid Build Coastguard Worker cupsFilePutConf(fp, "OpPolicy", pclass->op_policy);
784*5e7646d2SAndroid Build Coastguard Worker if (pclass->error_policy)
785*5e7646d2SAndroid Build Coastguard Worker cupsFilePutConf(fp, "ErrorPolicy", pclass->error_policy);
786*5e7646d2SAndroid Build Coastguard Worker
787*5e7646d2SAndroid Build Coastguard Worker for (i = pclass->num_options, option = pclass->options;
788*5e7646d2SAndroid Build Coastguard Worker i > 0;
789*5e7646d2SAndroid Build Coastguard Worker i --, option ++)
790*5e7646d2SAndroid Build Coastguard Worker {
791*5e7646d2SAndroid Build Coastguard Worker snprintf(value, sizeof(value), "%s %s", option->name, option->value);
792*5e7646d2SAndroid Build Coastguard Worker cupsFilePutConf(fp, "Option", value);
793*5e7646d2SAndroid Build Coastguard Worker }
794*5e7646d2SAndroid Build Coastguard Worker
795*5e7646d2SAndroid Build Coastguard Worker if (pclass == DefaultPrinter)
796*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "</DefaultClass>\n");
797*5e7646d2SAndroid Build Coastguard Worker else
798*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(fp, "</Class>\n");
799*5e7646d2SAndroid Build Coastguard Worker }
800*5e7646d2SAndroid Build Coastguard Worker
801*5e7646d2SAndroid Build Coastguard Worker cupsdCloseCreatedConfFile(fp, filename);
802*5e7646d2SAndroid Build Coastguard Worker }
803