Annotation of /trunk/cups/patches/cups-1.5.2-avahi-2-backend.patch
Parent Directory | Revision Log
Revision 1642 -
(hide annotations)
(download)
Thu Feb 16 08:44:18 2012 UTC (12 years, 7 months ago) by niro
File size: 30788 byte(s)
Thu Feb 16 08:44:18 2012 UTC (12 years, 7 months ago) by niro
File size: 30788 byte(s)
-added redhat/fedora avahi patches
1 | niro | 1642 | diff -up cups-1.5.2/backend/dnssd.c.avahi-2-backend cups-1.5.2/backend/dnssd.c |
2 | --- cups-1.5.2/backend/dnssd.c.avahi-2-backend 2012-02-06 11:09:08.318644741 +0100 | ||
3 | +++ cups-1.5.2/backend/dnssd.c 2012-02-06 11:09:08.326644641 +0100 | ||
4 | @@ -15,14 +15,21 @@ | ||
5 | * | ||
6 | * Contents: | ||
7 | * | ||
8 | + * next_txt_record() - Get next TXT record from a cups_txt_records_t. | ||
9 | + * parse_txt_record_pair() - Read key/value pair in cups_txt_records_t. | ||
10 | * main() - Browse for printers. | ||
11 | * browse_callback() - Browse devices. | ||
12 | * browse_local_callback() - Browse local devices. | ||
13 | * compare_devices() - Compare two devices. | ||
14 | * exec_backend() - Execute the backend that corresponds to the | ||
15 | * resolved service name. | ||
16 | + * device_type() - Get DNS-SD type enumeration from string. | ||
17 | * get_device() - Create or update a device. | ||
18 | * query_callback() - Process query data. | ||
19 | + * avahi_client_callback() - Avahi client callback function. | ||
20 | + * avahi_query_callback() - Avahi query callback function. | ||
21 | + * avahi_browse_callback() - Avahi browse callback function. | ||
22 | + * find_device() - Find a device from its name and domain. | ||
23 | * sigterm_handler() - Handle termination signals... | ||
24 | * unquote() - Unquote a name string. | ||
25 | */ | ||
26 | @@ -33,7 +40,18 @@ | ||
27 | |||
28 | #include "backend-private.h" | ||
29 | #include <cups/array.h> | ||
30 | -#include <dns_sd.h> | ||
31 | +#ifdef HAVE_DNSSD | ||
32 | +# include <dns_sd.h> | ||
33 | +#endif /* HAVE_DNSSD */ | ||
34 | +#ifdef HAVE_AVAHI | ||
35 | +# include <avahi-client/client.h> | ||
36 | +# include <avahi-client/lookup.h> | ||
37 | +# include <avahi-common/simple-watch.h> | ||
38 | +# include <avahi-common/domain.h> | ||
39 | +# include <avahi-common/error.h> | ||
40 | +# include <avahi-common/malloc.h> | ||
41 | +#define kDNSServiceMaxDomainName AVAHI_DOMAIN_NAME_MAX | ||
42 | +#endif /* HAVE_AVAHI */ | ||
43 | |||
44 | |||
45 | /* | ||
46 | @@ -53,7 +71,12 @@ typedef enum | ||
47 | |||
48 | typedef struct | ||
49 | { | ||
50 | +#ifdef HAVE_DNSSD | ||
51 | DNSServiceRef ref; /* Service reference for resolve */ | ||
52 | +#endif /* HAVE_DNSSD */ | ||
53 | +#ifdef HAVE_AVAHI | ||
54 | + int resolved; /* Did we resolve the device? */ | ||
55 | +#endif /* HAVE_AVAHI */ | ||
56 | char *name, /* Service name */ | ||
57 | *domain, /* Domain name */ | ||
58 | *fullName, /* Full name */ | ||
59 | @@ -65,6 +88,20 @@ typedef struct | ||
60 | sent; /* Did we list the device? */ | ||
61 | } cups_device_t; | ||
62 | |||
63 | +typedef struct | ||
64 | +{ | ||
65 | + char key[256]; | ||
66 | + char value[256]; | ||
67 | + | ||
68 | +#ifdef HAVE_DNSSD | ||
69 | + const uint8_t *data; | ||
70 | + const uint8_t *datanext; | ||
71 | + const uint8_t *dataend; | ||
72 | +#else /* HAVE_AVAHI */ | ||
73 | + AvahiStringList *txt; | ||
74 | +#endif /* HAVE_DNSSD */ | ||
75 | +} cups_txt_records_t; | ||
76 | + | ||
77 | |||
78 | /* | ||
79 | * Local globals... | ||
80 | @@ -78,6 +115,7 @@ static int job_canceled = 0; | ||
81 | * Local functions... | ||
82 | */ | ||
83 | |||
84 | +#ifdef HAVE_DNSSD | ||
85 | static void browse_callback(DNSServiceRef sdRef, | ||
86 | DNSServiceFlags flags, | ||
87 | uint32_t interfaceIndex, | ||
88 | @@ -93,12 +131,6 @@ static void browse_local_callback(DNSSe | ||
89 | const char *regtype, | ||
90 | const char *replyDomain, | ||
91 | void *context); | ||
92 | -static int compare_devices(cups_device_t *a, cups_device_t *b); | ||
93 | -static void exec_backend(char **argv); | ||
94 | -static cups_device_t *get_device(cups_array_t *devices, | ||
95 | - const char *serviceName, | ||
96 | - const char *regtype, | ||
97 | - const char *replyDomain); | ||
98 | static void query_callback(DNSServiceRef sdRef, | ||
99 | DNSServiceFlags flags, | ||
100 | uint32_t interfaceIndex, | ||
101 | @@ -107,9 +139,118 @@ static void query_callback(DNSServiceRe | ||
102 | uint16_t rrclass, uint16_t rdlen, | ||
103 | const void *rdata, uint32_t ttl, | ||
104 | void *context); | ||
105 | +#endif /* HAVE_DNSSD */ | ||
106 | +#ifdef HAVE_AVAHI | ||
107 | +static void avahi_client_callback (AvahiClient *client, | ||
108 | + AvahiClientState state, | ||
109 | + void *context); | ||
110 | +static void avahi_browse_callback (AvahiServiceBrowser *browser, | ||
111 | + AvahiIfIndex interface, | ||
112 | + AvahiProtocol protocol, | ||
113 | + AvahiBrowserEvent event, | ||
114 | + const char *serviceName, | ||
115 | + const char *regtype, | ||
116 | + const char *replyDomain, | ||
117 | + AvahiLookupResultFlags flags, | ||
118 | + void *context); | ||
119 | +#endif /* HAVE_AVAHI */ | ||
120 | + | ||
121 | +static cups_device_t * find_device (cups_array_t *devices, | ||
122 | + cups_txt_records_t *txt, | ||
123 | + cups_device_t *dkey); | ||
124 | +static int compare_devices(cups_device_t *a, cups_device_t *b); | ||
125 | +static void exec_backend(char **argv); | ||
126 | +static cups_device_t *get_device(cups_array_t *devices, | ||
127 | + const char *serviceName, | ||
128 | + const char *regtype, | ||
129 | + const char *replyDomain); | ||
130 | static void sigterm_handler(int sig); | ||
131 | static void unquote(char *dst, const char *src, size_t dstsize); | ||
132 | |||
133 | +#ifdef HAVE_AVAHI | ||
134 | +static AvahiSimplePoll *simple_poll = NULL; | ||
135 | +static int avahi_got_callback; | ||
136 | +#endif /* HAVE_AVAHI */ | ||
137 | + | ||
138 | + | ||
139 | +/* | ||
140 | + * 'next_txt_record()' - Get next TXT record from a cups_txt_records_t. | ||
141 | + */ | ||
142 | + | ||
143 | +static cups_txt_records_t * | ||
144 | +next_txt_record (cups_txt_records_t *txt) | ||
145 | +{ | ||
146 | +#ifdef HAVE_DNSSD | ||
147 | + txt->data = txt->datanext; | ||
148 | +#else /* HAVE_AVAHI */ | ||
149 | + txt->txt = avahi_string_list_get_next (txt->txt); | ||
150 | + if (txt->txt == NULL) | ||
151 | + return NULL; | ||
152 | +#endif /* HAVE_DNSSD */ | ||
153 | + | ||
154 | + return txt; | ||
155 | +} | ||
156 | + | ||
157 | + | ||
158 | +/* | ||
159 | + * 'parse_txt_record_pair()' - Read key/value pair in cups_txt_records_t. | ||
160 | + */ | ||
161 | + | ||
162 | +static int | ||
163 | +parse_txt_record_pair (cups_txt_records_t *txt) | ||
164 | +{ | ||
165 | +#ifdef HAVE_DNSSD | ||
166 | + uint8_t datalen; | ||
167 | + uint8_t *data = txt->data; | ||
168 | + char *ptr; | ||
169 | + | ||
170 | + /* | ||
171 | + * Read a key/value pair starting with an 8-bit length. Since the | ||
172 | + * length is 8 bits and the size of the key/value buffers is 256, we | ||
173 | + * don't need to check for overflow... | ||
174 | + */ | ||
175 | + | ||
176 | + datalen = *data++; | ||
177 | + if (!datalen || (data + datalen) >= txt->dataend) | ||
178 | + return NULL; | ||
179 | + txt->datanext = data + datalen; | ||
180 | + | ||
181 | + for (ptr = txt->key; data < txt->datanext && *data != '='; data ++) | ||
182 | + *ptr++ = *data; | ||
183 | + *ptr = '\0'; | ||
184 | + | ||
185 | + if (data < txt->datanext && *data == '=') | ||
186 | + { | ||
187 | + data++; | ||
188 | + | ||
189 | + if (data < datanext) | ||
190 | + memcpy (txt->value, data, txt->datanext - data); | ||
191 | + value[txt->datanext - data] = '\0'; | ||
192 | + } | ||
193 | + else | ||
194 | + return 1; | ||
195 | +#else /* HAVE_AVAHI */ | ||
196 | + char *key, *value; | ||
197 | + size_t len; | ||
198 | + avahi_string_list_get_pair (txt->txt, &key, &value, &len); | ||
199 | + if (len > sizeof (txt->value) - 1) | ||
200 | + len = sizeof (txt->value) - 1; | ||
201 | + | ||
202 | + memcpy (txt->value, value, len); | ||
203 | + txt->value[len] = '\0'; | ||
204 | + len = strlen (key); | ||
205 | + if (len > sizeof (txt->key) - 1) | ||
206 | + len = sizeof (txt->key) - 1; | ||
207 | + | ||
208 | + memcpy (txt->key, key, len); | ||
209 | + txt->key[len] = '\0'; | ||
210 | + avahi_free (key); | ||
211 | + avahi_free (value); | ||
212 | +#endif /* HAVE_AVAHI */ | ||
213 | + | ||
214 | + return 0; | ||
215 | +} | ||
216 | + | ||
217 | |||
218 | /* | ||
219 | * 'main()' - Browse for printers. | ||
220 | @@ -120,6 +261,13 @@ main(int argc, /* I - Number of comm | ||
221 | char *argv[]) /* I - Command-line arguments */ | ||
222 | { | ||
223 | const char *name; /* Backend name */ | ||
224 | + cups_array_t *devices; /* Device array */ | ||
225 | + cups_device_t *device; /* Current device */ | ||
226 | + char uriName[1024]; /* Unquoted fullName for URI */ | ||
227 | +#ifdef HAVE_DNSSD | ||
228 | + int fd; /* Main file descriptor */ | ||
229 | + fd_set input; /* Input set for select() */ | ||
230 | + struct timeval timeout; /* Timeout for select() */ | ||
231 | DNSServiceRef main_ref, /* Main service reference */ | ||
232 | fax_ipp_ref, /* IPP fax service reference */ | ||
233 | ipp_ref, /* IPP service reference */ | ||
234 | @@ -133,12 +281,11 @@ main(int argc, /* I - Number of comm | ||
235 | pdl_datastream_ref, /* AppSocket service reference */ | ||
236 | printer_ref, /* LPD service reference */ | ||
237 | riousbprint_ref; /* Remote IO service reference */ | ||
238 | - int fd; /* Main file descriptor */ | ||
239 | - fd_set input; /* Input set for select() */ | ||
240 | - struct timeval timeout; /* Timeout for select() */ | ||
241 | - cups_array_t *devices; /* Device array */ | ||
242 | - cups_device_t *device; /* Current device */ | ||
243 | - char uriName[1024]; /* Unquoted fullName for URI */ | ||
244 | +#endif /* HAVE_DNSSD */ | ||
245 | +#ifdef HAVE_AVAHI | ||
246 | + AvahiClient *client; | ||
247 | + int error; | ||
248 | +#endif /* HAVE_AVAHI */ | ||
249 | #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) | ||
250 | struct sigaction action; /* Actions for POSIX signals */ | ||
251 | #endif /* HAVE_SIGACTION && !HAVE_SIGSET */ | ||
252 | @@ -198,6 +345,49 @@ main(int argc, /* I - Number of comm | ||
253 | * Browse for different kinds of printers... | ||
254 | */ | ||
255 | |||
256 | +#ifdef HAVE_AVAHI | ||
257 | + if ((simple_poll = avahi_simple_poll_new ()) == NULL) | ||
258 | + { | ||
259 | + perror ("ERROR: Unable to create avahi simple poll object"); | ||
260 | + return (1); | ||
261 | + } | ||
262 | + | ||
263 | + client = avahi_client_new (avahi_simple_poll_get (simple_poll), | ||
264 | + 0, avahi_client_callback, NULL, &error); | ||
265 | + if (!client) | ||
266 | + { | ||
267 | + perror ("DEBUG: Unable to create avahi client"); | ||
268 | + return (0); | ||
269 | + } | ||
270 | + | ||
271 | + avahi_service_browser_new (client, AVAHI_IF_UNSPEC, | ||
272 | + AVAHI_PROTO_UNSPEC, | ||
273 | + "_fax-ipp._tcp", NULL, 0, | ||
274 | + avahi_browse_callback, devices); | ||
275 | + avahi_service_browser_new (client, AVAHI_IF_UNSPEC, | ||
276 | + AVAHI_PROTO_UNSPEC, | ||
277 | + "_ipp._tcp", NULL, 0, | ||
278 | + avahi_browse_callback, devices); | ||
279 | + avahi_service_browser_new (client, AVAHI_IF_UNSPEC, | ||
280 | + AVAHI_PROTO_UNSPEC, | ||
281 | + "_ipp-tls._tcp", NULL, 0, | ||
282 | + avahi_browse_callback, devices); | ||
283 | + avahi_service_browser_new (client, AVAHI_IF_UNSPEC, | ||
284 | + AVAHI_PROTO_UNSPEC, | ||
285 | + "_pdl-datastream._tcp", | ||
286 | + NULL, 0, | ||
287 | + avahi_browse_callback, | ||
288 | + devices); | ||
289 | + avahi_service_browser_new (client, AVAHI_IF_UNSPEC, | ||
290 | + AVAHI_PROTO_UNSPEC, | ||
291 | + "_printer._tcp", NULL, 0, | ||
292 | + avahi_browse_callback, devices); | ||
293 | + avahi_service_browser_new (client, AVAHI_IF_UNSPEC, | ||
294 | + AVAHI_PROTO_UNSPEC, | ||
295 | + "_riousbprint._tcp", NULL, 0, | ||
296 | + avahi_browse_callback, devices); | ||
297 | +#endif /* HAVE_AVAHI */ | ||
298 | +#ifdef HAVE_DNSSD | ||
299 | if (DNSServiceCreateConnection(&main_ref) != kDNSServiceErr_NoError) | ||
300 | { | ||
301 | perror("ERROR: Unable to create service connection"); | ||
302 | @@ -258,6 +448,7 @@ main(int argc, /* I - Number of comm | ||
303 | riousbprint_ref = main_ref; | ||
304 | DNSServiceBrowse(&riousbprint_ref, kDNSServiceFlagsShareConnection, 0, | ||
305 | "_riousbprint._tcp", NULL, browse_callback, devices); | ||
306 | +#endif /* HAVE_DNSSD */ | ||
307 | |||
308 | /* | ||
309 | * Loop until we are killed... | ||
310 | @@ -265,6 +456,9 @@ main(int argc, /* I - Number of comm | ||
311 | |||
312 | while (!job_canceled) | ||
313 | { | ||
314 | + int announce = 0; | ||
315 | + | ||
316 | +#ifdef HAVE_DNSSD | ||
317 | FD_ZERO(&input); | ||
318 | FD_SET(fd, &input); | ||
319 | |||
320 | @@ -284,11 +478,35 @@ main(int argc, /* I - Number of comm | ||
321 | } | ||
322 | else | ||
323 | { | ||
324 | + announce = 1; | ||
325 | + } | ||
326 | +#else /* HAVE_AVAHI */ | ||
327 | + int r; | ||
328 | + avahi_got_callback = 0; | ||
329 | + r = avahi_simple_poll_iterate (simple_poll, 1); | ||
330 | + if (r != 0 && r != EINTR) | ||
331 | + { | ||
332 | + /* | ||
333 | + * We've been told to exit the loop. Perhaps the connection to | ||
334 | + * avahi failed. | ||
335 | + */ | ||
336 | + | ||
337 | + break; | ||
338 | + } | ||
339 | + | ||
340 | + if (avahi_got_callback) | ||
341 | + announce = 1; | ||
342 | +#endif /* HAVE_DNSSD */ | ||
343 | + | ||
344 | + if (announce) | ||
345 | + { | ||
346 | /* | ||
347 | * Announce any devices we've found... | ||
348 | */ | ||
349 | |||
350 | +#ifdef HAVE_DNSSD | ||
351 | DNSServiceErrorType status; /* DNS query status */ | ||
352 | +#endif /* HAVE_DNSSD */ | ||
353 | cups_device_t *best; /* Best matching device */ | ||
354 | char device_uri[1024]; /* Device URI */ | ||
355 | int count; /* Number of queries */ | ||
356 | @@ -302,6 +520,7 @@ main(int argc, /* I - Number of comm | ||
357 | if (device->sent) | ||
358 | sent ++; | ||
359 | |||
360 | +#ifdef HAVE_DNSSD | ||
361 | if (device->ref) | ||
362 | count ++; | ||
363 | |||
364 | @@ -333,14 +552,23 @@ main(int argc, /* I - Number of comm | ||
365 | count ++; | ||
366 | } | ||
367 | } | ||
368 | - else if (!device->sent) | ||
369 | + else | ||
370 | +#endif /* HAVE_DNSSD */ | ||
371 | +#ifdef HAVE_AVAHI | ||
372 | + if (!device->resolved) | ||
373 | + continue; | ||
374 | + else | ||
375 | +#endif /* HAVE_AVAHI */ | ||
376 | + if (!device->sent) | ||
377 | { | ||
378 | +#ifdef HAVE_DNSSD | ||
379 | /* | ||
380 | * Got the TXT records, now report the device... | ||
381 | */ | ||
382 | |||
383 | DNSServiceRefDeallocate(device->ref); | ||
384 | device->ref = 0; | ||
385 | +#endif /* HAVE_DNSSD */ | ||
386 | |||
387 | if (!best) | ||
388 | best = device; | ||
389 | @@ -401,6 +629,7 @@ main(int argc, /* I - Number of comm | ||
390 | } | ||
391 | |||
392 | |||
393 | +#ifdef HAVE_DNSSD | ||
394 | /* | ||
395 | * 'browse_callback()' - Browse devices. | ||
396 | */ | ||
397 | @@ -489,6 +718,7 @@ browse_local_callback( | ||
398 | device->fullName); | ||
399 | device->sent = 1; | ||
400 | } | ||
401 | +#endif /* HAVE_DNSSD */ | ||
402 | |||
403 | |||
404 | /* | ||
405 | @@ -569,6 +799,41 @@ exec_backend(char **argv) /* I - Comman | ||
406 | |||
407 | |||
408 | /* | ||
409 | + * 'device_type()' - Get DNS-SD type enumeration from string. | ||
410 | + */ | ||
411 | + | ||
412 | +static int | ||
413 | +device_type (const char *regtype) | ||
414 | +{ | ||
415 | +#ifdef HAVE_AVAHI | ||
416 | + if (!strcmp(regtype, "_ipp._tcp")) | ||
417 | + return (CUPS_DEVICE_IPP); | ||
418 | + else if (!strcmp(regtype, "_ipps._tcp") || | ||
419 | + !strcmp(regtype, "_ipp-tls._tcp")) | ||
420 | + return (CUPS_DEVICE_IPPS); | ||
421 | + else if (!strcmp(regtype, "_fax-ipp._tcp")) | ||
422 | + return (CUPS_DEVICE_FAX_IPP); | ||
423 | + else if (!strcmp(regtype, "_printer._tcp")) | ||
424 | + return (CUPS_DEVICE_PDL_DATASTREAM); | ||
425 | +#else | ||
426 | + if (!strcmp(regtype, "_ipp._tcp.")) | ||
427 | + return (CUPS_DEVICE_IPP); | ||
428 | + else if (!strcmp(regtype, "_ipps._tcp.") || | ||
429 | + !strcmp(regtype, "_ipp-tls._tcp.")) | ||
430 | + return (CUPS_DEVICE_IPPS); | ||
431 | + else if (!strcmp(regtype, "_fax-ipp._tcp.")) | ||
432 | + return (CUPS_DEVICE_FAX_IPP); | ||
433 | + else if (!strcmp(regtype, "_printer._tcp.")) | ||
434 | + return (CUPS_DEVICE_PRINTER); | ||
435 | + else if (!strcmp(regtype, "_pdl-datastream._tcp.")) | ||
436 | + return (CUPS_DEVICE_PDL_DATASTREAM); | ||
437 | +#endif /* HAVE_AVAHI */ | ||
438 | + | ||
439 | + return (CUPS_DEVICE_RIOUSBPRINT); | ||
440 | +} | ||
441 | + | ||
442 | + | ||
443 | +/* | ||
444 | * 'get_device()' - Create or update a device. | ||
445 | */ | ||
446 | |||
447 | @@ -589,20 +854,7 @@ get_device(cups_array_t *devices, /* I - | ||
448 | */ | ||
449 | |||
450 | key.name = (char *)serviceName; | ||
451 | - | ||
452 | - if (!strcmp(regtype, "_ipp._tcp.")) | ||
453 | - key.type = CUPS_DEVICE_IPP; | ||
454 | - else if (!strcmp(regtype, "_ipps._tcp.") || | ||
455 | - !strcmp(regtype, "_ipp-tls._tcp.")) | ||
456 | - key.type = CUPS_DEVICE_IPPS; | ||
457 | - else if (!strcmp(regtype, "_fax-ipp._tcp.")) | ||
458 | - key.type = CUPS_DEVICE_FAX_IPP; | ||
459 | - else if (!strcmp(regtype, "_printer._tcp.")) | ||
460 | - key.type = CUPS_DEVICE_PRINTER; | ||
461 | - else if (!strcmp(regtype, "_pdl-datastream._tcp.")) | ||
462 | - key.type = CUPS_DEVICE_PDL_DATASTREAM; | ||
463 | - else | ||
464 | - key.type = CUPS_DEVICE_RIOUSBPRINT; | ||
465 | + key.type = device_type (regtype); | ||
466 | |||
467 | for (device = cupsArrayFind(devices, &key); | ||
468 | device; | ||
469 | @@ -622,8 +874,14 @@ get_device(cups_array_t *devices, /* I - | ||
470 | free(device->domain); | ||
471 | device->domain = strdup(replyDomain); | ||
472 | |||
473 | +#ifdef HAVE_DNSSD | ||
474 | DNSServiceConstructFullName(fullName, device->name, regtype, | ||
475 | replyDomain); | ||
476 | +#else /* HAVE_AVAHI */ | ||
477 | + avahi_service_name_join (fullName, kDNSServiceMaxDomainName, | ||
478 | + serviceName, regtype, replyDomain); | ||
479 | +#endif /* HAVE_DNSSD */ | ||
480 | + | ||
481 | free(device->fullName); | ||
482 | device->fullName = strdup(fullName); | ||
483 | } | ||
484 | @@ -643,6 +901,9 @@ get_device(cups_array_t *devices, /* I - | ||
485 | device->domain = strdup(replyDomain); | ||
486 | device->type = key.type; | ||
487 | device->priority = 50; | ||
488 | +#ifdef HAVE_AVAHI | ||
489 | + device->resolved = 0; | ||
490 | +#endif /* HAVE_AVAHI */ | ||
491 | |||
492 | cupsArrayAdd(devices, device); | ||
493 | |||
494 | @@ -650,13 +911,20 @@ get_device(cups_array_t *devices, /* I - | ||
495 | * Set the "full name" of this service, which is used for queries... | ||
496 | */ | ||
497 | |||
498 | +#ifdef HAVE_DNSSD | ||
499 | DNSServiceConstructFullName(fullName, serviceName, regtype, replyDomain); | ||
500 | +#else /* HAVE_AVAHI */ | ||
501 | + avahi_service_name_join (fullName, kDNSServiceMaxDomainName, | ||
502 | + serviceName, regtype, replyDomain); | ||
503 | +#endif /* HAVE_DNSSD */ | ||
504 | + | ||
505 | device->fullName = strdup(fullName); | ||
506 | |||
507 | return (device); | ||
508 | } | ||
509 | |||
510 | |||
511 | +#ifdef HAVE_DNSSD | ||
512 | /* | ||
513 | * 'query_callback()' - Process query data. | ||
514 | */ | ||
515 | @@ -680,7 +948,7 @@ query_callback( | ||
516 | *ptr; /* Pointer into string */ | ||
517 | cups_device_t dkey, /* Search key */ | ||
518 | *device; /* Device */ | ||
519 | - | ||
520 | + cups_txt_records_t txt; | ||
521 | |||
522 | fprintf(stderr, "DEBUG2: query_callback(sdRef=%p, flags=%x, " | ||
523 | "interfaceIndex=%d, errorCode=%d, fullName=\"%s\", " | ||
524 | @@ -714,94 +982,233 @@ query_callback( | ||
525 | if ((ptr = strstr(name, "._")) != NULL) | ||
526 | *ptr = '\0'; | ||
527 | |||
528 | - if (strstr(fullName, "_ipp._tcp.")) | ||
529 | - dkey.type = CUPS_DEVICE_IPP; | ||
530 | - else if (strstr(fullName, "_ipps._tcp.") || | ||
531 | - strstr(fullName, "_ipp-tls._tcp.")) | ||
532 | - dkey.type = CUPS_DEVICE_IPPS; | ||
533 | - else if (strstr(fullName, "_fax-ipp._tcp.")) | ||
534 | - dkey.type = CUPS_DEVICE_FAX_IPP; | ||
535 | - else if (strstr(fullName, "_printer._tcp.")) | ||
536 | - dkey.type = CUPS_DEVICE_PRINTER; | ||
537 | - else if (strstr(fullName, "_pdl-datastream._tcp.")) | ||
538 | - dkey.type = CUPS_DEVICE_PDL_DATASTREAM; | ||
539 | + dkey.type = device_type (fullName); | ||
540 | + | ||
541 | + txt.data = rdata; | ||
542 | + txt.dataend = rdata + rdlen; | ||
543 | + device = find_device ((cups_array_t *) context, &txt, &dkey); | ||
544 | + if (!device) | ||
545 | + fprintf(stderr, "DEBUG: Ignoring TXT record for \"%s\"...\n", fullName); | ||
546 | +} | ||
547 | +#endif /* HAVE_DNSSD */ | ||
548 | + | ||
549 | + | ||
550 | +#ifdef HAVE_AVAHI | ||
551 | +/* | ||
552 | + * 'avahi_client_callback()' - Avahi client callback function. | ||
553 | + */ | ||
554 | + | ||
555 | +static void | ||
556 | +avahi_client_callback(AvahiClient *client, | ||
557 | + AvahiClientState state, | ||
558 | + void *context) | ||
559 | +{ | ||
560 | + /* | ||
561 | + * If the connection drops, quit. | ||
562 | + */ | ||
563 | + | ||
564 | + if (state == AVAHI_CLIENT_FAILURE) | ||
565 | + { | ||
566 | + fprintf (stderr, "ERROR: Avahi connection failed\n"); | ||
567 | + avahi_simple_poll_quit (simple_poll); | ||
568 | + } | ||
569 | +} | ||
570 | + | ||
571 | + | ||
572 | +/* | ||
573 | + * 'avahi_query_callback()' - Avahi query callback function. | ||
574 | + */ | ||
575 | + | ||
576 | +static void | ||
577 | +avahi_query_callback(AvahiServiceResolver *resolver, | ||
578 | + AvahiIfIndex interface, | ||
579 | + AvahiProtocol protocol, | ||
580 | + AvahiResolverEvent event, | ||
581 | + const char *name, | ||
582 | + const char *type, | ||
583 | + const char *domain, | ||
584 | + const char *host_name, | ||
585 | + const AvahiAddress *address, | ||
586 | + uint16_t port, | ||
587 | + AvahiStringList *txt, | ||
588 | + AvahiLookupResultFlags flags, | ||
589 | + void *context) | ||
590 | +{ | ||
591 | + AvahiClient *client; | ||
592 | + cups_device_t key, | ||
593 | + *device; | ||
594 | + char uqname[1024], | ||
595 | + *ptr; | ||
596 | + cups_txt_records_t txtr; | ||
597 | + | ||
598 | + client = avahi_service_resolver_get_client (resolver); | ||
599 | + if (event != AVAHI_RESOLVER_FOUND) | ||
600 | + { | ||
601 | + if (event == AVAHI_RESOLVER_FAILURE) | ||
602 | + { | ||
603 | + fprintf (stderr, "ERROR: %s\n", | ||
604 | + avahi_strerror (avahi_client_errno (client))); | ||
605 | + } | ||
606 | + | ||
607 | + avahi_service_resolver_free (resolver); | ||
608 | + return; | ||
609 | + } | ||
610 | + | ||
611 | + /* | ||
612 | + * Set search key for device. | ||
613 | + */ | ||
614 | + | ||
615 | + key.name = uqname; | ||
616 | + unquote (uqname, name, sizeof (uqname)); | ||
617 | + if ((ptr = strstr(name, "._")) != NULL) | ||
618 | + *ptr = '\0'; | ||
619 | + | ||
620 | + key.domain = (char *) domain; | ||
621 | + key.type = device_type (type); | ||
622 | + | ||
623 | + /* | ||
624 | + * Find the device and the the TXT information. | ||
625 | + */ | ||
626 | + | ||
627 | + txtr.txt = txt; | ||
628 | + device = find_device ((cups_array_t *) context, &txtr, &key); | ||
629 | + if (device) | ||
630 | + { | ||
631 | + /* | ||
632 | + * Let the main loop know to announce the device. | ||
633 | + */ | ||
634 | + | ||
635 | + device->resolved = 1; | ||
636 | + avahi_got_callback = 1; | ||
637 | + } | ||
638 | else | ||
639 | - dkey.type = CUPS_DEVICE_RIOUSBPRINT; | ||
640 | + fprintf (stderr, "DEBUG: Ignoring TXT record for \"%s\"...\n", name); | ||
641 | + | ||
642 | + avahi_service_resolver_free (resolver); | ||
643 | +} | ||
644 | + | ||
645 | + | ||
646 | +/* | ||
647 | + * 'avahi_browse_callback()' - Avahi browse callback function. | ||
648 | + */ | ||
649 | + | ||
650 | +static void | ||
651 | +avahi_browse_callback(AvahiServiceBrowser *browser, | ||
652 | + AvahiIfIndex interface, | ||
653 | + AvahiProtocol protocol, | ||
654 | + AvahiBrowserEvent event, | ||
655 | + const char *name, | ||
656 | + const char *type, | ||
657 | + const char *domain, | ||
658 | + AvahiLookupResultFlags flags, | ||
659 | + void *context) | ||
660 | +{ | ||
661 | + AvahiClient *client = avahi_service_browser_get_client (browser); | ||
662 | + | ||
663 | + switch (event) | ||
664 | + { | ||
665 | + case AVAHI_BROWSER_FAILURE: | ||
666 | + fprintf (stderr, "ERROR: %s\n", | ||
667 | + avahi_strerror (avahi_client_errno (client))); | ||
668 | + avahi_simple_poll_quit (simple_poll); | ||
669 | + return; | ||
670 | + | ||
671 | + case AVAHI_BROWSER_NEW: | ||
672 | + /* | ||
673 | + * This object is new on the network. | ||
674 | + */ | ||
675 | + | ||
676 | + if (flags & AVAHI_LOOKUP_RESULT_LOCAL) | ||
677 | + { | ||
678 | + /* | ||
679 | + * This comes from the local machine so ignore it. | ||
680 | + */ | ||
681 | + | ||
682 | + fprintf (stderr, "DEBUG: ignoring local service %s\n", name); | ||
683 | + } | ||
684 | + else | ||
685 | + { | ||
686 | + /* | ||
687 | + * Create a device entry for it if it doesn't yet exist. | ||
688 | + */ | ||
689 | + | ||
690 | + get_device ((cups_array_t *)context, name, type, domain); | ||
691 | + | ||
692 | + /* | ||
693 | + * Now look for a TXT entry. | ||
694 | + */ | ||
695 | + | ||
696 | + if (avahi_service_resolver_new (client, interface, protocol, | ||
697 | + name, type, domain, | ||
698 | + AVAHI_PROTO_UNSPEC, 0, | ||
699 | + avahi_query_callback, context) == NULL) | ||
700 | + { | ||
701 | + fprintf (stderr, "ERROR: failed to resolve service %s: %s\n", | ||
702 | + name, avahi_strerror (avahi_client_errno (client))); | ||
703 | + } | ||
704 | + } | ||
705 | + | ||
706 | + break; | ||
707 | + | ||
708 | + case AVAHI_BROWSER_REMOVE: | ||
709 | + case AVAHI_BROWSER_ALL_FOR_NOW: | ||
710 | + case AVAHI_BROWSER_CACHE_EXHAUSTED: | ||
711 | + break; | ||
712 | + } | ||
713 | +} | ||
714 | +#endif /* HAVE_AVAHI */ | ||
715 | + | ||
716 | |||
717 | - for (device = cupsArrayFind(devices, &dkey); | ||
718 | +/* | ||
719 | + * 'find_device()' - Find a device from its name and domain. | ||
720 | + */ | ||
721 | + | ||
722 | +static cups_device_t * | ||
723 | +find_device (cups_array_t *devices, | ||
724 | + cups_txt_records_t *txt, | ||
725 | + cups_device_t *dkey) | ||
726 | +{ | ||
727 | + cups_device_t *device; | ||
728 | + char *ptr; | ||
729 | + | ||
730 | + for (device = cupsArrayFind(devices, dkey); | ||
731 | device; | ||
732 | device = cupsArrayNext(devices)) | ||
733 | { | ||
734 | - if (_cups_strcasecmp(device->name, dkey.name) || | ||
735 | - _cups_strcasecmp(device->domain, dkey.domain)) | ||
736 | + if (_cups_strcasecmp(device->name, dkey->name) || | ||
737 | + _cups_strcasecmp(device->domain, dkey->domain)) | ||
738 | { | ||
739 | device = NULL; | ||
740 | break; | ||
741 | } | ||
742 | - else if (device->type == dkey.type) | ||
743 | + else if (device->type == dkey->type) | ||
744 | { | ||
745 | /* | ||
746 | * Found it, pull out the priority and make and model from the TXT | ||
747 | * record and save it... | ||
748 | */ | ||
749 | |||
750 | - const uint8_t *data, /* Pointer into data */ | ||
751 | - *datanext, /* Next key/value pair */ | ||
752 | - *dataend; /* End of entire TXT record */ | ||
753 | - uint8_t datalen; /* Length of current key/value pair */ | ||
754 | - char key[256], /* Key string */ | ||
755 | - value[256], /* Value string */ | ||
756 | - make_and_model[512], | ||
757 | + char make_and_model[512], | ||
758 | /* Manufacturer and model */ | ||
759 | model[256], /* Model */ | ||
760 | - device_id[2048];/* 1284 device ID */ | ||
761 | - | ||
762 | + device_id[2048]; /* 1284 device ID */ | ||
763 | |||
764 | device_id[0] = '\0'; | ||
765 | make_and_model[0] = '\0'; | ||
766 | |||
767 | strcpy(model, "Unknown"); | ||
768 | |||
769 | - for (data = rdata, dataend = data + rdlen; | ||
770 | - data < dataend; | ||
771 | - data = datanext) | ||
772 | + for (;;) | ||
773 | { | ||
774 | - /* | ||
775 | - * Read a key/value pair starting with an 8-bit length. Since the | ||
776 | - * length is 8 bits and the size of the key/value buffers is 256, we | ||
777 | - * don't need to check for overflow... | ||
778 | - */ | ||
779 | - | ||
780 | - datalen = *data++; | ||
781 | - | ||
782 | - if (!datalen || (data + datalen) > dataend) | ||
783 | - break; | ||
784 | - | ||
785 | - datanext = data + datalen; | ||
786 | - | ||
787 | - for (ptr = key; data < datanext && *data != '='; data ++) | ||
788 | - *ptr++ = *data; | ||
789 | - *ptr = '\0'; | ||
790 | + char *key; | ||
791 | + char *value; | ||
792 | |||
793 | - if (data < datanext && *data == '=') | ||
794 | - { | ||
795 | - data ++; | ||
796 | - | ||
797 | - if (data < datanext) | ||
798 | - memcpy(value, data, datanext - data); | ||
799 | - value[datanext - data] = '\0'; | ||
800 | + if (parse_txt_record_pair (txt)) | ||
801 | + goto next; | ||
802 | |||
803 | - fprintf(stderr, "DEBUG2: query_callback: \"%s=%s\".\n", | ||
804 | - key, value); | ||
805 | - } | ||
806 | - else | ||
807 | - { | ||
808 | - fprintf(stderr, "DEBUG2: query_callback: \"%s\" with no value.\n", | ||
809 | - key); | ||
810 | - continue; | ||
811 | - } | ||
812 | - | ||
813 | - if (!_cups_strncasecmp(key, "usb_", 4)) | ||
814 | + key = txt->key; | ||
815 | + value = txt->value; | ||
816 | + if (!strncasecmp(key, "usb_", 4)) | ||
817 | { | ||
818 | /* | ||
819 | * Add USB device ID information... | ||
820 | @@ -856,6 +1263,10 @@ query_callback( | ||
821 | if (device->type == CUPS_DEVICE_PRINTER) | ||
822 | device->sent = 1; | ||
823 | } | ||
824 | + | ||
825 | + next: | ||
826 | + if (next_txt_record (txt) == NULL) | ||
827 | + break; | ||
828 | } | ||
829 | |||
830 | if (device->device_id) | ||
831 | @@ -912,11 +1323,9 @@ query_callback( | ||
832 | } | ||
833 | } | ||
834 | |||
835 | - if (!device) | ||
836 | - fprintf(stderr, "DEBUG: Ignoring TXT record for \"%s\"...\n", fullName); | ||
837 | + return device; | ||
838 | } | ||
839 | |||
840 | - | ||
841 | /* | ||
842 | * 'sigterm_handler()' - Handle termination signals... | ||
843 | */ | ||
844 | diff -up cups-1.5.2/cups/http-support.c.avahi-2-backend cups-1.5.2/cups/http-support.c | ||
845 | --- cups-1.5.2/cups/http-support.c.avahi-2-backend 2011-09-26 20:46:46.000000000 +0200 | ||
846 | +++ cups-1.5.2/cups/http-support.c 2012-02-06 11:09:08.327644629 +0100 | ||
847 | @@ -43,6 +43,10 @@ | ||
848 | * http_copy_decode() - Copy and decode a URI. | ||
849 | * http_copy_encode() - Copy and encode a URI. | ||
850 | * http_resolve_cb() - Build a device URI for the given service name. | ||
851 | + * avahi_resolve_uri_client_cb() | ||
852 | + * - Avahi client callback for resolving URI. | ||
853 | + * avahi_resolve_uri_resolver_cb() | ||
854 | + * - Avahi resolver callback for resolving URI. | ||
855 | */ | ||
856 | |||
857 | /* | ||
858 | @@ -60,6 +64,11 @@ | ||
859 | # include <sys/select.h> | ||
860 | # endif /* WIN32 */ | ||
861 | #endif /* HAVE_DNSSD */ | ||
862 | +#ifdef HAVE_AVAHI | ||
863 | +# include <avahi-client/client.h> | ||
864 | +# include <avahi-client/lookup.h> | ||
865 | +# include <avahi-common/simple-watch.h> | ||
866 | +#endif /* HAVE_AVAHI */ | ||
867 | |||
868 | |||
869 | /* | ||
870 | @@ -127,6 +136,24 @@ static void DNSSD_API http_resolve_cb(DN | ||
871 | void *context); | ||
872 | #endif /* HAVE_DNSSD */ | ||
873 | |||
874 | +#ifdef HAVE_AVAHI | ||
875 | +static void avahi_resolve_uri_client_cb(AvahiClient *client, | ||
876 | + AvahiClientState state, | ||
877 | + void *simple_poll); | ||
878 | +static void avahi_resolve_uri_resolver_cb(AvahiServiceResolver *resolver, | ||
879 | + AvahiIfIndex interface, | ||
880 | + AvahiProtocol protocol, | ||
881 | + AvahiResolverEvent event, | ||
882 | + const char *name, | ||
883 | + const char *type, | ||
884 | + const char *domain, | ||
885 | + const char *host_name, | ||
886 | + const AvahiAddress *address, | ||
887 | + uint16_t port, | ||
888 | + AvahiStringList *txt, | ||
889 | + AvahiLookupResultFlags flags, | ||
890 | + void *context); | ||
891 | +#endif /* HAVE_AVAHI */ | ||
892 | |||
893 | /* | ||
894 | * 'httpAssembleURI()' - Assemble a uniform resource identifier from its | ||
895 | @@ -1431,6 +1458,9 @@ _httpResolveURI( | ||
896 | |||
897 | if (strstr(hostname, "._tcp")) | ||
898 | { | ||
899 | +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) | ||
900 | + char *regtype, /* Pointer to type in hostname */ | ||
901 | + *domain; /* Pointer to domain in hostname */ | ||
902 | #ifdef HAVE_DNSSD | ||
903 | # ifdef WIN32 | ||
904 | # pragma comment(lib, "dnssd.lib") | ||
905 | @@ -1449,6 +1479,17 @@ _httpResolveURI( | ||
906 | fd_set input_set; /* Input set for select() */ | ||
907 | struct timeval stimeout; /* Timeout value for select() */ | ||
908 | #endif /* HAVE_POLL */ | ||
909 | +#else /* HAVE_AVAHI */ | ||
910 | + AvahiSimplePoll *simple_poll; | ||
911 | + AvahiClient *client; | ||
912 | + int error; | ||
913 | + struct | ||
914 | + { | ||
915 | + AvahiSimplePoll *poll; | ||
916 | + _http_uribuf_t uribuf; | ||
917 | + } user_data; | ||
918 | +#endif /* HAVE_DNSSD */ | ||
919 | + | ||
920 | |||
921 | if (options & _HTTP_RESOLVE_STDERR) | ||
922 | fprintf(stderr, "DEBUG: Resolving \"%s\"...\n", hostname); | ||
923 | @@ -1485,9 +1526,16 @@ _httpResolveURI( | ||
924 | if (domain) | ||
925 | *domain++ = '\0'; | ||
926 | |||
927 | +#ifdef HAVE_DNSSD | ||
928 | uribuf.buffer = resolved_uri; | ||
929 | uribuf.bufsize = resolved_size; | ||
930 | uribuf.options = options; | ||
931 | +#else | ||
932 | + user_data.uribuf.buffer = resolved_uri; | ||
933 | + user_data.uribuf.bufsize = resolved_size; | ||
934 | + user_data.uribuf.options = options; | ||
935 | +#endif | ||
936 | + | ||
937 | resolved_uri[0] = '\0'; | ||
938 | |||
939 | DEBUG_printf(("6_httpResolveURI: Resolving hostname=\"%s\", regtype=\"%s\", " | ||
940 | @@ -1501,6 +1549,7 @@ _httpResolveURI( | ||
941 | |||
942 | uri = NULL; | ||
943 | |||
944 | +#ifdef HAVE_DNSSD | ||
945 | if (DNSServiceCreateConnection(&ref) == kDNSServiceErr_NoError) | ||
946 | { | ||
947 | localref = ref; | ||
948 | @@ -1608,6 +1657,36 @@ _httpResolveURI( | ||
949 | |||
950 | DNSServiceRefDeallocate(ref); | ||
951 | } | ||
952 | +#else /* HAVE_AVAHI */ | ||
953 | + if ((simple_poll = avahi_simple_poll_new ()) != NULL) | ||
954 | + { | ||
955 | + if ((client = avahi_client_new (avahi_simple_poll_get (simple_poll), | ||
956 | + 0, avahi_resolve_uri_client_cb, | ||
957 | + &simple_poll, &error)) != NULL) | ||
958 | + { | ||
959 | + user_data.poll = simple_poll; | ||
960 | + if (avahi_service_resolver_new (client, AVAHI_IF_UNSPEC, | ||
961 | + AVAHI_PROTO_UNSPEC, hostname, | ||
962 | + regtype, domain, AVAHI_PROTO_UNSPEC, 0, | ||
963 | + avahi_resolve_uri_resolver_cb, | ||
964 | + &user_data) != NULL) | ||
965 | + { | ||
966 | + avahi_simple_poll_loop (simple_poll); | ||
967 | + | ||
968 | + /* | ||
969 | + * Collect the result. | ||
970 | + */ | ||
971 | + | ||
972 | + if (resolved_uri[0]) | ||
973 | + uri = resolved_uri; | ||
974 | + } | ||
975 | + | ||
976 | + avahi_client_free (client); | ||
977 | + } | ||
978 | + | ||
979 | + avahi_simple_poll_free (simple_poll); | ||
980 | + } | ||
981 | +#endif /* HAVE_DNSSD */ | ||
982 | |||
983 | if (options & _HTTP_RESOLVE_STDERR) | ||
984 | { | ||
985 | @@ -1619,13 +1698,13 @@ _httpResolveURI( | ||
986 | fputs("STATE: -connecting-to-device,offline-report\n", stderr); | ||
987 | } | ||
988 | |||
989 | -#else | ||
990 | +#else /* HAVE_DNSSD || HAVE_AVAHI */ | ||
991 | /* | ||
992 | * No DNS-SD support... | ||
993 | */ | ||
994 | |||
995 | uri = NULL; | ||
996 | -#endif /* HAVE_DNSSD */ | ||
997 | +#endif /* HAVE_DNSSD || HAVE_AVAHI */ | ||
998 | |||
999 | if ((options & _HTTP_RESOLVE_STDERR) && !uri) | ||
1000 | _cupsLangPrintFilter(stderr, "ERROR", _("Unable to find printer.")); | ||
1001 | @@ -1914,6 +1993,116 @@ http_resolve_cb( | ||
1002 | #endif /* HAVE_DNSSD */ | ||
1003 | |||
1004 | |||
1005 | +#ifdef HAVE_AVAHI | ||
1006 | +/* | ||
1007 | + * 'avahi_resolve_uri_client_cb()' - Avahi client callback for resolving URI. | ||
1008 | + */ | ||
1009 | + | ||
1010 | +static void | ||
1011 | +avahi_resolve_uri_client_cb (AvahiClient *client, | ||
1012 | + AvahiClientState state, | ||
1013 | + void *simple_poll) | ||
1014 | +{ | ||
1015 | + DEBUG_printf(("avahi_resolve_uri_client_callback(client=%p, state=%d, " | ||
1016 | + "simple_poll=%p)\n", client, state, simple_poll)); | ||
1017 | + | ||
1018 | + /* | ||
1019 | + * If the connection drops, quit. | ||
1020 | + */ | ||
1021 | + | ||
1022 | + if (state == AVAHI_CLIENT_FAILURE) | ||
1023 | + avahi_simple_poll_quit (simple_poll); | ||
1024 | +} | ||
1025 | + | ||
1026 | + | ||
1027 | +/* | ||
1028 | + * 'avahi_resolve_uri_resolver_cb()' - Avahi resolver callback for resolving | ||
1029 | + * URI. | ||
1030 | + */ | ||
1031 | + | ||
1032 | +static void | ||
1033 | +avahi_resolve_uri_resolver_cb (AvahiServiceResolver *resolver, | ||
1034 | + AvahiIfIndex interface, | ||
1035 | + AvahiProtocol protocol, | ||
1036 | + AvahiResolverEvent event, | ||
1037 | + const char *name, | ||
1038 | + const char *type, | ||
1039 | + const char *domain, | ||
1040 | + const char *host_name, | ||
1041 | + const AvahiAddress *address, | ||
1042 | + uint16_t port, | ||
1043 | + AvahiStringList *txt, | ||
1044 | + AvahiLookupResultFlags flags, | ||
1045 | + void *context) | ||
1046 | +{ | ||
1047 | + const char *scheme; /* URI scheme */ | ||
1048 | + char rp[256]; /* Remote printer */ | ||
1049 | + AvahiStringList *pair; | ||
1050 | + char *value; | ||
1051 | + size_t valueLen = 0; | ||
1052 | + char addr[AVAHI_ADDRESS_STR_MAX]; | ||
1053 | + struct | ||
1054 | + { | ||
1055 | + AvahiSimplePoll *poll; | ||
1056 | + _http_uribuf_t uribuf; | ||
1057 | + } *poll_uribuf = context; | ||
1058 | + | ||
1059 | + DEBUG_printf(("avahi_resolve_uri_resolver_callback(resolver=%p, " | ||
1060 | + "interface=%d, protocol=%d, event=%d, name=\"%s\", " | ||
1061 | + "type=\"%s\", domain=\"%s\", host_name=\"%s\", address=%p, " | ||
1062 | + "port=%d, txt=%p, flags=%d, context=%p)\n", | ||
1063 | + resolver, interface, protocol, event, name, type, domain, | ||
1064 | + host_name, address, port, txt, flags, context)); | ||
1065 | + | ||
1066 | + if (event != AVAHI_RESOLVER_FOUND) | ||
1067 | + { | ||
1068 | + avahi_service_resolver_free (resolver); | ||
1069 | + avahi_simple_poll_quit (poll_uribuf->poll); | ||
1070 | + return; | ||
1071 | + } | ||
1072 | + | ||
1073 | + /* | ||
1074 | + * Figure out the scheme from the full name... | ||
1075 | + */ | ||
1076 | + | ||
1077 | + if (strstr(type, "_ipp.")) | ||
1078 | + scheme = "ipp"; | ||
1079 | + else if (strstr(type, "_printer.")) | ||
1080 | + scheme = "lpd"; | ||
1081 | + else if (strstr(type, "_pdl-datastream.")) | ||
1082 | + scheme = "socket"; | ||
1083 | + else | ||
1084 | + scheme = "riousbprint"; | ||
1085 | + | ||
1086 | + /* | ||
1087 | + * Extract the "remote printer key from the TXT record... | ||
1088 | + */ | ||
1089 | + | ||
1090 | + if ((pair = avahi_string_list_find (txt, "rp")) != NULL) | ||
1091 | + { | ||
1092 | + avahi_string_list_get_pair (pair, NULL, &value, &valueLen); | ||
1093 | + rp[0] = '/'; | ||
1094 | + memcpy (rp + 1, value, valueLen); | ||
1095 | + rp[valueLen + 1] = '\0'; | ||
1096 | + } | ||
1097 | + else | ||
1098 | + rp[0] = '\0'; | ||
1099 | + | ||
1100 | + /* | ||
1101 | + * Assemble the final device URI... | ||
1102 | + */ | ||
1103 | + | ||
1104 | + avahi_address_snprint (addr, AVAHI_ADDRESS_STR_MAX, address); | ||
1105 | + httpAssembleURI(HTTP_URI_CODING_ALL, poll_uribuf->uribuf.buffer, | ||
1106 | + poll_uribuf->uribuf.bufsize, scheme, NULL, | ||
1107 | + addr, port, rp); | ||
1108 | + DEBUG_printf(("avahi_resolve_uri_resolver_callback: Resolved URI is \"%s\"\n", | ||
1109 | + poll_uribuf->uribuf.buffer)); | ||
1110 | + avahi_simple_poll_quit (poll_uribuf->poll); | ||
1111 | +} | ||
1112 | +#endif /* HAVE_AVAHI */ | ||
1113 | + | ||
1114 | + | ||
1115 | /* | ||
1116 | * End of "$Id: http-support.c 10017 2011-09-26 18:46:46Z mike $". | ||
1117 | */ |