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