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