]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Merge branch 'master' into ABI 674/head
authorMichael R Sweet <michael.r.sweet@gmail.com>
Tue, 2 Apr 2024 22:44:53 +0000 (18:44 -0400)
committerGitHub <noreply@github.com>
Tue, 2 Apr 2024 22:44:53 +0000 (18:44 -0400)
48 files changed:
1  2 
backend/dnssd.c
backend/ipp.c
backend/snmp.c
backend/usb-libusb.c
cgi-bin/admin.c
cgi-bin/help-index.c
cups/array.c
cups/dest-options.c
cups/dest.c
cups/ipp-support.c
cups/language.c
cups/libcups2.def
cups/ppd-cache.c
cups/ppd-conflicts.c
cups/ppd-emit.c
cups/ppd-localize.c
cups/ppd.c
cups/pwg-media.c
cups/string-private.h
cups/string.c
cups/testarray.c
notifier/rss.c
ppdc/ppdc.cxx
ppdc/ppdmerge.cxx
scheduler/auth.c
scheduler/auth.h
scheduler/banners.c
scheduler/client.c
scheduler/colorman.c
scheduler/cups-driverd.cxx
scheduler/cupsd.h
scheduler/cupsfilter.c
scheduler/filter.c
scheduler/job.c
scheduler/main.c
scheduler/mime.c
scheduler/network.c
scheduler/policy.c
scheduler/printers.c
scheduler/process.c
scheduler/quotas.c
scheduler/select.c
scheduler/subscriptions.c
scheduler/type.c
scheduler/util.h
tools/ippeveprinter.c
tools/ippfind.c
tools/ipptool.c

diff --cc backend/dnssd.c
Simple merge
diff --cc backend/ipp.c
Simple merge
diff --cc backend/snmp.c
Simple merge
Simple merge
diff --cc cgi-bin/admin.c
Simple merge
Simple merge
diff --cc cups/array.c
index f54e66485a977a893dac9fd3901f5c121d6d8958,2758a605acac42c1c4ba437318be72b3919168cf..f870cf66487be9c2c7b055c56734ebb0dc1d2927
@@@ -772,25 -809,26 +809,26 @@@ cupsArrayNew3(cups_array_cb_t  f,       // I 
  }
  
  
- /*
-  * '_cupsArrayNewStrings()' - Create a new array of comma-delimited strings.
-  *
-  * Note: The array automatically manages copies of the strings passed. If the
-  * string pointer "s" is NULL or the empty string, no strings are added to the
-  * newly created array.
-  */
- cups_array_t *                                /* O - Array */
- _cupsArrayNewStrings(const char *s,   /* I - Delimited strings or NULL */
-                      char       delim)        /* I - Delimiter character */
+ //
+ // 'cupsArrayNewStrings()' - Create a new array of delimited strings.
+ //
+ // This function creates a new array of strings that are delimited by the
+ // specified character.  The array automatically manages copies of the strings
+ // passed.  If the string pointer "s" is `NULL` or the empty string, no strings
+ // are added to the newly created array.
+ //
+ // @since CUPS 2.5@
+ //
+ cups_array_t *                                // O - Array
+ cupsArrayNewStrings(const char *s,    // I - Delimited strings or `NULL`
+                     char       delim) // I - Delimiter character
  {
-   cups_array_t        *a;                     /* Array */
+   cups_array_t        *a;                     // Array
  
  
-   if ((a = cupsArrayNew3((cups_array_func_t)_cupsArrayStrcmp, NULL, NULL, 0,
-                          (cups_acopy_func_t)_cupsStrPrivAlloc,
-                          (cups_afree_func_t)_cupsStrPrivFree)) != NULL)
-     _cupsArrayAddStrings(a, s, delim);
 -  if ((a = cupsArrayNew3((cups_array_cb_t)strcmp, NULL, NULL, 0, (cups_acopy_cb_t)_cupsStrAlloc, (cups_afree_cb_t)_cupsStrFree)) != NULL)
++  if ((a = cupsArrayNew3((cups_array_cb_t)strcmp, NULL, NULL, 0, (cups_acopy_cb_t)_cupsArrayStrdup, (cups_afree_cb_t)_cupsArrayFree)) != NULL)
+     cupsArrayAddStrings(a, s, delim);
  
    return (a);
  }
index 4555c10829a7ac4fbf02ec724b837731b7a55573,0ad969c78ae39747346c12cb6bdfa8633456f352..bac55fba25204b469d2c0010fb32fc16059ab336
@@@ -39,21 -39,12 +39,12 @@@ static void                cups_create_cached(http_t 
                                           unsigned flags);
  static void           cups_create_constraints(cups_dinfo_t *dinfo);
  static void           cups_create_defaults(cups_dinfo_t *dinfo);
- static void           cups_create_media_db(cups_dinfo_t *dinfo,
-                                            unsigned flags);
+ static void           cups_create_media_db(cups_dinfo_t *dinfo, unsigned flags);
 -static void           cups_free_media_db(_cups_media_db_t *mdb);
 +static void           cups_free_media_db(_cups_media_db_t *mdb, void *data);
- static int            cups_get_media_db(http_t *http, cups_dinfo_t *dinfo,
-                                         pwg_media_t *pwg, unsigned flags,
-                                         cups_size_t *size);
+ static int            cups_get_media_db(http_t *http, cups_dinfo_t *dinfo, pwg_media_t *pwg, unsigned flags, cups_size_t *size, cups_media_t *media);
  static int            cups_is_close_media_db(_cups_media_db_t *a,
                                               _cups_media_db_t *b);
- static cups_array_t   *cups_test_constraints(cups_dinfo_t *dinfo,
-                                              const char *new_option,
-                                              const char *new_value,
-                                              int num_options,
-                                              cups_option_t *options,
-                                              int *num_conflicts,
-                                              cups_option_t **conflicts);
+ static cups_array_t   *cups_test_constraints(cups_dinfo_t *dinfo, const char *new_option, const char *new_value, int num_options, cups_option_t *options, int *num_conflicts, cups_option_t **conflicts);
  static void           cups_update_ready(http_t *http, cups_dinfo_t *dinfo);
  
  
diff --cc cups/dest.c
index 416bd2ddc2fb205e859e69b4f11b6514d87b8a3b,9c589b0d0b20be4f20be0c8cc50692372d62336e..d406af2270c304e59480fb00896033559c3a32e4
@@@ -2575,143 -2480,42 +2480,46 @@@ cups_compare_dests(cups_dest_t *a,  // 
  }
  
  
- #ifdef HAVE_DNSSD
- #  ifdef HAVE_MDNSRESPONDER
- /*
-  * 'cups_dnssd_browse_cb()' - Browse for printers.
-  */
+ //
+ // 'cups_dest_browse_cb()' - Browse for printers.
+ //
  
  static void
- cups_dnssd_browse_cb(
-     DNSServiceRef       sdRef,                /* I - Service reference */
-     DNSServiceFlags     flags,                /* I - Option flags */
-     uint32_t            interfaceIndex,       /* I - Interface number */
-     DNSServiceErrorType errorCode,    /* I - Error, if any */
-     const char          *serviceName, /* I - Name of service/device */
-     const char          *regtype,     /* I - Type of service */
-     const char          *replyDomain, /* I - Service domain */
-     void                *context)     /* I - Enumeration data */
+ cups_dest_browse_cb(
+     cups_dnssd_browse_t *browse,      // I - DNS-SD browser
+     void                *context,     // I - Enumeration data
+     cups_dnssd_flags_t  flags,                // I - Flags
+     uint32_t            if_index,     // I - Interface
+     const char          *serviceName, // I - Name of service/device
+     const char          *regtype,     // I - Type of service
+     const char          *replyDomain) // I - Service domain
  {
    _cups_dnssd_data_t  *data = (_cups_dnssd_data_t *)context;
-                                       /* Enumeration data */
+                                       // Enumeration data
  
  
-   DEBUG_printf(("5cups_dnssd_browse_cb(sdRef=%p, flags=%x, interfaceIndex=%d, errorCode=%d, serviceName=\"%s\", regtype=\"%s\", replyDomain=\"%s\", context=%p)", (void *)sdRef, flags, interfaceIndex, errorCode, serviceName, regtype, replyDomain, context));
+   DEBUG_printf("5cups_dest_browse_cb(browse=%p, context=%p, flags=%x, if_index=%d, serviceName=\"%s\", regtype=\"%s\", replyDomain=\"%s\")", (void *)browse, context, flags, if_index, serviceName, regtype, replyDomain);
  
-  /*
-   * Don't do anything on error...
-   */
-   if (errorCode != kDNSServiceErr_NoError)
+   // Don't do anything on error, only add services...
+   if ((flags & CUPS_DNSSD_FLAGS_ERROR) || !(flags & CUPS_DNSSD_FLAGS_ADD))
      return;
  
-  /*
-   * Get the device...
-   */
+   // Get the device...
    cups_dnssd_get_device(data, serviceName, regtype, replyDomain);
  }
