]> git.ipfire.org Git - thirdparty/cups.git/blame - systemv/lpinfo.c
Merge changes from CUPS 1.5svn-r8849.
[thirdparty/cups.git] / systemv / lpinfo.c
CommitLineData
ef416fc2 1/*
b19ccc9e 2 * "$Id: lpinfo.c 7810 2008-07-29 01:11:15Z mike $"
ef416fc2 3 *
4 * "lpinfo" command for the Common UNIX Printing System (CUPS).
5 *
4d301e69 6 * Copyright 2007-2009 by Apple Inc.
ef416fc2 7 * Copyright 1997-2006 by Easy Software Products.
8 *
9 * These coded instructions, statements, and computer programs are the
bc44d920 10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
ef416fc2 14 *
15 * Contents:
16 *
17 * main() - Parse options and show information.
ae71f5de 18 * device_cb - Device callback.
ef416fc2 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>
29#include <errno.h>
30#include <cups/string.h>
31#include <cups/cups.h>
32#include <cups/i18n.h>
33#include <cups/debug.h>
34
35
36/*
37 * Local functions...
38 */
39
ae71f5de
MS
40static void device_cb(const char *device_clas, const char *device_id,
41 const char *device_info,
42 const char *device_make_and_model,
749b1e90
MS
43 const char *device_uri, const char *device_location,
44 void *user_data);
ed6e7faf
MS
45static int show_devices(int long_status, int timeout,
46 const char *include_schemes,
47 const char *exclude_schemes);
48static int show_models(int long_status,
58dc1933 49 const char *device_id, const char *language,
ed6e7faf
MS
50 const char *make_model, const char *product,
51 const char *include_schemes,
52 const char *exclude_schemes);
ef416fc2 53
54
55/*
56 * 'main()' - Parse options and show status information.
57 */
58
59int
60main(int argc, /* I - Number of command-line arguments */
61 char *argv[]) /* I - Command-line arguments */
62{
63 int i; /* Looping var */
ef416fc2 64 int long_status; /* Long listing? */
58dc1933
MS
65 const char *device_id, /* 1284 device ID */
66 *language, /* Language */
67 *make_model, /* Make and model */
ed6e7faf
MS
68 *product, /* Product */
69 *include_schemes, /* Schemes to include */
70 *exclude_schemes; /* Schemes to exclude */
58dc1933 71 int timeout; /* Device timeout */
ef416fc2 72
73
07725fee 74 _cupsSetLocale(argv);
d09495fa 75
ed6e7faf
MS
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;
ef416fc2 84
85 for (i = 1; i < argc; i ++)
86 if (argv[i][0] == '-')
87 switch (argv[i][1])
88 {
89 case 'E' : /* Encrypt */
90#ifdef HAVE_SSL
91 cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
ef416fc2 92#else
fa73b229 93 _cupsLangPrintf(stderr,
4d301e69 94 _("%s: Sorry, no encryption support compiled in\n"),
ef416fc2 95 argv[0]);
96#endif /* HAVE_SSL */
97 break;
98
58dc1933 99 case 'h' : /* Connect to host */
58dc1933
MS
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,
4d301e69 109 _("Error: need hostname after \'-h\' option\n"));
58dc1933
MS
110 return (1);
111 }
112
113 cupsSetServer(argv[i]);
114 }
115 break;
116
ef416fc2 117 case 'l' : /* Show long listing */
118 long_status = 1;
119 break;
120
121 case 'm' : /* Show models */
ed6e7faf
MS
122 if (show_models(long_status, device_id, language, make_model,
123 product, include_schemes, exclude_schemes))
ef416fc2 124 return (1);
125 break;
126
127 case 'v' : /* Show available devices */
ed6e7faf
MS
128 if (show_devices(long_status, timeout, include_schemes,
129 exclude_schemes))
ef416fc2 130 return (1);
131 break;
132
58dc1933
MS
133 case '-' : /* --something */
134 if (!strcmp(argv[i], "--device-id"))
ef416fc2 135 {
58dc1933 136 i ++;
ef416fc2 137
58dc1933
MS
138 if (i < argc)
139 device_id = argv[i];
140 else
141 {
142 _cupsLangPuts(stderr,
143 _("lpinfo: Expected 1284 device ID string "
4d301e69 144 "after --device-id\n"));
58dc1933
MS
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 }
ed6e7faf
MS
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 "
4d301e69 162 "--exclude-schemes\n"));
ed6e7faf
MS
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 "
4d301e69 180 "--include-schemes\n"));
ed6e7faf
MS
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 }
58dc1933 188 else if (!strcmp(argv[i], "--language"))
ef416fc2 189 {
190 i ++;
58dc1933
MS
191 if (i < argc)
192 language = argv[i];
193 else
ef416fc2 194 {
58dc1933
MS
195 _cupsLangPuts(stderr,
196 _("lpinfo: Expected language after "
4d301e69 197 "--language\n"));
ef416fc2 198 return (1);
58dc1933
MS
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 "
4d301e69 214 "--make-and-model\n"));
58dc1933
MS
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 "
4d301e69 231 "--product\n"));
58dc1933
MS
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,
4d301e69 247 _("lpinfo: Expected timeout after --timeout\n"));
58dc1933
MS
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 {
4d301e69 257 _cupsLangPrintf(stderr, _("lpinfo: Unknown option \'%s\'\n"),
58dc1933
MS
258 argv[i]);
259 return (1);
ef416fc2 260 }
261 break;
262
263 default :
4d301e69 264 _cupsLangPrintf(stderr, _("lpinfo: Unknown option \'%c\'\n"),
ef416fc2 265 argv[i][1]);
266 return (1);
267 }
268 else
269 {
4d301e69 270 _cupsLangPrintf(stderr, _("lpinfo: Unknown argument \'%s\'\n"),
ef416fc2 271 argv[i]);
272 return (1);
273 }
274
275 return (0);
276}
277
278
279/*
ae71f5de 280 * 'device_cb()' - Device callback.
ef416fc2 281 */
282
ae71f5de
MS
283static void
284device_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 */
749b1e90 290 const char *device_location, /* I - device-location string */
ae71f5de 291 void *user_data) /* I - User data */
ef416fc2 292{
ae71f5de 293 int *long_status; /* Show verbose info? */
ef416fc2 294
ef416fc2 295
296 /*
ae71f5de 297 * Display the device...
ef416fc2 298 */
299
ae71f5de 300 long_status = (int *)user_data;
ef416fc2 301
ae71f5de 302 if (*long_status)
ef416fc2 303 {
ae71f5de
MS
304 _cupsLangPrintf(stdout,
305 _("Device: uri = %s\n"
306 " class = %s\n"
307 " info = %s\n"
308 " make-and-model = %s\n"
749b1e90
MS
309 " device-id = %s\n"
310 " location = %s\n"),
ae71f5de 311 device_uri, device_class, device_info,
749b1e90 312 device_make_and_model, device_id, device_location);
ae71f5de
MS
313 }
314 else
315 _cupsLangPrintf(stdout, "%s %s\n", device_class, device_uri);
316}
ef416fc2 317
ef416fc2 318
ae71f5de
MS
319/*
320 * 'show_devices()' - Show available devices.
321 */
ef416fc2 322
ae71f5de 323static int /* O - 0 on success, 1 on failure */
ed6e7faf
MS
324show_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 */
ae71f5de 329{
ed6e7faf
MS
330 if (cupsGetDevices(CUPS_HTTP_DEFAULT, timeout, include_schemes,
331 exclude_schemes, device_cb, &long_status) != IPP_OK)
ef416fc2 332 {
fa73b229 333 _cupsLangPrintf(stderr, "lpinfo: %s\n", cupsLastErrorString());
ef416fc2 334 return (1);
335 }
336
337 return (0);
338}
339
340
341/*
342 * 'show_models()' - Show available PPDs.
343 */
344
345static int /* O - 0 on success, 1 on failure */
ed6e7faf
MS
346show_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 */
ef416fc2 354{
355 ipp_t *request, /* IPP Request */
356 *response; /* IPP Response */
357 ipp_attribute_t *attr; /* Current attribute */
fa73b229 358 const char *ppd_device_id, /* Pointer to ppd-device-id */
359 *ppd_language, /* Pointer to ppd-natural-language */
58dc1933 360 *ppd_make_model, /* Pointer to ppd-make-and-model */
fa73b229 361 *ppd_name; /* Pointer to ppd-name */
ed6e7faf 362 cups_option_t option; /* in/exclude-schemes option */
ef416fc2 363
364
ef416fc2 365 /*
58dc1933 366 * Build a CUPS_GET_PPDS request...
ef416fc2 367 */
368
fa73b229 369 request = ippNewRequest(CUPS_GET_PPDS);
ef416fc2 370
58dc1933
MS
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
ed6e7faf
MS
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
ef416fc2 400 /*
401 * Do the request and get back a response...
402 */
403
ed6e7faf 404 if ((response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) != NULL)
ef416fc2 405 {
406 /*
407 * Loop through the device list and display them...
408 */
409
410 if (response->request.status.status_code > IPP_OK_CONFLICT)
411 {
fa73b229 412 _cupsLangPrintf(stderr, "lpinfo: %s\n", cupsLastErrorString());
ef416fc2 413 ippDelete(response);
414 return (1);
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
58dc1933
MS
433 ppd_device_id = "NONE";
434 ppd_language = NULL;
435 ppd_make_model = NULL;
436 ppd_name = NULL;
ef416fc2 437
438 while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
439 {
fa73b229 440 if (!strcmp(attr->name, "ppd-device-id") &&
ef416fc2 441 attr->value_tag == IPP_TAG_TEXT)
fa73b229 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)
58dc1933 448 ppd_make_model = attr->values[0].string.text;
fa73b229 449 else if (!strcmp(attr->name, "ppd-name") &&
450 attr->value_tag == IPP_TAG_NAME)
ef416fc2 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
58dc1933 460 if (ppd_language == NULL || ppd_make_model == NULL || ppd_name == NULL)
ef416fc2 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 {
fa73b229 474 _cupsLangPrintf(stdout,
ef416fc2 475 _("Model: name = %s\n"
476 " natural_language = %s\n"
fa73b229 477 " make-and-model = %s\n"
478 " device-id = %s\n"),
58dc1933 479 ppd_name, ppd_language, ppd_make_model, ppd_device_id);
ef416fc2 480 }
481 else
58dc1933 482 _cupsLangPrintf(stdout, "%s %s\n", ppd_name, ppd_make_model);
ef416fc2 483
484 if (attr == NULL)
485 break;
486 }
487
488 ippDelete(response);
489 }
490 else
491 {
fa73b229 492 _cupsLangPrintf(stderr, "lpinfo: %s\n", cupsLastErrorString());
ef416fc2 493
494 return (1);
495 }
496
497 return (0);
498}
499
500
501/*
b19ccc9e 502 * End of "$Id: lpinfo.c 7810 2008-07-29 01:11:15Z mike $".
ef416fc2 503 */