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