- #  else /* HAVE_AVAHI */
- /*
-  * 'cups_dnssd_browse_cb()' - Browse for printers.
-  */
- static void
- cups_dnssd_browse_cb(
-     AvahiServiceBrowser    *browser,  /* I - Browser */
-     AvahiIfIndex           interface, /* I - Interface index (unused) */
-     AvahiProtocol          protocol,  /* I - Network protocol (unused) */
-     AvahiBrowserEvent      event,     /* I - What happened */
-     const char             *name,     /* I - Service name */
-     const char             *type,     /* I - Registration type */
-     const char             *domain,   /* I - Domain */
-     AvahiLookupResultFlags flags,     /* I - Flags */
-     void                   *context)  /* I - Devices array */
- {
- #ifdef DEBUG
-   AvahiClient         *client = avahi_service_browser_get_client(browser);
-                                       /* Client information */
- #endif /* DEBUG */
-   _cups_dnssd_data_t  *data = (_cups_dnssd_data_t *)context;
-                                       /* Enumeration data */
-   (void)interface;
-   (void)protocol;
-   (void)context;
-   DEBUG_printf(("cups_dnssd_browse_cb(..., name=\"%s\", type=\"%s\", domain=\"%s\", ...);", name, type, domain));
-   switch (event)
-   {
-     case AVAHI_BROWSER_FAILURE:
-       DEBUG_printf(("cups_dnssd_browse_cb: %s", avahi_strerror(avahi_client_errno(client))));
-       avahi_simple_poll_quit(data->simple_poll);
-       break;
-     case AVAHI_BROWSER_NEW:
-        /*
-       * This object is new on the network.
-       */
-       cups_dnssd_get_device(data, name, type, domain);
-       break;
-     case AVAHI_BROWSER_REMOVE :
-     case AVAHI_BROWSER_CACHE_EXHAUSTED :
-         break;
-     case AVAHI_BROWSER_ALL_FOR_NOW :
-         DEBUG_puts("cups_dnssd_browse_cb: ALL_FOR_NOW");
-         data->browsers --;
-         break;
-   }
- }
- /*
-  * 'cups_dnssd_client_cb()' - Avahi client callback function.
-  */
- static void
- cups_dnssd_client_cb(
-     AvahiClient      *client,         /* I - Client information (unused) */
-     AvahiClientState state,           /* I - Current state */
-     void             *context)                /* I - User data (unused) */
- {
-   _cups_dnssd_data_t  *data = (_cups_dnssd_data_t *)context;
-                                       /* Enumeration data */
-   (void)client;
-   DEBUG_printf(("cups_dnssd_client_cb(client=%p, state=%d, context=%p)", client, state, context));
-  /*
-   * If the connection drops, quit.
-   */
-   if (state == AVAHI_CLIENT_FAILURE)
-   {
-     DEBUG_puts("cups_dnssd_client_cb: Avahi connection failed.");
-     avahi_simple_poll_quit(data->simple_poll);
-   }
- }
- #  endif /* HAVE_MDNSRESPONDER */
- /*
-  * 'cups_dnssd_compare_device()' - Compare two devices.
-  */
 +
 +
+ //
+ // 'cups_dnssd_compare_device()' - Compare two devices.
+ //
  
- static int /* O - Result of comparison */
- cups_dnssd_compare_devices(_cups_dnssd_device_t *a, /* I - First device */
-                            _cups_dnssd_device_t *b, /* I - Second device */
-                            void *data)              /* Unused */
+ static int                            // O - Result of comparison
+ cups_dnssd_compare_devices(
+     _cups_dnssd_device_t *a,          // I - First device
 -    _cups_dnssd_device_t *b)          // I - Second device
++    _cups_dnssd_device_t *b,          // I - Second device
++    void                 *data) // I - Callback data (unused)
  {
 +  (void)data;
    return (strcmp(a->dest.name, b->dest.name));
  }
  
Simple merge
diff --cc cups/language.c
index 6f5d6fcfa0d294dcb8de0f358ff6403db04be91f,44eae1a779dc31b6f9e96abbe56213cb4d46154c..1f44a73e37a24ed95a7714430f021be5dc3abddd
@@@ -131,23 -112,9 +112,10 @@@ static const char * const lang_encoding
   */
  
  
- #ifdef __APPLE__
- static const char     *appleLangDefault(void);
- #  ifdef CUPS_BUNDLEDIR
- #    ifndef CF_RETURNS_RETAINED
- #      if __has_feature(attribute_cf_returns_retained)
- #        define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
- #      else
- #        define CF_RETURNS_RETAINED
- #      endif /* __has_feature(attribute_cf_returns_retained) */
- #    endif /* !CF_RETURNED_RETAINED */
- static cups_array_t   *appleMessageLoad(const char *locale) CF_RETURNS_RETAINED;
- #  endif /* CUPS_BUNDLEDIR */
- #endif /* __APPLE__ */
  static cups_lang_t    *cups_cache_lookup(const char *name, cups_encoding_t encoding);
 -static int            cups_message_compare(_cups_message_t *m1, _cups_message_t *m2);
 -static void           cups_message_free(_cups_message_t *m);
 +static int            cups_message_compare(_cups_message_t *m1, _cups_message_t *m2,
 +                                void *data);
 +static void           cups_message_free(_cups_message_t *m, void *data);
  static void           cups_message_load(cups_lang_t *lang);
  static void           cups_message_puts(cups_file_t *fp, const char *s);
  static int            cups_read_strings(cups_file_t *fp, int flags, cups_array_t *a);
Simple merge
index 88decc7067c938226a984928103f245a59d57f14,ec0de56a72156d9722e2dfbd4ec9d50c362b1151..8be335b0847683be8e93960b6587b84107a3eb45
@@@ -3528,19 -3517,19 +3518,19 @@@ _ppdCreateFromIPP2
        y_dim      = ippFindAttribute(media_size, "y-dimension", IPP_TAG_INTEGER);
  
        if (x_dim && y_dim && (pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0))) != NULL)
-       strlcpy(ppdname, pwg->ppd, sizeof(ppdname));
+       cupsCopyString(ppdname, pwg->ppd, sizeof(ppdname));
        else
-       strlcpy(ppdname, "Unknown", sizeof(ppdname));
+       cupsCopyString(ppdname, "Unknown", sizeof(ppdname));
      }
      else
-       strlcpy(ppdname, "Unknown", sizeof(ppdname));
+       cupsCopyString(ppdname, "Unknown", sizeof(ppdname));
    }
    else if ((pwg = pwgMediaForPWG(ippGetString(ippFindAttribute(supported, "media-default", IPP_TAG_ZERO), 0, NULL))) != NULL)
-     strlcpy(ppdname, pwg->ppd, sizeof(ppdname));
+     cupsCopyString(ppdname, pwg->ppd, sizeof(ppdname));
    else
-     strlcpy(ppdname, "Unknown", sizeof(ppdname));
+     cupsCopyString(ppdname, "Unknown", sizeof(ppdname));
  
 -  sizes = cupsArrayNew3((cups_array_func_t)pwg_compare_sizes, NULL, NULL, 0, (cups_acopy_func_t)pwg_copy_size, (cups_afree_func_t)free);
 +  sizes = cupsArrayNew3((cups_array_func_t)pwg_compare_sizes, NULL, NULL, 0, (cups_acopy_func_t)pwg_copy_size, _cupsArrayFree);
  
    if ((attr = ippFindAttribute(supported, "media-col-database", IPP_TAG_BEGIN_COLLECTION)) != NULL)
    {
Simple merge
diff --cc cups/ppd-emit.c
Simple merge
Simple merge
diff --cc cups/ppd.c
Simple merge
Simple merge
index df5873c8ca214821f46350c4cf7d0d01872c60bf,e76d20d70c49ec59f0180a70be67c0dc53743bd8..6f9d35dbe358d06a796fd61ad325750b171a4ac1
@@@ -131,85 -118,25 +118,31 @@@ extern int _cups_isspace(int ch)
  extern int _cups_isupper(int ch);
  extern int _cups_tolower(int ch);
  extern int _cups_toupper(int ch);
- #  endif /* _CUPS_INLINE */
+ #  endif // _CUPS_INLINE
  
  
- /*
 * Prototypes...
 */
+ //
// Functions...
//
  
- extern ssize_t        _cups_safe_vsnprintf(char *buffer, size_t bufsize, const char *format, va_list args) _CUPS_PRIVATE;
  extern void   _cups_strcpy(char *dst, const char *src) _CUPS_PRIVATE;
- #  ifndef HAVE_STRDUP
- extern char   *_cups_strdup(const char *) _CUPS_PRIVATE;
- #    define strdup _cups_strdup
- #  endif /* !HAVE_STRDUP */
  extern int    _cups_strcasecmp(const char *, const char *) _CUPS_PRIVATE;
  extern int    _cups_strncasecmp(const char *, const char *, size_t n) _CUPS_PRIVATE;
- #  ifndef HAVE_STRLCAT
- extern size_t _cups_strlcat(char *, const char *, size_t) _CUPS_PRIVATE;
- #    define strlcat _cups_strlcat
- #  endif /* !HAVE_STRLCAT */
- #  ifndef HAVE_STRLCPY
- extern size_t _cups_strlcpy(char *, const char *, size_t) _CUPS_PRIVATE;
- #    define strlcpy _cups_strlcpy
- #  endif /* !HAVE_STRLCPY */
- #  ifndef HAVE_SNPRINTF
- extern int    _cups_snprintf(char *, size_t, const char *, ...) _CUPS_FORMAT(3, 4) _CUPS_PRIVATE;
- #    define snprintf _cups_snprintf
- #  endif /* !HAVE_SNPRINTF */
- #  ifndef HAVE_VSNPRINTF
- extern int    _cups_vsnprintf(char *, size_t, const char *, va_list) _CUPS_PRIVATE;
- #    define vsnprintf _cups_vsnprintf
- #  endif /* !HAVE_VSNPRINTF */
- /*
-  * String pool functions...
-  */
 +
++extern int _cupsArrayStrcasecmp(const char *s, const char *t, void *data) _CUPS_PRIVATE;
++extern int _cupsArrayStrcmp(const char *s1, const char *s2, void *data) _CUPS_PRIVATE;
++extern char *_cupsArrayStrdup(const char *element, void *data) _CUPS_PRIVATE;
++extern void _cupsArrayFree(void *element, void *data) _CUPS_PRIVATE;
 +
  extern char   *_cupsStrAlloc(const char *s) _CUPS_PRIVATE;
+ extern char   *_cupsStrDate(char *buf, size_t bufsize, time_t timeval) _CUPS_PRIVATE;
  extern void   _cupsStrFlush(void) _CUPS_PRIVATE;
+ extern char   *_cupsStrFormatd(char *buf, char *bufend, double number, struct lconv *loc) _CUPS_PRIVATE;
  extern void   _cupsStrFree(const char *s) _CUPS_PRIVATE;
  extern char   *_cupsStrRetain(const char *s) _CUPS_PRIVATE;
+ extern double _cupsStrScand(const char *buf, char **bufptr, struct lconv *loc) _CUPS_PRIVATE;
  extern size_t _cupsStrStatistics(size_t *alloc_bytes, size_t *total_bytes) _CUPS_PRIVATE;
  
- extern char *_cupsStrPrivAlloc(const char *s, void *data) _CUPS_PRIVATE;
- extern void _cupsStrPrivFree(const char *s, void *data) _CUPS_PRIVATE;
- /*
-  * Floating point number functions...
-  */
- extern char   *_cupsStrFormatd(char *buf, char *bufend, double number,
-                                struct lconv *loc) _CUPS_PRIVATE;
- extern double _cupsStrScand(const char *buf, char **bufptr,
-                             struct lconv *loc) _CUPS_PRIVATE;
- /*
-  * Date function...
-  */
- extern char   *_cupsStrDate(char *buf, size_t bufsize, time_t timeval) _CUPS_PRIVATE;
- extern int _cupsArrayStrcmp(const char *s1, const char *s2, void *data) _CUPS_PRIVATE;
- extern int _cupsArrayStrcasecmp(const char *s, const char *t, void *data) _CUPS_PRIVATE;
- extern char *_cupsArrayStrdup(const char *element, void *data) _CUPS_PRIVATE;
- extern void _cupsArrayFree(void *element, void *data) _CUPS_PRIVATE;
- /*
-  * C++ magic...
-  */
  
  #  ifdef __cplusplus
  }
