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