* information.
*/
-/*
- * Include necessary headers...
- */
-
#include "cupsd.h"
#include <grp.h>
#endif /* HAVE_MDNSRESPONDER && __APPLE__ */
-/*
- * Local globals...
- */
-
-#ifdef HAVE_AVAHI
-static int avahi_running = 0;
-#endif /* HAVE_AVAHI */
-
-
/*
* Local functions...
*/
-static char *get_auth_info_required(cupsd_printer_t *p,
- char *buffer, size_t bufsize);
-# ifdef __APPLE__
-static void dnssdAddAlias(const void *key, const void *value,
- void *context);
-# endif /* __APPLE__ */
-static cupsd_txt_t dnssdBuildTxtRecord(cupsd_printer_t *p);
-# ifdef HAVE_AVAHI
-static void dnssdClientCallback(AvahiClient *c, AvahiClientState state, void *userdata);
-# endif /* HAVE_AVAHI */
-static void dnssdDeregisterAllPrinters(int from_callback);
-static void dnssdDeregisterInstance(cupsd_srv_t *srv, int from_callback);
-static void dnssdDeregisterPrinter(cupsd_printer_t *p, int clear_name, int from_callback);
-static const char *dnssdErrorString(int error);
-static void dnssdFreeTxtRecord(cupsd_txt_t *txt);
-static void dnssdRegisterAllPrinters(int from_callback);
-# ifdef HAVE_MDNSRESPONDER
-static void dnssdRegisterCallback(DNSServiceRef sdRef,
- DNSServiceFlags flags,
- DNSServiceErrorType errorCode,
- const char *name,
- const char *regtype,
- const char *domain,
- void *context);
-# else
-static void dnssdRegisterCallback(AvahiEntryGroup *p,
- AvahiEntryGroupState state,
- void *context);
-# endif /* HAVE_MDNSRESPONDER */
-static int dnssdRegisterInstance(cupsd_srv_t *srv, cupsd_printer_t *p, char *name, const char *type, const char *subtypes, int port, cupsd_txt_t *txt, int commit, int from_callback);
-static void dnssdRegisterPrinter(cupsd_printer_t *p, int from_callback);
+static char *get_auth_info_required(cupsd_printer_t *p, char *buffer, size_t bufsize);
+static int dnssdBuildTxtRecord(cupsd_printer_t *p, cups_option_t **txt);
+static void dnssdErrorCB(void *cb_data, const char *message);
+static void dnssdRegisterCallback(cups_dnssd_service_t *service, void *cb_data, cups_dnssd_flags_t flags);
+static void dnssdRegisterPrinter(cupsd_printer_t *p);
static void dnssdStop(void);
-# ifdef HAVE_MDNSRESPONDER
-static void dnssdUpdate(void);
-# endif /* HAVE_MDNSRESPONDER */
-static void dnssdUpdateDNSSDName(int from_callback);
/*
* Only deregister if browsing is enabled and it's a local printer...
*/
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdDeregisterPrinter(p=%p(%s), removeit=%d)", (void *)p, p->name,
- removeit);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdDeregisterPrinter(p=%p(%s), removeit=%d)", (void *)p, p->name, removeit);
- if (!Browsing || !p->shared ||
- (p->type & (CUPS_PTYPE_REMOTE | CUPS_PTYPE_SCANNER)))
+ if (!Browsing || !p->shared || (p->type & (CUPS_PTYPE_REMOTE | CUPS_PTYPE_SCANNER)))
return;
/*
* Announce the deletion...
*/
- if (removeit && (BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDMaster)
- dnssdDeregisterPrinter(p, 1, 0);
+ if (removeit && (BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDContext)
+ {
+ cupsDNSSDServiceDelete(p->dnssd);
+ p->dnssd = NULL;
+ }
}
void
cupsdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
{
- cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdRegisterPrinter(p=%p(%s))", (void *)p,
- p->name);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdRegisterPrinter(p=%p(%s))", (void *)p, p->name);
- if (!Browsing || !BrowseLocalProtocols ||
- (p->type & (CUPS_PTYPE_REMOTE | CUPS_PTYPE_SCANNER)))
+ if (!Browsing || !BrowseLocalProtocols || (p->type & (CUPS_PTYPE_REMOTE | CUPS_PTYPE_SCANNER)))
return;
- if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDMaster)
- dnssdRegisterPrinter(p, 0);
+ if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDContext)
+ dnssdRegisterPrinter(p);
}
void
cupsdStartBrowsing(void)
{
+ cupsd_printer_t *p; /* Current printer */
+
+
if (!Browsing || !BrowseLocalProtocols)
return;
if (BrowseLocalProtocols & BROWSE_DNSSD)
{
-# ifdef HAVE_MDNSRESPONDER
- DNSServiceErrorType error; /* Error from service creation */
-
- /*
- * First create a "master" connection for all registrations...
- */
-
- if ((error = DNSServiceCreateConnection(&DNSSDMaster))
- != kDNSServiceErr_NoError)
+ if ((DNSSDContext = cupsDNSSDNew(dnssdErrorCB, /*cb_data*/NULL)) == NULL)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to create master DNS-SD reference: %d", error);
-
if (FatalErrors & CUPSD_FATAL_BROWSE)
cupsdEndProcess(getpid(), 0);
- }
- else
- {
- /*
- * Add the master connection to the select list...
- */
-
- int fd = DNSServiceRefSockFD(DNSSDMaster);
- fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
-
- cupsdAddSelect(fd, (cupsd_selfunc_t)dnssdUpdate, NULL, NULL);
+ return;
}
/*
DNSSDPort = 0;
cupsdUpdateDNSSDName();
-# else /* HAVE_AVAHI */
- if ((DNSSDMaster = avahi_threaded_poll_new()) == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create DNS-SD thread.");
+ /*
+ * Register the individual printers
+ */
- if (FatalErrors & CUPSD_FATAL_BROWSE)
- cupsdEndProcess(getpid(), 0);
- }
- else
+ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers))
{
- int error; /* Error code, if any */
-
- DNSSDClient = avahi_client_new(avahi_threaded_poll_get(DNSSDMaster), AVAHI_CLIENT_NO_FAIL, dnssdClientCallback, NULL, &error);
-
- if (DNSSDClient == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to communicate with avahi-daemon: %s",
- dnssdErrorString(error));
-
- if (FatalErrors & CUPSD_FATAL_BROWSE)
- cupsdEndProcess(getpid(), 0);
-
- avahi_threaded_poll_free(DNSSDMaster);
- DNSSDMaster = NULL;
- }
- else
- avahi_threaded_poll_start(DNSSDMaster);
+ if (!(p->type & (CUPS_PTYPE_REMOTE | CUPS_PTYPE_SCANNER)))
+ dnssdRegisterPrinter(p);
}
-# endif /* HAVE_MDNSRESPONDER */
}
-
- /*
- * Register the individual printers
- */
-
- dnssdRegisterAllPrinters(0);
}
if (!Browsing || !BrowseLocalProtocols)
return;
- /*
- * De-register the individual printers
- */
-
- dnssdDeregisterAllPrinters(0);
-
/*
* Shut down browsing sockets...
*/
- if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDMaster)
+ if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDContext)
dnssdStop();
}
void
cupsdUpdateDNSSDName(void)
{
- dnssdUpdateDNSSDName(0);
-}
+ char name[1024]; /* Computer/host name */
-# ifdef __APPLE__
-/*
- * 'dnssdAddAlias()' - Add a DNS-SD alias name.
- */
+ /*
+ * Only share the web interface and printers when non-local listening is
+ * enabled...
+ */
-static void
-dnssdAddAlias(const void *key, /* I - Key */
- const void *value, /* I - Value (domain) */
- void *context) /* I - Unused */
-{
- char valueStr[1024], /* Domain string */
- hostname[1024], /* Complete hostname */
- *hostptr; /* Pointer into hostname */
+ if (!DNSSDPort)
+ {
+ /*
+ * Get the port we use for registrations. If we are not listening on any
+ * non-local ports, there is no sense sharing local printers via Bonjour...
+ */
+
+ cupsd_listener_t *lis; /* Current listening socket */
+
+ for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); lis; lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
+ {
+ if (httpAddrLocalhost(&(lis->address)))
+ continue;
+
+ DNSSDPort = httpAddrPort(&(lis->address));
+ break;
+ }
+ }
+
+ if (!DNSSDPort)
+ return;
+ /*
+ * Get the computer name...
+ */
- (void)key;
- (void)context;
+ if (cupsDNSSDCopyComputerName(DNSSDContext, name, sizeof(name)) && name[0])
+ cupsdSetString(&DNSSDComputerName, name);
- if (CFGetTypeID((CFStringRef)value) == CFStringGetTypeID() &&
- CFStringGetCString((CFStringRef)value, valueStr, sizeof(valueStr),
- kCFStringEncodingUTF8))
+ if (!DNSSDComputerName)
{
- snprintf(hostname, sizeof(hostname), "%s.%s", DNSSDHostName, valueStr);
- hostptr = hostname + strlen(hostname) - 1;
- if (*hostptr == '.')
- *hostptr = '\0'; /* Strip trailing dot */
+ /*
+ * Use the ServerName instead...
+ */
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Using ServerName \"%s\" as computer name.", ServerName);
+ cupsdSetString(&DNSSDComputerName, ServerName);
+ }
- if (!DNSSDAlias)
- DNSSDAlias = cupsArrayNew(NULL, NULL);
+ /*
+ * Get the hostname...
+ */
+
+ if (cupsDNSSDCopyHostName(DNSSDContext, name, sizeof(name)))
+ cupsdSetString(&DNSSDHostName, name);
+
+ if (!DNSSDHostName)
+ {
+ if (strchr(ServerName, '.'))
+ cupsdSetString(&DNSSDHostName, ServerName);
+ else
+ cupsdSetStringf(&DNSSDHostName, "%s.local", ServerName);
- cupsdAddAlias(DNSSDAlias, hostname);
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Added Back to My Mac ServerAlias %s",
- hostname);
+ cupsdLogMessage(CUPSD_LOG_INFO, "Defaulting to \"DNSSDHostName %s\".", DNSSDHostName);
+ }
+
+ /*
+ * Then (re)register the web interface if enabled...
+ */
+
+ cupsDNSSDServiceDelete(DNSSDWebIF);
+ DNSSDWebIF = NULL;
+
+ if (BrowseWebIF)
+ {
+ char webif[1024]; /* Web interface share name */
+
+ if (DNSSDComputerName)
+ snprintf(webif, sizeof(webif), "CUPS @ %s", DNSSDComputerName);
+ else
+ cupsCopyString(webif, "CUPS", sizeof(webif));
+
+ DNSSDWebIF = cupsDNSSDServiceNew(DNSSDContext, CUPS_DNSSD_IF_INDEX_ANY, webif, /*cb*/NULL, /*cb_data*/NULL);
+ cupsDNSSDServiceAdd(DNSSDWebIF, "_http._tcp", /*domain*/NULL, DNSSDHostName, (uint16_t)DNSSDPort, /*num_txt*/0, /*txt*/NULL);
+ cupsDNSSDServicePublish(DNSSDWebIF);
}
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Bad Back to My Mac domain in dynamic store!");
}
-# endif /* __APPLE__ */
/*
* 'dnssdBuildTxtRecord()' - Build a TXT record from printer info.
*/
-static cupsd_txt_t /* O - TXT record */
+static int /* O - Number of TXT key/value pairs */
dnssdBuildTxtRecord(
- cupsd_printer_t *p) /* I - Printer information */
+ cupsd_printer_t *p, /* I - Printer information */
+ cups_option_t **txt) /* O - TXT key/value pairs */
{
int i, /* Looping var */
- count; /* Count of key/value pairs */
+ num_txt; /* Number of TXT key/value pairs */
char admin_hostname[256], /* Hostname for admin page */
- adminurl_str[256], /* URL for the admin page */
- type_str[32], /* Type to string buffer */
- rp_str[256], /* Queue name string buffer */
- air_str[256], /* auth-info-required string buffer */
- urf_str[256], /* URF string buffer */
- *keyvalue[32][2], /* Table of key/value pairs */
+ rp[256], /* RP value */
+ value[256], /* TXT value */
*ptr; /* Pointer in string */
- cupsd_txt_t txt; /* TXT record */
cupsd_listener_t *lis; /* Current listener */
const char *admin_scheme = "http"; /* Admin page URL scheme */
ipp_attribute_t *urf_supported; /* urf-supported attribute */
+
/*
* Load up the key value pairs...
*/
- count = 0;
+ num_txt = 0;
+ *txt = NULL;
- keyvalue[count ][0] = "txtvers";
- keyvalue[count++][1] = "1";
+ num_txt = cupsAddOption("txtvers", "1", num_txt, txt);
+ num_txt = cupsAddOption("qtotal", "1", num_txt, txt);
- keyvalue[count ][0] = "qtotal";
- keyvalue[count++][1] = "1";
+ snprintf(rp, sizeof(rp), "%s/%s", (p->type & CUPS_PTYPE_CLASS) ? "classes" : "printers", p->name);
+ num_txt = cupsAddOption("rp", rp, num_txt, txt);
- keyvalue[count ][0] = "rp";
- keyvalue[count++][1] = rp_str;
- snprintf(rp_str, sizeof(rp_str), "%s/%s", (p->type & CUPS_PTYPE_CLASS) ? "classes" : "printers", p->name);
-
- keyvalue[count ][0] = "ty";
- keyvalue[count++][1] = p->make_model ? p->make_model : "Unknown";
+ num_txt = cupsAddOption("ty", p->make_model ? p->make_model : "Unknown", num_txt, txt);
/*
* Get the hostname for the admin page...
}
}
- httpAssembleURIf(HTTP_URI_CODING_ALL, adminurl_str, sizeof(adminurl_str), admin_scheme, NULL, admin_hostname, DNSSDPort, "/%s/%s", (p->type & CUPS_PTYPE_CLASS) ? "classes" : "printers", p->name);
- keyvalue[count ][0] = "adminurl";
- keyvalue[count++][1] = adminurl_str;
+ httpAssembleURIf(HTTP_URI_CODING_ALL, value, sizeof(value), admin_scheme, NULL, admin_hostname, DNSSDPort, "/%s/%s", (p->type & CUPS_PTYPE_CLASS) ? "classes" : "printers", p->name);
+
+ num_txt = cupsAddOption("adminurl", value, num_txt, txt);
if (p->location)
- {
- keyvalue[count ][0] = "note";
- keyvalue[count++][1] = p->location;
- }
+ num_txt = cupsAddOption("note", p->location, num_txt, txt);
- keyvalue[count ][0] = "priority";
- keyvalue[count++][1] = "0";
+ num_txt = cupsAddOption("priority", "0", num_txt, txt);
- keyvalue[count ][0] = "product";
- keyvalue[count++][1] = p->pc && p->pc->product ? p->pc->product : "Unknown";
+ num_txt = cupsAddOption("product", p->pc && p->pc->product ? p->pc->product : "Unknown", num_txt, txt);
- keyvalue[count ][0] = "pdl";
- keyvalue[count++][1] = p->pdl ? p->pdl : "application/postscript";
+ num_txt = cupsAddOption("pdl", p->pdl ? p->pdl : "application/postscript", num_txt, txt);
- if (get_auth_info_required(p, air_str, sizeof(air_str)))
- {
- keyvalue[count ][0] = "air";
- keyvalue[count++][1] = air_str;
- }
+ if (get_auth_info_required(p, value, sizeof(value)))
+ num_txt = cupsAddOption("air", value, num_txt, txt);
- keyvalue[count ][0] = "UUID";
- keyvalue[count++][1] = p->uuid + 9;
+ num_txt = cupsAddOption("UUID", p->uuid + 9, num_txt, txt);
- keyvalue[count ][0] = "TLS";
- keyvalue[count++][1] = "1.3";
+ num_txt = cupsAddOption("TLS", "1.3", num_txt, txt);
if ((urf_supported = ippFindAttribute(p->ppd_attrs, "urf-supported", IPP_TAG_KEYWORD)) != NULL)
{
int urf_count = ippGetCount(urf_supported);
// Number of URF values
- urf_str[0] = '\0';
- for (i = 0, ptr = urf_str; i < urf_count; i ++)
+ value[0] = '\0';
+ for (i = 0, ptr = value; i < urf_count; i ++)
{
- const char *value = ippGetString(urf_supported, i, NULL);
+ const char *keyword = ippGetString(urf_supported, i, NULL);
- if (ptr > urf_str && ptr < (urf_str + sizeof(urf_str) - 1))
+ if (ptr > value && ptr < (value + sizeof(value) - 1))
*ptr++ = ',';
- cupsCopyString(ptr, value, sizeof(urf_str) - (size_t)(ptr - urf_str));
+ cupsCopyString(ptr, keyword, sizeof(value) - (size_t)(ptr - value));
ptr += strlen(ptr);
- if (ptr >= (urf_str + sizeof(urf_str) - 1))
+ if (ptr >= (value + sizeof(value) - 1))
break;
}
- keyvalue[count ][0] = "URF";
- keyvalue[count++][1] = urf_str;
+ num_txt = cupsAddOption("URF", value, num_txt, txt);
}
- keyvalue[count ][0] = "mopria-certified";
- keyvalue[count++][1] = "1.3";
+ num_txt = cupsAddOption("mopria-certified", "1.3", num_txt, txt);
if (p->type & CUPS_PTYPE_FAX)
{
- keyvalue[count ][0] = "Fax";
- keyvalue[count++][1] = "T";
- keyvalue[count ][0] = "rfo";
- keyvalue[count++][1] = rp_str;
+ num_txt = cupsAddOption("Fax", "T", num_txt, txt);
+ num_txt = cupsAddOption("rfo", rp, num_txt, txt);
}
if (p->type & CUPS_PTYPE_COLOR)
- {
- keyvalue[count ][0] = "Color";
- keyvalue[count++][1] = (p->type & CUPS_PTYPE_COLOR) ? "T" : "F";
- }
+ num_txt = cupsAddOption("Color", (p->type & CUPS_PTYPE_COLOR) ? "T" : "F", num_txt, txt);
if (p->type & CUPS_PTYPE_DUPLEX)
- {
- keyvalue[count ][0] = "Duplex";
- keyvalue[count++][1] = (p->type & CUPS_PTYPE_DUPLEX) ? "T" : "F";
- }
+ num_txt = cupsAddOption("Duplex", (p->type & CUPS_PTYPE_DUPLEX) ? "T" : "F", num_txt, txt);
if (p->type & CUPS_PTYPE_STAPLE)
- {
- keyvalue[count ][0] = "Staple";
- keyvalue[count++][1] = (p->type & CUPS_PTYPE_STAPLE) ? "T" : "F";
- }
+ num_txt = cupsAddOption("Staple", (p->type & CUPS_PTYPE_STAPLE) ? "T" : "F", num_txt, txt);
if (p->type & CUPS_PTYPE_COPIES)
- {
- keyvalue[count ][0] = "Copies";
- keyvalue[count++][1] = (p->type & CUPS_PTYPE_COPIES) ? "T" : "F";
- }
+ num_txt = cupsAddOption("Copies", (p->type & CUPS_PTYPE_COPIES) ? "T" : "F", num_txt, txt);
if (p->type & CUPS_PTYPE_COLLATE)
- {
- keyvalue[count ][0] = "Collate";
- keyvalue[count++][1] = (p->type & CUPS_PTYPE_COLLATE) ? "T" : "F";
- }
+ num_txt = cupsAddOption("Collate", (p->type & CUPS_PTYPE_COLLATE) ? "T" : "F", num_txt, txt);
if (p->type & CUPS_PTYPE_PUNCH)
- {
- keyvalue[count ][0] = "Punch";
- keyvalue[count++][1] = (p->type & CUPS_PTYPE_PUNCH) ? "T" : "F";
- }
+ num_txt = cupsAddOption("Punch", (p->type & CUPS_PTYPE_PUNCH) ? "T" : "F", num_txt, txt);
if (p->type & CUPS_PTYPE_BIND)
- {
- keyvalue[count ][0] = "Bind";
- keyvalue[count++][1] = (p->type & CUPS_PTYPE_BIND) ? "T" : "F";
- }
+ num_txt = cupsAddOption("Bind", (p->type & CUPS_PTYPE_BIND) ? "T" : "F", num_txt, txt);
if (p->type & CUPS_PTYPE_SORT)
- {
- keyvalue[count ][0] = "Sort";
- keyvalue[count++][1] = (p->type & CUPS_PTYPE_SORT) ? "T" : "F";
- }
+ num_txt = cupsAddOption("Sort", (p->type & CUPS_PTYPE_SORT) ? "T" : "F", num_txt, txt);
if (p->type & CUPS_PTYPE_MFP)
- {
- keyvalue[count ][0] = "Scan";
- keyvalue[count++][1] = (p->type & CUPS_PTYPE_MFP) ? "T" : "F";
- }
+ num_txt = cupsAddOption("Scan", (p->type & CUPS_PTYPE_MFP) ? "T" : "F", num_txt, txt);
- snprintf(type_str, sizeof(type_str), "0x%X", p->type | CUPS_PTYPE_REMOTE);
+ snprintf(value, sizeof(value), "0x%X", p->type | CUPS_PTYPE_REMOTE);
+ num_txt = cupsAddOption("printer-type", value, num_txt, txt);
- keyvalue[count ][0] = "printer-type";
- keyvalue[count++][1] = type_str;
-
- /*
- * Then pack them into a proper txt record...
- */
-
-# ifdef HAVE_MDNSRESPONDER
- TXTRecordCreate(&txt, 0, NULL);
-
- for (i = 0; i < count; i ++)
- {
- size_t len = strlen(keyvalue[i][1]);
-
- if (len < 256)
- TXTRecordSetValue(&txt, keyvalue[i][0], (uint8_t)len, keyvalue[i][1]);
- }
-
-# else
- for (i = 0, txt = NULL; i < count; i ++)
- txt = avahi_string_list_add_printf(txt, "%s=%s", keyvalue[i][0],
- keyvalue[i][1]);
-# endif /* HAVE_MDNSRESPONDER */
-
- return (txt);
+ return (num_txt);
}
-# ifdef HAVE_AVAHI
-/*
- * 'dnssdClientCallback()' - Client callback for Avahi.
- *
- * Called whenever the client or server state changes...
- */
+//
+// 'dnssdErrorCB()' - DNS-SD error callback.
+//
static void
-dnssdClientCallback(
- AvahiClient *c, /* I - Client */
- AvahiClientState state, /* I - Current state */
- void *userdata) /* I - User data (unused) */
+dnssdErrorCB(void *cb_data, // I - Callback data (unused)
+ const char *message) // I - Error message
{
- int error; /* Error code, if any */
-
-
- (void)userdata;
-
- if (!c)
- return;
-
- /*
- * Make sure DNSSDClient is already set also if this callback function is
- * already running before avahi_client_new() in dnssdStartBrowsing()
- * finishes.
- */
-
- if (!DNSSDClient)
- DNSSDClient = c;
-
- switch (state)
- {
- case AVAHI_CLIENT_S_REGISTERING:
- case AVAHI_CLIENT_S_RUNNING:
- case AVAHI_CLIENT_S_COLLISION:
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Avahi server connection now available, registering printers for Bonjour broadcasting.");
-
- /*
- * Mark that Avahi server is running...
- */
-
- avahi_running = 1;
-
- /*
- * Set the computer name and register the web interface...
- */
-
- DNSSDPort = 0;
- dnssdUpdateDNSSDName(1);
-
- /*
- * Register the individual printers
- */
-
- dnssdRegisterAllPrinters(1);
- break;
-
- case AVAHI_CLIENT_FAILURE:
- if (avahi_client_errno(c) == AVAHI_ERR_DISCONNECTED)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Avahi server disappeared, unregistering printers for Bonjour broadcasting.");
-
- /*
- * Unregister everything and close the client...
- */
-
- dnssdDeregisterAllPrinters(1);
- dnssdDeregisterInstance(&WebIFSrv, 1);
- avahi_client_free(DNSSDClient);
- DNSSDClient = NULL;
-
- /*
- * Mark that Avahi server is not running...
- */
-
- avahi_running = 0;
-
- /*
- * Renew Avahi client...
- */
-
- DNSSDClient = avahi_client_new(avahi_threaded_poll_get(DNSSDMaster), AVAHI_CLIENT_NO_FAIL, dnssdClientCallback, NULL, &error);
-
- if (!DNSSDClient)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to communicate with avahi-daemon: %s", dnssdErrorString(error));
- if (FatalErrors & CUPSD_FATAL_BROWSE)
- cupsdEndProcess(getpid(), 0);
- }
- }
- else
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Communication with avahi-daemon has failed: %s", avahi_strerror(avahi_client_errno(c)));
- if (FatalErrors & CUPSD_FATAL_BROWSE)
- cupsdEndProcess(getpid(), 0);
- }
- break;
+ (void)cb_data;
- default:
- break;
- }
+ cupsdLogMessage(CUPSD_LOG_ERROR, "[DNS-SD] %s", message);
}
-# endif /* HAVE_AVAHI */
/*
- * 'dnssdDeregisterAllPrinters()' - Deregister all printers.
+ * 'dnssdRegisterCallback()' - Service registration callback.
*/
static void
-dnssdDeregisterAllPrinters(
- int from_callback) /* I - Deregistering because of callback? */
+dnssdRegisterCallback(
+ cups_dnssd_service_t *service, // I - Service
+ void *cb_data, // I - Callback data (printer)
+ cups_dnssd_flags_t flags) // I - Registration flags
{
- cupsd_printer_t *p; /* Current printer */
+ cupsd_printer_t *p = (cupsd_printer_t *)cb_data;
+ // Current printer
+ const char *reg_name; // Updated service name
- if (!DNSSDMaster)
+ if (flags & CUPS_DNSSD_FLAGS_ERROR)
return;
- for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
- p;
- p = (cupsd_printer_t *)cupsArrayNext(Printers))
- if (!(p->type & (CUPS_PTYPE_REMOTE | CUPS_PTYPE_SCANNER)))
- dnssdDeregisterPrinter(p, 1, from_callback);
-}
-
-
-/*
- * 'dnssdDeregisterInstance()' - Deregister a DNS-SD service instance.
- */
-
-static void
-dnssdDeregisterInstance(
- cupsd_srv_t *srv, /* I - Service */
- int from_callback) /* I - Called from callback? */
-{
- if (!srv || !*srv)
+ if (!p)
return;
-# ifdef HAVE_MDNSRESPONDER
- (void)from_callback;
-
- DNSServiceRefDeallocate(*srv);
-
- *srv = NULL;
-
-# else /* HAVE_AVAHI */
- if (!from_callback)
- avahi_threaded_poll_lock(DNSSDMaster);
-
- if (*srv)
- {
- avahi_entry_group_free(*srv);
- *srv = NULL;
- }
-
- if (!from_callback)
- avahi_threaded_poll_unlock(DNSSDMaster);
-# endif /* HAVE_MDNSRESPONDER */
-}
-
-
-/*
- * 'dnssdDeregisterPrinter()' - Deregister all services for a printer.
- */
-
-static void
-dnssdDeregisterPrinter(
- cupsd_printer_t *p, /* I - Printer */
- int clear_name, /* I - Clear the name? */
- int from_callback) /* I - Called from callback? */
-
-{
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "dnssdDeregisterPrinter(p=%p(%s), clear_name=%d)", (void *)p, p->name,
- clear_name);
-
- if (p->ipp_srv)
- {
- dnssdDeregisterInstance(&p->ipp_srv, from_callback);
-
-# ifdef HAVE_MDNSRESPONDER
- dnssdDeregisterInstance(&p->ipps_srv, from_callback);
- dnssdDeregisterInstance(&p->printer_srv, from_callback);
-# endif /* HAVE_MDNSRESPONDER */
- }
-
- /*
- * Remove the printer from the array of DNS-SD printers but keep the
- * registered name...
- */
-
- cupsArrayRemove(DNSSDPrinters, p);
-
- /*
- * Optionally clear the service name...
- */
-
- if (clear_name)
- cupsdClearString(&p->reg_name);
-}
-
-
-/*
- * 'dnssdErrorString()' - Return an error string for an error code.
- */
+ reg_name = cupsDNSSDServiceGetName(service);
-static const char * /* O - Error message */
-dnssdErrorString(int error) /* I - Error number */
-{
-# ifdef HAVE_MDNSRESPONDER
- switch (error)
+ if ((!p->reg_name || _cups_strcasecmp(reg_name, p->reg_name)))
{
- case kDNSServiceErr_NoError :
- return ("OK.");
-
- default :
- case kDNSServiceErr_Unknown :
- return ("Unknown error.");
-
- case kDNSServiceErr_NoSuchName :
- return ("Service not found.");
-
- case kDNSServiceErr_NoMemory :
- return ("Out of memory.");
-
- case kDNSServiceErr_BadParam :
- return ("Bad parameter.");
-
- case kDNSServiceErr_BadReference :
- return ("Bad service reference.");
-
- case kDNSServiceErr_BadState :
- return ("Bad state.");
-
- case kDNSServiceErr_BadFlags :
- return ("Bad flags.");
-
- case kDNSServiceErr_Unsupported :
- return ("Unsupported.");
-
- case kDNSServiceErr_NotInitialized :
- return ("Not initialized.");
-
- case kDNSServiceErr_AlreadyRegistered :
- return ("Already registered.");
-
- case kDNSServiceErr_NameConflict :
- return ("Name conflict.");
-
- case kDNSServiceErr_Invalid :
- return ("Invalid name.");
-
- case kDNSServiceErr_Firewall :
- return ("Firewall prevents registration.");
-
- case kDNSServiceErr_Incompatible :
- return ("Client library incompatible.");
-
- case kDNSServiceErr_BadInterfaceIndex :
- return ("Bad interface index.");
-
- case kDNSServiceErr_Refused :
- return ("Server prevents registration.");
-
- case kDNSServiceErr_NoSuchRecord :
- return ("Record not found.");
-
- case kDNSServiceErr_NoAuth :
- return ("Authentication required.");
-
- case kDNSServiceErr_NoSuchKey :
- return ("Encryption key not found.");
-
- case kDNSServiceErr_NATTraversal :
- return ("Unable to traverse NAT boundary.");
-
- case kDNSServiceErr_DoubleNAT :
- return ("Unable to traverse double-NAT boundary.");
-
- case kDNSServiceErr_BadTime :
- return ("Bad system time.");
-
- case kDNSServiceErr_BadSig :
- return ("Bad signature.");
-
- case kDNSServiceErr_BadKey :
- return ("Bad encryption key.");
-
- case kDNSServiceErr_Transient :
- return ("Transient error occurred - please try again.");
-
- case kDNSServiceErr_ServiceNotRunning :
- return ("Server not running.");
-
- case kDNSServiceErr_NATPortMappingUnsupported :
- return ("NAT doesn't support NAT-PMP or UPnP.");
-
- case kDNSServiceErr_NATPortMappingDisabled :
- return ("NAT supports NAT-PNP or UPnP but it is disabled.");
-
- case kDNSServiceErr_NoRouter :
- return ("No Internet/default router configured.");
-
- case kDNSServiceErr_PollingMode :
- return ("Service polling mode error.");
-
- case kDNSServiceErr_Timeout :
- return ("Service timeout.");
- }
-
-# else /* HAVE_AVAHI */
- return (avahi_strerror(error));
-# endif /* HAVE_MDNSRESPONDER */
-}
-
-
-/*
- * 'dnssdRegisterCallback()' - Free a TXT record.
- */
-
-static void
-dnssdFreeTxtRecord(cupsd_txt_t *txt) /* I - TXT record */
-{
-# ifdef HAVE_MDNSRESPONDER
- TXTRecordDeallocate(txt);
-
-# else /* HAVE_AVAHI */
- avahi_string_list_free(*txt);
- *txt = NULL;
-# endif /* HAVE_MDNSRESPONDER */
-}
-
-
-/*
- * 'dnssdRegisterAllPrinters()' - Register all printers.
- */
-
-static void
-dnssdRegisterAllPrinters(int from_callback) /* I - Called from callback? */
-{
- cupsd_printer_t *p; /* Current printer */
-
-
- if (!DNSSDMaster)
- return;
-
- for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
- p;
- p = (cupsd_printer_t *)cupsArrayNext(Printers))
- if (!(p->type & (CUPS_PTYPE_REMOTE | CUPS_PTYPE_SCANNER)))
- dnssdRegisterPrinter(p, from_callback);
-}
-
-
-/*
- * 'dnssdRegisterCallback()' - DNSServiceRegister callback.
- */
-
-# ifdef HAVE_MDNSRESPONDER
-static void
-dnssdRegisterCallback(
- DNSServiceRef sdRef, /* I - DNS Service reference */
- DNSServiceFlags flags, /* I - Reserved for future use */
- DNSServiceErrorType errorCode, /* I - Error code */
- const char *name, /* I - Service name */
- const char *regtype, /* I - Service type */
- const char *domain, /* I - Domain. ".local" for now */
- void *context) /* I - Printer */
-{
- cupsd_printer_t *p = (cupsd_printer_t *)context;
- /* Current printer */
-
-
- (void)sdRef;
- (void)flags;
- (void)domain;
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterCallback(%s, %s) for %s (%s)",
- name, regtype, p ? p->name : "Web Interface",
- p ? (p->reg_name ? p->reg_name : "(null)") : "NA");
-
- if (errorCode)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "DNSServiceRegister failed with error %d", (int)errorCode);
- return;
- }
- else if (p && (!p->reg_name || _cups_strcasecmp(name, p->reg_name)))
- {
- cupsdLogMessage(CUPSD_LOG_INFO, "Using service name \"%s\" for \"%s\"",
- name, p->name);
+ cupsdLogMessage(CUPSD_LOG_INFO, "Using service name \"%s\" for \"%s\".", reg_name, p->name);
cupsArrayRemove(DNSSDPrinters, p);
- cupsdSetString(&p->reg_name, name);
+ cupsdSetString(&p->reg_name, reg_name);
cupsArrayAdd(DNSSDPrinters, p);
LastEvent |= CUPSD_EVENT_PRINTER_MODIFIED;
}
}
-# else /* HAVE_AVAHI */
-static void
-dnssdRegisterCallback(
- AvahiEntryGroup *srv, /* I - Service */
- AvahiEntryGroupState state, /* I - Registration state */
- void *context) /* I - Printer */
-{
- cupsd_printer_t *p = (cupsd_printer_t *)context;
- /* Current printer */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "dnssdRegisterCallback(srv=%p, state=%d, context=%p) "
- "for %s (%s)", srv, state, context,
- p ? p->name : "Web Interface",
- p ? (p->reg_name ? p->reg_name : "(null)") : "NA");
-
- /* TODO: Handle collisions with avahi_alternate_service_name(p->reg_name)? */
-}
-# endif /* HAVE_MDNSRESPONDER */
-
-
-/*
- * 'dnssdRegisterInstance()' - Register an instance of a printer service.
- */
-
-static int /* O - 1 on success, 0 on failure */
-dnssdRegisterInstance(
- cupsd_srv_t *srv, /* O - Service */
- cupsd_printer_t *p, /* I - Printer */
- char *name, /* I - DNS-SD service name */
- const char *type, /* I - DNS-SD service type */
- const char *subtypes, /* I - Subtypes to register or NULL */
- int port, /* I - Port number or 0 */
- cupsd_txt_t *txt, /* I - TXT record */
- int commit, /* I - Commit registration? */
- int from_callback) /* I - Called from callback? */
-{
- char temp[256], /* Temporary string */
- *ptr; /* Pointer into string */
- int error; /* Any error */
-
-
-# ifdef HAVE_MDNSRESPONDER
- (void)from_callback;
-# endif /* HAVE_MDNSRESPONDER */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Registering \"%s\" with DNS-SD type \"%s\".", name, type);
-
- if (p && !srv)
- {
- /*
- * Assign the correct pointer for "srv"...
- */
-
-# ifdef HAVE_MDNSRESPONDER
- if (!strcmp(type, "_printer._tcp"))
- srv = &p->printer_srv; /* Target LPD service */
- else if (!strcmp(type, "_ipps._tcp"))
- srv = &p->ipps_srv; /* Target IPPS service */
- else
- srv = &p->ipp_srv; /* Target IPP service */
-
-# else /* HAVE_AVAHI */
- srv = &p->ipp_srv; /* Target service group */
-# endif /* HAVE_MDNSRESPONDER */
- }
-
-# ifdef HAVE_MDNSRESPONDER
- (void)commit;
-
-# else /* HAVE_AVAHI */
- if (!from_callback)
- avahi_threaded_poll_lock(DNSSDMaster);
-
- if (!*srv)
- *srv = avahi_entry_group_new(DNSSDClient, dnssdRegisterCallback, NULL);
- if (!*srv)
- {
- if (!from_callback)
- avahi_threaded_poll_unlock(DNSSDMaster);
-
- cupsdLogMessage(CUPSD_LOG_WARN, "DNS-SD registration of \"%s\" failed: %s",
- name, dnssdErrorString(avahi_client_errno(DNSSDClient)));
- return (0);
- }
-# endif /* HAVE_MDNSRESPONDER */
-
- /*
- * Make sure the name is <= 63 octets, and when we truncate be sure to
- * properly truncate any UTF-8 characters...
- */
-
- ptr = name + strlen(name);
- while ((ptr - name) > 63)
- {
- do
- {
- ptr --;
- }
- while (ptr > name && (*ptr & 0xc0) == 0x80);
-
- if (ptr > name)
- *ptr = '\0';
- }
-
- /*
- * Register the service...
- */
-
-# ifdef HAVE_MDNSRESPONDER
- if (subtypes)
- snprintf(temp, sizeof(temp), "%s,%s", type, subtypes);
- else
- cupsCopyString(temp, type, sizeof(temp));
-
- *srv = DNSSDMaster;
- error = DNSServiceRegister(srv, kDNSServiceFlagsShareConnection,
- 0, name, temp, NULL, DNSSDHostName, htons(port),
- txt ? TXTRecordGetLength(txt) : 0,
- txt ? TXTRecordGetBytesPtr(txt) : NULL,
- dnssdRegisterCallback, p);
-
-# else /* HAVE_AVAHI */
- if (txt)
- {
- AvahiStringList *temptxt;
- for (temptxt = *txt; temptxt; temptxt = temptxt->next)
- cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS_SD \"%s\" %s", name, temptxt->text);
- }
-
- error = avahi_entry_group_add_service_strlst(*srv, AVAHI_IF_UNSPEC,
- AVAHI_PROTO_UNSPEC, 0, name,
- type, NULL, DNSSDHostName, port,
- txt ? *txt : NULL);
- if (error)
- cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD service add for \"%s\" failed.",
- name);
-
- if (!error && subtypes)
- {
- /*
- * Register all of the subtypes...
- */
-
- char *start, /* Start of subtype */
- subtype[256]; /* Subtype string */
-
- cupsCopyString(temp, subtypes, sizeof(temp));
-
- for (start = temp; *start; start = ptr)
- {
- /*
- * Skip leading whitespace...
- */
-
- while (*start && isspace(*start & 255))
- start ++;
-
- /*
- * Grab everything up to the next comma or the end of the string...
- */
-
- for (ptr = start; *ptr && *ptr != ','; ptr ++);
-
- if (*ptr)
- *ptr++ = '\0';
-
- if (!*start)
- break;
-
- /*
- * Register the subtype...
- */
-
- snprintf(subtype, sizeof(subtype), "%s._sub.%s", start, type);
-
- error = avahi_entry_group_add_service_subtype(*srv, AVAHI_IF_UNSPEC,
- AVAHI_PROTO_UNSPEC, 0,
- name, type, NULL, subtype);
- if (error)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "DNS-SD subtype %s registration for \"%s\" failed." ,
- subtype, name);
- break;
- }
- }
- }
-
- if (!error && commit)
- {
- if ((error = avahi_entry_group_commit(*srv)) != 0)
- cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD commit of \"%s\" failed.",
- name);
- }
-
- if (!from_callback)
- avahi_threaded_poll_unlock(DNSSDMaster);
-# endif /* HAVE_MDNSRESPONDER */
-
- if (error)
- {
- cupsdLogMessage(CUPSD_LOG_WARN, "DNS-SD registration of \"%s\" failed: %s",
- name, dnssdErrorString(error));
- cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD type: %s", type);
- if (subtypes)
- cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD sub-types: %s", subtypes);
- }
-
- return (!error);
-}
-
/*
* 'dnssdRegisterPrinter()' - Start sending broadcast information for a printer
static void
dnssdRegisterPrinter(
- cupsd_printer_t *p, /* I - Printer */
- int from_callback) /* I - Called from callback? */
+ cupsd_printer_t *p) /* I - Printer */
{
- char name[256]; /* Service name */
- int status; /* Registration status */
- cupsd_txt_t ipp_txt; /* IPP(S) TXT record */
+ char name[256], /* Service name */
+ regtype[256]; /* Registration type(s) */
+ int num_txt; /* Number of IPP(S) TXT key/value pairs */
+ cups_option_t *txt; /* IPP(S) TXT key/value pairs */
+ bool status; /* Registration status */
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterPrinter(%s) %s", p->name,
- !p->ipp_srv ? "new" : "update");
-
-# ifdef HAVE_AVAHI
- if (!avahi_running)
- return;
-# endif /* HAVE_AVAHI */
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterPrinter(%s)", p->name);
/*
* Remove the current registrations if we have them and then return if
* per-printer sharing was just disabled...
*/
- dnssdDeregisterPrinter(p, 0, from_callback);
+ cupsDNSSDServiceDelete(p->dnssd);
+ p->dnssd = NULL;
if (!p->shared)
return;
cupsCopyString(name, p->info, sizeof(name));
}
else if (DNSSDComputerName)
+ {
snprintf(name, sizeof(name), "%s @ %s", p->name, DNSSDComputerName);
+ }
else
+ {
cupsCopyString(name, p->name, sizeof(name));
+ }
}
else
+ {
cupsCopyString(name, p->reg_name, sizeof(name));
+ }
/*
* Register IPP and LPD...
* our name, but use port number 0 so that we don't have clients using LPD...
*/
- ipp_txt = dnssdBuildTxtRecord(p);
+ p->dnssd = cupsDNSSDServiceNew(DNSSDContext, CUPS_DNSSD_IF_INDEX_ANY, name, dnssdRegisterCallback, p);
+ status = p->dnssd != NULL;
- status = dnssdRegisterInstance(NULL, p, name, "_printer._tcp", NULL, 0, NULL, 0, from_callback);
+ // LPD placeholder
+ status &= cupsDNSSDServiceAdd(p->dnssd, "_printer._tcp", /*domain*/NULL, DNSSDHostName, /*port*/0, /*num_txt*/0, /*txt*/NULL);
- if (status)
- dnssdRegisterInstance(NULL, p, name, "_ipps._tcp", DNSSDSubTypes, DNSSDPort, &ipp_txt, 0, from_callback);
+ // IPP service
+ num_txt = dnssdBuildTxtRecord(p, &txt);
- if (status)
+ if (p->type & CUPS_PTYPE_FAX)
{
- /*
- * Use the "_fax-ipp" service type for fax queues, otherwise use "_ipp"...
- */
-
- if (p->type & CUPS_PTYPE_FAX)
- status = dnssdRegisterInstance(NULL, p, name, "_fax-ipp._tcp", DNSSDSubTypes, DNSSDPort, &ipp_txt, 1, from_callback);
+ if (DNSSDSubTypes)
+ snprintf(regtype, sizeof(regtype), "_fax-ipp._tcp,%s", DNSSDSubTypes);
+ else
+ cupsCopyString(regtype, "_fax-ipp._tcp", sizeof(regtype));
+ }
+ else
+ {
+ if (DNSSDSubTypes)
+ snprintf(regtype, sizeof(regtype), "_ipp._tcp,%s", DNSSDSubTypes);
else
- status = dnssdRegisterInstance(NULL, p, name, "_ipp._tcp", DNSSDSubTypes, DNSSDPort, &ipp_txt, 1, from_callback);
+ cupsCopyString(regtype, "_ipp._tcp", sizeof(regtype));
}
- dnssdFreeTxtRecord(&ipp_txt);
+ status &= cupsDNSSDServiceAdd(p->dnssd, regtype, /*domain*/NULL, DNSSDHostName, (uint16_t)DNSSDPort, num_txt, txt);
+
+ // IPPS service
+ if (DNSSDSubTypes)
+ snprintf(regtype, sizeof(regtype), "_ipps._tcp,%s", DNSSDSubTypes);
+ else
+ cupsCopyString(regtype, "_ipps._tcp", sizeof(regtype));
+
+ status &= cupsDNSSDServiceAdd(p->dnssd, regtype, /*domain*/NULL, DNSSDHostName, (uint16_t)DNSSDPort, num_txt, txt);
+
+ cupsFreeOptions(num_txt, txt);
if (status)
{
- /*
- * Save the registered name and add the printer to the array of DNS-SD
- * printers...
- */
-
+ // Save the registered name and add the printer to the array of DNS-SD
+ // printers...
cupsdSetString(&p->reg_name, name);
cupsArrayAdd(DNSSDPrinters, p);
}
else
{
- /*
- * Registration failed for this printer...
- */
-
- dnssdDeregisterInstance(&p->ipp_srv, from_callback);
-
-# ifdef HAVE_MDNSRESPONDER
- dnssdDeregisterInstance(&p->ipps_srv, from_callback);
- dnssdDeregisterInstance(&p->printer_srv, from_callback);
-# endif /* HAVE_MDNSRESPONDER */
+ // Registration failed for this printer...
+ cupsDNSSDServiceDelete(p->dnssd);
+ p->dnssd = NULL;
}
}
* De-register the individual printers
*/
- for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
- p;
- p = (cupsd_printer_t *)cupsArrayNext(Printers))
- dnssdDeregisterPrinter(p, 1, 0);
+ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers))
+ {
+ cupsDNSSDServiceDelete(p->dnssd);
+ p->dnssd = NULL;
+ }
/*
* Shutdown the rest of the service refs...
*/
- dnssdDeregisterInstance(&WebIFSrv, 0);
-
-# ifdef HAVE_MDNSRESPONDER
- cupsdRemoveSelect(DNSServiceRefSockFD(DNSSDMaster));
-
- DNSServiceRefDeallocate(DNSSDMaster);
- DNSSDMaster = NULL;
-
-# else /* HAVE_AVAHI */
- if (DNSSDMaster)
- avahi_threaded_poll_stop(DNSSDMaster);
-
- if (DNSSDClient)
- {
- avahi_client_free(DNSSDClient);
- DNSSDClient = NULL;
- }
+ cupsDNSSDServiceDelete(DNSSDWebIF);
+ DNSSDWebIF = NULL;
- if (DNSSDMaster)
- {
- avahi_threaded_poll_free(DNSSDMaster);
- DNSSDMaster = NULL;
- }
-# endif /* HAVE_MDNSRESPONDER */
+ cupsDNSSDDelete(DNSSDContext);
+ DNSSDContext = NULL;
cupsArrayDelete(DNSSDPrinters);
DNSSDPrinters = NULL;
}
-# ifdef HAVE_MDNSRESPONDER
-/*
- * 'dnssdUpdate()' - Handle DNS-SD queries.
- */
-
-static void
-dnssdUpdate(void)
-{
- DNSServiceErrorType sdErr; /* Service discovery error */
-
-
- if ((sdErr = DNSServiceProcessResult(DNSSDMaster)) != kDNSServiceErr_NoError)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "DNS Service Discovery registration error %d!",
- sdErr);
- dnssdStop();
- }
-}
-# endif /* HAVE_MDNSRESPONDER */
-
-
-/*
- * 'dnssdUpdateDNSSDName()' - Update the listen port, computer name, and web interface registration.
- */
-
-static void
-dnssdUpdateDNSSDName(int from_callback) /* I - Called from callback? */
-{
- char webif[1024]; /* Web interface share name */
-# ifdef __APPLE__
- SCDynamicStoreRef sc; /* Context for dynamic store */
- CFDictionaryRef btmm; /* Back-to-My-Mac domains */
- CFStringEncoding nameEncoding; /* Encoding of computer name */
- CFStringRef nameRef; /* Host name CFString */
- char nameBuffer[1024]; /* C-string buffer */
-# endif /* __APPLE__ */
-
-
- /*
- * Only share the web interface and printers when non-local listening is
- * enabled...
- */
-
- if (!DNSSDPort)
- {
- /*
- * Get the port we use for registrations. If we are not listening on any
- * non-local ports, there is no sense sharing local printers via Bonjour...
- */
-
- cupsd_listener_t *lis; /* Current listening socket */
-
- for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
- lis;
- lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
- {
- if (httpAddrLocalhost(&(lis->address)))
- continue;
-
- DNSSDPort = httpAddrPort(&(lis->address));
- break;
- }
- }
-
- if (!DNSSDPort)
- return;
-
- /*
- * Get the computer name as a c-string...
- */
-
-# ifdef __APPLE__
- sc = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("cupsd"), NULL, NULL);
-
- if (sc)
- {
- /*
- * Get the computer name from the dynamic store...
- */
-
- cupsdClearString(&DNSSDComputerName);
-
- if ((nameRef = SCDynamicStoreCopyComputerName(sc, &nameEncoding)) != NULL)
- {
- if (CFStringGetCString(nameRef, nameBuffer, sizeof(nameBuffer),
- kCFStringEncodingUTF8))
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Dynamic store computer name is \"%s\".", nameBuffer);
- cupsdSetString(&DNSSDComputerName, nameBuffer);
- }
-
- CFRelease(nameRef);
- }
-
- if (!DNSSDComputerName)
- {
- /*
- * Use the ServerName instead...
- */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Using ServerName \"%s\" as computer name.", ServerName);
- cupsdSetString(&DNSSDComputerName, ServerName);
- }
-
- if (!DNSSDHostName)
- {
- /*
- * Get the local hostname from the dynamic store...
- */
-
- if ((nameRef = SCDynamicStoreCopyLocalHostName(sc)) != NULL)
- {
- if (CFStringGetCString(nameRef, nameBuffer, sizeof(nameBuffer),
- kCFStringEncodingUTF8))
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Dynamic store host name is \"%s\".", nameBuffer);
-
- if (strchr(nameBuffer, '.'))
- cupsdSetString(&DNSSDHostName, nameBuffer);
- else
- cupsdSetStringf(&DNSSDHostName, "%s.local", nameBuffer);
-
- cupsdLogMessage(CUPSD_LOG_INFO, "Defaulting to \"DNSSDHostName %s\".", DNSSDHostName);
- }
-
- CFRelease(nameRef);
- }
- }
-
- if (!DNSSDHostName)
- {
- /*
- * Use the ServerName instead...
- */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Using ServerName \"%s\" as host name.", ServerName);
- cupsdSetString(&DNSSDHostName, ServerName);
-
- cupsdLogMessage(CUPSD_LOG_INFO, "Defaulting to \"DNSSDHostName %s\".", DNSSDHostName);
- }
-
- /*
- * Get any Back-to-My-Mac domains and add them as aliases...
- */
-
- cupsdFreeAliases(DNSSDAlias);
- DNSSDAlias = NULL;
-
- btmm = SCDynamicStoreCopyValue(sc, CFSTR("Setup:/Network/BackToMyMac"));
- if (btmm && CFGetTypeID(btmm) == CFDictionaryGetTypeID())
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG, "%d Back to My Mac aliases to add.",
- (int)CFDictionaryGetCount(btmm));
- CFDictionaryApplyFunction(btmm, dnssdAddAlias, NULL);
- }
- else if (btmm)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Bad Back to My Mac data in dynamic store!");
- else
- cupsdLogMessage(CUPSD_LOG_DEBUG, "No Back to My Mac aliases to add.");
-
- if (btmm)
- CFRelease(btmm);
-
- CFRelease(sc);
- }
- else
-# endif /* __APPLE__ */
-# ifdef HAVE_AVAHI
- if (DNSSDClient)
- {
- const char *host_name = avahi_client_get_host_name(DNSSDClient);
-
- cupsdSetString(&DNSSDComputerName, host_name ? host_name : ServerName);
-
- if (!DNSSDHostName)
- {
- const char *host_fqdn = avahi_client_get_host_name_fqdn(DNSSDClient);
-
- if (host_fqdn)
- cupsdSetString(&DNSSDHostName, host_fqdn);
- else if (strchr(ServerName, '.'))
- cupsdSetString(&DNSSDHostName, ServerName);
- else
- cupsdSetStringf(&DNSSDHostName, "%s.local", ServerName);
-
- cupsdLogMessage(CUPSD_LOG_INFO, "Defaulting to \"DNSSDHostName %s\".", DNSSDHostName);
- }
- }
- else
-# endif /* HAVE_AVAHI */
- {
- cupsdSetString(&DNSSDComputerName, ServerName);
-
- if (!DNSSDHostName)
- {
- if (strchr(ServerName, '.'))
- cupsdSetString(&DNSSDHostName, ServerName);
- else
- cupsdSetStringf(&DNSSDHostName, "%s.local", ServerName);
-
- cupsdLogMessage(CUPSD_LOG_INFO, "Defaulting to \"DNSSDHostName %s\".", DNSSDHostName);
- }
- }
-
- /*
- * Then (re)register the web interface if enabled...
- */
-
- if (BrowseWebIF)
- {
- if (DNSSDComputerName)
- snprintf(webif, sizeof(webif), "CUPS @ %s", DNSSDComputerName);
- else
- cupsCopyString(webif, "CUPS", sizeof(webif));
-
- dnssdDeregisterInstance(&WebIFSrv, from_callback);
- dnssdRegisterInstance(&WebIFSrv, NULL, webif, "_http._tcp", "_printer", DNSSDPort, NULL, 1, from_callback);
- }
-}
-
-
/*
* 'get_auth_info_required()' - Get the auth-info-required value to advertise.
*/