diff --cc cups/string.c
index 770616cf521bc3a0dd35d9904244b40a866e8fe5,22b0ef555e2988597eb91bedf36080126cdeec8a..fac91560fe7f4e07654a9ccfe10dfd6d8790fdb8
@@@ -34,7 -30,476 +30,476 @@@ static cups_array_t       *stringpool = NULL
   * Local functions...
   */
  
 -static int    compare_sp_items(_cups_sp_item_t *a, _cups_sp_item_t *b);
 +static int compare_sp_items(_cups_sp_item_t *a, _cups_sp_item_t *b, void *data);
+ static void   validate_end(char *s, char *end);
+ //
+ // 'cupsConcatString()' - Safely concatenate two UTF-8 strings.
+ //
+ // @since CUPS 2.5@
+ //
+ size_t                                        // O - Length of string
+ cupsConcatString(char       *dst,     // O - Destination string
+                  const char *src,     // I - Source string
+                size_t     dstsize)    // I - Size of destination string buffer
+ {
+   size_t      srclen;                 // Length of source string
+   size_t      dstlen;                 // Length of destination string
+   // Range check input...
+   if (!dst || !src || dstsize == 0)
+     return (0);
+   // Figure out how much room is left...
+   dstlen = strlen(dst);
+   if (dstsize < (dstlen + 1))
+     return (dstlen);                  // No room, return immediately...
+   dstsize -= dstlen + 1;
+   // Figure out how much room is needed...
+   srclen = strlen(src);
+   // Copy the appropriate amount...
+   if (srclen <= dstsize)
+   {
+     // String fits, just copy over...
+     memmove(dst + dstlen, src, srclen);
+     dst[dstlen + srclen] = '\0';
+   }
+   else
+   {
+     // String too big, copy what we can and clean up the end...
+     memmove(dst + dstlen, src, dstsize);
+     dst[dstlen + dstsize] = '\0';
+     validate_end(dst, dst + dstlen + dstsize);
+   }
+   return (dstlen + srclen);
+ }
+ //
+ // 'cupsCopyString()' - Safely copy a UTF-8 string.
+ //
+ // @since CUPS 2.5@
+ //
+ size_t                                        // O - Length of string
+ cupsCopyString(char       *dst,               // O - Destination string
+                const char *src,               // I - Source string
+              size_t     dstsize)      // I - Size of destination string buffer
+ {
+   size_t      srclen;                 // Length of source string
+   // Range check input...
+   if (!dst || !src || dstsize == 0)
+   {
+     if (dst)
+       *dst = '\0';
+     return (0);
+   }
+   // Figure out how much room is needed...
+   dstsize --;
+   srclen = strlen(src);
+   // Copy the appropriate amount...
+   if (srclen <= dstsize)
+   {
+     // Source string will fit...
+     memmove(dst, src, srclen);
+     dst[srclen] = '\0';
+   }
+   else
+   {
+     // Source string too big, copy what we can and clean up the end...
+     memmove(dst, src, dstsize);
+     dst[dstsize] = '\0';
+     validate_end(dst, dst + dstsize);
+   }
+   return (srclen);
+ }
+ //
+ // 'cupsFormatString()' - Format a UTF-8 string into a fixed size buffer.
+ //
+ // This function formats a UTF-8 string into a fixed size buffer, escaping
+ // special/control characters as needed so they can be safely displayed or
+ // logged.
+ //
+ // @since CUPS 2.5@
+ //
+ ssize_t                                       // O - Number of bytes formatted
+ cupsFormatString(
+     char       *buffer,                       // O - Output buffer
+     size_t     bufsize,                       // O - Size of output buffer
+     const char *format,                       // I - `printf`-style format string
+     ...)                              // I - Additional arguments
+ {
+   va_list     ap;                     // Pointer to additional arguments
+   ssize_t     ret;                    // Return value
+   // Range check input...
+   if (!buffer || bufsize < 2 || !format)
+     return (-1);
+   // Format the string...
+   va_start(ap, format);
+   ret = cupsFormatStringv(buffer, bufsize, format, ap);
+   va_end(ap);
+   // Return the number of bytes that could have been written...
+   return (ret);
+ }
+ //
+ // 'cupsFormatStringv()' - Format a UTF-8 string into a fixed size buffer (`va_list` version).
+ //
+ // This function formats a UTF-8 string into a fixed size buffer using a
+ // variable argument pointer, escaping special/control characters as needed so
+ // they can be safely displayed or logged.
+ //
+ // @since CUPS 2.5@
+ //
+ ssize_t                                       // O - Number of bytes formatted
+ cupsFormatStringv(
+     char       *buffer,                       // O - Output buffer
+     size_t     bufsize,                       // O - Size of output buffer
+     const char *format,                       // I - printf-style format string
+     va_list    ap)                    // I - Pointer to additional arguments
+ {
+   char                *bufptr,                // Pointer to position in buffer
+               *bufend,                // Pointer to end of buffer
+               size,                   // Size character (h, l, L)
+               type;                   // Format type character
+   int         width,                  // Width of field
+               prec;                   // Number of characters of precision
+   char                tformat[100],           // Temporary format string for snprintf()
+               *tptr,                  // Pointer into temporary format
+               temp[1024];             // Buffer for formatted numbers
+   char                *s;                     // Pointer to string
+   ssize_t     bytes;                  // Total number of bytes needed
+   // Range check input...
+   if (!buffer || bufsize < 2 || !format)
+     return (-1);
+   // Loop through the format string, formatting as needed...
+   bufptr = buffer;
+   bufend = buffer + bufsize - 1;
+   bytes  = 0;
+   while (*format)
+   {
+     if (*format == '%')
+     {
+       // Format character...
+       tptr = tformat;
+       *tptr++ = *format++;
+       if (*format == '%')
+       {
+         if (bufptr < bufend)
+         *bufptr++ = *format;
+         bytes ++;
+         format ++;
+       continue;
+       }
+       else if (strchr(" -+#\'", *format))
+       {
+         *tptr++ = *format++;
+       }
+       if (*format == '*')
+       {
+         // Get width from argument...
+       format ++;
+       width = va_arg(ap, int);
+       snprintf(tptr, sizeof(tformat) - (size_t)(tptr - tformat), "%d", width);
+       tptr += strlen(tptr);
+       }
+       else
+       {
+       width = 0;
+       while (isdigit(*format & 255))
+       {
+         if (tptr < (tformat + sizeof(tformat) - 1))
+           *tptr++ = *format;
+         width = width * 10 + *format++ - '0';
+       }
+       }
+       if (*format == '.')
+       {
+       if (tptr < (tformat + sizeof(tformat) - 1))
+         *tptr++ = *format;
+         format ++;
+         if (*format == '*')
+       {
+           // Get precision from argument...
+         format ++;
+         prec = va_arg(ap, int);
+         snprintf(tptr, sizeof(tformat) - (size_t)(tptr - tformat), "%d", prec);
+         tptr += strlen(tptr);
+       }
+       else
+       {
+         prec = 0;
+         while (isdigit(*format & 255))
+         {
+           if (tptr < (tformat + sizeof(tformat) - 1))
+             *tptr++ = *format;
+           prec = prec * 10 + *format++ - '0';
+         }
+       }
+       }
+       if (*format == 'l' && format[1] == 'l')
+       {
+         size = 'L';
+       if (tptr < (tformat + sizeof(tformat) - 2))
+       {
+         *tptr++ = 'l';
+         *tptr++ = 'l';
+       }
+       format += 2;
+       }
+       else if (*format == 'h' || *format == 'l' || *format == 'L')
+       {
+       if (tptr < (tformat + sizeof(tformat) - 1))
+         *tptr++ = *format;
+         size = *format++;
+       }
+       else
+       {
+         size = 0;
+       }
+       if (!*format)
+         break;
+       if (tptr < (tformat + sizeof(tformat) - 1))
+         *tptr++ = *format;
+       type  = *format++;
+       *tptr = '\0';
+       switch (type)
+       {
+       case 'E' : // Floating point formats
+       case 'G' :
+       case 'e' :
+       case 'f' :
+       case 'g' :
+           if ((size_t)(width + 2) > sizeof(temp))
+             break;
+           snprintf(temp, sizeof(temp), tformat, va_arg(ap, double));
+             bytes += (int)strlen(temp);
+             if (bufptr < bufend)
+           {
+             cupsCopyString(bufptr, temp, (size_t)(bufend - bufptr));
+             bufptr += strlen(bufptr);
+           }
+           break;
+         case 'B' : // Integer formats
+       case 'X' :
+       case 'b' :
+         case 'd' :
+       case 'i' :
+       case 'o' :
+       case 'u' :
+       case 'x' :
+           if ((size_t)(width + 2) > sizeof(temp))
+             break;
+ #  ifdef HAVE_LONG_LONG
+             if (size == 'L')
+             snprintf(temp, sizeof(temp), tformat, va_arg(ap, long long));
+           else
+ #  endif // HAVE_LONG_LONG
+             if (size == 'l')
+             snprintf(temp, sizeof(temp), tformat, va_arg(ap, long));
+           else
+             snprintf(temp, sizeof(temp), tformat, va_arg(ap, int));
+             bytes += (int)strlen(temp);
+           if (bufptr < bufend)
+           {
+             cupsCopyString(bufptr, temp, (size_t)(bufend - bufptr));
+             bufptr += strlen(bufptr);
+           }
+           break;
+       case 'p' : // Pointer value
+           if ((size_t)(width + 2) > sizeof(temp))
+             break;
+           snprintf(temp, sizeof(temp), tformat, va_arg(ap, void *));
+             bytes += (int)strlen(temp);
+           if (bufptr < bufend)
+           {
+             cupsCopyString(bufptr, temp, (size_t)(bufend - bufptr));
+             bufptr += strlen(bufptr);
+           }
+           break;
+         case 'c' : // Character or character array
+           bytes += width;
+           if (bufptr < bufend)
+           {
+             if (width <= 1)
+             {
+               *bufptr++ = (char)va_arg(ap, int);
+             }
+             else
+             {
+               if ((bufptr + width) > bufend)
+                 width = (int)(bufend - bufptr);
+               memcpy(bufptr, va_arg(ap, char *), (size_t)width);
+               bufptr += width;
+             }
+           }
+           break;
+       case 's' : // String
+           if ((s = va_arg(ap, char *)) == NULL)
+             s = "(null)";
+             // Copy the C string, replacing control chars and \ with C character escapes...
+             for (; *s && bufptr < bufend; s ++)
+           {
+             if (*s == '\n')
+             {
+               *bufptr++ = '\\';
+               if (bufptr < bufend)
+                 *bufptr++ = 'n';
+               bytes += 2;
+             }
+             else if (*s == '\r')
+             {
+               *bufptr++ = '\\';
+               if (bufptr < bufend)
+                 *bufptr++ = 'r';
+               bytes += 2;
+             }
+             else if (*s == '\t')
+             {
+               *bufptr++ = '\\';
+               if (bufptr < bufend)
+                 *bufptr++ = 't';
+               bytes += 2;
+             }
+             else if (*s == '\\')
+             {
+               *bufptr++ = '\\';
+               if (bufptr < bufend)
+                 *bufptr++ = '\\';
+               bytes += 2;
+             }
+             else if (*s == '\'')
+             {
+               *bufptr++ = '\\';
+               if (bufptr < bufend)
+                 *bufptr++ = '\'';
+               bytes += 2;
+             }
+             else if (*s == '\"')
+             {
+               *bufptr++ = '\\';
+               if (bufptr < bufend)
+                 *bufptr++ = '\"';
+               bytes += 2;
+             }
+             else if ((*s & 255) < ' ')
+             {
+               *bufptr++ = '\\';
+               if (bufptr < bufend)
+                 *bufptr++ = '0';
+               if (bufptr < bufend)
+                 *bufptr++ = '0' + *s / 8;
+               if (bufptr < bufend)
+                 *bufptr++ = '0' + (*s & 7);
+               bytes += 4;
+             }
+             else
+             {
+               *bufptr++ = *s;
+               bytes ++;
+             }
+             }
+             if (bufptr >= bufend)
+             bytes += 2 * strlen(s);
+           break;
+       case 'n' : // Output number of chars so far
+           *(va_arg(ap, int *)) = (int)bytes;
+           break;
+       }
+     }
+     else
+     {
+       // Literal character...
+       bytes ++;
+       if (bufptr < bufend)
+         *bufptr++ = *format++;
+     }
+   }
+   // Nul-terminate the string and return the number of characters needed.
+   if (bufptr < bufend)
+   {
+     // Everything fit in the buffer...
+     *bufptr = '\0';
+   }
+   else
+   {
+     // Make sure the last characters are valid UTF-8...
+     *bufend = '\0';
+     validate_end(buffer, bufend);
+   }
+   return (bytes);
+ }
  
  /*
   * '_cupsStrAlloc()' - Allocate/reference a string.
@@@ -646,15 -1055,11 +1055,16 @@@ int                           /* O - Result of comparison (-1
  _cups_strcasecmp(const char *s,       /* I - First string */
                   const char *t)       /* I - Second string */
  {
-   char u, v;
++  int diff;
++
++
    while (*s != '\0' && *t != '\0')
    {
-     u = _cups_tolower(*s);
-     v = _cups_tolower(*t);
 -    if (_cups_tolower(*s) < _cups_tolower(*t))
++    diff = _cups_tolower(*s) - _cups_tolower(*t);
 +
-     if (u < v)
++    if (diff < 0)
        return (-1);
-     else if (u > v)
 -    else if (_cups_tolower(*s) > _cups_tolower(*t))
++    else if (diff > 0)
        return (1);
  
      s ++;
@@@ -679,14 -1083,11 +1089,15 @@@ _cups_strncasecmp(const char *s,      /* I 
                    const char *t,      /* I - Second string */
                  size_t     n)         /* I - Maximum number of characters to compare */
  {
-   char u, v;
++  int diff;
++
++
    while (*s != '\0' && *t != '\0' && n > 0)
    {
-     u = _cups_tolower(*s);
-     v = _cups_tolower(*t);
-     if (u < v)
 -    if (_cups_tolower(*s) < _cups_tolower(*t))
++    diff = _cups_tolower(*s) - _cups_tolower(*t);
++    if (diff < 0)
        return (-1);
-     else if (u > v)
 -    else if (_cups_tolower(*s) > _cups_tolower(*t))
++    else if (diff > 0)
        return (1);
  
      s ++;
  }
  
  
- #ifndef HAVE_STRLCAT
  /*
-  * '_cups_strlcat()' - Safely concatenate two strings.
+  * 'compare_sp_items()' - Compare two string pool items...
   */
  
- size_t                                        /* O - Length of string */
- _cups_strlcat(char       *dst,                /* O - Destination string */
-               const char *src,                /* I - Source string */
-             size_t     size)          /* I - Size of destination string buffer */
+ static int                            /* O - Result of comparison */
+ compare_sp_items(_cups_sp_item_t *a,  /* I - First item */
 -                 _cups_sp_item_t *b)  /* I - Second item */
++                 _cups_sp_item_t *b,  /* I - Second item */
++                 void            *data)         /* I - Unused */
  {
-   size_t      srclen;                 /* Length of source string */
-   size_t      dstlen;                 /* Length of destination string */
-  /*
-   * Figure out how much room is left...
-   */
-   dstlen = strlen(dst);
-   if (size < (dstlen + 1))
-     return (dstlen);                  /* No room, return immediately... */
-   size -= dstlen + 1;
-  /*
-   * Figure out how much room is needed...
-   */
-   srclen = strlen(src);
-  /*
-   * Copy the appropriate amount...
-   */
-   if (srclen > size)
-     srclen = size;
-   memmove(dst + dstlen, src, srclen);
-   dst[dstlen + srclen] = '\0';
-   return (dstlen + srclen);
 -  return (strcmp(a->str, b->str));
++  (void)data;
++ 
++ return (strcmp(a->str, b->str));
  }
- #endif /* !HAVE_STRLCAT */
  
  
- #ifndef HAVE_STRLCPY
- /*
-  * '_cups_strlcpy()' - Safely copy two strings.
-  */
+ //
+ // 'validate_end()' - Validate the last UTF-8 character in a buffer.
+ //
  
- size_t                                        /* O - Length of string */
- _cups_strlcpy(char       *dst,                /* O - Destination string */
-               const char *src,                /* I - Source string */
-             size_t      size)         /* I - Size of destination string buffer */
+ static void
+ validate_end(char *s,                 // I - Pointer to start of string
+              char *end)                       // I - Pointer to end of string
  {
-   size_t      srclen;                 /* Length of source string */
+   char *ptr = end - 1;                        // Pointer into string
  
  
-   if (size == 0)
-     return (0);
-  /*
-   * Figure out how much room is needed...
-   */
-   size --;
-   srclen = strlen(src);
-  /*
-   * Copy the appropriate amount...
-   */
-   if (srclen > size)
-     srclen = size;
-   memmove(dst, src, srclen);
-   dst[srclen] = '\0';
-   return (srclen);
- }
- #endif /* !HAVE_STRLCPY */
- /*
-  * 'compare_sp_items()' - Compare two string pool items...
-  */
+   if (ptr > s && *ptr & 0x80)
+   {
+     while ((*ptr & 0xc0) == 0x80 && ptr > s)
+       ptr --;
  
- static int                           /* O - Result of comparison */
- compare_sp_items(_cups_sp_item_t *a, /* I - First item */
-                  _cups_sp_item_t *b, /* I - Second item */
-                  void *data)         /* Unused */
- {
-   (void)data;
-   return (strcmp(a->str, b->str));
+     if ((*ptr & 0xe0) == 0xc0)
+     {
+       // Verify 2-byte UTF-8 sequence...
+       if ((end - ptr) != 2)
+         *ptr = '\0';
+     }
+     else if ((*ptr & 0xf0) == 0xe0)
+     {
+       // Verify 3-byte UTF-8 sequence...
+       if ((end - ptr) != 3)
+         *ptr = '\0';
+     }
+     else if ((*ptr & 0xf8) == 0xf0)
+     {
+       // Verify 4-byte UTF-8 sequence...
+       if ((end - ptr) != 4)
+         *ptr = '\0';
+     }
+     else if (*ptr & 0x80)
+     {
+       // Invalid sequence at end...
+       *ptr = '\0';
+     }
+   }
  }
- int _cupsArrayStrcasecmp(const char *s, /* I - First string */
 +
 +
 +/*
 + * '_cupsArrayStrcasecmp()' - Compare two strings...
 + */
 +
-                          void *data)    /* Unused */
++int /* O - Result of comparison */
++_cupsArrayStrcasecmp(const char *s, /* I - First string */
 +                         const char *t, /* I - Second string */
-   return _cups_strcasecmp(s, t);
++                         void *data)    /* I - Unused */
 +{
 +  (void)data;
++  return (_cups_strcasecmp(s, t));
 +}
index a224fce85e01087b3a598427dfe5b9ef9e229eec,864376b2191c2c141d380d4d6dcee815c1e6e12f..d5270b2769c8a3f3bc9de3293d8750eb14fa0bc2
@@@ -25,47 -24,43 +24,43 @@@ static double      get_seconds(void)
  static int    load_words(const char *filename, cups_array_t *array);
  
  
- /*
 * 'main()' - Main entry.
 */
+ //
// 'main()' - Main entry.
//
  
- int                                   /* O - Exit status */
+ int                                   // O - Exit status
  main(void)
  {
-   int         i;                      /* Looping var */
-   cups_array_t        *array,                 /* Test array */
-               *dup_array;             /* Duplicate array */
-   int         status;                 /* Exit status */
-   char                *text;                  /* Text from array */
-   char                word[256];              /* Word from file */
-   double      start,                  /* Start time */
-               end;                    /* End time */
-   cups_dir_t  *dir;                   /* Current directory */
-   cups_dentry_t       *dent;                  /* Directory entry */
-   char                *saved[32];             /* Saved entries */
-   void                *data;                  /* User data for arrays */
-  /*
-   * No errors so far...
-   */
+   int         i;                      // Looping var
+   cups_array_t        *array,                 // Test array
+               *dup_array;             // Duplicate array
+   int         status;                 // Exit status
+   char                *text;                  // Text from array
+   char                word[256];              // Word from file
+   double      start,                  // Start time
+               end;                    // End time
+   cups_dir_t  *dir;                   // Current directory
+   cups_dentry_t       *dent;                  // Directory entry
+   char                *saved[32];             // Saved entries
+   void                *data;                  // User data for arrays
+   // No errors so far...
    status = 0;
  
-  /*
-   * cupsArrayNew()
-   */
-   fputs("cupsArrayNew: ", stdout);
+   // cupsArrayNew()
+   testBegin("cupsArrayNew3");
  
    data  = (void *)"testarray";
-   array = cupsArrayNew((cups_array_func_t)_cupsArrayStrcmp, data);
 -  array = cupsArrayNew3((cups_array_cb_t)strcmp, data, NULL, 0, (cups_acopy_cb_t)strdup, (cups_afree_cb_t)free);
++  array = cupsArrayNew3((cups_array_func_t)_cupsArrayStrcmp, data, NULL, 0, (cups_acopy_cb_t)_cupsArrayStrdup, (cups_afree_cb_t)_cupsArrayFree);
  
    if (array)
-     puts("PASS");
+   {
+     testEnd(true);
+   }
    else
    {
-     puts("FAIL (returned NULL, expected pointer)");
+     testEndMessage(false, "returned NULL, expected pointer");
      status ++;
    }
  
diff --cc notifier/rss.c
Simple merge
diff --cc ppdc/ppdc.cxx
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 90731441dc881760083472f2a825b583b0518b63,1173d2bb4c7f1df93c588fdcfabd4e1f401ee8d9..62ac21c69812bbc1bc732a886c7cf677fb41e9aa
  
  static int            check_if_modified(cupsd_client_t *con,
                                          struct stat *filestats);
--static int            compare_clients(cupsd_client_t *a, cupsd_client_t *b,
-                               void *data);
- #ifdef HAVE_TLS
 -                                      void *data);
++static int            compare_clients(cupsd_client_t *a, cupsd_client_t *b, void *data);
  static int            cupsd_start_tls(cupsd_client_t *con, http_encryption_t e);
- #endif /* HAVE_TLS */
  static char           *get_file(cupsd_client_t *con, struct stat *filestats,
 -                                char *filename, size_t len);
 +                        char *filename, size_t len);
  static http_status_t  install_cupsd_conf(cupsd_client_t *con);
  static int            is_cgi(cupsd_client_t *con, const char *filename,
 -                             struct stat *filestats, mime_type_t *type);
 +                    struct stat *filestats, mime_type_t *type);
  static int            is_path_absolute(const char *path);
  static int            pipe_command(cupsd_client_t *con, int infile, int *outfile,
 -                                   char *command, char *options, int root);
 +                           char *command, char *options, int root);
  static int            valid_host(cupsd_client_t *con);
  static int            write_file(cupsd_client_t *con, http_status_t code,
 -                                 char *filename, char *type,
 -                                 struct stat *filestats);
 +                         char *filename, char *type,
 +                         struct stat *filestats);
  static void           write_pipe(cupsd_client_t *con);
  
  
