]>
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); | |
ef416fc2 | 45 | static int show_devices(http_t *, int); |
46 | static int show_models(http_t *, int); | |
47 | ||
48 | ||
49 | /* | |
50 | * 'main()' - Parse options and show status information. | |
51 | */ | |
52 | ||
53 | int | |
54 | main(int argc, /* I - Number of command-line arguments */ | |
55 | char *argv[]) /* I - Command-line arguments */ | |
56 | { | |
57 | int i; /* Looping var */ | |
58 | http_t *http; /* Connection to server */ | |
59 | int long_status; /* Long listing? */ | |
60 | ||
61 | ||
07725fee | 62 | _cupsSetLocale(argv); |
d09495fa | 63 | |
ef416fc2 | 64 | http = NULL; |
65 | long_status = 0; | |
66 | ||
67 | for (i = 1; i < argc; i ++) | |
68 | if (argv[i][0] == '-') | |
69 | switch (argv[i][1]) | |
70 | { | |
71 | case 'E' : /* Encrypt */ | |
72 | #ifdef HAVE_SSL | |
73 | cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); | |
74 | ||
75 | if (http) | |
76 | httpEncryption(http, HTTP_ENCRYPT_REQUIRED); | |
77 | #else | |
fa73b229 | 78 | _cupsLangPrintf(stderr, |
ef416fc2 | 79 | _("%s: Sorry, no encryption support compiled in!\n"), |
80 | argv[0]); | |
81 | #endif /* HAVE_SSL */ | |
82 | break; | |
83 | ||
84 | case 'l' : /* Show long listing */ | |
85 | long_status = 1; | |
86 | break; | |
87 | ||
88 | case 'm' : /* Show models */ | |
89 | if (!http) | |
90 | { | |
91 | http = httpConnectEncrypt(cupsServer(), ippPort(), | |
92 | cupsEncryption()); | |
93 | ||
94 | if (http == NULL) | |
95 | { | |
fa73b229 | 96 | _cupsLangPrintf(stderr, |
ef416fc2 | 97 | _("lpinfo: Unable to connect to server: %s\n"), |
98 | strerror(errno)); | |
99 | return (1); | |
100 | } | |
101 | } | |
102 | ||
103 | if (show_models(http, long_status)) | |
104 | return (1); | |
105 | break; | |
106 | ||
107 | case 'v' : /* Show available devices */ | |
108 | if (!http) | |
109 | { | |
110 | http = httpConnectEncrypt(cupsServer(), ippPort(), | |
111 | cupsEncryption()); | |
112 | ||
113 | if (http == NULL) | |
114 | { | |
fa73b229 | 115 | _cupsLangPrintf(stderr, |
ef416fc2 | 116 | _("lpinfo: Unable to connect to server: %s\n"), |
117 | strerror(errno)); | |
118 | return (1); | |
119 | } | |
120 | } | |
121 | ||
122 | if (show_devices(http, long_status)) | |
123 | return (1); | |
124 | break; | |
125 | ||
126 | case 'h' : /* Connect to host */ | |
127 | if (http) | |
128 | { | |
129 | httpClose(http); | |
130 | http = NULL; | |
131 | } | |
132 | ||
133 | if (argv[i][2] != '\0') | |
134 | cupsSetServer(argv[i] + 2); | |
135 | else | |
136 | { | |
137 | i ++; | |
138 | ||
139 | if (i >= argc) | |
140 | { | |
fa73b229 | 141 | _cupsLangPuts(stderr, |
ef416fc2 | 142 | _("Error: need hostname after \'-h\' option!\n")); |
143 | return (1); | |
144 | } | |
145 | ||
146 | cupsSetServer(argv[i]); | |
147 | } | |
148 | break; | |
149 | ||
150 | default : | |
fa73b229 | 151 | _cupsLangPrintf(stderr, _("lpinfo: Unknown option \'%c\'!\n"), |
ef416fc2 | 152 | argv[i][1]); |
153 | return (1); | |
154 | } | |
155 | else | |
156 | { | |
fa73b229 | 157 | _cupsLangPrintf(stderr, _("lpinfo: Unknown argument \'%s\'!\n"), |
ef416fc2 | 158 | argv[i]); |
159 | return (1); | |
160 | } | |
161 | ||
162 | return (0); | |
163 | } | |
164 | ||
165 | ||
166 | /* | |
ae71f5de | 167 | * 'device_cb()' - Device callback. |
ef416fc2 | 168 | */ |
169 | ||
ae71f5de MS |
170 | static void |
171 | device_cb( | |
172 | const char *device_class, /* I - device-class string */ | |
173 | const char *device_id, /* I - device-id string */ | |
174 | const char *device_info, /* I - device-info string */ | |
175 | const char *device_make_and_model, /* I - device-make-and-model string */ | |
176 | const char *device_uri, /* I - device-uri string */ | |
749b1e90 | 177 | const char *device_location, /* I - device-location string */ |
ae71f5de | 178 | void *user_data) /* I - User data */ |
ef416fc2 | 179 | { |
ae71f5de | 180 | int *long_status; /* Show verbose info? */ |
ef416fc2 | 181 | |
ef416fc2 | 182 | |
183 | /* | |
ae71f5de | 184 | * Display the device... |
ef416fc2 | 185 | */ |
186 | ||
ae71f5de | 187 | long_status = (int *)user_data; |
ef416fc2 | 188 | |
ae71f5de | 189 | if (*long_status) |
ef416fc2 | 190 | { |
ae71f5de MS |
191 | _cupsLangPrintf(stdout, |
192 | _("Device: uri = %s\n" | |
193 | " class = %s\n" | |
194 | " info = %s\n" | |
195 | " make-and-model = %s\n" | |
749b1e90 MS |
196 | " device-id = %s\n" |
197 | " location = %s\n"), | |
ae71f5de | 198 | device_uri, device_class, device_info, |
749b1e90 | 199 | device_make_and_model, device_id, device_location); |
ae71f5de MS |
200 | } |
201 | else | |
202 | _cupsLangPrintf(stdout, "%s %s\n", device_class, device_uri); | |
203 | } | |
ef416fc2 | 204 | |
ef416fc2 | 205 | |
ae71f5de MS |
206 | /* |
207 | * 'show_devices()' - Show available devices. | |
208 | */ | |
ef416fc2 | 209 | |
ae71f5de MS |
210 | static int /* O - 0 on success, 1 on failure */ |
211 | show_devices(http_t *http, /* I - HTTP connection to server */ | |
212 | int long_status) /* I - Long status report? */ | |
213 | { | |
214 | if (cupsGetDevices(http, CUPS_TIMEOUT_DEFAULT, CUPS_EXCLUDE_NONE, device_cb, | |
215 | &long_status) != IPP_OK) | |
ef416fc2 | 216 | { |
fa73b229 | 217 | _cupsLangPrintf(stderr, "lpinfo: %s\n", cupsLastErrorString()); |
ef416fc2 | 218 | return (1); |
219 | } | |
220 | ||
221 | return (0); | |
222 | } | |
223 | ||
224 | ||
225 | /* | |
226 | * 'show_models()' - Show available PPDs. | |
227 | */ | |
228 | ||
229 | static int /* O - 0 on success, 1 on failure */ | |
230 | show_models(http_t *http, /* I - HTTP connection to server */ | |
231 | int long_status) /* I - Long status report? */ | |
232 | { | |
233 | ipp_t *request, /* IPP Request */ | |
234 | *response; /* IPP Response */ | |
235 | ipp_attribute_t *attr; /* Current attribute */ | |
fa73b229 | 236 | const char *ppd_device_id, /* Pointer to ppd-device-id */ |
237 | *ppd_language, /* Pointer to ppd-natural-language */ | |
238 | *ppd_make, /* Pointer to ppd-make-and-model */ | |
239 | *ppd_name; /* Pointer to ppd-name */ | |
ef416fc2 | 240 | |
241 | ||
242 | if (http == NULL) | |
243 | return (1); | |
244 | ||
245 | /* | |
246 | * Build a CUPS_GET_PPDS request, which requires the following | |
247 | * attributes: | |
248 | * | |
249 | * attributes-charset | |
250 | * attributes-natural-language | |
ef416fc2 | 251 | */ |
252 | ||
fa73b229 | 253 | request = ippNewRequest(CUPS_GET_PPDS); |
ef416fc2 | 254 | |
255 | /* | |
256 | * Do the request and get back a response... | |
257 | */ | |
258 | ||
259 | if ((response = cupsDoRequest(http, request, "/")) != NULL) | |
260 | { | |
261 | /* | |
262 | * Loop through the device list and display them... | |
263 | */ | |
264 | ||
265 | if (response->request.status.status_code > IPP_OK_CONFLICT) | |
266 | { | |
fa73b229 | 267 | _cupsLangPrintf(stderr, "lpinfo: %s\n", cupsLastErrorString()); |
ef416fc2 | 268 | ippDelete(response); |
269 | return (1); | |
270 | } | |
271 | ||
272 | for (attr = response->attrs; attr != NULL; attr = attr->next) | |
273 | { | |
274 | /* | |
275 | * Skip leading attributes until we hit a PPD... | |
276 | */ | |
277 | ||
278 | while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) | |
279 | attr = attr->next; | |
280 | ||
281 | if (attr == NULL) | |
282 | break; | |
283 | ||
284 | /* | |
285 | * Pull the needed attributes from this PPD... | |
286 | */ | |
287 | ||
fa73b229 | 288 | ppd_device_id = "NONE"; |
289 | ppd_language = NULL; | |
290 | ppd_make = NULL; | |
291 | ppd_name = NULL; | |
ef416fc2 | 292 | |
293 | while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) | |
294 | { | |
fa73b229 | 295 | if (!strcmp(attr->name, "ppd-device-id") && |
ef416fc2 | 296 | attr->value_tag == IPP_TAG_TEXT) |
fa73b229 | 297 | ppd_device_id = attr->values[0].string.text; |
298 | else if (!strcmp(attr->name, "ppd-natural-language") && | |
299 | attr->value_tag == IPP_TAG_LANGUAGE) | |
300 | ppd_language = attr->values[0].string.text; | |
301 | else if (!strcmp(attr->name, "ppd-make-and-model") && | |
302 | attr->value_tag == IPP_TAG_TEXT) | |
ef416fc2 | 303 | ppd_make = attr->values[0].string.text; |
fa73b229 | 304 | else if (!strcmp(attr->name, "ppd-name") && |
305 | attr->value_tag == IPP_TAG_NAME) | |
ef416fc2 | 306 | ppd_name = attr->values[0].string.text; |
307 | ||
308 | attr = attr->next; | |
309 | } | |
310 | ||
311 | /* | |
312 | * See if we have everything needed... | |
313 | */ | |
314 | ||
315 | if (ppd_language == NULL || ppd_make == NULL || ppd_name == NULL) | |
316 | { | |
317 | if (attr == NULL) | |
318 | break; | |
319 | else | |
320 | continue; | |
321 | } | |
322 | ||
323 | /* | |
324 | * Display the device... | |
325 | */ | |
326 | ||
327 | if (long_status) | |
328 | { | |
fa73b229 | 329 | _cupsLangPrintf(stdout, |
ef416fc2 | 330 | _("Model: name = %s\n" |
331 | " natural_language = %s\n" | |
fa73b229 | 332 | " make-and-model = %s\n" |
333 | " device-id = %s\n"), | |
334 | ppd_name, ppd_language, ppd_make, ppd_device_id); | |
ef416fc2 | 335 | } |
336 | else | |
fa73b229 | 337 | _cupsLangPrintf(stdout, "%s %s\n", ppd_name, ppd_make); |
ef416fc2 | 338 | |
339 | if (attr == NULL) | |
340 | break; | |
341 | } | |
342 | ||
343 | ippDelete(response); | |
344 | } | |
345 | else | |
346 | { | |
fa73b229 | 347 | _cupsLangPrintf(stderr, "lpinfo: %s\n", cupsLastErrorString()); |
ef416fc2 | 348 | |
349 | return (1); | |
350 | } | |
351 | ||
352 | return (0); | |
353 | } | |
354 | ||
355 | ||
356 | /* | |
b19ccc9e | 357 | * End of "$Id: lpinfo.c 7810 2008-07-29 01:11:15Z mike $". |
ef416fc2 | 358 | */ |