Skip to content

Commit d0b6695

Browse files
Merge pull request #1620 from abubakarsabir924-cell/fix-1599-signed
Fix duplicate local printers in DNS-SD discovery for CUPS 2.4.x (Issu…
2 parents 7782710 + f26d51a commit d0b6695

2 files changed

Lines changed: 82 additions & 4 deletions

File tree

cups/dest.c

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ typedef struct _cups_dnssd_data_s /* Enumeration data */
9393
cups_array_t *devices; /* Devices found so far */
9494
int num_dests; /* Number of lpoptions destinations */
9595
cups_dest_t *dests; /* lpoptions destinations */
96+
int num_local; /* Number of local cupsd queues */
97+
cups_dest_t *local_dests; /* Local cupsd queues */
9698
char def_name[1024], /* Default printer name, if any */
9799
*def_instance; /* Default printer instance, if any */
98100
} _cups_dnssd_data_t;
@@ -1391,7 +1393,8 @@ _cupsGetDests(http_t *http, /* I - Connection to server or
13911393
"printer-state-change-time",
13921394
"printer-state-reasons",
13931395
"printer-type",
1394-
"printer-uri-supported"
1396+
"printer-uri-supported",
1397+
"printer-uuid"
13951398
};
13961399

13971400

@@ -1500,7 +1503,8 @@ _cupsGetDests(http_t *http, /* I - Connection to server or
15001503
!strcmp(attr->name, "printer-is-accepting-jobs") ||
15011504
!strcmp(attr->name, "printer-location") ||
15021505
!strcmp(attr->name, "printer-state-reasons") ||
1503-
!strcmp(attr->name, "printer-uri-supported"))
1506+
!strcmp(attr->name, "printer-uri-supported") ||
1507+
!strcmp(attr->name, "printer-uuid"))
15041508
{
15051509
/*
15061510
* Add a printer description attribute...
@@ -3170,6 +3174,26 @@ cups_dnssd_query_cb(
31703174
if (!have_pdf && !have_raster)
31713175
device->state = _CUPS_DNSSD_INCOMPATIBLE;
31723176
}
3177+
else if (!_cups_strcasecmp(key, "UUID"))
3178+
{
3179+
// Suppress local printer being re-discovered via DNS-SD
3180+
int i;
3181+
device->dest.num_options = cupsAddOption("UUID", value,
3182+
device->dest.num_options,
3183+
&device->dest.options);
3184+
3185+
for (i = 0; i < data->num_local; i++)
3186+
{
3187+
const char *local_uuid = cupsGetOption("printer-uuid",
3188+
data->local_dests[i].num_options,
3189+
data->local_dests[i].options);
3190+
if (local_uuid && !_cups_strcasecmp(value, local_uuid + 9))
3191+
{
3192+
device->state = _CUPS_DNSSD_INCOMPATIBLE;
3193+
break;
3194+
}
3195+
}
3196+
}
31733197
else if (!_cups_strcasecmp(key, "printer-type"))
31743198
{
31753199
/*
@@ -3547,10 +3571,12 @@ cups_enum_dests(
35473571
if (!(mask & CUPS_PRINTER_DISCOVERED) || !(type & CUPS_PRINTER_DISCOVERED))
35483572
{
35493573
/*
3550-
* Get the list of local printers and pass them to the callback function...
3574+
* Get the list of local printers...
35513575
*/
35523576

35533577
num_dests = _cupsGetDests(http, IPP_OP_CUPS_GET_PRINTERS, NULL, &dests, type, mask);
3578+
data.num_local = 0;
3579+
data.local_dests = NULL;
35543580

35553581
if (data.def_name[0])
35563582
{
@@ -3574,6 +3600,12 @@ cups_enum_dests(
35743600
const char *device_uri; /* Device URI */
35753601
#endif /* HAVE_DNSSD */
35763602

3603+
/*
3604+
* Pass the list of local printers to the callback function...
3605+
*/
3606+
3607+
data.num_local = cupsCopyDest(dest, data.num_local, &data.local_dests);
3608+
35773609
if ((user_dest = cupsGetDest(dest->name, NULL, data.num_dests, data.dests)) != NULL)
35783610
{
35793611
/*
@@ -3665,6 +3697,7 @@ cups_enum_dests(
36653697
DEBUG_puts("1cups_enum_dests: Unable to create service browser, returning 0.");
36663698

36673699
cupsFreeDests(data.num_dests, data.dests);
3700+
cupsFreeDests(data.num_local, data.local_dests);
36683701
cupsArrayDelete(data.devices);
36693702

36703703
return (0);
@@ -3679,6 +3712,7 @@ cups_enum_dests(
36793712
DNSServiceRefDeallocate(data.main_ref);
36803713

36813714
cupsFreeDests(data.num_dests, data.dests);
3715+
cupsFreeDests(data.num_local, data.local_dests);
36823716
cupsArrayDelete(data.devices);
36833717

36843718
return (0);
@@ -3692,6 +3726,7 @@ cups_enum_dests(
36923726
DNSServiceRefDeallocate(data.main_ref);
36933727

36943728
cupsFreeDests(data.num_dests, data.dests);
3729+
cupsFreeDests(data.num_local, data.local_dests);
36953730
cupsArrayDelete(data.devices);
36963731

36973732
return (0);
@@ -3704,6 +3739,7 @@ cups_enum_dests(
37043739
DEBUG_puts("1cups_enum_dests: Unable to create Avahi poll, returning 0.");
37053740

37063741
cupsFreeDests(data.num_dests, data.dests);
3742+
cupsFreeDests(data.num_local, data.local_dests);
37073743
cupsArrayDelete(data.devices);
37083744

37093745
return (0);
@@ -3720,6 +3756,7 @@ cups_enum_dests(
37203756
avahi_simple_poll_free(data.simple_poll);
37213757

37223758
cupsFreeDests(data.num_dests, data.dests);
3759+
cupsFreeDests(data.num_local, data.local_dests);
37233760
cupsArrayDelete(data.devices);
37243761

37253762
return (0);
@@ -3734,6 +3771,7 @@ cups_enum_dests(
37343771
avahi_simple_poll_free(data.simple_poll);
37353772

37363773
cupsFreeDests(data.num_dests, data.dests);
3774+
cupsFreeDests(data.num_local, data.local_dests);
37373775
cupsArrayDelete(data.devices);
37383776

37393777
return (0);
@@ -3750,6 +3788,7 @@ cups_enum_dests(
37503788
avahi_simple_poll_free(data.simple_poll);
37513789

37523790
cupsFreeDests(data.num_dests, data.dests);
3791+
cupsFreeDests(data.num_local, data.local_dests);
37533792
cupsArrayDelete(data.devices);
37543793

37553794
return (0);
@@ -3862,7 +3901,7 @@ cups_enum_dests(
38623901

38633902
DEBUG_printf(("1cups_enum_dests: Query for \"%s\" is complete.", device->fullName));
38643903

3865-
if ((device->type & mask) == type)
3904+
if (((device->type & mask) == type) && (device->state != _CUPS_DNSSD_INCOMPATIBLE))
38663905
{
38673906
cups_dest_t *user_dest; /* Destination from lpoptions */
38683907

@@ -3940,6 +3979,7 @@ cups_enum_dests(
39403979
enum_finished:
39413980

39423981
cupsFreeDests(data.num_dests, data.dests);
3982+
cupsFreeDests(data.num_local, data.local_dests);
39433983

39443984
#ifdef HAVE_DNSSD
39453985
cupsArrayDelete(data.devices);

scheduler/ipp.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5715,7 +5715,45 @@ create_local_printer(
57155715
send_ipp_status(con, IPP_STATUS_OK, _("Printer \"%s\" already exists."), printer->name);
57165716
goto add_printer_attributes;
57175717
}
5718+
/* Check for existing permanent queue with same UUID */
5719+
{
5720+
cupsd_printer_t *perm;
5721+
char req_uuid[64] = "";
5722+
5723+
/* Extract UUID from hostname like: UUID.local */
5724+
const char *host_start = strstr(ptr, "://");
5725+
if (host_start)
5726+
{
5727+
host_start += 3;
5728+
const char *dot_local = strstr(host_start, ".local");
5729+
if (dot_local)
5730+
{
5731+
size_t ulen = (size_t)(dot_local - host_start);
5732+
if (ulen < sizeof(req_uuid))
5733+
{
5734+
memcpy(req_uuid, host_start, ulen);
5735+
req_uuid[ulen] = '\0';
5736+
}
5737+
}
5738+
}
5739+
5740+
if (req_uuid[0])
5741+
{
5742+
for (perm = (cupsd_printer_t *)cupsArrayFirst(Printers); perm; perm = (cupsd_printer_t *)cupsArrayNext(Printers))
5743+
{
5744+
if (!perm->temporary && perm->uuid && !strcasecmp(req_uuid, perm->uuid + 9))
5745+
{
5746+
cupsdLogMessage(CUPSD_LOG_DEBUG, "create_local_printer: FOUND MATCHING PERMANENT QUEUE: %s", perm->name);
5747+
printer = perm;
5748+
printer->state_time = time(NULL);
5749+
send_ipp_status(con, IPP_STATUS_OK, _("Printer \"%s\" already exists."), printer->name);
5750+
goto add_printer_attributes;
5751+
}
5752+
}
5753+
}
57185754
}
5755+
}
5756+
57195757

57205758
/*
57215759
* Create the printer...

0 commit comments

Comments
 (0)