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