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
8 * SNMP discovery backend for the Common UNIX Printing System (CUPS).
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
17 * free_array() - Free an array of strings.
19 * get_interface_addresses() - Get the broadcast address(es) associated
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
31 + * Private CUPS API to set the last error...
34 +extern void _cupsSetError(ipp_status_t status, const char *message);
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,
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);
63 - * Display the results...
69 * Close, free, and return with no errors...
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)");
80 temp = calloc(1, sizeof(snmp_cache_t));
82 temp->make_and_model = strdup(make_and_model);
84 cupsArrayAdd(Devices, temp);
91 @@ -1228,6 +1235,173 @@
95 + * 'do_request()' - Do a non-blocking IPP request.
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 */
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 */
109 + * Setup the HTTP variables needed...
112 + httpClearFields(http);
113 + httpSetLength(http, ippLength(request));
114 + httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/ipp");
117 + * Do the POST request...
120 + debug_printf("DEBUG: %.3f POST %s...\n", run_time(), resource);
122 + if (httpPost(http, resource))
124 + if (httpReconnect(http))
126 + _cupsSetError(IPP_DEVICE_ERROR, "Unable to reconnect");
129 + else if (httpPost(http, resource))
131 + _cupsSetError(IPP_GONE, "Unable to POST");
137 + * Send the IPP data...
140 + request->state = IPP_IDLE;
141 + status = HTTP_CONTINUE;
143 + while ((state = ippWrite(http, request)) != IPP_DATA)
144 + if (state == IPP_ERROR)
146 + status = HTTP_ERROR;
149 + else if (httpCheck(http))
151 + if ((status = httpUpdate(http)) != HTTP_CONTINUE)
156 + * Get the server's return status...
159 + debug_printf("DEBUG: %.3f Getting response...\n", run_time());
161 + while (status == HTTP_CONTINUE)
162 + if (httpWait(http, 1000))
163 + status = httpUpdate(http);
166 + status = HTTP_ERROR;
167 + http->error = ETIMEDOUT;
170 + if (status != HTTP_OK)
173 + * Flush any error message...
182 + * Read the response...
185 + response = ippNew();
187 + while ((state = ippRead(http, response)) != IPP_DATA)
188 + if (state == IPP_ERROR)
191 + * Delete the response...
194 + ippDelete(response);
197 + _cupsSetError(IPP_SERVICE_UNAVAILABLE, strerror(errno));
203 + * Delete the original request and return the response...
206 + ippDelete(request);
210 + ipp_attribute_t *attr; /* status-message attribute */
213 + attr = ippFindAttribute(response, "status-message", IPP_TAG_TEXT);
215 + _cupsSetError(response->request.status.status_code,
216 + attr ? attr->values[0].string.text :
217 + ippErrorString(response->request.status.status_code));
219 + else if (status != HTTP_OK)
223 + case HTTP_NOT_FOUND :
224 + _cupsSetError(IPP_NOT_FOUND, httpStatus(status));
227 + case HTTP_UNAUTHORIZED :
228 + _cupsSetError(IPP_NOT_AUTHORIZED, httpStatus(status));
231 + case HTTP_FORBIDDEN :
232 + _cupsSetError(IPP_FORBIDDEN, httpStatus(status));
235 + case HTTP_BAD_REQUEST :
236 + _cupsSetError(IPP_BAD_REQUEST, httpStatus(status));
239 + case HTTP_REQUEST_TOO_LARGE :
240 + _cupsSetError(IPP_REQUEST_VALUE, httpStatus(status));
243 + case HTTP_NOT_IMPLEMENTED :
244 + _cupsSetError(IPP_OPERATION_NOT_SUPPORTED, httpStatus(status));
247 + case HTTP_NOT_SUPPORTED :
248 + _cupsSetError(IPP_VERSION_NOT_SUPPORTED, httpStatus(status));
252 + _cupsSetError(IPP_SERVICE_UNAVAILABLE, httpStatus(status));
262 * 'fix_make_model()' - Fix common problems in the make-and-model string.
265 @@ -1422,24 +1596,18 @@
269 - * 'list_devices()' - List all of the devices we found...
270 + * 'list_device()' - List a device we found...
275 +list_device(snmp_cache_t *cache) /* I - Cached device */
277 - snmp_cache_t *cache; /* Cached device */
280 - for (cache = (snmp_cache_t *)cupsArrayFirst(Devices);
282 - cache = (snmp_cache_t *)cupsArrayNext(Devices))
284 - printf("network %s \"%s\" \"%s %s\" \"%s\"\n",
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 : "");
290 + printf("network %s \"%s\" \"%s %s\" \"%s\"\n",
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 : "");
298 @@ -1551,8 +1719,6 @@
302 - debug_printf("DEBUG: %s supports IPP!\n", device->addrname);
305 * Use non-blocking IO...
307 @@ -1578,16 +1744,14 @@
308 httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
309 device->addrname, 631, resources[i]);
311 - debug_printf("DEBUG: Trying %s (num_uris=%d)\n", uri, num_uris);
313 request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
315 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
318 - response = cupsDoRequest(http, request, resources[i]);
319 + response = do_request(http, request, resources[i]);
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());
325 if (response && response->request.status.status_code == IPP_OK)
326 @@ -2211,9 +2375,11 @@
328 device->make_and_model = strdup(make_model);
331 + list_device(device);