1 diff -up cups-1.5.0/backend/dnssd.c.avahi-2-backend cups-1.5.0/backend/dnssd.c
2 --- cups-1.5.0/backend/dnssd.c.avahi-2-backend 2011-08-05 15:04:46.182591844 +0100
3 +++ cups-1.5.0/backend/dnssd.c 2011-08-05 15:05:13.868710181 +0100
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.
28 #include "backend-private.h"
29 #include <cups/array.h>
33 +#endif /* HAVE_DNSSD */
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 */
46 @@ -53,7 +71,12 @@ typedef enum
51 DNSServiceRef ref; /* Service reference for resolve */
52 +#endif /* HAVE_DNSSD */
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? */
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;
80 @@ -78,6 +115,7 @@ static int job_canceled = 0;
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
90 const char *replyDomain,
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,
105 +#endif /* HAVE_DNSSD */
107 +static void avahi_client_callback (AvahiClient *client,
108 + AvahiClientState state,
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,
119 +#endif /* HAVE_AVAHI */
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);
134 +static AvahiSimplePoll *simple_poll = NULL;
135 +static int avahi_got_callback;
136 +#endif /* HAVE_AVAHI */
140 + * 'next_txt_record()' - Get next TXT record from a cups_txt_records_t.
143 +static cups_txt_records_t *
144 +next_txt_record (cups_txt_records_t *txt)
147 + txt->data = txt->datanext;
148 +#else /* HAVE_AVAHI */
149 + txt->txt = avahi_string_list_get_next (txt->txt);
150 + if (txt->txt == NULL)
152 +#endif /* HAVE_DNSSD */
159 + * 'parse_txt_record_pair()' - Read key/value pair in cups_txt_records_t.
163 +parse_txt_record_pair (cups_txt_records_t *txt)
167 + uint8_t *data = txt->data;
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...
177 + if (!datalen || (data + datalen) >= txt->dataend)
179 + txt->datanext = data + datalen;
181 + for (ptr = txt->key; data < txt->datanext && *data != '='; data ++)
185 + if (data < txt->datanext && *data == '=')
189 + if (data < datanext)
190 + memcpy (txt->value, data, txt->datanext - data);
191 + value[txt->datanext - data] = '\0';
195 +#else /* HAVE_AVAHI */
198 + avahi_string_list_get_pair (txt->txt, &key, &value, &len);
199 + if (len > sizeof (txt->value) - 1)
200 + len = sizeof (txt->value) - 1;
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;
208 + memcpy (txt->key, key, len);
209 + txt->key[len] = '\0';
211 + avahi_free (value);
212 +#endif /* HAVE_AVAHI */
219 * 'main()' - Browse for printers.
220 @@ -120,6 +261,13 @@ main(int argc, /* I - Number of comm
221 char *argv[]) /* I - Command-line arguments */
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 */
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 */
246 + AvahiClient *client;
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...
257 + if ((simple_poll = avahi_simple_poll_new ()) == NULL)
259 + perror ("ERROR: Unable to create avahi simple poll object");
263 + client = avahi_client_new (avahi_simple_poll_get (simple_poll),
264 + 0, avahi_client_callback, NULL, &error);
267 + perror ("DEBUG: Unable to create avahi client");
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",
287 + avahi_browse_callback,
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 */
299 if (DNSServiceCreateConnection(&main_ref) != kDNSServiceErr_NoError)
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 */
309 * Loop until we are killed...
310 @@ -265,6 +456,9 @@ main(int argc, /* I - Number of comm
312 while (!job_canceled)
320 @@ -284,11 +478,35 @@ main(int argc, /* I - Number of comm
326 +#else /* HAVE_AVAHI */
328 + avahi_got_callback = 0;
329 + r = avahi_simple_poll_iterate (simple_poll, 1);
330 + if (r != 0 && r != EINTR)
333 + * We've been told to exit the loop. Perhaps the connection to
340 + if (avahi_got_callback)
342 +#endif /* HAVE_DNSSD */
347 * Announce any devices we've found...
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
364 @@ -333,14 +552,23 @@ main(int argc, /* I - Number of comm
368 - else if (!device->sent)
370 +#endif /* HAVE_DNSSD */
372 + if (!device->resolved)
375 +#endif /* HAVE_AVAHI */
380 * Got the TXT records, now report the device...
383 DNSServiceRefDeallocate(device->ref);
385 +#endif /* HAVE_DNSSD */
389 @@ -401,6 +629,7 @@ main(int argc, /* I - Number of comm
395 * 'browse_callback()' - Browse devices.
397 @@ -489,6 +718,7 @@ browse_local_callback(
401 +#endif /* HAVE_DNSSD */
405 @@ -569,6 +799,41 @@ exec_backend(char **argv) /* I - Comman
409 + * 'device_type()' - Get DNS-SD type enumeration from string.
413 +device_type (const char *regtype)
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);
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 */
439 + return (CUPS_DEVICE_RIOUSBPRINT);
444 * 'get_device()' - Create or update a device.
447 @@ -589,20 +854,7 @@ get_device(cups_array_t *devices, /* I -
450 key.name = (char *)serviceName;
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;
464 - key.type = CUPS_DEVICE_RIOUSBPRINT;
465 + key.type = device_type (regtype);
467 for (device = cupsArrayFind(devices, &key);
469 @@ -622,8 +874,14 @@ get_device(cups_array_t *devices, /* I -
470 free(device->domain);
471 device->domain = strdup(replyDomain);
474 DNSServiceConstructFullName(fullName, device->name, regtype,
476 +#else /* HAVE_AVAHI */
477 + avahi_service_name_join (fullName, kDNSServiceMaxDomainName,
478 + serviceName, regtype, replyDomain);
479 +#endif /* HAVE_DNSSD */
481 free(device->fullName);
482 device->fullName = strdup(fullName);
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;
489 + device->resolved = 0;
490 +#endif /* HAVE_AVAHI */
492 cupsArrayAdd(devices, device);
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...
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 */
505 device->fullName = strdup(fullName);
513 * 'query_callback()' - Process query data.
515 @@ -680,7 +948,7 @@ query_callback(
516 *ptr; /* Pointer into string */
517 cups_device_t dkey, /* Search key */
518 *device; /* Device */
520 + cups_txt_records_t txt;
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)
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);
542 + txt.dataend = rdata + rdlen;
543 + device = find_device ((cups_array_t *) context, &txt, &dkey);
545 + fprintf(stderr, "DEBUG: Ignoring TXT record for \"%s\"...\n", fullName);
547 +#endif /* HAVE_DNSSD */
552 + * 'avahi_client_callback()' - Avahi client callback function.
556 +avahi_client_callback(AvahiClient *client,
557 + AvahiClientState state,
561 + * If the connection drops, quit.
564 + if (state == AVAHI_CLIENT_FAILURE)
566 + fprintf (stderr, "ERROR: Avahi connection failed\n");
567 + avahi_simple_poll_quit (simple_poll);
573 + * 'avahi_query_callback()' - Avahi query callback function.
577 +avahi_query_callback(AvahiServiceResolver *resolver,
578 + AvahiIfIndex interface,
579 + AvahiProtocol protocol,
580 + AvahiResolverEvent event,
583 + const char *domain,
584 + const char *host_name,
585 + const AvahiAddress *address,
587 + AvahiStringList *txt,
588 + AvahiLookupResultFlags flags,
591 + AvahiClient *client;
596 + cups_txt_records_t txtr;
598 + client = avahi_service_resolver_get_client (resolver);
599 + if (event != AVAHI_RESOLVER_FOUND)
601 + if (event == AVAHI_RESOLVER_FAILURE)
603 + fprintf (stderr, "ERROR: %s\n",
604 + avahi_strerror (avahi_client_errno (client)));
607 + avahi_service_resolver_free (resolver);
612 + * Set search key for device.
616 + unquote (uqname, name, sizeof (uqname));
617 + if ((ptr = strstr(name, "._")) != NULL)
620 + key.domain = (char *) domain;
621 + key.type = device_type (type);
624 + * Find the device and the the TXT information.
628 + device = find_device ((cups_array_t *) context, &txtr, &key);
632 + * Let the main loop know to announce the device.
635 + device->resolved = 1;
636 + avahi_got_callback = 1;
639 - dkey.type = CUPS_DEVICE_RIOUSBPRINT;
640 + fprintf (stderr, "DEBUG: Ignoring TXT record for \"%s\"...\n", name);
642 + avahi_service_resolver_free (resolver);
647 + * 'avahi_browse_callback()' - Avahi browse callback function.
651 +avahi_browse_callback(AvahiServiceBrowser *browser,
652 + AvahiIfIndex interface,
653 + AvahiProtocol protocol,
654 + AvahiBrowserEvent event,
657 + const char *domain,
658 + AvahiLookupResultFlags flags,
661 + AvahiClient *client = avahi_service_browser_get_client (browser);
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);
671 + case AVAHI_BROWSER_NEW:
673 + * This object is new on the network.
676 + if (flags & AVAHI_LOOKUP_RESULT_LOCAL)
679 + * This comes from the local machine so ignore it.
682 + fprintf (stderr, "DEBUG: ignoring local service %s\n", name);
687 + * Create a device entry for it if it doesn't yet exist.
690 + get_device ((cups_array_t *)context, name, type, domain);
693 + * Now look for a TXT entry.
696 + if (avahi_service_resolver_new (client, interface, protocol,
697 + name, type, domain,
698 + AVAHI_PROTO_UNSPEC, 0,
699 + avahi_query_callback, context) == NULL)
701 + fprintf (stderr, "ERROR: failed to resolve service %s: %s\n",
702 + name, avahi_strerror (avahi_client_errno (client)));
708 + case AVAHI_BROWSER_REMOVE:
709 + case AVAHI_BROWSER_ALL_FOR_NOW:
710 + case AVAHI_BROWSER_CACHE_EXHAUSTED:
714 +#endif /* HAVE_AVAHI */
717 - for (device = cupsArrayFind(devices, &dkey);
719 + * 'find_device()' - Find a device from its name and domain.
722 +static cups_device_t *
723 +find_device (cups_array_t *devices,
724 + cups_txt_records_t *txt,
725 + cups_device_t *dkey)
727 + cups_device_t *device;
730 + for (device = cupsArrayFind(devices, dkey);
732 device = cupsArrayNext(devices))
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))
742 - else if (device->type == dkey.type)
743 + else if (device->type == dkey->type)
746 * Found it, pull out the priority and make and model from the TXT
747 * record and save it...
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 */
762 + device_id[2048]; /* 1284 device ID */
765 make_and_model[0] = '\0';
767 strcpy(model, "Unknown");
769 - for (data = rdata, dataend = data + rdlen;
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...
782 - if (!datalen || (data + datalen) >= dataend)
785 - datanext = data + datalen;
787 - for (ptr = key; data < datanext && *data != '='; data ++)
793 - if (data < datanext && *data == '=')
797 - if (data < datanext)
798 - memcpy(value, data, datanext - data);
799 - value[datanext - data] = '\0';
800 + if (parse_txt_record_pair (txt))
803 - fprintf(stderr, "DEBUG2: query_callback: \"%s=%s\".\n",
808 - fprintf(stderr, "DEBUG2: query_callback: \"%s\" with no value.\n",
813 - if (!_cups_strncasecmp(key, "usb_", 4))
815 + value = txt->value;
816 + if (!strncasecmp(key, "usb_", 4))
819 * Add USB device ID information...
820 @@ -856,6 +1263,10 @@ query_callback(
821 if (device->type == CUPS_DEVICE_PRINTER)
826 + if (next_txt_record (txt) == NULL)
830 if (device->device_id)
831 @@ -912,11 +1323,9 @@ query_callback(
836 - fprintf(stderr, "DEBUG: Ignoring TXT record for \"%s\"...\n", fullName);
842 * 'sigterm_handler()' - Handle termination signals...
844 diff -up cups-1.5.0/cups/http-support.c.avahi-2-backend cups-1.5.0/cups/http-support.c
845 --- cups-1.5.0/cups/http-support.c.avahi-2-backend 2011-06-10 23:06:26.000000000 +0100
846 +++ cups-1.5.0/cups/http-support.c 2011-08-05 15:05:13.870710117 +0100
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.
859 # include <sys/select.h>
861 #endif /* HAVE_DNSSD */
863 +# include <avahi-client/client.h>
864 +# include <avahi-client/lookup.h>
865 +# include <avahi-common/simple-watch.h>
866 +#endif /* HAVE_AVAHI */
870 @@ -127,6 +136,24 @@ static void DNSSD_API http_resolve_cb(DN
872 #endif /* HAVE_DNSSD */
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,
884 + const char *domain,
885 + const char *host_name,
886 + const AvahiAddress *address,
888 + AvahiStringList *txt,
889 + AvahiLookupResultFlags flags,
891 +#endif /* HAVE_AVAHI */
894 * 'httpAssembleURI()' - Assemble a uniform resource identifier from its
895 @@ -1431,6 +1458,9 @@ _httpResolveURI(
897 if (strstr(hostname, "._tcp"))
899 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
900 + char *regtype, /* Pointer to type in hostname */
901 + *domain; /* Pointer to domain in hostname */
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;
915 + AvahiSimplePoll *poll;
916 + _http_uribuf_t uribuf;
918 +#endif /* HAVE_DNSSD */
921 if (options & _HTTP_RESOLVE_STDERR)
922 fprintf(stderr, "DEBUG: Resolving \"%s\"...\n", hostname);
923 @@ -1485,9 +1526,16 @@ _httpResolveURI(
928 uribuf.buffer = resolved_uri;
929 uribuf.bufsize = resolved_size;
930 uribuf.options = options;
932 + user_data.uribuf.buffer = resolved_uri;
933 + user_data.uribuf.bufsize = resolved_size;
934 + user_data.uribuf.options = options;
937 resolved_uri[0] = '\0';
939 DEBUG_printf(("6_httpResolveURI: Resolving hostname=\"%s\", regtype=\"%s\", "
940 @@ -1501,6 +1549,7 @@ _httpResolveURI(
945 if (DNSServiceCreateConnection(&ref) == kDNSServiceErr_NoError)
948 @@ -1608,6 +1657,36 @@ _httpResolveURI(
950 DNSServiceRefDeallocate(ref);
952 +#else /* HAVE_AVAHI */
953 + if ((simple_poll = avahi_simple_poll_new ()) != NULL)
955 + if ((client = avahi_client_new (avahi_simple_poll_get (simple_poll),
956 + 0, avahi_resolve_uri_client_cb,
957 + &simple_poll, &error)) != NULL)
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)
966 + avahi_simple_poll_loop (simple_poll);
969 + * Collect the result.
972 + if (resolved_uri[0])
973 + uri = resolved_uri;
976 + avahi_client_free (client);
979 + avahi_simple_poll_free (simple_poll);
981 +#endif /* HAVE_DNSSD */
983 if (options & _HTTP_RESOLVE_STDERR)
985 @@ -1619,13 +1698,13 @@ _httpResolveURI(
986 fputs("STATE: -connecting-to-device,offline-report\n", stderr);
990 +#else /* HAVE_DNSSD || HAVE_AVAHI */
992 * No DNS-SD support...
996 -#endif /* HAVE_DNSSD */
997 +#endif /* HAVE_DNSSD || HAVE_AVAHI */
999 if ((options & _HTTP_RESOLVE_STDERR) && !uri)
1000 _cupsLangPrintFilter(stderr, "ERROR", _("Unable to find printer."));
1001 @@ -1895,6 +1974,116 @@ http_resolve_cb(
1002 #endif /* HAVE_DNSSD */
1007 + * 'avahi_resolve_uri_client_cb()' - Avahi client callback for resolving URI.
1011 +avahi_resolve_uri_client_cb (AvahiClient *client,
1012 + AvahiClientState state,
1013 + void *simple_poll)
1015 + DEBUG_printf(("avahi_resolve_uri_client_callback(client=%p, state=%d, "
1016 + "simple_poll=%p)\n", client, state, simple_poll));
1019 + * If the connection drops, quit.
1022 + if (state == AVAHI_CLIENT_FAILURE)
1023 + avahi_simple_poll_quit (simple_poll);
1028 + * 'avahi_resolve_uri_resolver_cb()' - Avahi resolver callback for resolving
1033 +avahi_resolve_uri_resolver_cb (AvahiServiceResolver *resolver,
1034 + AvahiIfIndex interface,
1035 + AvahiProtocol protocol,
1036 + AvahiResolverEvent event,
1039 + const char *domain,
1040 + const char *host_name,
1041 + const AvahiAddress *address,
1043 + AvahiStringList *txt,
1044 + AvahiLookupResultFlags flags,
1047 + const char *scheme; /* URI scheme */
1048 + char rp[256]; /* Remote printer */
1049 + AvahiStringList *pair;
1051 + size_t valueLen = 0;
1052 + char addr[AVAHI_ADDRESS_STR_MAX];
1055 + AvahiSimplePoll *poll;
1056 + _http_uribuf_t uribuf;
1057 + } *poll_uribuf = context;
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));
1066 + if (event != AVAHI_RESOLVER_FOUND)
1068 + avahi_service_resolver_free (resolver);
1069 + avahi_simple_poll_quit (poll_uribuf->poll);
1074 + * Figure out the scheme from the full name...
1077 + if (strstr(type, "_ipp."))
1079 + else if (strstr(type, "_printer."))
1081 + else if (strstr(type, "_pdl-datastream."))
1082 + scheme = "socket";
1084 + scheme = "riousbprint";
1087 + * Extract the "remote printer key from the TXT record...
1090 + if ((pair = avahi_string_list_find (txt, "rp")) != NULL)
1092 + avahi_string_list_get_pair (pair, NULL, &value, &valueLen);
1094 + memcpy (rp + 1, value, valueLen);
1095 + rp[valueLen + 1] = '\0';
1101 + * Assemble the final device URI...
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,
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);
1112 +#endif /* HAVE_AVAHI */