* cupsdUpdateLDAPBrowse() - Scan for new printers via LDAP...
* cupsdUpdateSLPBrowse() - Get browsing information via SLP.
* dequote() - Remote quotes from a string.
+ * dnssdAddAlias() - Add a DNS-SD alias name.
* dnssdBuildTxtRecord() - Build a TXT record from printer info.
* dnssdComparePrinters() - Compare the registered names of two printers.
* dnssdDeregisterPrinter() - Stop sending broadcast information for a
*/
static char *dequote(char *d, const char *s, int dlen);
+static char *get_auth_info_required(cupsd_printer_t *p, char *buffer,
+ size_t bufsize);
#ifdef __APPLE__
static int get_hostconfig(const char *name);
#endif /* __APPLE__ */
#ifdef HAVE_DNSSD
+# ifdef HAVE_COREFOUNDATION
+static void dnssdAddAlias(const void *key, const void *value,
+ void *context);
+# endif /* HAVE_COREFOUNDATION */
static char *dnssdBuildTxtRecord(int *txt_len, cupsd_printer_t *p,
int for_lpd);
static int dnssdComparePrinters(cupsd_printer_t *a, cupsd_printer_t *b);
removeit);
if (!Browsing || !p->shared ||
- (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)))
+ (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
+ CUPS_PRINTER_SCANNER)))
return;
/*
p->name);
if (!Browsing || !BrowseLocalProtocols ||
- (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)))
+ (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
+ CUPS_PRINTER_SCANNER)))
return;
#ifdef HAVE_LIBSLP
for (count = 0, p = (cupsd_printer_t *)cupsArrayFirst(Printers);
count < max_count && p != NULL;
p = (cupsd_printer_t *)cupsArrayNext(Printers))
- if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) &&
+ if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
+ CUPS_PRINTER_SCANNER)) &&
p->shared && p->browse_time < ut)
count ++;
if (!p)
break;
- else if ((p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) ||
+ else if ((p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
+ CUPS_PRINTER_SCANNER)) ||
!p->shared)
continue;
else if (p->browse_time < ut)
for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
p;
p = (cupsd_printer_t *)cupsArrayNext(Printers))
- if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)))
+ if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
+ CUPS_PRINTER_SCANNER)))
cupsdRegisterPrinter(p);
}
argv[1] = pollp->hostname;
if (cupsdStartProcess(polld, argv, envp, -1, -1, statusfds[1], -1, -1,
- 0, DefaultProfile, 0, &(pollp->pid)) < 0)
+ 0, DefaultProfile, NULL, &(pollp->pid)) < 0)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"cupsdStartPolling: Unable to fork polling daemon - %s",
for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
p;
p = (cupsd_printer_t *)cupsArrayNext(Printers))
- if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)))
+ if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
+ CUPS_PRINTER_SCANNER)))
cupsdDeregisterPrinter(p, 1);
/*
DNSServiceErrorType error; /* Error from service creation */
char webif[1024]; /* Web interface share name */
#ifdef HAVE_COREFOUNDATION_H
- CFStringRef nameRef; /* Computer name CFString */
+ SCDynamicStoreRef sc; /* Context for dynamic store */
+ CFDictionaryRef btmm; /* Back-to-My-Mac domains */
+ CFStringRef nameRef; /* Host name CFString */
char nameBuffer[1024]; /* C-string buffer */
- CFStringEncoding nameEncoding; /* Computer name encoding */
#endif /* HAVE_COREFOUNDATION_H */
* enabled...
*/
+
if (!DNSSDPort)
return;
*/
#ifdef HAVE_COREFOUNDATION_H
- cupsdClearString(&DNSSDName);
+ sc = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("cupsd"), NULL, NULL);
- if ((nameRef = SCDynamicStoreCopyComputerName(NULL,
- &nameEncoding)) != NULL)
+ if (sc)
{
- if (CFStringGetCString(nameRef, nameBuffer, sizeof(nameBuffer),
- kCFStringEncodingUTF8))
- cupsdSetString(&DNSSDName, nameBuffer);
+ /*
+ * Get the computer name from the dynamic store...
+ */
- CFRelease(nameRef);
- }
+ cupsdClearString(&DNSSDName);
-#else
- cupsdSetString(&DNSSDName, ServerName);
+ if ((nameRef = SCDynamicStoreCopyLocalHostName(sc)) != NULL)
+ {
+ if (CFStringGetCString(nameRef, nameBuffer, sizeof(nameBuffer),
+ kCFStringEncodingUTF8))
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Dynamic store host name is \"%s\".", nameBuffer);
+ cupsdSetString(&DNSSDName, nameBuffer);
+ }
+
+ CFRelease(nameRef);
+ }
+
+ if (!DNSSDName)
+ {
+ /*
+ * Use the ServerName instead...
+ */
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Using ServerName \"%s\" as host name.", ServerName);
+ cupsdSetString(&DNSSDName, ServerName);
+ }
+
+ /*
+ * 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 /* HAVE_COREFOUNDATION_H */
+ cupsdSetString(&DNSSDName, ServerName);
/*
* Then (re)register the web interface if enabled...
#ifdef HAVE_DNSSD
+# ifdef HAVE_COREFOUNDATION
+/*
+ * 'dnssdAddAlias()' - Add a DNS-SD alias name.
+ */
+
+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 */
+
+
+ (void)context;
+
+ if (CFGetTypeID((CFStringRef)value) == CFStringGetTypeID() &&
+ CFStringGetCString((CFStringRef)value, valueStr, sizeof(valueStr),
+ kCFStringEncodingUTF8))
+ {
+ snprintf(hostname, sizeof(hostname), "%s.%s", DNSSDName, valueStr);
+ if (!DNSSDAlias)
+ DNSSDAlias = cupsArrayNew(NULL, NULL);
+
+ cupsdAddAlias(DNSSDAlias, hostname);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Added Back to My Mac ServerAlias %s",
+ hostname);
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Bad Back to My Mac domain in dynamic store!");
+}
+# endif /* HAVE_COREFOUNDATION */
+
+
/*
* 'dnssdBuildTxtRecord()' - Build a TXT record from printer info.
*/
cupsd_printer_t *p, /* I - Printer information */
int for_lpd) /* I - 1 = LPD, 0 = IPP */
{
- int i, j; /* Looping vars */
+ int i; /* Looping var */
char type_str[32], /* Type to string buffer */
state_str[32], /* State to string buffer */
rp_str[1024], /* Queue name string buffer */
air_str[1024], /* auth-info-required string buffer */
*keyvalue[32][2]; /* Table of key/value pairs */
- ipp_attribute_t *air_attr; /* auth-info-required attribute */
/*
keyvalue[i ][0] = "pdl";
keyvalue[i++][1] = p->pdl ? p->pdl : "application/postscript";
- if ((air_attr = ippFindAttribute(p->attrs, "auth-info-required",
- IPP_TAG_KEYWORD)) != NULL &&
- strcmp(air_attr->values[0].string.text, "none"))
+ if (get_auth_info_required(p, air_str, sizeof(air_str)))
{
- char *air = air_str; /* Pointer into string */
-
-
- for (j = 0; j < air_attr->num_values; j ++)
- {
- if (air >= (air_str + sizeof(air_str) - 2))
- break;
-
- if (j)
- *air++ = ',';
-
- strlcpy(air, air_attr->values[j].string.text,
- sizeof(air_str) - (air - air_str));
- air += strlen(air);
- }
-
keyvalue[i ][0] = "air";
keyvalue[i++][1] = air_str;
}
*nameptr; /* Pointer into name */
int ipp_len, /* IPP TXT record length */
printer_len; /* LPD TXT record length */
- char resource[1024]; /* Resource path for printer */
const char *regtype; /* Registration type */
- const char *domain; /* Registration domain */
- cupsd_location_t *location, /* Printer location */
- *policy; /* Operation policy for Print-Job */
- unsigned address[4]; /* INADDR_ANY address */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterPrinter(%s) %s", p->name,
cupsArrayAdd(DNSSDPrinters, p);
}
- /*
- * If 'Allow printing from the Internet' is enabled (i.e. from any address)
- * let dnssd decide on the domain, otherwise restrict it to ".local".
- */
-
- if (p->type & CUPS_PRINTER_CLASS)
- snprintf(resource, sizeof(resource), "/classes/%s", p->name);
- else
- snprintf(resource, sizeof(resource), "/printers/%s", p->name);
-
- address[0] = address[1] = address[2] = address[3] = 0;
- location = cupsdFindBest(resource, HTTP_POST);
- policy = cupsdFindPolicyOp(p->op_policy_ptr, IPP_PRINT_JOB);
-
- if ((location && !cupsdCheckAccess(address, "", 0, location)) ||
- (policy && !cupsdCheckAccess(address, "", 0, policy)))
- domain = "local.";
- else
- domain = NULL;
-
/*
* Register IPP and (optionally) LPD...
*/
"_ipp._tcp,_cups";
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Registering DNS-SD printer %s with name \"%s\", "
- "type \"%s\", and domain \"%s\"", p->name, name, regtype,
- domain ? domain : "(null)");
+ "Registering DNS-SD printer %s with name \"%s\" and "
+ "type \"%s\"", p->name, name, regtype);
/*
* Register the queue, dropping characters as needed until we succeed...
{
p->ipp_ref = DNSSDRef;
if ((se = DNSServiceRegister(&p->ipp_ref, kDNSServiceFlagsShareConnection,
- 0, name, regtype, domain, NULL,
+ 0, name, regtype, NULL, NULL,
htons(DNSSDPort), ipp_len, ipp_txt,
dnssdRegisterCallback,
p)) == kDNSServiceErr_BadParam)
*/
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Registering DNS-SD printer %s with name \"%s\", "
- "type \"_printer._tcp\", and domain \"%s\"", p->name,
- name, domain ? domain : "(null)");
+ "Registering DNS-SD printer %s with name \"%s\" and "
+ "type \"_printer._tcp\"", p->name, name);
p->printer_ref = DNSSDRef;
if ((se = DNSServiceRegister(&p->printer_ref,
kDNSServiceFlagsShareConnection,
- 0, name, "_printer._tcp", domain, NULL,
+ 0, name, "_printer._tcp", NULL, NULL,
htons(515), printer_len, printer_txt,
dnssdRegisterCallback,
p)) == kDNSServiceErr_NoError)
#endif /* HAVE_DNSSD */
+/*
+ * 'get_auth_info_required()' - Get the auth-info-required value to advertise.
+ */
+
+static char * /* O - String or NULL if none */
+get_auth_info_required(
+ cupsd_printer_t *p, /* I - Printer */
+ char *buffer, /* I - Value buffer */
+ size_t bufsize) /* I - Size of value buffer */
+{
+ cupsd_location_t *auth; /* Pointer to authentication element */
+ char resource[1024]; /* Printer/class resource path */
+
+
+ /*
+ * If auth-info-required is set for this printer, return that...
+ */
+
+ if (p->num_auth_info_required > 0 && strcmp(p->auth_info_required[0], "none"))
+ {
+ int i; /* Looping var */
+ char *bufptr; /* Pointer into buffer */
+
+ for (i = 0, bufptr = buffer; i < p->num_auth_info_required; i ++)
+ {
+ if (bufptr >= (buffer + bufsize - 2))
+ break;
+
+ if (i)
+ *bufptr++ = ',';
+
+ strlcpy(bufptr, p->auth_info_required[i], bufsize - (bufptr - buffer));
+ bufptr += strlen(bufptr);
+ }
+
+ return (buffer);
+ }
+
+ /*
+ * Figure out the authentication data requirements to advertise...
+ */
+
+ if (p->type & CUPS_PRINTER_CLASS)
+ snprintf(resource, sizeof(resource), "/classes/%s", p->name);
+ else
+ snprintf(resource, sizeof(resource), "/printers/%s", p->name);
+
+ if ((auth = cupsdFindBest(resource, HTTP_POST)) == NULL ||
+ auth->type == CUPSD_AUTH_NONE)
+ auth = cupsdFindPolicyOp(p->op_policy_ptr, IPP_PRINT_JOB);
+
+ if (auth)
+ {
+ int auth_type; /* Authentication type */
+
+ if ((auth_type = auth->type) == CUPSD_AUTH_DEFAULT)
+ auth_type = DefaultAuthType;
+
+ switch (auth_type)
+ {
+ case CUPSD_AUTH_NONE :
+ return (NULL);
+
+ case CUPSD_AUTH_NEGOTIATE :
+ strlcpy(buffer, "negotiate", bufsize);
+ break;
+
+ default :
+ strlcpy(buffer, "username,password", bufsize);
+ break;
+ }
+
+ return (buffer);
+ }
+
+ return (NULL);
+}
+
+
#ifdef __APPLE__
/*
* 'get_hostconfig()' - Get an /etc/hostconfig service setting.
uri[1024], /* Printer URI */
location[1024], /* printer-location */
info[1024], /* printer-info */
- make_model[1024];
+ make_model[1024],
/* printer-make-and-model */
+ air[1024]; /* auth-info-required */
cupsd_netif_t *iface; /* Network interface */
else
strlcpy(make_model, "Local System V Printer", sizeof(make_model));
+ if (get_auth_info_required(p, packet, sizeof(packet)))
+ snprintf(air, sizeof(air), " auth-info-required=%s", packet);
+ else
+ air[0] = '\0';
+
/*
* Send a packet to each browse address...
*/
(p->type & CUPS_PRINTER_CLASS) ? "/classes/%s" :
"/printers/%s",
p->name);
- snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\" %s\n",
+ snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\" %s%s\n",
type, p->state, uri, location, info, make_model,
- p->browse_attrs ? p->browse_attrs : "");
+ p->browse_attrs ? p->browse_attrs : "", air);
bytes = strlen(packet);
(p->type & CUPS_PRINTER_CLASS) ? "/classes/%s" :
"/printers/%s",
p->name);
- snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\" %s\n",
+ snprintf(packet, sizeof(packet),
+ "%x %x %s \"%s\" \"%s\" \"%s\" %s%s\n",
type, p->state, uri, location, info, make_model,
- p->browse_attrs ? p->browse_attrs : "");
+ p->browse_attrs ? p->browse_attrs : "", air);
bytes = strlen(packet);
* the default server name...
*/
- snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\" %s\n",
+ snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\" %s%s\n",
type, p->state, p->uri, location, info, make_model,
- p->browse_attrs ? p->browse_attrs : "");
+ p->browse_attrs ? p->browse_attrs : "", air);
bytes = strlen(packet);
cupsdLogMessage(CUPSD_LOG_DEBUG2,
argv[4] = NULL;
cupsdStartProcess("/bin/launchctl", argv, envp, -1, -1, -1, -1, -1, 1,
- NULL, 0, &pid);
+ NULL, NULL, &pid);
}
#endif /* __APPLE__ */
else