]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | /* |
b19ccc9e | 2 | * "$Id: lpadmin.c 7720 2008-07-11 22:46:21Z mike $" |
ef416fc2 | 3 | * |
71e16022 | 4 | * "lpadmin" command for CUPS. |
ef416fc2 | 5 | * |
71e16022 | 6 | * Copyright 2007-2010 by Apple Inc. |
ef416fc2 | 7 | * Copyright 1997-2006 by Easy Software Products. |
8 | * | |
9 | * These coded instructions, statements, and computer programs are the | |
bc44d920 | 10 | * property of Apple Inc. and are protected by Federal copyright |
11 | * law. Distribution and use rights are outlined in the file "LICENSE.txt" | |
12 | * which should have been included with this file. If this file is | |
13 | * file is missing or damaged, see the license at "http://www.cups.org/". | |
ef416fc2 | 14 | * |
15 | * Contents: | |
16 | * | |
17 | * main() - Parse options and configure the scheduler. | |
18 | * add_printer_to_class() - Add a printer to a class. | |
19 | * default_printer() - Set the default printing destination. | |
7cf5915e | 20 | * delete_printer() - Delete a printer from the system. |
ef416fc2 | 21 | * delete_printer_from_class() - Delete a printer from a class. |
7cf5915e MS |
22 | * enable_printer() - Enable a printer. |
23 | * set_printer_options() - Set the printer options and/or file. | |
ef416fc2 | 24 | * validate_name() - Make sure the printer name only contains |
7cf5915e | 25 | * valid chars. |
ef416fc2 | 26 | */ |
27 | ||
28 | /* | |
29 | * Include necessary headers... | |
30 | */ | |
31 | ||
71e16022 | 32 | #include <cups/cups-private.h> |
ef416fc2 | 33 | |
34 | ||
35 | /* | |
36 | * Local functions... | |
37 | */ | |
38 | ||
7cf5915e MS |
39 | static int add_printer_to_class(http_t *http, char *printer, char *pclass); |
40 | static int default_printer(http_t *http, char *printer); | |
41 | static int delete_printer(http_t *http, char *printer); | |
42 | static int delete_printer_from_class(http_t *http, char *printer, | |
43 | char *pclass); | |
44 | static int enable_printer(http_t *http, char *printer); | |
45 | static int set_printer_options(http_t *http, char *printer, | |
46 | int num_options, cups_option_t *options, | |
47 | char *file); | |
48 | static int validate_name(const char *name); | |
ef416fc2 | 49 | |
50 | ||
51 | /* | |
52 | * 'main()' - Parse options and configure the scheduler. | |
53 | */ | |
54 | ||
55 | int | |
56 | main(int argc, /* I - Number of command-line arguments */ | |
57 | char *argv[]) /* I - Command-line arguments */ | |
58 | { | |
59 | int i; /* Looping var */ | |
60 | http_t *http; /* Connection to server */ | |
61 | char *printer, /* Destination printer */ | |
62 | *pclass, /* Printer class name */ | |
63 | *val; /* Pointer to allow/deny value */ | |
64 | int num_options; /* Number of options */ | |
65 | cups_option_t *options; /* Options */ | |
7cf5915e | 66 | char *file; /* New PPD file/interface script */ |
ef416fc2 | 67 | |
68 | ||
07725fee | 69 | _cupsSetLocale(argv); |
d09495fa | 70 | |
ef416fc2 | 71 | http = NULL; |
72 | printer = NULL; | |
73 | num_options = 0; | |
74 | options = NULL; | |
7cf5915e | 75 | file = NULL; |
ef416fc2 | 76 | |
77 | for (i = 1; i < argc; i ++) | |
78 | if (argv[i][0] == '-') | |
79 | switch (argv[i][1]) | |
80 | { | |
81 | case 'c' : /* Add printer to class */ | |
82 | if (!http) | |
83 | { | |
84 | http = httpConnectEncrypt(cupsServer(), ippPort(), | |
85 | cupsEncryption()); | |
86 | ||
87 | if (http == NULL) | |
88 | { | |
fa73b229 | 89 | _cupsLangPrintf(stderr, |
0837b7e8 | 90 | _("lpadmin: Unable to connect to server: %s"), |
ef416fc2 | 91 | strerror(errno)); |
92 | return (1); | |
93 | } | |
94 | } | |
95 | ||
96 | if (printer == NULL) | |
97 | { | |
fa73b229 | 98 | _cupsLangPuts(stderr, |
ef416fc2 | 99 | _("lpadmin: Unable to add a printer to the class:\n" |
100 | " You must specify a printer name " | |
0837b7e8 | 101 | "first.")); |
ef416fc2 | 102 | return (1); |
103 | } | |
104 | ||
105 | if (argv[i][2]) | |
106 | pclass = argv[i] + 2; | |
107 | else | |
108 | { | |
109 | i ++; | |
110 | ||
111 | if (i >= argc) | |
112 | { | |
fa73b229 | 113 | _cupsLangPuts(stderr, |
0837b7e8 MS |
114 | _("lpadmin: Expected class name after \"-c\" " |
115 | "option.")); | |
ef416fc2 | 116 | return (1); |
117 | } | |
118 | ||
119 | pclass = argv[i]; | |
120 | } | |
121 | ||
122 | if (!validate_name(pclass)) | |
123 | { | |
fa73b229 | 124 | _cupsLangPuts(stderr, |
ef416fc2 | 125 | _("lpadmin: Class name can only contain printable " |
0837b7e8 | 126 | "characters.")); |
ef416fc2 | 127 | return (1); |
128 | } | |
129 | ||
130 | if (add_printer_to_class(http, printer, pclass)) | |
131 | return (1); | |
132 | break; | |
133 | ||
134 | case 'd' : /* Set as default destination */ | |
135 | if (!http) | |
136 | { | |
137 | http = httpConnectEncrypt(cupsServer(), ippPort(), | |
138 | cupsEncryption()); | |
139 | ||
140 | if (http == NULL) | |
141 | { | |
fa73b229 | 142 | _cupsLangPrintf(stderr, |
0837b7e8 | 143 | _("lpadmin: Unable to connect to server: %s"), |
ef416fc2 | 144 | strerror(errno)); |
145 | return (1); | |
146 | } | |
147 | } | |
148 | ||
149 | if (argv[i][2]) | |
150 | printer = argv[i] + 2; | |
151 | else | |
152 | { | |
153 | i ++; | |
154 | ||
155 | if (i >= argc) | |
156 | { | |
fa73b229 | 157 | _cupsLangPuts(stderr, |
0837b7e8 MS |
158 | _("lpadmin: Expected printer name after \"-d\" " |
159 | "option.")); | |
ef416fc2 | 160 | return (1); |
161 | } | |
162 | ||
163 | printer = argv[i]; | |
164 | } | |
165 | ||
166 | if (!validate_name(printer)) | |
167 | { | |
fa73b229 | 168 | _cupsLangPuts(stderr, |
ef416fc2 | 169 | _("lpadmin: Printer name can only contain " |
0837b7e8 | 170 | "printable characters.")); |
ef416fc2 | 171 | return (1); |
172 | } | |
173 | ||
174 | if (default_printer(http, printer)) | |
175 | return (1); | |
176 | ||
177 | i = argc; | |
178 | break; | |
179 | ||
180 | case 'h' : /* Connect to host */ | |
181 | if (http) | |
182 | { | |
183 | httpClose(http); | |
184 | http = NULL; | |
185 | } | |
186 | ||
187 | if (argv[i][2] != '\0') | |
188 | cupsSetServer(argv[i] + 2); | |
189 | else | |
190 | { | |
191 | i ++; | |
192 | ||
193 | if (i >= argc) | |
194 | { | |
fa73b229 | 195 | _cupsLangPuts(stderr, |
0837b7e8 MS |
196 | _("lpadmin: Expected hostname after \"-h\" " |
197 | "option.")); | |
ef416fc2 | 198 | return (1); |
199 | } | |
200 | ||
201 | cupsSetServer(argv[i]); | |
202 | } | |
203 | break; | |
204 | ||
205 | case 'i' : /* Use the specified interface script */ | |
ef416fc2 | 206 | if (argv[i][2]) |
7cf5915e | 207 | file = argv[i] + 2; |
ef416fc2 | 208 | else |
209 | { | |
210 | i ++; | |
211 | ||
212 | if (i >= argc) | |
213 | { | |
fa73b229 | 214 | _cupsLangPuts(stderr, |
0837b7e8 MS |
215 | _("lpadmin: Expected interface after \"-i\" " |
216 | "option.")); | |
ef416fc2 | 217 | return (1); |
218 | } | |
219 | ||
7cf5915e | 220 | file = argv[i]; |
ef416fc2 | 221 | } |
222 | break; | |
223 | ||
224 | case 'E' : /* Enable the printer */ | |
225 | if (printer == NULL) | |
226 | { | |
227 | #ifdef HAVE_SSL | |
228 | cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); | |
229 | ||
230 | if (http) | |
231 | httpEncryption(http, HTTP_ENCRYPT_REQUIRED); | |
232 | #else | |
0837b7e8 | 233 | _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), |
ef416fc2 | 234 | argv[0]); |
235 | #endif /* HAVE_SSL */ | |
236 | break; | |
237 | } | |
238 | ||
239 | if (!http) | |
240 | { | |
241 | http = httpConnectEncrypt(cupsServer(), ippPort(), | |
242 | cupsEncryption()); | |
243 | ||
244 | if (http == NULL) | |
245 | { | |
fa73b229 | 246 | _cupsLangPrintf(stderr, |
0837b7e8 | 247 | _("lpadmin: Unable to connect to server: %s"), |
ef416fc2 | 248 | strerror(errno)); |
249 | return (1); | |
250 | } | |
251 | } | |
252 | ||
253 | if (enable_printer(http, printer)) | |
254 | return (1); | |
255 | break; | |
256 | ||
257 | case 'm' : /* Use the specified standard script/PPD file */ | |
ef416fc2 | 258 | if (argv[i][2]) |
7cf5915e MS |
259 | num_options = cupsAddOption("ppd-name", argv[i] + 2, num_options, |
260 | &options); | |
ef416fc2 | 261 | else |
262 | { | |
263 | i ++; | |
264 | ||
265 | if (i >= argc) | |
266 | { | |
fa73b229 | 267 | _cupsLangPuts(stderr, |
0837b7e8 MS |
268 | _("lpadmin: Expected model after \"-m\" " |
269 | "option.")); | |
ef416fc2 | 270 | return (1); |
271 | } | |
272 | ||
7cf5915e MS |
273 | num_options = cupsAddOption("ppd-name", argv[i], num_options, |
274 | &options); | |
ef416fc2 | 275 | } |
276 | break; | |
277 | ||
278 | case 'o' : /* Set option */ | |
279 | if (argv[i][2]) | |
280 | num_options = cupsParseOptions(argv[i] + 2, num_options, &options); | |
281 | else | |
282 | { | |
283 | i ++; | |
284 | ||
285 | if (i >= argc) | |
286 | { | |
fa73b229 | 287 | _cupsLangPuts(stderr, |
0837b7e8 MS |
288 | _("lpadmin: Expected name=value after \"-o\" " |
289 | "option.")); | |
ef416fc2 | 290 | return (1); |
291 | } | |
292 | ||
293 | num_options = cupsParseOptions(argv[i], num_options, &options); | |
294 | } | |
295 | break; | |
296 | ||
297 | case 'p' : /* Add/modify a printer */ | |
ef416fc2 | 298 | if (argv[i][2]) |
299 | printer = argv[i] + 2; | |
300 | else | |
301 | { | |
302 | i ++; | |
303 | ||
304 | if (i >= argc) | |
305 | { | |
fa73b229 | 306 | _cupsLangPuts(stderr, |
0837b7e8 MS |
307 | _("lpadmin: Expected printer after \"-p\" " |
308 | "option.")); | |
ef416fc2 | 309 | return (1); |
310 | } | |
311 | ||
312 | printer = argv[i]; | |
313 | } | |
314 | ||
315 | if (!validate_name(printer)) | |
316 | { | |
fa73b229 | 317 | _cupsLangPuts(stderr, |
ef416fc2 | 318 | _("lpadmin: Printer name can only contain " |
0837b7e8 | 319 | "printable characters.")); |
ef416fc2 | 320 | return (1); |
321 | } | |
322 | break; | |
323 | ||
324 | case 'r' : /* Remove printer from class */ | |
325 | if (!http) | |
326 | { | |
327 | http = httpConnectEncrypt(cupsServer(), ippPort(), | |
328 | cupsEncryption()); | |
329 | ||
330 | if (http == NULL) | |
331 | { | |
fa73b229 | 332 | _cupsLangPrintf(stderr, |
0837b7e8 | 333 | _("lpadmin: Unable to connect to server: %s"), |
ef416fc2 | 334 | strerror(errno)); |
335 | return (1); | |
336 | } | |
337 | } | |
338 | ||
339 | if (printer == NULL) | |
340 | { | |
fa73b229 | 341 | _cupsLangPuts(stderr, |
ef416fc2 | 342 | _("lpadmin: Unable to remove a printer from the " |
343 | "class:\n" | |
344 | " You must specify a printer name " | |
0837b7e8 | 345 | "first.")); |
ef416fc2 | 346 | return (1); |
347 | } | |
348 | ||
349 | if (argv[i][2]) | |
350 | pclass = argv[i] + 2; | |
351 | else | |
352 | { | |
353 | i ++; | |
354 | ||
355 | if (i >= argc) | |
356 | { | |
fa73b229 | 357 | _cupsLangPuts(stderr, |
0837b7e8 MS |
358 | _("lpadmin: Expected class after \"-r\" " |
359 | "option.")); | |
ef416fc2 | 360 | return (1); |
361 | } | |
362 | ||
363 | pclass = argv[i]; | |
364 | } | |
365 | ||
366 | if (!validate_name(pclass)) | |
367 | { | |
fa73b229 | 368 | _cupsLangPuts(stderr, |
ef416fc2 | 369 | _("lpadmin: Class name can only contain printable " |
0837b7e8 | 370 | "characters.")); |
ef416fc2 | 371 | return (1); |
372 | } | |
373 | ||
374 | if (delete_printer_from_class(http, printer, pclass)) | |
375 | return (1); | |
376 | break; | |
377 | ||
f301802f | 378 | case 'U' : /* Username */ |
379 | if (argv[i][2] != '\0') | |
380 | cupsSetUser(argv[i] + 2); | |
381 | else | |
382 | { | |
383 | i ++; | |
384 | if (i >= argc) | |
385 | { | |
386 | _cupsLangPrintf(stderr, | |
387 | _("%s: Error - expected username after " | |
0837b7e8 | 388 | "\"-U\" option."), argv[0]); |
f301802f | 389 | return (1); |
390 | } | |
391 | ||
392 | cupsSetUser(argv[i]); | |
393 | } | |
394 | break; | |
395 | ||
ef416fc2 | 396 | case 'u' : /* Allow/deny users */ |
397 | if (argv[i][2]) | |
398 | val = argv[i] + 2; | |
399 | else | |
400 | { | |
401 | i ++; | |
402 | ||
403 | if (i >= argc) | |
404 | { | |
fa73b229 | 405 | _cupsLangPuts(stderr, |
ef416fc2 | 406 | _("lpadmin: Expected allow/deny:userlist after " |
0837b7e8 | 407 | "\"-u\" option.")); |
ef416fc2 | 408 | return (1); |
409 | } | |
410 | ||
411 | val = argv[i]; | |
412 | } | |
413 | ||
414 | if (!strncasecmp(val, "allow:", 6)) | |
415 | num_options = cupsAddOption("requesting-user-name-allowed", | |
416 | val + 6, num_options, &options); | |
417 | else if (!strncasecmp(val, "deny:", 5)) | |
418 | num_options = cupsAddOption("requesting-user-name-denied", | |
419 | val + 5, num_options, &options); | |
420 | else | |
421 | { | |
fa73b229 | 422 | _cupsLangPrintf(stderr, |
0837b7e8 | 423 | _("lpadmin: Unknown allow/deny option \"%s\"."), |
ef416fc2 | 424 | val); |
425 | return (1); | |
426 | } | |
427 | break; | |
428 | ||
429 | case 'v' : /* Set the device-uri attribute */ | |
ef416fc2 | 430 | if (argv[i][2]) |
7cf5915e MS |
431 | num_options = cupsAddOption("device-uri", argv[i] + 2, |
432 | num_options, &options); | |
ef416fc2 | 433 | else |
434 | { | |
435 | i ++; | |
436 | ||
437 | if (i >= argc) | |
438 | { | |
fa73b229 | 439 | _cupsLangPuts(stderr, |
0837b7e8 MS |
440 | _("lpadmin: Expected device URI after \"-v\" " |
441 | "option.")); | |
ef416fc2 | 442 | return (1); |
443 | } | |
444 | ||
7cf5915e MS |
445 | num_options = cupsAddOption("device-uri", argv[i], |
446 | num_options, &options); | |
ef416fc2 | 447 | } |
448 | break; | |
449 | ||
450 | case 'x' : /* Delete a printer */ | |
451 | if (!http) | |
452 | { | |
453 | http = httpConnectEncrypt(cupsServer(), ippPort(), | |
454 | cupsEncryption()); | |
455 | ||
456 | if (http == NULL) | |
457 | { | |
fa73b229 | 458 | _cupsLangPrintf(stderr, |
0837b7e8 | 459 | _("lpadmin: Unable to connect to server: %s"), |
ef416fc2 | 460 | strerror(errno)); |
461 | return (1); | |
462 | } | |
463 | } | |
464 | ||
465 | if (argv[i][2]) | |
466 | printer = argv[i] + 2; | |
467 | else | |
468 | { | |
469 | i ++; | |
470 | ||
471 | if (i >= argc) | |
472 | { | |
fa73b229 | 473 | _cupsLangPuts(stderr, |
ef416fc2 | 474 | _("lpadmin: Expected printer or class after " |
0837b7e8 | 475 | "\"-x\" option.")); |
ef416fc2 | 476 | return (1); |
477 | } | |
478 | ||
479 | printer = argv[i]; | |
480 | } | |
481 | ||
482 | if (!validate_name(printer)) | |
483 | { | |
fa73b229 | 484 | _cupsLangPuts(stderr, |
ef416fc2 | 485 | _("lpadmin: Printer name can only contain " |
0837b7e8 | 486 | "printable characters.")); |
ef416fc2 | 487 | return (1); |
488 | } | |
489 | ||
490 | if (delete_printer(http, printer)) | |
491 | return (1); | |
492 | ||
493 | i = argc; | |
494 | break; | |
495 | ||
496 | case 'D' : /* Set the printer-info attribute */ | |
ef416fc2 | 497 | if (argv[i][2]) |
7cf5915e MS |
498 | num_options = cupsAddOption("printer-info", argv[i] + 2, |
499 | num_options, &options); | |
ef416fc2 | 500 | else |
501 | { | |
502 | i ++; | |
503 | ||
504 | if (i >= argc) | |
505 | { | |
fa73b229 | 506 | _cupsLangPuts(stderr, |
ef416fc2 | 507 | _("lpadmin: Expected description after " |
0837b7e8 | 508 | "\"-D\" option.")); |
ef416fc2 | 509 | return (1); |
510 | } | |
511 | ||
7cf5915e MS |
512 | num_options = cupsAddOption("printer-info", argv[i], |
513 | num_options, &options); | |
ef416fc2 | 514 | } |
515 | break; | |
516 | ||
517 | case 'I' : /* Set the supported file types (ignored) */ | |
518 | i ++; | |
519 | ||
520 | if (i >= argc) | |
521 | { | |
fa73b229 | 522 | _cupsLangPuts(stderr, |
0837b7e8 MS |
523 | _("lpadmin: Expected file type(s) after \"-I\" " |
524 | "option.")); | |
ef416fc2 | 525 | return (1); |
526 | } | |
527 | ||
fa73b229 | 528 | _cupsLangPuts(stderr, |
0837b7e8 | 529 | _("lpadmin: Warning - content type list ignored.")); |
ef416fc2 | 530 | break; |
531 | ||
532 | case 'L' : /* Set the printer-location attribute */ | |
ef416fc2 | 533 | if (argv[i][2]) |
7cf5915e MS |
534 | num_options = cupsAddOption("printer-location", argv[i] + 2, |
535 | num_options, &options); | |
ef416fc2 | 536 | else |
537 | { | |
538 | i ++; | |
539 | ||
540 | if (i >= argc) | |
541 | { | |
fa73b229 | 542 | _cupsLangPuts(stderr, |
0837b7e8 MS |
543 | _("lpadmin: Expected location after \"-L\" " |
544 | "option.")); | |
ef416fc2 | 545 | return (1); |
546 | } | |
547 | ||
7cf5915e MS |
548 | num_options = cupsAddOption("printer-location", argv[i], |
549 | num_options, &options); | |
ef416fc2 | 550 | } |
551 | break; | |
552 | ||
553 | case 'P' : /* Use the specified PPD file */ | |
ef416fc2 | 554 | if (argv[i][2]) |
7cf5915e | 555 | file = argv[i] + 2; |
ef416fc2 | 556 | else |
557 | { | |
558 | i ++; | |
559 | ||
560 | if (i >= argc) | |
561 | { | |
fa73b229 | 562 | _cupsLangPuts(stderr, |
0837b7e8 | 563 | _("lpadmin: Expected PPD after \"-P\" option.")); |
ef416fc2 | 564 | return (1); |
565 | } | |
566 | ||
7cf5915e | 567 | file = argv[i]; |
ef416fc2 | 568 | } |
569 | break; | |
570 | ||
571 | default : | |
fa73b229 | 572 | _cupsLangPrintf(stderr, |
0837b7e8 | 573 | _("lpadmin: Unknown option \"%c\"."), argv[i][1]); |
ef416fc2 | 574 | return (1); |
575 | } | |
576 | else | |
577 | { | |
0837b7e8 | 578 | _cupsLangPrintf(stderr, _("lpadmin: Unknown argument \"%s\"."), |
ef416fc2 | 579 | argv[i]); |
580 | return (1); | |
581 | } | |
582 | ||
583 | /* | |
584 | * Set options as needed... | |
585 | */ | |
586 | ||
7cf5915e | 587 | if (num_options || file) |
ef416fc2 | 588 | { |
589 | if (!http) | |
590 | { | |
591 | http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); | |
592 | ||
593 | if (http == NULL) | |
594 | { | |
fa73b229 | 595 | _cupsLangPrintf(stderr, |
0837b7e8 | 596 | _("lpadmin: Unable to connect to server: %s"), |
ef416fc2 | 597 | strerror(errno)); |
598 | return (1); | |
599 | } | |
600 | } | |
601 | ||
602 | if (printer == NULL) | |
603 | { | |
fa73b229 | 604 | _cupsLangPuts(stderr, |
ef416fc2 | 605 | _("lpadmin: Unable to set the printer options:\n" |
0837b7e8 | 606 | " You must specify a printer name first.")); |
ef416fc2 | 607 | return (1); |
608 | } | |
609 | ||
7cf5915e | 610 | if (set_printer_options(http, printer, num_options, options, file)) |
ef416fc2 | 611 | return (1); |
612 | } | |
613 | ||
614 | if (printer == NULL) | |
615 | { | |
fa73b229 | 616 | _cupsLangPuts(stdout, |
ef416fc2 | 617 | _("Usage:\n" |
618 | "\n" | |
619 | " lpadmin [-h server] -d destination\n" | |
620 | " lpadmin [-h server] -x destination\n" | |
621 | " lpadmin [-h server] -p printer [-c add-class] " | |
622 | "[-i interface] [-m model]\n" | |
623 | " [-r remove-class] [-v device] " | |
624 | "[-D description]\n" | |
625 | " [-P ppd-file] [-o name=value]\n" | |
626 | " [-u allow:user,user] " | |
0837b7e8 | 627 | "[-u deny:user,user]")); |
ef416fc2 | 628 | } |
629 | ||
630 | if (http) | |
631 | httpClose(http); | |
632 | ||
633 | return (0); | |
634 | } | |
635 | ||
636 | ||
637 | /* | |
638 | * 'add_printer_to_class()' - Add a printer to a class. | |
639 | */ | |
640 | ||
641 | static int /* O - 0 on success, 1 on fail */ | |
642 | add_printer_to_class(http_t *http, /* I - Server connection */ | |
643 | char *printer, /* I - Printer to add */ | |
644 | char *pclass) /* I - Class to add to */ | |
645 | { | |
646 | int i; /* Looping var */ | |
647 | ipp_t *request, /* IPP Request */ | |
648 | *response; /* IPP Response */ | |
649 | ipp_attribute_t *attr, /* Current attribute */ | |
650 | *members; /* Members in class */ | |
ef416fc2 | 651 | char uri[HTTP_MAX_URI]; /* URI for printer/class */ |
652 | ||
653 | ||
654 | DEBUG_printf(("add_printer_to_class(%p, \"%s\", \"%s\")\n", http, | |
655 | printer, pclass)); | |
656 | ||
657 | /* | |
658 | * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following | |
659 | * attributes: | |
660 | * | |
661 | * attributes-charset | |
662 | * attributes-natural-language | |
663 | * printer-uri | |
664 | */ | |
665 | ||
fa73b229 | 666 | request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); |
667 | ||
a4d04587 | 668 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
669 | "localhost", 0, "/classes/%s", pclass); | |
ef416fc2 | 670 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, |
671 | "printer-uri", NULL, uri); | |
672 | ||
673 | /* | |
674 | * Do the request and get back a response... | |
675 | */ | |
676 | ||
677 | response = cupsDoRequest(http, request, "/"); | |
678 | ||
679 | /* | |
680 | * Build a CUPS_ADD_CLASS request, which requires the following | |
681 | * attributes: | |
682 | * | |
683 | * attributes-charset | |
684 | * attributes-natural-language | |
685 | * printer-uri | |
686 | * member-uris | |
687 | */ | |
688 | ||
fa73b229 | 689 | request = ippNewRequest(CUPS_ADD_CLASS); |
ef416fc2 | 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 | { | |
fa73b229 | 703 | _cupsLangPrintf(stderr, |
0837b7e8 MS |
704 | _("lpadmin: Printer %s is already a member of class " |
705 | "%s."), printer, pclass); | |
ef416fc2 | 706 | ippDelete(request); |
707 | ippDelete(response); | |
708 | return (0); | |
709 | } | |
710 | ||
711 | /* | |
712 | * OK, the printer isn't part of the class, so add it... | |
713 | */ | |
714 | ||
a4d04587 | 715 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
716 | "localhost", 0, "/printers/%s", printer); | |
ef416fc2 | 717 | |
718 | if (response != NULL && | |
719 | (members = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL) | |
720 | { | |
721 | /* | |
722 | * Add the printer to the existing list... | |
723 | */ | |
724 | ||
725 | attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI, | |
726 | "member-uris", members->num_values + 1, NULL, NULL); | |
727 | for (i = 0; i < members->num_values; i ++) | |
1f0275e3 | 728 | attr->values[i].string.text = _cupsStrAlloc(members->values[i].string.text); |
ef416fc2 | 729 | |
1f0275e3 | 730 | attr->values[i].string.text = _cupsStrAlloc(uri); |
ef416fc2 | 731 | } |
732 | else | |
1f0275e3 MS |
733 | ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris", NULL, |
734 | uri); | |
ef416fc2 | 735 | |
736 | /* | |
737 | * Then send the request... | |
738 | */ | |
739 | ||
740 | ippDelete(response); | |
741 | ||
742 | if ((response = cupsDoRequest(http, request, "/admin/")) == NULL) | |
743 | { | |
0837b7e8 | 744 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
ef416fc2 | 745 | |
746 | return (1); | |
747 | } | |
748 | else if (response->request.status.status_code > IPP_OK_CONFLICT) | |
749 | { | |
0837b7e8 | 750 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
ef416fc2 | 751 | |
752 | ippDelete(response); | |
753 | ||
754 | return (1); | |
755 | } | |
756 | else | |
757 | { | |
758 | ippDelete(response); | |
759 | ||
760 | return (0); | |
761 | } | |
762 | } | |
763 | ||
764 | ||
765 | /* | |
766 | * 'default_printer()' - Set the default printing destination. | |
767 | */ | |
768 | ||
769 | static int /* O - 0 on success, 1 on fail */ | |
770 | default_printer(http_t *http, /* I - Server connection */ | |
771 | char *printer) /* I - Printer name */ | |
772 | { | |
773 | ipp_t *request, /* IPP Request */ | |
774 | *response; /* IPP Response */ | |
ef416fc2 | 775 | char uri[HTTP_MAX_URI]; /* URI for printer/class */ |
776 | ||
777 | ||
778 | DEBUG_printf(("default_printer(%p, \"%s\")\n", http, printer)); | |
779 | ||
780 | /* | |
781 | * Build a CUPS_SET_DEFAULT request, which requires the following | |
782 | * attributes: | |
783 | * | |
784 | * attributes-charset | |
785 | * attributes-natural-language | |
786 | * printer-uri | |
787 | */ | |
788 | ||
a4d04587 | 789 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
790 | "localhost", 0, "/printers/%s", printer); | |
ef416fc2 | 791 | |
fa73b229 | 792 | request = ippNewRequest(CUPS_SET_DEFAULT); |
ef416fc2 | 793 | |
794 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, | |
795 | "printer-uri", NULL, uri); | |
796 | ||
797 | /* | |
798 | * Do the request and get back a response... | |
799 | */ | |
800 | ||
801 | if ((response = cupsDoRequest(http, request, "/admin/")) == NULL) | |
802 | { | |
0837b7e8 | 803 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
ef416fc2 | 804 | |
805 | return (1); | |
806 | } | |
807 | else if (response->request.status.status_code > IPP_OK_CONFLICT) | |
808 | { | |
0837b7e8 | 809 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
ef416fc2 | 810 | |
811 | ippDelete(response); | |
812 | ||
813 | return (1); | |
814 | } | |
815 | else | |
816 | { | |
817 | ippDelete(response); | |
818 | ||
819 | return (0); | |
820 | } | |
821 | } | |
822 | ||
823 | ||
824 | /* | |
825 | * 'delete_printer()' - Delete a printer from the system... | |
826 | */ | |
827 | ||
828 | static int /* O - 0 on success, 1 on fail */ | |
829 | delete_printer(http_t *http, /* I - Server connection */ | |
830 | char *printer) /* I - Printer to delete */ | |
831 | { | |
832 | ipp_t *request, /* IPP Request */ | |
833 | *response; /* IPP Response */ | |
ef416fc2 | 834 | char uri[HTTP_MAX_URI]; /* URI for printer/class */ |
835 | ||
836 | ||
837 | DEBUG_printf(("delete_printer(%p, \"%s\")\n", http, printer)); | |
838 | ||
839 | /* | |
840 | * Build a CUPS_DELETE_PRINTER request, which requires the following | |
841 | * attributes: | |
842 | * | |
843 | * attributes-charset | |
844 | * attributes-natural-language | |
845 | * printer-uri | |
846 | */ | |
847 | ||
fa73b229 | 848 | request = ippNewRequest(CUPS_DELETE_PRINTER); |
849 | ||
a4d04587 | 850 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
851 | "localhost", 0, "/printers/%s", printer); | |
ef416fc2 | 852 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, |
853 | "printer-uri", NULL, uri); | |
854 | ||
855 | /* | |
856 | * Do the request and get back a response... | |
857 | */ | |
858 | ||
859 | if ((response = cupsDoRequest(http, request, "/admin/")) == NULL) | |
860 | { | |
0837b7e8 | 861 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
ef416fc2 | 862 | |
863 | return (1); | |
864 | } | |
865 | else if (response->request.status.status_code > IPP_OK_CONFLICT) | |
866 | { | |
0837b7e8 | 867 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
ef416fc2 | 868 | |
869 | ippDelete(response); | |
870 | ||
871 | return (1); | |
872 | } | |
873 | else | |
874 | { | |
875 | ippDelete(response); | |
876 | ||
877 | return (0); | |
878 | } | |
879 | } | |
880 | ||
881 | ||
882 | /* | |
883 | * 'delete_printer_from_class()' - Delete a printer from a class. | |
884 | */ | |
885 | ||
886 | static int /* O - 0 on success, 1 on fail */ | |
fa73b229 | 887 | delete_printer_from_class( |
888 | http_t *http, /* I - Server connection */ | |
889 | char *printer, /* I - Printer to remove */ | |
890 | char *pclass) /* I - Class to remove from */ | |
ef416fc2 | 891 | { |
892 | int i, j, k; /* Looping vars */ | |
893 | ipp_t *request, /* IPP Request */ | |
894 | *response; /* IPP Response */ | |
895 | ipp_attribute_t *attr, /* Current attribute */ | |
896 | *members; /* Members in class */ | |
ef416fc2 | 897 | char uri[HTTP_MAX_URI]; /* URI for printer/class */ |
898 | ||
899 | ||
900 | DEBUG_printf(("delete_printer_from_class(%p, \"%s\", \"%s\")\n", http, | |
901 | printer, pclass)); | |
902 | ||
903 | /* | |
904 | * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following | |
905 | * attributes: | |
906 | * | |
907 | * attributes-charset | |
908 | * attributes-natural-language | |
909 | * printer-uri | |
910 | */ | |
911 | ||
fa73b229 | 912 | request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); |
913 | ||
a4d04587 | 914 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
915 | "localhost", 0, "/classes/%s", pclass); | |
ef416fc2 | 916 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, |
917 | "printer-uri", NULL, uri); | |
918 | ||
919 | /* | |
920 | * Do the request and get back a response... | |
921 | */ | |
922 | ||
923 | if ((response = cupsDoRequest(http, request, "/classes/")) == NULL || | |
924 | response->request.status.status_code == IPP_NOT_FOUND) | |
925 | { | |
0837b7e8 | 926 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
fa73b229 | 927 | |
ef416fc2 | 928 | ippDelete(response); |
fa73b229 | 929 | |
ef416fc2 | 930 | return (1); |
931 | } | |
932 | ||
933 | /* | |
934 | * See if the printer is already in the class... | |
935 | */ | |
936 | ||
937 | if ((members = ippFindAttribute(response, "member-names", IPP_TAG_NAME)) == NULL) | |
938 | { | |
0837b7e8 | 939 | _cupsLangPuts(stderr, _("lpadmin: No member names were seen.")); |
fa73b229 | 940 | |
ef416fc2 | 941 | ippDelete(response); |
fa73b229 | 942 | |
ef416fc2 | 943 | return (1); |
944 | } | |
945 | ||
946 | for (i = 0; i < members->num_values; i ++) | |
fa73b229 | 947 | if (!strcasecmp(printer, members->values[i].string.text)) |
ef416fc2 | 948 | break; |
949 | ||
950 | if (i >= members->num_values) | |
951 | { | |
fa73b229 | 952 | _cupsLangPrintf(stderr, |
0837b7e8 | 953 | _("lpadmin: Printer %s is not a member of class %s."), |
fa73b229 | 954 | printer, pclass); |
955 | ||
ef416fc2 | 956 | ippDelete(response); |
fa73b229 | 957 | |
ef416fc2 | 958 | return (1); |
959 | } | |
960 | ||
961 | if (members->num_values == 1) | |
962 | { | |
963 | /* | |
964 | * Build a CUPS_DELETE_CLASS request, which requires the following | |
965 | * attributes: | |
966 | * | |
967 | * attributes-charset | |
968 | * attributes-natural-language | |
969 | * printer-uri | |
970 | */ | |
971 | ||
fa73b229 | 972 | request = ippNewRequest(CUPS_DELETE_CLASS); |
ef416fc2 | 973 | |
974 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, | |
975 | "printer-uri", NULL, uri); | |
976 | } | |
977 | else | |
978 | { | |
979 | /* | |
980 | * Build a CUPS_ADD_CLASS request, which requires the following | |
981 | * attributes: | |
982 | * | |
983 | * attributes-charset | |
984 | * attributes-natural-language | |
985 | * printer-uri | |
986 | * member-uris | |
987 | */ | |
988 | ||
fa73b229 | 989 | request = ippNewRequest(CUPS_ADD_CLASS); |
ef416fc2 | 990 | |
991 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, | |
992 | "printer-uri", NULL, uri); | |
993 | ||
994 | /* | |
995 | * Delete the printer from the class... | |
996 | */ | |
997 | ||
998 | members = ippFindAttribute(response, "member-uris", IPP_TAG_URI); | |
999 | attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI, | |
1000 | "member-uris", members->num_values - 1, NULL, NULL); | |
1001 | ||
1002 | for (j = 0, k = 0; j < members->num_values; j ++) | |
1003 | if (j != i) | |
1f0275e3 MS |
1004 | attr->values[k ++].string.text = |
1005 | _cupsStrAlloc(members->values[j].string.text); | |
ef416fc2 | 1006 | } |
1007 | ||
1008 | /* | |
1009 | * Then send the request... | |
1010 | */ | |
1011 | ||
1012 | ippDelete(response); | |
1013 | ||
1014 | if ((response = cupsDoRequest(http, request, "/admin/")) == NULL) | |
1015 | { | |
0837b7e8 | 1016 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
fa73b229 | 1017 | |
ef416fc2 | 1018 | return (1); |
1019 | } | |
1020 | else if (response->request.status.status_code > IPP_OK_CONFLICT) | |
1021 | { | |
0837b7e8 | 1022 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
ef416fc2 | 1023 | |
1024 | ippDelete(response); | |
1025 | ||
1026 | return (1); | |
1027 | } | |
1028 | else | |
1029 | { | |
1030 | ippDelete(response); | |
1031 | ||
1032 | return (0); | |
1033 | } | |
1034 | } | |
1035 | ||
1036 | ||
1037 | /* | |
1038 | * 'enable_printer()' - Enable a printer... | |
1039 | */ | |
1040 | ||
1041 | static int /* O - 0 on success, 1 on fail */ | |
1042 | enable_printer(http_t *http, /* I - Server connection */ | |
1043 | char *printer) /* I - Printer to enable */ | |
1044 | { | |
1045 | ipp_t *request, /* IPP Request */ | |
1046 | *response; /* IPP Response */ | |
ef416fc2 | 1047 | char uri[HTTP_MAX_URI]; /* URI for printer/class */ |
1048 | ||
1049 | ||
1050 | DEBUG_printf(("enable_printer(%p, \"%s\")\n", http, printer)); | |
1051 | ||
1052 | /* | |
1053 | * Build a CUPS_ADD_PRINTER request, which requires the following | |
1054 | * attributes: | |
1055 | * | |
1056 | * attributes-charset | |
1057 | * attributes-natural-language | |
1058 | * printer-uri | |
1059 | * printer-state | |
1060 | * printer-is-accepting-jobs | |
1061 | */ | |
1062 | ||
fa73b229 | 1063 | request = ippNewRequest(CUPS_ADD_PRINTER); |
1064 | ||
a4d04587 | 1065 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
1066 | "localhost", 0, "/printers/%s", printer); | |
ef416fc2 | 1067 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, |
1068 | "printer-uri", NULL, uri); | |
1069 | ||
1070 | ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state", | |
1071 | IPP_PRINTER_IDLE); | |
1072 | ||
1073 | ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1); | |
1074 | ||
1075 | /* | |
1076 | * Do the request and get back a response... | |
1077 | */ | |
1078 | ||
1079 | if ((response = cupsDoRequest(http, request, "/admin/")) == NULL) | |
1080 | { | |
0837b7e8 | 1081 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
fa73b229 | 1082 | |
ef416fc2 | 1083 | return (1); |
1084 | } | |
1085 | else if (response->request.status.status_code > IPP_OK_CONFLICT) | |
1086 | { | |
0837b7e8 | 1087 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
ef416fc2 | 1088 | |
1089 | ippDelete(response); | |
1090 | ||
1091 | return (1); | |
1092 | } | |
1093 | else | |
1094 | { | |
1095 | ippDelete(response); | |
1096 | ||
1097 | return (0); | |
1098 | } | |
1099 | } | |
1100 | ||
1101 | ||
ef416fc2 | 1102 | /* |
1103 | * 'set_printer_options()' - Set the printer options. | |
1104 | */ | |
1105 | ||
1106 | static int /* O - 0 on success, 1 on fail */ | |
fa73b229 | 1107 | set_printer_options( |
1108 | http_t *http, /* I - Server connection */ | |
1109 | char *printer, /* I - Printer */ | |
1110 | int num_options, /* I - Number of options */ | |
7cf5915e MS |
1111 | cups_option_t *options, /* I - Options */ |
1112 | char *file) /* I - PPD file/interface script */ | |
ef416fc2 | 1113 | { |
1114 | ipp_t *request, /* IPP Request */ | |
1115 | *response; /* IPP Response */ | |
1116 | ipp_attribute_t *attr; /* IPP attribute */ | |
ef416fc2 | 1117 | ipp_op_t op; /* Operation to perform */ |
b423cd4c | 1118 | const char *ppdfile; /* PPD filename */ |
1119 | int ppdchanged; /* PPD changed? */ | |
1120 | ppd_file_t *ppd; /* PPD file */ | |
1121 | ppd_choice_t *choice; /* Marked choice */ | |
ef416fc2 | 1122 | char uri[HTTP_MAX_URI], /* URI for printer/class */ |
1123 | line[1024], /* Line from PPD file */ | |
1124 | keyword[1024], /* Keyword from Default line */ | |
1125 | *keyptr, /* Pointer into keyword... */ | |
1126 | tempfile[1024]; /* Temporary filename */ | |
7cf5915e | 1127 | cups_file_t *in, /* PPD file */ |
ef416fc2 | 1128 | *out; /* Temporary file */ |
7cf5915e MS |
1129 | const char *protocol, /* Old protocol option */ |
1130 | *customval; /* Custom option value */ | |
ef416fc2 | 1131 | |
1132 | ||
7cf5915e MS |
1133 | DEBUG_printf(("set_printer_options(http=%p, printer=\"%s\", num_options=%d, " |
1134 | "options=%p, file=\"%s\")\n", http, printer, num_options, | |
1135 | options, file)); | |
ef416fc2 | 1136 | |
a4d04587 | 1137 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
1138 | "localhost", 0, "/printers/%s", printer); | |
ef416fc2 | 1139 | |
1140 | /* | |
1141 | * Build a GET_PRINTER_ATTRIBUTES request, which requires the following | |
1142 | * attributes: | |
1143 | * | |
1144 | * attributes-charset | |
1145 | * attributes-natural-language | |
1146 | * printer-uri | |
1147 | * requested-attributes | |
1148 | */ | |
1149 | ||
fa73b229 | 1150 | request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); |
ef416fc2 | 1151 | |
1152 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, | |
1153 | "printer-uri", NULL, uri); | |
ef416fc2 | 1154 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, |
1155 | "requested-attributes", NULL, "printer-type"); | |
1156 | ||
1157 | /* | |
1158 | * Do the request... | |
1159 | */ | |
1160 | ||
7cf5915e | 1161 | op = CUPS_ADD_MODIFY_PRINTER; |
ef416fc2 | 1162 | |
1163 | if ((response = cupsDoRequest(http, request, "/")) != NULL) | |
1164 | { | |
1165 | /* | |
1166 | * See what kind of printer or class it is... | |
1167 | */ | |
1168 | ||
b423cd4c | 1169 | if ((attr = ippFindAttribute(response, "printer-type", |
1170 | IPP_TAG_ENUM)) != NULL) | |
ef416fc2 | 1171 | { |
1172 | if (attr->values[0].integer & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT)) | |
1173 | { | |
7cf5915e | 1174 | op = CUPS_ADD_MODIFY_CLASS; |
a4d04587 | 1175 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
1176 | "localhost", 0, "/classes/%s", printer); | |
ef416fc2 | 1177 | } |
1178 | } | |
1179 | ||
1180 | ippDelete(response); | |
1181 | } | |
1182 | ||
1183 | /* | |
7cf5915e MS |
1184 | * Build a CUPS_ADD_MODIFY_PRINTER or CUPS_ADD_MODIFY_CLASS request, which |
1185 | * requires the following attributes: | |
ef416fc2 | 1186 | * |
1187 | * attributes-charset | |
1188 | * attributes-natural-language | |
1189 | * printer-uri | |
1190 | * other options | |
1191 | */ | |
1192 | ||
fa73b229 | 1193 | request = ippNewRequest(op); |
ef416fc2 | 1194 | |
1195 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, | |
1196 | "printer-uri", NULL, uri); | |
7cf5915e MS |
1197 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, |
1198 | "requesting-user-name", NULL, cupsUser()); | |
ef416fc2 | 1199 | |
1200 | /* | |
1201 | * Add the options... | |
1202 | */ | |
1203 | ||
b423cd4c | 1204 | cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER); |
1205 | ||
1206 | if ((protocol = cupsGetOption("protocol", num_options, options)) != NULL) | |
1207 | { | |
1208 | if (!strcasecmp(protocol, "bcp")) | |
a41f09e2 | 1209 | ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "port-monitor", |
b423cd4c | 1210 | NULL, "bcp"); |
1211 | else if (!strcasecmp(protocol, "tbcp")) | |
a41f09e2 | 1212 | ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "port-monitor", |
b423cd4c | 1213 | NULL, "tbcp"); |
1214 | } | |
ef416fc2 | 1215 | |
7cf5915e MS |
1216 | if (file) |
1217 | ppdfile = file; | |
1218 | else if (op == CUPS_ADD_MODIFY_PRINTER) | |
ef416fc2 | 1219 | ppdfile = cupsGetPPD(printer); |
1220 | else | |
1221 | ppdfile = NULL; | |
1222 | ||
1223 | if (ppdfile != NULL) | |
1224 | { | |
1225 | /* | |
1226 | * Set default options in the PPD file... | |
1227 | */ | |
1228 | ||
b423cd4c | 1229 | ppd = ppdOpenFile(ppdfile); |
1230 | ppdMarkDefaults(ppd); | |
1231 | cupsMarkOptions(ppd, num_options, options); | |
1232 | ||
7cf5915e | 1233 | if ((out = cupsTempFile2(tempfile, sizeof(tempfile))) < 0) |
ef416fc2 | 1234 | { |
0837b7e8 | 1235 | _cupsLangPrintError(NULL, _("lpadmin: Unable to create temporary file")); |
ef416fc2 | 1236 | ippDelete(request); |
7cf5915e MS |
1237 | if (ppdfile != file) |
1238 | unlink(ppdfile); | |
ef416fc2 | 1239 | return (1); |
1240 | } | |
1241 | ||
7cf5915e | 1242 | if ((in = cupsFileOpen(ppdfile, "r")) == NULL) |
ef416fc2 | 1243 | { |
fa73b229 | 1244 | _cupsLangPrintf(stderr, |
0837b7e8 | 1245 | _("lpadmin: Unable to open PPD file \"%s\" - %s"), |
ef416fc2 | 1246 | ppdfile, strerror(errno)); |
1247 | ippDelete(request); | |
7cf5915e MS |
1248 | if (ppdfile != file) |
1249 | unlink(ppdfile); | |
1250 | cupsFileClose(out); | |
ef416fc2 | 1251 | unlink(tempfile); |
1252 | return (1); | |
1253 | } | |
1254 | ||
b423cd4c | 1255 | ppdchanged = 0; |
ef416fc2 | 1256 | |
7cf5915e | 1257 | while (cupsFileGets(in, line, sizeof(line))) |
ef416fc2 | 1258 | { |
b423cd4c | 1259 | if (strncmp(line, "*Default", 8)) |
7cf5915e | 1260 | cupsFilePrintf(out, "%s\n", line); |
ef416fc2 | 1261 | else |
1262 | { | |
1263 | /* | |
1264 | * Get default option name... | |
1265 | */ | |
1266 | ||
1267 | strlcpy(keyword, line + 8, sizeof(keyword)); | |
1268 | ||
1269 | for (keyptr = keyword; *keyptr; keyptr ++) | |
1270 | if (*keyptr == ':' || isspace(*keyptr & 255)) | |
1271 | break; | |
1272 | ||
b423cd4c | 1273 | *keyptr++ = '\0'; |
1274 | while (isspace(*keyptr & 255)) | |
1275 | keyptr ++; | |
1276 | ||
1277 | if (!strcmp(keyword, "PageRegion") || | |
1278 | !strcmp(keyword, "PageSize") || | |
1279 | !strcmp(keyword, "PaperDimension") || | |
1280 | !strcmp(keyword, "ImageableArea")) | |
1281 | { | |
1282 | if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) == NULL) | |
1283 | choice = ppdFindMarkedChoice(ppd, "PageRegion"); | |
1284 | } | |
ef416fc2 | 1285 | else |
b423cd4c | 1286 | choice = ppdFindMarkedChoice(ppd, keyword); |
ef416fc2 | 1287 | |
b423cd4c | 1288 | if (choice && strcmp(choice->choice, keyptr)) |
1289 | { | |
7cf5915e MS |
1290 | if (strcmp(choice->choice, "Custom")) |
1291 | { | |
1292 | cupsFilePrintf(out, "*Default%s: %s\n", keyword, choice->choice); | |
1293 | ppdchanged = 1; | |
1294 | } | |
1295 | else if ((customval = cupsGetOption(keyword, num_options, | |
1296 | options)) != NULL) | |
1297 | { | |
1298 | cupsFilePrintf(out, "*Default%s: %s\n", keyword, customval); | |
1299 | ppdchanged = 1; | |
1300 | } | |
1301 | else | |
1302 | cupsFilePrintf(out, "%s\n", line); | |
b423cd4c | 1303 | } |
ef416fc2 | 1304 | else |
7cf5915e | 1305 | cupsFilePrintf(out, "%s\n", line); |
ef416fc2 | 1306 | } |
1307 | } | |
1308 | ||
7cf5915e MS |
1309 | cupsFileClose(in); |
1310 | cupsFileClose(out); | |
b423cd4c | 1311 | ppdClose(ppd); |
ef416fc2 | 1312 | |
1313 | /* | |
1314 | * Do the request... | |
1315 | */ | |
1316 | ||
b423cd4c | 1317 | ippDelete(cupsDoFileRequest(http, request, "/admin/", |
7cf5915e | 1318 | ppdchanged ? tempfile : file)); |
ef416fc2 | 1319 | |
1320 | /* | |
1321 | * Clean up temp files... (TODO: catch signals in case we CTRL-C during | |
1322 | * lpadmin) | |
1323 | */ | |
1324 | ||
7cf5915e MS |
1325 | if (ppdfile != file) |
1326 | unlink(ppdfile); | |
ef416fc2 | 1327 | unlink(tempfile); |
1328 | } | |
1329 | else | |
1330 | { | |
1331 | /* | |
1332 | * No PPD file - just set the options... | |
1333 | */ | |
1334 | ||
b423cd4c | 1335 | ippDelete(cupsDoRequest(http, request, "/admin/")); |
ef416fc2 | 1336 | } |
1337 | ||
1338 | /* | |
1339 | * Check the response... | |
1340 | */ | |
1341 | ||
fa73b229 | 1342 | if (cupsLastError() > IPP_OK_CONFLICT) |
ef416fc2 | 1343 | { |
0837b7e8 | 1344 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
ef416fc2 | 1345 | |
1346 | return (1); | |
1347 | } | |
1348 | else | |
ef416fc2 | 1349 | return (0); |
ef416fc2 | 1350 | } |
1351 | ||
1352 | ||
1353 | /* | |
1354 | * 'validate_name()' - Make sure the printer name only contains valid chars. | |
1355 | */ | |
1356 | ||
fa73b229 | 1357 | static int /* O - 0 if name is no good, 1 if name is good */ |
1358 | validate_name(const char *name) /* I - Name to check */ | |
ef416fc2 | 1359 | { |
fa73b229 | 1360 | const char *ptr; /* Pointer into name */ |
ef416fc2 | 1361 | |
1362 | ||
1363 | /* | |
1364 | * Scan the whole name... | |
1365 | */ | |
1366 | ||
1367 | for (ptr = name; *ptr; ptr ++) | |
1368 | if (*ptr == '@') | |
1369 | break; | |
1370 | else if ((*ptr >= 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/' || | |
1371 | *ptr == '#') | |
1372 | return (0); | |
1373 | ||
1374 | /* | |
1375 | * All the characters are good; validate the length, too... | |
1376 | */ | |
1377 | ||
1378 | return ((ptr - name) < 128); | |
1379 | } | |
1380 | ||
1381 | ||
1382 | /* | |
b19ccc9e | 1383 | * End of "$Id: lpadmin.c 7720 2008-07-11 22:46:21Z mike $". |
ef416fc2 | 1384 | */ |