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