]> git.ipfire.org Git - thirdparty/cups.git/blob - systemv/lpadmin.c
Copyright update...
[thirdparty/cups.git] / systemv / lpadmin.c
1 /*
2 * "$Id: lpadmin.c,v 1.28 2002/01/02 17:59:19 mike Exp $"
3 *
4 * "lpadmin" command for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1997-2002 by Easy Software Products.
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
17 * 44141 Airport View Drive, Suite 204
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 *
26 * main() - Parse options and configure the scheduler.
27 * add_printer_to_class() - Add a printer to a class.
28 * default_printer() - Set the default printing destination.
29 * delete_printer() - Delete a printer from the system...
30 * delete_printer_from_class() - Delete a printer from a class.
31 * enable_printer() - Enable a printer...
32 * set_printer_device() - Set the device-uri attribute.
33 * set_printer_file() - Set the interface script or PPD file.
34 * set_printer_info() - Set the printer description string.
35 * set_printer_location() - Set the printer location string.
36 * set_printer_model() - Set the driver model file.
37 * set_printer_options() - Set the printer options.
38 * validate_name() - Make sure the printer name only contains
39 * letters, numbers, and the underscore...
40 */
41
42 /*
43 * Include necessary headers...
44 */
45
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <ctype.h>
49 #include <cups/cups.h>
50 #include <cups/string.h>
51 #include <cups/language.h>
52 #include <cups/debug.h>
53 #include <config.h>
54 #ifdef HAVE_LIBZ
55 # include <zlib.h>
56 #endif /* HAVE_LIBZ */
57
58
59 /*
60 * Local functions...
61 */
62
63 static void add_printer_to_class(http_t *, char *, char *);
64 static void default_printer(http_t *, char *);
65 static void delete_printer(http_t *, char *);
66 static void delete_printer_from_class(http_t *, char *, char *);
67 static void enable_printer(http_t *, char *);
68 static char *get_line(char *, int, FILE *fp);
69 static void set_printer_device(http_t *, char *, char *);
70 static void set_printer_file(http_t *, char *, char *);
71 static void set_printer_info(http_t *, char *, char *);
72 static void set_printer_location(http_t *, char *, char *);
73 static void set_printer_model(http_t *, char *, char *);
74 static void set_printer_options(http_t *, char *, int, cups_option_t *);
75 static int validate_name(const char *);
76
77
78 /*
79 * 'main()' - Parse options and configure the scheduler.
80 */
81
82 int
83 main(int argc, /* I - Number of command-line arguments */
84 char *argv[]) /* I - Command-line arguments */
85 {
86 int i; /* Looping var */
87 http_t *http; /* Connection to server */
88 char *printer, /* Destination printer */
89 *pclass, /* Printer class name */
90 *val; /* Pointer to allow/deny value */
91 int num_options; /* Number of options */
92 cups_option_t *options; /* Options */
93 http_encryption_t encryption; /* Encryption? */
94
95
96 http = NULL;
97 printer = NULL;
98 num_options = 0;
99 options = NULL;
100 encryption = cupsEncryption();
101
102 for (i = 1; i < argc; i ++)
103 if (argv[i][0] == '-')
104 switch (argv[i][1])
105 {
106 case 'c' : /* Add printer to class */
107 if (!http)
108 {
109 http = httpConnectEncrypt(cupsServer(), ippPort(), encryption);
110
111 if (http == NULL)
112 {
113 perror("lpadmin: Unable to connect to server");
114 return (1);
115 }
116 }
117
118 if (printer == NULL)
119 {
120 fputs("lpadmin: Unable to add a printer to the class:\n", stderr);
121 fputs(" You must specify a printer name first!\n", stderr);
122 return (1);
123 }
124
125 if (argv[i][2])
126 pclass = argv[i] + 2;
127 else
128 {
129 i ++;
130
131 if (i >= argc)
132 {
133 fputs("lpadmin: Expected class name after \'-c\' option!\n", stderr);
134 return (1);
135 }
136
137 pclass = argv[i];
138 }
139
140 if (!validate_name(pclass))
141 {
142 fputs("lpadmin: Class name can only contain letters, numbers, and the underscore!\n", stderr);
143 return (1);
144 }
145
146 add_printer_to_class(http, printer, pclass);
147 break;
148
149 case 'd' : /* Set as default destination */
150 if (!http)
151 {
152 http = httpConnectEncrypt(cupsServer(), ippPort(), encryption);
153
154 if (http == NULL)
155 {
156 perror("lpadmin: Unable to connect to server");
157 return (1);
158 }
159 }
160
161 if (argv[i][2])
162 printer = argv[i] + 2;
163 else
164 {
165 i ++;
166
167 if (i >= argc)
168 {
169 fputs("lpadmin: Expected printer name after \'-d\' option!\n", stderr);
170 return (1);
171 }
172
173 printer = argv[i];
174 }
175
176 if (!validate_name(printer))
177 {
178 fputs("lpadmin: Printer name can only contain letters, numbers, and the underscore!\n", stderr);
179 return (1);
180 }
181
182 default_printer(http, printer);
183 i = argc;
184 break;
185
186 case 'h' : /* Connect to host */
187 if (http)
188 httpClose(http);
189
190 if (argv[i][2] != '\0')
191 http = httpConnectEncrypt(argv[i] + 2, ippPort(), encryption);
192 else
193 {
194 i ++;
195
196 if (i >= argc)
197 {
198 fputs("lpadmin: Expected hostname after \'-h\' option!\n", stderr);
199 return (1);
200 }
201 else
202 http = httpConnectEncrypt(argv[i], ippPort(), encryption);
203 }
204
205 if (http == NULL)
206 {
207 perror("lpadmin: Unable to connect to server");
208 return (1);
209 }
210 else
211 cupsSetServer(http->hostname);
212 break;
213
214 case 'i' : /* Use the specified interface script */
215 if (!http)
216 {
217 http = httpConnectEncrypt(cupsServer(), ippPort(), encryption);
218
219 if (http == NULL)
220 {
221 perror("lpadmin: Unable to connect to server");
222 return (1);
223 }
224 }
225
226 if (printer == NULL)
227 {
228 fputs("lpadmin: Unable to set the interface script:\n", stderr);
229 fputs(" You must specify a printer name first!\n", stderr);
230 return (1);
231 }
232
233 if (argv[i][2])
234 set_printer_file(http, printer, argv[i] + 2);
235 else
236 {
237 i ++;
238
239 if (i >= argc)
240 {
241 fputs("lpadmin: Expected interface after \'-i\' option!\n", stderr);
242 return (1);
243 }
244
245 set_printer_file(http, printer, argv[i]);
246 }
247 break;
248
249 case 'E' : /* Enable the printer */
250 if (printer == NULL)
251 {
252 #ifdef HAVE_LIBSSL
253 cupsSetEncryption(encryption = HTTP_ENCRYPT_REQUIRED);
254
255 if (http)
256 httpEncryption(http, encryption);
257 #else
258 fprintf(stderr, "%s: Sorry, no encryption support compiled in!\n",
259 argv[0]);
260 #endif /* HAVE_LIBSSL */
261 break;
262 }
263
264 if (!http)
265 {
266 http = httpConnectEncrypt(cupsServer(), ippPort(), encryption);
267
268 if (http == NULL)
269 {
270 perror("lpadmin: Unable to connect to server");
271 return (1);
272 }
273 }
274
275 enable_printer(http, printer);
276 break;
277
278 case 'm' : /* Use the specified standard script/PPD file */
279 if (!http)
280 {
281 http = httpConnectEncrypt(cupsServer(), ippPort(), encryption);
282
283 if (http == NULL)
284 {
285 perror("lpadmin: Unable to connect to server");
286 return (1);
287 }
288 }
289
290 if (printer == NULL)
291 {
292 fputs("lpadmin: Unable to set the interface script or PPD file:\n", stderr);
293 fputs(" You must specify a printer name first!\n", stderr);
294 return (1);
295 }
296
297 if (argv[i][2])
298 set_printer_model(http, printer, argv[i] + 2);
299 else
300 {
301 i ++;
302
303 if (i >= argc)
304 {
305 fputs("lpadmin: Expected model after \'-m\' option!\n", stderr);
306 return (1);
307 }
308
309 set_printer_model(http, printer, argv[i]);
310 }
311 break;
312
313 case 'o' : /* Set option */
314 if (argv[i][2])
315 num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
316 else
317 {
318 i ++;
319
320 if (i >= argc)
321 {
322 fputs("lpadmin: Expected name=value after \'-o\' option!\n", stderr);
323 return (1);
324 }
325
326 num_options = cupsParseOptions(argv[i], num_options, &options);
327 }
328 break;
329
330 case 'p' : /* Add/modify a printer */
331 if (!http)
332 {
333 http = httpConnectEncrypt(cupsServer(), ippPort(), encryption);
334
335 if (http == NULL)
336 {
337 perror("lpadmin: Unable to connect to server");
338 return (1);
339 }
340 }
341
342 if (argv[i][2])
343 printer = argv[i] + 2;
344 else
345 {
346 i ++;
347
348 if (i >= argc)
349 {
350 fputs("lpadmin: Expected printer after \'-p\' option!\n", stderr);
351 return (1);
352 }
353
354 printer = argv[i];
355 }
356
357 if (!validate_name(printer))
358 {
359 fputs("lpadmin: Printer name can only contain letters, numbers, and the underscore!\n", stderr);
360 return (1);
361 }
362 break;
363
364 case 'r' : /* Remove printer from class */
365 if (!http)
366 {
367 http = httpConnectEncrypt(cupsServer(), ippPort(), encryption);
368
369 if (http == NULL)
370 {
371 perror("lpadmin: Unable to connect to server");
372 return (1);
373 }
374 }
375
376 if (printer == NULL)
377 {
378 fputs("lpadmin: Unable to remove a printer from the class:\n", stderr);
379 fputs(" You must specify a printer name first!\n", stderr);
380 return (1);
381 }
382
383 if (argv[i][2])
384 pclass = argv[i] + 2;
385 else
386 {
387 i ++;
388
389 if (i >= argc)
390 {
391 fputs("lpadmin: Expected class after \'-r\' option!\n", stderr);
392 return (1);
393 }
394
395 pclass = argv[i];
396 }
397
398 if (!validate_name(pclass))
399 {
400 fputs("lpadmin: Class name can only contain letters, numbers, and the underscore!\n", stderr);
401 return (1);
402 }
403
404 delete_printer_from_class(http, printer, pclass);
405 break;
406
407 case 'u' : /* Allow/deny users */
408 if (argv[i][2])
409 val = argv[i] + 2;
410 else
411 {
412 i ++;
413
414 if (i >= argc)
415 {
416 fputs("lpadmin: Expected name=value after \'-o\' option!\n", stderr);
417 return (1);
418 }
419
420 val = argv[i];
421 }
422
423 if (strncasecmp(val, "allow:", 6) == 0)
424 num_options = cupsAddOption("requesting-user-name-allowed",
425 val + 6, num_options, &options);
426 else if (strncasecmp(val, "deny:", 5) == 0)
427 num_options = cupsAddOption("requesting-user-name-denied",
428 val + 5, num_options, &options);
429 else
430 {
431 fprintf(stderr, "lpadmin: Unknown allow/deny option \"%s\"!\n",
432 val);
433 return (1);
434 }
435 break;
436
437 case 'v' : /* Set the device-uri attribute */
438 if (!http)
439 {
440 http = httpConnectEncrypt(cupsServer(), ippPort(), encryption);
441
442 if (http == NULL)
443 {
444 perror("lpadmin: Unable to connect to server");
445 return (1);
446 }
447 }
448
449 if (printer == NULL)
450 {
451 fputs("lpadmin: Unable to set the device URI:\n", stderr);
452 fputs(" You must specify a printer name first!\n", stderr);
453 return (1);
454 }
455
456 if (argv[i][2])
457 set_printer_device(http, printer, argv[i] + 2);
458 else
459 {
460 i ++;
461
462 if (i >= argc)
463 {
464 fputs("lpadmin: Expected device URI after \'-v\' option!\n", stderr);
465 return (1);
466 }
467
468 set_printer_device(http, printer, argv[i]);
469 }
470 break;
471
472 case 'x' : /* Delete a printer */
473 if (!http)
474 {
475 http = httpConnectEncrypt(cupsServer(), ippPort(), encryption);
476
477 if (http == NULL)
478 {
479 perror("lpadmin: Unable to connect to server");
480 return (1);
481 }
482 }
483
484 if (argv[i][2])
485 printer = argv[i] + 2;
486 else
487 {
488 i ++;
489
490 if (i >= argc)
491 {
492 fputs("lpadmin: Expected printer or class after \'-x\' option!\n", stderr);
493 return (1);
494 }
495
496 printer = argv[i];
497 }
498
499 if (!validate_name(printer))
500 {
501 fputs("lpadmin: Printer name can only contain letters, numbers, and the underscore!\n", stderr);
502 return (1);
503 }
504
505 delete_printer(http, printer);
506 i = argc;
507 break;
508
509 case 'D' : /* Set the printer-info attribute */
510 if (!http)
511 {
512 http = httpConnectEncrypt(cupsServer(), ippPort(), encryption);
513
514 if (http == NULL)
515 {
516 perror("lpadmin: Unable to connect to server");
517 return (1);
518 }
519 }
520
521 if (printer == NULL)
522 {
523 fputs("lpadmin: Unable to set the printer description:\n", stderr);
524 fputs(" You must specify a printer name first!\n", stderr);
525 return (1);
526 }
527
528 if (argv[i][2])
529 set_printer_info(http, printer, argv[i] + 2);
530 else
531 {
532 i ++;
533
534 if (i >= argc)
535 {
536 fputs("lpadmin: Expected description after \'-D\' option!\n", stderr);
537 return (1);
538 }
539
540 set_printer_info(http, printer, argv[i]);
541 }
542 break;
543
544 case 'L' : /* Set the printer-location attribute */
545 if (!http)
546 {
547 http = httpConnectEncrypt(cupsServer(), ippPort(), encryption);
548
549 if (http == NULL)
550 {
551 perror("lpadmin: Unable to connect to server");
552 return (1);
553 }
554 }
555
556 if (printer == NULL)
557 {
558 fputs("lpadmin: Unable to set the printer location:\n", stderr);
559 fputs(" You must specify a printer name first!\n", stderr);
560 return (1);
561 }
562
563 if (argv[i][2])
564 set_printer_location(http, printer, argv[i] + 2);
565 else
566 {
567 i ++;
568
569 if (i >= argc)
570 {
571 fputs("lpadmin: Expected location after \'-L\' option!\n", stderr);
572 return (1);
573 }
574
575 set_printer_location(http, printer, argv[i]);
576 }
577 break;
578
579 case 'P' : /* Use the specified PPD file */
580 if (!http)
581 {
582 http = httpConnectEncrypt(cupsServer(), ippPort(), encryption);
583
584 if (http == NULL)
585 {
586 perror("lpadmin: Unable to connect to server");
587 return (1);
588 }
589 }
590
591 if (printer == NULL)
592 {
593 fputs("lpadmin: Unable to set the PPD file:\n", stderr);
594 fputs(" You must specify a printer name first!\n", stderr);
595 return (1);
596 }
597
598 if (argv[i][2])
599 set_printer_file(http, printer, argv[i] + 2);
600 else
601 {
602 i ++;
603
604 if (i >= argc)
605 {
606 fputs("lpadmin: Expected PPD after \'-P\' option!\n", stderr);
607 return (1);
608 }
609
610 set_printer_file(http, printer, argv[i]);
611 }
612 break;
613
614 default :
615 fprintf(stderr, "lpadmin: Unknown option \'%c\'!\n", argv[i][1]);
616 return (1);
617 }
618 else
619 {
620 fprintf(stderr, "lpadmin: Unknown argument \'%s\'!\n", argv[i]);
621 return (1);
622 }
623
624 /*
625 * Set options as needed...
626 */
627
628 if (num_options)
629 {
630 if (!http)
631 {
632 http = httpConnectEncrypt(cupsServer(), ippPort(), encryption);
633
634 if (http == NULL)
635 {
636 perror("lpadmin: Unable to connect to server");
637 return (1);
638 }
639 }
640
641 if (printer == NULL)
642 {
643 fputs("lpadmin: Unable to set the printer options:\n", stderr);
644 fputs(" You must specify a printer name first!\n", stderr);
645 return (1);
646 }
647
648 set_printer_options(http, printer, num_options, options);
649 }
650
651 if (printer == NULL)
652 {
653 puts("Usage:");
654 puts("");
655 puts(" lpadmin [-h server] -d destination");
656 puts(" lpadmin [-h server] -x destination");
657 puts(" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]");
658 puts(" [-r remove-class] [-v device] [-D description]");
659 puts(" [-P ppd-file] [-o name=value]");
660 puts(" [-u allow:user,user] [-u deny:user,user]");
661 puts("");
662 }
663
664 if (http)
665 httpClose(http);
666
667 return (0);
668 }
669
670
671 /*
672 * 'add_printer_to_class()' - Add a printer to a class.
673 */
674
675 static void
676 add_printer_to_class(http_t *http, /* I - Server connection */
677 char *printer, /* I - Printer to add */
678 char *pclass) /* I - Class to add to */
679 {
680 int i; /* Looping var */
681 ipp_t *request, /* IPP Request */
682 *response; /* IPP Response */
683 ipp_attribute_t *attr, /* Current attribute */
684 *members; /* Members in class */
685 cups_lang_t *language; /* Default language */
686 char uri[HTTP_MAX_URI]; /* URI for printer/class */
687
688
689 DEBUG_printf(("add_printer_to_class(%p, \"%s\", \"%s\")\n", http,
690 printer, pclass));
691
692 /*
693 * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
694 * attributes:
695 *
696 * attributes-charset
697 * attributes-natural-language
698 * printer-uri
699 */
700
701 snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s", pclass);
702
703 request = ippNew();
704
705 request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
706 request->request.op.request_id = 1;
707
708 language = cupsLangDefault();
709
710 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
711 "attributes-charset", NULL, cupsLangEncoding(language));
712
713 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
714 "attributes-natural-language", NULL, language->language);
715
716 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
717 "printer-uri", NULL, uri);
718
719 /*
720 * Do the request and get back a response...
721 */
722
723 response = cupsDoRequest(http, request, "/");
724
725 /*
726 * Build a CUPS_ADD_CLASS request, which requires the following
727 * attributes:
728 *
729 * attributes-charset
730 * attributes-natural-language
731 * printer-uri
732 * member-uris
733 */
734
735 request = ippNew();
736
737 request->request.op.operation_id = CUPS_ADD_CLASS;
738 request->request.op.request_id = 1;
739
740 language = cupsLangDefault();
741
742 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
743 "attributes-charset", NULL, cupsLangEncoding(language));
744
745 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
746 "attributes-natural-language", NULL, language->language);
747
748 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
749 "printer-uri", NULL, uri);
750
751 /*
752 * See if the printer is already in the class...
753 */
754
755 if (response != NULL &&
756 (members = ippFindAttribute(response, "member-names", IPP_TAG_NAME)) != NULL)
757 for (i = 0; i < members->num_values; i ++)
758 if (strcasecmp(printer, members->values[i].string.text) == 0)
759 {
760 fprintf(stderr, "lpadmin: Printer %s is already a member of class %s.\n",
761 printer, pclass);
762 ippDelete(request);
763 ippDelete(response);
764 return;
765 }
766
767 /*
768 * OK, the printer isn't part of the class, so add it...
769 */
770
771 snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
772
773 if (response != NULL &&
774 (members = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL)
775 {
776 /*
777 * Add the printer to the existing list...
778 */
779
780 attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI,
781 "member-uris", members->num_values + 1, NULL, NULL);
782 for (i = 0; i < members->num_values; i ++)
783 attr->values[i].string.text = strdup(members->values[i].string.text);
784
785 attr->values[i].string.text = strdup(uri);
786 }
787 else
788 attr = ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris", NULL, uri);
789
790 /*
791 * Then send the request...
792 */
793
794 ippDelete(response);
795
796 if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
797 fprintf(stderr, "lpadmin: add-class failed: %s\n",
798 ippErrorString(cupsLastError()));
799 else
800 {
801 if (response->request.status.status_code > IPP_OK_CONFLICT)
802 fprintf(stderr, "lpadmin: add-class failed: %s\n",
803 ippErrorString(response->request.status.status_code));
804
805 ippDelete(response);
806 }
807 }
808
809
810 /*
811 * 'default_printer()' - Set the default printing destination.
812 */
813
814 static void
815 default_printer(http_t *http, /* I - Server connection */
816 char *printer) /* I - Printer name */
817 {
818 ipp_t *request, /* IPP Request */
819 *response; /* IPP Response */
820 cups_lang_t *language; /* Default language */
821 char uri[HTTP_MAX_URI]; /* URI for printer/class */
822
823
824 DEBUG_printf(("default_printer(%p, \"%s\")\n", http, printer));
825
826 /*
827 * Build a CUPS_SET_DEFAULT request, which requires the following
828 * attributes:
829 *
830 * attributes-charset
831 * attributes-natural-language
832 * printer-uri
833 */
834
835 snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
836
837 request = ippNew();
838
839 request->request.op.operation_id = CUPS_SET_DEFAULT;
840 request->request.op.request_id = 1;
841
842 language = cupsLangDefault();
843
844 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
845 "attributes-charset", NULL, cupsLangEncoding(language));
846
847 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
848 "attributes-natural-language", NULL, language->language);
849
850 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
851 "printer-uri", NULL, uri);
852
853 /*
854 * Do the request and get back a response...
855 */
856
857 if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
858 fprintf(stderr, "lpadmin: set-default failed: %s\n",
859 ippErrorString(cupsLastError()));
860 else
861 {
862 if (response->request.status.status_code > IPP_OK_CONFLICT)
863 fprintf(stderr, "lpadmin: set-default failed: %s\n",
864 ippErrorString(response->request.status.status_code));
865
866 ippDelete(response);
867 }
868 }
869
870
871 /*
872 * 'delete_printer()' - Delete a printer from the system...
873 */
874
875 static void
876 delete_printer(http_t *http, /* I - Server connection */
877 char *printer) /* I - Printer to delete */
878 {
879 ipp_t *request, /* IPP Request */
880 *response; /* IPP Response */
881 cups_lang_t *language; /* Default language */
882 char uri[HTTP_MAX_URI]; /* URI for printer/class */
883
884
885 DEBUG_printf(("delete_printer(%p, \"%s\")\n", http, printer));
886
887 /*
888 * Build a CUPS_DELETE_PRINTER request, which requires the following
889 * attributes:
890 *
891 * attributes-charset
892 * attributes-natural-language
893 * printer-uri
894 */
895
896 snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
897
898 request = ippNew();
899
900 request->request.op.operation_id = CUPS_DELETE_PRINTER;
901 request->request.op.request_id = 1;
902
903 language = cupsLangDefault();
904
905 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
906 "attributes-charset", NULL, cupsLangEncoding(language));
907
908 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
909 "attributes-natural-language", NULL, language->language);
910
911 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
912 "printer-uri", NULL, uri);
913
914 /*
915 * Do the request and get back a response...
916 */
917
918 if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
919 fprintf(stderr, "lpadmin: delete-printer failed: %s\n",
920 ippErrorString(cupsLastError()));
921 else
922 {
923 if (response->request.status.status_code > IPP_OK_CONFLICT)
924 fprintf(stderr, "lpadmin: delete-printer failed: %s\n",
925 ippErrorString(response->request.status.status_code));
926
927 ippDelete(response);
928 }
929 }
930
931
932 /*
933 * 'delete_printer_from_class()' - Delete a printer from a class.
934 */
935
936 static void
937 delete_printer_from_class(http_t *http, /* I - Server connection */
938 char *printer, /* I - Printer to remove */
939 char *pclass) /* I - Class to remove from */
940 {
941 int i, j, k; /* Looping vars */
942 ipp_t *request, /* IPP Request */
943 *response; /* IPP Response */
944 ipp_attribute_t *attr, /* Current attribute */
945 *members; /* Members in class */
946 cups_lang_t *language; /* Default language */
947 char uri[HTTP_MAX_URI]; /* URI for printer/class */
948
949
950 DEBUG_printf(("delete_printer_from_class(%p, \"%s\", \"%s\")\n", http,
951 printer, pclass));
952
953 /*
954 * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
955 * attributes:
956 *
957 * attributes-charset
958 * attributes-natural-language
959 * printer-uri
960 */
961
962 snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s", pclass);
963
964 request = ippNew();
965
966 request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
967 request->request.op.request_id = 1;
968
969 language = cupsLangDefault();
970
971 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
972 "attributes-charset", NULL, cupsLangEncoding(language));
973
974 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
975 "attributes-natural-language", NULL, language->language);
976
977 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
978 "printer-uri", NULL, uri);
979
980 /*
981 * Do the request and get back a response...
982 */
983
984 if ((response = cupsDoRequest(http, request, "/classes/")) == NULL ||
985 response->request.status.status_code == IPP_NOT_FOUND)
986 {
987 ippDelete(response);
988 fprintf(stderr, "lpadmin: Class %s does not exist!\n", pclass);
989 return;
990 }
991
992 /*
993 * See if the printer is already in the class...
994 */
995
996 if ((members = ippFindAttribute(response, "member-names", IPP_TAG_NAME)) == NULL)
997 {
998 ippDelete(response);
999 fputs("lpadmin: No member names were seen!\n", stderr);
1000 return;
1001 }
1002
1003 for (i = 0; i < members->num_values; i ++)
1004 if (strcasecmp(printer, members->values[i].string.text) == 0)
1005 break;
1006
1007 if (i >= members->num_values)
1008 {
1009 fprintf(stderr, "lpadmin: Printer %s is not a member of class %s.\n",
1010 printer, pclass);
1011 ippDelete(response);
1012 return;
1013 }
1014
1015 if (members->num_values == 1)
1016 {
1017 /*
1018 * Build a CUPS_DELETE_CLASS request, which requires the following
1019 * attributes:
1020 *
1021 * attributes-charset
1022 * attributes-natural-language
1023 * printer-uri
1024 */
1025
1026 request = ippNew();
1027
1028 request->request.op.operation_id = CUPS_DELETE_CLASS;
1029 request->request.op.request_id = 1;
1030
1031 language = cupsLangDefault();
1032
1033 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1034 "attributes-charset", NULL, cupsLangEncoding(language));
1035
1036 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1037 "attributes-natural-language", NULL, language->language);
1038
1039 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1040 "printer-uri", NULL, uri);
1041 }
1042 else
1043 {
1044 /*
1045 * Build a CUPS_ADD_CLASS request, which requires the following
1046 * attributes:
1047 *
1048 * attributes-charset
1049 * attributes-natural-language
1050 * printer-uri
1051 * member-uris
1052 */
1053
1054 request = ippNew();
1055
1056 request->request.op.operation_id = CUPS_ADD_CLASS;
1057 request->request.op.request_id = 1;
1058
1059 language = cupsLangDefault();
1060
1061 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1062 "attributes-charset", NULL, cupsLangEncoding(language));
1063
1064 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1065 "attributes-natural-language", NULL, language->language);
1066
1067 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1068 "printer-uri", NULL, uri);
1069
1070 /*
1071 * Delete the printer from the class...
1072 */
1073
1074 members = ippFindAttribute(response, "member-uris", IPP_TAG_URI);
1075 attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI,
1076 "member-uris", members->num_values - 1, NULL, NULL);
1077
1078 for (j = 0, k = 0; j < members->num_values; j ++)
1079 if (j != i)
1080 attr->values[k ++].string.text = strdup(members->values[j].string.text);
1081 }
1082
1083 /*
1084 * Then send the request...
1085 */
1086
1087 ippDelete(response);
1088
1089 if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
1090 fprintf(stderr, "lpadmin: add/delete-class failed: %s\n",
1091 ippErrorString(cupsLastError()));
1092 else
1093 {
1094 if (response->request.status.status_code > IPP_OK_CONFLICT)
1095 fprintf(stderr, "lpadmin: add/delete-class failed: %s\n",
1096 ippErrorString(response->request.status.status_code));
1097
1098 ippDelete(response);
1099 }
1100 }
1101
1102
1103 /*
1104 * 'enable_printer()' - Enable a printer...
1105 */
1106
1107 static void
1108 enable_printer(http_t *http, /* I - Server connection */
1109 char *printer) /* I - Printer to enable */
1110 {
1111 ipp_t *request, /* IPP Request */
1112 *response; /* IPP Response */
1113 cups_lang_t *language; /* Default language */
1114 char uri[HTTP_MAX_URI]; /* URI for printer/class */
1115
1116
1117 DEBUG_printf(("enable_printer(%p, \"%s\")\n", http, printer));
1118
1119 /*
1120 * Build a CUPS_ADD_PRINTER request, which requires the following
1121 * attributes:
1122 *
1123 * attributes-charset
1124 * attributes-natural-language
1125 * printer-uri
1126 * printer-state
1127 * printer-is-accepting-jobs
1128 */
1129
1130 snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
1131
1132 request = ippNew();
1133
1134 request->request.op.operation_id = CUPS_ADD_PRINTER;
1135 request->request.op.request_id = 1;
1136
1137 language = cupsLangDefault();
1138
1139 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1140 "attributes-charset", NULL, cupsLangEncoding(language));
1141
1142 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1143 "attributes-natural-language", NULL, language->language);
1144
1145 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1146 "printer-uri", NULL, uri);
1147
1148 ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
1149 IPP_PRINTER_IDLE);
1150
1151 ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1);
1152
1153 /*
1154 * Do the request and get back a response...
1155 */
1156
1157 if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
1158 fprintf(stderr, "lpadmin: add-printer failed: %s\n",
1159 ippErrorString(cupsLastError()));
1160 else
1161 {
1162 if (response->request.status.status_code > IPP_OK_CONFLICT)
1163 fprintf(stderr, "lpadmin: add-printer failed: %s\n",
1164 ippErrorString(response->request.status.status_code));
1165
1166 ippDelete(response);
1167 }
1168 }
1169
1170
1171 /*
1172 * 'get_line()' - Get a line that is terminated by a LF, CR, or CR LF.
1173 */
1174
1175 static char * /* O - Pointer to buf or NULL on EOF */
1176 get_line(char *buf, /* I - Line buffer */
1177 int length, /* I - Length of buffer */
1178 FILE *fp) /* I - File to read from */
1179 {
1180 char *bufptr; /* Pointer into buffer */
1181 int ch; /* Character from file */
1182
1183
1184 length --;
1185 bufptr = buf;
1186
1187 while ((ch = getc(fp)) != EOF)
1188 {
1189 if (ch == '\n')
1190 break;
1191 else if (ch == '\r')
1192 {
1193 /*
1194 * Look for LF...
1195 */
1196
1197 ch = getc(fp);
1198 if (ch != '\n' && ch != EOF)
1199 ungetc(ch, fp);
1200
1201 break;
1202 }
1203
1204 *bufptr++ = ch;
1205 length --;
1206 if (length == 0)
1207 break;
1208 }
1209
1210 *bufptr = '\0';
1211
1212 if (ch == EOF)
1213 return (NULL);
1214 else
1215 return (buf);
1216 }
1217
1218
1219 /*
1220 * 'set_printer_device()' - Set the device-uri attribute.
1221 */
1222
1223 static void
1224 set_printer_device(http_t *http, /* I - Server connection */
1225 char *printer, /* I - Printer */
1226 char *device) /* I - New device URI */
1227 {
1228 ipp_t *request, /* IPP Request */
1229 *response; /* IPP Response */
1230 cups_lang_t *language; /* Default language */
1231 char uri[HTTP_MAX_URI]; /* URI for printer/class */
1232
1233
1234 DEBUG_printf(("set_printer_device(%p, \"%s\", \"%s\")\n", http, printer,
1235 device));
1236
1237 /*
1238 * Build a CUPS_ADD_PRINTER request, which requires the following
1239 * attributes:
1240 *
1241 * attributes-charset
1242 * attributes-natural-language
1243 * printer-uri
1244 */
1245
1246 snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
1247
1248 request = ippNew();
1249
1250 request->request.op.operation_id = CUPS_ADD_PRINTER;
1251 request->request.op.request_id = 1;
1252
1253 language = cupsLangDefault();
1254
1255 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1256 "attributes-charset", NULL, cupsLangEncoding(language));
1257
1258 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1259 "attributes-natural-language", NULL, language->language);
1260
1261 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1262 "printer-uri", NULL, uri);
1263
1264 /*
1265 * Add the device URI...
1266 */
1267
1268 if (device[0] == '/')
1269 {
1270 /*
1271 * Convert filename to URI...
1272 */
1273
1274 snprintf(uri, sizeof(uri), "file:%s", device);
1275 ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL,
1276 uri);
1277 }
1278 else
1279 ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL,
1280 device);
1281
1282 /*
1283 * Do the request and get back a response...
1284 */
1285
1286 if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
1287 fprintf(stderr, "lpadmin: add-printer failed: %s\n",
1288 ippErrorString(cupsLastError()));
1289 else
1290 {
1291 if (response->request.status.status_code > IPP_OK_CONFLICT)
1292 fprintf(stderr, "lpadmin: add-printer failed: %s\n",
1293 ippErrorString(response->request.status.status_code));
1294
1295 ippDelete(response);
1296 }
1297 }
1298
1299
1300 /*
1301 * 'set_printer_file()' - Set the interface script or PPD file.
1302 */
1303
1304 static void
1305 set_printer_file(http_t *http, /* I - Server connection */
1306 char *printer, /* I - Printer */
1307 char *file) /* I - PPD file or interface script */
1308 {
1309 ipp_t *request, /* IPP Request */
1310 *response; /* IPP Response */
1311 cups_lang_t *language; /* Default language */
1312 char uri[HTTP_MAX_URI]; /* URI for printer/class */
1313 #ifdef HAVE_LIBZ
1314 char tempfile[1024]; /* Temporary filename */
1315 int fd; /* Temporary file */
1316 gzFile *gz; /* GZIP'd file */
1317 char buffer[8192]; /* Copy buffer */
1318 int bytes; /* Bytes in buffer */
1319
1320
1321 DEBUG_printf(("set_printer_file(%p, \"%s\", \"%s\")\n", http, printer,
1322 file));
1323
1324 /*
1325 * See if the file is gzip'd; if so, unzip it to a temporary file and
1326 * send the uncompressed file.
1327 */
1328
1329 if (strcmp(file + strlen(file) - 3, ".gz") == 0)
1330 {
1331 /*
1332 * Yes, the file is compressed; uncompress to a temp file...
1333 */
1334
1335 if ((fd = cupsTempFd(tempfile, sizeof(tempfile))) < 0)
1336 {
1337 perror("lpadmin: Unable to create temporary file");
1338 return;
1339 }
1340
1341 if ((gz = gzopen(file, "rb")) == NULL)
1342 {
1343 perror("lpadmin: Unable to open file");
1344 close(fd);
1345 unlink(tempfile);
1346 return;
1347 }
1348
1349 while ((bytes = gzread(gz, buffer, sizeof(buffer))) > 0)
1350 write(fd, buffer, bytes);
1351
1352 close(fd);
1353 gzclose(gz);
1354
1355 file = tempfile;
1356 }
1357 #endif /* HAVE_LIBZ */
1358
1359 /*
1360 * Build a CUPS_ADD_PRINTER request, which requires the following
1361 * attributes:
1362 *
1363 * attributes-charset
1364 * attributes-natural-language
1365 * printer-uri
1366 */
1367
1368 snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
1369
1370 request = ippNew();
1371
1372 request->request.op.operation_id = CUPS_ADD_PRINTER;
1373 request->request.op.request_id = 1;
1374
1375 language = cupsLangDefault();
1376
1377 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1378 "attributes-charset", NULL, cupsLangEncoding(language));
1379
1380 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1381 "attributes-natural-language", NULL, language->language);
1382
1383 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1384 "printer-uri", NULL, uri);
1385
1386 /*
1387 * Do the request and get back a response...
1388 */
1389
1390 if ((response = cupsDoFileRequest(http, request, "/admin/", file)) == NULL)
1391 fprintf(stderr, "lpadmin: add-printer failed: %s\n",
1392 ippErrorString(cupsLastError()));
1393 else
1394 {
1395 if (response->request.status.status_code > IPP_OK_CONFLICT)
1396 fprintf(stderr, "lpadmin: add-printer failed: %s\n",
1397 ippErrorString(response->request.status.status_code));
1398
1399 ippDelete(response);
1400 }
1401
1402 #ifdef HAVE_LIBZ
1403 /*
1404 * Remove the temporary file as needed...
1405 */
1406
1407 if (file == tempfile)
1408 unlink(tempfile);
1409 #endif /* HAVE_LIBZ */
1410 }
1411
1412
1413 /*
1414 * 'set_printer_info()' - Set the printer description string.
1415 */
1416
1417 static void
1418 set_printer_info(http_t *http, /* I - Server connection */
1419 char *printer, /* I - Printer */
1420 char *info) /* I - New description string */
1421 {
1422 ipp_t *request, /* IPP Request */
1423 *response; /* IPP Response */
1424 cups_lang_t *language; /* Default language */
1425 char uri[HTTP_MAX_URI]; /* URI for printer/class */
1426
1427
1428 DEBUG_printf(("set_printer_info(%p, \"%s\", \"%s\")\n", http, printer,
1429 info));
1430
1431 /*
1432 * Build a CUPS_ADD_PRINTER request, which requires the following
1433 * attributes:
1434 *
1435 * attributes-charset
1436 * attributes-natural-language
1437 * printer-uri
1438 */
1439
1440 snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
1441
1442 request = ippNew();
1443
1444 request->request.op.operation_id = CUPS_ADD_PRINTER;
1445 request->request.op.request_id = 1;
1446
1447 language = cupsLangDefault();
1448
1449 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1450 "attributes-charset", NULL, cupsLangEncoding(language));
1451
1452 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1453 "attributes-natural-language", NULL, language->language);
1454
1455 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1456 "printer-uri", NULL, uri);
1457
1458 /*
1459 * Add the info string...
1460 */
1461
1462 ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info", NULL,
1463 info);
1464
1465 /*
1466 * Do the request and get back a response...
1467 */
1468
1469 if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
1470 fprintf(stderr, "lpadmin: add-printer failed: %s\n",
1471 ippErrorString(cupsLastError()));
1472 else
1473 {
1474 if (response->request.status.status_code > IPP_OK_CONFLICT)
1475 fprintf(stderr, "lpadmin: add-printer failed: %s\n",
1476 ippErrorString(response->request.status.status_code));
1477
1478 ippDelete(response);
1479 }
1480 }
1481
1482
1483 /*
1484 * 'set_printer_location()' - Set the printer location string.
1485 */
1486
1487 static void
1488 set_printer_location(http_t *http, /* I - Server connection */
1489 char *printer, /* I - Printer */
1490 char *location) /* I - New location string */
1491 {
1492 ipp_t *request, /* IPP Request */
1493 *response; /* IPP Response */
1494 cups_lang_t *language; /* Default language */
1495 char uri[HTTP_MAX_URI]; /* URI for printer/class */
1496
1497
1498 DEBUG_printf(("set_printer_location(%p, \"%s\", \"%s\")\n", http, printer,
1499 location));
1500
1501 /*
1502 * Build a CUPS_ADD_PRINTER request, which requires the following
1503 * attributes:
1504 *
1505 * attributes-charset
1506 * attributes-natural-language
1507 * printer-uri
1508 */
1509
1510 snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
1511
1512 request = ippNew();
1513
1514 request->request.op.operation_id = CUPS_ADD_PRINTER;
1515 request->request.op.request_id = 1;
1516
1517 language = cupsLangDefault();
1518
1519 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1520 "attributes-charset", NULL, cupsLangEncoding(language));
1521
1522 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1523 "attributes-natural-language", NULL, language->language);
1524
1525 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1526 "printer-uri", NULL, uri);
1527
1528 /*
1529 * Add the location string...
1530 */
1531
1532 ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location", NULL,
1533 location);
1534
1535 /*
1536 * Do the request and get back a response...
1537 */
1538
1539 if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
1540 fprintf(stderr, "lpadmin: add-printer failed: %s\n",
1541 ippErrorString(cupsLastError()));
1542 else
1543 {
1544 if (response->request.status.status_code > IPP_OK_CONFLICT)
1545 fprintf(stderr, "lpadmin: add-printer failed: %s\n",
1546 ippErrorString(response->request.status.status_code));
1547
1548 ippDelete(response);
1549 }
1550 }
1551
1552
1553 /*
1554 * 'set_printer_model()' - Set the driver model file.
1555 */
1556
1557 static void
1558 set_printer_model(http_t *http, /* I - Server connection */
1559 char *printer, /* I - Printer */
1560 char *model) /* I - Driver model file */
1561 {
1562 ipp_t *request, /* IPP Request */
1563 *response; /* IPP Response */
1564 cups_lang_t *language; /* Default language */
1565 char uri[HTTP_MAX_URI]; /* URI for printer/class */
1566
1567
1568 /*
1569 * Build a CUPS_ADD_PRINTER request, which requires the following
1570 * attributes:
1571 *
1572 * attributes-charset
1573 * attributes-natural-language
1574 * printer-uri
1575 * ppd-name
1576 */
1577
1578 snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
1579
1580 request = ippNew();
1581
1582 request->request.op.operation_id = CUPS_ADD_PRINTER;
1583 request->request.op.request_id = 1;
1584
1585 language = cupsLangDefault();
1586
1587 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1588 "attributes-charset", NULL, cupsLangEncoding(language));
1589
1590 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1591 "attributes-natural-language", NULL, language->language);
1592
1593 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1594 "printer-uri", NULL, uri);
1595
1596 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
1597 "ppd-name", NULL, model);
1598
1599 /*
1600 * Do the request and get back a response...
1601 */
1602
1603 if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
1604 fprintf(stderr, "lpadmin: add-printer failed: %s\n",
1605 ippErrorString(cupsLastError()));
1606 else
1607 {
1608 if (response->request.status.status_code > IPP_OK_CONFLICT)
1609 fprintf(stderr, "lpadmin: add-printer failed: %s\n",
1610 ippErrorString(response->request.status.status_code));
1611
1612 ippDelete(response);
1613 }
1614 }
1615
1616
1617 /*
1618 * 'set_printer_options()' - Set the printer options.
1619 */
1620
1621 static void
1622 set_printer_options(http_t *http, /* I - Server connection */
1623 char *printer, /* I - Printer */
1624 int num_options, /* I - Number of options */
1625 cups_option_t *options) /* I - Options */
1626 {
1627 ipp_t *request, /* IPP Request */
1628 *response; /* IPP Response */
1629 ipp_attribute_t *attr; /* IPP attribute */
1630 cups_lang_t *language; /* Default language */
1631 ipp_op_t op; /* Operation to perform */
1632 const char *val, /* Option value */
1633 *ppdfile; /* PPD filename */
1634 char uri[HTTP_MAX_URI], /* URI for printer/class */
1635 line[1024], /* Line from PPD file */
1636 keyword[1024], /* Keyword from Default line */
1637 *keyptr, /* Pointer into keyword... */
1638 tempfile[1024]; /* Temporary filename */
1639 FILE *in, /* PPD file */
1640 *out; /* Temporary file */
1641 int outfd; /* Temporary file descriptor */
1642
1643
1644 DEBUG_printf(("set_printer_options(%p, \"%s\", %d, %p)\n", http, printer,
1645 num_options, options));
1646
1647 language = cupsLangDefault();
1648
1649 snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
1650
1651 /*
1652 * Build a GET_PRINTER_ATTRIBUTES request, which requires the following
1653 * attributes:
1654 *
1655 * attributes-charset
1656 * attributes-natural-language
1657 * printer-uri
1658 * requested-attributes
1659 */
1660
1661 request = ippNew();
1662
1663 request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
1664 request->request.op.request_id = 1;
1665
1666 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1667 "attributes-charset", NULL, cupsLangEncoding(language));
1668
1669 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1670 "attributes-natural-language", NULL, language->language);
1671
1672 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1673 "printer-uri", NULL, uri);
1674
1675 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
1676 "requested-attributes", NULL, "printer-type");
1677
1678 /*
1679 * Do the request...
1680 */
1681
1682 op = CUPS_ADD_PRINTER;
1683
1684 if ((response = cupsDoRequest(http, request, "/")) != NULL)
1685 {
1686 /*
1687 * See what kind of printer or class it is...
1688 */
1689
1690 if ((attr = ippFindAttribute(response, "printer-type", IPP_TAG_ENUM)) != NULL)
1691 {
1692 if (attr->values[0].integer & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT))
1693 op = CUPS_ADD_CLASS;
1694 }
1695
1696 ippDelete(response);
1697 }
1698
1699 /*
1700 * Build a CUPS_ADD_PRINTER or CUPS_ADD_CLASS request, which requires
1701 * the following attributes:
1702 *
1703 * attributes-charset
1704 * attributes-natural-language
1705 * printer-uri
1706 * other options
1707 */
1708
1709 request = ippNew();
1710
1711 request->request.op.operation_id = op;
1712 request->request.op.request_id = 1;
1713
1714 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1715 "attributes-charset", NULL, cupsLangEncoding(language));
1716
1717 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1718 "attributes-natural-language", NULL, language->language);
1719
1720 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1721 "printer-uri", NULL, uri);
1722
1723 /*
1724 * Add the options...
1725 */
1726
1727 cupsEncodeOptions(request, num_options, options);
1728
1729 if (op == CUPS_ADD_PRINTER)
1730 ppdfile = cupsGetPPD(printer);
1731 else
1732 ppdfile = NULL;
1733
1734 if (ppdfile != NULL)
1735 {
1736 /*
1737 * Set default options in the PPD file...
1738 */
1739
1740 outfd = cupsTempFd(tempfile, sizeof(tempfile));
1741
1742 in = fopen(ppdfile, "rb");
1743 out = fdopen(outfd, "wb");
1744
1745 while (get_line(line, sizeof(line), in) != NULL)
1746 {
1747 if (strncmp(line, "*Default", 8) != 0)
1748 fprintf(out, "%s\n", line);
1749 else
1750 {
1751 /*
1752 * Get default option name...
1753 */
1754
1755 strncpy(keyword, line + 8, sizeof(keyword) - 1);
1756 keyword[sizeof(keyword) - 1] = '\0';
1757
1758 for (keyptr = keyword; *keyptr; keyptr ++)
1759 if (*keyptr == ':' || isspace(*keyptr))
1760 break;
1761
1762 *keyptr = '\0';
1763
1764 if (strcmp(keyword, "PageRegion") == 0)
1765 val = cupsGetOption("PageSize", num_options, options);
1766 else
1767 val = cupsGetOption(keyword, num_options, options);
1768
1769 if (val != NULL)
1770 fprintf(out, "*Default%s: %s\n", keyword, val);
1771 else
1772 fprintf(out, "%s\n", line);
1773 }
1774 }
1775
1776 fclose(in);
1777 fclose(out);
1778 close(outfd);
1779
1780 /*
1781 * Do the request...
1782 */
1783
1784 response = cupsDoFileRequest(http, request, "/admin/", tempfile);
1785
1786 /*
1787 * Clean up temp files... (TODO: catch signals in case we CTRL-C during
1788 * lpadmin)
1789 */
1790
1791 unlink(ppdfile);
1792 unlink(tempfile);
1793 }
1794 else
1795 {
1796 /*
1797 * No PPD file - just set the options...
1798 */
1799
1800 response = cupsDoRequest(http, request, "/admin/");
1801 }
1802
1803 /*
1804 * Check the response...
1805 */
1806
1807 if (response == NULL)
1808 fprintf(stderr, "lpadmin: %s failed: %s\n",
1809 op == CUPS_ADD_PRINTER ? "add-printer" : "add-class",
1810 ippErrorString(cupsLastError()));
1811 else
1812 {
1813 if (response->request.status.status_code > IPP_OK_CONFLICT)
1814 fprintf(stderr, "lpadmin: %s failed: %s\n",
1815 op == CUPS_ADD_PRINTER ? "add-printer" : "add-class",
1816 ippErrorString(response->request.status.status_code));
1817
1818 ippDelete(response);
1819 }
1820 }
1821
1822
1823 /*
1824 * 'validate_name()' - Make sure the printer name only contains letters,
1825 * numbers, and the underscore...
1826 */
1827
1828 static int /* O - 0 if name is no good, 1 if name is good */
1829 validate_name(const char *name) /* I - Name to check */
1830 {
1831 /*
1832 * Don't allow names to start with a digit...
1833 */
1834
1835 if (isdigit(*name))
1836 return (0);
1837
1838 /*
1839 * Scan the whole name...
1840 */
1841
1842 while (*name)
1843 if (*name == '@')
1844 return (1);
1845 else if (!isalnum(*name) && *name != '_')
1846 return (0);
1847 else
1848 name ++;
1849
1850 return (1);
1851 }
1852
1853
1854 /*
1855 * End of "$Id: lpadmin.c,v 1.28 2002/01/02 17:59:19 mike Exp $".
1856 */