]> git.ipfire.org Git - thirdparty/cups.git/blame - systemv/lpadmin.c
Full sweep of all Clang warnings, plus some bug fixes for incorrect memcpy usage.
[thirdparty/cups.git] / systemv / lpadmin.c
CommitLineData
ef416fc2 1/*
f2d18633 2 * "$Id$"
ef416fc2 3 *
7e86f2f6 4 * "lpadmin" command for CUPS.
ef416fc2 5 *
7e86f2f6
MS
6 * Copyright 2007-2014 by Apple Inc.
7 * Copyright 1997-2006 by Easy Software Products.
ef416fc2 8 *
7e86f2f6
MS
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
ef416fc2 14 */
15
16/*
17 * Include necessary headers...
18 */
19
71e16022 20#include <cups/cups-private.h>
ef416fc2 21
22
23/*
24 * Local functions...
25 */
26
eac3a0a0
MS
27static int add_printer_to_class(http_t *http, char *printer, char *pclass);
28static int default_printer(http_t *http, char *printer);
29static int delete_printer(http_t *http, char *printer);
30static int delete_printer_from_class(http_t *http, char *printer,
31 char *pclass);
32static int delete_printer_option(http_t *http, char *printer,
33 char *option);
34static int enable_printer(http_t *http, char *printer);
35static cups_ptype_t get_printer_type(http_t *http, char *printer, char *uri,
36 size_t urisize);
37static int set_printer_options(http_t *http, char *printer,
38 int num_options, cups_option_t *options,
39 char *file);
40static int validate_name(const char *name);
ef416fc2 41
42
43/*
44 * 'main()' - Parse options and configure the scheduler.
45 */
46
47int
48main(int argc, /* I - Number of command-line arguments */
49 char *argv[]) /* I - Command-line arguments */
50{
51 int i; /* Looping var */
52 http_t *http; /* Connection to server */
53 char *printer, /* Destination printer */
54 *pclass, /* Printer class name */
55 *val; /* Pointer to allow/deny value */
56 int num_options; /* Number of options */
57 cups_option_t *options; /* Options */
7cf5915e 58 char *file; /* New PPD file/interface script */
ef416fc2 59
60
07725fee 61 _cupsSetLocale(argv);
d09495fa 62
ef416fc2 63 http = NULL;
64 printer = NULL;
65 num_options = 0;
66 options = NULL;
7cf5915e 67 file = NULL;
ef416fc2 68
69 for (i = 1; i < argc; i ++)
70 if (argv[i][0] == '-')
71 switch (argv[i][1])
72 {
73 case 'c' : /* Add printer to class */
74 if (!http)
75 {
76 http = httpConnectEncrypt(cupsServer(), ippPort(),
77 cupsEncryption());
78
79 if (http == NULL)
80 {
fa73b229 81 _cupsLangPrintf(stderr,
0837b7e8 82 _("lpadmin: Unable to connect to server: %s"),
ef416fc2 83 strerror(errno));
84 return (1);
85 }
86 }
87
88 if (printer == NULL)
89 {
fa73b229 90 _cupsLangPuts(stderr,
ef416fc2 91 _("lpadmin: Unable to add a printer to the class:\n"
92 " You must specify a printer name "
0837b7e8 93 "first."));
ef416fc2 94 return (1);
95 }
96
97 if (argv[i][2])
98 pclass = argv[i] + 2;
99 else
100 {
101 i ++;
102
103 if (i >= argc)
104 {
fa73b229 105 _cupsLangPuts(stderr,
0837b7e8
MS
106 _("lpadmin: Expected class name after \"-c\" "
107 "option."));
ef416fc2 108 return (1);
109 }
110
111 pclass = argv[i];
112 }
113
114 if (!validate_name(pclass))
115 {
fa73b229 116 _cupsLangPuts(stderr,
ef416fc2 117 _("lpadmin: Class name can only contain printable "
0837b7e8 118 "characters."));
ef416fc2 119 return (1);
120 }
121
122 if (add_printer_to_class(http, printer, pclass))
123 return (1);
124 break;
125
126 case 'd' : /* Set as default destination */
127 if (!http)
128 {
129 http = httpConnectEncrypt(cupsServer(), ippPort(),
130 cupsEncryption());
131
132 if (http == NULL)
133 {
fa73b229 134 _cupsLangPrintf(stderr,
0837b7e8 135 _("lpadmin: Unable to connect to server: %s"),
ef416fc2 136 strerror(errno));
137 return (1);
138 }
139 }
140
141 if (argv[i][2])
142 printer = argv[i] + 2;
143 else
144 {
145 i ++;
146
147 if (i >= argc)
148 {
fa73b229 149 _cupsLangPuts(stderr,
0837b7e8
MS
150 _("lpadmin: Expected printer name after \"-d\" "
151 "option."));
ef416fc2 152 return (1);
153 }
154
155 printer = argv[i];
156 }
157
158 if (!validate_name(printer))
159 {
fa73b229 160 _cupsLangPuts(stderr,
ef416fc2 161 _("lpadmin: Printer name can only contain "
0837b7e8 162 "printable characters."));
ef416fc2 163 return (1);
164 }
165
166 if (default_printer(http, printer))
167 return (1);
168
169 i = argc;
170 break;
171
172 case 'h' : /* Connect to host */
173 if (http)
174 {
175 httpClose(http);
176 http = NULL;
177 }
178
179 if (argv[i][2] != '\0')
180 cupsSetServer(argv[i] + 2);
181 else
182 {
183 i ++;
184
185 if (i >= argc)
186 {
fa73b229 187 _cupsLangPuts(stderr,
0837b7e8
MS
188 _("lpadmin: Expected hostname after \"-h\" "
189 "option."));
ef416fc2 190 return (1);
191 }
192
193 cupsSetServer(argv[i]);
194 }
195 break;
196
197 case 'i' : /* Use the specified interface script */
ef416fc2 198 if (argv[i][2])
7cf5915e 199 file = argv[i] + 2;
ef416fc2 200 else
201 {
202 i ++;
203
204 if (i >= argc)
205 {
fa73b229 206 _cupsLangPuts(stderr,
0837b7e8
MS
207 _("lpadmin: Expected interface after \"-i\" "
208 "option."));
ef416fc2 209 return (1);
210 }
211
7cf5915e 212 file = argv[i];
ef416fc2 213 }
214 break;
215
216 case 'E' : /* Enable the printer */
217 if (printer == NULL)
218 {
219#ifdef HAVE_SSL
220 cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
221
222 if (http)
223 httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
224#else
0837b7e8 225 _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."),
ef416fc2 226 argv[0]);
227#endif /* HAVE_SSL */
228 break;
229 }
230
231 if (!http)
232 {
233 http = httpConnectEncrypt(cupsServer(), ippPort(),
234 cupsEncryption());
235
236 if (http == NULL)
237 {
fa73b229 238 _cupsLangPrintf(stderr,
0837b7e8 239 _("lpadmin: Unable to connect to server: %s"),
ef416fc2 240 strerror(errno));
241 return (1);
242 }
243 }
244
245 if (enable_printer(http, printer))
246 return (1);
247 break;
248
249 case 'm' : /* Use the specified standard script/PPD file */
ef416fc2 250 if (argv[i][2])
7cf5915e
MS
251 num_options = cupsAddOption("ppd-name", argv[i] + 2, num_options,
252 &options);
ef416fc2 253 else
254 {
255 i ++;
256
257 if (i >= argc)
258 {
fa73b229 259 _cupsLangPuts(stderr,
0837b7e8
MS
260 _("lpadmin: Expected model after \"-m\" "
261 "option."));
ef416fc2 262 return (1);
263 }
264
7cf5915e
MS
265 num_options = cupsAddOption("ppd-name", argv[i], num_options,
266 &options);
ef416fc2 267 }
268 break;
269
270 case 'o' : /* Set option */
271 if (argv[i][2])
272 num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
273 else
274 {
275 i ++;
276
277 if (i >= argc)
278 {
fa73b229 279 _cupsLangPuts(stderr,
0837b7e8
MS
280 _("lpadmin: Expected name=value after \"-o\" "
281 "option."));
ef416fc2 282 return (1);
283 }
284
285 num_options = cupsParseOptions(argv[i], num_options, &options);
286 }
287 break;
288
289 case 'p' : /* Add/modify a printer */
ef416fc2 290 if (argv[i][2])
291 printer = argv[i] + 2;
292 else
293 {
294 i ++;
295
296 if (i >= argc)
297 {
fa73b229 298 _cupsLangPuts(stderr,
0837b7e8
MS
299 _("lpadmin: Expected printer after \"-p\" "
300 "option."));
ef416fc2 301 return (1);
302 }
303
304 printer = argv[i];
305 }
306
307 if (!validate_name(printer))
308 {
fa73b229 309 _cupsLangPuts(stderr,
ef416fc2 310 _("lpadmin: Printer name can only contain "
0837b7e8 311 "printable characters."));
ef416fc2 312 return (1);
313 }
314 break;
315
316 case 'r' : /* Remove printer from class */
317 if (!http)
318 {
319 http = httpConnectEncrypt(cupsServer(), ippPort(),
320 cupsEncryption());
321
322 if (http == NULL)
323 {
fa73b229 324 _cupsLangPrintf(stderr,
0837b7e8 325 _("lpadmin: Unable to connect to server: %s"),
ef416fc2 326 strerror(errno));
327 return (1);
328 }
329 }
330
331 if (printer == NULL)
332 {
fa73b229 333 _cupsLangPuts(stderr,
ef416fc2 334 _("lpadmin: Unable to remove a printer from the "
335 "class:\n"
336 " You must specify a printer name "
0837b7e8 337 "first."));
ef416fc2 338 return (1);
339 }
340
341 if (argv[i][2])
342 pclass = argv[i] + 2;
343 else
344 {
345 i ++;
346
347 if (i >= argc)
348 {
fa73b229 349 _cupsLangPuts(stderr,
0837b7e8
MS
350 _("lpadmin: Expected class after \"-r\" "
351 "option."));
ef416fc2 352 return (1);
353 }
354
355 pclass = argv[i];
356 }
357
358 if (!validate_name(pclass))
359 {
fa73b229 360 _cupsLangPuts(stderr,
ef416fc2 361 _("lpadmin: Class name can only contain printable "
0837b7e8 362 "characters."));
ef416fc2 363 return (1);
364 }
365
366 if (delete_printer_from_class(http, printer, pclass))
367 return (1);
368 break;
369
eac3a0a0
MS
370 case 'R' : /* Remove option */
371 if (!http)
372 {
373 http = httpConnectEncrypt(cupsServer(), ippPort(),
374 cupsEncryption());
375
376 if (http == NULL)
377 {
378 _cupsLangPrintf(stderr,
379 _("lpadmin: Unable to connect to server: %s"),
380 strerror(errno));
381 return (1);
382 }
383 }
384
385 if (printer == NULL)
386 {
387 _cupsLangPuts(stderr,
388 _("lpadmin: Unable to delete option:\n"
389 " You must specify a printer name "
390 "first."));
391 return (1);
392 }
393
394 if (argv[i][2])
395 val = argv[i] + 2;
396 else
397 {
398 i ++;
399
400 if (i >= argc)
401 {
402 _cupsLangPuts(stderr,
403 _("lpadmin: Expected name after \"-R\" "
404 "option."));
405 return (1);
406 }
407
408 val = argv[i];
409 }
410
411 if (delete_printer_option(http, printer, val))
412 return (1);
413 break;
414
f301802f 415 case 'U' : /* Username */
416 if (argv[i][2] != '\0')
417 cupsSetUser(argv[i] + 2);
418 else
419 {
420 i ++;
421 if (i >= argc)
422 {
423 _cupsLangPrintf(stderr,
424 _("%s: Error - expected username after "
0837b7e8 425 "\"-U\" option."), argv[0]);
f301802f 426 return (1);
427 }
428
429 cupsSetUser(argv[i]);
430 }
431 break;
88f9aafc 432
ef416fc2 433 case 'u' : /* Allow/deny users */
434 if (argv[i][2])
435 val = argv[i] + 2;
436 else
437 {
438 i ++;
439
440 if (i >= argc)
441 {
fa73b229 442 _cupsLangPuts(stderr,
ef416fc2 443 _("lpadmin: Expected allow/deny:userlist after "
0837b7e8 444 "\"-u\" option."));
ef416fc2 445 return (1);
446 }
447
448 val = argv[i];
449 }
450
88f9aafc 451 if (!_cups_strncasecmp(val, "allow:", 6))
ef416fc2 452 num_options = cupsAddOption("requesting-user-name-allowed",
453 val + 6, num_options, &options);
88f9aafc 454 else if (!_cups_strncasecmp(val, "deny:", 5))
ef416fc2 455 num_options = cupsAddOption("requesting-user-name-denied",
456 val + 5, num_options, &options);
457 else
458 {
fa73b229 459 _cupsLangPrintf(stderr,
0837b7e8 460 _("lpadmin: Unknown allow/deny option \"%s\"."),
ef416fc2 461 val);
462 return (1);
463 }
464 break;
465
466 case 'v' : /* Set the device-uri attribute */
ef416fc2 467 if (argv[i][2])
7cf5915e
MS
468 num_options = cupsAddOption("device-uri", argv[i] + 2,
469 num_options, &options);
ef416fc2 470 else
471 {
472 i ++;
473
474 if (i >= argc)
475 {
fa73b229 476 _cupsLangPuts(stderr,
0837b7e8
MS
477 _("lpadmin: Expected device URI after \"-v\" "
478 "option."));
ef416fc2 479 return (1);
480 }
481
7cf5915e
MS
482 num_options = cupsAddOption("device-uri", argv[i],
483 num_options, &options);
ef416fc2 484 }
485 break;
486
487 case 'x' : /* Delete a printer */
488 if (!http)
489 {
490 http = httpConnectEncrypt(cupsServer(), ippPort(),
491 cupsEncryption());
492
493 if (http == NULL)
494 {
fa73b229 495 _cupsLangPrintf(stderr,
0837b7e8 496 _("lpadmin: Unable to connect to server: %s"),
ef416fc2 497 strerror(errno));
498 return (1);
499 }
500 }
501
502 if (argv[i][2])
503 printer = argv[i] + 2;
504 else
505 {
506 i ++;
507
508 if (i >= argc)
509 {
fa73b229 510 _cupsLangPuts(stderr,
ef416fc2 511 _("lpadmin: Expected printer or class after "
0837b7e8 512 "\"-x\" option."));
ef416fc2 513 return (1);
514 }
515
516 printer = argv[i];
517 }
518
519 if (!validate_name(printer))
520 {
fa73b229 521 _cupsLangPuts(stderr,
ef416fc2 522 _("lpadmin: Printer name can only contain "
0837b7e8 523 "printable characters."));
ef416fc2 524 return (1);
525 }
526
527 if (delete_printer(http, printer))
528 return (1);
529
530 i = argc;
531 break;
532
533 case 'D' : /* Set the printer-info attribute */
ef416fc2 534 if (argv[i][2])
7cf5915e
MS
535 num_options = cupsAddOption("printer-info", argv[i] + 2,
536 num_options, &options);
ef416fc2 537 else
538 {
539 i ++;
540
541 if (i >= argc)
542 {
fa73b229 543 _cupsLangPuts(stderr,
ef416fc2 544 _("lpadmin: Expected description after "
0837b7e8 545 "\"-D\" option."));
ef416fc2 546 return (1);
547 }
548
7cf5915e
MS
549 num_options = cupsAddOption("printer-info", argv[i],
550 num_options, &options);
ef416fc2 551 }
552 break;
553
554 case 'I' : /* Set the supported file types (ignored) */
555 i ++;
556
557 if (i >= argc)
558 {
fa73b229 559 _cupsLangPuts(stderr,
0837b7e8
MS
560 _("lpadmin: Expected file type(s) after \"-I\" "
561 "option."));
ef416fc2 562 return (1);
563 }
564
fa73b229 565 _cupsLangPuts(stderr,
0837b7e8 566 _("lpadmin: Warning - content type list ignored."));
ef416fc2 567 break;
88f9aafc 568
ef416fc2 569 case 'L' : /* Set the printer-location attribute */
ef416fc2 570 if (argv[i][2])
7cf5915e
MS
571 num_options = cupsAddOption("printer-location", argv[i] + 2,
572 num_options, &options);
ef416fc2 573 else
574 {
575 i ++;
576
577 if (i >= argc)
578 {
fa73b229 579 _cupsLangPuts(stderr,
0837b7e8
MS
580 _("lpadmin: Expected location after \"-L\" "
581 "option."));
ef416fc2 582 return (1);
583 }
584
7cf5915e
MS
585 num_options = cupsAddOption("printer-location", argv[i],
586 num_options, &options);
ef416fc2 587 }
588 break;
589
590 case 'P' : /* Use the specified PPD file */
ef416fc2 591 if (argv[i][2])
7cf5915e 592 file = argv[i] + 2;
ef416fc2 593 else
594 {
595 i ++;
596
597 if (i >= argc)
598 {
fa73b229 599 _cupsLangPuts(stderr,
0837b7e8 600 _("lpadmin: Expected PPD after \"-P\" option."));
ef416fc2 601 return (1);
602 }
603
7cf5915e 604 file = argv[i];
ef416fc2 605 }
606 break;
607
608 default :
fa73b229 609 _cupsLangPrintf(stderr,
0837b7e8 610 _("lpadmin: Unknown option \"%c\"."), argv[i][1]);
ef416fc2 611 return (1);
612 }
613 else
614 {
0837b7e8 615 _cupsLangPrintf(stderr, _("lpadmin: Unknown argument \"%s\"."),
ef416fc2 616 argv[i]);
617 return (1);
618 }
619
620 /*
621 * Set options as needed...
622 */
623
7cf5915e 624 if (num_options || file)
ef416fc2 625 {
626 if (!http)
627 {
628 http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
629
630 if (http == NULL)
631 {
fa73b229 632 _cupsLangPrintf(stderr,
0837b7e8 633 _("lpadmin: Unable to connect to server: %s"),
ef416fc2 634 strerror(errno));
635 return (1);
636 }
637 }
638
639 if (printer == NULL)
640 {
fa73b229 641 _cupsLangPuts(stderr,
ef416fc2 642 _("lpadmin: Unable to set the printer options:\n"
0837b7e8 643 " You must specify a printer name first."));
ef416fc2 644 return (1);
645 }
646
7cf5915e 647 if (set_printer_options(http, printer, num_options, options, file))
ef416fc2 648 return (1);
649 }
650
651 if (printer == NULL)
652 {
fa73b229 653 _cupsLangPuts(stdout,
ef416fc2 654 _("Usage:\n"
655 "\n"
656 " lpadmin [-h server] -d destination\n"
657 " lpadmin [-h server] -x destination\n"
658 " lpadmin [-h server] -p printer [-c add-class] "
659 "[-i interface] [-m model]\n"
660 " [-r remove-class] [-v device] "
661 "[-D description]\n"
662 " [-P ppd-file] [-o name=value]\n"
663 " [-u allow:user,user] "
0837b7e8 664 "[-u deny:user,user]"));
ef416fc2 665 }
666
667 if (http)
668 httpClose(http);
669
670 return (0);
671}
672
673
674/*
675 * 'add_printer_to_class()' - Add a printer to a class.
676 */
677
678static int /* O - 0 on success, 1 on fail */
679add_printer_to_class(http_t *http, /* I - Server connection */
680 char *printer, /* I - Printer to add */
681 char *pclass) /* I - Class to add to */
682{
683 int i; /* Looping var */
684 ipp_t *request, /* IPP Request */
685 *response; /* IPP Response */
686 ipp_attribute_t *attr, /* Current attribute */
687 *members; /* Members in class */
ef416fc2 688 char uri[HTTP_MAX_URI]; /* URI for printer/class */
689
690
691 DEBUG_printf(("add_printer_to_class(%p, \"%s\", \"%s\")\n", http,
692 printer, pclass));
693
694 /*
695 * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
696 * attributes:
697 *
698 * attributes-charset
699 * attributes-natural-language
700 * printer-uri
eac3a0a0 701 * requesting-user-name
ef416fc2 702 */
703
fa73b229 704 request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
705
a4d04587 706 httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
707 "localhost", 0, "/classes/%s", pclass);
ef416fc2 708 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
709 "printer-uri", NULL, uri);
eac3a0a0
MS
710 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
711 NULL, cupsUser());
ef416fc2 712
713 /*
714 * Do the request and get back a response...
715 */
716
717 response = cupsDoRequest(http, request, "/");
718
719 /*
eac3a0a0 720 * Build a CUPS_ADD_MODIFY_CLASS request, which requires the following
ef416fc2 721 * attributes:
722 *
723 * attributes-charset
724 * attributes-natural-language
725 * printer-uri
eac3a0a0 726 * requesting-user-name
ef416fc2 727 * member-uris
728 */
729
eac3a0a0 730 request = ippNewRequest(CUPS_ADD_MODIFY_CLASS);
ef416fc2 731
732 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
733 "printer-uri", NULL, uri);
eac3a0a0
MS
734 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
735 NULL, cupsUser());
ef416fc2 736
737 /*
738 * See if the printer is already in the class...
739 */
740
741 if (response != NULL &&
eac3a0a0
MS
742 (members = ippFindAttribute(response, "member-names",
743 IPP_TAG_NAME)) != NULL)
ef416fc2 744 for (i = 0; i < members->num_values; i ++)
88f9aafc 745 if (_cups_strcasecmp(printer, members->values[i].string.text) == 0)
ef416fc2 746 {
fa73b229 747 _cupsLangPrintf(stderr,
0837b7e8
MS
748 _("lpadmin: Printer %s is already a member of class "
749 "%s."), printer, pclass);
ef416fc2 750 ippDelete(request);
751 ippDelete(response);
752 return (0);
753 }
754
755 /*
756 * OK, the printer isn't part of the class, so add it...
757 */
758
a4d04587 759 httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
760 "localhost", 0, "/printers/%s", printer);
ef416fc2 761
762 if (response != NULL &&
eac3a0a0
MS
763 (members = ippFindAttribute(response, "member-uris",
764 IPP_TAG_URI)) != NULL)
ef416fc2 765 {
766 /*
767 * Add the printer to the existing list...
768 */
769
770 attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI,
771 "member-uris", members->num_values + 1, NULL, NULL);
772 for (i = 0; i < members->num_values; i ++)
eac3a0a0
MS
773 attr->values[i].string.text =
774 _cupsStrAlloc(members->values[i].string.text);
ef416fc2 775
1f0275e3 776 attr->values[i].string.text = _cupsStrAlloc(uri);
ef416fc2 777 }
778 else
1f0275e3
MS
779 ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris", NULL,
780 uri);
ef416fc2 781
782 /*
783 * Then send the request...
784 */
785
786 ippDelete(response);
787
eac3a0a0
MS
788 ippDelete(cupsDoRequest(http, request, "/admin/"));
789 if (cupsLastError() > IPP_OK_CONFLICT)
ef416fc2 790 {
eac3a0a0 791 _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());
ef416fc2 792
793 return (1);
794 }
795 else
ef416fc2 796 return (0);
ef416fc2 797}
798
799
800/*
801 * 'default_printer()' - Set the default printing destination.
802 */
803
804static int /* O - 0 on success, 1 on fail */
805default_printer(http_t *http, /* I - Server connection */
806 char *printer) /* I - Printer name */
807{
eac3a0a0 808 ipp_t *request; /* IPP Request */
ef416fc2 809 char uri[HTTP_MAX_URI]; /* URI for printer/class */
810
811
812 DEBUG_printf(("default_printer(%p, \"%s\")\n", http, printer));
813
814 /*
815 * Build a CUPS_SET_DEFAULT request, which requires the following
816 * attributes:
817 *
818 * attributes-charset
819 * attributes-natural-language
820 * printer-uri
eac3a0a0 821 * requesting-user-name
ef416fc2 822 */
823
a4d04587 824 httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
825 "localhost", 0, "/printers/%s", printer);
ef416fc2 826
fa73b229 827 request = ippNewRequest(CUPS_SET_DEFAULT);
ef416fc2 828
829 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
830 "printer-uri", NULL, uri);
eac3a0a0
MS
831 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
832 NULL, cupsUser());
ef416fc2 833
834 /*
835 * Do the request and get back a response...
836 */
837
eac3a0a0 838 ippDelete(cupsDoRequest(http, request, "/admin/"));
ef416fc2 839
eac3a0a0 840 if (cupsLastError() > IPP_OK_CONFLICT)
ef416fc2 841 {
eac3a0a0 842 _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());
ef416fc2 843
844 return (1);
845 }
846 else
ef416fc2 847 return (0);
ef416fc2 848}
849
850
851/*
852 * 'delete_printer()' - Delete a printer from the system...
853 */
854
855static int /* O - 0 on success, 1 on fail */
856delete_printer(http_t *http, /* I - Server connection */
857 char *printer) /* I - Printer to delete */
858{
eac3a0a0 859 ipp_t *request; /* IPP Request */
ef416fc2 860 char uri[HTTP_MAX_URI]; /* URI for printer/class */
861
862
863 DEBUG_printf(("delete_printer(%p, \"%s\")\n", http, printer));
864
865 /*
866 * Build a CUPS_DELETE_PRINTER request, which requires the following
867 * attributes:
868 *
869 * attributes-charset
870 * attributes-natural-language
871 * printer-uri
eac3a0a0 872 * requesting-user-name
ef416fc2 873 */
874
fa73b229 875 request = ippNewRequest(CUPS_DELETE_PRINTER);
876
a4d04587 877 httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
878 "localhost", 0, "/printers/%s", printer);
ef416fc2 879 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
880 "printer-uri", NULL, uri);
eac3a0a0
MS
881 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
882 NULL, cupsUser());
ef416fc2 883
884 /*
885 * Do the request and get back a response...
886 */
887
eac3a0a0 888 ippDelete(cupsDoRequest(http, request, "/admin/"));
ef416fc2 889
eac3a0a0 890 if (cupsLastError() > IPP_OK_CONFLICT)
ef416fc2 891 {
eac3a0a0 892 _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());
ef416fc2 893
894 return (1);
895 }
896 else
ef416fc2 897 return (0);
ef416fc2 898}
899
900
901/*
902 * 'delete_printer_from_class()' - Delete a printer from a class.
903 */
904
905static int /* O - 0 on success, 1 on fail */
fa73b229 906delete_printer_from_class(
907 http_t *http, /* I - Server connection */
908 char *printer, /* I - Printer to remove */
909 char *pclass) /* I - Class to remove from */
ef416fc2 910{
911 int i, j, k; /* Looping vars */
912 ipp_t *request, /* IPP Request */
913 *response; /* IPP Response */
914 ipp_attribute_t *attr, /* Current attribute */
915 *members; /* Members in class */
ef416fc2 916 char uri[HTTP_MAX_URI]; /* URI for printer/class */
917
918
919 DEBUG_printf(("delete_printer_from_class(%p, \"%s\", \"%s\")\n", http,
920 printer, pclass));
921
922 /*
923 * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
924 * attributes:
925 *
926 * attributes-charset
927 * attributes-natural-language
928 * printer-uri
eac3a0a0 929 * requesting-user-name
ef416fc2 930 */
931
fa73b229 932 request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
933
a4d04587 934 httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
935 "localhost", 0, "/classes/%s", pclass);
ef416fc2 936 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
937 "printer-uri", NULL, uri);
eac3a0a0
MS
938 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
939 NULL, cupsUser());
ef416fc2 940
941 /*
942 * Do the request and get back a response...
943 */
944
945 if ((response = cupsDoRequest(http, request, "/classes/")) == NULL ||
946 response->request.status.status_code == IPP_NOT_FOUND)
947 {
eac3a0a0 948 _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());
fa73b229 949
ef416fc2 950 ippDelete(response);
fa73b229 951
ef416fc2 952 return (1);
953 }
954
955 /*
956 * See if the printer is already in the class...
957 */
958
959 if ((members = ippFindAttribute(response, "member-names", IPP_TAG_NAME)) == NULL)
960 {
0837b7e8 961 _cupsLangPuts(stderr, _("lpadmin: No member names were seen."));
fa73b229 962
ef416fc2 963 ippDelete(response);
fa73b229 964
ef416fc2 965 return (1);
966 }
967
968 for (i = 0; i < members->num_values; i ++)
88f9aafc 969 if (!_cups_strcasecmp(printer, members->values[i].string.text))
ef416fc2 970 break;
971
972 if (i >= members->num_values)
973 {
fa73b229 974 _cupsLangPrintf(stderr,
0837b7e8 975 _("lpadmin: Printer %s is not a member of class %s."),
fa73b229 976 printer, pclass);
977
ef416fc2 978 ippDelete(response);
fa73b229 979
ef416fc2 980 return (1);
981 }
982
983 if (members->num_values == 1)
984 {
985 /*
986 * Build a CUPS_DELETE_CLASS request, which requires the following
987 * attributes:
988 *
989 * attributes-charset
990 * attributes-natural-language
991 * printer-uri
eac3a0a0 992 * requesting-user-name
ef416fc2 993 */
994
fa73b229 995 request = ippNewRequest(CUPS_DELETE_CLASS);
ef416fc2 996
997 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
998 "printer-uri", NULL, uri);
eac3a0a0
MS
999 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
1000 "requesting-user-name", NULL, cupsUser());
ef416fc2 1001 }
1002 else
1003 {
1004 /*
eac3a0a0 1005 * Build a CUPS_ADD_MODIFY_CLASS request, which requires the following
ef416fc2 1006 * attributes:
1007 *
1008 * attributes-charset
1009 * attributes-natural-language
1010 * printer-uri
eac3a0a0 1011 * requesting-user-name
ef416fc2 1012 * member-uris
1013 */
1014
eac3a0a0 1015 request = ippNewRequest(CUPS_ADD_MODIFY_CLASS);
ef416fc2 1016
1017 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1018 "printer-uri", NULL, uri);
eac3a0a0
MS
1019 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
1020 "requesting-user-name", NULL, cupsUser());
ef416fc2 1021
1022 /*
1023 * Delete the printer from the class...
1024 */
1025
1026 members = ippFindAttribute(response, "member-uris", IPP_TAG_URI);
1027 attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI,
1028 "member-uris", members->num_values - 1, NULL, NULL);
1029
1030 for (j = 0, k = 0; j < members->num_values; j ++)
1031 if (j != i)
1f0275e3
MS
1032 attr->values[k ++].string.text =
1033 _cupsStrAlloc(members->values[j].string.text);
ef416fc2 1034 }
1035
1036 /*
1037 * Then send the request...
1038 */
1039
1040 ippDelete(response);
1041
eac3a0a0
MS
1042 ippDelete(cupsDoRequest(http, request, "/admin/"));
1043
1044 if (cupsLastError() > IPP_OK_CONFLICT)
ef416fc2 1045 {
eac3a0a0 1046 _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());
fa73b229 1047
ef416fc2 1048 return (1);
1049 }
eac3a0a0
MS
1050 else
1051 return (0);
1052}
ef416fc2 1053
ef416fc2 1054
eac3a0a0
MS
1055/*
1056 * 'delete_printer_option()' - Delete a printer option.
1057 */
1058
1059static int /* O - 0 on success, 1 on fail */
1060delete_printer_option(http_t *http, /* I - Server connection */
1061 char *printer, /* I - Printer */
1062 char *option) /* I - Option to delete */
1063{
1064 ipp_t *request; /* IPP request */
1065 char uri[HTTP_MAX_URI]; /* URI for printer/class */
1066
1067
1068 /*
1069 * Build a CUPS_ADD_MODIFY_PRINTER or CUPS_ADD_MODIFY_CLASS request, which
1070 * requires the following attributes:
1071 *
1072 * attributes-charset
1073 * attributes-natural-language
1074 * printer-uri
1075 * requesting-user-name
1076 * option with deleteAttr tag
1077 */
1078
a2326b5b 1079 if (get_printer_type(http, printer, uri, sizeof(uri)) & CUPS_PRINTER_CLASS)
eac3a0a0 1080 request = ippNewRequest(CUPS_ADD_MODIFY_CLASS);
ef416fc2 1081 else
eac3a0a0
MS
1082 request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER);
1083
1084 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1085 "printer-uri", NULL, uri);
1086 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
1087 "requesting-user-name", NULL, cupsUser());
1088 ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_DELETEATTR, option, 0);
1089
1090 /*
1091 * Do the request and get back a response...
1092 */
1093
1094 ippDelete(cupsDoRequest(http, request, "/admin/"));
1095
1096 if (cupsLastError() > IPP_OK_CONFLICT)
ef416fc2 1097 {
eac3a0a0 1098 _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());
ef416fc2 1099
eac3a0a0 1100 return (1);
ef416fc2 1101 }
eac3a0a0
MS
1102 else
1103 return (0);
ef416fc2 1104}
1105
1106
1107/*
1108 * 'enable_printer()' - Enable a printer...
1109 */
1110
1111static int /* O - 0 on success, 1 on fail */
1112enable_printer(http_t *http, /* I - Server connection */
1113 char *printer) /* I - Printer to enable */
1114{
eac3a0a0 1115 ipp_t *request; /* IPP Request */
ef416fc2 1116 char uri[HTTP_MAX_URI]; /* URI for printer/class */
1117
1118
1119 DEBUG_printf(("enable_printer(%p, \"%s\")\n", http, printer));
1120
1121 /*
eac3a0a0
MS
1122 * Build a CUPS_ADD_MODIFY_PRINTER or CUPS_ADD_MODIFY_CLASS request, which
1123 * require the following attributes:
ef416fc2 1124 *
1125 * attributes-charset
1126 * attributes-natural-language
1127 * printer-uri
eac3a0a0 1128 * requesting-user-name
ef416fc2 1129 * printer-state
1130 * printer-is-accepting-jobs
1131 */
1132
a2326b5b 1133 if (get_printer_type(http, printer, uri, sizeof(uri)) & CUPS_PRINTER_CLASS)
eac3a0a0
MS
1134 request = ippNewRequest(CUPS_ADD_MODIFY_CLASS);
1135 else
1136 request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER);
fa73b229 1137
ef416fc2 1138 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1139 "printer-uri", NULL, uri);
eac3a0a0
MS
1140 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
1141 "requesting-user-name", NULL, cupsUser());
ef416fc2 1142 ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
1143 IPP_PRINTER_IDLE);
ef416fc2 1144 ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1);
1145
1146 /*
1147 * Do the request and get back a response...
1148 */
1149
eac3a0a0 1150 ippDelete(cupsDoRequest(http, request, "/admin/"));
fa73b229 1151
eac3a0a0 1152 if (cupsLastError() > IPP_OK_CONFLICT)
ef416fc2 1153 {
eac3a0a0 1154 _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());
ef416fc2 1155
1156 return (1);
1157 }
1158 else
eac3a0a0
MS
1159 return (0);
1160}
1161
1162
1163/*
1164 * 'get_printer_type()' - Determine the printer type and URI.
1165 */
1166
1167static cups_ptype_t /* O - printer-type value */
1168get_printer_type(http_t *http, /* I - Server connection */
1169 char *printer, /* I - Printer name */
1170 char *uri, /* I - URI buffer */
1171 size_t urisize) /* I - Size of URI buffer */
1172{
1173 ipp_t *request, /* IPP request */
1174 *response; /* IPP response */
1175 ipp_attribute_t *attr; /* printer-type attribute */
1176 cups_ptype_t type; /* printer-type value */
1177
1178
1179 /*
1180 * Build a GET_PRINTER_ATTRIBUTES request, which requires the following
1181 * attributes:
1182 *
1183 * attributes-charset
1184 * attributes-natural-language
1185 * printer-uri
1186 * requested-attributes
1187 * requesting-user-name
1188 */
1189
7e86f2f6 1190 httpAssembleURIf(HTTP_URI_CODING_ALL, uri, (int)urisize, "ipp", NULL, "localhost", ippPort(), "/printers/%s", printer);
eac3a0a0
MS
1191
1192 request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
1193 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1194 "printer-uri", NULL, uri);
1195 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
1196 "requested-attributes", NULL, "printer-type");
1197 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
1198 "requesting-user-name", NULL, cupsUser());
1199
1200 /*
1201 * Do the request...
1202 */
1203
1204 response = cupsDoRequest(http, request, "/");
1205 if ((attr = ippFindAttribute(response, "printer-type",
1206 IPP_TAG_ENUM)) != NULL)
ef416fc2 1207 {
eac3a0a0 1208 type = (cups_ptype_t)attr->values[0].integer;
ef416fc2 1209
a2326b5b 1210 if (type & CUPS_PRINTER_CLASS)
7e86f2f6 1211 httpAssembleURIf(HTTP_URI_CODING_ALL, uri, (int)urisize, "ipp", NULL, "localhost", ippPort(), "/classes/%s", printer);
ef416fc2 1212 }
eac3a0a0
MS
1213 else
1214 type = CUPS_PRINTER_LOCAL;
1215
1216 ippDelete(response);
1217
1218 return (type);
ef416fc2 1219}
1220
1221
ef416fc2 1222/*
1223 * 'set_printer_options()' - Set the printer options.
1224 */
1225
1226static int /* O - 0 on success, 1 on fail */
fa73b229 1227set_printer_options(
1228 http_t *http, /* I - Server connection */
1229 char *printer, /* I - Printer */
1230 int num_options, /* I - Number of options */
7cf5915e
MS
1231 cups_option_t *options, /* I - Options */
1232 char *file) /* I - PPD file/interface script */
ef416fc2 1233{
eac3a0a0 1234 ipp_t *request; /* IPP Request */
b423cd4c 1235 const char *ppdfile; /* PPD filename */
1236 int ppdchanged; /* PPD changed? */
1237 ppd_file_t *ppd; /* PPD file */
1238 ppd_choice_t *choice; /* Marked choice */
ef416fc2 1239 char uri[HTTP_MAX_URI], /* URI for printer/class */
1240 line[1024], /* Line from PPD file */
1241 keyword[1024], /* Keyword from Default line */
1242 *keyptr, /* Pointer into keyword... */
1243 tempfile[1024]; /* Temporary filename */
7cf5915e 1244 cups_file_t *in, /* PPD file */
ef416fc2 1245 *out; /* Temporary file */
7cf5915e 1246 const char *protocol, /* Old protocol option */
eac3a0a0
MS
1247 *customval, /* Custom option value */
1248 *boolval; /* Boolean value */
1249 int wrote_ipp_supplies = 0, /* Wrote cupsIPPSupplies keyword? */
1250 wrote_snmp_supplies = 0;/* Wrote cupsSNMPSupplies keyword? */
ef416fc2 1251
1252
7cf5915e
MS
1253 DEBUG_printf(("set_printer_options(http=%p, printer=\"%s\", num_options=%d, "
1254 "options=%p, file=\"%s\")\n", http, printer, num_options,
1255 options, file));
ef416fc2 1256
ef416fc2 1257 /*
7cf5915e
MS
1258 * Build a CUPS_ADD_MODIFY_PRINTER or CUPS_ADD_MODIFY_CLASS request, which
1259 * requires the following attributes:
ef416fc2 1260 *
1261 * attributes-charset
1262 * attributes-natural-language
1263 * printer-uri
eac3a0a0 1264 * requesting-user-name
ef416fc2 1265 * other options
1266 */
1267
a2326b5b 1268 if (get_printer_type(http, printer, uri, sizeof(uri)) & CUPS_PRINTER_CLASS)
eac3a0a0
MS
1269 request = ippNewRequest(CUPS_ADD_MODIFY_CLASS);
1270 else
1271 request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER);
ef416fc2 1272
1273 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1274 "printer-uri", NULL, uri);
7cf5915e
MS
1275 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
1276 "requesting-user-name", NULL, cupsUser());
ef416fc2 1277
1278 /*
1279 * Add the options...
1280 */
1281
b0f26938 1282 cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION);
b423cd4c 1283 cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER);
1284
1285 if ((protocol = cupsGetOption("protocol", num_options, options)) != NULL)
1286 {
88f9aafc 1287 if (!_cups_strcasecmp(protocol, "bcp"))
a41f09e2 1288 ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "port-monitor",
b423cd4c 1289 NULL, "bcp");
88f9aafc 1290 else if (!_cups_strcasecmp(protocol, "tbcp"))
a41f09e2 1291 ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "port-monitor",
b423cd4c 1292 NULL, "tbcp");
1293 }
ef416fc2 1294
7cf5915e
MS
1295 if (file)
1296 ppdfile = file;
eac3a0a0 1297 else if (request->request.op.operation_id == CUPS_ADD_MODIFY_PRINTER)
ef416fc2 1298 ppdfile = cupsGetPPD(printer);
1299 else
1300 ppdfile = NULL;
1301
1302 if (ppdfile != NULL)
1303 {
1304 /*
1305 * Set default options in the PPD file...
1306 */
1307
b423cd4c 1308 ppd = ppdOpenFile(ppdfile);
1309 ppdMarkDefaults(ppd);
1310 cupsMarkOptions(ppd, num_options, options);
1311
0268488e 1312 if ((out = cupsTempFile2(tempfile, sizeof(tempfile))) == NULL)
ef416fc2 1313 {
0837b7e8 1314 _cupsLangPrintError(NULL, _("lpadmin: Unable to create temporary file"));
ef416fc2 1315 ippDelete(request);
7cf5915e
MS
1316 if (ppdfile != file)
1317 unlink(ppdfile);
ef416fc2 1318 return (1);
1319 }
1320
7cf5915e 1321 if ((in = cupsFileOpen(ppdfile, "r")) == NULL)
ef416fc2 1322 {
fa73b229 1323 _cupsLangPrintf(stderr,
0837b7e8 1324 _("lpadmin: Unable to open PPD file \"%s\" - %s"),
ef416fc2 1325 ppdfile, strerror(errno));
1326 ippDelete(request);
7cf5915e
MS
1327 if (ppdfile != file)
1328 unlink(ppdfile);
1329 cupsFileClose(out);
ef416fc2 1330 unlink(tempfile);
1331 return (1);
1332 }
1333
b423cd4c 1334 ppdchanged = 0;
ef416fc2 1335
7cf5915e 1336 while (cupsFileGets(in, line, sizeof(line)))
ef416fc2 1337 {
eac3a0a0
MS
1338 if (!strncmp(line, "*cupsIPPSupplies:", 17) &&
1339 (boolval = cupsGetOption("cupsIPPSupplies", num_options,
1340 options)) != NULL)
1341 {
1342 wrote_ipp_supplies = 1;
1343 cupsFilePrintf(out, "*cupsIPPSupplies: %s\n",
88f9aafc
MS
1344 (!_cups_strcasecmp(boolval, "true") ||
1345 !_cups_strcasecmp(boolval, "yes") ||
1346 !_cups_strcasecmp(boolval, "on")) ? "True" : "False");
eac3a0a0
MS
1347 }
1348 else if (!strncmp(line, "*cupsSNMPSupplies:", 18) &&
1349 (boolval = cupsGetOption("cupsSNMPSupplies", num_options,
1350 options)) != NULL)
1351 {
1352 wrote_snmp_supplies = 1;
1353 cupsFilePrintf(out, "*cupsSNMPSupplies: %s\n",
88f9aafc
MS
1354 (!_cups_strcasecmp(boolval, "true") ||
1355 !_cups_strcasecmp(boolval, "yes") ||
1356 !_cups_strcasecmp(boolval, "on")) ? "True" : "False");
eac3a0a0
MS
1357 }
1358 else if (strncmp(line, "*Default", 8))
7cf5915e 1359 cupsFilePrintf(out, "%s\n", line);
ef416fc2 1360 else
1361 {
1362 /*
1363 * Get default option name...
1364 */
1365
1366 strlcpy(keyword, line + 8, sizeof(keyword));
1367
1368 for (keyptr = keyword; *keyptr; keyptr ++)
1369 if (*keyptr == ':' || isspace(*keyptr & 255))
1370 break;
1371
b423cd4c 1372 *keyptr++ = '\0';
1373 while (isspace(*keyptr & 255))
1374 keyptr ++;
1375
1376 if (!strcmp(keyword, "PageRegion") ||
1377 !strcmp(keyword, "PageSize") ||
1378 !strcmp(keyword, "PaperDimension") ||
1379 !strcmp(keyword, "ImageableArea"))
1380 {
1381 if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) == NULL)
1382 choice = ppdFindMarkedChoice(ppd, "PageRegion");
1383 }
ef416fc2 1384 else
b423cd4c 1385 choice = ppdFindMarkedChoice(ppd, keyword);
ef416fc2 1386
b423cd4c 1387 if (choice && strcmp(choice->choice, keyptr))
1388 {
7cf5915e
MS
1389 if (strcmp(choice->choice, "Custom"))
1390 {
1391 cupsFilePrintf(out, "*Default%s: %s\n", keyword, choice->choice);
1392 ppdchanged = 1;
1393 }
1394 else if ((customval = cupsGetOption(keyword, num_options,
1395 options)) != NULL)
1396 {
1397 cupsFilePrintf(out, "*Default%s: %s\n", keyword, customval);
1398 ppdchanged = 1;
1399 }
1400 else
1401 cupsFilePrintf(out, "%s\n", line);
b423cd4c 1402 }
ef416fc2 1403 else
7cf5915e 1404 cupsFilePrintf(out, "%s\n", line);
ef416fc2 1405 }
1406 }
1407
eac3a0a0
MS
1408 if (!wrote_ipp_supplies &&
1409 (boolval = cupsGetOption("cupsIPPSupplies", num_options,
1410 options)) != NULL)
1411 {
1412 cupsFilePrintf(out, "*cupsIPPSupplies: %s\n",
88f9aafc
MS
1413 (!_cups_strcasecmp(boolval, "true") ||
1414 !_cups_strcasecmp(boolval, "yes") ||
1415 !_cups_strcasecmp(boolval, "on")) ? "True" : "False");
eac3a0a0
MS
1416 }
1417
1418 if (!wrote_snmp_supplies &&
1419 (boolval = cupsGetOption("cupsSNMPSupplies", num_options,
1420 options)) != NULL)
1421 {
1422 cupsFilePrintf(out, "*cupsSNMPSupplies: %s\n",
88f9aafc
MS
1423 (!_cups_strcasecmp(boolval, "true") ||
1424 !_cups_strcasecmp(boolval, "yes") ||
1425 !_cups_strcasecmp(boolval, "on")) ? "True" : "False");
eac3a0a0
MS
1426 }
1427
7cf5915e
MS
1428 cupsFileClose(in);
1429 cupsFileClose(out);
b423cd4c 1430 ppdClose(ppd);
ef416fc2 1431
1432 /*
1433 * Do the request...
1434 */
1435
b423cd4c 1436 ippDelete(cupsDoFileRequest(http, request, "/admin/",
7cf5915e 1437 ppdchanged ? tempfile : file));
ef416fc2 1438
1439 /*
1440 * Clean up temp files... (TODO: catch signals in case we CTRL-C during
1441 * lpadmin)
1442 */
1443
7cf5915e
MS
1444 if (ppdfile != file)
1445 unlink(ppdfile);
ef416fc2 1446 unlink(tempfile);
1447 }
1448 else
1449 {
1450 /*
1451 * No PPD file - just set the options...
1452 */
1453
b423cd4c 1454 ippDelete(cupsDoRequest(http, request, "/admin/"));
ef416fc2 1455 }
1456
1457 /*
1458 * Check the response...
1459 */
1460
fa73b229 1461 if (cupsLastError() > IPP_OK_CONFLICT)
ef416fc2 1462 {
eac3a0a0 1463 _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());
ef416fc2 1464
1465 return (1);
1466 }
1467 else
ef416fc2 1468 return (0);
ef416fc2 1469}
1470
1471
1472/*
1473 * 'validate_name()' - Make sure the printer name only contains valid chars.
1474 */
1475
fa73b229 1476static int /* O - 0 if name is no good, 1 if name is good */
1477validate_name(const char *name) /* I - Name to check */
ef416fc2 1478{
fa73b229 1479 const char *ptr; /* Pointer into name */
ef416fc2 1480
1481
1482 /*
1483 * Scan the whole name...
1484 */
1485
1486 for (ptr = name; *ptr; ptr ++)
1487 if (*ptr == '@')
1488 break;
1489 else if ((*ptr >= 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/' ||
1490 *ptr == '#')
1491 return (0);
1492
1493 /*
1494 * All the characters are good; validate the length, too...
1495 */
1496
1497 return ((ptr - name) < 128);
1498}
1499
1500
1501/*
f2d18633 1502 * End of "$Id$".
ef416fc2 1503 */