]>
Commit | Line | Data |
---|---|---|
a129ddbd | 1 | /* |
da275f55 | 2 | * "$Id: classes.c,v 1.34.2.18 2004/02/25 20:01:37 mike Exp $" |
a129ddbd | 3 | * |
cbbfcc63 | 4 | * Printer class routines for the Common UNIX Printing System (CUPS). |
a129ddbd | 5 | * |
1d9595ab | 6 | * Copyright 1997-2003 by Easy Software Products, all rights reserved. |
a129ddbd | 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 | |
8784b6a6 | 17 | * 44141 Airport View Drive, Suite 204 |
a129ddbd | 18 | * Hollywood, Maryland 20636-3111 USA |
19 | * | |
20 | * Voice: (301) 373-9603 | |
21 | * EMail: cups-info@cups.org | |
22 | * WWW: http://www.cups.org | |
23 | * | |
24 | * Contents: | |
25 | * | |
cbbfcc63 | 26 | * AddClass() - Add a class to the system. |
27 | * AddPrinterToClass() - Add a printer to a class... | |
28 | * DeletePrinterFromClass() - Delete a printer from a class. | |
29 | * DeletePrinterFromClasses() - Delete a printer from all classes. | |
30 | * DeleteAllClasses() - Remove all classes from the system. | |
31 | * FindAvailablePrinter() - Find an available printer in a class. | |
32 | * FindClass() - Find the named class. | |
33 | * LoadAllClasses() - Load classes from the classes.conf file. | |
34 | * SaveAllClasses() - Save classes to the classes.conf file. | |
a129ddbd | 35 | */ |
36 | ||
37 | /* | |
38 | * Include necessary headers... | |
39 | */ | |
40 | ||
fd8b1cf8 | 41 | #include "cupsd.h" |
a129ddbd | 42 | |
43 | ||
cbbfcc63 | 44 | /* |
45 | * 'AddClass()' - Add a class to the system. | |
46 | */ | |
47 | ||
48 | printer_t * /* O - New class */ | |
1049abbe | 49 | AddClass(const char *name) /* I - Name of class */ |
a9de544f | 50 | { |
cbbfcc63 | 51 | printer_t *c; /* New class */ |
52 | ||
53 | ||
54 | /* | |
55 | * Add the printer and set the type to "class"... | |
56 | */ | |
57 | ||
58 | if ((c = AddPrinter(name)) != NULL) | |
57c77867 | 59 | { |
d588a92e | 60 | /* |
61 | * Change from a printer to a class... | |
62 | */ | |
63 | ||
cbbfcc63 | 64 | c->type = CUPS_PRINTER_CLASS; |
d47f8ebe | 65 | |
99de6da0 | 66 | #ifdef AF_INET6 |
67 | if (Listeners[0].address.addr.sa_family == AF_INET6) | |
36992080 | 68 | SetStringf(&c->uri, "ipp://%s:%d/classes/%s", ServerName, |
69 | ntohs(Listeners[0].address.ipv6.sin6_port), name); | |
99de6da0 | 70 | else |
71 | #endif /* AF_INET6 */ | |
36992080 | 72 | SetStringf(&c->uri, "ipp://%s:%d/classes/%s", ServerName, |
73 | ntohs(Listeners[0].address.ipv4.sin_port), name); | |
57c77867 | 74 | } |
cbbfcc63 | 75 | |
76 | return (c); | |
77 | } | |
78 | ||
79 | ||
80 | /* | |
81 | * 'AddPrinterToClass()' - Add a printer to a class... | |
82 | */ | |
83 | ||
84 | void | |
85 | AddPrinterToClass(printer_t *c, /* I - Class to add to */ | |
86 | printer_t *p) /* I - Printer to add */ | |
87 | { | |
88 | printer_t **temp; /* Pointer to printer array */ | |
89 | ||
90 | ||
91 | /* | |
92 | * Allocate memory as needed... | |
93 | */ | |
94 | ||
95 | if (c->num_printers == 0) | |
96 | temp = malloc(sizeof(printer_t *)); | |
97 | else | |
98 | temp = realloc(c->printers, sizeof(printer_t *) * (c->num_printers + 1)); | |
99 | ||
100 | if (temp == NULL) | |
101 | { | |
5ea8888e | 102 | LogMessage(L_ERROR, "Unable to add printer %s to class %s!", |
cbbfcc63 | 103 | p->name, c->name); |
104 | return; | |
105 | } | |
106 | ||
107 | /* | |
108 | * Add the printer to the end of the array and update the number of printers. | |
109 | */ | |
110 | ||
111 | c->printers = temp; | |
112 | temp += c->num_printers; | |
113 | c->num_printers ++; | |
114 | ||
115 | *temp = p; | |
116 | ||
cbbfcc63 | 117 | /* |
118 | * Update the IPP attributes... | |
119 | */ | |
120 | ||
121 | SetPrinterAttrs(c); | |
a9de544f | 122 | } |
123 | ||
124 | ||
cbbfcc63 | 125 | /* |
126 | * 'DeletePrinterFromClass()' - Delete a printer from a class. | |
127 | */ | |
128 | ||
a9de544f | 129 | void |
cbbfcc63 | 130 | DeletePrinterFromClass(printer_t *c, /* I - Class to delete from */ |
131 | printer_t *p) /* I - Printer to delete */ | |
a9de544f | 132 | { |
8d853fdf | 133 | int i; /* Looping var */ |
134 | cups_ptype_t type; /* Class type */ | |
cbbfcc63 | 135 | |
136 | ||
137 | /* | |
138 | * See if the printer is in the class... | |
139 | */ | |
140 | ||
141 | for (i = 0; i < c->num_printers; i ++) | |
142 | if (p == c->printers[i]) | |
143 | break; | |
144 | ||
145 | /* | |
146 | * If it is, remove it from the list... | |
147 | */ | |
148 | ||
149 | if (i < c->num_printers) | |
150 | { | |
151 | /* | |
152 | * Yes, remove the printer... | |
153 | */ | |
154 | ||
155 | c->num_printers --; | |
156 | if (i < c->num_printers) | |
157 | memcpy(c->printers + i, c->printers + i + 1, | |
158 | (c->num_printers - i) * sizeof(printer_t *)); | |
159 | } | |
160 | ||
161 | /* | |
c1511ac0 | 162 | * Recompute the printer type mask as needed... |
cbbfcc63 | 163 | */ |
164 | ||
c1511ac0 | 165 | if (c->num_printers > 0) |
cbbfcc63 | 166 | { |
c1511ac0 | 167 | type = c->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT); |
168 | c->type = ~CUPS_PRINTER_REMOTE; | |
cbbfcc63 | 169 | |
c1511ac0 | 170 | for (i = 0; i < c->num_printers; i ++) |
171 | c->type &= c->printers[i]->type; | |
cbbfcc63 | 172 | |
c1511ac0 | 173 | c->type |= type; |
cbbfcc63 | 174 | |
c1511ac0 | 175 | /* |
176 | * Update the IPP attributes... | |
177 | */ | |
cbbfcc63 | 178 | |
c1511ac0 | 179 | SetPrinterAttrs(c); |
180 | } | |
a9de544f | 181 | } |
182 | ||
183 | ||
cbbfcc63 | 184 | /* |
185 | * 'DeletePrinterFromClasses()' - Delete a printer from all classes. | |
186 | */ | |
187 | ||
a9de544f | 188 | void |
cbbfcc63 | 189 | DeletePrinterFromClasses(printer_t *p) /* I - Printer to delete */ |
a9de544f | 190 | { |
a3ad20c9 | 191 | printer_t *c, /* Pointer to current class */ |
a3ad20c9 | 192 | *next; /* Pointer to next class */ |
cbbfcc63 | 193 | |
194 | ||
195 | /* | |
196 | * Loop through the printer/class list and remove the printer | |
197 | * from each class listed... | |
198 | */ | |
199 | ||
c1511ac0 | 200 | for (c = Printers; c != NULL; c = next) |
a3ad20c9 | 201 | { |
202 | next = c->next; | |
203 | ||
8d853fdf | 204 | if (c->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT)) |
cbbfcc63 | 205 | DeletePrinterFromClass(c, p); |
a3ad20c9 | 206 | } |
c1511ac0 | 207 | |
208 | /* | |
209 | * Then clean out any empty classes... | |
210 | */ | |
211 | ||
212 | for (c = Printers; c != NULL; c = next) | |
213 | { | |
214 | next = c->next; | |
215 | ||
216 | if ((c->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT)) && | |
217 | c->num_printers == 0) | |
9b2fe6bd | 218 | DeletePrinter(c, 1); |
c1511ac0 | 219 | } |
a9de544f | 220 | } |
221 | ||
222 | ||
cbbfcc63 | 223 | /* |
224 | * 'DeleteAllClasses()' - Remove all classes from the system. | |
225 | */ | |
226 | ||
a9de544f | 227 | void |
cbbfcc63 | 228 | DeleteAllClasses(void) |
a9de544f | 229 | { |
cbbfcc63 | 230 | printer_t *c, /* Pointer to current printer/class */ |
231 | *next; /* Pointer to next printer in list */ | |
232 | ||
233 | ||
234 | for (c = Printers; c != NULL; c = next) | |
235 | { | |
236 | next = c->next; | |
237 | ||
238 | if (c->type & CUPS_PRINTER_CLASS) | |
9b2fe6bd | 239 | DeletePrinter(c, 0); |
cbbfcc63 | 240 | } |
a9de544f | 241 | } |
242 | ||
243 | ||
cbbfcc63 | 244 | /* |
245 | * 'FindAvailablePrinter()' - Find an available printer in a class. | |
246 | */ | |
247 | ||
248 | printer_t * /* O - Available printer or NULL */ | |
1049abbe | 249 | FindAvailablePrinter(const char *name) /* I - Class to check */ |
a9de544f | 250 | { |
cbbfcc63 | 251 | int i; /* Looping var */ |
252 | printer_t *c; /* Printer class */ | |
253 | ||
254 | ||
255 | /* | |
256 | * Find the class... | |
257 | */ | |
258 | ||
259 | if ((c = FindClass(name)) == NULL) | |
4f954c4e | 260 | { |
261 | LogMessage(L_ERROR, "Unable to find class \"%s\"!", name); | |
cbbfcc63 | 262 | return (NULL); |
4f954c4e | 263 | } |
cbbfcc63 | 264 | |
265 | /* | |
266 | * Loop through the printers in the class and return the first idle | |
21eb8c86 | 267 | * printer... We keep track of the last printer that we used so that |
268 | * a "round robin" type of scheduling is realized (otherwise the first | |
269 | * server might be saturated with print jobs...) | |
5c9f9fef | 270 | * |
271 | * Thanks to Joel Fredrikson for helping us get this right! | |
cbbfcc63 | 272 | */ |
273 | ||
5c9f9fef | 274 | for (i = c->last_printer + 1; ; i ++) |
21eb8c86 | 275 | { |
5c9f9fef | 276 | if (i >= c->num_printers) |
277 | i = 0; | |
278 | ||
21eb8c86 | 279 | if (c->printers[i]->state == IPP_PRINTER_IDLE || |
280 | ((c->printers[i]->type & CUPS_PRINTER_REMOTE) && !c->printers[i]->job)) | |
281 | { | |
282 | c->last_printer = i; | |
cbbfcc63 | 283 | return (c->printers[i]); |
21eb8c86 | 284 | } |
35a2ba9d | 285 | |
5c9f9fef | 286 | if (i == c->last_printer) |
35a2ba9d | 287 | break; |
21eb8c86 | 288 | } |
cbbfcc63 | 289 | |
a9de544f | 290 | return (NULL); |
291 | } | |
292 | ||
293 | ||
cbbfcc63 | 294 | /* |
295 | * 'FindClass()' - Find the named class. | |
296 | */ | |
297 | ||
1049abbe | 298 | printer_t * /* O - Matching class or NULL */ |
299 | FindClass(const char *name) /* I - Name of class */ | |
a9de544f | 300 | { |
1049abbe | 301 | printer_t *c; /* Current class/printer */ |
8bd0441f | 302 | int diff; /* Difference */ |
cbbfcc63 | 303 | |
304 | ||
305 | for (c = Printers; c != NULL; c = c->next) | |
8bd0441f | 306 | if ((diff = strcasecmp(name, c->name)) == 0 && |
307 | (c->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT))) | |
308 | return (c); /* name == c->name */ | |
309 | else if (diff < 0) /* name < c->name */ | |
310 | return (NULL); | |
cbbfcc63 | 311 | |
a9de544f | 312 | return (NULL); |
313 | } | |
314 | ||
315 | ||
cbbfcc63 | 316 | /* |
317 | * 'LoadAllClasses()' - Load classes from the classes.conf file. | |
318 | */ | |
319 | ||
a9de544f | 320 | void |
321 | LoadAllClasses(void) | |
322 | { | |
7b0fde61 | 323 | cups_file_t *fp; /* classes.conf file */ |
cbbfcc63 | 324 | int linenum; /* Current line number */ |
325 | int len; /* Length of line */ | |
03081fd2 | 326 | char line[1024], /* Line from file */ |
cbbfcc63 | 327 | name[256], /* Parameter name */ |
328 | *nameptr, /* Pointer into name */ | |
aba2fa7e | 329 | *value, /* Pointer to value */ |
330 | *valueptr; /* Pointer into value */ | |
cbbfcc63 | 331 | printer_t *p, /* Current printer class */ |
332 | *temp; /* Temporary pointer to printer */ | |
333 | ||
334 | ||
335 | /* | |
cc0561c6 | 336 | * Open the classes.conf file... |
cbbfcc63 | 337 | */ |
338 | ||
a6988fb1 | 339 | snprintf(line, sizeof(line), "%s/classes.conf", ServerRoot); |
7b0fde61 | 340 | if ((fp = cupsFileOpen(line, "r")) == NULL) |
d47f8ebe | 341 | { |
342 | LogMessage(L_ERROR, "LoadAllClasses: Unable to open %s - %s", line, | |
343 | strerror(errno)); | |
cbbfcc63 | 344 | return; |
d47f8ebe | 345 | } |
cbbfcc63 | 346 | |
347 | /* | |
cc0561c6 | 348 | * Read class configurations until we hit EOF... |
cbbfcc63 | 349 | */ |
350 | ||
351 | linenum = 0; | |
352 | p = NULL; | |
353 | ||
7b0fde61 | 354 | while (cupsFileGets(fp, line, sizeof(line)) != NULL) |
cbbfcc63 | 355 | { |
356 | linenum ++; | |
357 | ||
358 | /* | |
359 | * Skip comment lines... | |
360 | */ | |
361 | ||
362 | if (line[0] == '#') | |
363 | continue; | |
364 | ||
365 | /* | |
753453e4 | 366 | * Strip trailing whitespace, if any... |
cbbfcc63 | 367 | */ |
368 | ||
369 | len = strlen(line); | |
370 | ||
da275f55 | 371 | while (len > 0 && isspace(line[len - 1] & 255)) |
cbbfcc63 | 372 | { |
373 | len --; | |
374 | line[len] = '\0'; | |
375 | } | |
376 | ||
377 | /* | |
378 | * Extract the name from the beginning of the line... | |
379 | */ | |
380 | ||
da275f55 | 381 | for (value = line; isspace(*value & 255); value ++); |
cbbfcc63 | 382 | |
da275f55 | 383 | for (nameptr = name; *value != '\0' && !isspace(*value & 255) && |
d588a92e | 384 | nameptr < (name + sizeof(name) - 1);) |
cbbfcc63 | 385 | *nameptr++ = *value++; |
386 | *nameptr = '\0'; | |
387 | ||
da275f55 | 388 | while (isspace(*value & 255)) |
cbbfcc63 | 389 | value ++; |
390 | ||
391 | if (name[0] == '\0') | |
392 | continue; | |
393 | ||
394 | /* | |
395 | * Decode the directive... | |
396 | */ | |
397 | ||
398 | if (strcmp(name, "<Class") == 0 || | |
399 | strcmp(name, "<DefaultClass") == 0) | |
400 | { | |
401 | /* | |
402 | * <Class name> or <DefaultClass name> | |
403 | */ | |
404 | ||
405 | if (line[len - 1] == '>' && p == NULL) | |
406 | { | |
407 | line[len - 1] = '\0'; | |
408 | ||
d47f8ebe | 409 | LogMessage(L_DEBUG, "LoadAllClasses: Loading class %s...", value); |
410 | ||
cbbfcc63 | 411 | p = AddClass(value); |
4139b718 | 412 | p->accepting = 1; |
413 | p->state = IPP_PRINTER_IDLE; | |
cbbfcc63 | 414 | |
415 | if (strcmp(name, "<DefaultClass") == 0) | |
416 | DefaultPrinter = p; | |
417 | } | |
418 | else | |
419 | { | |
5ea8888e | 420 | LogMessage(L_ERROR, "Syntax error on line %d of classes.conf.", |
cbbfcc63 | 421 | linenum); |
422 | return; | |
423 | } | |
424 | } | |
425 | else if (strcmp(name, "</Class>") == 0) | |
426 | { | |
427 | if (p != NULL) | |
428 | { | |
429 | SetPrinterAttrs(p); | |
430 | p = NULL; | |
431 | } | |
432 | else | |
433 | { | |
5ea8888e | 434 | LogMessage(L_ERROR, "Syntax error on line %d of classes.conf.", |
cbbfcc63 | 435 | linenum); |
436 | return; | |
437 | } | |
438 | } | |
439 | else if (p == NULL) | |
440 | { | |
5ea8888e | 441 | LogMessage(L_ERROR, "Syntax error on line %d of classes.conf.", |
cbbfcc63 | 442 | linenum); |
443 | return; | |
444 | } | |
445 | ||
446 | else if (strcmp(name, "Info") == 0) | |
36992080 | 447 | SetString(&p->info, value); |
cbbfcc63 | 448 | else if (strcmp(name, "Location") == 0) |
36992080 | 449 | SetString(&p->location, value); |
cbbfcc63 | 450 | else if (strcmp(name, "Printer") == 0) |
451 | { | |
36992080 | 452 | if ((temp = FindPrinter(value)) == NULL) |
453 | { | |
5ea8888e | 454 | LogMessage(L_WARN, "Unknown printer %s on line %d of classes.conf.", |
cbbfcc63 | 455 | value, linenum); |
36992080 | 456 | |
457 | /* | |
458 | * Add the missing remote printer... | |
459 | */ | |
460 | ||
36564e2c | 461 | if ((temp = AddPrinter(value)) != NULL) |
462 | { | |
d5e914c2 | 463 | SetString(&temp->make_model, "Remote Printer on unknown"); |
36992080 | 464 | |
36564e2c | 465 | temp->state = IPP_PRINTER_STOPPED; |
466 | temp->type |= CUPS_PRINTER_REMOTE; | |
467 | temp->browse_time = 2147483647; | |
36992080 | 468 | |
36564e2c | 469 | SetString(&temp->location, "Location Unknown"); |
470 | SetString(&temp->info, "No Information Available"); | |
471 | temp->hostname[0] = '\0'; | |
36992080 | 472 | |
36564e2c | 473 | SetPrinterAttrs(temp); |
474 | } | |
36992080 | 475 | } |
476 | ||
477 | if (temp) | |
478 | AddPrinterToClass(p, temp); | |
cbbfcc63 | 479 | } |
480 | else if (strcmp(name, "State") == 0) | |
481 | { | |
482 | /* | |
483 | * Set the initial queue state... | |
484 | */ | |
485 | ||
486 | if (strcasecmp(value, "idle") == 0) | |
487 | p->state = IPP_PRINTER_IDLE; | |
488 | else if (strcasecmp(value, "stopped") == 0) | |
489 | p->state = IPP_PRINTER_STOPPED; | |
05e63c18 | 490 | } |
03081fd2 | 491 | else if (strcmp(name, "StateMessage") == 0) |
492 | { | |
493 | /* | |
494 | * Set the initial queue state message... | |
495 | */ | |
496 | ||
da275f55 | 497 | while (isspace(*value & 255)) |
03081fd2 | 498 | value ++; |
499 | ||
def978d5 | 500 | strlcpy(p->state_message, value, sizeof(p->state_message)); |
03081fd2 | 501 | } |
05e63c18 | 502 | else if (strcmp(name, "Accepting") == 0) |
503 | { | |
504 | /* | |
505 | * Set the initial accepting state... | |
506 | */ | |
507 | ||
508 | if (strcasecmp(value, "yes") == 0) | |
509 | p->accepting = 1; | |
510 | else | |
511 | p->accepting = 0; | |
512 | } | |
aba2fa7e | 513 | else if (strcmp(name, "JobSheets") == 0) |
514 | { | |
515 | /* | |
516 | * Set the initial job sheets... | |
517 | */ | |
518 | ||
da275f55 | 519 | for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++); |
aba2fa7e | 520 | |
521 | if (*valueptr) | |
522 | *valueptr++ = '\0'; | |
523 | ||
36992080 | 524 | SetString(&p->job_sheets[0], value); |
aba2fa7e | 525 | |
da275f55 | 526 | while (isspace(*valueptr & 255)) |
aba2fa7e | 527 | valueptr ++; |
528 | ||
529 | if (*valueptr) | |
530 | { | |
da275f55 | 531 | for (value = valueptr; *valueptr && !isspace(*valueptr & 255); valueptr ++); |
aba2fa7e | 532 | |
533 | if (*valueptr) | |
534 | *valueptr++ = '\0'; | |
535 | ||
36992080 | 536 | SetString(&p->job_sheets[1], value); |
aba2fa7e | 537 | } |
538 | } | |
d7845573 | 539 | else if (strcmp(name, "AllowUser") == 0) |
540 | { | |
541 | p->deny_users = 0; | |
542 | AddPrinterUser(p, value); | |
543 | } | |
544 | else if (strcmp(name, "DenyUser") == 0) | |
545 | { | |
546 | p->deny_users = 1; | |
547 | AddPrinterUser(p, value); | |
548 | } | |
549 | else if (strcmp(name, "QuotaPeriod") == 0) | |
550 | p->quota_period = atoi(value); | |
551 | else if (strcmp(name, "PageLimit") == 0) | |
552 | p->page_limit = atoi(value); | |
553 | else if (strcmp(name, "KLimit") == 0) | |
554 | p->k_limit = atoi(value); | |
05e63c18 | 555 | else |
556 | { | |
557 | /* | |
558 | * Something else we don't understand... | |
559 | */ | |
4139b718 | 560 | |
5ea8888e | 561 | LogMessage(L_ERROR, "Unknown configuration directive %s on line %d of classes.conf.", |
05e63c18 | 562 | name, linenum); |
cbbfcc63 | 563 | } |
564 | } | |
565 | ||
7b0fde61 | 566 | cupsFileClose(fp); |
a9de544f | 567 | } |
568 | ||
569 | ||
cbbfcc63 | 570 | /* |
571 | * 'SaveAllClasses()' - Save classes to the classes.conf file. | |
572 | */ | |
573 | ||
a9de544f | 574 | void |
575 | SaveAllClasses(void) | |
576 | { | |
7b0fde61 | 577 | cups_file_t *fp; /* classes.conf file */ |
cc0561c6 | 578 | char temp[1024]; /* Temporary string */ |
579 | printer_t *pclass; /* Current printer class */ | |
580 | int i; /* Looping var */ | |
581 | time_t curtime; /* Current time */ | |
582 | struct tm *curdate; /* Current date */ | |
583 | ||
584 | ||
585 | /* | |
586 | * Create the classes.conf file... | |
587 | */ | |
588 | ||
a6988fb1 | 589 | snprintf(temp, sizeof(temp), "%s/classes.conf", ServerRoot); |
7b0fde61 | 590 | if ((fp = cupsFileOpen(temp, "w")) == NULL) |
cc0561c6 | 591 | { |
5ea8888e | 592 | LogMessage(L_ERROR, "Unable to save classes.conf - %s", strerror(errno)); |
cc0561c6 | 593 | return; |
594 | } | |
595 | else | |
5ea8888e | 596 | LogMessage(L_INFO, "Saving classes.conf..."); |
cc0561c6 | 597 | |
35a2ba9d | 598 | /* |
599 | * Restrict access to the file... | |
600 | */ | |
601 | ||
aa7b8dba | 602 | fchown(cupsFileNumber(fp), getuid(), Group); |
d59a189c | 603 | fchmod(cupsFileNumber(fp), ConfigFilePerm); |
35a2ba9d | 604 | |
cc0561c6 | 605 | /* |
606 | * Write a small header to the file... | |
607 | */ | |
608 | ||
609 | curtime = time(NULL); | |
aa3b74e1 | 610 | curdate = localtime(&curtime); |
8a32fc08 | 611 | strftime(temp, sizeof(temp) - 1, CUPS_STRFTIME_FORMAT, curdate); |
cc0561c6 | 612 | |
7b0fde61 | 613 | cupsFilePuts(fp, "# Class configuration file for " CUPS_SVERSION "\n"); |
614 | cupsFilePrintf(fp, "# Written by cupsd on %s\n", temp); | |
cc0561c6 | 615 | |
616 | /* | |
617 | * Write each local class known to the system... | |
618 | */ | |
619 | ||
620 | for (pclass = Printers; pclass != NULL; pclass = pclass->next) | |
621 | { | |
622 | /* | |
623 | * Skip remote destinations and regular printers... | |
624 | */ | |
625 | ||
626 | if ((pclass->type & CUPS_PRINTER_REMOTE) || | |
327265ac | 627 | (pclass->type & CUPS_PRINTER_IMPLICIT) || |
cc0561c6 | 628 | !(pclass->type & CUPS_PRINTER_CLASS)) |
629 | continue; | |
630 | ||
631 | /* | |
632 | * Write printers as needed... | |
633 | */ | |
634 | ||
635 | if (pclass == DefaultPrinter) | |
7b0fde61 | 636 | cupsFilePrintf(fp, "<DefaultClass %s>\n", pclass->name); |
cc0561c6 | 637 | else |
7b0fde61 | 638 | cupsFilePrintf(fp, "<Class %s>\n", pclass->name); |
cc0561c6 | 639 | |
36992080 | 640 | if (pclass->info) |
7b0fde61 | 641 | cupsFilePrintf(fp, "Info %s\n", pclass->info); |
753453e4 | 642 | |
36992080 | 643 | if (pclass->location) |
7b0fde61 | 644 | cupsFilePrintf(fp, "Location %s\n", pclass->location); |
753453e4 | 645 | |
cc0561c6 | 646 | if (pclass->state == IPP_PRINTER_STOPPED) |
03081fd2 | 647 | { |
7b0fde61 | 648 | cupsFilePuts(fp, "State Stopped\n"); |
649 | cupsFilePrintf(fp, "StateMessage %s\n", pclass->state_message); | |
03081fd2 | 650 | } |
cc0561c6 | 651 | else |
7b0fde61 | 652 | cupsFilePuts(fp, "State Idle\n"); |
753453e4 | 653 | |
05e63c18 | 654 | if (pclass->accepting) |
7b0fde61 | 655 | cupsFilePuts(fp, "Accepting Yes\n"); |
05e63c18 | 656 | else |
7b0fde61 | 657 | cupsFilePuts(fp, "Accepting No\n"); |
cc0561c6 | 658 | |
659 | for (i = 0; i < pclass->num_printers; i ++) | |
7b0fde61 | 660 | cupsFilePrintf(fp, "Printer %s\n", pclass->printers[i]->name); |
cc0561c6 | 661 | |
7b0fde61 | 662 | cupsFilePrintf(fp, "QuotaPeriod %d\n", pclass->quota_period); |
663 | cupsFilePrintf(fp, "PageLimit %d\n", pclass->page_limit); | |
664 | cupsFilePrintf(fp, "KLimit %d\n", pclass->k_limit); | |
d7845573 | 665 | |
666 | for (i = 0; i < pclass->num_users; i ++) | |
7b0fde61 | 667 | cupsFilePrintf(fp, "%sUser %s\n", pclass->deny_users ? "Deny" : "Allow", |
668 | pclass->users[i]); | |
d7845573 | 669 | |
7b0fde61 | 670 | cupsFilePuts(fp, "</Class>\n"); |
cc0561c6 | 671 | } |
672 | ||
7b0fde61 | 673 | cupsFileClose(fp); |
a9de544f | 674 | } |
675 | ||
676 | ||
a129ddbd | 677 | /* |
da275f55 | 678 | * End of "$Id: classes.c,v 1.34.2.18 2004/02/25 20:01:37 mike Exp $". |
a129ddbd | 679 | */ |