From: Michael R Sweet Date: Tue, 2 Apr 2024 22:44:53 +0000 (-0400) Subject: Merge branch 'master' into ABI X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F674%2Fhead;p=thirdparty%2Fcups.git Merge branch 'master' into ABI --- e7fb5c305449b305e7bc6b2c726a0c983e879079 diff --cc cups/array.c index f54e66485a,2758a605ac..f870cf6648 --- a/cups/array.c +++ b/cups/array.c @@@ -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); } diff --cc cups/dest-options.c index 4555c10829,0ad969c78a..bac55fba25 --- a/cups/dest-options.c +++ b/cups/dest-options.c @@@ -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 416bd2ddc2,9c589b0d0b..d406af2270 --- a/cups/dest.c +++ b/cups/dest.c @@@ -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)); } diff --cc cups/language.c index 6f5d6fcfa0,44eae1a779..1f44a73e37 --- a/cups/language.c +++ b/cups/language.c @@@ -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); diff --cc cups/ppd-cache.c index 88decc7067,ec0de56a72..8be335b084 --- a/cups/ppd-cache.c +++ b/cups/ppd-cache.c @@@ -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) { diff --cc cups/string-private.h index df5873c8ca,e76d20d70c..6f9d35dbe3 --- a/cups/string-private.h +++ b/cups/string-private.h @@@ -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 770616cf52,22b0ef555e..fac91560fe --- a/cups/string.c +++ b/cups/string.c @@@ -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 ++; @@@ -705,113 -1106,56 +1116,73 @@@ } - #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'; + } + } } + + +/* + * '_cupsArrayStrcasecmp()' - Compare two strings... + */ + - int _cupsArrayStrcasecmp(const char *s, /* I - First string */ ++int /* O - Result of comparison */ ++_cupsArrayStrcasecmp(const char *s, /* I - First string */ + const char *t, /* I - Second string */ - void *data) /* Unused */ ++ void *data) /* I - Unused */ +{ + (void)data; - return _cups_strcasecmp(s, t); ++ return (_cups_strcasecmp(s, t)); +} diff --cc cups/testarray.c index a224fce85e,864376b219..d5270b2769 --- a/cups/testarray.c +++ b/cups/testarray.c @@@ -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 scheduler/client.c index 90731441dc,1173d2bb4c..62ac21c698 --- a/scheduler/client.c +++ b/scheduler/client.c @@@ -34,23 -34,21 +34,20 @@@ 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); diff --cc scheduler/cups-driverd.cxx index 28eea0da93,7d17b94c9d..0d0f1f1e23 --- a/scheduler/cups-driverd.cxx +++ b/scheduler/cups-driverd.cxx @@@ -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 @@@ -718,16 -695,14 +698,16 @@@ } - /* - * '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 @@@ -736,18 -711,16 +716,18 @@@ } - /* - * '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); @@@ -756,16 -729,15 +736,16 @@@ } - /* - * '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 /* diff --cc scheduler/select.c index 3079f3d52b,d3a8e36f4f..9852e59be4 --- a/scheduler/select.c +++ b/scheduler/select.c @@@ -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); } diff --cc tools/ippeveprinter.c index 7cc730567c,1165d0814e..7629112a17 --- a/tools/ippeveprinter.c +++ b/tools/ippeveprinter.c @@@ -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"); @@@ -2508,7 -2152,7 +2154,7 @@@ 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"); @@@ -2791,7 -2401,7 +2403,7 @@@ 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 58eb62145d,c293838d1e..a2f2012e42 --- a/tools/ippfind.c +++ b/tools/ippfind.c @@@ -22,179 -18,122 +18,122 @@@ # include #else # include - #endif /* _WIN32 */ + #endif // _WIN32 #include - #ifdef HAVE_MDNSRESPONDER - # include - #elif defined(HAVE_AVAHI) - # include - # include - # include - # include - # include - # include - # define kDNSServiceMaxDomainName AVAHI_DOMAIN_NAME_MAX - #endif /* HAVE_MDNSRESPONDER */ + #include #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 + + // + // 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 int compare_services(ippfind_srv_t *a, ippfind_srv_t *b); +static int compare_services(ippfind_srv_t *a, ippfind_srv_t *b, void *data); - 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 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) { + (void)data; - 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."); + - 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 0ca9870a9f,01c7215023..918f162ce0 --- a/tools/ipptool.c +++ b/tools/ipptool.c @@@ -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 ++) {