#ifdef HAVE_AVAHI
static AvahiSimplePoll *simple_poll = NULL;
/* Poll information */
-static int got_callback = 0;
- /* Got a callback? */
+static int got_data = 0; /* Got data from poll? */
#endif /* HAVE_AVAHI */
const void *rdata, uint32_t ttl,
void *context)
__attribute__((nonnull(1,5,9,11)));
-#endif /* HAVE_DNSSD */
-#ifdef HAVE_AVAHI
+#elif defined(HAVE_AVAHI)
+static int poll_callback(struct pollfd *pollfds,
+ unsigned int num_pollfds, int timeout,
+ void *context);
static void query_callback(AvahiRecordBrowser *browser,
AvahiIfIndex interface,
AvahiProtocol protocol,
size_t rdlen,
AvahiLookupResultFlags flags,
void *context);
-#endif /* HAVE_AVAHI */
+#endif /* HAVE_DNSSD */
static void sigterm_handler(int sig);
static void unquote(char *dst, const char *src, size_t dstsize)
__attribute__((nonnull(1,2)));
#ifdef HAVE_AVAHI
if ((simple_poll = avahi_simple_poll_new()) == NULL)
{
- fputs("DEBUG: Unable to create avahi simple poll object.\n", stderr);
+ fputs("DEBUG: Unable to create Avahi simple poll object.\n", stderr);
return (1);
}
+ avahi_simple_poll_set_func(simple_poll, poll_callback, NULL);
+
client = avahi_client_new(avahi_simple_poll_get(simple_poll),
0, client_callback, simple_poll, &error);
if (!client)
{
- fputs("DEBUG: Unable to create avahi client.\n", stderr);
+ fputs("DEBUG: Unable to create Avahi client.\n", stderr);
return (1);
}
FD_SET(fd, &input);
timeout.tv_sec = 0;
- timeout.tv_usec = 250000;
+ timeout.tv_usec = 500000;
if (select(fd + 1, &input, NULL, NULL, &timeout) < 0)
continue;
announce = 1;
#elif defined(HAVE_AVAHI)
- got_callback = 0;
+ got_data = 0;
- if ((error = avahi_simple_poll_iterate(simple_poll, 3)) != 0 &&
- errno != EINTR)
+ if ((error = avahi_simple_poll_iterate(simple_poll, 500)) > 0)
{
/*
* We've been told to exit the loop. Perhaps the connection to
break;
}
- if (got_callback)
+ if (!got_data)
announce = 1;
#endif /* HAVE_DNSSD */
+/* fprintf(stderr, "DEBUG: announce=%d\n", announce);*/
+
if (announce)
{
/*
* Found the device, now get the TXT record(s) for it...
*/
- if (count < 20)
+ if (count < 50)
{
fprintf(stderr, "DEBUG: Querying \"%s\"...\n", device->fullName);
sent ++;
}
+ fprintf(stderr, "DEBUG: sent=%d, count=%d\n", sent, count);
+
if (sent == cupsArrayCount(devices))
break;
}
"interfaceIndex=%d, errorCode=%d, serviceName=\"%s\", "
"regtype=\"%s\", replyDomain=\"%s\", context=%p)\n",
sdRef, flags, interfaceIndex, errorCode,
- serviceName ? serviceName : "(null)",
- regtype ? regtype : "(null)",
- replyDomain ? replyDomain : "(null)",
- context);
+ serviceName, regtype, replyDomain, context);
/*
* Only process "add" data...
"interfaceIndex=%d, errorCode=%d, serviceName=\"%s\", "
"regtype=\"%s\", replyDomain=\"%s\", context=%p)\n",
sdRef, flags, interfaceIndex, errorCode,
- serviceName ? serviceName : "(null)",
- regtype ? regtype : "(null)",
- replyDomain ? replyDomain : "(null)",
- context);
+ serviceName, regtype, replyDomain, context);
/*
* Only process "add" data...
*/
get_device((cups_array_t *)context, name, type, domain);
- got_callback = 1;
}
break;
replyDomain);
#else /* HAVE_AVAHI */
avahi_service_name_join(fullName, kDNSServiceMaxDomainName,
- serviceName, regtype, replyDomain);
+ serviceName, regtype, replyDomain);
#endif /* HAVE_DNSSD */
free(device->fullName);
}
+#ifdef HAVE_AVAHI
+/*
+ * 'poll_callback()' - Wait for input on the specified file descriptors.
+ *
+ * Note: This function is needed because avahi_simple_poll_iterate is broken
+ * and always uses a timeout of 0 (!) milliseconds.
+ * (Avahi Ticket #364)
+ */
+
+static int /* O - Number of file descriptors matching */
+poll_callback(
+ struct pollfd *pollfds, /* I - File descriptors */
+ unsigned int num_pollfds, /* I - Number of file descriptors */
+ int timeout, /* I - Timeout in milliseconds (unused) */
+ void *context) /* I - User data (unused) */
+{
+ int val; /* Return value */
+
+
+ (void)timeout;
+ (void)context;
+
+ val = poll(pollfds, num_pollfds, 500);
+
+ if (val < 0)
+ fprintf(stderr, "DEBUG: poll_callback: %s\n", strerror(errno));
+ else if (val > 0)
+ got_data = 1;
+
+ return (val);
+}
+#endif /* HAVE_AVAHI */
+
+
#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
# ifdef HAVE_DNSSD
/*
value[256], /* Value string */
make_and_model[512], /* Manufacturer and model */
model[256], /* Model */
+ pdl[256], /* PDL */
device_id[2048]; /* 1284 device ID */
device_id[0] = '\0';
make_and_model[0] = '\0';
+ pdl[0] = '\0';
- strcpy(model, "Unknown");
+ strlcpy(model, "Unknown", sizeof(model));
for (data = rdata, dataend = data + rdlen;
data < dataend;
if (!_cups_strcasecmp(key, "usb_MFG") || !_cups_strcasecmp(key, "usb_MANU") ||
!_cups_strcasecmp(key, "usb_MANUFACTURER"))
- strcpy(make_and_model, value);
+ strlcpy(make_and_model, value, sizeof(make_and_model));
else if (!_cups_strcasecmp(key, "usb_MDL") || !_cups_strcasecmp(key, "usb_MODEL"))
- strcpy(model, value);
+ strlcpy(model, value, sizeof(model));
else if (!_cups_strcasecmp(key, "product") && !strstr(value, "Ghostscript"))
{
if (value[0] == '(')
if ((ptr = value + strlen(value) - 1) > value && *ptr == ')')
*ptr = '\0';
- strcpy(model, value + 1);
+ strlcpy(model, value + 1, sizeof(model));
}
else
- strcpy(model, value);
+ strlcpy(model, value, sizeof(model));
}
else if (!_cups_strcasecmp(key, "ty"))
{
- strcpy(model, value);
+ strlcpy(model, value, sizeof(model));
if ((ptr = strchr(model, ',')) != NULL)
*ptr = '\0';
}
+ else if (!_cups_strcasecmp(key, "pdl"))
+ strlcpy(pdl, value, sizeof(pdl));
else if (!_cups_strcasecmp(key, "priority"))
device->priority = atoi(value);
else if ((device->type == CUPS_DEVICE_IPP ||
}
}
+ if (device_id[0] &&
+ !strstr(device_id, "CMD:") &&
+ !strstr(device_id, "COMMAND SET:") &&
+ (strstr(pdl, "application/pdf") ||
+ strstr(pdl, "application/postscript") ||
+ strstr(pdl, "application/vnd.hp-PCL") ||
+ strstr(pdl, "image/")))
+ {
+ value[0] = '\0';
+ if (strstr(pdl, "application/pdf"))
+ strlcat(value, ",PDF", sizeof(value));
+ if (strstr(pdl, "application/postscript"))
+ strlcat(value, ",PS", sizeof(value));
+ if (strstr(pdl, "application/vnd.hp-PCL"))
+ strlcat(value, ",PCL", sizeof(value));
+ for (ptr = strstr(pdl, "image/"); ptr; ptr = strstr(ptr, "image/"))
+ {
+ char *valptr = value + strlen(value);
+ /* Pointer into value */
+
+ if (valptr < (value + sizeof(value) - 1))
+ *valptr++ = ',';
+
+ ptr += 6;
+ while (isalnum(*ptr & 255) || *ptr == '-' || *ptr == '.')
+ {
+ if (isalnum(*ptr & 255) && valptr < (value + sizeof(value) - 1))
+ *valptr++ = toupper(*ptr++ & 255);
+ else
+ break;
+ }
+
+ *valptr = '\0';
+ }
+
+ ptr = device_id + strlen(device_id);
+ snprintf(ptr, sizeof(device_id) - (ptr - device_id), "CMD:%s;",
+ value + 1);
+ }
+
if (device_id[0])
device->device_id = strdup(device_id);
else
}
else
device->make_and_model = strdup(model);
-
-# ifdef HAVE_AVAHI
- got_callback = 1;
-# endif /* HAVE_AVAHI */
}
#endif /* HAVE_DNSSD || HAVE_AVAHI */