Simple merge
index 28eea0da935b68a9d0904e837231c5c5b15e8078,7d17b94c9dab4a3c909bff97ad44e49df248319e..0d0f1f1e2391287e174faf0d9fbd6f0cd6792701
@@@ -155,36 -145,21 +145,21 @@@ static int              cat_drv(const char *name, i
  static void           cat_ppd(const char *name, int request_id) _CUPS_NORETURN;
  static int            cat_static(const char *name, int request_id);
  static int            cat_tar(const char *name, int request_id);
 -static int            compare_inodes(struct stat *a, struct stat *b);
 -static int            compare_matches(const ppd_info_t *p0, const ppd_info_t *p1);
 -static int            compare_names(const ppd_info_t *p0, const ppd_info_t *p1);
 -static int            compare_ppds(const ppd_info_t *p0, const ppd_info_t *p1);
 +static int            compare_inodes(struct stat *a, struct stat *b, void *data);
- static int            compare_matches(const ppd_info_t *p0,
-                               const ppd_info_t *p1,
-                               void *data);
- static int            compare_names(const ppd_info_t *p0,
-                             const ppd_info_t *p1,
-                             void *data);
- static int            compare_ppds(const ppd_info_t *p0,
-                            const ppd_info_t *p1,
-                            void *data);
++static int            compare_matches(const ppd_info_t *p0, const ppd_info_t *p1, void *data);
++static int            compare_names(const ppd_info_t *p0, const ppd_info_t *p1, void *data);
++static int            compare_ppds(const ppd_info_t *p0, const ppd_info_t *p1, void *data);
  static void           dump_ppds_dat(const char *filename) _CUPS_NORETURN;
  static void           free_array(cups_array_t *a);
- static cups_file_t    *get_file(const char *name, int request_id,
-                                 const char *subdir, char *buffer,
-                                 size_t bufsize, char **subfile);
+ static cups_file_t    *get_file(const char *name, int request_id, const char *subdir, char *buffer, size_t bufsize, char **subfile);
  static void           list_ppds(int request_id, int limit, const char *opt) _CUPS_NORETURN;
- static int            load_drivers(cups_array_t *include,
-                                    cups_array_t *exclude);
- static int            load_drv(const char *filename, const char *name,
-                                cups_file_t *fp, time_t mtime, off_t size);
- static void           load_ppd(const char *filename, const char *name,
-                                const char *scheme, struct stat *fileinfo,
-                                ppd_info_t *ppd, cups_file_t *fp, off_t end);
+ static int            load_drivers(cups_array_t *include, cups_array_t *exclude);
+ static int            load_drv(const char *filename, const char *name, cups_file_t *fp, time_t mtime, off_t size);
+ static void           load_ppd(const char *filename, const char *name, const char *scheme, struct stat *fileinfo, ppd_info_t *ppd, cups_file_t *fp, off_t end);
  static int            load_ppds(const char *d, const char *p, int descend);
- static void           load_ppds_dat(char *filename, size_t filesize,
-                                     int verbose);
- static int            load_tar(const char *filename, const char *name,
-                                cups_file_t *fp, time_t mtime, off_t size);
- static int            read_tar(cups_file_t *fp, char *name, size_t namesize,
-                                struct stat *info);
+ static void           load_ppds_dat(char *filename, size_t filesize, int verbose);
+ static int            load_tar(const char *filename, const char *name, cups_file_t *fp, time_t mtime, off_t size);
+ static int            read_tar(cups_file_t *fp, char *name, size_t namesize, struct stat *info);
  static regex_t                *regex_device_id(const char *device_id);
  static regex_t                *regex_string(const char *s);
  
@@@ -700,17 -680,14 +680,17 @@@ cat_tar(const char *name,               // I - PPD n
  }
  
  
- /*
 * 'compare_inodes()' - Compare two inodes.
 */
+ //
// 'compare_inodes()' - Compare two inodes.
//
  
 -static int                            // O - Result of comparison
 -compare_inodes(struct stat *a,                // I - First inode
 -               struct stat *b)                // I - Second inode
 +static int                     /* O - Result of comparison */
 +compare_inodes(struct stat *a, /* I - First inode */
 +               struct stat *b, /* I - Second inode */
-                void *data)     /* Unused */
++               void *data)     /* I - Unused */
  {
 +  (void)data;
 +
    if (a->st_dev != b->st_dev)
      return (a->st_dev - b->st_dev);
    else
  }
  
  
