]>
Commit | Line | Data |
---|---|---|
3270670b | 1 | /* |
c9d3f842 | 2 | * "$Id$" |
3270670b | 3 | * |
3d94661a | 4 | * "lpadmin" command for CUPS. |
3270670b | 5 | * |
2101ba5e | 6 | * Copyright 2007-2011 by Apple Inc. |
0e66904d | 7 | * Copyright 1997-2006 by Easy Software Products. |
3270670b | 8 | * |
9 | * These coded instructions, statements, and computer programs are the | |
4e8d321f | 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/". | |
3270670b | 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. | |
6bff400e | 20 | * delete_printer() - Delete a printer from the system. |
3270670b | 21 | * delete_printer_from_class() - Delete a printer from a class. |
6bff400e | 22 | * enable_printer() - Enable a printer. |
23 | * set_printer_options() - Set the printer options and/or file. | |
9c817392 | 24 | * validate_name() - Make sure the printer name only contains |
6bff400e | 25 | * valid chars. |
3270670b | 26 | */ |
27 | ||
28 | /* | |
29 | * Include necessary headers... | |
30 | */ | |
31 | ||
3d94661a | 32 | #include <cups/cups-private.h> |
3270670b | 33 | |
34 | ||
35 | /* | |
36 | * Local functions... | |
37 | */ | |
38 | ||
6bff400e | 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); | |
3270670b | 49 | |
50 | ||
51 | /* | |
52 | * 'main()' - Parse options and configure the scheduler. | |
53 | */ | |
54 | ||
55 | int | |
01a426e9 | 56 | main(int argc, /* I - Number of command-line arguments */ |
57 | char *argv[]) /* I - Command-line arguments */ | |
3270670b | 58 | { |
fb10bf13 | 59 | int i; /* Looping var */ |
9c817392 | 60 | http_t *http; /* Connection to server */ |
fb10bf13 | 61 | char *printer, /* Destination printer */ |
9c817392 | 62 | *pclass, /* Printer class name */ |
b070f93d | 63 | *val; /* Pointer to allow/deny value */ |
01a426e9 | 64 | int num_options; /* Number of options */ |
65 | cups_option_t *options; /* Options */ | |
6bff400e | 66 | char *file; /* New PPD file/interface script */ |
3270670b | 67 | |
68 | ||
156dd8aa | 69 | _cupsSetLocale(argv); |
ebad28ad | 70 | |
01a426e9 | 71 | http = NULL; |
72 | printer = NULL; | |
73 | num_options = 0; | |
74 | options = NULL; | |
6bff400e | 75 | file = NULL; |
3270670b | 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 */ | |
96ecd6f0 | 82 | if (!http) |
83 | { | |
192a8a08 | 84 | http = httpConnectEncrypt(cupsServer(), ippPort(), |
85 | cupsEncryption()); | |
96ecd6f0 | 86 | |
87 | if (http == NULL) | |
88 | { | |
89fd567e | 89 | _cupsLangPrintf(stderr, |
4c4eea89 | 90 | _("lpadmin: Unable to connect to server: %s"), |
b7382443 | 91 | strerror(errno)); |
96ecd6f0 | 92 | return (1); |
93 | } | |
94 | } | |
95 | ||
3270670b | 96 | if (printer == NULL) |
97 | { | |
89fd567e | 98 | _cupsLangPuts(stderr, |
b7382443 | 99 | _("lpadmin: Unable to add a printer to the class:\n" |
100 | " You must specify a printer name " | |
4c4eea89 | 101 | "first.")); |
3270670b | 102 | return (1); |
103 | } | |
104 | ||
105 | if (argv[i][2]) | |
9c817392 | 106 | pclass = argv[i] + 2; |
3270670b | 107 | else |
108 | { | |
109 | i ++; | |
9c817392 | 110 | |
111 | if (i >= argc) | |
112 | { | |
89fd567e | 113 | _cupsLangPuts(stderr, |
4c4eea89 | 114 | _("lpadmin: Expected class name after \"-c\" " |
115 | "option.")); | |
9c817392 | 116 | return (1); |
117 | } | |
118 | ||
119 | pclass = argv[i]; | |
120 | } | |
121 | ||
122 | if (!validate_name(pclass)) | |
123 | { | |
89fd567e | 124 | _cupsLangPuts(stderr, |
b7382443 | 125 | _("lpadmin: Class name can only contain printable " |
4c4eea89 | 126 | "characters.")); |
9c817392 | 127 | return (1); |
3270670b | 128 | } |
0bd85f71 | 129 | |
3b8ff70f | 130 | if (add_printer_to_class(http, printer, pclass)) |
131 | return (1); | |
3270670b | 132 | break; |
133 | ||
134 | case 'd' : /* Set as default destination */ | |
96ecd6f0 | 135 | if (!http) |
136 | { | |
192a8a08 | 137 | http = httpConnectEncrypt(cupsServer(), ippPort(), |
138 | cupsEncryption()); | |
96ecd6f0 | 139 | |
140 | if (http == NULL) | |
141 | { | |
89fd567e | 142 | _cupsLangPrintf(stderr, |
4c4eea89 | 143 | _("lpadmin: Unable to connect to server: %s"), |
b7382443 | 144 | strerror(errno)); |
96ecd6f0 | 145 | return (1); |
146 | } | |
147 | } | |
148 | ||
3270670b | 149 | if (argv[i][2]) |
150 | printer = argv[i] + 2; | |
151 | else | |
152 | { | |
153 | i ++; | |
9c817392 | 154 | |
155 | if (i >= argc) | |
156 | { | |
89fd567e | 157 | _cupsLangPuts(stderr, |
4c4eea89 | 158 | _("lpadmin: Expected printer name after \"-d\" " |
159 | "option.")); | |
9c817392 | 160 | return (1); |
161 | } | |
162 | ||
3270670b | 163 | printer = argv[i]; |
164 | } | |
165 | ||
9c817392 | 166 | if (!validate_name(printer)) |
167 | { | |
89fd567e | 168 | _cupsLangPuts(stderr, |
b7382443 | 169 | _("lpadmin: Printer name can only contain " |
4c4eea89 | 170 | "printable characters.")); |
9c817392 | 171 | return (1); |
172 | } | |
173 | ||
3b8ff70f | 174 | if (default_printer(http, printer)) |
175 | return (1); | |
176 | ||
3270670b | 177 | i = argc; |
178 | break; | |
179 | ||
808dd474 | 180 | case 'h' : /* Connect to host */ |
96ecd6f0 | 181 | if (http) |
192a8a08 | 182 | { |
96ecd6f0 | 183 | httpClose(http); |
192a8a08 | 184 | http = NULL; |
185 | } | |
808dd474 | 186 | |
187 | if (argv[i][2] != '\0') | |
192a8a08 | 188 | cupsSetServer(argv[i] + 2); |
808dd474 | 189 | else |
190 | { | |
191 | i ++; | |
8a4fe7c7 | 192 | |
193 | if (i >= argc) | |
194 | { | |
89fd567e | 195 | _cupsLangPuts(stderr, |
4c4eea89 | 196 | _("lpadmin: Expected hostname after \"-h\" " |
197 | "option.")); | |
8a4fe7c7 | 198 | return (1); |
199 | } | |
808dd474 | 200 | |
192a8a08 | 201 | cupsSetServer(argv[i]); |
808dd474 | 202 | } |
203 | break; | |
204 | ||
3270670b | 205 | case 'i' : /* Use the specified interface script */ |
3270670b | 206 | if (argv[i][2]) |
6bff400e | 207 | file = argv[i] + 2; |
3270670b | 208 | else |
209 | { | |
210 | i ++; | |
9c817392 | 211 | |
212 | if (i >= argc) | |
213 | { | |
89fd567e | 214 | _cupsLangPuts(stderr, |
4c4eea89 | 215 | _("lpadmin: Expected interface after \"-i\" " |
216 | "option.")); | |
9c817392 | 217 | return (1); |
218 | } | |
219 | ||
6bff400e | 220 | file = argv[i]; |
3270670b | 221 | } |
222 | break; | |
223 | ||
65a75084 | 224 | case 'E' : /* Enable the printer */ |
1c9e0181 | 225 | if (printer == NULL) |
226 | { | |
bcf61448 | 227 | #ifdef HAVE_SSL |
192a8a08 | 228 | cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); |
1c9e0181 | 229 | |
230 | if (http) | |
192a8a08 | 231 | httpEncryption(http, HTTP_ENCRYPT_REQUIRED); |
1c9e0181 | 232 | #else |
4c4eea89 | 233 | _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), |
b7382443 | 234 | argv[0]); |
bcf61448 | 235 | #endif /* HAVE_SSL */ |
1c9e0181 | 236 | break; |
237 | } | |
238 | ||
96ecd6f0 | 239 | if (!http) |
240 | { | |
192a8a08 | 241 | http = httpConnectEncrypt(cupsServer(), ippPort(), |
242 | cupsEncryption()); | |
96ecd6f0 | 243 | |
244 | if (http == NULL) | |
245 | { | |
89fd567e | 246 | _cupsLangPrintf(stderr, |
4c4eea89 | 247 | _("lpadmin: Unable to connect to server: %s"), |
b7382443 | 248 | strerror(errno)); |
96ecd6f0 | 249 | return (1); |
250 | } | |
1c9e0181 | 251 | } |
65a75084 | 252 | |
3b8ff70f | 253 | if (enable_printer(http, printer)) |
254 | return (1); | |
65a75084 | 255 | break; |
256 | ||
3270670b | 257 | case 'm' : /* Use the specified standard script/PPD file */ |
3270670b | 258 | if (argv[i][2]) |
6bff400e | 259 | num_options = cupsAddOption("ppd-name", argv[i] + 2, num_options, |
260 | &options); | |
3270670b | 261 | else |
262 | { | |
263 | i ++; | |
9c817392 | 264 | |
265 | if (i >= argc) | |
266 | { | |
89fd567e | 267 | _cupsLangPuts(stderr, |
4c4eea89 | 268 | _("lpadmin: Expected model after \"-m\" " |
269 | "option.")); | |
9c817392 | 270 | return (1); |
271 | } | |
272 | ||
6bff400e | 273 | num_options = cupsAddOption("ppd-name", argv[i], num_options, |
274 | &options); | |
3270670b | 275 | } |
3270670b | 276 | break; |
277 | ||
01a426e9 | 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 | { | |
89fd567e | 287 | _cupsLangPuts(stderr, |
4c4eea89 | 288 | _("lpadmin: Expected name=value after \"-o\" " |
289 | "option.")); | |
01a426e9 | 290 | return (1); |
291 | } | |
292 | ||
293 | num_options = cupsParseOptions(argv[i], num_options, &options); | |
294 | } | |
295 | break; | |
296 | ||
3270670b | 297 | case 'p' : /* Add/modify a printer */ |
298 | if (argv[i][2]) | |
299 | printer = argv[i] + 2; | |
300 | else | |
301 | { | |
302 | i ++; | |
9c817392 | 303 | |
304 | if (i >= argc) | |
305 | { | |
89fd567e | 306 | _cupsLangPuts(stderr, |
4c4eea89 | 307 | _("lpadmin: Expected printer after \"-p\" " |
308 | "option.")); | |
9c817392 | 309 | return (1); |
310 | } | |
311 | ||
3270670b | 312 | printer = argv[i]; |
313 | } | |
808dd474 | 314 | |
9c817392 | 315 | if (!validate_name(printer)) |
316 | { | |
89fd567e | 317 | _cupsLangPuts(stderr, |
b7382443 | 318 | _("lpadmin: Printer name can only contain " |
4c4eea89 | 319 | "printable characters.")); |
9c817392 | 320 | return (1); |
321 | } | |
3270670b | 322 | break; |
323 | ||
324 | case 'r' : /* Remove printer from class */ | |
96ecd6f0 | 325 | if (!http) |
326 | { | |
192a8a08 | 327 | http = httpConnectEncrypt(cupsServer(), ippPort(), |
328 | cupsEncryption()); | |
96ecd6f0 | 329 | |
330 | if (http == NULL) | |
331 | { | |
89fd567e | 332 | _cupsLangPrintf(stderr, |
4c4eea89 | 333 | _("lpadmin: Unable to connect to server: %s"), |
b7382443 | 334 | strerror(errno)); |
96ecd6f0 | 335 | return (1); |
336 | } | |
337 | } | |
338 | ||
3270670b | 339 | if (printer == NULL) |
340 | { | |
89fd567e | 341 | _cupsLangPuts(stderr, |
b7382443 | 342 | _("lpadmin: Unable to remove a printer from the " |
343 | "class:\n" | |
344 | " You must specify a printer name " | |
4c4eea89 | 345 | "first.")); |
3270670b | 346 | return (1); |
347 | } | |
348 | ||
349 | if (argv[i][2]) | |
9c817392 | 350 | pclass = argv[i] + 2; |
3270670b | 351 | else |
352 | { | |
353 | i ++; | |
9c817392 | 354 | |
355 | if (i >= argc) | |
356 | { | |
89fd567e | 357 | _cupsLangPuts(stderr, |
4c4eea89 | 358 | _("lpadmin: Expected class after \"-r\" " |
359 | "option.")); | |
9c817392 | 360 | return (1); |
361 | } | |
362 | ||
363 | pclass = argv[i]; | |
3270670b | 364 | } |
9c817392 | 365 | |
366 | if (!validate_name(pclass)) | |
367 | { | |
89fd567e | 368 | _cupsLangPuts(stderr, |
b7382443 | 369 | _("lpadmin: Class name can only contain printable " |
4c4eea89 | 370 | "characters.")); |
9c817392 | 371 | return (1); |
372 | } | |
373 | ||
3b8ff70f | 374 | if (delete_printer_from_class(http, printer, pclass)) |
375 | return (1); | |
3270670b | 376 | break; |
377 | ||
5bce1394 | 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 " | |
4c4eea89 | 388 | "\"-U\" option."), argv[0]); |
5bce1394 | 389 | return (1); |
390 | } | |
391 | ||
392 | cupsSetUser(argv[i]); | |
393 | } | |
394 | break; | |
395 | ||
01a426e9 | 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 | { | |
89fd567e | 405 | _cupsLangPuts(stderr, |
b7382443 | 406 | _("lpadmin: Expected allow/deny:userlist after " |
4c4eea89 | 407 | "\"-u\" option.")); |
01a426e9 | 408 | return (1); |
409 | } | |
410 | ||
411 | val = argv[i]; | |
412 | } | |
413 | ||
b7382443 | 414 | if (!strncasecmp(val, "allow:", 6)) |
01a426e9 | 415 | num_options = cupsAddOption("requesting-user-name-allowed", |
416 | val + 6, num_options, &options); | |
b7382443 | 417 | else if (!strncasecmp(val, "deny:", 5)) |
01a426e9 | 418 | num_options = cupsAddOption("requesting-user-name-denied", |
419 | val + 5, num_options, &options); | |
420 | else | |
421 | { | |
89fd567e | 422 | _cupsLangPrintf(stderr, |
4c4eea89 | 423 | _("lpadmin: Unknown allow/deny option \"%s\"."), |
b7382443 | 424 | val); |
01a426e9 | 425 | return (1); |
426 | } | |
427 | break; | |
428 | ||
3270670b | 429 | case 'v' : /* Set the device-uri attribute */ |
3270670b | 430 | if (argv[i][2]) |
6bff400e | 431 | num_options = cupsAddOption("device-uri", argv[i] + 2, |
432 | num_options, &options); | |
3270670b | 433 | else |
434 | { | |
435 | i ++; | |
9c817392 | 436 | |
437 | if (i >= argc) | |
438 | { | |
89fd567e | 439 | _cupsLangPuts(stderr, |
4c4eea89 | 440 | _("lpadmin: Expected device URI after \"-v\" " |
441 | "option.")); | |
9c817392 | 442 | return (1); |
443 | } | |
444 | ||
6bff400e | 445 | num_options = cupsAddOption("device-uri", argv[i], |
446 | num_options, &options); | |
3270670b | 447 | } |
448 | break; | |
449 | ||
450 | case 'x' : /* Delete a printer */ | |
96ecd6f0 | 451 | if (!http) |
452 | { | |
192a8a08 | 453 | http = httpConnectEncrypt(cupsServer(), ippPort(), |
454 | cupsEncryption()); | |
96ecd6f0 | 455 | |
456 | if (http == NULL) | |
457 | { | |
89fd567e | 458 | _cupsLangPrintf(stderr, |
4c4eea89 | 459 | _("lpadmin: Unable to connect to server: %s"), |
b7382443 | 460 | strerror(errno)); |
96ecd6f0 | 461 | return (1); |
462 | } | |
463 | } | |
464 | ||
3270670b | 465 | if (argv[i][2]) |
466 | printer = argv[i] + 2; | |
467 | else | |
468 | { | |
469 | i ++; | |
9c817392 | 470 | |
471 | if (i >= argc) | |
472 | { | |
89fd567e | 473 | _cupsLangPuts(stderr, |
b7382443 | 474 | _("lpadmin: Expected printer or class after " |
4c4eea89 | 475 | "\"-x\" option.")); |
9c817392 | 476 | return (1); |
477 | } | |
478 | ||
3270670b | 479 | printer = argv[i]; |
480 | } | |
481 | ||
9c817392 | 482 | if (!validate_name(printer)) |
483 | { | |
89fd567e | 484 | _cupsLangPuts(stderr, |
b7382443 | 485 | _("lpadmin: Printer name can only contain " |
4c4eea89 | 486 | "printable characters.")); |
9c817392 | 487 | return (1); |
488 | } | |
489 | ||
3b8ff70f | 490 | if (delete_printer(http, printer)) |
491 | return (1); | |
492 | ||
3270670b | 493 | i = argc; |
494 | break; | |
495 | ||
496 | case 'D' : /* Set the printer-info attribute */ | |
3270670b | 497 | if (argv[i][2]) |
6bff400e | 498 | num_options = cupsAddOption("printer-info", argv[i] + 2, |
499 | num_options, &options); | |
3270670b | 500 | else |
501 | { | |
502 | i ++; | |
9c817392 | 503 | |
504 | if (i >= argc) | |
505 | { | |
89fd567e | 506 | _cupsLangPuts(stderr, |
b7382443 | 507 | _("lpadmin: Expected description after " |
4c4eea89 | 508 | "\"-D\" option.")); |
9c817392 | 509 | return (1); |
510 | } | |
511 | ||
6bff400e | 512 | num_options = cupsAddOption("printer-info", argv[i], |
513 | num_options, &options); | |
3270670b | 514 | } |
515 | break; | |
516 | ||
f8f971b2 | 517 | case 'I' : /* Set the supported file types (ignored) */ |
518 | i ++; | |
519 | ||
520 | if (i >= argc) | |
521 | { | |
89fd567e | 522 | _cupsLangPuts(stderr, |
4c4eea89 | 523 | _("lpadmin: Expected file type(s) after \"-I\" " |
524 | "option.")); | |
f8f971b2 | 525 | return (1); |
526 | } | |
527 | ||
89fd567e | 528 | _cupsLangPuts(stderr, |
4c4eea89 | 529 | _("lpadmin: Warning - content type list ignored.")); |
f8f971b2 | 530 | break; |
531 | ||
6c7527d1 | 532 | case 'L' : /* Set the printer-location attribute */ |
6c7527d1 | 533 | if (argv[i][2]) |
6bff400e | 534 | num_options = cupsAddOption("printer-location", argv[i] + 2, |
535 | num_options, &options); | |
6c7527d1 | 536 | else |
537 | { | |
538 | i ++; | |
9c817392 | 539 | |
540 | if (i >= argc) | |
541 | { | |
89fd567e | 542 | _cupsLangPuts(stderr, |
4c4eea89 | 543 | _("lpadmin: Expected location after \"-L\" " |
544 | "option.")); | |
9c817392 | 545 | return (1); |
546 | } | |
547 | ||
6bff400e | 548 | num_options = cupsAddOption("printer-location", argv[i], |
549 | num_options, &options); | |
6c7527d1 | 550 | } |
551 | break; | |
552 | ||
3270670b | 553 | case 'P' : /* Use the specified PPD file */ |
3270670b | 554 | if (argv[i][2]) |
6bff400e | 555 | file = argv[i] + 2; |
3270670b | 556 | else |
557 | { | |
558 | i ++; | |
9c817392 | 559 | |
560 | if (i >= argc) | |
561 | { | |
89fd567e | 562 | _cupsLangPuts(stderr, |
4c4eea89 | 563 | _("lpadmin: Expected PPD after \"-P\" option.")); |
9c817392 | 564 | return (1); |
565 | } | |
566 | ||
6bff400e | 567 | file = argv[i]; |
3270670b | 568 | } |
569 | break; | |
570 | ||
571 | default : | |
89fd567e | 572 | _cupsLangPrintf(stderr, |
4c4eea89 | 573 | _("lpadmin: Unknown option \"%c\"."), argv[i][1]); |
3270670b | 574 | return (1); |
575 | } | |
576 | else | |
577 | { | |
4c4eea89 | 578 | _cupsLangPrintf(stderr, _("lpadmin: Unknown argument \"%s\"."), |
b7382443 | 579 | argv[i]); |
3270670b | 580 | return (1); |
581 | } | |
582 | ||
01a426e9 | 583 | /* |
584 | * Set options as needed... | |
585 | */ | |
586 | ||
6bff400e | 587 | if (num_options || file) |
01a426e9 | 588 | { |
589 | if (!http) | |
590 | { | |
192a8a08 | 591 | http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); |
01a426e9 | 592 | |
593 | if (http == NULL) | |
594 | { | |
89fd567e | 595 | _cupsLangPrintf(stderr, |
4c4eea89 | 596 | _("lpadmin: Unable to connect to server: %s"), |
b7382443 | 597 | strerror(errno)); |
01a426e9 | 598 | return (1); |
599 | } | |
600 | } | |
601 | ||
602 | if (printer == NULL) | |
603 | { | |
89fd567e | 604 | _cupsLangPuts(stderr, |
b7382443 | 605 | _("lpadmin: Unable to set the printer options:\n" |
4c4eea89 | 606 | " You must specify a printer name first.")); |
01a426e9 | 607 | return (1); |
608 | } | |
609 | ||
6bff400e | 610 | if (set_printer_options(http, printer, num_options, options, file)) |
3b8ff70f | 611 | return (1); |
01a426e9 | 612 | } |
613 | ||
3270670b | 614 | if (printer == NULL) |
615 | { | |
89fd567e | 616 | _cupsLangPuts(stdout, |
b7382443 | 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] " | |
4c4eea89 | 627 | "[-u deny:user,user]")); |
3270670b | 628 | } |
629 | ||
96ecd6f0 | 630 | if (http) |
631 | httpClose(http); | |
3270670b | 632 | |
633 | return (0); | |
634 | } | |
635 | ||
636 | ||
637 | /* | |
638 | * 'add_printer_to_class()' - Add a printer to a class. | |
639 | */ | |
640 | ||
3b8ff70f | 641 | static int /* O - 0 on success, 1 on fail */ |
3270670b | 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 */ | |
3270670b | 651 | char uri[HTTP_MAX_URI]; /* URI for printer/class */ |
652 | ||
653 | ||
01a426e9 | 654 | DEBUG_printf(("add_printer_to_class(%p, \"%s\", \"%s\")\n", http, |
65a75084 | 655 | printer, pclass)); |
656 | ||
3270670b | 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 | ||
00f3aaf5 | 666 | request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); |
667 | ||
00a1fad8 | 668 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
669 | "localhost", 0, "/classes/%s", pclass); | |
3270670b | 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 | ||
96ecd6f0 | 677 | response = cupsDoRequest(http, request, "/"); |
3270670b | 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 | ||
00f3aaf5 | 689 | request = ippNewRequest(CUPS_ADD_CLASS); |
3270670b | 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 | { | |
00f3aaf5 | 703 | _cupsLangPrintf(stderr, |
4c4eea89 | 704 | _("lpadmin: Printer %s is already a member of class " |
705 | "%s."), printer, pclass); | |
3270670b | 706 | ippDelete(request); |
707 | ippDelete(response); | |
3b8ff70f | 708 | return (0); |
3270670b | 709 | } |
710 | ||
711 | /* | |
712 | * OK, the printer isn't part of the class, so add it... | |
713 | */ | |
714 | ||
00a1fad8 | 715 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
716 | "localhost", 0, "/printers/%s", printer); | |
3270670b | 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 ++) | |
c97b7208 | 728 | attr->values[i].string.text = _cupsStrAlloc(members->values[i].string.text); |
3270670b | 729 | |
c97b7208 | 730 | attr->values[i].string.text = _cupsStrAlloc(uri); |
3270670b | 731 | } |
732 | else | |
c97b7208 | 733 | ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris", NULL, |
734 | uri); | |
3270670b | 735 | |
736 | /* | |
737 | * Then send the request... | |
738 | */ | |
739 | ||
740 | ippDelete(response); | |
741 | ||
742 | if ((response = cupsDoRequest(http, request, "/admin/")) == NULL) | |
3b8ff70f | 743 | { |
4c4eea89 | 744 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
3b8ff70f | 745 | |
746 | return (1); | |
747 | } | |
7b2e6b69 | 748 | else if (response->request.status.status_code > IPP_OK_CONFLICT) |
96ecd6f0 | 749 | { |
4c4eea89 | 750 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
96ecd6f0 | 751 | |
3270670b | 752 | ippDelete(response); |
3b8ff70f | 753 | |
754 | return (1); | |
96ecd6f0 | 755 | } |
7b2e6b69 | 756 | else |
757 | { | |
758 | ippDelete(response); | |
3b8ff70f | 759 | |
7b2e6b69 | 760 | return (0); |
761 | } | |
3270670b | 762 | } |
763 | ||
764 | ||
765 | /* | |
766 | * 'default_printer()' - Set the default printing destination. | |
767 | */ | |
768 | ||
3b8ff70f | 769 | static int /* O - 0 on success, 1 on fail */ |
3270670b | 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 */ | |
3270670b | 775 | char uri[HTTP_MAX_URI]; /* URI for printer/class */ |
776 | ||
777 | ||
01a426e9 | 778 | DEBUG_printf(("default_printer(%p, \"%s\")\n", http, printer)); |
65a75084 | 779 | |
3270670b | 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 | ||
00a1fad8 | 789 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
790 | "localhost", 0, "/printers/%s", printer); | |
3270670b | 791 | |
00f3aaf5 | 792 | request = ippNewRequest(CUPS_SET_DEFAULT); |
3270670b | 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) | |
3b8ff70f | 802 | { |
4c4eea89 | 803 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
3b8ff70f | 804 | |
805 | return (1); | |
806 | } | |
807 | else if (response->request.status.status_code > IPP_OK_CONFLICT) | |
3270670b | 808 | { |
4c4eea89 | 809 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
3270670b | 810 | |
811 | ippDelete(response); | |
3b8ff70f | 812 | |
813 | return (1); | |
814 | } | |
815 | else | |
816 | { | |
817 | ippDelete(response); | |
818 | ||
819 | return (0); | |
3270670b | 820 | } |
821 | } | |
822 | ||
823 | ||
824 | /* | |
825 | * 'delete_printer()' - Delete a printer from the system... | |
826 | */ | |
827 | ||
3b8ff70f | 828 | static int /* O - 0 on success, 1 on fail */ |
3270670b | 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 */ | |
3270670b | 834 | char uri[HTTP_MAX_URI]; /* URI for printer/class */ |
835 | ||
836 | ||
01a426e9 | 837 | DEBUG_printf(("delete_printer(%p, \"%s\")\n", http, printer)); |
65a75084 | 838 | |
3270670b | 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 | ||
00f3aaf5 | 848 | request = ippNewRequest(CUPS_DELETE_PRINTER); |
849 | ||
00a1fad8 | 850 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
851 | "localhost", 0, "/printers/%s", printer); | |
3270670b | 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) | |
3b8ff70f | 860 | { |
4c4eea89 | 861 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
3b8ff70f | 862 | |
863 | return (1); | |
864 | } | |
865 | else if (response->request.status.status_code > IPP_OK_CONFLICT) | |
3270670b | 866 | { |
4c4eea89 | 867 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
3270670b | 868 | |
869 | ippDelete(response); | |
3b8ff70f | 870 | |
871 | return (1); | |
872 | } | |
873 | else | |
874 | { | |
875 | ippDelete(response); | |
876 | ||
877 | return (0); | |
3270670b | 878 | } |
879 | } | |
880 | ||
881 | ||
882 | /* | |
883 | * 'delete_printer_from_class()' - Delete a printer from a class. | |
884 | */ | |
885 | ||
3b8ff70f | 886 | static int /* O - 0 on success, 1 on fail */ |
00f3aaf5 | 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 */ | |
3270670b | 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 */ | |
3270670b | 897 | char uri[HTTP_MAX_URI]; /* URI for printer/class */ |
898 | ||
899 | ||
01a426e9 | 900 | DEBUG_printf(("delete_printer_from_class(%p, \"%s\", \"%s\")\n", http, |
65a75084 | 901 | printer, pclass)); |
902 | ||
3270670b | 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 | ||
00f3aaf5 | 912 | request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); |
913 | ||
00a1fad8 | 914 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
915 | "localhost", 0, "/classes/%s", pclass); | |
3270670b | 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 || | |
0a3ac972 | 924 | response->request.status.status_code == IPP_NOT_FOUND) |
3270670b | 925 | { |
4c4eea89 | 926 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
00f3aaf5 | 927 | |
3270670b | 928 | ippDelete(response); |
00f3aaf5 | 929 | |
3b8ff70f | 930 | return (1); |
3270670b | 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 | { | |
4c4eea89 | 939 | _cupsLangPuts(stderr, _("lpadmin: No member names were seen.")); |
00f3aaf5 | 940 | |
3270670b | 941 | ippDelete(response); |
00f3aaf5 | 942 | |
3b8ff70f | 943 | return (1); |
3270670b | 944 | } |
945 | ||
946 | for (i = 0; i < members->num_values; i ++) | |
00f3aaf5 | 947 | if (!strcasecmp(printer, members->values[i].string.text)) |
3270670b | 948 | break; |
949 | ||
950 | if (i >= members->num_values) | |
951 | { | |
00f3aaf5 | 952 | _cupsLangPrintf(stderr, |
4c4eea89 | 953 | _("lpadmin: Printer %s is not a member of class %s."), |
00f3aaf5 | 954 | printer, pclass); |
955 | ||
3270670b | 956 | ippDelete(response); |
00f3aaf5 | 957 | |
3b8ff70f | 958 | return (1); |
3270670b | 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 | ||
00f3aaf5 | 972 | request = ippNewRequest(CUPS_DELETE_CLASS); |
3270670b | 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 | ||
00f3aaf5 | 989 | request = ippNewRequest(CUPS_ADD_CLASS); |
3270670b | 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) | |
c97b7208 | 1004 | attr->values[k ++].string.text = |
1005 | _cupsStrAlloc(members->values[j].string.text); | |
3270670b | 1006 | } |
1007 | ||
1008 | /* | |
1009 | * Then send the request... | |
1010 | */ | |
1011 | ||
1012 | ippDelete(response); | |
1013 | ||
1014 | if ((response = cupsDoRequest(http, request, "/admin/")) == NULL) | |
3b8ff70f | 1015 | { |
4c4eea89 | 1016 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
00f3aaf5 | 1017 | |
3b8ff70f | 1018 | return (1); |
1019 | } | |
1020 | else if (response->request.status.status_code > IPP_OK_CONFLICT) | |
96ecd6f0 | 1021 | { |
4c4eea89 | 1022 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
96ecd6f0 | 1023 | |
3270670b | 1024 | ippDelete(response); |
3b8ff70f | 1025 | |
1026 | return (1); | |
1027 | } | |
1028 | else | |
1029 | { | |
1030 | ippDelete(response); | |
1031 | ||
1032 | return (0); | |
96ecd6f0 | 1033 | } |
3270670b | 1034 | } |
1035 | ||
1036 | ||
65a75084 | 1037 | /* |
1038 | * 'enable_printer()' - Enable a printer... | |
1039 | */ | |
1040 | ||
3b8ff70f | 1041 | static int /* O - 0 on success, 1 on fail */ |
65a75084 | 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 */ | |
65a75084 | 1047 | char uri[HTTP_MAX_URI]; /* URI for printer/class */ |
1048 | ||
1049 | ||
01a426e9 | 1050 | DEBUG_printf(("enable_printer(%p, \"%s\")\n", http, printer)); |
65a75084 | 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 | ||
00f3aaf5 | 1063 | request = ippNewRequest(CUPS_ADD_PRINTER); |
1064 | ||
00a1fad8 | 1065 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
1066 | "localhost", 0, "/printers/%s", printer); | |
65a75084 | 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) | |
3b8ff70f | 1080 | { |
4c4eea89 | 1081 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
00f3aaf5 | 1082 | |
3b8ff70f | 1083 | return (1); |
1084 | } | |
1085 | else if (response->request.status.status_code > IPP_OK_CONFLICT) | |
65a75084 | 1086 | { |
4c4eea89 | 1087 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
65a75084 | 1088 | |
1089 | ippDelete(response); | |
3b8ff70f | 1090 | |
1091 | return (1); | |
1092 | } | |
1093 | else | |
1094 | { | |
1095 | ippDelete(response); | |
1096 | ||
1097 | return (0); | |
65a75084 | 1098 | } |
1099 | } | |
1100 | ||
1101 | ||
01a426e9 | 1102 | /* |
1103 | * 'set_printer_options()' - Set the printer options. | |
1104 | */ | |
1105 | ||
3b8ff70f | 1106 | static int /* O - 0 on success, 1 on fail */ |
00f3aaf5 | 1107 | set_printer_options( |
1108 | http_t *http, /* I - Server connection */ | |
1109 | char *printer, /* I - Printer */ | |
1110 | int num_options, /* I - Number of options */ | |
6bff400e | 1111 | cups_option_t *options, /* I - Options */ |
1112 | char *file) /* I - PPD file/interface script */ | |
01a426e9 | 1113 | { |
1114 | ipp_t *request, /* IPP Request */ | |
1115 | *response; /* IPP Response */ | |
5a3ef28d | 1116 | ipp_attribute_t *attr; /* IPP attribute */ |
5a3ef28d | 1117 | ipp_op_t op; /* Operation to perform */ |
a309520e | 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 */ | |
01a426e9 | 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 */ | |
6bff400e | 1127 | cups_file_t *in, /* PPD file */ |
01a426e9 | 1128 | *out; /* Temporary file */ |
0050629b | 1129 | const char *protocol, /* Old protocol option */ |
ece2b4cf | 1130 | *customval, /* Custom option value */ |
1131 | *boolval; /* Boolean value */ | |
1132 | int wrote_ipp_supplies = 0, /* Wrote cupsIPPSupplies keyword? */ | |
1133 | wrote_snmp_supplies = 0;/* Wrote cupsSNMPSupplies keyword? */ | |
01a426e9 | 1134 | |
1135 | ||
6bff400e | 1136 | DEBUG_printf(("set_printer_options(http=%p, printer=\"%s\", num_options=%d, " |
1137 | "options=%p, file=\"%s\")\n", http, printer, num_options, | |
1138 | options, file)); | |
01a426e9 | 1139 | |
00a1fad8 | 1140 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
1141 | "localhost", 0, "/printers/%s", printer); | |
5a3ef28d | 1142 | |
01a426e9 | 1143 | /* |
5a3ef28d | 1144 | * Build a GET_PRINTER_ATTRIBUTES request, which requires the following |
01a426e9 | 1145 | * attributes: |
1146 | * | |
1147 | * attributes-charset | |
1148 | * attributes-natural-language | |
1149 | * printer-uri | |
5a3ef28d | 1150 | * requested-attributes |
01a426e9 | 1151 | */ |
1152 | ||
00f3aaf5 | 1153 | request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); |
5a3ef28d | 1154 | |
1155 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, | |
1156 | "printer-uri", NULL, uri); | |
5a3ef28d | 1157 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, |
1158 | "requested-attributes", NULL, "printer-type"); | |
1159 | ||
1160 | /* | |
1161 | * Do the request... | |
1162 | */ | |
1163 | ||
6bff400e | 1164 | op = CUPS_ADD_MODIFY_PRINTER; |
5a3ef28d | 1165 | |
1166 | if ((response = cupsDoRequest(http, request, "/")) != NULL) | |
1167 | { | |
1168 | /* | |
1169 | * See what kind of printer or class it is... | |
1170 | */ | |
1171 | ||
a309520e | 1172 | if ((attr = ippFindAttribute(response, "printer-type", |
1173 | IPP_TAG_ENUM)) != NULL) | |
5a3ef28d | 1174 | { |
1175 | if (attr->values[0].integer & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT)) | |
1176 | { | |
6bff400e | 1177 | op = CUPS_ADD_MODIFY_CLASS; |
00a1fad8 | 1178 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
1179 | "localhost", 0, "/classes/%s", printer); | |
5a3ef28d | 1180 | } |
1181 | } | |
1182 | ||
1183 | ippDelete(response); | |
1184 | } | |
1185 | ||
1186 | /* | |
6bff400e | 1187 | * Build a CUPS_ADD_MODIFY_PRINTER or CUPS_ADD_MODIFY_CLASS request, which |
1188 | * requires the following attributes: | |
5a3ef28d | 1189 | * |
1190 | * attributes-charset | |
1191 | * attributes-natural-language | |
1192 | * printer-uri | |
1193 | * other options | |
1194 | */ | |
1195 | ||
00f3aaf5 | 1196 | request = ippNewRequest(op); |
01a426e9 | 1197 | |
1198 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, | |
1199 | "printer-uri", NULL, uri); | |
6bff400e | 1200 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, |
1201 | "requesting-user-name", NULL, cupsUser()); | |
01a426e9 | 1202 | |
1203 | /* | |
1204 | * Add the options... | |
1205 | */ | |
1206 | ||
a309520e | 1207 | cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER); |
1208 | ||
1209 | if ((protocol = cupsGetOption("protocol", num_options, options)) != NULL) | |
1210 | { | |
1211 | if (!strcasecmp(protocol, "bcp")) | |
a88691d5 | 1212 | ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "port-monitor", |
a309520e | 1213 | NULL, "bcp"); |
1214 | else if (!strcasecmp(protocol, "tbcp")) | |
a88691d5 | 1215 | ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "port-monitor", |
a309520e | 1216 | NULL, "tbcp"); |
1217 | } | |
01a426e9 | 1218 | |
6bff400e | 1219 | if (file) |
1220 | ppdfile = file; | |
1221 | else if (op == CUPS_ADD_MODIFY_PRINTER) | |
5a3ef28d | 1222 | ppdfile = cupsGetPPD(printer); |
1223 | else | |
1224 | ppdfile = NULL; | |
1225 | ||
1226 | if (ppdfile != NULL) | |
01a426e9 | 1227 | { |
1228 | /* | |
1229 | * Set default options in the PPD file... | |
1230 | */ | |
1231 | ||
a309520e | 1232 | ppd = ppdOpenFile(ppdfile); |
1233 | ppdMarkDefaults(ppd); | |
1234 | cupsMarkOptions(ppd, num_options, options); | |
1235 | ||
2101ba5e | 1236 | if ((out = cupsTempFile2(tempfile, sizeof(tempfile))) == NULL) |
b2d75006 | 1237 | { |
bd2147fb | 1238 | _cupsLangPrintError(NULL, _("lpadmin: Unable to create temporary file")); |
b2d75006 | 1239 | ippDelete(request); |
6bff400e | 1240 | if (ppdfile != file) |
1241 | unlink(ppdfile); | |
b2d75006 | 1242 | return (1); |
1243 | } | |
1244 | ||
6bff400e | 1245 | if ((in = cupsFileOpen(ppdfile, "r")) == NULL) |
b2d75006 | 1246 | { |
89fd567e | 1247 | _cupsLangPrintf(stderr, |
4c4eea89 | 1248 | _("lpadmin: Unable to open PPD file \"%s\" - %s"), |
b7382443 | 1249 | ppdfile, strerror(errno)); |
b2d75006 | 1250 | ippDelete(request); |
6bff400e | 1251 | if (ppdfile != file) |
1252 | unlink(ppdfile); | |
1253 | cupsFileClose(out); | |
b2d75006 | 1254 | unlink(tempfile); |
1255 | return (1); | |
1256 | } | |
01a426e9 | 1257 | |
a309520e | 1258 | ppdchanged = 0; |
01a426e9 | 1259 | |
6bff400e | 1260 | while (cupsFileGets(in, line, sizeof(line))) |
01a426e9 | 1261 | { |
ece2b4cf | 1262 | if (!strncmp(line, "*cupsIPPSupplies:", 17) && |
1263 | (boolval = cupsGetOption("cupsIPPSupplies", num_options, | |
1264 | options)) != NULL) | |
1265 | { | |
1266 | wrote_ipp_supplies = 1; | |
1267 | cupsFilePrintf(out, "*cupsIPPSupplies: %s\n", | |
1268 | (!strcasecmp(boolval, "true") || | |
1269 | !strcasecmp(boolval, "yes") || | |
1270 | !strcasecmp(boolval, "on")) ? "True" : "False"); | |
1271 | } | |
1272 | else if (!strncmp(line, "*cupsSNMPSupplies:", 18) && | |
1273 | (boolval = cupsGetOption("cupsSNMPSupplies", num_options, | |
1274 | options)) != NULL) | |
1275 | { | |
1276 | wrote_snmp_supplies = 1; | |
1277 | cupsFilePrintf(out, "*cupsSNMPSupplies: %s\n", | |
1278 | (!strcasecmp(boolval, "true") || | |
1279 | !strcasecmp(boolval, "yes") || | |
1280 | !strcasecmp(boolval, "on")) ? "True" : "False"); | |
1281 | } | |
1282 | else if (strncmp(line, "*Default", 8)) | |
6bff400e | 1283 | cupsFilePrintf(out, "%s\n", line); |
01a426e9 | 1284 | else |
1285 | { | |
1286 | /* | |
1287 | * Get default option name... | |
1288 | */ | |
1289 | ||
def978d5 | 1290 | strlcpy(keyword, line + 8, sizeof(keyword)); |
01a426e9 | 1291 | |
1292 | for (keyptr = keyword; *keyptr; keyptr ++) | |
64bbab09 | 1293 | if (*keyptr == ':' || isspace(*keyptr & 255)) |
01a426e9 | 1294 | break; |
1295 | ||
a309520e | 1296 | *keyptr++ = '\0'; |
1297 | while (isspace(*keyptr & 255)) | |
1298 | keyptr ++; | |
01a426e9 | 1299 | |
42d6b787 | 1300 | if (!strcmp(keyword, "PageRegion") || |
1301 | !strcmp(keyword, "PageSize") || | |
1302 | !strcmp(keyword, "PaperDimension") || | |
1303 | !strcmp(keyword, "ImageableArea")) | |
1304 | { | |
1305 | if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) == NULL) | |
1306 | choice = ppdFindMarkedChoice(ppd, "PageRegion"); | |
1307 | } | |
01a426e9 | 1308 | else |
a309520e | 1309 | choice = ppdFindMarkedChoice(ppd, keyword); |
01a426e9 | 1310 | |
a309520e | 1311 | if (choice && strcmp(choice->choice, keyptr)) |
1312 | { | |
0050629b | 1313 | if (strcmp(choice->choice, "Custom")) |
1314 | { | |
1315 | cupsFilePrintf(out, "*Default%s: %s\n", keyword, choice->choice); | |
1316 | ppdchanged = 1; | |
1317 | } | |
1318 | else if ((customval = cupsGetOption(keyword, num_options, | |
1319 | options)) != NULL) | |
1320 | { | |
1321 | cupsFilePrintf(out, "*Default%s: %s\n", keyword, customval); | |
1322 | ppdchanged = 1; | |
1323 | } | |
1324 | else | |
1325 | cupsFilePrintf(out, "%s\n", line); | |
a309520e | 1326 | } |
01a426e9 | 1327 | else |
6bff400e | 1328 | cupsFilePrintf(out, "%s\n", line); |
01a426e9 | 1329 | } |
1330 | } | |
1331 | ||
ece2b4cf | 1332 | if (!wrote_ipp_supplies && |
1333 | (boolval = cupsGetOption("cupsIPPSupplies", num_options, | |
1334 | options)) != NULL) | |
1335 | { | |
1336 | cupsFilePrintf(out, "*cupsIPPSupplies: %s\n", | |
1337 | (!strcasecmp(boolval, "true") || | |
1338 | !strcasecmp(boolval, "yes") || | |
1339 | !strcasecmp(boolval, "on")) ? "True" : "False"); | |
1340 | } | |
1341 | ||
1342 | if (!wrote_snmp_supplies && | |
1343 | (boolval = cupsGetOption("cupsSNMPSupplies", num_options, | |
1344 | options)) != NULL) | |
1345 | { | |
1346 | cupsFilePrintf(out, "*cupsSNMPSupplies: %s\n", | |
1347 | (!strcasecmp(boolval, "true") || | |
1348 | !strcasecmp(boolval, "yes") || | |
1349 | !strcasecmp(boolval, "on")) ? "True" : "False"); | |
1350 | } | |
1351 | ||
6bff400e | 1352 | cupsFileClose(in); |
1353 | cupsFileClose(out); | |
a309520e | 1354 | ppdClose(ppd); |
01a426e9 | 1355 | |
1356 | /* | |
1357 | * Do the request... | |
1358 | */ | |
1359 | ||
a309520e | 1360 | ippDelete(cupsDoFileRequest(http, request, "/admin/", |
6bff400e | 1361 | ppdchanged ? tempfile : file)); |
01a426e9 | 1362 | |
1363 | /* | |
1364 | * Clean up temp files... (TODO: catch signals in case we CTRL-C during | |
1365 | * lpadmin) | |
1366 | */ | |
1367 | ||
6bff400e | 1368 | if (ppdfile != file) |
1369 | unlink(ppdfile); | |
01a426e9 | 1370 | unlink(tempfile); |
1371 | } | |
1372 | else | |
1373 | { | |
1374 | /* | |
1375 | * No PPD file - just set the options... | |
1376 | */ | |
1377 | ||
a309520e | 1378 | ippDelete(cupsDoRequest(http, request, "/admin/")); |
01a426e9 | 1379 | } |
1380 | ||
1381 | /* | |
5a3ef28d | 1382 | * Check the response... |
01a426e9 | 1383 | */ |
1384 | ||
00f3aaf5 | 1385 | if (cupsLastError() > IPP_OK_CONFLICT) |
01a426e9 | 1386 | { |
4c4eea89 | 1387 | _cupsLangPrintf(stderr, "lpadmin: %s", cupsLastErrorString()); |
3b8ff70f | 1388 | |
1389 | return (1); | |
1390 | } | |
1391 | else | |
3b8ff70f | 1392 | return (0); |
01a426e9 | 1393 | } |
1394 | ||
1395 | ||
6c7527d1 | 1396 | /* |
aa37e40e | 1397 | * 'validate_name()' - Make sure the printer name only contains valid chars. |
9c817392 | 1398 | */ |
1399 | ||
00f3aaf5 | 1400 | static int /* O - 0 if name is no good, 1 if name is good */ |
1401 | validate_name(const char *name) /* I - Name to check */ | |
9c817392 | 1402 | { |
00f3aaf5 | 1403 | const char *ptr; /* Pointer into name */ |
095bb32d | 1404 | |
1405 | ||
74bb2a4e | 1406 | /* |
1407 | * Scan the whole name... | |
1408 | */ | |
1409 | ||
095bb32d | 1410 | for (ptr = name; *ptr; ptr ++) |
1411 | if (*ptr == '@') | |
1412 | break; | |
a3901bc4 | 1413 | else if ((*ptr >= 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/' || |
1414 | *ptr == '#') | |
9c817392 | 1415 | return (0); |
9c817392 | 1416 | |
095bb32d | 1417 | /* |
1418 | * All the characters are good; validate the length, too... | |
1419 | */ | |
1420 | ||
1421 | return ((ptr - name) < 128); | |
9c817392 | 1422 | } |
1423 | ||
1424 | ||
1425 | /* | |
c9d3f842 | 1426 | * End of "$Id$". |
3270670b | 1427 | */ |