]>
Commit | Line | Data |
---|---|---|
38138d28 | 1 | /* |
b2e10895 | 2 | * "$Id$" |
38138d28 | 3 | * |
4 | * "lpinfo" command for the Common UNIX Printing System (CUPS). | |
5 | * | |
4e8d321f | 6 | * Copyright 2007 by Apple Inc. |
0e66904d | 7 | * Copyright 1997-2006 by Easy Software Products. |
38138d28 | 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/". | |
38138d28 | 14 | * |
15 | * Contents: | |
16 | * | |
17 | * main() - Parse options and show information. | |
7e8f437e | 18 | * device_cb - Device callback. |
38138d28 | 19 | * show_devices() - Show available devices. |
20 | * show_models() - Show available PPDs. | |
21 | */ | |
22 | ||
23 | /* | |
24 | * Include necessary headers... | |
25 | */ | |
26 | ||
27 | #include <stdio.h> | |
28 | #include <stdlib.h> | |
b7382443 | 29 | #include <errno.h> |
30 | #include <cups/string.h> | |
38138d28 | 31 | #include <cups/cups.h> |
b7382443 | 32 | #include <cups/i18n.h> |
38138d28 | 33 | #include <cups/debug.h> |
38138d28 | 34 | |
35 | ||
36 | /* | |
37 | * Local functions... | |
38 | */ | |
39 | ||
7e8f437e | 40 | static void device_cb(const char *device_clas, const char *device_id, |
41 | const char *device_info, | |
42 | const char *device_make_and_model, | |
2317ac1e | 43 | const char *device_uri, const char *device_location, |
44 | void *user_data); | |
05e571cf | 45 | static int show_devices(int long_status, int timeout, |
46 | const char *include_schemes, | |
47 | const char *exclude_schemes); | |
48 | static int show_models(int long_status, | |
904836ce | 49 | const char *device_id, const char *language, |
05e571cf | 50 | const char *make_model, const char *product, |
51 | const char *include_schemes, | |
52 | const char *exclude_schemes); | |
38138d28 | 53 | |
54 | ||
55 | /* | |
56 | * 'main()' - Parse options and show status information. | |
57 | */ | |
58 | ||
59 | int | |
b7382443 | 60 | main(int argc, /* I - Number of command-line arguments */ |
61 | char *argv[]) /* I - Command-line arguments */ | |
38138d28 | 62 | { |
b7382443 | 63 | int i; /* Looping var */ |
b7382443 | 64 | int long_status; /* Long listing? */ |
904836ce | 65 | const char *device_id, /* 1284 device ID */ |
66 | *language, /* Language */ | |
67 | *make_model, /* Make and model */ | |
05e571cf | 68 | *product, /* Product */ |
69 | *include_schemes, /* Schemes to include */ | |
70 | *exclude_schemes; /* Schemes to exclude */ | |
904836ce | 71 | int timeout; /* Device timeout */ |
38138d28 | 72 | |
73 | ||
156dd8aa | 74 | _cupsSetLocale(argv); |
ebad28ad | 75 | |
05e571cf | 76 | long_status = 0; |
77 | device_id = NULL; | |
78 | language = NULL; | |
79 | make_model = NULL; | |
80 | product = NULL; | |
81 | include_schemes = CUPS_INCLUDE_ALL; | |
82 | exclude_schemes = CUPS_EXCLUDE_NONE; | |
83 | timeout = CUPS_TIMEOUT_DEFAULT; | |
38138d28 | 84 | |
85 | for (i = 1; i < argc; i ++) | |
86 | if (argv[i][0] == '-') | |
87 | switch (argv[i][1]) | |
88 | { | |
1c9e0181 | 89 | case 'E' : /* Encrypt */ |
bcf61448 | 90 | #ifdef HAVE_SSL |
192a8a08 | 91 | cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); |
1c9e0181 | 92 | #else |
89fd567e | 93 | _cupsLangPrintf(stderr, |
b7382443 | 94 | _("%s: Sorry, no encryption support compiled in!\n"), |
95 | argv[0]); | |
bcf61448 | 96 | #endif /* HAVE_SSL */ |
1c9e0181 | 97 | break; |
98 | ||
904836ce | 99 | case 'h' : /* Connect to host */ |
904836ce | 100 | if (argv[i][2] != '\0') |
101 | cupsSetServer(argv[i] + 2); | |
102 | else | |
103 | { | |
104 | i ++; | |
105 | ||
106 | if (i >= argc) | |
107 | { | |
108 | _cupsLangPuts(stderr, | |
109 | _("Error: need hostname after \'-h\' option!\n")); | |
110 | return (1); | |
111 | } | |
112 | ||
113 | cupsSetServer(argv[i]); | |
114 | } | |
115 | break; | |
116 | ||
38138d28 | 117 | case 'l' : /* Show long listing */ |
118 | long_status = 1; | |
119 | break; | |
120 | ||
121 | case 'm' : /* Show models */ | |
05e571cf | 122 | if (show_models(long_status, device_id, language, make_model, |
123 | product, include_schemes, exclude_schemes)) | |
b2e10895 | 124 | return (1); |
38138d28 | 125 | break; |
126 | ||
127 | case 'v' : /* Show available devices */ | |
05e571cf | 128 | if (show_devices(long_status, timeout, include_schemes, |
129 | exclude_schemes)) | |
b2e10895 | 130 | return (1); |
38138d28 | 131 | break; |
132 | ||
904836ce | 133 | case '-' : /* --something */ |
134 | if (!strcmp(argv[i], "--device-id")) | |
192a8a08 | 135 | { |
904836ce | 136 | i ++; |
38138d28 | 137 | |
904836ce | 138 | if (i < argc) |
139 | device_id = argv[i]; | |
140 | else | |
141 | { | |
142 | _cupsLangPuts(stderr, | |
143 | _("lpinfo: Expected 1284 device ID string " | |
144 | "after --device-id!\n")); | |
145 | return (1); | |
146 | } | |
147 | } | |
148 | else if (!strncmp(argv[i], "--device-id=", 12) && argv[i][12]) | |
149 | { | |
150 | device_id = argv[i] + 12; | |
151 | } | |
05e571cf | 152 | else if (!strcmp(argv[i], "--exclude-schemes")) |
153 | { | |
154 | i ++; | |
155 | ||
156 | if (i < argc) | |
157 | exclude_schemes = argv[i]; | |
158 | else | |
159 | { | |
160 | _cupsLangPuts(stderr, | |
161 | _("lpinfo: Expected scheme list after " | |
162 | "--exclude-schemes!\n")); | |
163 | return (1); | |
164 | } | |
165 | } | |
166 | else if (!strncmp(argv[i], "--exclude-schemes=", 18) && argv[i][18]) | |
167 | { | |
168 | exclude_schemes = argv[i] + 18; | |
169 | } | |
170 | else if (!strcmp(argv[i], "--include-schemes")) | |
171 | { | |
172 | i ++; | |
173 | ||
174 | if (i < argc) | |
175 | include_schemes = argv[i]; | |
176 | else | |
177 | { | |
178 | _cupsLangPuts(stderr, | |
179 | _("lpinfo: Expected scheme list after " | |
180 | "--include-schemes!\n")); | |
181 | return (1); | |
182 | } | |
183 | } | |
184 | else if (!strncmp(argv[i], "--include-schemes=", 18) && argv[i][18]) | |
185 | { | |
186 | include_schemes = argv[i] + 18; | |
187 | } | |
904836ce | 188 | else if (!strcmp(argv[i], "--language")) |
38138d28 | 189 | { |
190 | i ++; | |
904836ce | 191 | if (i < argc) |
192 | language = argv[i]; | |
193 | else | |
38138d28 | 194 | { |
904836ce | 195 | _cupsLangPuts(stderr, |
196 | _("lpinfo: Expected language after " | |
197 | "--language!\n")); | |
38138d28 | 198 | return (1); |
904836ce | 199 | } |
200 | } | |
201 | else if (!strncmp(argv[i], "--language=", 11) && argv[i][11]) | |
202 | { | |
203 | language = argv[i] + 11; | |
204 | } | |
205 | else if (!strcmp(argv[i], "--make-and-model")) | |
206 | { | |
207 | i ++; | |
208 | if (i < argc) | |
209 | make_model= argv[i]; | |
210 | else | |
211 | { | |
212 | _cupsLangPuts(stderr, | |
213 | _("lpinfo: Expected make and model after " | |
214 | "--make-and-model!\n")); | |
215 | return (1); | |
216 | } | |
217 | } | |
218 | else if (!strncmp(argv[i], "--make-and-model=", 17) && argv[i][17]) | |
219 | { | |
220 | make_model = argv[i] + 17; | |
221 | } | |
222 | else if (!strcmp(argv[i], "--product")) | |
223 | { | |
224 | i ++; | |
225 | if (i < argc) | |
226 | product = argv[i]; | |
227 | else | |
228 | { | |
229 | _cupsLangPuts(stderr, | |
230 | _("lpinfo: Expected product string after " | |
231 | "--product!\n")); | |
232 | return (1); | |
233 | } | |
234 | } | |
235 | else if (!strncmp(argv[i], "--product=", 10) && argv[i][10]) | |
236 | { | |
237 | product = argv[i] + 10; | |
238 | } | |
239 | else if (!strcmp(argv[i], "--timeout")) | |
240 | { | |
241 | i ++; | |
242 | if (i < argc) | |
243 | timeout = atoi(argv[i]); | |
244 | else | |
245 | { | |
246 | _cupsLangPuts(stderr, | |
247 | _("lpinfo: Expected timeout after --timeout!\n")); | |
248 | return (1); | |
249 | } | |
250 | } | |
251 | else if (!strncmp(argv[i], "--timeout=", 10) && argv[i][10]) | |
252 | { | |
253 | timeout = atoi(argv[i] + 10); | |
254 | } | |
255 | else | |
256 | { | |
257 | _cupsLangPrintf(stderr, _("lpinfo: Unknown option \'%s\'!\n"), | |
258 | argv[i]); | |
259 | return (1); | |
38138d28 | 260 | } |
261 | break; | |
262 | ||
263 | default : | |
89fd567e | 264 | _cupsLangPrintf(stderr, _("lpinfo: Unknown option \'%c\'!\n"), |
b7382443 | 265 | argv[i][1]); |
38138d28 | 266 | return (1); |
267 | } | |
268 | else | |
269 | { | |
89fd567e | 270 | _cupsLangPrintf(stderr, _("lpinfo: Unknown argument \'%s\'!\n"), |
b7382443 | 271 | argv[i]); |
38138d28 | 272 | return (1); |
273 | } | |
274 | ||
275 | return (0); | |
276 | } | |
277 | ||
278 | ||
279 | /* | |
7e8f437e | 280 | * 'device_cb()' - Device callback. |
38138d28 | 281 | */ |
282 | ||
7e8f437e | 283 | static void |
284 | device_cb( | |
285 | const char *device_class, /* I - device-class string */ | |
286 | const char *device_id, /* I - device-id string */ | |
287 | const char *device_info, /* I - device-info string */ | |
288 | const char *device_make_and_model, /* I - device-make-and-model string */ | |
289 | const char *device_uri, /* I - device-uri string */ | |
2317ac1e | 290 | const char *device_location, /* I - device-location string */ |
7e8f437e | 291 | void *user_data) /* I - User data */ |
38138d28 | 292 | { |
7e8f437e | 293 | int *long_status; /* Show verbose info? */ |
38138d28 | 294 | |
38138d28 | 295 | |
296 | /* | |
7e8f437e | 297 | * Display the device... |
38138d28 | 298 | */ |
299 | ||
7e8f437e | 300 | long_status = (int *)user_data; |
38138d28 | 301 | |
7e8f437e | 302 | if (*long_status) |
38138d28 | 303 | { |
7e8f437e | 304 | _cupsLangPrintf(stdout, |
305 | _("Device: uri = %s\n" | |
306 | " class = %s\n" | |
307 | " info = %s\n" | |
308 | " make-and-model = %s\n" | |
2317ac1e | 309 | " device-id = %s\n" |
310 | " location = %s\n"), | |
7e8f437e | 311 | device_uri, device_class, device_info, |
2317ac1e | 312 | device_make_and_model, device_id, device_location); |
7e8f437e | 313 | } |
314 | else | |
315 | _cupsLangPrintf(stdout, "%s %s\n", device_class, device_uri); | |
316 | } | |
38138d28 | 317 | |
38138d28 | 318 | |
7e8f437e | 319 | /* |
320 | * 'show_devices()' - Show available devices. | |
321 | */ | |
38138d28 | 322 | |
7e8f437e | 323 | static int /* O - 0 on success, 1 on failure */ |
05e571cf | 324 | show_devices( |
325 | int long_status, /* I - Long status report? */ | |
326 | int timeout, /* I - Timeout */ | |
327 | const char *include_schemes, /* I - List of schemes to include */ | |
328 | const char *exclude_schemes) /* I - List of schemes to exclude */ | |
7e8f437e | 329 | { |
05e571cf | 330 | if (cupsGetDevices(CUPS_HTTP_DEFAULT, timeout, include_schemes, |
331 | exclude_schemes, device_cb, &long_status) != IPP_OK) | |
b2e10895 | 332 | { |
00f3aaf5 | 333 | _cupsLangPrintf(stderr, "lpinfo: %s\n", cupsLastErrorString()); |
b2e10895 | 334 | return (1); |
335 | } | |
336 | ||
337 | return (0); | |
38138d28 | 338 | } |
339 | ||
340 | ||
341 | /* | |
342 | * 'show_models()' - Show available PPDs. | |
343 | */ | |
344 | ||
b7382443 | 345 | static int /* O - 0 on success, 1 on failure */ |
05e571cf | 346 | show_models( |
347 | int long_status, /* I - Long status report? */ | |
348 | const char *device_id, /* I - 1284 device ID */ | |
349 | const char *language, /* I - Language */ | |
350 | const char *make_model, /* I - Make and model */ | |
351 | const char *product, /* I - Product */ | |
352 | const char *include_schemes, /* I - List of schemes to include */ | |
353 | const char *exclude_schemes) /* I - List of schemes to exclude */ | |
38138d28 | 354 | { |
b7382443 | 355 | ipp_t *request, /* IPP Request */ |
356 | *response; /* IPP Response */ | |
357 | ipp_attribute_t *attr; /* Current attribute */ | |
00f3aaf5 | 358 | const char *ppd_device_id, /* Pointer to ppd-device-id */ |
359 | *ppd_language, /* Pointer to ppd-natural-language */ | |
904836ce | 360 | *ppd_make_model, /* Pointer to ppd-make-and-model */ |
00f3aaf5 | 361 | *ppd_name; /* Pointer to ppd-name */ |
05e571cf | 362 | cups_option_t option; /* in/exclude-schemes option */ |
38138d28 | 363 | |
364 | ||
38138d28 | 365 | /* |
904836ce | 366 | * Build a CUPS_GET_PPDS request... |
38138d28 | 367 | */ |
368 | ||
00f3aaf5 | 369 | request = ippNewRequest(CUPS_GET_PPDS); |
38138d28 | 370 | |
904836ce | 371 | if (device_id) |
372 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, "ppd-device-id", | |
373 | NULL, device_id); | |
374 | if (language) | |
375 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "ppd-language", | |
376 | NULL, language); | |
377 | if (make_model) | |
378 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, "ppd-make-and-model", | |
379 | NULL, make_model); | |
380 | if (product) | |
381 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, "ppd-product", | |
382 | NULL, product); | |
383 | ||
05e571cf | 384 | if (include_schemes) |
385 | { | |
386 | option.name = "include-schemes"; | |
387 | option.value = (char *)include_schemes; | |
388 | ||
389 | cupsEncodeOptions2(request, 1, &option, IPP_TAG_OPERATION); | |
390 | } | |
391 | ||
392 | if (exclude_schemes) | |
393 | { | |
394 | option.name = "exclude-schemes"; | |
395 | option.value = (char *)exclude_schemes; | |
396 | ||
397 | cupsEncodeOptions2(request, 1, &option, IPP_TAG_OPERATION); | |
398 | } | |
399 | ||
38138d28 | 400 | /* |
401 | * Do the request and get back a response... | |
402 | */ | |
403 | ||
05e571cf | 404 | if ((response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) != NULL) |
38138d28 | 405 | { |
406 | /* | |
407 | * Loop through the device list and display them... | |
408 | */ | |
409 | ||
0a3ac972 | 410 | if (response->request.status.status_code > IPP_OK_CONFLICT) |
38138d28 | 411 | { |
00f3aaf5 | 412 | _cupsLangPrintf(stderr, "lpinfo: %s\n", cupsLastErrorString()); |
38138d28 | 413 | ippDelete(response); |
b2e10895 | 414 | return (1); |
38138d28 | 415 | } |
416 | ||
417 | for (attr = response->attrs; attr != NULL; attr = attr->next) | |
418 | { | |
419 | /* | |
420 | * Skip leading attributes until we hit a PPD... | |
421 | */ | |
422 | ||
423 | while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) | |
424 | attr = attr->next; | |
425 | ||
426 | if (attr == NULL) | |
427 | break; | |
428 | ||
429 | /* | |
430 | * Pull the needed attributes from this PPD... | |
431 | */ | |
432 | ||
904836ce | 433 | ppd_device_id = "NONE"; |
434 | ppd_language = NULL; | |
435 | ppd_make_model = NULL; | |
436 | ppd_name = NULL; | |
38138d28 | 437 | |
438 | while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) | |
439 | { | |
00f3aaf5 | 440 | if (!strcmp(attr->name, "ppd-device-id") && |
38138d28 | 441 | attr->value_tag == IPP_TAG_TEXT) |
00f3aaf5 | 442 | ppd_device_id = attr->values[0].string.text; |
443 | else if (!strcmp(attr->name, "ppd-natural-language") && | |
444 | attr->value_tag == IPP_TAG_LANGUAGE) | |
445 | ppd_language = attr->values[0].string.text; | |
446 | else if (!strcmp(attr->name, "ppd-make-and-model") && | |
447 | attr->value_tag == IPP_TAG_TEXT) | |
904836ce | 448 | ppd_make_model = attr->values[0].string.text; |
00f3aaf5 | 449 | else if (!strcmp(attr->name, "ppd-name") && |
450 | attr->value_tag == IPP_TAG_NAME) | |
38138d28 | 451 | ppd_name = attr->values[0].string.text; |
452 | ||
453 | attr = attr->next; | |
454 | } | |
455 | ||
456 | /* | |
457 | * See if we have everything needed... | |
458 | */ | |
459 | ||
904836ce | 460 | if (ppd_language == NULL || ppd_make_model == NULL || ppd_name == NULL) |
38138d28 | 461 | { |
462 | if (attr == NULL) | |
463 | break; | |
464 | else | |
465 | continue; | |
466 | } | |
467 | ||
468 | /* | |
469 | * Display the device... | |
470 | */ | |
471 | ||
472 | if (long_status) | |
473 | { | |
89fd567e | 474 | _cupsLangPrintf(stdout, |
b7382443 | 475 | _("Model: name = %s\n" |
476 | " natural_language = %s\n" | |
00f3aaf5 | 477 | " make-and-model = %s\n" |
478 | " device-id = %s\n"), | |
904836ce | 479 | ppd_name, ppd_language, ppd_make_model, ppd_device_id); |
38138d28 | 480 | } |
481 | else | |
904836ce | 482 | _cupsLangPrintf(stdout, "%s %s\n", ppd_name, ppd_make_model); |
38138d28 | 483 | |
484 | if (attr == NULL) | |
485 | break; | |
486 | } | |
487 | ||
488 | ippDelete(response); | |
489 | } | |
490 | else | |
b2e10895 | 491 | { |
00f3aaf5 | 492 | _cupsLangPrintf(stderr, "lpinfo: %s\n", cupsLastErrorString()); |
b2e10895 | 493 | |
494 | return (1); | |
495 | } | |
496 | ||
497 | return (0); | |
38138d28 | 498 | } |
499 | ||
500 | ||
501 | /* | |
b2e10895 | 502 | * End of "$Id$". |
38138d28 | 503 | */ |