- /*
 * 'compare_matches()' - Compare PPD match scores for sorting.
 */
+ //
// 'compare_matches()' - Compare PPD match scores for sorting.
//
  
 -static int
 -compare_matches(const ppd_info_t *p0, // I - First PPD
 -                const ppd_info_t *p1) // I - Second PPD
 +static int compare_matches(const ppd_info_t *p0, /* I - First PPD */
 +                           const ppd_info_t *p1, /* I - Second PPD */
-                            void *data)           /* Unused */
++                           void             *data)           /* I - Unused */
  {
 +  (void)data;
 +
    if (p1->matches != p0->matches)
      return (p1->matches - p0->matches);
    else
  }
  
  
- /*
 * 'compare_names()' - Compare PPD filenames for sorting.
 */
+ //
// 'compare_names()' - Compare PPD filenames for sorting.
//
  
 -static int                            // O - Result of comparison
 -compare_names(const ppd_info_t *p0,   // I - First PPD file
 -              const ppd_info_t *p1)   // I - Second PPD file
 +static int                          /* O - Result of comparison */
 +compare_names(const ppd_info_t *p0, /* I - First PPD file */
 +              const ppd_info_t *p1, /* I - Second PPD file */
-               void *data)           /* Unused */
++              void             *data)           /* I - Unused */
  {
-   int diff;                           /* Difference between strings */
+   int diff;                           // Difference between strings
  
 +  (void)data;
  
    if ((diff = strcmp(p0->record.filename, p1->record.filename)) != 0)
      return (diff);
  }
  
  
- /*
 * 'compare_ppds()' - Compare PPD file make and model names for sorting.
 */
