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