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