+ //
// 'compare_ppds()' - Compare PPD file make and model names for sorting.
//
  
 -static int                            // O - Result of comparison
 -compare_ppds(const ppd_info_t *p0,    // I - First PPD file
 -             const ppd_info_t *p1)    // I - Second PPD file
 +static int                         /* O - Result of comparison */
 +compare_ppds(const ppd_info_t *p0, /* I - First PPD file */
 +             const ppd_info_t *p1, /* I - Second PPD file */
-              void *data)           /* Unused */
++             void             *data)           /* I - Unused */
  {
-   int diff;                           /* Difference between strings */
+   int diff;                           // Difference between strings
  
  
   /*
Simple merge
Simple merge
Simple merge
diff --cc scheduler/job.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 3079f3d52b444b352837150dd66f99ff1538dcd4,d3a8e36f4f76fe416de35ea751113459aff6e572..9852e59be42800bd868dba3f9c9beebfd290a0e5
@@@ -192,32 -178,13 +178,13 @@@ static cups_array_t     *cupsd_fds = NULL
  static int            cupsd_alloc_pollfds = 0,
                        cupsd_update_pollfds = 0;
  static struct pollfd  *cupsd_pollfds = NULL;
- #  ifdef HAVE_EPOLL
- static int            cupsd_epoll_fd = -1;
- static struct epoll_event *cupsd_epoll_events = NULL;
- #  endif /* HAVE_EPOLL */
- #else /* select() */
- static fd_set         cupsd_global_input,
-                       cupsd_global_output,
-                       cupsd_current_input,
-                       cupsd_current_output;
- #endif /* HAVE_KQUEUE */
- /*
-  * Local functions...
-  */
+ //
+ // Local functions...
+ //
  
 -static int            compare_fds(_cupsd_fd_t *a, _cupsd_fd_t *b);
 +static int    compare_fds(_cupsd_fd_t *a, _cupsd_fd_t *b, void *data);
  static _cupsd_fd_t    *find_fd(int fd);
  #define                       release_fd(f) { \
                          (f)->use --; \
@@@ -878,21 -425,14 +425,16 @@@ cupsdStopSelect(void
  }
  
  
- /*
 * 'compare_fds()' - Compare file descriptors.
 */
+ //
// 'compare_fds()' - Compare file descriptors.
//
  
- static int                  /* O - Result of comparison */
- compare_fds(_cupsd_fd_t *a, /* I - First file descriptor */
-             _cupsd_fd_t *b, /* I - Second file descriptor */
-             void *data)     /* Unused */
 -static int                            // O - Result of comparison
 -compare_fds(_cupsd_fd_t *a,           // I - First file descriptor
 -            _cupsd_fd_t *b)           // I - Second file descriptor
++static int                  // O - Result of comparison
++compare_fds(_cupsd_fd_t *a, // I - First file descriptor
++            _cupsd_fd_t *b, // I - Second file descriptor
++            void *data)     // I - Unused
  {
 +  (void)data;
    return (a->fd - b->fd);
  }
  
Simple merge
Simple merge
Simple merge
index 7cc730567c743415c75afc866ee48cae90e74206,1165d0814ed217147de7b4f4a7830dadff651d4a..7629112a174713110ff996954c56ea477c7b1ebd
@@@ -274,8 -231,8 +231,8 @@@ typedef struct ippeve_client_s             // Clie
  
  static http_status_t  authenticate_request(ippeve_client_t *client);
  static void           clean_jobs(ippeve_printer_t *printer);
- static int compare_jobs(ippeve_job_t *a, ippeve_job_t *b, void *data);
- static void           copy_attributes(ipp_t *to, ipp_t *from, cups_array_t *ra, ipp_tag_t group_tag, int quickcopy);
 -static int            compare_jobs(ippeve_job_t *a, ippeve_job_t *b);
++static int            compare_jobs(ippeve_job_t *a, ippeve_job_t *b, void *data);
+ static void           copy_attributes(ipp_t *to, ipp_t *from, cups_array_t *ra, ipp_tag_t group_tag, bool quickcopy);
  static void           copy_job_attributes(ippeve_client_t *client, ippeve_job_t *job, cups_array_t *ra);
  static ippeve_client_t        *create_client(ippeve_printer_t *printer, int sock);
  static ippeve_job_t   *create_job(ippeve_client_t *client);
@@@ -876,16 -751,14 +751,16 @@@ clean_jobs(ippeve_printer_t *printer)   /
  }
  
  
- /*
 * 'compare_jobs()' - Compare two jobs.
 */
+ //
// 'compare_jobs()' - Compare two jobs.
//
  
- static int                    /* O - Result of comparison */
- compare_jobs(ippeve_job_t *a, /* I - First job */
-              ippeve_job_t *b, /* I - Second job */
-              void *data)      /* Unused */
 -static int                            // O - Result of comparison
 -compare_jobs(ippeve_job_t *a,         // I - First job
 -             ippeve_job_t *b)         // I - Second job
++static int                    // O - Result of comparison
++compare_jobs(ippeve_job_t *a, // I - First job
++             ippeve_job_t *b, // I - Second job
++             void         *data) // I - Unused
  {
 +  (void)data;
    return (b->id - a->id);
  }
  
@@@ -2482,13 -2132,10 +2134,10 @@@ finish_document_data
      goto abort_job;
    }
  
-  /*
-   * Return the job info...
-   */
+   // Return the job info...
    respond_ipp(client, IPP_STATUS_OK, NULL);
  
-   ra = cupsArrayNew((cups_array_func_t)_cupsArrayStrcmp, NULL);
 -  ra = cupsArrayNew3((cups_array_cb_t)strcmp, NULL, NULL, 0, NULL, NULL);
++  ra = cupsArrayNew3((cups_array_cb_t)_cupsArrayStrcmp, NULL, NULL, 0, NULL, NULL);
    cupsArrayAdd(ra, "job-id");
    cupsArrayAdd(ra, "job-state");
    cupsArrayAdd(ra, "job-state-message");
    job->state     = IPP_JSTATE_ABORTED;
    job->completed = time(NULL);
  
-   ra = cupsArrayNew((cups_array_func_t)_cupsArrayStrcmp, NULL);
 -  ra = cupsArrayNew3((cups_array_cb_t)strcmp, NULL, NULL, 0, NULL, NULL);
++  ra = cupsArrayNew3((cups_array_cb_t)_cupsArrayStrcmp, NULL, NULL, 0, NULL, NULL);
    cupsArrayAdd(ra, "job-id");
    cupsArrayAdd(ra, "job-state");
    cupsArrayAdd(ra, "job-state-reasons");
@@@ -2758,21 -2377,15 +2379,15 @@@ finish_document_uri
    job->filename = strdup(filename);
    job->state    = IPP_JSTATE_PENDING;
  
-   _cupsRWUnlock(&(client->printer->rwlock));
-  /*
-   * Process the job...
-   */
+   cupsRWUnlock(&(client->printer->rwlock));
  
+   // Process the job...
    process_job(job);
  
-  /*
-   * Return the job info...
-   */
+   // Return the job info...
    respond_ipp(client, IPP_STATUS_OK, NULL);
  
-   ra = cupsArrayNew((cups_array_func_t)_cupsArrayStrcmp, NULL);
 -  ra = cupsArrayNew3((cups_array_cb_t)strcmp, NULL, NULL, 0, NULL, NULL);
++  ra = cupsArrayNew3((cups_array_cb_t)_cupsArrayStrcmp, NULL, NULL, 0, NULL, NULL);
    cupsArrayAdd(ra, "job-id");
    cupsArrayAdd(ra, "job-state");
    cupsArrayAdd(ra, "job-state-reasons");
    job->state     = IPP_JSTATE_ABORTED;
    job->completed = time(NULL);
  
-   ra = cupsArrayNew((cups_array_func_t)_cupsArrayStrcmp, NULL);
 -  ra = cupsArrayNew3((cups_array_cb_t)strcmp, NULL, NULL, 0, NULL, NULL);
++  ra = cupsArrayNew3((cups_array_cb_t)_cupsArrayStrcmp, NULL, NULL, 0, NULL, NULL);
    cupsArrayAdd(ra, "job-id");
    cupsArrayAdd(ra, "job-state");
    cupsArrayAdd(ra, "job-state-reasons");
@@@ -3377,13 -2978,10 +2980,10 @@@ ipp_create_job(ippeve_client_t *client
      return;
    }
  
-  /*
-   * Return the job info...
-   */
+   // Return the job info...
    respond_ipp(client, IPP_STATUS_OK, NULL);
  
-   ra = cupsArrayNew((cups_array_func_t)_cupsArrayStrcmp, NULL);
 -  ra = cupsArrayNew3((cups_array_cb_t)strcmp, NULL, NULL, 0, NULL, NULL);
++  ra = cupsArrayNew3((cups_array_cb_t)_cupsArrayStrcmp, NULL, NULL, 0, NULL, NULL);
    cupsArrayAdd(ra, "job-id");
    cupsArrayAdd(ra, "job-state");
    cupsArrayAdd(ra, "job-state-message");
diff --cc tools/ippfind.c
index 58eb62145d9471962e4be89e30dd8d496c0462de,c293838d1ea4cef2a344f480a766f3de2c75bff4..a2f2012e4201e28be500a18cc1e614a8785353ef
  #  include <sys/timeb.h>
  #else
  #  include <sys/wait.h>
- #endif /* _WIN32 */
+ #endif // _WIN32
  #include <regex.h>
- #ifdef HAVE_MDNSRESPONDER
- #  include <dns_sd.h>
- #elif defined(HAVE_AVAHI)
- #  include <avahi-client/client.h>
- #  include <avahi-client/lookup.h>
- #  include <avahi-common/simple-watch.h>
- #  include <avahi-common/domain.h>
- #  include <avahi-common/error.h>
- #  include <avahi-common/malloc.h>
- #  define kDNSServiceMaxDomainName AVAHI_DOMAIN_NAME_MAX
- #endif /* HAVE_MDNSRESPONDER */
+ #include <cups/dnssd.h>
  
  #ifndef _WIN32
- extern char **environ;                        /* Process environment variables */
- #endif /* !_WIN32 */
+ extern char **environ;                        // Process environment variables
+ #endif // !_WIN32
  
  
- /*
 * Structures...
 */
