]> git.ipfire.org Git - thirdparty/cups.git/blame - scheduler/printers.c
Fixed address to 44141 Airport View Drive...
[thirdparty/cups.git] / scheduler / printers.c
CommitLineData
a129ddbd 1/*
8784b6a6 2 * "$Id: printers.c,v 1.20 1999/06/18 18:36:49 mike Exp $"
a129ddbd 3 *
cbbfcc63 4 * Printer routines for the Common UNIX Printing System (CUPS).
a129ddbd 5 *
a9de544f 6 * Copyright 1997-1999 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 *
6abc7437 26 * AddPrinter() - Add a printer to the system.
27 * DeleteAllPrinters() - Delete all printers from the system.
28 * DeletePrinter() - Delete a printer from the system.
29 * FindPrinter() - Find a printer in the list.
30 * LoadAllPrinters() - Load printers from the printers.conf file.
cbbfcc63 31 * SaveAllPrinters() - Save all printer definitions to the printers.conf
32 * SetPrinterAttrs() - Set printer attributes based upon the PPD file.
33 * SetPrinterState() - Update the current state of a printer.
34 * StopPrinter() - Stop a printer from printing any jobs...
a129ddbd 35 */
36
37/*
38 * Include necessary headers...
39 */
40
fd8b1cf8 41#include "cupsd.h"
a129ddbd 42
43
44/*
a9de544f 45 * 'AddPrinter()' - Add a printer to the system.
46 */
47
48printer_t * /* O - New printer */
49AddPrinter(char *name) /* I - Name of printer */
50{
51 printer_t *p, /* New printer */
52 *current, /* Current printer in list */
53 *prev; /* Previous printer in list */
54
55
56 /*
57 * Range check input...
58 */
59
60 if (name == NULL)
61 return (NULL);
62
63 /*
64 * Create a new printer entity...
65 */
66
67 if ((p = calloc(sizeof(printer_t), 1)) == NULL)
68 return (NULL);
69
f3d580b9 70 strcpy(p->name, name);
71 p->state = IPP_PRINTER_STOPPED;
c7fa9d06 72 p->accepting = 0;
73 p->filetype = mimeAddType(MimeDatabase, "printer", name);
74
75 /*
76 * Setup required filters and IPP attributes...
77 */
78
cbbfcc63 79 SetPrinterAttrs(p);
a9de544f 80
81 /*
82 * Insert the printer in the printer list alphabetically...
83 */
84
85 for (prev = NULL, current = Printers;
86 current != NULL;
87 prev = current, current = current->next)
f3d580b9 88 if (strcasecmp(p->name, current->name) < 0)
a9de544f 89 break;
90
91 /*
92 * Insert this printer before the current one...
93 */
94
95 if (prev == NULL)
96 Printers = p;
97 else
98 prev->next = p;
99
100 p->next = current;
101
102 return (p);
103}
104
105
c7fa9d06 106/*
107 * 'AddPrinterFilter()' - Add a MIME filter for a printer.
108 */
109
110void
111AddPrinterFilter(printer_t *p, /* I - Printer to add to */
112 char *filter) /* I - Filter to add */
113{
114 int i; /* Looping var */
115 char super[MIME_MAX_SUPER], /* Super-type for filter */
116 type[MIME_MAX_TYPE], /* Type for filter */
117 program[1024]; /* Program/filter name */
118 int cost; /* Cost of filter */
119 mime_type_t **temptype; /* MIME type looping var */
120
121
122 /*
123 * Range check input...
124 */
125
126 if (p == NULL || filter == NULL)
127 return;
128
129 /*
130 * Parse the filter string; it should be in the following format:
131 *
132 * super/type cost program
133 */
134
135 if (sscanf(filter, "%[^/]/%s%d%s", super, type, &cost, program) != 4)
136 {
137 LogMessage(LOG_ERROR, "AddPrinterFilter: Invalid filter string \"%s\"!",
138 filter);
139 return;
140 }
141
142 /*
143 * Add the filter to the MIME database, supporting wildcards as needed...
144 */
145
146 for (temptype = MimeDatabase->types, i = MimeDatabase->num_types;
147 i > 0;
148 i --, temptype ++)
149 if ((super[0] == '*' || strcmp((*temptype)->super, super) == 0) &&
150 (type[0] == '*' || strcmp((*temptype)->type, type) == 0))
151 mimeAddFilter(MimeDatabase, *temptype, p->filetype, cost, program);
152}
153
154
a9de544f 155/*
156 * 'DeleteAllPrinters()' - Delete all printers from the system.
157 */
158
159void
160DeleteAllPrinters(void)
161{
cbbfcc63 162 printer_t *p, /* Pointer to current printer/class */
163 *next; /* Pointer to next printer in list */
164
165
166 for (p = Printers; p != NULL; p = next)
167 {
168 next = p->next;
169
170 if (!(p->type & CUPS_PRINTER_CLASS))
171 DeletePrinter(p);
172 }
a9de544f 173}
174
175
176/*
177 * 'DeletePrinter()' - Delete a printer from the system.
178 */
179
180void
181DeletePrinter(printer_t *p) /* I - Printer to delete */
182{
3270670b 183 int i; /* Looping var */
a9de544f 184 printer_t *current, /* Current printer in list */
185 *prev; /* Previous printer in list */
186
187
188 /*
189 * Range check input...
190 */
191
192 if (p == NULL)
193 return;
194
195 /*
196 * Stop printing on this printer...
197 */
198
199 StopPrinter(p);
200
201 /*
202 * Remove the printer from the list...
203 */
204
205 for (prev = NULL, current = Printers;
206 current != NULL;
207 prev = current, current = current->next)
208 if (p == current)
209 break;
210
211 if (current == NULL)
212 {
213 fputs("cupsd: WARNING - tried to delete a non-existent printer!\n", stderr);
214 return;
215 }
216
217 if (prev == NULL)
218 Printers = p->next;
219 else
220 prev->next = p->next;
221
3270670b 222 if (p->printers != NULL)
223 free(p->printers);
224
225 ippDelete(p->attrs);
226
a9de544f 227 free(p);
3270670b 228
229 /*
230 * If p is the default printer, assign the next one...
231 */
232
233 if (p == DefaultPrinter)
234 DefaultPrinter = Printers;
a9de544f 235}
236
237
c7fa9d06 238/*
239 * 'AddPrinterFilter()' - Add a MIME filter for a printer.
240 */
241
242void
243DeletePrinterFilters(printer_t *p) /* I - Printer to remove from */
244{
245 int i; /* Looping var */
246 mime_filter_t *filter; /* MIME filter looping var */
247
248
249 /*
250 * Range check input...
251 */
252
253 if (p == NULL)
254 return;
255
256 /*
257 * Remove all filters from the MIME database that have a destination
258 * type == printer...
259 */
260
261 for (filter = MimeDatabase->filters, i = MimeDatabase->num_filters;
262 i > 0;
263 i --, filter ++)
264 if (filter->dst == p->filetype)
265 {
266 /*
267 * Delete the current filter...
268 */
269
270 MimeDatabase->num_filters --;
271
272 if (i > 1)
273 memcpy(filter, filter + 1, sizeof(mime_filter_t) * (i - 1));
274
275 filter --;
276 }
277}
278
279
a9de544f 280/*
281 * 'FindPrinter()' - Find a printer in the list.
282 */
283
284printer_t * /* O - Printer in list */
285FindPrinter(char *name) /* I - Name of printer to find */
286{
287 printer_t *p; /* Current printer */
288
289
290 for (p = Printers; p != NULL; p = p->next)
f3d580b9 291 switch (strcasecmp(name, p->name))
a9de544f 292 {
cbbfcc63 293 case 0 : /* name == p->name */
294 if (!(p->type & CUPS_PRINTER_CLASS))
295 return (p);
a9de544f 296 case 1 : /* name > p->name */
297 break;
a9de544f 298 case -1 : /* name < p->name */
299 return (NULL);
300 }
301
302 return (NULL);
303}
304
305
306/*
307 * 'LoadAllPrinters()' - Load printers from the printers.conf file.
308 */
309
310void
311LoadAllPrinters(void)
312{
a9de544f 313 FILE *fp; /* printers.conf file */
6abc7437 314 int i; /* Looping var */
a9de544f 315 int linenum; /* Current line number */
316 int len; /* Length of line */
a74b005d 317 char line[HTTP_MAX_BUFFER], /* Line from file */
a9de544f 318 name[256], /* Parameter name */
319 *nameptr, /* Pointer into name */
6abc7437 320 *value, /* Pointer to value */
321 *lineptr, /* Pointer in line */
c7fa9d06 322 *temp; /* Temporary pointer */
a9de544f 323 printer_t *p; /* Current printer */
324
325
326 /*
327 * Open the printer.conf file...
328 */
329
a74b005d 330 sprintf(line, "%s/conf/printers.conf", ServerRoot);
a9de544f 331 if ((fp = fopen(line, "r")) == NULL)
332 return;
333
334 /*
335 * Read printer configurations until we hit EOF...
336 */
337
338 linenum = 0;
339 p = NULL;
340
341 while (fgets(line, sizeof(line), fp) != NULL)
342 {
343 linenum ++;
344
345 /*
346 * Skip comment lines...
347 */
348
349 if (line[0] == '#')
350 continue;
351
352 /*
353 * Strip trailing newline, if any...
354 */
355
356 len = strlen(line);
357
358 if (line[len - 1] == '\n')
359 {
360 len --;
361 line[len] = '\0';
362 }
363
364 /*
365 * Extract the name from the beginning of the line...
366 */
367
368 for (value = line; isspace(*value); value ++);
369
370 for (nameptr = name; *value != '\0' && !isspace(*value);)
371 *nameptr++ = *value++;
372 *nameptr = '\0';
373
374 while (isspace(*value))
375 value ++;
376
377 if (name[0] == '\0')
378 continue;
379
380 /*
381 * Decode the directive...
382 */
383
1d2c70a6 384 if (strcmp(name, "<Printer") == 0 ||
385 strcmp(name, "<DefaultPrinter") == 0)
a9de544f 386 {
387 /*
1d2c70a6 388 * <Printer name> or <DefaultPrinter name>
a9de544f 389 */
390
391 if (line[len - 1] == '>' && p == NULL)
392 {
cbbfcc63 393 /*
394 * Add the printer and a base file type...
395 */
396
a9de544f 397 line[len - 1] = '\0';
398
c7fa9d06 399 p = AddPrinter(value);
cbbfcc63 400
401 /*
402 * Set the default printer as needed...
403 */
404
1d2c70a6 405 if (strcmp(name, "<DefaultPrinter") == 0)
cbbfcc63 406 DefaultPrinter = p;
a9de544f 407 }
408 else
409 {
410 LogMessage(LOG_ERROR, "Syntax error on line %d of printers.conf.",
411 linenum);
412 return;
413 }
414 }
415 else if (strcmp(name, "</Printer>") == 0)
416 {
417 if (p != NULL)
e5cf24b2 418 {
cbbfcc63 419 SetPrinterAttrs(p);
a9de544f 420 p = NULL;
e5cf24b2 421 }
a9de544f 422 else
423 {
424 LogMessage(LOG_ERROR, "Syntax error on line %d of printers.conf.",
425 linenum);
426 return;
427 }
428 }
429 else if (p == NULL)
430 {
431 LogMessage(LOG_ERROR, "Syntax error on line %d of printers.conf.",
432 linenum);
433 return;
434 }
435
436 else if (strcmp(name, "Info") == 0)
f3d580b9 437 strncpy(p->info, value, sizeof(p->info) - 1);
a9de544f 438 else if (strcmp(name, "MoreInfo") == 0)
f3d580b9 439 strncpy(p->more_info, value, sizeof(p->more_info) - 1);
a74b005d 440 else if (strcmp(name, "Location") == 0)
f3d580b9 441 strncpy(p->location, value, sizeof(p->location) - 1);
a74b005d 442 else if (strcmp(name, "DeviceURI") == 0)
a9de544f 443 strncpy(p->device_uri, value, sizeof(p->device_uri) - 1);
c7fa9d06 444 else if (strcmp(name, "State") == 0)
a9de544f 445 {
446 /*
c7fa9d06 447 * Set the initial queue state...
6abc7437 448 */
449
c7fa9d06 450 if (strcasecmp(value, "idle") == 0)
451 {
452 p->state = IPP_PRINTER_IDLE;
453 p->accepting = 1;
454 }
455 else if (strcasecmp(value, "stopped") == 0)
456 {
457 p->state = IPP_PRINTER_STOPPED;
458 p->accepting = 0;
459 }
a9de544f 460 }
c7fa9d06 461 else
a9de544f 462 {
463 /*
c7fa9d06 464 * Something else we don't understand...
a9de544f 465 */
466
c7fa9d06 467 LogMessage(LOG_ERROR, "Unknown configuration directive %s on line %d of printers.conf.",
468 name, linenum);
a9de544f 469 }
a9de544f 470 }
471
472 fclose(fp);
473}
474
475
d6de4648 476/*
477 * 'SaveAllPrinters()' - Save all printer definitions to the printers.conf
478 * file.
479 */
480
a9de544f 481void
482SaveAllPrinters(void)
483{
cc0561c6 484 FILE *fp; /* printers.conf file */
485 char temp[1024]; /* Temporary string */
486 printer_t *printer; /* Current printer class */
487 int i; /* Looping var */
488 time_t curtime; /* Current time */
489 struct tm *curdate; /* Current date */
490
491
492 /*
493 * Create the printers.conf file...
494 */
495
496 sprintf(temp, "%s/conf/printers.conf", ServerRoot);
497 if ((fp = fopen(temp, "w")) == NULL)
498 {
499 LogMessage(LOG_ERROR, "Unable to save printers.conf - %s", strerror(errno));
500 return;
501 }
502 else
503 LogMessage(LOG_INFO, "Saving printers.conf...");
504
505 /*
506 * Write a small header to the file...
507 */
508
509 curtime = time(NULL);
510 curdate = gmtime(&curtime);
511 strftime(temp, sizeof(temp) - 1, "# Written by cupsd on %c\n", curdate);
512
513 fputs("# Class configuration file for " CUPS_SVERSION "\n", fp);
514 fputs(temp, fp);
515
516 /*
517 * Write each local printer known to the system...
518 */
519
520 for (printer = Printers; printer != NULL; printer = printer->next)
521 {
522 /*
523 * Skip remote destinations and printer classes...
524 */
525
526 if ((printer->type & CUPS_PRINTER_REMOTE) ||
527 (printer->type & CUPS_PRINTER_CLASS))
528 continue;
529
530 /*
531 * Write printers as needed...
532 */
533
534 if (printer == DefaultPrinter)
535 fprintf(fp, "<DefaultPrinter %s>\n", printer->name);
536 else
537 fprintf(fp, "<Printer %s>\n", printer->name);
538
539 if (printer->info[0])
540 fprintf(fp, "Info %s\n", printer->info);
541 if (printer->more_info[0])
542 fprintf(fp, "MoreInfo %s\n", printer->more_info);
543 if (printer->location[0])
544 fprintf(fp, "Location %s\n", printer->location);
545 if (printer->device_uri[0])
546 fprintf(fp, "DeviceURI %s\n", printer->device_uri);
547 if (printer->state == IPP_PRINTER_STOPPED)
548 fputs("State Stopped\n", fp);
549 else
550 fputs("State Idle\n", fp);
551
552 fputs("</Printer>\n", fp);
553 }
554
555 fclose(fp);
a9de544f 556}
557
558
f3d580b9 559/*
cbbfcc63 560 * 'SetPrinterAttrs()' - Set printer attributes based upon the PPD file.
f3d580b9 561 */
562
a9de544f 563void
cbbfcc63 564SetPrinterAttrs(printer_t *p) /* I - Printer to setup */
f3d580b9 565{
566 char uri[HTTP_MAX_URI];/* URI for printer */
567 int i; /* Looping var */
568 char filename[1024]; /* Name of PPD file */
569 int num_media; /* Number of media options */
570 ppd_file_t *ppd; /* PPD file data */
571 ppd_option_t *input_slot, /* InputSlot options */
572 *media_type, /* MediaType options */
573 *page_size; /* PageSize options */
574 ipp_attribute_t *attr; /* Attribute data */
575 ipp_value_t *val; /* Attribute value */
576 int nups[3] = /* number-up-supported values */
577 { 1, 2, 4 };
578 ipp_orient_t orients[4] = /* orientation-requested-supported values */
579 {
580 IPP_PORTRAIT,
581 IPP_LANDSCAPE,
582 IPP_REVERSE_LANDSCAPE,
583 IPP_REVERSE_PORTRAIT
584 };
585 char *sides[3] = /* sides-supported values */
586 {
587 "one",
588 "two-long-edge",
589 "two-short-edge"
590 };
591 ipp_op_t ops[] = /* operations-supported values */
592 {
593 IPP_PRINT_JOB,
594 IPP_VALIDATE_JOB,
595 IPP_CANCEL_JOB,
596 IPP_GET_JOB_ATTRIBUTES,
597 IPP_GET_JOBS,
598 IPP_GET_PRINTER_ATTRIBUTES,
599 IPP_PAUSE_PRINTER,
600 IPP_RESUME_PRINTER,
601 IPP_PURGE_JOBS,
602 CUPS_GET_DEFAULT,
603 CUPS_GET_PRINTERS,
604 CUPS_ADD_PRINTER,
605 CUPS_DELETE_PRINTER,
606 CUPS_GET_CLASSES,
607 CUPS_ADD_CLASS,
608 CUPS_DELETE_CLASS,
609 CUPS_ACCEPT_JOBS,
610 CUPS_REJECT_JOBS
611 };
612 char *charsets[] = /* charset-supported values */
613 {
614 "us-ascii",
615 "iso-8859-1",
616 "iso-8859-2",
617 "iso-8859-3",
618 "iso-8859-4",
619 "iso-8859-5",
620 "iso-8859-6",
621 "iso-8859-7",
622 "iso-8859-8",
623 "iso-8859-9",
624 "iso-8859-10",
625 "utf-8"
626 };
d6de4648 627 int num_finishings;
628 ipp_finish_t finishings[5];
f3d580b9 629
630
c7fa9d06 631 /*
632 * Clear out old filters and add a filter from application/vnd.cups-raw to
633 * printer/name to handle "raw" printing by users.
634 */
635
636 DeletePrinterFilters(p);
637 AddPrinterFilter(p, "application/vnd.cups-raw 0 -");
638
f3d580b9 639 /*
640 * Create the required IPP attributes for a printer...
641 */
642
643 if (p->attrs)
644 ippDelete(p->attrs);
645
646 p->attrs = ippNew();
647
cbbfcc63 648 if (p->type & CUPS_PRINTER_CLASS)
649 sprintf(p->uri, "ipp://%s:%d/classes/%s", ServerName,
650 ntohs(Listeners[0].address.sin_port), p->name);
651 else
652 sprintf(p->uri, "ipp://%s:%d/printers/%s", ServerName,
653 ntohs(Listeners[0].address.sin_port), p->name);
f3d580b9 654 ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-uri-supported",
d6de4648 655 NULL, p->uri);
f3d580b9 656 ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
657 "uri-security-supported", NULL, "none");
658 ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME, "printer-name", NULL,
659 p->name);
660 ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location",
661 NULL, p->location);
662 ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info",
663 NULL, p->info);
664 ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-more-info",
665 NULL, p->more_info);
666 ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
667 "pdl-override-supported", NULL, "not-attempted");
668 ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "operations-supported",
42d48bd2 669 sizeof(ops) / sizeof(ops[0]), (int *)ops);
f3d580b9 670 ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_CHARSET, "charset-configured",
671 NULL, DefaultCharset);
672 ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_CHARSET, "charset-supported",
673 sizeof(charsets) / sizeof(charsets[0]), NULL, charsets);
674 ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
675 "natural-language-configured", NULL, DefaultLanguage);
676 ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
677 "generated-natural-language-supported", NULL, DefaultLanguage);
678 ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE,
679 "document-format-default", NULL, "application/octet-stream");
680 ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE,
681 "document-format-supported", NULL, "application/octet-stream");
682 ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
683 "job-priority-supported", 100);
684 ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
685 "job-priority-default", 50);
686 ippAddRange(p->attrs, IPP_TAG_PRINTER, "copies-supported", 1, 100);
687 ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
688 "copies-default", 1);
689 ippAddBoolean(p->attrs, IPP_TAG_PRINTER, "page-ranges-supported", 1);
690 ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
691 "number-up-supported", 3, nups);
692 ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
693 "number-up-default", 1);
694 ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
42d48bd2 695 "orientation-requested-supported", 4, (int *)orients);
f3d580b9 696 ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
697 "orientation-requested-default", IPP_PORTRAIT);
698
699 /*
cbbfcc63 700 * Assign additional attributes depending on whether this is a printer
701 * or class...
f3d580b9 702 */
703
cbbfcc63 704 if (p->type & CUPS_PRINTER_CLASS)
f3d580b9 705 {
706 /*
cbbfcc63 707 * Add class-specific attributes...
f3d580b9 708 */
709
cbbfcc63 710 if (p->num_printers > 0)
711 {
712 /*
713 * Add a list of member URIs and names...
714 */
715
716 attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI,
717 "member-uris", p->num_printers, NULL, NULL);
718
719 for (i = 0; i < p->num_printers; i ++)
720 attr->values[i].string.text = strdup(p->printers[i]->uri);
d6de4648 721
cbbfcc63 722 attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
723 "member-names", p->num_printers, NULL, NULL);
f3d580b9 724
cbbfcc63 725 for (i = 0; i < p->num_printers; i ++)
726 attr->values[i].string.text = strdup(p->printers[i]->name);
727 }
728 }
729 else
730 {
f3d580b9 731 /*
cbbfcc63 732 * Add printer-specific attributes...
f3d580b9 733 */
734
cbbfcc63 735 ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL,
736 p->device_uri);
f3d580b9 737
cbbfcc63 738 /*
739 * Assign additional attributes from the PPD file (if any)...
740 */
f3d580b9 741
cbbfcc63 742 p->type = CUPS_PRINTER_LOCAL + CUPS_PRINTER_BW + CUPS_PRINTER_SMALL;
743 finishings[0] = IPP_FINISH_NONE;
744 num_finishings = 1;
f3d580b9 745
cbbfcc63 746 sprintf(filename, "%s/ppd/%s.ppd", ServerRoot, p->name);
747 if ((ppd = ppdOpenFile(filename)) != NULL)
748 {
749 /*
750 * Add make/model and other various attributes...
751 */
f3d580b9 752
cbbfcc63 753 if (ppd->color_device)
754 p->type += CUPS_PRINTER_COLOR;
755 if (ppd->variable_sizes)
756 p->type += CUPS_PRINTER_VARIABLE;
757 if (!ppd->manual_copies)
758 p->type += CUPS_PRINTER_COPIES;
f3d580b9 759
cbbfcc63 760 ippAddBoolean(p->attrs, IPP_TAG_PRINTER, "color-supported",
761 ppd->color_device);
762 ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
763 "printer-make-and-model", NULL, ppd->nickname);
f3d580b9 764
cbbfcc63 765 /*
766 * Add media options from the PPD file...
767 */
f3d580b9 768
cbbfcc63 769 if ((input_slot = ppdFindOption(ppd, "InputSlot")) != NULL)
770 num_media = input_slot->num_choices;
771 else
772 num_media = 0;
f3d580b9 773
cbbfcc63 774 if ((media_type = ppdFindOption(ppd, "MediaType")) != NULL)
775 num_media += media_type->num_choices;
d6de4648 776
cbbfcc63 777 if ((page_size = ppdFindOption(ppd, "PageSize")) != NULL)
778 num_media += page_size->num_choices;
f3d580b9 779
cbbfcc63 780 attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
781 "media-supported", num_media, NULL, NULL);
782 val = attr->values;
d6de4648 783
cbbfcc63 784 if (input_slot != NULL)
785 for (i = 0; i < input_slot->num_choices; i ++, val ++)
786 val->string.text = strdup(input_slot->choices[i].choice);
d6de4648 787
cbbfcc63 788 if (media_type != NULL)
789 for (i = 0; i < media_type->num_choices; i ++, val ++)
790 val->string.text = strdup(media_type->choices[i].choice);
d6de4648 791
cbbfcc63 792 if (page_size != NULL)
793 for (i = 0; i < page_size->num_choices; i ++, val ++)
794 val->string.text = strdup(page_size->choices[i].choice);
d6de4648 795
cbbfcc63 796 ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
797 NULL, page_size->defchoice);
d6de4648 798
cbbfcc63 799 if (ppdFindOption(ppd, "Duplex") != NULL)
800 {
801 p->type += CUPS_PRINTER_DUPLEX;
d6de4648 802
cbbfcc63 803 ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "sides-supported",
804 3, NULL, sides);
805 ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "sides-default",
806 NULL, "one");
807 }
808
809 if (ppdFindOption(ppd, "Collate") != NULL)
810 p->type += CUPS_PRINTER_COLLATE;
811
812 if (ppdFindOption(ppd, "StapleLocation") != NULL)
813 {
814 p->type += CUPS_PRINTER_STAPLE;
815 finishings[num_finishings++] = IPP_FINISH_STAPLE;
816 }
817
818 if (ppdFindOption(ppd, "BindEdge") != NULL)
819 {
820 p->type += CUPS_PRINTER_BIND;
821 finishings[num_finishings++] = IPP_FINISH_BIND;
822 }
823
824 p->type -= CUPS_PRINTER_SMALL;
825
826 for (i = 0; i < ppd->num_sizes; i ++)
827 if (ppd->sizes[i].length > 1728)
828 p->type += CUPS_PRINTER_LARGE;
829 else if (ppd->sizes[i].length > 1008)
830 p->type += CUPS_PRINTER_MEDIUM;
831 else
832 p->type += CUPS_PRINTER_SMALL;
833
c7fa9d06 834 /*
835 * Add any filters in the PPD file...
836 */
837
838 for (i = 0; i < ppd->num_filters; i ++)
839 AddPrinterFilter(p, ppd->filters[i]);
840
841 if (ppd->num_filters == 0)
842 AddPrinterFilter(p, "application/vnd.cups-postscript 0 -");
843
cbbfcc63 844 ppdClose(ppd);
845 }
5b88701c 846 else if (access(filename, 0) == 0)
847 {
848 LogMessage(LOG_ERROR, "PPD file for %s cannot be loaded!", p->name);
849
850 AddPrinterFilter(p, "application/vnd.cups-postscript 0 -");
851 }
cbbfcc63 852
853 ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
854 "finishings-supported", num_finishings, (int *)finishings);
855 ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
856 "finishings-default", IPP_FINISH_NONE);
857 }
d6de4648 858
c7fa9d06 859 /*
860 * Add the CUPS-specific printer-type attribute...
861 */
862
d6de4648 863 ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-type", p->type);
c7fa9d06 864
865 /*
866 * If we have an interface script, add a filter entry for it...
867 */
868
869 sprintf(filename, "%s/interfaces/%s", ServerRoot, p->name);
870 if (access(filename, X_OK) == 0)
871 {
872 /*
873 * Yes, we have a System V style interface script; use it!
874 */
875
876 sprintf(filename, "*/* 0 %s/interfaces/%s", ServerRoot, p->name);
877 AddPrinterFilter(p, filename);
878 }
879
880 /*
881 * Remote printers go directly to the remote destination...
882 */
883
884 if (p->type & CUPS_PRINTER_REMOTE)
885 AddPrinterFilter(p, "*/* 0 -");
f3d580b9 886}
887
888
889/*
cbbfcc63 890 * 'SetPrinterState()' - Update the current state of a printer.
891 */
892
893void
894SetPrinterState(printer_t *p, /* I - Printer to change */
895 ipp_pstate_t s) /* I - New state */
896{
897 ipp_pstate_t old_state; /* Old printer state */
898
899
900 /*
901 * Set the new state...
902 */
903
904 old_state = p->state;
905 p->state = s;
906 p->state_time = time(NULL);
907
908 if (old_state != s)
909 p->browse_time = 0;
910
911 /*
912 * Save the printer configuration if a printer goes from idle or processing
913 * to stopped (or visa-versa)...
914 */
915
916 if ((old_state == IPP_PRINTER_STOPPED) != (s == IPP_PRINTER_STOPPED))
917 SaveAllPrinters();
918
919 /*
920 * Check to see if any pending jobs can now be printed...
921 */
922
923 CheckJobs();
924}
925
926
927/*
928 * 'StopPrinter()' - Stop a printer from printing any jobs...
929 */
930
931void
932StopPrinter(printer_t *p) /* I - Printer to stop */
933{
934 if (p->job)
935 StopJob(((job_t *)p->job)->id);
936
937 p->state = IPP_PRINTER_STOPPED;
938}
939
940
941/*
8784b6a6 942 * End of "$Id: printers.c,v 1.20 1999/06/18 18:36:49 mike Exp $".
a129ddbd 943 */