diff --git a/man/cupsd.conf.5 b/man/cupsd.conf.5 index a34d16a08..592448e2b 100644 --- a/man/cupsd.conf.5 +++ b/man/cupsd.conf.5 @@ -146,6 +146,25 @@ The value "none" disables the "@ Computer Name" suffix added to shared printer n \fBDNSSDHostName \fIHOSTNAME\fR Specifies the fully-qualified domain name for the server that is used for DNS-SD sharing. The default is typically the server's ".local" hostname and is updated whenever that hostname changes. +.\"#DNSSDServiceName +.TP 5 +\fBDNSSDServiceName \fIservice-name\fR +Specifies the service name announced for a shared printer. +\fIservice-name\fR may contain the following placeholders: +.RS +.IP %n 5 +The printer's name. +.IP %i 5 +The printer's \fIinfo\fR field. +.IP %l 5 +The printer's \fIlocation\fR field. +.IP %m 5 +The printer's \fImake & model\fR field. +.IP %c 5 +The server's name. +.IP %% 5 +A literal percent sign. +.RE .\"#ErrorPolicy .TP 5 \fBErrorPolicy abort-job\fR diff --git a/scheduler/conf.c b/scheduler/conf.c index e55afdbd7..791087183 100644 --- a/scheduler/conf.c +++ b/scheduler/conf.c @@ -81,6 +81,7 @@ static const cupsd_var_t cupsd_vars[] = { "DirtyCleanInterval", &DirtyCleanInterval, CUPSD_VARTYPE_TIME }, { "DNSSDComputerName", &DNSSDComputerName, CUPSD_VARTYPE_STRING }, { "DNSSDHostName", &DNSSDHostName, CUPSD_VARTYPE_STRING }, + { "DNSSDServiceName", &DNSSDServiceName, CUPSD_VARTYPE_STRING }, { "ErrorPolicy", &ErrorPolicy, CUPSD_VARTYPE_STRING }, { "FilterLimit", &FilterLimit, CUPSD_VARTYPE_INTEGER }, #ifdef HAVE_GSSAPI diff --git a/scheduler/dirsvc.c b/scheduler/dirsvc.c index 1c05c80ad..0530cc0bb 100644 --- a/scheduler/dirsvc.c +++ b/scheduler/dirsvc.c @@ -485,7 +485,45 @@ dnssdRegisterPrinter( if (!p->reg_name) { - if (p->info && strlen(p->info) > 0) + if (DNSSDServiceName && DNSSDServiceName[0] != '\0') { + char *s = DNSSDServiceName, *e = name + sizeof(name), *q = name, c; + + while (1) { + c = *s++; + /* assert(q < e); */ + if (c == '\0' || q == e - 1) { + *q = '\0'; + break; + } else if (c == '%') { + c = *s++; + if (c == '\0') { /* putting this into the case would need a break 2 */ + *q = '\0'; + break; + } else if (c == '%') { /* could be put into case */ + *q++ = '%'; + } else { + char *r; + switch (c) { + case 'n': r = p->name; break; + case 'l': r = p->location; break; + case 'i': r = p->info; break; + case 'm': r = p->make_model; break; + case 'c': r = DNSSDComputerName; break; + default: continue; + } + if (r == NULL) continue; + q += strlcpy(q, r, e - q); + if (q >= e) { + *(e - 1) = '\0'; + break; + } + } + } else { + *q++ = c; + } + } + } + else if (p->info && strlen(p->info) > 0) { if (DNSSDComputerName) snprintf(name, sizeof(name), "%s @ %s", p->info, DNSSDComputerName); diff --git a/scheduler/dirsvc.h b/scheduler/dirsvc.h index 77d8c36dc..70b20ba05 100644 --- a/scheduler/dirsvc.h +++ b/scheduler/dirsvc.h @@ -36,8 +36,11 @@ VAR char *DNSSDHostName VALUE(NULL); /* Hostname */ VAR int DNSSDHostNameConfigured VALUE(0); /* Was the DNSSDHostName value configured in cupsd.conf? */ -VAR char *DNSSDSubTypes VALUE(NULL); +VAR char *DNSSDSubTypes VALUE(NULL). /* Bonjour registration subtypes */ + *DNSSDServiceName + VALUE(NULL); + /* DNSSD service name */ VAR cups_array_t *DNSSDAlias VALUE(NULL); /* List of dynamic ServerAlias's */ VAR int DNSSDPort VALUE(0);