+ //
// Structures...
//
  
- typedef enum ippfind_exit_e           /* Exit codes */
+ typedef enum ippfind_exit_e           // Exit codes
  {
-   IPPFIND_EXIT_TRUE = 0,              /* OK and result is true */
-   IPPFIND_EXIT_FALSE,                 /* OK but result is false*/
-   IPPFIND_EXIT_BONJOUR,                       /* Browse/resolve failure */
-   IPPFIND_EXIT_SYNTAX,                        /* Bad option or syntax error */
-   IPPFIND_EXIT_MEMORY                 /* Out of memory */
+   IPPFIND_EXIT_TRUE = 0,              // OK and result is true
+   IPPFIND_EXIT_FALSE,                 // OK but result is false
+   IPPFIND_EXIT_BONJOUR,                       // Browse/resolve failure
+   IPPFIND_EXIT_SYNTAX,                        // Bad option or syntax error
+   IPPFIND_EXIT_MEMORY                 // Out of memory
  } ippfind_exit_t;
  
- typedef enum ippfind_op_e             /* Operations for expressions */
+ typedef enum ippfind_op_e             // Operations for expressions
  {
-   /* "Evaluation" operations */
-   IPPFIND_OP_NONE,                    /* No operation */
-   IPPFIND_OP_AND,                     /* Logical AND of all children */
-   IPPFIND_OP_OR,                      /* Logical OR of all children */
-   IPPFIND_OP_TRUE,                    /* Always true */
-   IPPFIND_OP_FALSE,                   /* Always false */
-   IPPFIND_OP_IS_LOCAL,                        /* Is a local service */
-   IPPFIND_OP_IS_REMOTE,                       /* Is a remote service */
-   IPPFIND_OP_DOMAIN_REGEX,            /* Domain matches regular expression */
-   IPPFIND_OP_NAME_REGEX,              /* Name matches regular expression */
-   IPPFIND_OP_NAME_LITERAL,            /* Name matches literal string */
-   IPPFIND_OP_HOST_REGEX,              /* Hostname matches regular expression */
-   IPPFIND_OP_PORT_RANGE,              /* Port matches range */
-   IPPFIND_OP_PATH_REGEX,              /* Path matches regular expression */
-   IPPFIND_OP_TXT_EXISTS,              /* TXT record key exists */
-   IPPFIND_OP_TXT_REGEX,                       /* TXT record key matches regular expression */
-   IPPFIND_OP_URI_REGEX,                       /* URI matches regular expression */
-   /* "Output" operations */
-   IPPFIND_OP_EXEC,                    /* Execute when true */
-   IPPFIND_OP_LIST,                    /* List when true */
-   IPPFIND_OP_PRINT_NAME,              /* Print URI when true */
-   IPPFIND_OP_PRINT_URI,                       /* Print name when true */
-   IPPFIND_OP_QUIET                    /* No output when true */
+   // "Evaluation" operations
+   IPPFIND_OP_NONE,                    // No operation
+   IPPFIND_OP_AND,                     // Logical AND of all children
+   IPPFIND_OP_OR,                      // Logical OR of all children
+   IPPFIND_OP_TRUE,                    // Always true
+   IPPFIND_OP_FALSE,                   // Always false
+   IPPFIND_OP_IS_LOCAL,                        // Is a local service
+   IPPFIND_OP_IS_REMOTE,                       // Is a remote service
+   IPPFIND_OP_DOMAIN_REGEX,            // Domain matches regular expression
+   IPPFIND_OP_NAME_REGEX,              // Name matches regular expression
+   IPPFIND_OP_NAME_LITERAL,            // Name matches literal string
+   IPPFIND_OP_HOST_REGEX,              // Hostname matches regular expression
+   IPPFIND_OP_PORT_RANGE,              // Port matches range
+   IPPFIND_OP_PATH_REGEX,              // Path matches regular expression
+   IPPFIND_OP_TXT_EXISTS,              // TXT record key exists
+   IPPFIND_OP_TXT_REGEX,                       // TXT record key matches regular expression
+   IPPFIND_OP_URI_REGEX,                       // URI matches regular expression
+   // "Output" operations
+   IPPFIND_OP_EXEC,                    // Execute when true
+   IPPFIND_OP_LIST,                    // List when true
+   IPPFIND_OP_PRINT_NAME,              // Print URI when true
+   IPPFIND_OP_PRINT_URI,                       // Print name when true
+   IPPFIND_OP_QUIET                    // No output when true
  } ippfind_op_t;
  
- typedef struct ippfind_expr_s         /* Expression */
+ typedef struct ippfind_expr_s         // Expression
  {
    struct ippfind_expr_s
-               *prev,                  /* Previous expression */
-               *next,                  /* Next expression */
-               *parent,                /* Parent expressions */
-               *child;                 /* Child expressions */
-   ippfind_op_t        op;                     /* Operation code (see above) */
-   int         invert;                 /* Invert the result */
-   char                *name;                  /* TXT record key or literal name */
-   regex_t     re;                     /* Regular expression for matching */
-   int         range[2];               /* Port number range */
-   int         num_args;               /* Number of arguments for exec */
-   char                **args;                 /* Arguments for exec */
+               *prev,                  // Previous expression
+               *next,                  // Next expression
+               *parent,                // Parent expressions
+               *child;                 // Child expressions
+   ippfind_op_t        op;                     // Operation code (see above)
+   bool                invert;                 // Invert the result?
+   char                *name;                  // TXT record key or literal name
+   regex_t     re;                     // Regular expression for matching
+   int         range[2];               // Port number range
+   size_t      num_args;               // Number of arguments for exec
+   char                **args;                 // Arguments for exec
  } ippfind_expr_t;
  
- typedef struct ippfind_srv_s          /* Service information */
+ typedef struct ippfind_srvs_s         // Services array
  {
- #ifdef HAVE_MDNSRESPONDER
-   DNSServiceRef       ref;                    /* Service reference for query */
- #elif defined(HAVE_AVAHI)
-   AvahiServiceResolver *ref;          /* Resolver */
- #endif /* HAVE_MDNSRESPONDER */
-   char                *name,                  /* Service name */
-               *domain,                /* Domain name */
-               *regtype,               /* Registration type */
-               *fullName,              /* Full name */
-               *host,                  /* Hostname */
-               *resource,              /* Resource path */
-               *uri;                   /* URI */
-   int         num_txt;                /* Number of TXT record keys */
-   cups_option_t       *txt;                   /* TXT record keys */
-   int         port,                   /* Port number */
-               is_local,               /* Is a local service? */
-               is_processed,           /* Did we process the service? */
-               is_resolved;            /* Got the resolve data? */
- } ippfind_srv_t;
+   cups_rwlock_t       rwlock;                 // R/W lock
+   cups_array_t        *services;              // Services array
+ } ippfind_srvs_t;
  
+ typedef struct ippfind_srv_s          // Service information
+ {
+   cups_dnssd_resolve_t *resolve;      // Resolve request
+   char                *name,                  // Service name
+               *domain,                // Domain name
+               *regtype,               // Registration type
+               *fullName,              // Full name
+               *host,                  // Hostname
+               *resource,              // Resource path
+               *uri;                   // URI
+   int         num_txt;                // Number of TXT record keys
+   cups_option_t       *txt;                   // TXT record keys
+   int         port;                   // Port number
+   bool                is_local,               // Is a local service?
+               is_processed,           // Did we process the service?
+               is_resolved;            // Got the resolve data?
+ } ippfind_srv_t;
  
- /*
-  * Local globals...
-  */
  
- #ifdef HAVE_MDNSRESPONDER
- static DNSServiceRef dnssd_ref;               /* Master service reference */
- #elif defined(HAVE_AVAHI)
- static AvahiClient *avahi_client = NULL;/* Client information */
- static int    avahi_got_data = 0;     /* Got data from poll? */
- static AvahiSimplePoll *avahi_poll = NULL;
-                                       /* Poll information */
- #endif /* HAVE_MDNSRESPONDER */
+ //
+ // Local globals...
+ //
  
+ static cups_dnssd_t *dnssd;           // DNS-SD context
  static int    address_family = AF_UNSPEC;
-                                       /* Address family for LIST */
- static int    bonjour_error = 0;      /* Error browsing/resolving? */
- static double bonjour_timeout = 1.0;  /* Timeout in seconds */
- static int    ipp_version = 20;       /* IPP version for LIST */
- /*
-  * Local functions...
-  */
- #ifdef HAVE_MDNSRESPONDER
- static void DNSSD_API browse_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context) _CUPS_NONNULL(1,5,6,7,8);
- static void DNSSD_API browse_local_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context) _CUPS_NONNULL(1,5,6,7,8);
- #elif defined(HAVE_AVAHI)
- static void           browse_callback(AvahiServiceBrowser *browser,
-                                       AvahiIfIndex interface,
-                                       AvahiProtocol protocol,
-                                       AvahiBrowserEvent event,
-                                       const char *serviceName,
-                                       const char *regtype,
-                                       const char *replyDomain,
-                                       AvahiLookupResultFlags flags,
-                                       void *context);
- static void           client_callback(AvahiClient *client,
-                                       AvahiClientState state,
-                                       void *context);
- #endif /* HAVE_MDNSRESPONDER */
+                                       // Address family for LIST
+ static int    bonjour_error = 0;      // Error browsing/resolving?
+ static double bonjour_timeout = 1.0;  // Timeout in seconds
+ static int    ipp_version = 20;       // IPP version for LIST
  
 -static int            compare_services(ippfind_srv_t *a, ippfind_srv_t *b);
+ //
+ // Local functions...
+ //
+ static void           browse_callback(cups_dnssd_browse_t *browse, void *context, cups_dnssd_flags_t flags, uint32_t if_index, const char *serviceName, const char *regtype, const char *replyDomain);
- static const char     *dnssd_error_string(int error);
- static int            eval_expr(ippfind_srv_t *service,
-                                 ippfind_expr_t *expressions);
- static int            exec_program(ippfind_srv_t *service, int num_args,
-                                    char **args);
- static ippfind_srv_t  *get_service(cups_array_t *services, const char *serviceName, const char *regtype, const char *replyDomain) _CUPS_NONNULL(1,2,3,4);
 +static int            compare_services(ippfind_srv_t *a, ippfind_srv_t *b, void *data);
