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