]>
Commit | Line | Data |
---|---|---|
3270670b | 1 | /* |
c9d3f842 | 2 | * "$Id$" |
3270670b | 3 | * |
3d94661a | 4 | * "lpadmin" command for CUPS. |
3270670b | 5 | * |
3d94661a | 6 | * Copyright 2007-2010 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, |
b7382443 | 90 | _("lpadmin: Unable to connect to server: %s\n"), |
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 " | |
157fcea9 | 101 | "first\n")); |
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, |
b7382443 | 114 | _("lpadmin: Expected class name after \'-c\' " |
157fcea9 | 115 | "option\n")); |
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 " |
157fcea9 | 126 | "characters\n")); |
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, |
b7382443 | 143 | _("lpadmin: Unable to connect to server: %s\n"), |
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, |
b7382443 | 158 | _("lpadmin: Expected printer name after \'-d\' " |
157fcea9 | 159 | "option\n")); |
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 " |
157fcea9 | 170 | "printable characters\n")); |
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, |
b7382443 | 196 | _("lpadmin: Expected hostname after \'-h\' " |
157fcea9 | 197 | "option\n")); |
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, |
b7382443 | 215 | _("lpadmin: Expected interface after \'-i\' " |
157fcea9 | 216 | "option\n")); |
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 |
89fd567e | 233 | _cupsLangPrintf(stderr, |
157fcea9 | 234 | _("%s: Sorry, no encryption support compiled in\n"), |
b7382443 | 235 | argv[0]); |
bcf61448 | 236 | #endif /* HAVE_SSL */ |
1c9e0181 | 237 | break; |
238 | } | |
239 | ||
96ecd6f0 | 240 | if (!http) |
241 | { | |
192a8a08 | 242 | http = httpConnectEncrypt(cupsServer(), ippPort(), |
243 | cupsEncryption()); | |
96ecd6f0 | 244 | |
245 | if (http == NULL) | |
246 | { | |
89fd567e | 247 | _cupsLangPrintf(stderr, |
b7382443 | 248 | _("lpadmin: Unable to connect to server: %s\n"), |
249 | strerror(errno)); | |
96ecd6f0 | 250 | return (1); |
251 | } | |
1c9e0181 | 252 | } |
65a75084 | 253 | |
3b8ff70f | 254 | if (enable_printer(http, printer)) |
255 | return (1); | |
65a75084 | 256 | break; |
257 | ||
3270670b | 258 | case 'm' : /* Use the specified standard script/PPD file */ |
3270670b | 259 | if (argv[i][2]) |
6bff400e | 260 | num_options = cupsAddOption("ppd-name", argv[i] + 2, num_options, |
261 | &options); | |
3270670b | 262 | else |
263 | { | |
264 | i ++; | |
9c817392 | 265 | |
266 | if (i >= argc) | |
267 | { | |
89fd567e | 268 | _cupsLangPuts(stderr, |
b7382443 | 269 | _("lpadmin: Expected model after \'-m\' " |
157fcea9 | 270 | "option\n")); |
9c817392 | 271 | return (1); |
272 | } | |
273 | ||
6bff400e | 274 | num_options = cupsAddOption("ppd-name", argv[i], num_options, |
275 | &options); | |
3270670b | 276 | } |
3270670b | 277 | break; |
278 | ||
01a426e9 | 279 | case 'o' : /* Set option */ |
280 | if (argv[i][2]) | |
281 | num_options = cupsParseOptions(argv[i] + 2, num_options, &options); | |
282 | else | |
283 | { | |
284 | i ++; | |
285 | ||
286 | if (i >= argc) | |
287 | { | |
89fd567e | 288 | _cupsLangPuts(stderr, |
b7382443 | 289 | _("lpadmin: Expected name=value after \'-o\' " |
157fcea9 | 290 | "option\n")); |
01a426e9 | 291 | return (1); |
292 | } | |
293 | ||
294 | num_options = cupsParseOptions(argv[i], num_options, &options); | |
295 | } | |
296 | break; | |
297 | ||
3270670b | 298 | case 'p' : /* Add/modify a printer */ |
299 | if (argv[i][2]) | |
300 | printer = argv[i] + 2; | |
301 | else | |
302 | { | |
303 | i ++; | |
9c817392 | 304 | |
305 | if (i >= argc) | |
306 | { | |
89fd567e | 307 | _cupsLangPuts(stderr, |
b7382443 | 308 | _("lpadmin: Expected printer after \'-p\' " |
157fcea9 | 309 | "option\n")); |
9c817392 | 310 | return (1); |
311 | } | |
312 | ||
3270670b | 313 | printer = argv[i]; |
314 | } | |
808dd474 | 315 | |
9c817392 | 316 | if (!validate_name(printer)) |
317 | { | |
89fd567e | 318 | _cupsLangPuts(stderr, |
b7382443 | 319 | _("lpadmin: Printer name can only contain " |
157fcea9 | 320 | "printable characters\n")); |
9c817392 | 321 | return (1); |
322 | } | |
3270670b | 323 | break; |
324 | ||
325 | case 'r' : /* Remove printer from class */ | |
96ecd6f0 | 326 | if (!http) |
327 | { | |
192a8a08 | 328 | http = httpConnectEncrypt(cupsServer(), ippPort(), |
329 | cupsEncryption()); | |
96ecd6f0 | 330 | |
331 | if (http == NULL) | |
332 | { | |
89fd567e | 333 | _cupsLangPrintf(stderr, |
b7382443 | 334 | _("lpadmin: Unable to connect to server: %s\n"), |
335 | strerror(errno)); | |
96ecd6f0 | 336 | return (1); |
337 | } | |
338 | } | |
339 | ||
3270670b | 340 | if (printer == NULL) |
341 | { | |
89fd567e | 342 | _cupsLangPuts(stderr, |
b7382443 | 343 | _("lpadmin: Unable to remove a printer from the " |
344 | "class:\n" | |
345 | " You must specify a printer name " | |
157fcea9 | 346 | "first\n")); |
3270670b | 347 | return (1); |
348 | } | |
349 | ||
350 | if (argv[i][2]) | |
9c817392 | 351 | pclass = argv[i] + 2; |
3270670b | 352 | else |
353 | { | |
354 | i ++; | |
9c817392 | 355 | |
356 | if (i >= argc) | |
357 | { | |
89fd567e | 358 | _cupsLangPuts(stderr, |
b7382443 | 359 | _("lpadmin: Expected class after \'-r\' " |
157fcea9 | 360 | "option\n")); |
9c817392 | 361 | return (1); |
362 | } | |
363 | ||
364 | pclass = argv[i]; | |
3270670b | 365 | } |
9c817392 | 366 | |
367 | if (!validate_name(pclass)) | |
368 | { | |
89fd567e | 369 | _cupsLangPuts(stderr, |
b7382443 | 370 | _("lpadmin: Class name can only contain printable " |
157fcea9 | 371 | "characters\n")); |
9c817392 | 372 | return (1); |
373 | } | |
374 | ||
3b8ff70f | 375 | if (delete_printer_from_class(http, printer, pclass)) |
376 | return (1); | |
3270670b | 377 | break; |
378 | ||
5bce1394 | 379 | case 'U' : /* Username */ |
380 | if (argv[i][2] != '\0') | |
381 | cupsSetUser(argv[i] + 2); | |
382 | else | |
383 | { | |
384 | i ++; | |
385 | if (i >= argc) | |
386 | { | |
387 | _cupsLangPrintf(stderr, | |
388 | _("%s: Error - expected username after " | |
157fcea9 | 389 | "\'-U\' option\n"), |
5bce1394 | 390 | argv[0]); |
391 | return (1); | |
392 | } | |
393 | ||
394 | cupsSetUser(argv[i]); | |
395 | } | |
396 | break; | |
397 | ||
01a426e9 | 398 | case 'u' : /* Allow/deny users */ |
399 | if (argv[i][2]) | |
400 | val = argv[i] + 2; | |
401 | else | |
402 | { | |
403 | i ++; | |
404 | ||
405 | if (i >= argc) | |
406 | { | |
89fd567e | 407 | _cupsLangPuts(stderr, |
b7382443 | 408 | _("lpadmin: Expected allow/deny:userlist after " |
157fcea9 | 409 | "\'-u\' option\n")); |
01a426e9 | 410 | return (1); |
411 | } | |
412 | ||
413 | val = argv[i]; | |
414 | } | |
415 | ||
b7382443 | 416 | if (!strncasecmp(val, "allow:", 6)) |
01a426e9 | 417 | num_options = cupsAddOption("requesting-user-name-allowed", |
418 | val + 6, num_options, &options); | |
b7382443 | 419 | else if (!strncasecmp(val, "deny:", 5)) |
01a426e9 | 420 | num_options = cupsAddOption("requesting-user-name-denied", |
421 | val + 5, num_options, &options); | |
422 | else | |
423 | { | |
89fd567e | 424 | _cupsLangPrintf(stderr, |
157fcea9 | 425 | _("lpadmin: Unknown allow/deny option \"%s\"\n"), |
b7382443 | 426 | val); |
01a426e9 | 427 | return (1); |
428 | } | |
429 | break; | |
430 | ||
3270670b | 431 | case 'v' : /* Set the device-uri attribute */ |
3270670b | 432 | if (argv[i][2]) |
6bff400e | 433 | num_options = cupsAddOption("device-uri", argv[i] + 2, |
434 | num_options, &options); | |
3270670b | 435 | else |
436 | { | |
437 | i ++; | |
9c817392 | 438 | |
439 | if (i >= argc) | |
440 | { | |
89fd567e | 441 | _cupsLangPuts(stderr, |
b7382443 | 442 | _("lpadmin: Expected device URI after \'-v\' " |
157fcea9 | 443 | "option\n")); |
9c817392 | 444 | return (1); |
445 | } | |
446 | ||
6bff400e | 447 | num_options = cupsAddOption("device-uri", argv[i], |
448 | num_options, &options); | |
3270670b | 449 | } |
450 | break; | |
451 | ||
452 | case 'x' : /* Delete a printer */ | |
96ecd6f0 | 453 | if (!http) |
454 | { | |
192a8a08 | 455 | http = httpConnectEncrypt(cupsServer(), ippPort(), |
456 | cupsEncryption()); | |
96ecd6f0 | 457 | |
458 | if (http == NULL) | |
459 | { | |
89fd567e | 460 | _cupsLangPrintf(stderr, |
b7382443 | 461 | _("lpadmin: Unable to connect to server: %s\n"), |
462 | strerror(errno)); | |
96ecd6f0 | 463 | return (1); |
464 | } | |
465 | } | |
466 | ||
3270670b | 467 | if (argv[i][2]) |
468 | printer = argv[i] + 2; | |
469 | else | |
470 | { | |
471 | i ++; | |
9c817392 | 472 | |
473 | if (i >= argc) | |
474 | { | |
89fd567e | 475 | _cupsLangPuts(stderr, |
b7382443 | 476 | _("lpadmin: Expected printer or class after " |
157fcea9 | 477 | "\'-x\' option\n")); |
9c817392 | 478 | return (1); |
479 | } | |
480 | ||
3270670b | 481 | printer = argv[i]; |
482 | } | |
483 | ||
9c817392 | 484 | if (!validate_name(printer)) |
485 | { | |
89fd567e | 486 | _cupsLangPuts(stderr, |
b7382443 | 487 | _("lpadmin: Printer name can only contain " |
157fcea9 | 488 | "printable characters\n")); |
9c817392 | 489 | return (1); |
490 | } | |
491 | ||
3b8ff70f | 492 | if (delete_printer(http, printer)) |
493 | return (1); | |
494 | ||
3270670b | 495 | i = argc; |
496 | break; | |
497 | ||
498 | case 'D' : /* Set the printer-info attribute */ | |
3270670b | 499 | if (argv[i][2]) |
6bff400e | 500 | num_options = cupsAddOption("printer-info", argv[i] + 2, |
501 | num_options, &options); | |
3270670b | 502 | else |
503 | { | |
504 | i ++; | |
9c817392 | 505 | |
506 | if (i >= argc) | |
507 | { | |
89fd567e | 508 | _cupsLangPuts(stderr, |
b7382443 | 509 | _("lpadmin: Expected description after " |
157fcea9 | 510 | "\'-D\' option\n")); |
9c817392 | 511 | return (1); |
512 | } | |
513 | ||
6bff400e | 514 | num_options = cupsAddOption("printer-info", argv[i], |
515 | num_options, &options); | |
3270670b | 516 | } |
517 | break; | |
518 | ||
f8f971b2 | 519 | case 'I' : /* Set the supported file types (ignored) */ |
520 | i ++; | |
521 | ||
522 | if (i >= argc) | |
523 | { | |
89fd567e | 524 | _cupsLangPuts(stderr, |
b7382443 | 525 | _("lpadmin: Expected file type(s) after \'-I\' " |
157fcea9 | 526 | "option\n")); |
f8f971b2 | 527 | return (1); |
528 | } | |
529 | ||
89fd567e | 530 | _cupsLangPuts(stderr, |
157fcea9 | 531 | _("lpadmin: Warning - content type list ignored\n")); |
f8f971b2 | 532 | break; |
533 | ||
6c7527d1 | 534 | case 'L' : /* Set the printer-location attribute */ |
6c7527d1 | 535 | if (argv[i][2]) |
6bff400e | 536 | num_options = cupsAddOption("printer-location", argv[i] + 2, |
537 | num_options, &options); | |
6c7527d1 | 538 | else |
539 | { | |
540 | i ++; | |
9c817392 | 541 | |
542 | if (i >= argc) | |
543 | { | |
89fd567e | 544 | _cupsLangPuts(stderr, |
b7382443 | 545 | _("lpadmin: Expected location after \'-L\' " |
157fcea9 | 546 | "option\n")); |
9c817392 | 547 | return (1); |
548 | } | |
549 | ||
6bff400e | 550 | num_options = cupsAddOption("printer-location", argv[i], |
551 | num_options, &options); | |
6c7527d1 | 552 | } |
553 | break; | |
554 | ||
3270670b | 555 | case 'P' : /* Use the specified PPD file */ |
3270670b | 556 | if (argv[i][2]) |
6bff400e | 557 | file = argv[i] + 2; |
3270670b | 558 | else |
559 | { | |
560 | i ++; | |
9c817392 | 561 | |
562 | if (i >= argc) | |
563 | { | |
89fd567e | 564 | _cupsLangPuts(stderr, |
157fcea9 | 565 | _("lpadmin: Expected PPD after \'-P\' option\n")); |
9c817392 | 566 | return (1); |
567 | } | |
568 | ||
6bff400e | 569 | file = argv[i]; |
3270670b | 570 | } |
571 | break; | |
572 | ||
573 | default : | |
89fd567e | 574 | _cupsLangPrintf(stderr, |
157fcea9 | 575 | _("lpadmin: Unknown option \'%c\'\n"), argv[i][1]); |
3270670b | 576 | return (1); |
577 | } | |
578 | else | |
579 | { | |
157fcea9 | 580 | _cupsLangPrintf(stderr, _("lpadmin: Unknown argument \'%s\'\n"), |
b7382443 | 581 | argv[i]); |
3270670b | 582 | return (1); |
583 | } | |
584 | ||
01a426e9 | 585 | /* |
586 | * Set options as needed... | |
587 | */ | |
588 | ||
6bff400e | 589 | if (num_options || file) |
01a426e9 | 590 | { |
591 | if (!http) | |
592 | { | |
192a8a08 | 593 | http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); |
01a426e9 | 594 | |
595 | if (http == NULL) | |
596 | { | |
89fd567e | 597 | _cupsLangPrintf(stderr, |
b7382443 | 598 | _("lpadmin: Unable to connect to server: %s\n"), |
599 | strerror(errno)); | |
01a426e9 | 600 | return (1); |
601 | } | |
602 | } | |
603 | ||
604 | if (printer == NULL) | |
605 | { | |
89fd567e | 606 | _cupsLangPuts(stderr, |
b7382443 | 607 | _("lpadmin: Unable to set the printer options:\n" |
157fcea9 | 608 | " You must specify a printer name first\n")); |
01a426e9 | 609 | return (1); |
610 | } | |
611 | ||
6bff400e | 612 | if (set_printer_options(http, printer, num_options, options, file)) |
3b8ff70f | 613 | return (1); |
01a426e9 | 614 | } |
615 | ||
3270670b | 616 | if (printer == NULL) |
617 | { | |
89fd567e | 618 | _cupsLangPuts(stdout, |
b7382443 | 619 | _("Usage:\n" |
620 | "\n" | |
621 | " lpadmin [-h server] -d destination\n" | |
622 | " lpadmin [-h server] -x destination\n" | |
623 | " lpadmin [-h server] -p printer [-c add-class] " | |
624 | "[-i interface] [-m model]\n" | |
625 | " [-r remove-class] [-v device] " | |
626 | "[-D description]\n" | |
627 | " [-P ppd-file] [-o name=value]\n" | |
628 | " [-u allow:user,user] " | |
629 | "[-u deny:user,user]\n" | |
630 | "\n")); | |
3270670b | 631 | } |
632 | ||
96ecd6f0 | 633 | if (http) |
634 | httpClose(http); | |
3270670b | 635 | |
636 | return (0); | |
637 | } | |
638 | ||
639 | ||
640 | /* | |
641 | * 'add_printer_to_class()' - Add a printer to a class. | |
642 | */ | |
643 | ||
3b8ff70f | 644 | static int /* O - 0 on success, 1 on fail */ |
3270670b | 645 | add_printer_to_class(http_t *http, /* I - Server connection */ |
646 | char *printer, /* I - Printer to add */ | |
647 | char *pclass) /* I - Class to add to */ | |
648 | { | |
649 | int i; /* Looping var */ | |
650 | ipp_t *request, /* IPP Request */ | |
651 | *response; /* IPP Response */ | |
652 | ipp_attribute_t *attr, /* Current attribute */ | |
653 | *members; /* Members in class */ | |
3270670b | 654 | char uri[HTTP_MAX_URI]; /* URI for printer/class */ |
655 | ||
656 | ||
01a426e9 | 657 | DEBUG_printf(("add_printer_to_class(%p, \"%s\", \"%s\")\n", http, |
65a75084 | 658 | printer, pclass)); |
659 | ||
3270670b | 660 | /* |
661 | * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following | |
662 | * attributes: | |
663 | * | |
664 | * attributes-charset | |
665 | * attributes-natural-language | |
666 | * printer-uri | |
667 | */ | |
668 | ||
00f3aaf5 | 669 | request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); |
670 | ||
00a1fad8 | 671 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
672 | "localhost", 0, "/classes/%s", pclass); | |
3270670b | 673 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, |
674 | "printer-uri", NULL, uri); | |
675 | ||
676 | /* | |
677 | * Do the request and get back a response... | |
678 | */ | |
679 | ||
96ecd6f0 | 680 | response = cupsDoRequest(http, request, "/"); |
3270670b | 681 | |
682 | /* | |
683 | * Build a CUPS_ADD_CLASS request, which requires the following | |
684 | * attributes: | |
685 | * | |
686 | * attributes-charset | |
687 | * attributes-natural-language | |
688 | * printer-uri | |
689 | * member-uris | |
690 | */ | |
691 | ||
00f3aaf5 | 692 | request = ippNewRequest(CUPS_ADD_CLASS); |
3270670b | 693 | |
694 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, | |
695 | "printer-uri", NULL, uri); | |
696 | ||
697 | /* | |
698 | * See if the printer is already in the class... | |
699 | */ | |
700 | ||
701 | if (response != NULL && | |
702 | (members = ippFindAttribute(response, "member-names", IPP_TAG_NAME)) != NULL) | |
703 | for (i = 0; i < members->num_values; i ++) | |
704 | if (strcasecmp(printer, members->values[i].string.text) == 0) | |
705 | { | |
00f3aaf5 | 706 | _cupsLangPrintf(stderr, |
707 | _("lpadmin: Printer %s is already a member of class %s.\n"), | |
708 | printer, pclass); | |
3270670b | 709 | ippDelete(request); |
710 | ippDelete(response); | |
3b8ff70f | 711 | return (0); |
3270670b | 712 | } |
713 | ||
714 | /* | |
715 | * OK, the printer isn't part of the class, so add it... | |
716 | */ | |
717 | ||
00a1fad8 | 718 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
719 | "localhost", 0, "/printers/%s", printer); | |
3270670b | 720 | |
721 | if (response != NULL && | |
722 | (members = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL) | |
723 | { | |
724 | /* | |
725 | * Add the printer to the existing list... | |
726 | */ | |
727 | ||
728 | attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI, | |
729 | "member-uris", members->num_values + 1, NULL, NULL); | |
730 | for (i = 0; i < members->num_values; i ++) | |
c97b7208 | 731 | attr->values[i].string.text = _cupsStrAlloc(members->values[i].string.text); |
3270670b | 732 | |
c97b7208 | 733 | attr->values[i].string.text = _cupsStrAlloc(uri); |
3270670b | 734 | } |
735 | else | |
c97b7208 | 736 | ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris", NULL, |
737 | uri); | |
3270670b | 738 | |
739 | /* | |
740 | * Then send the request... | |
741 | */ | |
742 | ||
743 | ippDelete(response); | |
744 | ||
745 | if ((response = cupsDoRequest(http, request, "/admin/")) == NULL) | |
3b8ff70f | 746 | { |
00f3aaf5 | 747 | _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); |
3b8ff70f | 748 | |
749 | return (1); | |
750 | } | |
7b2e6b69 | 751 | else if (response->request.status.status_code > IPP_OK_CONFLICT) |
96ecd6f0 | 752 | { |
00f3aaf5 | 753 | _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); |
96ecd6f0 | 754 | |
3270670b | 755 | ippDelete(response); |
3b8ff70f | 756 | |
757 | return (1); | |
96ecd6f0 | 758 | } |
7b2e6b69 | 759 | else |
760 | { | |
761 | ippDelete(response); | |
3b8ff70f | 762 | |
7b2e6b69 | 763 | return (0); |
764 | } | |
3270670b | 765 | } |
766 | ||
767 | ||
768 | /* | |
769 | * 'default_printer()' - Set the default printing destination. | |
770 | */ | |
771 | ||
3b8ff70f | 772 | static int /* O - 0 on success, 1 on fail */ |
3270670b | 773 | default_printer(http_t *http, /* I - Server connection */ |
774 | char *printer) /* I - Printer name */ | |
775 | { | |
776 | ipp_t *request, /* IPP Request */ | |
777 | *response; /* IPP Response */ | |
3270670b | 778 | char uri[HTTP_MAX_URI]; /* URI for printer/class */ |
779 | ||
780 | ||
01a426e9 | 781 | DEBUG_printf(("default_printer(%p, \"%s\")\n", http, printer)); |
65a75084 | 782 | |
3270670b | 783 | /* |
784 | * Build a CUPS_SET_DEFAULT request, which requires the following | |
785 | * attributes: | |
786 | * | |
787 | * attributes-charset | |
788 | * attributes-natural-language | |
789 | * printer-uri | |
790 | */ | |
791 | ||
00a1fad8 | 792 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
793 | "localhost", 0, "/printers/%s", printer); | |
3270670b | 794 | |
00f3aaf5 | 795 | request = ippNewRequest(CUPS_SET_DEFAULT); |
3270670b | 796 | |
797 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, | |
798 | "printer-uri", NULL, uri); | |
799 | ||
800 | /* | |
801 | * Do the request and get back a response... | |
802 | */ | |
803 | ||
804 | if ((response = cupsDoRequest(http, request, "/admin/")) == NULL) | |
3b8ff70f | 805 | { |
00f3aaf5 | 806 | _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); |
3b8ff70f | 807 | |
808 | return (1); | |
809 | } | |
810 | else if (response->request.status.status_code > IPP_OK_CONFLICT) | |
3270670b | 811 | { |
00f3aaf5 | 812 | _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); |
3270670b | 813 | |
814 | ippDelete(response); | |
3b8ff70f | 815 | |
816 | return (1); | |
817 | } | |
818 | else | |
819 | { | |
820 | ippDelete(response); | |
821 | ||
822 | return (0); | |
3270670b | 823 | } |
824 | } | |
825 | ||
826 | ||
827 | /* | |
828 | * 'delete_printer()' - Delete a printer from the system... | |
829 | */ | |
830 | ||
3b8ff70f | 831 | static int /* O - 0 on success, 1 on fail */ |
3270670b | 832 | delete_printer(http_t *http, /* I - Server connection */ |
833 | char *printer) /* I - Printer to delete */ | |
834 | { | |
835 | ipp_t *request, /* IPP Request */ | |
836 | *response; /* IPP Response */ | |
3270670b | 837 | char uri[HTTP_MAX_URI]; /* URI for printer/class */ |
838 | ||
839 | ||
01a426e9 | 840 | DEBUG_printf(("delete_printer(%p, \"%s\")\n", http, printer)); |
65a75084 | 841 | |
3270670b | 842 | /* |
843 | * Build a CUPS_DELETE_PRINTER request, which requires the following | |
844 | * attributes: | |
845 | * | |
846 | * attributes-charset | |
847 | * attributes-natural-language | |
848 | * printer-uri | |
849 | */ | |
850 | ||
00f3aaf5 | 851 | request = ippNewRequest(CUPS_DELETE_PRINTER); |
852 | ||
00a1fad8 | 853 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
854 | "localhost", 0, "/printers/%s", printer); | |
3270670b | 855 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, |
856 | "printer-uri", NULL, uri); | |
857 | ||
858 | /* | |
859 | * Do the request and get back a response... | |
860 | */ | |
861 | ||
862 | if ((response = cupsDoRequest(http, request, "/admin/")) == NULL) | |
3b8ff70f | 863 | { |
00f3aaf5 | 864 | _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); |
3b8ff70f | 865 | |
866 | return (1); | |
867 | } | |
868 | else if (response->request.status.status_code > IPP_OK_CONFLICT) | |
3270670b | 869 | { |
00f3aaf5 | 870 | _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); |
3270670b | 871 | |
872 | ippDelete(response); | |
3b8ff70f | 873 | |
874 | return (1); | |
875 | } | |
876 | else | |
877 | { | |
878 | ippDelete(response); | |
879 | ||
880 | return (0); | |
3270670b | 881 | } |
882 | } | |
883 | ||
884 | ||
885 | /* | |
886 | * 'delete_printer_from_class()' - Delete a printer from a class. | |
887 | */ | |
888 | ||
3b8ff70f | 889 | static int /* O - 0 on success, 1 on fail */ |
00f3aaf5 | 890 | delete_printer_from_class( |
891 | http_t *http, /* I - Server connection */ | |
892 | char *printer, /* I - Printer to remove */ | |
893 | char *pclass) /* I - Class to remove from */ | |
3270670b | 894 | { |
895 | int i, j, k; /* Looping vars */ | |
896 | ipp_t *request, /* IPP Request */ | |
897 | *response; /* IPP Response */ | |
898 | ipp_attribute_t *attr, /* Current attribute */ | |
899 | *members; /* Members in class */ | |
3270670b | 900 | char uri[HTTP_MAX_URI]; /* URI for printer/class */ |
901 | ||
902 | ||
01a426e9 | 903 | DEBUG_printf(("delete_printer_from_class(%p, \"%s\", \"%s\")\n", http, |
65a75084 | 904 | printer, pclass)); |
905 | ||
3270670b | 906 | /* |
907 | * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following | |
908 | * attributes: | |
909 | * | |
910 | * attributes-charset | |
911 | * attributes-natural-language | |
912 | * printer-uri | |
913 | */ | |
914 | ||
00f3aaf5 | 915 | request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); |
916 | ||
00a1fad8 | 917 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
918 | "localhost", 0, "/classes/%s", pclass); | |
3270670b | 919 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, |
920 | "printer-uri", NULL, uri); | |
921 | ||
922 | /* | |
923 | * Do the request and get back a response... | |
924 | */ | |
925 | ||
926 | if ((response = cupsDoRequest(http, request, "/classes/")) == NULL || | |
0a3ac972 | 927 | response->request.status.status_code == IPP_NOT_FOUND) |
3270670b | 928 | { |
00f3aaf5 | 929 | _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); |
930 | ||
3270670b | 931 | ippDelete(response); |
00f3aaf5 | 932 | |
3b8ff70f | 933 | return (1); |
3270670b | 934 | } |
935 | ||
936 | /* | |
937 | * See if the printer is already in the class... | |
938 | */ | |
939 | ||
940 | if ((members = ippFindAttribute(response, "member-names", IPP_TAG_NAME)) == NULL) | |
941 | { | |
157fcea9 | 942 | _cupsLangPuts(stderr, _("lpadmin: No member names were seen\n")); |
00f3aaf5 | 943 | |
3270670b | 944 | ippDelete(response); |
00f3aaf5 | 945 | |
3b8ff70f | 946 | return (1); |
3270670b | 947 | } |
948 | ||
949 | for (i = 0; i < members->num_values; i ++) | |
00f3aaf5 | 950 | if (!strcasecmp(printer, members->values[i].string.text)) |
3270670b | 951 | break; |
952 | ||
953 | if (i >= members->num_values) | |
954 | { | |
00f3aaf5 | 955 | _cupsLangPrintf(stderr, |
956 | _("lpadmin: Printer %s is not a member of class %s.\n"), | |
957 | printer, pclass); | |
958 | ||
3270670b | 959 | ippDelete(response); |
00f3aaf5 | 960 | |
3b8ff70f | 961 | return (1); |
3270670b | 962 | } |
963 | ||
964 | if (members->num_values == 1) | |
965 | { | |
966 | /* | |
967 | * Build a CUPS_DELETE_CLASS request, which requires the following | |
968 | * attributes: | |
969 | * | |
970 | * attributes-charset | |
971 | * attributes-natural-language | |
972 | * printer-uri | |
973 | */ | |
974 | ||
00f3aaf5 | 975 | request = ippNewRequest(CUPS_DELETE_CLASS); |
3270670b | 976 | |
977 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, | |
978 | "printer-uri", NULL, uri); | |
979 | } | |
980 | else | |
981 | { | |
982 | /* | |
983 | * Build a CUPS_ADD_CLASS request, which requires the following | |
984 | * attributes: | |
985 | * | |
986 | * attributes-charset | |
987 | * attributes-natural-language | |
988 | * printer-uri | |
989 | * member-uris | |
990 | */ | |
991 | ||
00f3aaf5 | 992 | request = ippNewRequest(CUPS_ADD_CLASS); |
3270670b | 993 | |
994 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, | |
995 | "printer-uri", NULL, uri); | |
996 | ||
997 | /* | |
998 | * Delete the printer from the class... | |
999 | */ | |
1000 | ||
1001 | members = ippFindAttribute(response, "member-uris", IPP_TAG_URI); | |
1002 | attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI, | |
1003 | "member-uris", members->num_values - 1, NULL, NULL); | |
1004 | ||
1005 | for (j = 0, k = 0; j < members->num_values; j ++) | |
1006 | if (j != i) | |
c97b7208 | 1007 | attr->values[k ++].string.text = |
1008 | _cupsStrAlloc(members->values[j].string.text); | |
3270670b | 1009 | } |
1010 | ||
1011 | /* | |
1012 | * Then send the request... | |
1013 | */ | |
1014 | ||
1015 | ippDelete(response); | |
1016 | ||
1017 | if ((response = cupsDoRequest(http, request, "/admin/")) == NULL) | |
3b8ff70f | 1018 | { |
00f3aaf5 | 1019 | _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); |
1020 | ||
3b8ff70f | 1021 | return (1); |
1022 | } | |
1023 | else if (response->request.status.status_code > IPP_OK_CONFLICT) | |
96ecd6f0 | 1024 | { |
00f3aaf5 | 1025 | _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); |
96ecd6f0 | 1026 | |
3270670b | 1027 | ippDelete(response); |
3b8ff70f | 1028 | |
1029 | return (1); | |
1030 | } | |
1031 | else | |
1032 | { | |
1033 | ippDelete(response); | |
1034 | ||
1035 | return (0); | |
96ecd6f0 | 1036 | } |
3270670b | 1037 | } |
1038 | ||
1039 | ||
65a75084 | 1040 | /* |
1041 | * 'enable_printer()' - Enable a printer... | |
1042 | */ | |
1043 | ||
3b8ff70f | 1044 | static int /* O - 0 on success, 1 on fail */ |
65a75084 | 1045 | enable_printer(http_t *http, /* I - Server connection */ |
1046 | char *printer) /* I - Printer to enable */ | |
1047 | { | |
1048 | ipp_t *request, /* IPP Request */ | |
1049 | *response; /* IPP Response */ | |
65a75084 | 1050 | char uri[HTTP_MAX_URI]; /* URI for printer/class */ |
1051 | ||
1052 | ||
01a426e9 | 1053 | DEBUG_printf(("enable_printer(%p, \"%s\")\n", http, printer)); |
65a75084 | 1054 | |
1055 | /* | |
1056 | * Build a CUPS_ADD_PRINTER request, which requires the following | |
1057 | * attributes: | |
1058 | * | |
1059 | * attributes-charset | |
1060 | * attributes-natural-language | |
1061 | * printer-uri | |
1062 | * printer-state | |
1063 | * printer-is-accepting-jobs | |
1064 | */ | |
1065 | ||
00f3aaf5 | 1066 | request = ippNewRequest(CUPS_ADD_PRINTER); |
1067 | ||
00a1fad8 | 1068 | httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, |
1069 | "localhost", 0, "/printers/%s", printer); | |
65a75084 | 1070 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, |
1071 | "printer-uri", NULL, uri); | |
1072 | ||
1073 | ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state", | |
1074 | IPP_PRINTER_IDLE); | |
1075 | ||
1076 | ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1); | |
1077 | ||
1078 | /* | |
1079 | * Do the request and get back a response... | |
1080 | */ | |
1081 | ||
1082 | if ((response = cupsDoRequest(http, request, "/admin/")) == NULL) | |
3b8ff70f | 1083 | { |
00f3aaf5 | 1084 | _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); |
1085 | ||
3b8ff70f | 1086 | return (1); |
1087 | } | |
1088 | else if (response->request.status.status_code > IPP_OK_CONFLICT) | |
65a75084 | 1089 | { |
00f3aaf5 | 1090 | _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); |
65a75084 | 1091 | |
1092 | ippDelete(response); | |
3b8ff70f | 1093 | |
1094 | return (1); | |
1095 | } | |
1096 | else | |
1097 | { | |
1098 | ippDelete(response); | |
1099 | ||
1100 | return (0); | |
65a75084 | 1101 | } |
1102 | } | |
1103 | ||
1104 | ||
01a426e9 | 1105 | /* |
1106 | * 'set_printer_options()' - Set the printer options. | |
1107 | */ | |
1108 | ||
3b8ff70f | 1109 | static int /* O - 0 on success, 1 on fail */ |
00f3aaf5 | 1110 | set_printer_options( |
1111 | http_t *http, /* I - Server connection */ | |
1112 | char *printer, /* I - Printer */ | |
1113 | int num_options, /* I - Number of options */ | |
6bff400e | 1114 | cups_option_t *options, /* I - Options */ |
1115 | char *file) /* I - PPD file/interface script */ | |
01a426e9 | 1116 | { |
1117 | ipp_t *request, /* IPP Request */ | |
1118 | *response; /* IPP Response */ | |
5a3ef28d | 1119 | ipp_attribute_t *attr; /* IPP attribute */ |
5a3ef28d | 1120 | ipp_op_t op; /* Operation to perform */ |
a309520e | 1121 | const char *ppdfile; /* PPD filename */ |
1122 | int ppdchanged; /* PPD changed? */ | |
1123 | ppd_file_t *ppd; /* PPD file */ | |
1124 | ppd_choice_t *choice; /* Marked choice */ | |
01a426e9 | 1125 | char uri[HTTP_MAX_URI], /* URI for printer/class */ |
1126 | line[1024], /* Line from PPD file */ | |
1127 | keyword[1024], /* Keyword from Default line */ | |
1128 | *keyptr, /* Pointer into keyword... */ | |
1129 | tempfile[1024]; /* Temporary filename */ | |
6bff400e | 1130 | cups_file_t *in, /* PPD file */ |
01a426e9 | 1131 | *out; /* Temporary file */ |
0050629b | 1132 | const char *protocol, /* Old protocol option */ |
1133 | *customval; /* Custom option value */ | |
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 | ||
6bff400e | 1236 | if ((out = cupsTempFile2(tempfile, sizeof(tempfile))) < 0) |
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, |
b7382443 | 1248 | _("lpadmin: Unable to open PPD file \"%s\" - %s\n"), |
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 | { |
a309520e | 1262 | if (strncmp(line, "*Default", 8)) |
6bff400e | 1263 | cupsFilePrintf(out, "%s\n", line); |
01a426e9 | 1264 | else |
1265 | { | |
1266 | /* | |
1267 | * Get default option name... | |
1268 | */ | |
1269 | ||
def978d5 | 1270 | strlcpy(keyword, line + 8, sizeof(keyword)); |
01a426e9 | 1271 | |
1272 | for (keyptr = keyword; *keyptr; keyptr ++) | |
64bbab09 | 1273 | if (*keyptr == ':' || isspace(*keyptr & 255)) |
01a426e9 | 1274 | break; |
1275 | ||
a309520e | 1276 | *keyptr++ = '\0'; |
1277 | while (isspace(*keyptr & 255)) | |
1278 | keyptr ++; | |
01a426e9 | 1279 | |
42d6b787 | 1280 | if (!strcmp(keyword, "PageRegion") || |
1281 | !strcmp(keyword, "PageSize") || | |
1282 | !strcmp(keyword, "PaperDimension") || | |
1283 | !strcmp(keyword, "ImageableArea")) | |
1284 | { | |
1285 | if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) == NULL) | |
1286 | choice = ppdFindMarkedChoice(ppd, "PageRegion"); | |
1287 | } | |
01a426e9 | 1288 | else |
a309520e | 1289 | choice = ppdFindMarkedChoice(ppd, keyword); |
01a426e9 | 1290 | |
a309520e | 1291 | if (choice && strcmp(choice->choice, keyptr)) |
1292 | { | |
0050629b | 1293 | if (strcmp(choice->choice, "Custom")) |
1294 | { | |
1295 | cupsFilePrintf(out, "*Default%s: %s\n", keyword, choice->choice); | |
1296 | ppdchanged = 1; | |
1297 | } | |
1298 | else if ((customval = cupsGetOption(keyword, num_options, | |
1299 | options)) != NULL) | |
1300 | { | |
1301 | cupsFilePrintf(out, "*Default%s: %s\n", keyword, customval); | |
1302 | ppdchanged = 1; | |
1303 | } | |
1304 | else | |
1305 | cupsFilePrintf(out, "%s\n", line); | |
a309520e | 1306 | } |
01a426e9 | 1307 | else |
6bff400e | 1308 | cupsFilePrintf(out, "%s\n", line); |
01a426e9 | 1309 | } |
1310 | } | |
1311 | ||
6bff400e | 1312 | cupsFileClose(in); |
1313 | cupsFileClose(out); | |
a309520e | 1314 | ppdClose(ppd); |
01a426e9 | 1315 | |
1316 | /* | |
1317 | * Do the request... | |
1318 | */ | |
1319 | ||
a309520e | 1320 | ippDelete(cupsDoFileRequest(http, request, "/admin/", |
6bff400e | 1321 | ppdchanged ? tempfile : file)); |
01a426e9 | 1322 | |
1323 | /* | |
1324 | * Clean up temp files... (TODO: catch signals in case we CTRL-C during | |
1325 | * lpadmin) | |
1326 | */ | |
1327 | ||
6bff400e | 1328 | if (ppdfile != file) |
1329 | unlink(ppdfile); | |
01a426e9 | 1330 | unlink(tempfile); |
1331 | } | |
1332 | else | |
1333 | { | |
1334 | /* | |
1335 | * No PPD file - just set the options... | |
1336 | */ | |
1337 | ||
a309520e | 1338 | ippDelete(cupsDoRequest(http, request, "/admin/")); |
01a426e9 | 1339 | } |
1340 | ||
1341 | /* | |
5a3ef28d | 1342 | * Check the response... |
01a426e9 | 1343 | */ |
1344 | ||
00f3aaf5 | 1345 | if (cupsLastError() > IPP_OK_CONFLICT) |
01a426e9 | 1346 | { |
00f3aaf5 | 1347 | _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); |
3b8ff70f | 1348 | |
1349 | return (1); | |
1350 | } | |
1351 | else | |
3b8ff70f | 1352 | return (0); |
01a426e9 | 1353 | } |
1354 | ||
1355 | ||
6c7527d1 | 1356 | /* |
aa37e40e | 1357 | * 'validate_name()' - Make sure the printer name only contains valid chars. |
9c817392 | 1358 | */ |
1359 | ||
00f3aaf5 | 1360 | static int /* O - 0 if name is no good, 1 if name is good */ |
1361 | validate_name(const char *name) /* I - Name to check */ | |
9c817392 | 1362 | { |
00f3aaf5 | 1363 | const char *ptr; /* Pointer into name */ |
095bb32d | 1364 | |
1365 | ||
74bb2a4e | 1366 | /* |
1367 | * Scan the whole name... | |
1368 | */ | |
1369 | ||
095bb32d | 1370 | for (ptr = name; *ptr; ptr ++) |
1371 | if (*ptr == '@') | |
1372 | break; | |
a3901bc4 | 1373 | else if ((*ptr >= 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/' || |
1374 | *ptr == '#') | |
9c817392 | 1375 | return (0); |
9c817392 | 1376 | |
095bb32d | 1377 | /* |
1378 | * All the characters are good; validate the length, too... | |
1379 | */ | |
1380 | ||
1381 | return ((ptr - name) < 128); | |
9c817392 | 1382 | } |
1383 | ||
1384 | ||
1385 | /* | |
c9d3f842 | 1386 | * End of "$Id$". |
3270670b | 1387 | */ |