+ static int            eval_expr(ippfind_srv_t *service, ippfind_expr_t *expressions);
+ static int            exec_program(ippfind_srv_t *service, int num_args, char **args);
+ static ippfind_srv_t  *get_service(ippfind_srvs_t *services, const char *serviceName, const char *regtype, const char *replyDomain) _CUPS_NONNULL(1,2,3,4);
  static double         get_time(void);
  static int            list_service(ippfind_srv_t *service);
- static ippfind_expr_t *new_expr(ippfind_op_t op, int invert,
-                                 const char *value, const char *regex,
-                                 char **args);
- #ifdef HAVE_MDNSRESPONDER
- static void DNSSD_API resolve_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullName, const char *hostTarget, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context) _CUPS_NONNULL(1,5,6,9, 10);
- #elif defined(HAVE_AVAHI)
- static int            poll_callback(struct pollfd *pollfds,
-                                     unsigned int num_pollfds, int timeout,
-                                     void *context);
- static void           resolve_callback(AvahiServiceResolver *res,
-                                        AvahiIfIndex interface,
-                                        AvahiProtocol protocol,
-                                        AvahiResolverEvent event,
-                                        const char *serviceName,
-                                        const char *regtype,
-                                        const char *replyDomain,
-                                        const char *host_name,
-                                        const AvahiAddress *address,
-                                        uint16_t port,
-                                        AvahiStringList *txt,
-                                        AvahiLookupResultFlags flags,
-                                        void *context);
- #endif /* HAVE_MDNSRESPONDER */
+ static ippfind_expr_t *new_expr(ippfind_op_t op, bool invert, const char *value, const char *regex, char **args);
+ static void           resolve_callback(cups_dnssd_resolve_t *resolve, void *context, cups_dnssd_flags_t flags, uint32_t if_index, const char *fullName, const char *hostTarget, uint16_t port, int num_txt, cups_option_t *txt);
  static void           set_service_uri(ippfind_srv_t *service);
  static void           show_usage(void) _CUPS_NORETURN;
  static void           show_version(void) _CUPS_NORETURN;
@@@ -1550,208 -1142,41 +1142,44 @@@ main(int  argc,                             // I - Number of com
  
  static void
  browse_callback(
-     AvahiServiceBrowser    *browser,  /* I - Browser */
-     AvahiIfIndex           interface, /* I - Interface index (unused) */
-     AvahiProtocol          protocol,  /* I - Network protocol (unused) */
-     AvahiBrowserEvent      event,     /* I - What happened */
-     const char             *name,     /* I - Service name */
-     const char             *type,     /* I - Registration type */
-     const char             *domain,   /* I - Domain */
-     AvahiLookupResultFlags flags,     /* I - Flags */
-     void                   *context)  /* I - Services array */
+     cups_dnssd_browse_t *browse,      // I - Browse request
+     void                *context,     // I - Services array
+     cups_dnssd_flags_t  flags,                // I - Flags
+     uint32_t            if_index,     // I - Interface
+     const char          *serviceName, // I - Name of service/device
+     const char          *regtype,     // I - Type of service
+     const char          *replyDomain) // I - Service domain
  {
-   AvahiClient *client = avahi_service_browser_get_client(browser);
-                                       /* Client information */
-   ippfind_srv_t       *service;               /* Service information */
-   (void)interface;
-   (void)protocol;
-   (void)context;
-   switch (event)
-   {
-     case AVAHI_BROWSER_FAILURE:
-       fprintf(stderr, "DEBUG: browse_callback: %s\n",
-               avahi_strerror(avahi_client_errno(client)));
-       bonjour_error = 1;
-       avahi_simple_poll_quit(avahi_poll);
-       break;
-     case AVAHI_BROWSER_NEW:
-        /*
-       * This object is new on the network. Create a device entry for it if
-       * it doesn't yet exist.
-       */
+   ippfind_srv_t       *service;               // Service
  
-       service = get_service((cups_array_t *)context, name, type, domain);
-       if (flags & AVAHI_LOOKUP_RESULT_LOCAL)
-         service->is_local = 1;
-       break;
-     case AVAHI_BROWSER_REMOVE:
-     case AVAHI_BROWSER_ALL_FOR_NOW:
-     case AVAHI_BROWSER_CACHE_EXHAUSTED:
-         break;
-   }
- }
- /*
-  * 'client_callback()' - Avahi client callback function.
-  */
+   if (getenv("IPPFIND_DEBUG"))
+     fprintf(stderr, "B flags=0x%04X, if_index=%u, serviceName=\"%s\", regtype=\"%s\", replyDomain=\"%s\"\n", flags, if_index, serviceName, regtype, replyDomain);
  
- static void
- client_callback(
-     AvahiClient      *client,         /* I - Client information (unused) */
-     AvahiClientState state,           /* I - Current state */
-     void             *context)                /* I - User data (unused) */
- {
-   (void)client;
-   (void)context;
+   (void)browse;
  
-  /*
-   * If the connection drops, quit.
-   */
+   // Only process "add" data...
+   if ((flags & CUPS_DNSSD_FLAGS_ERROR) || !(flags & CUPS_DNSSD_FLAGS_ADD))
+     return;
  
-   if (state == AVAHI_CLIENT_FAILURE)
-   {
-     fputs("DEBUG: Avahi connection failed.\n", stderr);
-     bonjour_error = 1;
-     avahi_simple_poll_quit(avahi_poll);
-   }
+   // Get the device...
+   service = get_service((ippfind_srvs_t *)context, serviceName, regtype, replyDomain);
+   if (if_index == CUPS_DNSSD_IF_INDEX_LOCAL)
+     service->is_local = 1;
  }
- #endif /* HAVE_AVAHI */
  
  
- /*
 * 'compare_services()' - Compare two devices.
 */
+ //
// 'compare_services()' - Compare two devices.
//
  
- static int                         /* O - Result of comparison */
- compare_services(ippfind_srv_t *a, /* I - First device */
-                  ippfind_srv_t *b, /* I - Second device */
-                  void *data)       /* Unused */
+ static int                            // O - Result of comparison
+ compare_services(ippfind_srv_t *a,    // I - First device
 -                 ippfind_srv_t *b)    // I - Second device
++                 ippfind_srv_t *b,    // I - Second device
++                 void          *data) // I - Callback data (unused)
  {
-   return (strcmp(a->name, b->name));
- }
- /*
-  * 'dnssd_error_string()' - Return an error string for an error code.
-  */
- static const char *                   /* O - Error message */
- dnssd_error_string(int error)         /* I - Error number */
- {
- #  ifdef HAVE_MDNSRESPONDER
-   switch (error)
-   {
-     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.");
 +  (void)data;
-     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.");
- #ifndef _WIN32
-     case kDNSServiceErr_Timeout :
-         return ("Service timeout.");
- #endif /* !_WIN32 */
-   }
- #  elif defined(HAVE_AVAHI)
-   return (avahi_strerror(error));
- #  endif /* HAVE_MDNSRESPONDER */
 +
+   return (_cups_strcasecmp(a->name, b->name));
  }
  
  
diff --cc tools/ipptool.c
index 0ca9870a9fa7cf67fa5923338c32ef1d17a00738,01c72150238456699667770118c5839c70fc2de5..918f162ce03909d2a76d6c1d2fc52804fb30baf0
@@@ -1573,16 -1737,16 +1737,16 @@@ do_test(ipp_file_t     *f,           // I - IPP 
        if (ippGetGroupTag(attrptr) != IPP_TAG_OPERATION)
          add_stringf(data->errors, "detailed-status-message (text(MAX)) has wrong group tag %s (RFC 8011 section 4.1.6.3).", ippTagString(ippGetGroupTag(attrptr)));
        if (ippGetCount(attrptr) != 1)
-         add_stringf(data->errors, "detailed-status-message (text(MAX)) has %d values (RFC 8011 section 4.1.6.3).", ippGetCount(attrptr));
+         add_stringf(data->errors, "detailed-status-message (text(MAX)) has %u values (RFC 8011 section 4.1.6.3).", (unsigned)ippGetCount(attrptr));
        if (detailed_status_message && strlen(detailed_status_message) > 1023)
-         add_stringf(data->errors, "detailed-status-message (text(MAX)) has bad length %d (RFC 8011 section 4.1.6.3).", (int)strlen(detailed_status_message));
+         add_stringf(data->errors, "detailed-status-message (text(MAX)) has bad length %u (RFC 8011 section 4.1.6.3).", (unsigned)strlen(detailed_status_message));
        }
  
-       a = cupsArrayNew((cups_array_func_t)_cupsArrayStrcmp, NULL);
 -      a = cupsArrayNew3((cups_array_cb_t)strcmp, NULL, NULL, 0, NULL, NULL);
++      a = cupsArrayNew3((cups_array_cb_t)_cupsArrayStrcmp, NULL, NULL, 0, NULL, NULL);
  
-       for (attrptr = ippFirstAttribute(response), group = ippGetGroupTag(attrptr);
+       for (attrptr = ippGetFirstAttribute(response), group = ippGetGroupTag(attrptr);
           attrptr;
-          attrptr = ippNextAttribute(response))
+          attrptr = ippGetNextAttribute(response))
        {
        if (ippGetGroupTag(attrptr) != group)
        {
@@@ -5704,7 -6864,7 +6864,7 @@@ with_distinct_values
    }
  
    // Collect values and determine they are all unique...
-   values = cupsArrayNew3((cups_array_func_t)_cupsArrayStrcmp, NULL, NULL, 0, (cups_acopy_func_t)_cupsArrayStrdup, _cupsArrayFree);
 -  values = cupsArrayNew3((cups_array_cb_t)strcmp, NULL, NULL, 0, (cups_acopy_cb_t)strdup, (cups_afree_cb_t)free);
++  values = cupsArrayNew3((cups_array_cb_t)_cupsArrayStrcmp, NULL, NULL, 0, (cups_acopy_cb_t)strdup, (cups_afree_cb_t)free);
  
    for (i = 0; i < count; i ++)
    {