]> git.ipfire.org Git - thirdparty/cups.git/blob - systemv/lpinfo.c
Merge changes from CUPS 1.5svn-r8849.
[thirdparty/cups.git] / systemv / lpinfo.c
1 /*
2 * "$Id: lpinfo.c 7810 2008-07-29 01:11:15Z mike $"
3 *
4 * "lpinfo" command for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 2007-2009 by Apple Inc.
7 * Copyright 1997-2006 by Easy Software Products.
8 *
9 * These coded instructions, statements, and computer programs are the
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/".
14 *
15 * Contents:
16 *
17 * main() - Parse options and show information.
18 * device_cb - Device callback.
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
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,
43 const char *device_uri, const char *device_location,
44 void *user_data);
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,
49 const char *device_id, const char *language,
50 const char *make_model, const char *product,
51 const char *include_schemes,
52 const char *exclude_schemes);
53
54
55 /*
56 * 'main()' - Parse options and show status information.
57 */
58
59 int
60 main(int argc, /* I - Number of command-line arguments */
61 char *argv[]) /* I - Command-line arguments */
62 {
63 int i; /* Looping var */
64 int long_status; /* Long listing? */
65 const char *device_id, /* 1284 device ID */
66 *language, /* Language */
67 *make_model, /* Make and model */
68 *product, /* Product */
69 *include_schemes, /* Schemes to include */
70 *exclude_schemes; /* Schemes to exclude */
71 int timeout; /* Device timeout */
72
73
74 _cupsSetLocale(argv);
75
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;
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);
92 #else
93 _cupsLangPrintf(stderr,
94 _("%s: Sorry, no encryption support compiled in\n"),
95 argv[0]);
96 #endif /* HAVE_SSL */
97 break;
98
99 case 'h' : /* Connect to host */
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
117 case 'l' : /* Show long listing */
118 long_status = 1;
119 break;
120
121 case 'm' : /* Show models */
122 if (show_models(long_status, device_id, language, make_model,
123 product, include_schemes, exclude_schemes))
124 return (1);
125 break;
126
127 case 'v' : /* Show available devices */
128 if (show_devices(long_status, timeout, include_schemes,
129 exclude_schemes))
130 return (1);
131 break;
132
133 case '-' : /* --something */
134 if (!strcmp(argv[i], "--device-id"))
135 {
136 i ++;
137
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 }
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 }
188 else if (!strcmp(argv[i], "--language"))
189 {
190 i ++;
191 if (i < argc)
192 language = argv[i];
193 else
194 {
195 _cupsLangPuts(stderr,
196 _("lpinfo: Expected language after "
197 "--language\n"));
198 return (1);
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);
260 }
261 break;
262
263 default :
264 _cupsLangPrintf(stderr, _("lpinfo: Unknown option \'%c\'\n"),
265 argv[i][1]);
266 return (1);
267 }
268 else
269 {
270 _cupsLangPrintf(stderr, _("lpinfo: Unknown argument \'%s\'\n"),
271 argv[i]);
272 return (1);
273 }
274
275 return (0);
276 }
277
278
279 /*
280 * 'device_cb()' - Device callback.
281 */
282
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 */
290 const char *device_location, /* I - device-location string */
291 void *user_data) /* I - User data */
292 {
293 int *long_status; /* Show verbose info? */
294
295
296 /*
297 * Display the device...
298 */
299
300 long_status = (int *)user_data;
301
302 if (*long_status)
303 {
304 _cupsLangPrintf(stdout,
305 _("Device: uri = %s\n"
306 " class = %s\n"
307 " info = %s\n"
308 " make-and-model = %s\n"
309 " device-id = %s\n"
310 " location = %s\n"),
311 device_uri, device_class, device_info,
312 device_make_and_model, device_id, device_location);
313 }
314 else
315 _cupsLangPrintf(stdout, "%s %s\n", device_class, device_uri);
316 }
317
318
319 /*
320 * 'show_devices()' - Show available devices.
321 */
322
323 static int /* O - 0 on success, 1 on failure */
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 */
329 {
330 if (cupsGetDevices(CUPS_HTTP_DEFAULT, timeout, include_schemes,
331 exclude_schemes, device_cb, &long_status) != IPP_OK)
332 {
333 _cupsLangPrintf(stderr, "lpinfo: %s\n", cupsLastErrorString());
334 return (1);
335 }
336
337 return (0);
338 }
339
340
341 /*
342 * 'show_models()' - Show available PPDs.
343 */
344
345 static int /* O - 0 on success, 1 on failure */
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 */
354 {
355 ipp_t *request, /* IPP Request */
356 *response; /* IPP Response */
357 ipp_attribute_t *attr; /* Current attribute */
358 const char *ppd_device_id, /* Pointer to ppd-device-id */
359 *ppd_language, /* Pointer to ppd-natural-language */
360 *ppd_make_model, /* Pointer to ppd-make-and-model */
361 *ppd_name; /* Pointer to ppd-name */
362 cups_option_t option; /* in/exclude-schemes option */
363
364
365 /*
366 * Build a CUPS_GET_PPDS request...
367 */
368
369 request = ippNewRequest(CUPS_GET_PPDS);
370
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
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
400 /*
401 * Do the request and get back a response...
402 */
403
404 if ((response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) != NULL)
405 {
406 /*
407 * Loop through the device list and display them...
408 */
409
410 if (response->request.status.status_code > IPP_OK_CONFLICT)
411 {
412 _cupsLangPrintf(stderr, "lpinfo: %s\n", cupsLastErrorString());
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
433 ppd_device_id = "NONE";
434 ppd_language = NULL;
435 ppd_make_model = NULL;
436 ppd_name = NULL;
437
438 while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
439 {
440 if (!strcmp(attr->name, "ppd-device-id") &&
441 attr->value_tag == IPP_TAG_TEXT)
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)
448 ppd_make_model = attr->values[0].string.text;
449 else if (!strcmp(attr->name, "ppd-name") &&
450 attr->value_tag == IPP_TAG_NAME)
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
460 if (ppd_language == NULL || ppd_make_model == NULL || ppd_name == NULL)
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 {
474 _cupsLangPrintf(stdout,
475 _("Model: name = %s\n"
476 " natural_language = %s\n"
477 " make-and-model = %s\n"
478 " device-id = %s\n"),
479 ppd_name, ppd_language, ppd_make_model, ppd_device_id);
480 }
481 else
482 _cupsLangPrintf(stdout, "%s %s\n", ppd_name, ppd_make_model);
483
484 if (attr == NULL)
485 break;
486 }
487
488 ippDelete(response);
489 }
490 else
491 {
492 _cupsLangPrintf(stderr, "lpinfo: %s\n", cupsLastErrorString());
493
494 return (1);
495 }
496
497 return (0);
498 }
499
500
501 /*
502 * End of "$Id: lpinfo.c 7810 2008-07-29 01:11:15Z mike $".
503 */