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