]> git.ipfire.org Git - thirdparty/cups.git/blame - systemv/lpinfo.c
License change: Apache License, Version 2.0.
[thirdparty/cups.git] / systemv / lpinfo.c
CommitLineData
ef416fc2 1/*
503b54c9 2 * "lpinfo" command for CUPS.
ef416fc2 3 *
bdbfacc7 4 * Copyright 2007-2016 by Apple Inc.
503b54c9 5 * Copyright 1997-2006 by Easy Software Products.
ef416fc2 6 *
e3101897 7 * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
ef416fc2 8 */
9
10/*
11 * Include necessary headers...
12 */
13
71e16022 14#include <cups/cups-private.h>
68c4690a 15#include <cups/adminutil.h>
ef416fc2 16
17
18/*
19 * Local functions...
20 */
21
ae71f5de
MS
22static void device_cb(const char *device_clas, const char *device_id,
23 const char *device_info,
24 const char *device_make_and_model,
749b1e90
MS
25 const char *device_uri, const char *device_location,
26 void *user_data);
ed6e7faf
MS
27static int show_devices(int long_status, int timeout,
28 const char *include_schemes,
29 const char *exclude_schemes);
30static int show_models(int long_status,
58dc1933 31 const char *device_id, const char *language,
ed6e7faf
MS
32 const char *make_model, const char *product,
33 const char *include_schemes,
34 const char *exclude_schemes);
ef416fc2 35
36
37/*
38 * 'main()' - Parse options and show status information.
39 */
40
41int
42main(int argc, /* I - Number of command-line arguments */
43 char *argv[]) /* I - Command-line arguments */
44{
45 int i; /* Looping var */
ef416fc2 46 int long_status; /* Long listing? */
bdbfacc7
MS
47 const char *opt, /* Option pointer */
48 *device_id, /* 1284 device ID */
58dc1933
MS
49 *language, /* Language */
50 *make_model, /* Make and model */
ed6e7faf
MS
51 *product, /* Product */
52 *include_schemes, /* Schemes to include */
53 *exclude_schemes; /* Schemes to exclude */
58dc1933 54 int timeout; /* Device timeout */
ef416fc2 55
56
07725fee 57 _cupsSetLocale(argv);
d09495fa 58
ed6e7faf
MS
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;
ef416fc2 67
68 for (i = 1; i < argc; i ++)
bdbfacc7
MS
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
ef416fc2 109 {
bdbfacc7
MS
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 */
ef416fc2 185#ifdef HAVE_SSL
bdbfacc7 186 cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
ef416fc2 187#else
bdbfacc7 188 _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), argv[0]);
ef416fc2 189#endif /* HAVE_SSL */
bdbfacc7 190 break;
58dc1933 191
bdbfacc7
MS
192 case 'h' : /* Connect to host */
193 if (opt[1] != '\0')
58dc1933 194 {
bdbfacc7
MS
195 cupsSetServer(opt + 1);
196 opt += strlen(opt) - 1;
58dc1933 197 }
ed6e7faf
MS
198 else
199 {
bdbfacc7 200 i ++;
ed6e7faf 201
bdbfacc7
MS
202 if (i >= argc)
203 {
204 _cupsLangPuts(stderr, _("Error: need hostname after \"-h\" option."));
205 return (1);
206 }
207
208 cupsSetServer(argv[i]);
58dc1933 209 }
bdbfacc7
MS
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))
58dc1933 218 return (1);
bdbfacc7 219 break;
57b7b66b 220
bdbfacc7
MS
221 case 'v' : /* Show available devices */
222 if (show_devices(long_status, timeout, include_schemes, exclude_schemes))
58dc1933 223 return (1);
bdbfacc7 224 break;
ef416fc2 225
bdbfacc7
MS
226 default :
227 _cupsLangPrintf(stderr, _("%s: Unknown option \"%c\"."), argv[0], *opt);
228 return (1);
229 }
ef416fc2 230 }
bdbfacc7 231 }
ef416fc2 232 else
233 {
bdbfacc7 234 _cupsLangPrintf(stderr, _("%s: Unknown argument \"%s\"."), argv[0], argv[i]);
ef416fc2 235 return (1);
236 }
bdbfacc7 237 }
ef416fc2 238
239 return (0);
240}
241
242
243/*
ae71f5de 244 * 'device_cb()' - Device callback.
ef416fc2 245 */
246
ae71f5de
MS
247static void
248device_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 */
749b1e90 254 const char *device_location, /* I - device-location string */
ae71f5de 255 void *user_data) /* I - User data */
ef416fc2 256{
ae71f5de 257 int *long_status; /* Show verbose info? */
ef416fc2 258
ef416fc2 259
260 /*
ae71f5de 261 * Display the device...
ef416fc2 262 */
263
ae71f5de 264 long_status = (int *)user_data;
ef416fc2 265
ae71f5de 266 if (*long_status)
ef416fc2 267 {
ae71f5de
MS
268 _cupsLangPrintf(stdout,
269 _("Device: uri = %s\n"
270 " class = %s\n"
271 " info = %s\n"
272 " make-and-model = %s\n"
749b1e90 273 " device-id = %s\n"
0837b7e8 274 " location = %s"),
ae71f5de 275 device_uri, device_class, device_info,
749b1e90 276 device_make_and_model, device_id, device_location);
ae71f5de
MS
277 }
278 else
0837b7e8 279 _cupsLangPrintf(stdout, "%s %s", device_class, device_uri);
ae71f5de 280}
ef416fc2 281
ef416fc2 282
ae71f5de
MS
283/*
284 * 'show_devices()' - Show available devices.
285 */
ef416fc2 286
ae71f5de 287static int /* O - 0 on success, 1 on failure */
ed6e7faf
MS
288show_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 */
ae71f5de 293{
ed6e7faf
MS
294 if (cupsGetDevices(CUPS_HTTP_DEFAULT, timeout, include_schemes,
295 exclude_schemes, device_cb, &long_status) != IPP_OK)
ef416fc2 296 {
0837b7e8 297 _cupsLangPrintf(stderr, "lpinfo: %s", cupsLastErrorString());
ef416fc2 298 return (1);
299 }
300
301 return (0);
302}
303
304
305/*
306 * 'show_models()' - Show available PPDs.
307 */
308
309static int /* O - 0 on success, 1 on failure */
ed6e7faf
MS
310show_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 */
ef416fc2 318{
319 ipp_t *request, /* IPP Request */
320 *response; /* IPP Response */
321 ipp_attribute_t *attr; /* Current attribute */
fa73b229 322 const char *ppd_device_id, /* Pointer to ppd-device-id */
323 *ppd_language, /* Pointer to ppd-natural-language */
58dc1933 324 *ppd_make_model, /* Pointer to ppd-make-and-model */
fa73b229 325 *ppd_name; /* Pointer to ppd-name */
ed6e7faf 326 cups_option_t option; /* in/exclude-schemes option */
ef416fc2 327
328
ef416fc2 329 /*
58dc1933 330 * Build a CUPS_GET_PPDS request...
ef416fc2 331 */
332
fa73b229 333 request = ippNewRequest(CUPS_GET_PPDS);
ef416fc2 334
58dc1933
MS
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
ed6e7faf
MS
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
ef416fc2 364 /*
365 * Do the request and get back a response...
366 */
367
ed6e7faf 368 if ((response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) != NULL)
ef416fc2 369 {
370 /*
371 * Loop through the device list and display them...
372 */
373
374 if (response->request.status.status_code > IPP_OK_CONFLICT)
375 {
0837b7e8 376 _cupsLangPrintf(stderr, "lpinfo: %s", cupsLastErrorString());
ef416fc2 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
58dc1933
MS
397 ppd_device_id = "NONE";
398 ppd_language = NULL;
399 ppd_make_model = NULL;
400 ppd_name = NULL;
ef416fc2 401
402 while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
403 {
fa73b229 404 if (!strcmp(attr->name, "ppd-device-id") &&
ef416fc2 405 attr->value_tag == IPP_TAG_TEXT)
fa73b229 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)
58dc1933 412 ppd_make_model = attr->values[0].string.text;
fa73b229 413 else if (!strcmp(attr->name, "ppd-name") &&
414 attr->value_tag == IPP_TAG_NAME)
ef416fc2 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
58dc1933 424 if (ppd_language == NULL || ppd_make_model == NULL || ppd_name == NULL)
ef416fc2 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 {
fa73b229 438 _cupsLangPrintf(stdout,
ef416fc2 439 _("Model: name = %s\n"
440 " natural_language = %s\n"
fa73b229 441 " make-and-model = %s\n"
0837b7e8 442 " device-id = %s"),
58dc1933 443 ppd_name, ppd_language, ppd_make_model, ppd_device_id);
ef416fc2 444 }
445 else
0837b7e8 446 _cupsLangPrintf(stdout, "%s %s", ppd_name, ppd_make_model);
ef416fc2 447
448 if (attr == NULL)
449 break;
450 }
451
452 ippDelete(response);
453 }
454 else
455 {
0837b7e8 456 _cupsLangPrintf(stderr, "lpinfo: %s", cupsLastErrorString());
ef416fc2 457
458 return (1);
459 }
460
461 return (0);
462}