1 diff -up cups-1.5.2/cgi-bin/admin.c.avahi-5-services cups-1.5.2/cgi-bin/admin.c
2 --- cups-1.5.2/cgi-bin/admin.c.avahi-5-services 2011-08-17 22:01:53.000000000 +0100
3 +++ cups-1.5.2/cgi-bin/admin.c 2012-03-14 15:08:25.701611799 +0000
4 @@ -1643,7 +1643,7 @@ do_config_server(http_t *http) /* I - H
6 local_protocols[0] = '\0';
9 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
10 if (cgiGetVariable("BROWSE_LOCAL_DNSSD"))
12 if (local_protocols[0])
13 @@ -1651,7 +1651,7 @@ do_config_server(http_t *http) /* I - H
15 strcat(local_protocols, "dnssd");
17 -#endif /* HAVE_DNSSD */
18 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
21 if (cgiGetVariable("BROWSE_LOCAL_LDAP"))
22 @@ -2718,9 +2718,9 @@ do_menu(http_t *http) /* I - HTTP conn
23 #endif /* HAVE_GSSAPI */
24 cgiSetVariable("KERBEROS", "");
27 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
28 cgiSetVariable("HAVE_DNSSD", "1");
29 -#endif /* HAVE_DNSSD */
30 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
33 cgiSetVariable("HAVE_LDAP", "1");
34 diff -up cups-1.5.2/scheduler/avahi.h.avahi-5-services cups-1.5.2/scheduler/avahi.h
35 --- cups-1.5.2/scheduler/avahi.h.avahi-5-services 2012-03-14 15:07:29.477542381 +0000
36 +++ cups-1.5.2/scheduler/avahi.h 2012-03-14 15:08:25.701611799 +0000
39 * Avahi poll implementation for the CUPS scheduler.
41 - * Copyright (C) 2010, 2011 Red Hat, Inc.
42 + * Copyright (C) 2010, 2011, 2012 Red Hat, Inc.
44 * Tim Waugh <twaugh@redhat.com>
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 +#ifndef _CUPS_AVAHI_H_
52 +# define _CUPS_AVAHI_H_
55 -# include <avahi-client/client.h>
56 -# include <avahi-client/publish.h>
57 -#endif /* HAVE_AVAHI */
59 + * Include necessary headers...
62 -#ifdef HAVE_AUTHORIZATION_H
63 -# include <Security/Authorization.h>
64 -#endif /* HAVE_AUTHORIZATION_H */
68 +# include <avahi-client/client.h>
69 +# include <avahi-client/publish.h>
70 +# endif /* HAVE_AVAHI */
77 cups_array_t *watched_fds;
78 cups_array_t *timeouts;
80 -#endif /* HAVE_AVAHI */
81 +# endif /* HAVE_AVAHI */
89 extern AvahiCupsPoll * avahi_cups_poll_new(void);
90 extern void avahi_cups_poll_free(AvahiCupsPoll *cups_poll);
91 extern const AvahiPoll *avahi_cups_poll_get(AvahiCupsPoll *cups_poll);
92 -#endif /* HAVE_AVAHI */
93 +# endif /* HAVE_AVAHI */
95 +#endif /* !_CUPS_AVAHI_H_ */
99 diff -up cups-1.5.2/scheduler/client.c.avahi-5-services cups-1.5.2/scheduler/client.c
100 --- cups-1.5.2/scheduler/client.c.avahi-5-services 2012-01-13 23:00:22.000000000 +0000
101 +++ cups-1.5.2/scheduler/client.c 2012-03-14 15:08:25.703611797 +0000
102 @@ -4989,7 +4989,7 @@ valid_host(cupsd_client_t *con) /* I -
103 !strncmp(host, "[::1]:", 6));
107 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
109 * Check if the hostname is something.local (Bonjour); if so, allow it.
111 @@ -4998,7 +4998,7 @@ valid_host(cupsd_client_t *con) /* I -
112 (!_cups_strcasecmp(end, ".local") || !_cups_strncasecmp(end, ".local:", 7) ||
113 !_cups_strcasecmp(end, ".local.") || !_cups_strncasecmp(end, ".local.:", 8)))
115 -#endif /* HAVE_DNSSD */
116 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
119 * Check if the hostname is an IP address...
120 diff -up cups-1.5.2/scheduler/conf.c.avahi-5-services cups-1.5.2/scheduler/conf.c
121 --- cups-1.5.2/scheduler/conf.c.avahi-5-services 2012-03-14 15:04:17.636305526 +0000
122 +++ cups-1.5.2/scheduler/conf.c 2012-03-14 15:08:25.706611803 +0000
123 @@ -652,7 +652,7 @@ cupsdReadConfiguration(void)
124 Browsing = CUPS_DEFAULT_BROWSING;
125 DefaultShared = CUPS_DEFAULT_DEFAULT_SHARED;
128 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
129 cupsdSetString(&DNSSDRegType, "_ipp._tcp,_cups");
130 #endif /* HAVE_DNSSD */
132 diff -up cups-1.5.2/scheduler/dirsvc.c.avahi-5-services cups-1.5.2/scheduler/dirsvc.c
133 --- cups-1.5.2/scheduler/dirsvc.c.avahi-5-services 2012-03-14 15:04:17.674305572 +0000
134 +++ cups-1.5.2/scheduler/dirsvc.c 2012-03-14 15:08:25.709611806 +0000
136 * ldap_connect() - Start new LDAP connection
137 * ldap_reconnect() - Reconnect to LDAP Server
138 * ldap_disconnect() - Disconnect from LDAP Server
139 + * cupsdStartAvahiClient() - Start an Avahi client if needed
140 * cupsdStartBrowsing() - Start sending and receiving broadcast
142 * cupsdStartPolling() - Start polling servers as needed.
144 * dequote() - Remote quotes from a string.
145 * dnssdAddAlias() - Add a DNS-SD alias name.
146 * dnssdBuildTxtRecord() - Build a TXT record from printer info.
147 - * dnssdComparePrinters() - Compare the registered names of two printers.
148 * dnssdDeregisterPrinter() - Stop sending broadcast information for a
150 * dnssdPackTxtRecord() - Pack an array of key/value pairs into the TXT
152 + * avahiPackTxtRecord() - Pack an array of key/value pairs into an
154 * dnssdRegisterCallback() - DNSServiceRegister callback.
155 * dnssdRegisterPrinter() - Start sending broadcast information for a
156 * printer or update the broadcast contents.
166 # endif /* HAVE_SYSTEMCONFIGURATION */
167 # endif /* __APPLE__ */
168 #endif /* HAVE_DNSSD */
170 +# include <avahi-common/domain.h>
171 +#endif /* HAVE_AVAHI */
175 +typedef char *cupsd_txt_record_t;
176 +#endif /* HAVE_DNSSD */
178 +typedef AvahiStringList *cupsd_txt_record_t;
179 +#endif /* HAVE_AVAHI */
183 @@ -159,27 +173,38 @@ static void update_polling(void);
184 static void update_smb(int onoff);
187 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
188 +static cupsd_txt_record_t dnssdBuildTxtRecord(int *txt_len, cupsd_printer_t *p,
190 +static void dnssdDeregisterPrinter(cupsd_printer_t *p);
191 +static void dnssdRegisterPrinter(cupsd_printer_t *p);
192 +static void dnssdStop(void);
193 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
196 # ifdef HAVE_COREFOUNDATION
197 static void dnssdAddAlias(const void *key, const void *value,
199 # endif /* HAVE_COREFOUNDATION */
200 -static char *dnssdBuildTxtRecord(int *txt_len, cupsd_printer_t *p,
202 -static int dnssdComparePrinters(cupsd_printer_t *a, cupsd_printer_t *b);
203 -static void dnssdDeregisterPrinter(cupsd_printer_t *p);
204 -static char *dnssdPackTxtRecord(int *txt_len, char *keyvalue[][2],
206 static void dnssdRegisterCallback(DNSServiceRef sdRef,
207 DNSServiceFlags flags,
208 DNSServiceErrorType errorCode,
209 const char *name, const char *regtype,
210 const char *domain, void *context);
211 -static void dnssdRegisterPrinter(cupsd_printer_t *p);
212 -static void dnssdStop(void);
213 static void dnssdUpdate(void);
214 #endif /* HAVE_DNSSD */
217 +static AvahiStringList *avahiPackTxtRecord(char *keyvalue[][2],
219 +static void avahi_entry_group_cb (AvahiEntryGroup *group,
220 + AvahiEntryGroupState state,
222 +static void avahi_client_cb (AvahiClient *client,
223 + AvahiClientState state,
225 +#endif /* HAVE_AVAHI */
228 static const char * const ldap_attrs[] =/* CUPS LDAP attributes */
230 @@ -283,10 +308,10 @@ cupsdDeregisterPrinter(
231 ldap_dereg_printer(p);
232 #endif /* HAVE_LDAP */
235 - if (removeit && (BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDRef)
236 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
237 + if (removeit && (BrowseLocalProtocols & BROWSE_DNSSD))
238 dnssdDeregisterPrinter(p);
239 -#endif /* HAVE_DNSSD */
240 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
244 @@ -702,10 +727,10 @@ cupsdRegisterPrinter(cupsd_printer_t *p)
245 slpRegisterPrinter(p); */
246 #endif /* HAVE_LIBSLP */
249 - if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDRef)
250 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
251 + if ((BrowseLocalProtocols & BROWSE_DNSSD))
252 dnssdRegisterPrinter(p);
253 -#endif /* HAVE_DNSSD */
254 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
258 @@ -1419,6 +1444,36 @@ ldap_disconnect(LDAP *ld) /* I - LDAP h
259 #endif /* HAVE_LDAP */
264 + * 'cupsdStartAvahiClient()' - Start an Avahi client if needed
268 +cupsdStartAvahiClient(void)
272 + if (!AvahiCupsClient && !AvahiCupsClientConnecting)
274 + if (!AvahiCupsPollHandle)
275 + AvahiCupsPollHandle = avahi_cups_poll_new ();
277 + if (AvahiCupsPollHandle)
279 + if (avahi_client_new (avahi_cups_poll_get (AvahiCupsPollHandle),
280 + AVAHI_CLIENT_NO_FAIL,
281 + avahi_client_cb, NULL,
283 + AvahiCupsClientConnecting = 1;
285 + cupsdLogMessage (CUPSD_LOG_WARN, "Avahi client failed: %d", error);
289 +#endif /* HAVE_AVAHI */
293 * 'cupsdStartBrowsing()' - Start sending and receiving broadcast information.
295 @@ -1542,13 +1597,16 @@ cupsdStartBrowsing(void)
300 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
301 if ((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_DNSSD)
304 DNSServiceErrorType error; /* Error from service creation */
305 +#endif /* HAVE_DNSSD */
306 cupsd_listener_t *lis; /* Current listening socket */
311 * First create a "master" connection for all registrations...
313 @@ -1573,6 +1631,7 @@ cupsdStartBrowsing(void)
314 fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
316 cupsdAddSelect(fd, (cupsd_selfunc_t)dnssdUpdate, NULL, NULL);
317 +#endif /* HAVE_DNSSD */
320 * Then get the port we use for registrations. If we are not listening
321 @@ -1598,17 +1657,23 @@ cupsdStartBrowsing(void)
324 if (BrowseRemoteProtocols & BROWSE_DNSSD)
325 - DNSSDPrinters = cupsArrayNew((cups_array_func_t)dnssdComparePrinters,
327 + DNSSDPrinters = cupsArrayNew(NULL, NULL);
330 * Set the computer name and register the web interface...
333 cupsdUpdateDNSSDName();
336 + cupsdStartAvahiClient ();
337 +#endif /* HAVE_AVAHI */
342 #endif /* HAVE_DNSSD */
344 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
347 if ((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_SLP)
348 @@ -1834,10 +1899,10 @@ cupsdStopBrowsing(void)
353 - if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDRef)
354 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
355 + if ((BrowseLocalProtocols & BROWSE_DNSSD))
357 -#endif /* HAVE_DNSSD */
358 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
361 if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_SLP) &&
362 @@ -1902,7 +1967,7 @@ cupsdStopPolling(void)
367 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
369 * 'cupsdUpdateDNSSDName()' - Update the computer name we use for browsing...
371 @@ -1910,8 +1975,14 @@ cupsdStopPolling(void)
373 cupsdUpdateDNSSDName(void)
376 DNSServiceErrorType error; /* Error from service creation */
377 char webif[1024]; /* Web interface share name */
378 +#endif /* HAVE_DNSSD */
380 + int ret; /* Error from service creation */
381 + char webif[AVAHI_LABEL_MAX]; /* Web interface share name */
382 +#endif /* HAVE_AVAHI */
383 # ifdef HAVE_SYSTEMCONFIGURATION
384 SCDynamicStoreRef sc; /* Context for dynamic store */
385 CFDictionaryRef btmm; /* Back-to-My-Mac domains */
386 @@ -2042,6 +2113,7 @@ cupsdUpdateDNSSDName(void)
388 strlcpy(webif, "CUPS Web Interface", sizeof(webif));
392 DNSServiceRefDeallocate(WebIFRef);
394 @@ -2054,9 +2126,45 @@ cupsdUpdateDNSSDName(void)
395 NULL)) != kDNSServiceErr_NoError)
396 cupsdLogMessage(CUPSD_LOG_ERROR,
397 "DNS-SD web interface registration failed: %d", error);
398 +#endif /* HAVE_DNSSD */
401 + if (!AvahiCupsClient)
403 + * Client not yet running.
407 + if (AvahiWebIFGroup)
408 + avahi_entry_group_reset (AvahiWebIFGroup);
410 + AvahiWebIFGroup = avahi_entry_group_new (AvahiCupsClient,
411 + avahi_entry_group_cb,
414 + if (AvahiWebIFGroup)
416 + ret = avahi_entry_group_add_service (AvahiWebIFGroup,
418 + AVAHI_PROTO_UNSPEC,
421 + "_http._tcp", /* type */
424 + DNSSDPort, /* port */
427 + ret = avahi_entry_group_commit (AvahiWebIFGroup);
430 + cupsdLogMessage (CUPSD_LOG_ERROR,
431 + "Avahi web interface registration failed: %d", ret);
433 +#endif /* HAVE_AVAHI */
436 -#endif /* HAVE_DNSSD */
437 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
441 @@ -2334,13 +2442,15 @@ dnssdAddAlias(const void *key, /* I - K
442 "Bad Back to My Mac domain in dynamic store!");
444 # endif /* HAVE_COREFOUNDATION */
445 +#endif /* HAVE_DNSSD */
448 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
450 * 'dnssdBuildTxtRecord()' - Build a TXT record from printer info.
453 -static char * /* O - TXT record */
454 +static cupsd_txt_record_t /* O - TXT record */
456 int *txt_len, /* O - TXT record length */
457 cupsd_printer_t *p, /* I - Printer information */
458 @@ -2379,7 +2489,12 @@ dnssdBuildTxtRecord(
459 keyvalue[i ][0] = "ty";
460 keyvalue[i++][1] = p->make_model ? p->make_model : "Unknown";
462 - snprintf(admin_hostname, sizeof(admin_hostname), "%s.local.", DNSSDHostName);
463 + snprintf(admin_hostname, sizeof(admin_hostname),
466 + "." /* terminating dot no good for Avahi */
467 +#endif /* HAVE_DNSSD */
469 httpAssembleURIf(HTTP_URI_CODING_ALL, adminurl_str, sizeof(adminurl_str),
470 "http", NULL, admin_hostname, DNSSDPort, "/%s/%s",
471 (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers",
472 @@ -2462,19 +2577,12 @@ dnssdBuildTxtRecord(
473 * Then pack them into a proper txt record...
477 return (dnssdPackTxtRecord(txt_len, keyvalue, i));
482 - * 'dnssdComparePrinters()' - Compare the registered names of two printers.
485 -static int /* O - Result of comparison */
486 -dnssdComparePrinters(cupsd_printer_t *a,/* I - First printer */
487 - cupsd_printer_t *b)/* I - Second printer */
489 - return (_cups_strcasecmp(a->reg_name, b->reg_name));
490 +#endif /* HAVE_DNSSD */
492 + return (avahiPackTxtRecord(keyvalue, i));
493 +#endif /* HAVE_AVAHI */
497 @@ -2489,6 +2597,10 @@ dnssdDeregisterPrinter(
499 cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdDeregisterPrinter(%s)", p->name);
506 * Closing the socket deregisters the service
508 @@ -2524,6 +2636,24 @@ dnssdDeregisterPrinter(
509 free(p->printer_txt);
510 p->printer_txt = NULL;
512 +#endif /* HAVE_DNSSD */
515 + if (p->avahi_group)
517 + avahi_entry_group_reset (p->avahi_group);
518 + avahi_entry_group_free (p->avahi_group);
519 + p->avahi_group = NULL;
522 + avahi_string_list_free (p->ipp_txt);
524 + if (p->printer_txt)
525 + avahi_string_list_free (p->printer_txt);
527 + p->ipp_txt = p->printer_txt = NULL;
529 +#endif /* HAVE_AVAHI */
532 * Remove the printer from the array of DNS-SD printers, then clear the
533 @@ -2533,8 +2663,10 @@ dnssdDeregisterPrinter(
534 cupsArrayRemove(DNSSDPrinters, p);
535 cupsdClearString(&p->reg_name);
537 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
542 * 'dnssdPackTxtRecord()' - Pack an array of key/value pairs into the
544 @@ -2644,8 +2776,10 @@ dnssdRegisterCallback(
545 LastEvent |= CUPSD_EVENT_PRINTER_MODIFIED;
548 +#endif /* HAVE_DNSSD */
551 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
553 * 'dnssdRegisterPrinter()' - Start sending broadcast information for a printer
554 * or update the broadcast contents.
555 @@ -2654,20 +2788,40 @@ dnssdRegisterCallback(
557 dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
560 DNSServiceErrorType se; /* dnssd errors */
561 char *ipp_txt, /* IPP TXT record buffer */
562 *printer_txt, /* LPD TXT record buffer */
563 - name[1024], /* Service name */
564 - *nameptr; /* Pointer into name */
565 + name[1024]; /* Service name */
566 int ipp_len, /* IPP TXT record length */
567 printer_len, /* LPD TXT record length */
568 printer_port; /* LPD port number */
569 +#endif /* HAVE_DNSSD */
571 + int ret; /* Error code */
572 + AvahiStringList *ipp_txt, /* IPP TXT record */
573 + *printer_txt; /* LPD TXT record */
574 + char name[AVAHI_LABEL_MAX], /* Service name */
575 + fullsubtype[AVAHI_LABEL_MAX]; /* Full subtype */
576 + char *regtype_copy, /* Writeable copy of reg type */
577 + *subtype, /* Current service sub type */
578 + *nextsubtype; /* Next service sub type */
579 +#endif /* HAVE_AVAHI */
580 + char *nameptr; /* Pointer into name */
581 const char *regtype; /* Registration type */
588 cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterPrinter(%s) %s", p->name,
589 !p->ipp_ref ? "new" : "update");
591 +#endif /* HAVE_DNSSD */
593 + cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterPrinter(%s) %s", p->name,
594 + !p->avahi_group ? "new" : "update");
595 +#endif /* HAVE_AVAHI */
597 * If per-printer sharing was just disabled make sure we're not
598 * registered before returning.
599 @@ -2686,12 +2840,36 @@ dnssdRegisterPrinter(cupsd_printer_t *p)
600 if (p->info && strlen(p->info) > 0)
602 if (DNSSDComputerName)
603 - snprintf(name, sizeof(name), "%s @ %s", p->info, DNSSDComputerName);
606 + * Make sure there is room for at least 15 characters of
607 + * DNSSDComputerName.
610 + assert(sizeof(name) >= 15 + 4);
611 + nameptr = name + strlcpy(name, p->info,
613 + strnlen(DNSSDComputerName, 15));
614 + nameptr += strlcpy(nameptr, " @ ", sizeof(name) - (nameptr - name));
615 + strlcpy(nameptr, DNSSDComputerName, sizeof(name) - (nameptr - name));
618 strlcpy(name, p->info, sizeof(name));
620 else if (DNSSDComputerName)
621 - snprintf(name, sizeof(name), "%s @ %s", p->name, DNSSDComputerName);
624 + * Make sure there is room for at least 15 characters of
625 + * DNSSDComputerName.
628 + assert(sizeof(name) >= 15 + 4);
629 + nameptr = name + strlcpy(name, p->info,
631 + strnlen(DNSSDComputerName, 15));
632 + nameptr += strlcpy(nameptr, " @ ", sizeof(name) - (nameptr - name));
633 + strlcpy(nameptr, DNSSDComputerName, sizeof(name) - (nameptr - name));
636 strlcpy(name, p->name, sizeof(name));
638 @@ -2712,6 +2890,7 @@ dnssdRegisterPrinter(cupsd_printer_t *p)
639 * Register IPP and (optionally) LPD...
643 ipp_len = 0; /* anti-compiler-warning-code */
644 ipp_txt = dnssdBuildTxtRecord(&ipp_len, p, 0);
646 @@ -2884,6 +3063,209 @@ dnssdRegisterPrinter(cupsd_printer_t *p)
650 +#endif /* HAVE_DNSSD */
652 + if (!AvahiCupsClient)
654 + * Client not running yet. The client callback will call us again later.
658 + ipp_txt = dnssdBuildTxtRecord(NULL, p, 0);
659 + printer_txt = dnssdBuildTxtRecord(NULL, p, 1);
660 + regtype = (p->type & CUPS_PRINTER_FAX) ? "_fax-ipp._tcp" : DNSSDRegType;
662 + if (p->avahi_group && p->ipp_txt && ipp_txt &&
663 + !avahi_string_list_equal (p->ipp_txt, ipp_txt))
666 + * Update the existing registration...
669 + avahi_string_list_free (p->ipp_txt);
671 + if (p->printer_txt)
672 + avahi_string_list_free (p->printer_txt);
675 + * Update the service group entry.
678 + regtype_copy = strdup (regtype);
679 + subtype = strchr (regtype_copy, ',');
683 + cupsdLogMessage (CUPSD_LOG_DEBUG,
684 + "Updating TXT record for %s (%s)", name, regtype_copy);
685 + ret = avahi_entry_group_update_service_txt_strlst (p->avahi_group,
687 + AVAHI_PROTO_UNSPEC,
691 + free (regtype_copy);
694 + goto update_failed;
696 + p->ipp_txt = ipp_txt;
699 + if (BrowseLocalProtocols & BROWSE_LPD)
701 + ret = avahi_entry_group_update_service_txt_strlst (p->avahi_group,
703 + AVAHI_PROTO_UNSPEC,
705 + "_printer._tcp", NULL,
708 + goto update_failed;
710 + p->printer_txt = printer_txt;
711 + printer_txt = NULL;
714 + ret = avahi_entry_group_commit (p->avahi_group);
718 + cupsdLogMessage (CUPSD_LOG_ERROR,
719 + "Failed to update TXT record for %s: %d",
721 + avahi_entry_group_reset (p->avahi_group);
722 + avahi_entry_group_free (p->avahi_group);
723 + p->avahi_group = NULL;
724 + ipp_txt = p->ipp_txt;
729 + if (!p->avahi_group)
732 + * Initial registration. Use the _fax subtype for fax queues...
735 + p->avahi_group = avahi_entry_group_new (AvahiCupsClient,
736 + avahi_entry_group_cb,
739 + cupsdLogMessage(CUPSD_LOG_DEBUG,
740 + "Registering Avahi printer %s with name \"%s\" and "
741 + "type \"%s\"", p->name, name, regtype);
743 + if (!p->avahi_group)
750 + * Add each service type (DNSSDRegType may contain several,
751 + * separated by commas).
754 + subtype = regtype_copy = strdup (regtype);
755 + while (subtype && *subtype)
757 + nextsubtype = strchr (subtype, ',');
759 + *nextsubtype++ = '\0';
761 + if (subtype == regtype_copy)
767 + cupsdLogMessage (CUPSD_LOG_DEBUG,
768 + "Adding TXT record for %s (%s)", name, regtype_copy);
769 + ret = avahi_entry_group_add_service_strlst (p->avahi_group,
771 + AVAHI_PROTO_UNSPEC,
772 + 0, name, regtype_copy,
783 + snprintf (fullsubtype, sizeof(fullsubtype),
784 + "%s._sub.%s", subtype, regtype_copy);
785 + cupsdLogMessage (CUPSD_LOG_DEBUG,
786 + "Adding TXT record for %s (%s)", name, fullsubtype);
787 + ret = avahi_entry_group_add_service_subtype (p->avahi_group,
789 + AVAHI_PROTO_UNSPEC,
792 + NULL, fullsubtype);
797 + free (regtype_copy);
801 + subtype = nextsubtype;
804 + free (regtype_copy);
805 + p->ipp_txt = ipp_txt;
808 + if (BrowseLocalProtocols & BROWSE_LPD)
810 + cupsdLogMessage(CUPSD_LOG_DEBUG,
811 + "Registering Avahi printer %s with name \"%s\" and "
812 + "type \"_printer._tcp\"", p->name, name);
814 + ret = avahi_entry_group_add_service_strlst (p->avahi_group,
816 + AVAHI_PROTO_UNSPEC,
818 + "_printer._tcp", NULL, NULL,
824 + p->printer_txt = printer_txt;
825 + printer_txt = NULL;
828 + ret = avahi_entry_group_commit (p->avahi_group);
833 + cupsdLogMessage (CUPSD_LOG_ERROR,
834 + "Failed to add Avahi entry for %s: %d",
836 + if (p->avahi_group)
838 + avahi_entry_group_reset (p->avahi_group);
839 + avahi_entry_group_free (p->avahi_group);
840 + p->avahi_group = NULL;
842 + ipp_txt = p->ipp_txt;
848 + avahi_string_list_free (ipp_txt);
851 + avahi_string_list_free (printer_txt);
852 +#endif /* HAVE_AVAHI */
856 @@ -2896,6 +3278,10 @@ dnssdStop(void)
858 cupsd_printer_t *p; /* Current printer */
863 +#endif /* HAVE_DNSSD */
866 * De-register the individual printers
867 @@ -2910,12 +3296,23 @@ dnssdStop(void)
868 * Shutdown the rest of the service refs...
874 DNSServiceRefDeallocate(WebIFRef);
877 +#endif /* HAVE_DNSSD */
879 + if (AvahiWebIFGroup)
881 + avahi_entry_group_reset (AvahiWebIFGroup);
882 + avahi_entry_group_free (AvahiWebIFGroup);
883 + AvahiWebIFGroup = NULL;
885 +#endif /* HAVE_AVAHI */
890 DNSServiceRefDeallocate(RemoteRef);
891 @@ -2926,14 +3323,17 @@ dnssdStop(void)
893 DNSServiceRefDeallocate(DNSSDRef);
895 +#endif /* HAVE_DNSSD */
897 cupsArrayDelete(DNSSDPrinters);
898 DNSSDPrinters = NULL;
902 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
907 * 'dnssdUpdate()' - Handle DNS-SD queries.
909 @@ -2955,6 +3355,153 @@ dnssdUpdate(void)
910 #endif /* HAVE_DNSSD */
915 + * 'avahiPackTxtRecord()' - Pack an array of key/value pairs into an
919 +static AvahiStringList * /* O - new string list */
920 +avahiPackTxtRecord(char *keyvalue[][2], /* I - Table of key value pairs */
921 + int count) /* I - Number of items in table */
923 + AvahiStringList *strlst = NULL;
928 + elements = malloc ((1 + count) * sizeof (char *));
932 + for (i = 0; i < count; i++)
934 + len = (1 + strlen (keyvalue[i][0]) +
935 + (keyvalue[i][1] ? 1 + strlen (keyvalue[i][1]) : 1));
936 + elements[i] = malloc (len * sizeof (char));
940 + snprintf (elements[i], len, "%s=%s", keyvalue[i][0], keyvalue[i][1]);
943 + strlst = avahi_string_list_new_from_array ((const char **) elements, count);
947 + free (elements[i]);
955 + * 'avahi_entry_group_cb()' - Avahi entry group callback function.
958 +avahi_entry_group_cb (AvahiEntryGroup *group,
959 + AvahiEntryGroupState state,
965 + name = ((cupsd_printer_t *) userdata)->reg_name;
967 + name = "CUPS web interface";
971 + case AVAHI_ENTRY_GROUP_UNCOMMITED:
972 + case AVAHI_ENTRY_GROUP_REGISTERING:
975 + case AVAHI_ENTRY_GROUP_ESTABLISHED:
976 + cupsdLogMessage (CUPSD_LOG_DEBUG,
977 + "Avahi entry group established for %s", name);
981 + cupsdLogMessage (CUPSD_LOG_DEBUG,
982 + "Avahi entry group %s has state %d",
990 + * 'avahi_client_cb()' - Avahi client callback function.
993 +avahi_client_cb (AvahiClient *client,
994 + AvahiClientState state,
997 + cupsd_printer_t *printer;
1000 + case AVAHI_CLIENT_S_RUNNING:
1002 + * Avahi client started successfully.
1004 + AvahiCupsClient = client;
1005 + AvahiCupsClientConnecting = 0;
1006 + cupsdLogMessage (CUPSD_LOG_DEBUG, "Avahi client started");
1008 + cupsdUpdateDNSSDName ();
1010 + for (printer = (cupsd_printer_t *)cupsArrayFirst(Printers);
1012 + printer = (cupsd_printer_t *)cupsArrayNext(Printers))
1013 + if (Browsing && (BrowseLocalProtocols & BROWSE_DNSSD) &&
1014 + (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
1015 + CUPS_PRINTER_SCANNER))) && printer->shared)
1016 + dnssdRegisterPrinter (printer);
1020 + case AVAHI_CLIENT_CONNECTING:
1022 + * No Avahi daemon, client is waiting.
1024 + cupsdLogMessage (CUPSD_LOG_DEBUG, "Avahi client connecting");
1027 + case AVAHI_CLIENT_S_REGISTERING:
1029 + * Not yet registered.
1031 + cupsdLogMessage (CUPSD_LOG_DEBUG, "Avahi client registering");
1034 + case AVAHI_CLIENT_FAILURE:
1036 + * Avahi client failed, close it to allow a clean restart.
1038 + cupsdLogMessage (CUPSD_LOG_ERROR,
1039 + "Avahi client failed, "
1040 + "closing client to allow a clean restart");
1042 + for (printer = (cupsd_printer_t *)cupsArrayFirst(Printers);
1044 + printer = (cupsd_printer_t *)cupsArrayNext(Printers))
1045 + dnssdDeregisterPrinter (printer);
1047 + avahi_client_free(client);
1048 + AvahiCupsClientConnecting = 0;
1049 + AvahiCupsClient = NULL;
1054 + cupsdLogMessage (CUPSD_LOG_DEBUG, "Avahi client state: %d", state);
1057 +#endif /* HAVE_AVAHI */
1061 * 'get_auth_info_required()' - Get the auth-info-required value to advertise.
1063 diff -up cups-1.5.2/scheduler/dirsvc.h.avahi-5-services cups-1.5.2/scheduler/dirsvc.h
1064 --- cups-1.5.2/scheduler/dirsvc.h.avahi-5-services 2011-03-21 02:12:14.000000000 +0000
1065 +++ cups-1.5.2/scheduler/dirsvc.h 2012-03-14 15:08:25.711611808 +0000
1067 # endif /* HAVE_LDAP_SSL_H */
1068 #endif /* HAVE_LDAP */
1071 +# include <avahi-client/publish.h>
1072 +#endif /* HAVE_AVAHI */
1075 * Browse protocols...
1077 @@ -131,19 +135,22 @@ VAR int PollPipe VALUE(0);
1078 VAR cupsd_statbuf_t *PollStatusBuffer VALUE(NULL);
1079 /* Status buffer for pollers */
1082 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
1083 VAR char *DNSSDComputerName VALUE(NULL),
1084 /* Computer/server name */
1085 *DNSSDHostName VALUE(NULL),
1087 *DNSSDRegType VALUE(NULL);
1088 /* Bonjour registration type */
1089 -VAR cups_array_t *DNSSDAlias VALUE(NULL);
1090 - /* List of dynamic ServerAlias's */
1091 VAR int DNSSDPort VALUE(0);
1092 /* Port number to register */
1093 VAR cups_array_t *DNSSDPrinters VALUE(NULL);
1094 /* Printers we have registered */
1095 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
1098 +VAR cups_array_t *DNSSDAlias VALUE(NULL);
1099 + /* List of dynamic ServerAlias's */
1100 VAR DNSServiceRef DNSSDRef VALUE(NULL),
1101 /* Master DNS-SD service reference */
1102 WebIFRef VALUE(NULL),
1103 @@ -152,6 +159,17 @@ VAR DNSServiceRef DNSSDRef VALUE(NULL),
1104 /* Remote printer browse reference */
1105 #endif /* HAVE_DNSSD */
1108 +VAR AvahiCupsPoll *AvahiCupsPollHandle VALUE(NULL);
1109 + /* AvahiCupsPoll object */
1110 +VAR AvahiClient *AvahiCupsClient VALUE(NULL);
1111 + /* AvahiClient object */
1112 +VAR int AvahiCupsClientConnecting VALUE(0);
1113 + /* Is AvahiClient object connecting? */
1114 +VAR AvahiEntryGroup *AvahiWebIFGroup VALUE(NULL);
1115 + /* Web interface entry group */
1116 +#endif /* HAVE_AVAHI */
1119 VAR SLPHandle BrowseSLPHandle VALUE(NULL);
1120 /* SLP API handle */
1121 @@ -195,13 +213,14 @@ extern void cupsdRegisterPrinter(cupsd_p
1122 extern void cupsdRestartPolling(void);
1123 extern void cupsdSaveRemoteCache(void);
1124 extern void cupsdSendBrowseList(void);
1125 +extern void cupsdStartAvahiClient(void);
1126 extern void cupsdStartBrowsing(void);
1127 extern void cupsdStartPolling(void);
1128 extern void cupsdStopBrowsing(void);
1129 extern void cupsdStopPolling(void);
1131 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
1132 extern void cupsdUpdateDNSSDName(void);
1133 -#endif /* HAVE_DNSSD */
1134 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
1136 extern void cupsdUpdateLDAPBrowse(void);
1137 #endif /* HAVE_LDAP */
1138 diff -up cups-1.5.2/scheduler/ipp.c.avahi-5-services cups-1.5.2/scheduler/ipp.c
1139 --- cups-1.5.2/scheduler/ipp.c.avahi-5-services 2012-03-14 15:04:17.665305560 +0000
1140 +++ cups-1.5.2/scheduler/ipp.c 2012-03-14 15:08:25.715611813 +0000
1141 @@ -6099,7 +6099,7 @@ copy_printer_attrs(
1142 ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time",
1143 ippTimeToDate(curtime));
1146 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
1147 if (!ra || cupsArrayFind(ra, "printer-dns-sd-name"))
1149 if (printer->reg_name)
1150 @@ -6109,7 +6109,7 @@ copy_printer_attrs(
1151 ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_NOVALUE,
1152 "printer-dns-sd-name", 0);
1154 -#endif /* HAVE_DNSSD */
1155 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
1157 if (!ra || cupsArrayFind(ra, "printer-error-policy"))
1158 ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME,
1159 diff -up cups-1.5.2/scheduler/main.c.avahi-5-services cups-1.5.2/scheduler/main.c
1160 --- cups-1.5.2/scheduler/main.c.avahi-5-services 2012-03-14 15:06:36.511476986 +0000
1161 +++ cups-1.5.2/scheduler/main.c 2012-03-14 15:08:25.718611817 +0000
1162 @@ -120,6 +120,10 @@ main(int argc, /* I - Number of comm
1163 cupsd_listener_t *lis; /* Current listener */
1164 time_t current_time, /* Current time */
1165 activity, /* Client activity timer */
1167 + avahi_client_time, /* Time for next Avahi client
1169 +#endif /* HAVE_AVAHI */
1170 browse_time, /* Next browse send time */
1171 senddoc_time, /* Send-Document time */
1172 expire_time, /* Subscription expire time */
1173 @@ -672,6 +676,9 @@ main(int argc, /* I - Number of comm
1176 current_time = time(NULL);
1178 + avahi_client_time = current_time;
1179 +#endif /* HAVE_AVAHI */
1180 browse_time = current_time;
1181 event_time = current_time;
1182 expire_time = current_time;
1183 @@ -894,6 +901,16 @@ main(int argc, /* I - Number of comm
1184 tmo = cupsdNextTimeout (&tmo_delay);
1185 if (tmo && tmo_delay == 0)
1186 cupsdRunTimeout (tmo);
1189 + * Try to restart the Avahi client every 10 seconds if needed...
1192 + if ((current_time - avahi_client_time) >= 10)
1194 + avahi_client_time = current_time;
1195 + cupsdStartAvahiClient();
1197 #endif /* HAVE_AVAHI */
1200 diff -up cups-1.5.2/scheduler/printers.c.avahi-5-services cups-1.5.2/scheduler/printers.c
1201 --- cups-1.5.2/scheduler/printers.c.avahi-5-services 2012-03-14 15:04:17.646305537 +0000
1202 +++ cups-1.5.2/scheduler/printers.c 2012-03-14 15:08:25.720611819 +0000
1203 @@ -883,9 +883,9 @@ cupsdDeletePrinter(
1204 cupsdClearString(&p->alert);
1205 cupsdClearString(&p->alert_description);
1208 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
1209 cupsdClearString(&p->pdl);
1210 -#endif /* HAVE_DNSSD */
1211 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
1213 cupsArrayDelete(p->filetypes);
1215 @@ -3787,7 +3787,7 @@ add_printer_formats(cupsd_printer_t *p)
1216 attr->values[i].string.text = _cupsStrAlloc(mimetype);
1220 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
1222 char pdl[1024]; /* Buffer to build pdl list */
1223 mime_filter_t *filter; /* MIME filter looping var */
1224 @@ -3843,7 +3843,7 @@ add_printer_formats(cupsd_printer_t *p)
1226 cupsdSetString(&p->pdl, pdl);
1228 -#endif /* HAVE_DNSSD */
1229 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
1233 diff -up cups-1.5.2/scheduler/printers.h.avahi-5-services cups-1.5.2/scheduler/printers.h
1234 --- cups-1.5.2/scheduler/printers.h.avahi-5-services 2011-03-18 18:42:46.000000000 +0000
1235 +++ cups-1.5.2/scheduler/printers.h 2012-03-14 15:08:25.721611820 +0000
1238 # include <dns_sd.h>
1239 #endif /* HAVE_DNSSD */
1241 +# include "avahi.h"
1242 +#endif /* HAVE_AVAHI */
1243 #include <cups/pwg-private.h>
1246 @@ -95,16 +98,23 @@ struct cupsd_printer_s
1247 time_t marker_time; /* Last time marker attributes were updated */
1248 _ppd_cache_t *pc; /* PPD cache and mapping data */
1251 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
1252 char *reg_name, /* Name used for service registration */
1253 - *pdl, /* pdl value for TXT record */
1254 - *ipp_txt, /* IPP TXT record contents */
1255 + *pdl; /* pdl value for TXT record */
1256 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
1258 + char *ipp_txt, /* IPP TXT record contents */
1259 *printer_txt; /* LPD TXT record contents */
1260 int ipp_len, /* IPP TXT record length */
1261 printer_len; /* LPD TXT record length */
1262 DNSServiceRef ipp_ref, /* Reference for _ipp._tcp,_cups */
1263 printer_ref; /* Reference for _printer._tcp */
1264 #endif /* HAVE_DNSSD */
1266 + AvahiStringList *ipp_txt, /* IPP TXT record */
1267 + *printer_txt; /* LPD TXT record */
1268 + AvahiEntryGroup *avahi_group; /* Avahi entry group */
1269 +#endif /* HAVE_AVAHI */