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