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