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