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