Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package pappl for openSUSE:Factory checked in at 2026-01-14 16:22:06 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/pappl (Old) and /work/SRC/openSUSE:Factory/.pappl.new.1928 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "pappl" Wed Jan 14 16:22:06 2026 rev:12 rq:1327084 version:1.4.10 Changes: -------- --- /work/SRC/openSUSE:Factory/pappl/pappl.changes 2025-03-25 22:17:30.255273464 +0100 +++ /work/SRC/openSUSE:Factory/.pappl.new.1928/pappl.changes 2026-01-14 16:22:16.878945044 +0100 @@ -1,0 +2,19 @@ +Fri Dec 26 21:47:24 UTC 2025 - Jan Engelhardt <[email protected]> + +- Update to release 1.4.10 + * Changed the preferred/first printer URI to use the "ipps" + scheme. + * Updated the USB serial number code to better support + non-compliant printers such as those from DYMO. + * Now shows the default and supported "output-bin" options. + * Now suppresses a duplicate 'auto' value for + "media-source-supported" to work around a bug in the + legacy-printer-app. + * Now logs the TLS version and cipher suite, when available. + * Now creates spool files with read-only permissions. + * Now supports setting "media-ready" with the modify sub-command. + * Fixed attribute copying issue from multiple client threads. + * Fixed driver validation for raw printing (Issue #391). + * Fixed a deadlock issue in the web interface (Issue #406). + +------------------------------------------------------------------- Old: ---- pappl-1.4.9.tar.gz pappl-1.4.9.tar.gz.sig New: ---- pappl-1.4.10.tar.gz pappl-1.4.10.tar.gz.sig ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ pappl.spec ++++++ --- /var/tmp/diff_new_pack.7xIPgz/_old 2026-01-14 16:22:17.878986527 +0100 +++ /var/tmp/diff_new_pack.7xIPgz/_new 2026-01-14 16:22:17.882986693 +0100 @@ -1,7 +1,7 @@ # # spec file for package pappl # -# Copyright (c) 2025 SUSE LLC +# Copyright (c) 2025 SUSE LLC and contributors # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ Name: pappl %define lname libpappl1 -Version: 1.4.9 +Version: 1.4.10 Release: 0 Summary: A printer application framework License: Apache-2.0 ++++++ _scmsync.obsinfo ++++++ --- /var/tmp/diff_new_pack.7xIPgz/_old 2026-01-14 16:22:17.938989015 +0100 +++ /var/tmp/diff_new_pack.7xIPgz/_new 2026-01-14 16:22:17.942989181 +0100 @@ -1,5 +1,5 @@ -mtime: 1742678832 -commit: 1ec9127fb9e237d48314e8a53479af3c67b5abb91c0a903b1f6a5dde42c8f711 +mtime: 1766785738 +commit: 964c9a4f686399923300faaa77ab2a605b1bbf01f3be838aa5f47e31582c9b36 url: https://src.opensuse.org/jengelh/pappl revision: master ++++++ build.specials.obscpio ++++++ ++++++ build.specials.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/.gitignore new/.gitignore --- old/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/.gitignore 2025-12-26 22:56:12.000000000 +0100 @@ -0,0 +1 @@ +.osc ++++++ pappl-1.4.9.tar.gz -> pappl-1.4.10.tar.gz ++++++ ++++ 3034 lines of diff (skipped) ++++ retrying with extended exclude list diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/CHANGES.md new/pappl-1.4.10/CHANGES.md --- old/pappl-1.4.9/CHANGES.md 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/CHANGES.md 2025-12-26 18:20:00.000000000 +0100 @@ -2,8 +2,28 @@ ================ -Changes in v1.4.9 (2025-03-20) ------------------------------- +v1.4.10 - 2025-12-26 +-------------------- + +- Changed the preferred/first printer URI to use the "ipps" scheme. +- Updated the USB serial number code to better support non-compliant printers + such as those from DYMO (Issue #396) +- Now show the default and supported "output-bin" options (Issue #393) +- Now suppress a duplicate 'auto' value for "media-source-supported" to work + around a bug in the legacy-printer-app (Issue #394) +- Now log the TLS version and cipher suite, when available. +- Now create spool files with read-only permissions. +- Now support setting "media-ready" with the modify sub-command (Issue #395) +- Fixed attribute copying issue from multiple client threads (Issue #390) +- Fixed driver validation for raw printing (Issue #391) +- Fixed PNG looping issue (Issue #398) +- Fixed default IPv6 listener (Issue #401) +- Fixed builds against the latest libcups (Issue #403) +- Fixed a deadlock issue in the web interface (Issue #406) + + +v1.4.9 - 2025-03-20 +------------------- - Fixed a bug in job event notifications. - Fixed a bug that would delay shutdown by 60 seconds. @@ -13,16 +33,16 @@ - Disabled raw socket support on Windows. -Changes in v1.4.8 (2024-11-14) ------------------------------- +v1.4.8 - 2024-11-14 +------------------- - SECURITY: The web interface password didn't work properly (Issue #373) - Now use the "listen-hostname" hostname as system hostname if a name is specified (Issue #369) -Changes in v1.4.7 (2024-08-15) ------------------------------- +v1.4.7 - 2024-08-15 +------------------- - PAM-based authentication did not work on Linux due to a glibc incompatibility (Issue #343) @@ -37,8 +57,8 @@ - Fixed the "no-tls" server option. -Changes in v1.4.6 (2024-02-09) ------------------------------- +v1.4.6 - 2024-02-09 +------------------- - Fixed reporting of "printer-strings-languages-supported" attribute (Issue #328) @@ -50,8 +70,8 @@ - Fixed localization of command-line (main loop) interface. -Changes in v1.4.5 (2024-01-26) ------------------------------- +v1.4.5 - 2024-01-26 +------------------- - Fixed `--disable-libpam` configure option. - Fixed support for "finishings", "output-bin", and "sides" options. @@ -60,8 +80,8 @@ - Fixed some Coverity-detected threading issues. -Changes in v1.4.4 (2023-12-21) ------------------------------- +v1.4.4 - 2023-12-21 +------------------- - Fixed "printer-settable-attributes-supported" value (Issue #311) - Fixed `-n` support for setting number of copies (Issue #312) @@ -71,8 +91,8 @@ - Fixed builds against current libcups3. -Changes in v1.4.3 (2023-11-15) ------------------------------- +v1.4.3 - 2023-11-15 +------------------- - Added "smi55357-device-uri" and "smi55357-driver" Printer Status attributes to Get-Printer-Attributes responses. @@ -84,23 +104,23 @@ - Fixed default "copies" value with `papplJobCreateWithFile`. -Changes in v1.4.2 (2024-10-16) ------------------------------- +v1.4.2 - 2024-10-16 +------------------- - Fixed potential crash while listing devices (Issue #296) - Fixed potential deadlock issue (Issue #297) - Fixed loading of previous state (Issue #298) -Changes in v1.4.1 (2024-10-10) ------------------------------- +v1.4.1 - 2024-10-10 +------------------- - Fixed typos in the names of the `papplJobResume` and `papplJobSuspend` functions (Issue #295) -Changes in v1.4.0 (2024-09-28) ------------------------------- +v1.4.0 - 2024-09-28 +------------------- - Added support for "job-retain-until" (Issue #14) - Added new PAPPL-Create-Printers operation, and the PAPPL mainloop API now diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/EMBEDDED.md new/pappl-1.4.10/EMBEDDED.md --- old/pappl-1.4.9/EMBEDDED.md 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/EMBEDDED.md 2025-12-26 18:20:00.000000000 +0100 @@ -17,6 +17,31 @@ ``` +Linux Kernel Configuration +-------------------------- + +Gadget support requires a bunch of USB modules that are not normally loaded or +configured. First, for a system with a USB 2.0 controller you will need to +enable `CONFIG_USB_DWC2`, `CONFIG_USB_DWC2_DUAL_ROLE`, and +`CONFIG_USB_DWC2_PERIPHERAL` plus a board/controller-specific USB driver. USB +3.x controllers need `CONFIG_USB_DWC3` along with the board/controller-specific +USB driver. + +PAPPL uses the "configfs" system for configuring USB gadgets dynamically, which +requires `CONFIGFS_FS`, `CONFIG_USB_CONFIGFS`, `CONFIG_USB_GADGET`, and +`USB_LIBCOMPOSITE`. Printing functionality requires +`CONFIG_USB_CONFIGFS_F_PRINTER`, `CONFIG_USB_CONFIGFS_F_FS`, `CONFIG_USB_F_FS`, +and `CONFIG_USB_F_PRINTER`. + +Ethernet (`PAPPL_UOPTIONS_ETHERNET`) gadgets require `CONFIG_USB_CONFIGFS_NCM`. + +Serial (`PAPPL_UOPTIONS_SERIAL`) gadgets require `CONFIG_USB_CONFIGFS_ACM` and +`CONFIG_USB_F_SERIAL`. + +Mass storage (`PAPPL_UOPTIONS_STORAGE`) gadgets require +`CONFIG_USB_CONFIGFS_MASS_STORAGE`. + + USB Printer Gadget Kernel Patch ------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/configure.ac new/pappl-1.4.10/configure.ac --- old/pappl-1.4.9/configure.ac 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/configure.ac 2025-12-26 18:20:00.000000000 +0100 @@ -21,7 +21,7 @@ dnl Package name and version... -AC_INIT([pappl], [1.4.9], [https://github.com/michaelrsweet/pappl/issues], [pappl], [https://www.msweet.org/pappl]) +AC_INIT([pappl], [1.4.10], [https://github.com/michaelrsweet/pappl/issues], [pappl], [https://www.msweet.org/pappl]) AC_CONFIG_HEADERS([config.h]) PAPPL_VERSION="AC_PACKAGE_VERSION" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/base-private.h new/pappl-1.4.10/pappl/base-private.h --- old/pappl-1.4.9/pappl/base-private.h 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/base-private.h 2025-12-26 18:20:00.000000000 +0100 @@ -37,8 +37,11 @@ // # if CUPS_VERSION_MAJOR < 3 +# define CUPS_BOOL_FALSE 0 +# define CUPS_BOOL_TRUE 1 # define CUPS_ENCODING_ISO8859_1 CUPS_ISO8859_1 # define CUPS_ENCODING_JIS_X0213 CUPS_JIS_X0213 +# define cups_bool_t int # define cups_len_t int # define cups_page_header_t cups_page_header2_t # define cupsArrayNew cupsArrayNew3 @@ -95,7 +98,10 @@ # define httpEncode64 httpEncode64_3 # endif // CUPS_VERSION_MINOR < 5 # else +# define CUPS_BOOL_FALSE false +# define CUPS_BOOL_TRUE true # define cups_b64len_t size_t +# define cups_bool_t bool # define cups_len_t size_t # define cups_utf8_t char # define IPP_NUM_CAST (size_t) @@ -140,6 +146,7 @@ { cups_array_t *ra; // Requested attributes ipp_tag_t group_tag; // Group to copy + int quickcopy; // Quick copy attributes? } _pappl_ipp_filter_t; typedef struct _pappl_link_s // Web interface navigation link diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/client-private.h new/pappl-1.4.10/pappl/client-private.h --- old/pappl-1.4.9/pappl/client-private.h 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/client-private.h 2025-12-26 18:20:00.000000000 +0100 @@ -1,7 +1,7 @@ // // Private client header file for the Printer Application Framework // -// Copyright © 2019-2022 by Michael R Sweet. +// Copyright © 2019-2025 by Michael R Sweet. // Copyright © 2010-2019 by Apple Inc. // // Licensed under Apache License v2.0. See the file "LICENSE" for more @@ -32,8 +32,7 @@ ipp_op_t operation_id; // IPP operation-id char uri[1024], // Request URI *options, // URI options - host_field[HTTP_MAX_VALUE]; - // Host: header + host_field[256]; // Host: header int host_port; // Port number from Host: header http_addr_t addr; // Client address char hostname[256]; // Client hostname diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/client.c new/pappl-1.4.10/pappl/client.c --- old/pappl-1.4.9/pappl/client.c 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/client.c 2025-12-26 18:20:00.000000000 +0100 @@ -1,7 +1,7 @@ // // Client processing code for the Printer Application Framework // -// Copyright © 2019-2024 by Michael R Sweet. +// Copyright © 2019-2025 by Michael R Sweet. // Copyright © 2010-2019 by Apple Inc. // // Licensed under Apache License v2.0. See the file "LICENSE" for more @@ -304,6 +304,10 @@ { if (strstr(httpGetField(client->http, HTTP_FIELD_UPGRADE), "TLS/") != NULL && !httpIsEncrypted(client->http) && !(client->system->options & PAPPL_SOPTIONS_NO_TLS)) { +#if CUPS_VERSION_MAJOR >= 3 || CUPS_VERSION_MINOR >= 5 + char security[256]; // Security description +#endif // CUPS_VERSION_MAJOR >= 3 || CUPS_VERSION_MINOR >= 5 + if (!papplClientRespond(client, HTTP_STATUS_SWITCHING_PROTOCOLS, NULL, NULL, 0, 0)) return (false); @@ -315,7 +319,11 @@ return (false); } +#if CUPS_VERSION_MAJOR >= 3 || CUPS_VERSION_MINOR >= 5 + papplLogClient(client, PAPPL_LOGLEVEL_INFO, "Connection now encrypted (%s).", httpGetSecurity(client->http, security, sizeof(security))); +#else papplLogClient(client, PAPPL_LOGLEVEL_INFO, "Connection now encrypted."); +#endif // CUPS_VERSION_MAJOR >= 3 || CUPS_VERSION_MINOR >= 5 } else if (!papplClientRespond(client, HTTP_STATUS_NOT_IMPLEMENTED, NULL, NULL, 0, 0)) return (false); @@ -524,7 +532,7 @@ if (code == HTTP_STATUS_UNAUTHORIZED) { - char value[HTTP_MAX_VALUE]; // WWW-Authenticate value + char value[256]; // WWW-Authenticate value snprintf(value, sizeof(value), "%s realm=\"%s\"", client->system->auth_scheme ? client->system->auth_scheme : "Basic", client->system->name); httpSetField(client->http, HTTP_FIELD_WWW_AUTHENTICATE, value); @@ -643,7 +651,10 @@ if (first_time && !(client->system->options & PAPPL_SOPTIONS_NO_TLS)) { // See if we need to negotiate a TLS connection... - char buf[1]; // First byte from client + char buf[1]; // First byte from client +#if CUPS_VERSION_MAJOR >= 3 || CUPS_VERSION_MINOR >= 5 + char security[256]; // Security description +#endif // CUPS_VERSION_MAJOR >= 3 || CUPS_VERSION_MINOR >= 5 if (recv(httpGetFd(client->http), buf, 1, MSG_PEEK) == 1 && (!buf[0] || !strchr("DGHOPT", buf[0]))) { @@ -655,7 +666,11 @@ break; } +#if CUPS_VERSION_MAJOR >= 3 || CUPS_VERSION_MINOR >= 5 + papplLogClient(client, PAPPL_LOGLEVEL_INFO, "Connection now encrypted (%s).", httpGetSecurity(client->http, security, sizeof(security))); +#else papplLogClient(client, PAPPL_LOGLEVEL_INFO, "Connection now encrypted."); +#endif // CUPS_VERSION_MAJOR >= 3 || CUPS_VERSION_MINOR >= 5 } first_time = 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/device-usb.c new/pappl-1.4.10/pappl/device-usb.c --- old/pappl-1.4.9/pappl/device-usb.c 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/device-usb.c 2025-12-26 18:20:00.000000000 +0100 @@ -1,7 +1,7 @@ // // USB device support code for the Printer Application Framework // -// Copyright © 2019-2023 by Michael R Sweet. +// Copyright © 2019-2025 by Michael R Sweet. // Copyright © 2007-2019 by Apple Inc. // // Licensed under Apache License v2.0. See the file "LICENSE" for more @@ -55,6 +55,7 @@ // #ifdef HAVE_LIBUSB +static void get_serial_number(_pappl_usb_dev_t *device, uint8_t desc_index, char *buffer, size_t bufsize); static void pappl_usb_close(pappl_device_t *device); static bool pappl_usb_find(pappl_device_cb_t cb, void *data, _pappl_usb_dev_t *device, pappl_deverror_cb_t err_cb, void *err_data); static char *pappl_usb_getid(pappl_device_t *device, char *buffer, size_t bufsize); @@ -82,6 +83,114 @@ #ifdef HAVE_LIBUSB // +// 'get_serial_number()' - Get the USB device serial number. +// +// This function is necessary because some vendors (DYMO, others) don't know +// how to implement USB correctly and having a unique serial number is necessary +// to support connecting more than one USB printer of the same make and model. +// +// The first bit of this code duplicates the strategy employed by +// `libusb_get_string_descriptor_ascii()` - get the list of supported language +// IDs and use the first (and usually only) language ID (almost always US +// English or 0x0409) to get the specified iSerialNumber string descriptor as +// a series of 16-bit UCS-2 Little Endian characters - this word order is +// mandated in section 8.1 of the USB 2.0 specification. The libusb function +// then copies the string, replacing any characters greater than 127 with '?' +// and happily embedding any non-printable ASCII characters such as NULs. +// +// In the case of DYMO printers, the iSerialNumber string consists of the +// U+3030 ("Wavy Dash") character followed by the ASCII serial number digits +// as 16-bit *Big Endian* characters. Acknowledging that USB implementors have +// proven capable of making lots of mistakes like this, this function takes a +// more pragmatic approach and converts serial number descriptors to hexadecimal +// if they don't contain purely printable US ASCII characters. This preserves +// backwards compatibility with conforming printers while allowing non- +// conforming printers to work reliably for the first time. +// +// If we are not able to get a serial number at all (`desc_index` is 0 or the +// other calls fail), then we fall back on using the configuration and interface +// indices from libusb, as before. +// + +static void +get_serial_number( + _pappl_usb_dev_t *device, // I - Device + uint8_t desc_index, // I - iSerialNumber index + char *buffer, // I - Buffer for serial number string + size_t bufsize) // I - Size of buffer +{ + uint8_t langbuf[4]; // Language code buffer + uint16_t langid; // Language code/ID + uint8_t snbuf[256]; // Raw serial number buffer + int snlen; // Length of response + uint16_t snchar; // Character from raw serial number buffer + int i; // Looping var + char *bufptr, // Pointer into string buffer + *bufend; // End of string buffer + + + // If there is no serial number string, fallback... + if (!desc_index) + goto fallback; + + // Get the first supported language code... + if (libusb_get_string_descriptor(device->handle, 0, 0, langbuf, sizeof(langbuf)) < 4) + goto fallback; // Didn't get 4 bytes + else if (langbuf[0] < 4 || (langbuf[0] & 1)) + goto fallback; // Bad length + else if (langbuf[1] != LIBUSB_DT_STRING) + goto fallback; // Not a string + + langid = langbuf[2] | (langbuf[3] << 8); + + // Then try to get the serial number string... + if ((snlen = libusb_get_string_descriptor(device->handle, desc_index, langid, snbuf, sizeof(snbuf))) < 10) + goto fallback; // Didn't get at least 10 bytes + else if (snbuf[0] != snlen || (snbuf[0] & 1)) + goto fallback; // Bad length + else if (snbuf[1] != LIBUSB_DT_STRING) + goto fallback; // Not a string + + // Loop through the string to determine whether it is valid... + for (i = 2, bufptr = buffer, bufend = buffer + bufsize - 1; i < snlen && bufptr < bufend; i += 2) + { + // Get the current UCS-2 character... + snchar = snbuf[i] | (snbuf[i + 1] << 8); + + // Abort if not printable ASCII... + if (snchar < 0x20 || snchar >= 0x7f) + break; + + // Otherwise copy... + *bufptr++ = (char)snchar; + } + + if (i >= snlen) + { + // Got a good string, return it... + *bufptr = '\0'; + return; + } + + // Convert string to HEX... + for (i = 2, bufptr = buffer, bufend = buffer + bufsize - 1; i < snlen && bufptr < bufend; i ++, bufptr += 2) + { + snprintf(bufptr, (size_t)(bufend - bufptr + 1), "%02X", snbuf[i]); + } + + if (i >= snlen) + return; // Converted all bytes to HEX... + + + // If we get here then we were not able to get a serial number string at all + // and have to hope that the bus and interface indices will be enough... + fallback: + + snprintf(buffer, bufsize, "%d.%d", device->conf, device->iface); +} + + +// // 'pappl_usb_close()' - Close a USB device. // @@ -387,8 +496,7 @@ if (libusb_get_string_descriptor_ascii(device->handle, devdesc.iProduct, (unsigned char *)temp_mdl, sizeof(temp_mdl)) <= 0) papplCopyString(temp_mdl, "Product", sizeof(temp_mdl)); - if (libusb_get_string_descriptor_ascii(device->handle, devdesc.iSerialNumber, (unsigned char *)sn, sizeof(sn)) <= 0) - snprintf(sn, sizeof(sn), "%d.%d", device->conf, device->iface); + get_serial_number(device, devdesc.iSerialNumber, sn, sizeof(sn)); if (!device->device_id[0]) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/httpmon-private.h new/pappl-1.4.10/pappl/httpmon-private.h --- old/pappl-1.4.9/pappl/httpmon-private.h 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/httpmon-private.h 2025-12-26 18:20:00.000000000 +0100 @@ -1,7 +1,7 @@ // // Private HTTP monitor definitions for the Printer Application Framework // -// Copyright © 2021-2022 by Michael R Sweet. +// Copyright © 2021-2025 by Michael R Sweet. // Copyright © 2012 by Apple Inc. // // Licensed under Apache License v2.0. See the file "LICENSE" for more @@ -38,7 +38,7 @@ typedef struct _pappl_http_buffer_s // HTTP data buffer { size_t used; // Bytes used in buffer - char data[HTTP_MAX_BUFFER]; // Data in buffer + char data[32768]; // Data in buffer } _pappl_http_buffer_t; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/httpmon.c new/pappl-1.4.10/pappl/httpmon.c --- old/pappl-1.4.9/pappl/httpmon.c 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/httpmon.c 2025-12-26 18:20:00.000000000 +0100 @@ -1,7 +1,7 @@ // // Private HTTP monitor implementation for the Printer Application Framework // -// Copyright © 2021 by Michael R Sweet. +// Copyright © 2021-2025 by Michael R Sweet. // Copyright © 2012 by Apple Inc. // // Licensed under Apache License v2.0. See the file "LICENSE" for more @@ -621,10 +621,10 @@ size_t bytes = 0; // Bytes to add - if (*datasize > 0 && hb->used < HTTP_MAX_BUFFER) + if (*datasize > 0 && hb->used < sizeof(hb->data)) { // Copy more data into client_data - if ((bytes = HTTP_MAX_BUFFER - hb->used) > *datasize) + if ((bytes = sizeof(hb->data) - hb->used) > *datasize) bytes = *datasize; memcpy(hb->data + hb->used, *data, bytes); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/job-filter.c new/pappl-1.4.10/pappl/job-filter.c --- old/pappl-1.4.9/pappl/job-filter.c 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/job-filter.c 2025-12-26 18:20:00.000000000 +0100 @@ -900,13 +900,7 @@ // Finish up... finish_png: - if (pp && info) - { - png_read_end(pp, info); - png_destroy_read_struct(&pp, &info, NULL); - pp = NULL; - info = NULL; - } + png_destroy_read_struct(&pp, &info, NULL); fclose(fp); fp = NULL; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/job-process.c new/pappl-1.4.10/pappl/job-process.c --- old/pappl-1.4.9/pappl/job-process.c 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/job-process.c 2025-12-26 18:20:00.000000000 +0100 @@ -538,7 +538,7 @@ if (!(filter->cb)(job, job->printer->device, filter->cbdata)) job->state = IPP_JSTATE_ABORTED; } - else if (!strcmp(job->format, job->printer->driver_data.format)) + else if (job->printer->driver_data.format && job->printer->driver_data.printfile_cb && !strcmp(job->format, job->printer->driver_data.format)) { if (!filter_raw(job, job->printer->device)) job->state = IPP_JSTATE_ABORTED; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/job.c new/pappl-1.4.10/pappl/job.c --- old/pappl-1.4.9/pappl/job.c 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/job.c 2025-12-26 18:20:00.000000000 +0100 @@ -511,7 +511,7 @@ if (!strcmp(mode, "r")) return (open(fname, O_RDONLY | O_NOFOLLOW | O_CLOEXEC | O_BINARY)); else if (!strcmp(mode, "w")) - return (open(fname, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW | O_CLOEXEC | O_BINARY, 0600)); + return (open(fname, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW | O_CLOEXEC | O_BINARY, 0400)); else if (!strcmp(mode, "x")) return (unlink(fname)); else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/mainloop-subcommands.c new/pappl-1.4.10/pappl/mainloop-subcommands.c --- old/pappl-1.4.9/pappl/mainloop-subcommands.c 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/mainloop-subcommands.c 2025-12-26 18:20:00.000000000 +0100 @@ -1,7 +1,7 @@ // // Standard papplMainloop sub-commands for the Printer Application Framework // -// Copyright © 2020-2024 by Michael R Sweet. +// Copyright © 2020-2025 by Michael R Sweet. // // Licensed under Apache License v2.0. See the file "LICENSE" for more // information. @@ -1135,6 +1135,7 @@ print_option(response, "media-tracking"); print_option(response, "media-type"); print_option(response, "orientation-requested"); + print_option(response, "output-bin"); print_option(response, "print-color-mode"); print_option(response, "print-content-optimize"); if (ippFindAttribute(response, "print-darkness-supported", IPP_TAG_ZERO)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/mainloop-support.c new/pappl-1.4.10/pappl/mainloop-support.c --- old/pappl-1.4.9/pappl/mainloop-support.c 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/mainloop-support.c 2025-12-26 18:20:00.000000000 +0100 @@ -1,7 +1,7 @@ // // papplMainloop support functions for the Printer Application Framework // -// Copyright © 2020-2024 by Michael R Sweet. +// Copyright © 2020-2025 by Michael R Sweet. // // Licensed under Apache License v2.0. See the file "LICENSE" for more // information. @@ -47,6 +47,7 @@ const char *value; // String value int intvalue; // Integer value const char *media_left_offset = cupsGetOption("media-left-offset", num_options, options), + *media_ready = cupsGetOption("media-ready", num_options, options), *media_source = cupsGetOption("media-source", num_options, options), *media_top_offset = cupsGetOption("media-top-offset", num_options, options), *media_tracking = cupsGetOption("media-tracking", num_options, options), @@ -172,10 +173,14 @@ ippAddIntegers(request, group_tag, IPP_TAG_ENUM, is_default ? "finishings-default" : "finishings", num_enumvalues, enumvalues); } - value = cupsGetOption("media", num_options, options); + if (is_default && media_ready) + value = media_ready; + else + value = cupsGetOption("media", num_options, options); + if (media_left_offset || media_source || media_top_offset || media_tracking || media_type) { - // Add media-col + // Add media-col/media-col-default/media-col-ready ipp_t *media_col = ippNew(); // media-col value pwg_media_t *pwg = pwgMediaForPWG(value); // Size @@ -205,13 +210,32 @@ if (media_type) ippAddString(media_col, IPP_TAG_ZERO, IPP_TAG_KEYWORD, "media-type", NULL, media_type); - ippAddCollection(request, group_tag, is_default ? "media-col-default" : "media-col", media_col); + if (is_default) + { + ippAddCollection(request, group_tag, "media-col-default", media_col); + if (media_ready) + ippAddCollection(request, group_tag, "media-col-ready", media_col); + } + else + { + ippAddCollection(request, group_tag, "media-col", media_col); + } + ippDelete(media_col); } else if (value) { - // Add media - ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, is_default ? "media-default" : "media", NULL, value); + // Add media/media-default/media-ready + if (is_default) + { + ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-default", NULL, value); + if (media_ready) + ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-ready", NULL, value); + } + else + { + ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "media", NULL, value); + } } if ((value = cupsGetOption("orientation-requested", num_options, options)) == NULL) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/printer-accessors.c new/pappl-1.4.10/pappl/printer-accessors.c --- old/pappl-1.4.9/pappl/printer-accessors.c 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/printer-accessors.c 2025-12-26 18:20:00.000000000 +0100 @@ -1,7 +1,7 @@ // // Printer accessor functions for the Printer Application Framework // -// Copyright © 2020-2024 by Michael R Sweet. +// Copyright © 2020-2025 by Michael R Sweet. // // Licensed under Apache License v2.0. See the file "LICENSE" for more // information. @@ -983,15 +983,17 @@ for (job = (pappl_job_t *)cupsArrayGetFirst(printer->active_jobs); job; job = (pappl_job_t *)cupsArrayGetNext(printer->active_jobs)) { + _papplRWLockWrite(job); + if (job->state == IPP_JSTATE_HELD && job->hold_until == 0 && !(job->state_reasons & PAPPL_JREASON_JOB_HOLD_UNTIL_SPECIFIED)) { // Release this job - _papplRWLockWrite(job); _papplJobReleaseNoLock(job, username); - _papplRWUnlock(job); released_jobs = true; } + + _papplRWUnlock(job); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/printer-driver.c new/pappl-1.4.10/pappl/printer-driver.c --- old/pappl-1.4.9/pappl/printer-driver.c 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/printer-driver.c 2025-12-26 18:20:00.000000000 +0100 @@ -1,7 +1,7 @@ // // Printer driver functions for the Printer Application Framework // -// Copyright © 2020-2024 by Michael R Sweet. +// Copyright © 2020-2025 by Michael R Sweet. // // Licensed under Apache License v2.0. See the file "LICENSE" for more // information. @@ -843,7 +843,14 @@ memcpy((void *)svalues, data->source, (size_t)num_values * sizeof(char *)); } - svalues[num_values ++] = "auto"; + for (i = 0; i < num_values; i ++) + { + if (!strcmp(svalues[i], "auto")) + break; + } + + if (i >= num_values) + svalues[num_values ++] = "auto"; ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "media-source-supported", num_values, NULL, svalues); @@ -1256,9 +1263,10 @@ "roll-10" }; - for (i = 0, ptr = is, *ptr = '\0', prefix = "IS"; i < (cups_len_t)data->num_source; i ++) + for (i = 0, ptr = is, *ptr = '\0', prefix = "IS0-"; i < (cups_len_t)data->num_source; i ++) { - for (j = 0; j < (int)(sizeof(iss) / sizeof(iss[0])); j ++) + // Skip "auto" (0) since that is always present... + for (j = 1; j < (int)(sizeof(iss) / sizeof(iss[0])); j ++) { if (!strcmp(iss[j], data->source[i])) { @@ -1548,6 +1556,11 @@ ret = false; } } + else if (data->format) + { + papplLogPrinter(printer, PAPPL_LOGLEVEL_ERROR, "Driver supports raw printing but hasn't set a print file callback."); + ret = false; + } if (!data->rendjob_cb || !data->rendpage_cb || !data->rstartjob_cb || !data->rstartpage_cb || !data->rwriteline_cb) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/printer-ipp.c new/pappl-1.4.10/pappl/printer-ipp.c --- old/pappl-1.4.9/pappl/printer-ipp.c 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/printer-ipp.c 2025-12-26 18:20:00.000000000 +0100 @@ -1,7 +1,7 @@ // // Printer IPP processing for the Printer Application Framework // -// Copyright © 2019-2024 by Michael R Sweet. +// Copyright © 2019-2025 by Michael R Sweet. // Copyright © 2010-2019 by Apple Inc. // // Licensed under Apache License v2.0. See the file "LICENSE" for more @@ -541,16 +541,16 @@ num_values = 0; - if (httpAddrIsLocalhost(httpGetAddress(client->http)) || !papplSystemGetTLSOnly(client->system)) + if (!httpAddrIsLocalhost(httpGetAddress(client->http)) && !(client->system->options & PAPPL_SOPTIONS_NO_TLS)) { - httpAssembleURI(HTTP_URI_CODING_ALL, uris[num_values], sizeof(uris[0]), "ipp", NULL, client->host_field, client->host_port, printer->resource); + httpAssembleURI(HTTP_URI_CODING_ALL, uris[num_values], sizeof(uris[0]), "ipps", NULL, client->host_field, client->host_port, printer->resource); values[num_values] = uris[num_values]; num_values ++; } - if (!httpAddrIsLocalhost(httpGetAddress(client->http)) && !(client->system->options & PAPPL_SOPTIONS_NO_TLS)) + if (httpAddrIsLocalhost(httpGetAddress(client->http)) || !papplSystemGetTLSOnly(client->system)) { - httpAssembleURI(HTTP_URI_CODING_ALL, uris[num_values], sizeof(uris[0]), "ipps", NULL, client->host_field, client->host_port, printer->resource); + httpAssembleURI(HTTP_URI_CODING_ALL, uris[num_values], sizeof(uris[0]), "ipp", NULL, client->host_field, client->host_port, printer->resource); values[num_values] = uris[num_values]; num_values ++; } @@ -609,8 +609,8 @@ { static const char * const uri_authentication_basic[] = { // uri-authentication-supported values - "none", - "basic" + "basic", + "none" }; ippAddStrings(client->response, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "uri-authentication-supported", 2, NULL, uri_authentication_basic); @@ -790,7 +790,9 @@ if (code == HTTP_STATUS_CONTINUE && client->job && client->job->username && strcmp(client->username, client->job->username)) { // Not the owner, try authorizing with admin group... + _papplRWLockRead(client->system); code = _papplClientIsAuthorizedForGroup(client, true, client->system->admin_group, client->system->admin_gid); + _papplRWUnlock(client->system); } if (code == HTTP_STATUS_CONTINUE) @@ -1604,7 +1606,9 @@ ippAddSeparator(client->response); count ++; + _papplRWLockRead(job); _papplJobCopyAttributesNoLock(job, client, ra); + _papplRWUnlock(job); } cupsArrayDelete(ra); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/printer-webif.c new/pappl-1.4.10/pappl/printer-webif.c --- old/pappl-1.4.9/pappl/printer-webif.c 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/printer-webif.c 2025-12-26 18:20:00.000000000 +0100 @@ -1,7 +1,7 @@ // // Printer web interface functions for the Printer Application Framework // -// Copyright © 2019-2024 by Michael R Sweet. +// Copyright © 2019-2025 by Michael R Sweet. // Copyright © 2010-2019 by Apple Inc. // // Licensed under Apache License v2.0. See the file "LICENSE" for more @@ -1001,7 +1001,7 @@ papplClientHTMLPrintf(client, "<input type=\"hidden\" name=\"action\" value=\"pause-printer\"><input type=\"submit\" value=\"%s\"></form>", papplClientGetLocString(client, _PAPPL_LOC("Pause Printing"))); } - if (printer->printer_id != printer->system->default_printer_id) + if (printer->printer_id != papplSystemGetDefaultPrinterID(printer->system)) { papplClientHTMLStartForm(client, uri, false); papplClientHTMLPrintf(client, "<input type=\"hidden\" name=\"action\" value=\"set-as-default\"><input type=\"submit\" value=\"%s\"></form>", papplClientGetLocString(client, _PAPPL_LOC("Set as Default"))); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/printer.c new/pappl-1.4.10/pappl/printer.c --- old/pappl-1.4.9/pappl/printer.c 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/printer.c 2025-12-26 18:20:00.000000000 +0100 @@ -227,8 +227,8 @@ }; static const char * const uri_security[] = { // uri-security-supported values - "none", - "tls" + "tls", + "none" }; static const char * const which_jobs[] = { // which-jobs-supported values diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/system-accessors.c new/pappl-1.4.10/pappl/system-accessors.c --- old/pappl-1.4.9/pappl/system-accessors.c 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/system-accessors.c 2025-12-26 18:20:00.000000000 +0100 @@ -146,8 +146,8 @@ if (system->port) { - ret = add_listeners(system, name, system->port, AF_INET) || - add_listeners(system, name, system->port, AF_INET6); + ret = add_listeners(system, name, system->port, AF_INET); + ret |= add_listeners(system, name, system->port, AF_INET6); } else { @@ -169,7 +169,7 @@ if (ret) { system->port = port; - add_listeners(system, name, port, AF_INET6); + ret |= add_listeners(system, name, port, AF_INET6); } } } @@ -1400,10 +1400,10 @@ // Note: Cannot use cupsArrayGetFirst/Last since other threads might be // enumerating the printers array. - _papplRWLockRead(system); + pthread_rwlock_rdlock(&system->printers_rwlock); for (i = 0, count = cupsArrayGetCount(system->printers); i < count; i ++) (cb)((pappl_printer_t *)cupsArrayGetElement(system->printers, i), data); - _papplRWUnlock(system); + pthread_rwlock_unlock(&system->printers_rwlock); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/system-ipp.c new/pappl-1.4.10/pappl/system-ipp.c --- old/pappl-1.4.9/pappl/system-ipp.c 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/system-ipp.c 2025-12-26 18:20:00.000000000 +0100 @@ -1,17 +1,13 @@ // // IPP processing for the Printer Application Framework // -// Copyright © 2019-2024 by Michael R Sweet. +// Copyright © 2019-2025 by Michael R Sweet. // Copyright © 2010-2019 by Apple Inc. // // Licensed under Apache License v2.0. See the file "LICENSE" for more // information. // -// -// Include necessary headers... -// - #include "pappl-private.h" @@ -456,6 +452,8 @@ { pappl_system_t *system = client->system; // System + cups_len_t i, // Looping var + count; // Number of printers pappl_printer_t *printer; // Current printer http_status_t auth_status; // Authorization status @@ -468,12 +466,14 @@ } // Loop through the printers... - _papplRWLockRead(system); - for (printer = (pappl_printer_t *)cupsArrayGetFirst(system->printers); printer; printer = (pappl_printer_t *)cupsArrayGetNext(system->printers)) + pthread_rwlock_rdlock(&system->printers_rwlock); + for (i = 0, count = cupsArrayGetCount(system->printers); i < count; i ++) { + printer = (pappl_printer_t *)cupsArrayGetElement(system->printers, i); + papplPrinterDisable(printer); } - _papplRWUnlock(system); + pthread_rwlock_unlock(&system->printers_rwlock); } @@ -487,6 +487,8 @@ { pappl_system_t *system = client->system; // System + cups_len_t i, // Looping var + count; // Number of printers pappl_printer_t *printer; // Current printer http_status_t auth_status; // Authorization status @@ -499,12 +501,14 @@ } // Loop through the printers... - _papplRWLockRead(system); - for (printer = (pappl_printer_t *)cupsArrayGetFirst(system->printers); printer; printer = (pappl_printer_t *)cupsArrayGetNext(system->printers)) + pthread_rwlock_rdlock(&system->printers_rwlock); + for (i = 0, count = cupsArrayGetCount(system->printers); i < count; i ++) { + printer = (pappl_printer_t *)cupsArrayGetElement(system->printers, i); + papplPrinterEnable(printer); } - _papplRWUnlock(system); + pthread_rwlock_unlock(&system->printers_rwlock); } @@ -783,7 +787,7 @@ papplClientRespondIPP(client, IPP_STATUS_OK, NULL); - _papplRWLockRead(system); + pthread_rwlock_rdlock(&system->printers_rwlock); // Enumerate the printers for the client... count = cupsArrayGetCount(system->printers); @@ -806,7 +810,7 @@ _papplRWUnlock(printer); } - _papplRWUnlock(system); + pthread_rwlock_unlock(&system->printers_rwlock); cupsArrayDelete(ra); } @@ -838,6 +842,7 @@ papplClientRespondIPP(client, IPP_STATUS_OK, NULL); _papplRWLockRead(system); + pthread_rwlock_rdlock(&system->printers_rwlock); _papplCopyAttributes(client->response, system->attrs, ra, IPP_TAG_ZERO, true); @@ -1006,6 +1011,7 @@ ippDelete(col); } + pthread_rwlock_unlock(&system->printers_rwlock); _papplRWUnlock(system); cupsArrayDelete(ra); @@ -1022,6 +1028,8 @@ { pappl_system_t *system = client->system; // System + cups_len_t i, // Looping var + count; // Number of printers pappl_printer_t *printer; // Current printer http_status_t auth_status; // Authorization status @@ -1034,12 +1042,14 @@ } // Loop through the printers... - _papplRWLockRead(system); - for (printer = (pappl_printer_t *)cupsArrayGetFirst(system->printers); printer; printer = (pappl_printer_t *)cupsArrayGetNext(system->printers)) + pthread_rwlock_rdlock(&system->printers_rwlock); + for (i = 0, count = cupsArrayGetCount(system->printers); i < count; i ++) { - papplPrinterPause(client->printer); + printer = (pappl_printer_t *)cupsArrayGetElement(system->printers, i); + + papplPrinterPause(printer); } - _papplRWUnlock(system); + pthread_rwlock_unlock(&system->printers_rwlock); } @@ -1053,6 +1063,8 @@ { pappl_system_t *system = client->system; // System + cups_len_t i, // Looping var + count; // Number of printers pappl_printer_t *printer; // Current printer http_status_t auth_status; // Authorization status @@ -1065,12 +1077,14 @@ } // Loop through the printers... - _papplRWLockRead(system); - for (printer = (pappl_printer_t *)cupsArrayGetFirst(system->printers); printer; printer = (pappl_printer_t *)cupsArrayGetNext(system->printers)) + pthread_rwlock_rdlock(&system->printers_rwlock); + for (i = 0, count = cupsArrayGetCount(system->printers); i < count; i ++) { - papplPrinterResume(client->printer); + printer = (pappl_printer_t *)cupsArrayGetElement(system->printers, i); + + papplPrinterResume(printer); } - _papplRWUnlock(system); + pthread_rwlock_unlock(&system->printers_rwlock); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/system-loadsave.c new/pappl-1.4.10/pappl/system-loadsave.c --- old/pappl-1.4.9/pappl/system-loadsave.c 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/system-loadsave.c 2025-12-26 18:20:00.000000000 +0100 @@ -1,7 +1,7 @@ // // System load/save functions for the Printer Application Framework // -// Copyright © 2020-2024 by Michael R Sweet. +// Copyright © 2020-2025 by Michael R Sweet. // // Licensed under Apache License v2.0. See the file "LICENSE" for more // information. @@ -443,6 +443,8 @@ // // Note: Cannot use cupsArrayGetFirst/Last since other threads might be // enumerating the printers array. + pthread_rwlock_rdlock(&system->printers_rwlock); + for (i = 0, count = cupsArrayGetCount(system->printers); i < count; i ++) { cups_len_t jcount; // Number of jobs @@ -620,6 +622,7 @@ _papplRWUnlock(printer); } + pthread_rwlock_unlock(&system->printers_rwlock); _papplRWUnlock(system); cupsFileClose(fp); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/system-printer.c new/pappl-1.4.10/pappl/system-printer.c --- old/pappl-1.4.9/pappl/system-printer.c 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/system-printer.c 2025-12-26 18:20:00.000000000 +0100 @@ -39,10 +39,12 @@ else printer->printer_id = system->next_printer_id ++; + pthread_rwlock_wrlock(&system->printers_rwlock); if (!system->printers) system->printers = cupsArrayNew((cups_array_cb_t)compare_printers, /*cb_data*/NULL, /*hash_cb*/NULL, /*hash_size*/0, /*copy_cb*/NULL, /*free_cb*/NULL); cupsArrayAdd(system->printers, printer); + pthread_rwlock_unlock(&system->printers_rwlock); if (!system->default_printer_id) system->default_printer_id = printer->printer_id; @@ -150,6 +152,8 @@ // Note: Cannot use cupsArrayGetFirst/Last since other threads might be // enumerating the printers array. + pthread_rwlock_rdlock(&system->printers_rwlock); + for (i = 0, count = cupsArrayGetCount(system->printers); i < count; i ++) { printer = (pappl_printer_t *)cupsArrayGetElement(system->printers, i); @@ -162,6 +166,8 @@ break; } + pthread_rwlock_unlock(&system->printers_rwlock); + if (i >= count) printer = NULL; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/system-private.h new/pappl-1.4.10/pappl/system-private.h --- old/pappl-1.4.9/pappl/system-private.h 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/system-private.h 2025-12-26 18:20:00.000000000 +0100 @@ -100,6 +100,7 @@ cups_array_t *localizations; // Array of localizations cups_array_t *filters; // Array of filters int next_client; // Next client number + pthread_rwlock_t printers_rwlock; // Printer array reader/writer lock cups_array_t *printers; // Array of printers int default_printer_id, // Default printer-id next_printer_id; // Next printer-id diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/system.c new/pappl-1.4.10/pappl/system.c --- old/pappl-1.4.9/pappl/system.c 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/system.c 2025-12-26 18:20:00.000000000 +0100 @@ -336,6 +336,7 @@ cupsArrayDelete(system->timers); pthread_rwlock_destroy(&system->rwlock); + pthread_rwlock_destroy(&system->printers_rwlock); pthread_mutex_destroy(&system->session_mutex); pthread_mutex_destroy(&system->config_mutex); pthread_mutex_destroy(&system->log_mutex); @@ -401,8 +402,7 @@ int pcount, // Poll count ptimeout; // Poll timeout pappl_client_t *client; // New client - char header[HTTP_MAX_VALUE]; - // Server: header value + char header[256]; // Server: header value int dns_sd_host_changes; // Current number of host name changes pappl_printer_t *printer; // Current printer @@ -537,6 +537,7 @@ _papplSystemRegisterDNSSDNoLock(system); // Start up printers... + pthread_rwlock_rdlock(&system->printers_rwlock); for (i = 0, count = cupsArrayGetCount(system->printers); i < count; i ++) { printer = (pappl_printer_t *)cupsArrayGetElement(system->printers, i); @@ -566,13 +567,18 @@ while (!printer->raw_active) { _papplRWUnlock(printer); + pthread_rwlock_unlock(&system->printers_rwlock); + usleep(1000); // Wait for raw thread to start + + pthread_rwlock_rdlock(&system->printers_rwlock); _papplRWLockRead(printer); } _papplRWUnlock(printer); } } } + pthread_rwlock_unlock(&system->printers_rwlock); // Start the USB gadget as needed... if ((system->options & PAPPL_SOPTIONS_USB_PRINTER) && (printer = papplSystemFindPrinter(system, NULL, system->default_printer_id, NULL)) != NULL) @@ -702,6 +708,7 @@ if (system->dns_sd_collision || force_dns_sd) _papplSystemRegisterDNSSDNoLock(system); + pthread_rwlock_rdlock(&system->printers_rwlock); for (i = 0, count = cupsArrayGetCount(system->printers); i < count; i ++) { printer = (pappl_printer_t *)cupsArrayGetElement(system->printers, i); @@ -709,6 +716,7 @@ if (printer->dns_sd_collision || force_dns_sd) _papplPrinterRegisterDNSSDNoLock(printer); } + pthread_rwlock_unlock(&system->printers_rwlock); system->dns_sd_any_collision = false; system->dns_sd_host_changes = dns_sd_host_changes; @@ -750,6 +758,7 @@ } // Otherwise shutdown immediately if there are no more active jobs... + pthread_rwlock_rdlock(&system->printers_rwlock); for (i = 0, count = cupsArrayGetCount(system->printers); i < count; i ++) { printer = (pappl_printer_t *)cupsArrayGetElement(system->printers, i); @@ -809,6 +818,7 @@ if (system->dns_sd_name) _papplSystemUnregisterDNSSDNoLock(system); + pthread_rwlock_rdlock(&system->printers_rwlock); for (i = 0, count = cupsArrayGetCount(system->printers); i < count; i ++) { printer = (pappl_printer_t *)cupsArrayGetElement(system->printers, i); @@ -817,6 +827,7 @@ if (printer->dns_sd_name) _papplPrinterUnregisterDNSSDNoLock(printer); } + pthread_rwlock_unlock(&system->printers_rwlock); system->is_running = false; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl/util.c new/pappl-1.4.10/pappl/util.c --- old/pappl-1.4.9/pappl/util.c 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl/util.c 2025-12-26 18:20:00.000000000 +0100 @@ -7,10 +7,6 @@ // information. // -// -// Include necessary headers... -// - #include "base-private.h" #ifdef HAVE_SYS_RANDOM_H # include <sys/random.h> @@ -24,6 +20,7 @@ #if CUPS_VERSION_MAJOR < 3 && CUPS_VERSION_MINOR < 5 static ipp_attribute_t *copy_col(ipp_t *dst, ipp_attribute_t *srcattr, int quickcopy); #endif // CUPS_VERSION_MAJOR < 3 && CUPS_VERSION_MINOR < 5 +static cups_bool_t filter_cb(_pappl_ipp_filter_t *filter, ipp_t *dst, ipp_attribute_t *attr); // @@ -38,31 +35,14 @@ ipp_tag_t group_tag, // I - Group to copy int quickcopy) // I - Do a quick copy? { - ipp_attribute_t *attr; // Current attribute - - - for (attr = ippGetFirstAttribute(from); attr; attr = ippGetNextAttribute(from)) - { - ipp_tag_t group = ippGetGroupTag(attr); - // Attribute group - const char *name = ippGetName(attr); - // Attribute name + _pappl_ipp_filter_t filter; // Copy filter - // Filter out attributes that are not requested... - if ((group_tag != IPP_TAG_ZERO && group != group_tag && group != IPP_TAG_ZERO) || !name || (!strcmp(name, "media-col-database") && !cupsArrayFind(ra, (void *)name))) - continue; - if (ra && !cupsArrayFind(ra, (void *)name)) - continue; + filter.ra = ra; + filter.group_tag = group_tag; + filter.quickcopy = quickcopy; - // Copy the attribute... -#if CUPS_VERSION_MAJOR < 3 && CUPS_VERSION_MINOR < 5 - if (ippGetValueTag(attr) == IPP_TAG_BEGIN_COLLECTION) - copy_col(to, attr, quickcopy); - else -#endif // CUPS_VERSION_MAJOR < 3 && CUPS_VERSION_MINOR < 5 - ippCopyAttribute(to, attr, quickcopy); - } + ippCopyAttributes(to, from, quickcopy, (ipp_copy_cb_t)filter_cb, &filter); } @@ -441,3 +421,44 @@ return (dstattr); } #endif // CUPS_VERSION_MAJOR < 3 && CUPS_VERSION_MINOR < 5 + + +// +// 'filter_cb()' - Filter printer attributes based on the requested array. +// + +static cups_bool_t // O - `CUPS_BOOL_TRUE` to copy, `CUPS_BOOL_FALSE` to ignore +filter_cb(_pappl_ipp_filter_t *filter, // I - Filter parameters + ipp_t *dst, // I - Destination (unused) + ipp_attribute_t *attr) // I - Source attribute +{ + ipp_tag_t group = ippGetGroupTag(attr); + // Attribute group + const char *name = ippGetName(attr); + // Attribute name + + +#ifndef _WIN32 /* Avoid MS compiler bug */ + (void)dst; +#endif /* !_WIN32 */ + + // Filter out attributes in the wrong group or the "media-col-database" attribute unless requested... + if ((filter->group_tag != IPP_TAG_ZERO && group != filter->group_tag && group != IPP_TAG_ZERO) || !name || (!strcmp(name, "media-col-database") && !cupsArrayFind(filter->ra, (void *)name))) + return (CUPS_BOOL_FALSE); + + // Otherwise filter attributes by name... + if (filter->ra && !cupsArrayFind(filter->ra, (void *)name)) + return (CUPS_BOOL_FALSE); + +#if CUPS_VERSION_MAJOR < 3 && CUPS_VERSION_MINOR < 5 + if (ippGetValueTag(attr) == IPP_TAG_BEGIN_COLLECTION) + { + // Copy the collection attribute manually since CUPS 2.4 and earlier has bugs... + copy_col(dst, attr, filter->quickcopy); + return (CUPS_BOOL_FALSE); + } +#endif // CUPS_VERSION_MAJOR < 3 && CUPS_VERSION_MINOR < 5 + + // Tell ippCopyAttributes to copy this attribute... + return (CUPS_BOOL_TRUE); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/pappl.spec new/pappl-1.4.10/pappl.spec --- old/pappl-1.4.9/pappl.spec 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/pappl.spec 2025-12-26 18:20:00.000000000 +0100 @@ -9,7 +9,7 @@ Summary: Printer Application Framework (PAPPL) Name: pappl -Version: 1.4.9 +Version: 1.4.10 Release: 1 License: Apache 2.0 Group: Development/Libraries diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/vcnet/config.h new/pappl-1.4.10/vcnet/config.h --- old/pappl-1.4.9/vcnet/config.h 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/vcnet/config.h 2025-12-26 18:20:00.000000000 +0100 @@ -107,7 +107,7 @@ // Version numbers -#define PAPPL_VERSION "1.4.9" +#define PAPPL_VERSION "1.4.10" #define PAPPL_VERSION_MAJOR 1 #define PAPPL_VERSION_MINOR 4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/vcnet/libpappl1_native.nuspec new/pappl-1.4.10/vcnet/libpappl1_native.nuspec --- old/pappl-1.4.9/vcnet/libpappl1_native.nuspec 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/vcnet/libpappl1_native.nuspec 2025-12-26 18:20:00.000000000 +0100 @@ -3,7 +3,7 @@ <metadata> <id>libpappl1_native</id> <title>Printer Application Framework (PAPPL) for VS2019+</title> - <version>1.4.9.0</version> + <version>1.4.10.0</version> <authors>Michael R Sweet</authors> <owners>michaelrsweet</owners> <projectUrl>https://github.com/michaelrsweet/pappl</projectUrl> @@ -18,7 +18,7 @@ <tags>airprint everywhere http ipp mopria native</tags> <dependencies> <dependency id="libcups2_native" version="2.4.11.1" /> - <dependency id="libpappl1_native.redist" version="1.4.9.0" /> + <dependency id="libpappl1_native.redist" version="1.4.10.0" /> </dependencies> </metadata> <files> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/vcnet/libpappl1_native.redist.nuspec new/pappl-1.4.10/vcnet/libpappl1_native.redist.nuspec --- old/pappl-1.4.9/vcnet/libpappl1_native.redist.nuspec 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/vcnet/libpappl1_native.redist.nuspec 2025-12-26 18:20:00.000000000 +0100 @@ -3,7 +3,7 @@ <metadata> <id>libpappl1_native.redist</id> <title>Printer Application Framework (PAPPL) for VS2019+ Redist</title> - <version>1.4.9.0</version> + <version>1.4.10.0</version> <authors>Michael R Sweet</authors> <owners>michaelrsweet</owners> <projectUrl>https://github.com/michaelrsweet/pappl</projectUrl> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/pappl-1.4.9/xcode/config.h new/pappl-1.4.10/xcode/config.h --- old/pappl-1.4.9/xcode/config.h 2025-03-20 17:50:33.000000000 +0100 +++ new/pappl-1.4.10/xcode/config.h 2025-12-26 18:20:00.000000000 +0100 @@ -8,7 +8,7 @@ // // Version numbers -#define PAPPL_VERSION "1.4.9" +#define PAPPL_VERSION "1.4.10" #define PAPPL_VERSION_MAJOR 1 #define PAPPL_VERSION_MINOR 4
