]>
Commit | Line | Data |
---|---|---|
9bb307fe KK |
1 | --- cups-1.2.2/backend/snmp.c.orig 2006-07-13 21:59:36.000000000 +0200 |
2 | +++ cups-1.2.2/backend/snmp.c 2006-07-28 21:31:44.005091500 +0200 | |
3 | @@ -1,5 +1,5 @@ | |
4 | /* | |
5 | - * "$Id$" | |
6 | + * "$Id$" | |
7 | * | |
8 | * SNMP discovery backend for the Common UNIX Printing System (CUPS). | |
9 | * | |
10 | @@ -52,6 +52,7 @@ | |
11 | * packed integer value. | |
12 | * compare_cache() - Compare two cache entries. | |
13 | * debug_printf() - Display some debugging information. | |
14 | + * do_request() - Do a non-blocking IPP request. | |
15 | * fix_make_model() - Fix common problems in the make-and-model | |
16 | * string. | |
17 | * free_array() - Free an array of strings. | |
18 | @@ -59,7 +60,7 @@ | |
19 | * get_interface_addresses() - Get the broadcast address(es) associated | |
20 | * with an interface. | |
21 | * hex_debug() - Output hex debugging data... | |
22 | - * list_devices() - List all of the devices we found... | |
23 | + * list_device() - List a device we found... | |
24 | * open_snmp_socket() - Open the SNMP broadcast socket. | |
25 | * password_cb() - Handle authentication requests. | |
26 | * probe_device() - Probe a device to discover whether it is a | |
27 | @@ -194,6 +195,13 @@ | |
28 | ||
29 | ||
30 | /* | |
31 | + * Private CUPS API to set the last error... | |
32 | + */ | |
33 | + | |
34 | +extern void _cupsSetError(ipp_status_t status, const char *message); | |
35 | + | |
36 | + | |
37 | +/* | |
38 | * Local functions... | |
39 | */ | |
40 | ||
41 | @@ -238,6 +246,8 @@ | |
42 | static int asn1_size_packed(int integer); | |
43 | static int compare_cache(snmp_cache_t *a, snmp_cache_t *b); | |
44 | static void debug_printf(const char *format, ...); | |
45 | +static ipp_t *do_request(http_t *http, ipp_t *request, | |
46 | + const char *resource); | |
47 | static void fix_make_model(char *make_model, | |
48 | const char *old_make_model, | |
49 | int make_model_size); | |
50 | @@ -245,7 +255,7 @@ | |
51 | static void free_cache(void); | |
52 | static http_addrlist_t *get_interface_addresses(const char *ifname); | |
53 | static void hex_debug(unsigned char *buffer, size_t len); | |
54 | -static void list_devices(void); | |
55 | +static void list_device(snmp_cache_t *cache); | |
56 | static int open_snmp_socket(void); | |
57 | static const char *password_cb(const char *prompt); | |
58 | static void probe_device(snmp_cache_t *device); | |
59 | @@ -330,12 +340,6 @@ | |
60 | scan_devices(fd); | |
61 | ||
62 | /* | |
63 | - * Display the results... | |
64 | - */ | |
65 | - | |
66 | - list_devices(); | |
67 | - | |
68 | - /* | |
69 | * Close, free, and return with no errors... | |
70 | */ | |
71 | ||
72 | @@ -384,7 +388,7 @@ | |
73 | ||
74 | debug_printf("DEBUG: add_cache(addr=%p, addrname=\"%s\", uri=\"%s\", " | |
75 | "id=\"%s\", make_and_model=\"%s\")\n", | |
76 | - addr, addrname, uri ? uri : "(null)", id ? id : "(null)", | |
77 | + addr, addrname, uri ? uri : "(null)", id ? id : "(null)", | |
78 | make_and_model ? make_and_model : "(null)"); | |
79 | ||
80 | temp = calloc(1, sizeof(snmp_cache_t)); | |
81 | @@ -402,6 +406,9 @@ | |
82 | temp->make_and_model = strdup(make_and_model); | |
83 | ||
84 | cupsArrayAdd(Devices, temp); | |
85 | + | |
86 | + if (uri) | |
87 | + list_device(temp); | |
88 | } | |
89 | ||
90 | ||
91 | @@ -1228,6 +1235,173 @@ | |
92 | ||
93 | ||
94 | /* | |
95 | + * 'do_request()' - Do a non-blocking IPP request. | |
96 | + */ | |
97 | + | |
98 | +static ipp_t * /* O - Response data or NULL */ | |
99 | +do_request(http_t *http, /* I - HTTP connection to server */ | |
100 | + ipp_t *request, /* I - IPP request */ | |
101 | + const char *resource) /* I - HTTP resource for POST */ | |
102 | +{ | |
103 | + ipp_t *response; /* IPP response data */ | |
104 | + http_status_t status; /* Status of HTTP request */ | |
105 | + ipp_state_t state; /* State of IPP processing */ | |
106 | + | |
107 | + | |
108 | + /* | |
109 | + * Setup the HTTP variables needed... | |
110 | + */ | |
111 | + | |
112 | + httpClearFields(http); | |
113 | + httpSetLength(http, ippLength(request)); | |
114 | + httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/ipp"); | |
115 | + | |
116 | + /* | |
117 | + * Do the POST request... | |
118 | + */ | |
119 | + | |
120 | + debug_printf("DEBUG: %.3f POST %s...\n", run_time(), resource); | |
121 | + | |
122 | + if (httpPost(http, resource)) | |
123 | + { | |
124 | + if (httpReconnect(http)) | |
125 | + { | |
126 | + _cupsSetError(IPP_DEVICE_ERROR, "Unable to reconnect"); | |
127 | + return (NULL); | |
128 | + } | |
129 | + else if (httpPost(http, resource)) | |
130 | + { | |
131 | + _cupsSetError(IPP_GONE, "Unable to POST"); | |
132 | + return (NULL); | |
133 | + } | |
134 | + } | |
135 | + | |
136 | + /* | |
137 | + * Send the IPP data... | |
138 | + */ | |
139 | + | |
140 | + request->state = IPP_IDLE; | |
141 | + status = HTTP_CONTINUE; | |
142 | + | |
143 | + while ((state = ippWrite(http, request)) != IPP_DATA) | |
144 | + if (state == IPP_ERROR) | |
145 | + { | |
146 | + status = HTTP_ERROR; | |
147 | + break; | |
148 | + } | |
149 | + else if (httpCheck(http)) | |
150 | + { | |
151 | + if ((status = httpUpdate(http)) != HTTP_CONTINUE) | |
152 | + break; | |
153 | + } | |
154 | + | |
155 | + /* | |
156 | + * Get the server's return status... | |
157 | + */ | |
158 | + | |
159 | + debug_printf("DEBUG: %.3f Getting response...\n", run_time()); | |
160 | + | |
161 | + while (status == HTTP_CONTINUE) | |
162 | + if (httpWait(http, 1000)) | |
163 | + status = httpUpdate(http); | |
164 | + else | |
165 | + { | |
166 | + status = HTTP_ERROR; | |
167 | + http->error = ETIMEDOUT; | |
168 | + } | |
169 | + | |
170 | + if (status != HTTP_OK) | |
171 | + { | |
172 | + /* | |
173 | + * Flush any error message... | |
174 | + */ | |
175 | + | |
176 | + httpFlush(http); | |
177 | + response = NULL; | |
178 | + } | |
179 | + else | |
180 | + { | |
181 | + /* | |
182 | + * Read the response... | |
183 | + */ | |
184 | + | |
185 | + response = ippNew(); | |
186 | + | |
187 | + while ((state = ippRead(http, response)) != IPP_DATA) | |
188 | + if (state == IPP_ERROR) | |
189 | + { | |
190 | + /* | |
191 | + * Delete the response... | |
192 | + */ | |
193 | + | |
194 | + ippDelete(response); | |
195 | + response = NULL; | |
196 | + | |
197 | + _cupsSetError(IPP_SERVICE_UNAVAILABLE, strerror(errno)); | |
198 | + break; | |
199 | + } | |
200 | + } | |
201 | + | |
202 | + /* | |
203 | + * Delete the original request and return the response... | |
204 | + */ | |
205 | + | |
206 | + ippDelete(request); | |
207 | + | |
208 | + if (response) | |
209 | + { | |
210 | + ipp_attribute_t *attr; /* status-message attribute */ | |
211 | + | |
212 | + | |
213 | + attr = ippFindAttribute(response, "status-message", IPP_TAG_TEXT); | |
214 | + | |
215 | + _cupsSetError(response->request.status.status_code, | |
216 | + attr ? attr->values[0].string.text : | |
217 | + ippErrorString(response->request.status.status_code)); | |
218 | + } | |
219 | + else if (status != HTTP_OK) | |
220 | + { | |
221 | + switch (status) | |
222 | + { | |
223 | + case HTTP_NOT_FOUND : | |
224 | + _cupsSetError(IPP_NOT_FOUND, httpStatus(status)); | |
225 | + break; | |
226 | + | |
227 | + case HTTP_UNAUTHORIZED : | |
228 | + _cupsSetError(IPP_NOT_AUTHORIZED, httpStatus(status)); | |
229 | + break; | |
230 | + | |
231 | + case HTTP_FORBIDDEN : | |
232 | + _cupsSetError(IPP_FORBIDDEN, httpStatus(status)); | |
233 | + break; | |
234 | + | |
235 | + case HTTP_BAD_REQUEST : | |
236 | + _cupsSetError(IPP_BAD_REQUEST, httpStatus(status)); | |
237 | + break; | |
238 | + | |
239 | + case HTTP_REQUEST_TOO_LARGE : | |
240 | + _cupsSetError(IPP_REQUEST_VALUE, httpStatus(status)); | |
241 | + break; | |
242 | + | |
243 | + case HTTP_NOT_IMPLEMENTED : | |
244 | + _cupsSetError(IPP_OPERATION_NOT_SUPPORTED, httpStatus(status)); | |
245 | + break; | |
246 | + | |
247 | + case HTTP_NOT_SUPPORTED : | |
248 | + _cupsSetError(IPP_VERSION_NOT_SUPPORTED, httpStatus(status)); | |
249 | + break; | |
250 | + | |
251 | + default : | |
252 | + _cupsSetError(IPP_SERVICE_UNAVAILABLE, httpStatus(status)); | |
253 | + break; | |
254 | + } | |
255 | + } | |
256 | + | |
257 | + return (response); | |
258 | +} | |
259 | + | |
260 | + | |
261 | +/* | |
262 | * 'fix_make_model()' - Fix common problems in the make-and-model string. | |
263 | */ | |
264 | ||
265 | @@ -1422,24 +1596,18 @@ | |
266 | ||
267 | ||
268 | /* | |
269 | - * 'list_devices()' - List all of the devices we found... | |
270 | + * 'list_device()' - List a device we found... | |
271 | */ | |
272 | ||
273 | static void | |
274 | -list_devices(void) | |
275 | +list_device(snmp_cache_t *cache) /* I - Cached device */ | |
276 | { | |
277 | - snmp_cache_t *cache; /* Cached device */ | |
278 | - | |
279 | - | |
280 | - for (cache = (snmp_cache_t *)cupsArrayFirst(Devices); | |
281 | - cache; | |
282 | - cache = (snmp_cache_t *)cupsArrayNext(Devices)) | |
283 | - if (cache->uri) | |
284 | - printf("network %s \"%s\" \"%s %s\" \"%s\"\n", | |
285 | - cache->uri, | |
286 | - cache->make_and_model ? cache->make_and_model : "Unknown", | |
287 | - cache->make_and_model ? cache->make_and_model : "Unknown", | |
288 | - cache->addrname, cache->id ? cache->id : ""); | |
289 | + if (cache->uri) | |
290 | + printf("network %s \"%s\" \"%s %s\" \"%s\"\n", | |
291 | + cache->uri, | |
292 | + cache->make_and_model ? cache->make_and_model : "Unknown", | |
293 | + cache->make_and_model ? cache->make_and_model : "Unknown", | |
294 | + cache->addrname, cache->id ? cache->id : ""); | |
295 | } | |
296 | ||
297 | ||
298 | @@ -1551,8 +1719,6 @@ | |
299 | }; | |
300 | ||
301 | ||
302 | - debug_printf("DEBUG: %s supports IPP!\n", device->addrname); | |
303 | - | |
304 | /* | |
305 | * Use non-blocking IO... | |
306 | */ | |
307 | @@ -1578,16 +1744,14 @@ | |
308 | httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, | |
309 | device->addrname, 631, resources[i]); | |
310 | ||
311 | - debug_printf("DEBUG: Trying %s (num_uris=%d)\n", uri, num_uris); | |
312 | - | |
313 | request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); | |
314 | ||
315 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", | |
316 | NULL, uri); | |
317 | ||
318 | - response = cupsDoRequest(http, request, resources[i]); | |
319 | + response = do_request(http, request, resources[i]); | |
320 | ||
321 | - debug_printf("DEBUG: %s %s (%s)\n", uri, | |
322 | + debug_printf("DEBUG: %.3f %s %s (%s)\n", run_time(), uri, | |
323 | ippErrorString(cupsLastError()), cupsLastErrorString()); | |
324 | ||
325 | if (response && response->request.status.status_code == IPP_OK) | |
326 | @@ -2211,9 +2375,11 @@ | |
327 | ||
328 | device->make_and_model = strdup(make_model); | |
329 | } | |
330 | + | |
331 | + list_device(device); | |
332 | } | |
333 | ||
334 | ||
335 | /* | |
336 | - * End of "$Id$". | |
337 | + * End of "$Id$". | |
338 | */ |