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