Radix cross Linux

The main Radix cross Linux repository contains the build scripts of packages, which have the most complete and common functionality for desktop machines

452 Commits   2 Branches   1 Tag
Index: Makefile
===================================================================
--- Makefile	(nonexistent)
+++ Makefile	(revision 5)
@@ -0,0 +1,60 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../build-system/constants.mk
+
+
+url         = $(DOWNLOAD_SERVER)/sources/packages/a/cups
+
+versions    = 2.4.2
+pkgname     = cups
+suffix      = tar.xz
+
+tarballs    = $(addsuffix .$(suffix), $(addprefix $(pkgname)-, $(versions)))
+sha1s       = $(addsuffix .sha1sum, $(tarballs))
+
+patches     = $(CURDIR)/patches/cups-2.4.2-freebind.patch
+patches    += $(CURDIR)/patches/cups-2.4.2-statedir.patch
+patches    += $(CURDIR)/patches/cups-2.4.2-tls-openssl.patch
+
+.NOTPARALLEL: $(patches)
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s) $(patches)
+
+
+include ../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+	@echo -e "\n======= Downloading source tarballs =======" ; \
+	 for tarball in $(tarballs) ; do \
+	   echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & \
+	 done ; wait
+
+$(sha1s): $(tarballs)
+	@for sha in $@ ; do \
+	   echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+	   echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & wait %1 ; \
+	   touch $$sha ; \
+	   echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+	   sha1sum --check $$sha ; ret="$$?" ; \
+	   if [ "$$ret" == "1" ]; then \
+	     echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+	     exit 1 ; \
+	   fi ; \
+	 done
+
+$(patches): $(sha1s)
+	@echo -e "\n======= Create Patches =======\n" ; \
+	 ( cd create-2.4.2-freebind-patch    ; ./create.patch.sh ) ; \
+	 ( cd create-2.4.2-statedir-patch    ; ./create.patch.sh ) ; \
+	 ( cd create-2.4.2-tls-openssl-patch ; ./create.patch.sh ) ; \
+	 echo -e "\n"
+
+download_clean:
+	@rm -f $(tarballs) $(sha1s) $(patches)
Index: create-2.4.2-freebind-patch/create.patch.sh
===================================================================
--- create-2.4.2-freebind-patch/create.patch.sh	(nonexistent)
+++ create-2.4.2-freebind-patch/create.patch.sh	(revision 5)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+VERSION=2.4.2
+
+tar --files-from=file.list -xJvf ../cups-$VERSION.tar.xz
+mv cups-$VERSION cups-$VERSION-orig
+
+cp -rf ./cups-$VERSION-new ./cups-$VERSION
+
+diff --unified -Nr  cups-$VERSION-orig  cups-$VERSION > cups-$VERSION-freebind.patch
+
+mv cups-$VERSION-freebind.patch ../patches
+
+rm -rf ./cups-$VERSION
+rm -rf ./cups-$VERSION-orig

Property changes on: create-2.4.2-freebind-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: create-2.4.2-freebind-patch/cups-2.4.2-new/cups/http-addr.c
===================================================================
--- create-2.4.2-freebind-patch/cups-2.4.2-new/cups/http-addr.c	(nonexistent)
+++ create-2.4.2-freebind-patch/cups-2.4.2-new/cups/http-addr.c	(revision 5)
@@ -0,0 +1,944 @@
+/*
+ * HTTP address routines for CUPS.
+ *
+ * Copyright © 2007-2021 by Apple Inc.
+ * Copyright © 1997-2006 by Easy Software Products, all rights reserved.
+ *
+ * Licensed under Apache License v2.0.  See the file "LICENSE" for more
+ * information.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cups-private.h"
+#include "debug-internal.h"
+#include <sys/stat.h>
+#ifdef HAVE_RESOLV_H
+#  include <resolv.h>
+#endif /* HAVE_RESOLV_H */
+#ifdef __APPLE__
+#  include <CoreFoundation/CoreFoundation.h>
+#  ifdef HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME
+#    include <SystemConfiguration/SystemConfiguration.h>
+#  endif /* HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME */
+#endif /* __APPLE__ */
+
+
+/*
+ * 'httpAddrAny()' - Check for the "any" address.
+ *
+ * @since CUPS 1.2/macOS 10.5@
+ */
+
+int					/* O - 1 if "any", 0 otherwise */
+httpAddrAny(const http_addr_t *addr)	/* I - Address to check */
+{
+  if (!addr)
+    return (0);
+
+#ifdef AF_INET6
+  if (addr->addr.sa_family == AF_INET6 &&
+      IN6_IS_ADDR_UNSPECIFIED(&(addr->ipv6.sin6_addr)))
+    return (1);
+#endif /* AF_INET6 */
+
+  if (addr->addr.sa_family == AF_INET &&
+      ntohl(addr->ipv4.sin_addr.s_addr) == 0x00000000)
+    return (1);
+
+  return (0);
+}
+
+
+/*
+ * 'httpAddrClose()' - Close a socket created by @link httpAddrConnect@ or
+ *                     @link httpAddrListen@.
+ *
+ * Pass @code NULL@ for sockets created with @link httpAddrConnect2@ and the
+ * listen address for sockets created with @link httpAddrListen@.  This function
+ * ensures that domain sockets are removed when closed.
+ *
+ * @since CUPS 2.0/OS 10.10@
+ */
+
+int						/* O - 0 on success, -1 on failure */
+httpAddrClose(http_addr_t *addr,		/* I - Listen address or @code NULL@ */
+              int         fd)			/* I - Socket file descriptor */
+{
+#ifdef _WIN32
+  if (closesocket(fd))
+#else
+  if (close(fd))
+#endif /* _WIN32 */
+    return (-1);
+
+#ifdef AF_LOCAL
+  if (addr && addr->addr.sa_family == AF_LOCAL)
+    return (unlink(addr->un.sun_path));
+#endif /* AF_LOCAL */
+
+  return (0);
+}
+
+
+/*
+ * 'httpAddrEqual()' - Compare two addresses.
+ *
+ * @since CUPS 1.2/macOS 10.5@
+ */
+
+int						/* O - 1 if equal, 0 if not */
+httpAddrEqual(const http_addr_t *addr1,		/* I - First address */
+              const http_addr_t *addr2)		/* I - Second address */
+{
+  if (!addr1 && !addr2)
+    return (1);
+
+  if (!addr1 || !addr2)
+    return (0);
+
+  if (addr1->addr.sa_family != addr2->addr.sa_family)
+    return (0);
+
+#ifdef AF_LOCAL
+  if (addr1->addr.sa_family == AF_LOCAL)
+    return (!strcmp(addr1->un.sun_path, addr2->un.sun_path));
+#endif /* AF_LOCAL */
+
+#ifdef AF_INET6
+  if (addr1->addr.sa_family == AF_INET6)
+    return (!memcmp(&(addr1->ipv6.sin6_addr), &(addr2->ipv6.sin6_addr), 16));
+#endif /* AF_INET6 */
+
+  return (addr1->ipv4.sin_addr.s_addr == addr2->ipv4.sin_addr.s_addr);
+}
+
+
+/*
+ * 'httpAddrLength()' - Return the length of the address in bytes.
+ *
+ * @since CUPS 1.2/macOS 10.5@
+ */
+
+int					/* O - Length in bytes */
+httpAddrLength(const http_addr_t *addr)	/* I - Address */
+{
+  if (!addr)
+    return (0);
+
+#ifdef AF_INET6
+  if (addr->addr.sa_family == AF_INET6)
+    return (sizeof(addr->ipv6));
+  else
+#endif /* AF_INET6 */
+#ifdef AF_LOCAL
+  if (addr->addr.sa_family == AF_LOCAL)
+    return ((int)(offsetof(struct sockaddr_un, sun_path) + strlen(addr->un.sun_path) + 1));
+  else
+#endif /* AF_LOCAL */
+  if (addr->addr.sa_family == AF_INET)
+    return (sizeof(addr->ipv4));
+  else
+    return (0);
+
+}
+
+
+/*
+ * 'httpAddrListen()' - Create a listening socket bound to the specified
+ *                      address and port.
+ *
+ * @since CUPS 1.7/macOS 10.9@
+ */
+
+int					/* O - Socket or -1 on error */
+httpAddrListen(http_addr_t *addr,	/* I - Address to bind to */
+               int         port)	/* I - Port number to bind to */
+{
+  int		fd = -1,		/* Socket */
+		val,			/* Socket value */
+                status;			/* Bind status */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (!addr || port < 0)
+    return (-1);
+
+ /*
+  * Make sure the network stack is initialized...
+  */
+
+  httpInitialize();
+
+ /*
+  * Create the socket and set options...
+  */
+
+  if ((fd = socket(addr->addr.sa_family, SOCK_STREAM, 0)) < 0)
+  {
+    _cupsSetHTTPError(HTTP_STATUS_ERROR);
+    return (-1);
+  }
+
+  val = 1;
+  setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, CUPS_SOCAST &val, sizeof(val));
+
+#ifdef __linux
+  setsockopt(fd, IPPROTO_IP, IP_FREEBIND, CUPS_SOCAST &val, sizeof(val));
+#endif /* __linux */
+
+#ifdef IPV6_V6ONLY
+  if (addr->addr.sa_family == AF_INET6)
+    setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, CUPS_SOCAST &val, sizeof(val));
+#endif /* IPV6_V6ONLY */
+
+ /*
+  * Bind the socket...
+  */
+
+#ifdef AF_LOCAL
+  if (addr->addr.sa_family == AF_LOCAL)
+  {
+    mode_t	mask;			/* Umask setting */
+
+   /*
+    * Remove any existing domain socket file...
+    */
+
+    unlink(addr->un.sun_path);
+
+   /*
+    * Save the current umask and set it to 0 so that all users can access
+    * the domain socket...
+    */
+
+    mask = umask(0);
+
+   /*
+    * Bind the domain socket...
+    */
+
+    status = bind(fd, (struct sockaddr *)addr, (socklen_t)httpAddrLength(addr));
+
+   /*
+    * Restore the umask and fix permissions...
+    */
+
+    umask(mask);
+    chmod(addr->un.sun_path, 0140777);
+  }
+  else
+#endif /* AF_LOCAL */
+  {
+    _httpAddrSetPort(addr, port);
+
+    status = bind(fd, (struct sockaddr *)addr, (socklen_t)httpAddrLength(addr));
+  }
+
+  if (status)
+  {
+    _cupsSetHTTPError(HTTP_STATUS_ERROR);
+
+    close(fd);
+
+    return (-1);
+  }
+
+ /*
+  * Listen...
+  */
+
+  if (listen(fd, 128))
+  {
+    _cupsSetHTTPError(HTTP_STATUS_ERROR);
+
+    close(fd);
+
+    return (-1);
+  }
+
+ /*
+  * Close on exec...
+  */
+
+#ifndef _WIN32
+  fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+#endif /* !_WIN32 */
+
+#ifdef SO_NOSIGPIPE
+ /*
+  * Disable SIGPIPE for this socket.
+  */
+
+  val = 1;
+  setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, CUPS_SOCAST &val, sizeof(val));
+#endif /* SO_NOSIGPIPE */
+
+  return (fd);
+}
+
+
+/*
+ * 'httpAddrLocalhost()' - Check for the local loopback address.
+ *
+ * @since CUPS 1.2/macOS 10.5@
+ */
+
+int					/* O - 1 if local host, 0 otherwise */
+httpAddrLocalhost(
+    const http_addr_t *addr)		/* I - Address to check */
+{
+  if (!addr)
+    return (1);
+
+#ifdef AF_INET6
+  if (addr->addr.sa_family == AF_INET6 &&
+      IN6_IS_ADDR_LOOPBACK(&(addr->ipv6.sin6_addr)))
+    return (1);
+#endif /* AF_INET6 */
+
+#ifdef AF_LOCAL
+  if (addr->addr.sa_family == AF_LOCAL)
+    return (1);
+#endif /* AF_LOCAL */
+
+  if (addr->addr.sa_family == AF_INET &&
+      (ntohl(addr->ipv4.sin_addr.s_addr) & 0xff000000) == 0x7f000000)
+    return (1);
+
+  return (0);
+}
+
+
+/*
+ * 'httpAddrLookup()' - Lookup the hostname associated with the address.
+ *
+ * @since CUPS 1.2/macOS 10.5@
+ */
+
+char *					/* O - Host name */
+httpAddrLookup(
+    const http_addr_t *addr,		/* I - Address to lookup */
+    char              *name,		/* I - Host name buffer */
+    int               namelen)		/* I - Size of name buffer */
+{
+  _cups_globals_t	*cg = _cupsGlobals();
+					/* Global data */
+
+
+  DEBUG_printf(("httpAddrLookup(addr=%p, name=%p, namelen=%d)", (void *)addr, (void *)name, namelen));
+
+ /*
+  * Range check input...
+  */
+
+  if (!addr || !name || namelen <= 2)
+  {
+    if (name && namelen >= 1)
+      *name = '\0';
+
+    return (NULL);
+  }
+
+#ifdef AF_LOCAL
+  if (addr->addr.sa_family == AF_LOCAL)
+  {
+    strlcpy(name, addr->un.sun_path, (size_t)namelen);
+    return (name);
+  }
+#endif /* AF_LOCAL */
+
+ /*
+  * Optimize lookups for localhost/loopback addresses...
+  */
+
+  if (httpAddrLocalhost(addr))
+  {
+    strlcpy(name, "localhost", (size_t)namelen);
+    return (name);
+  }
+
+#ifdef HAVE_RES_INIT
+ /*
+  * STR #2920: Initialize resolver after failure in cups-polld
+  *
+  * If the previous lookup failed, re-initialize the resolver to prevent
+  * temporary network errors from persisting.  This *should* be handled by
+  * the resolver libraries, but apparently the glibc folks do not agree.
+  *
+  * We set a flag at the end of this function if we encounter an error that
+  * requires reinitialization of the resolver functions.  We then call
+  * res_init() if the flag is set on the next call here or in httpAddrLookup().
+  */
+
+  if (cg->need_res_init)
+  {
+    res_init();
+
+    cg->need_res_init = 0;
+  }
+#endif /* HAVE_RES_INIT */
+
+#ifdef HAVE_GETNAMEINFO
+  {
+   /*
+    * STR #2486: httpAddrLookup() fails when getnameinfo() returns EAI_AGAIN
+    *
+    * FWIW, I think this is really a bug in the implementation of
+    * getnameinfo(), but falling back on httpAddrString() is easy to
+    * do...
+    */
+
+    int error = getnameinfo(&addr->addr, (socklen_t)httpAddrLength(addr), name, (socklen_t)namelen, NULL, 0, 0);
+
+    if (error)
+    {
+      if (error == EAI_FAIL)
+        cg->need_res_init = 1;
+
+      return (httpAddrString(addr, name, namelen));
+    }
+  }
+#else
+  {
+    struct hostent	*host;			/* Host from name service */
+
+
+#  ifdef AF_INET6
+    if (addr->addr.sa_family == AF_INET6)
+      host = gethostbyaddr((char *)&(addr->ipv6.sin6_addr),
+                	   sizeof(struct in_addr), AF_INET6);
+    else
+#  endif /* AF_INET6 */
+    host = gethostbyaddr((char *)&(addr->ipv4.sin_addr),
+                	 sizeof(struct in_addr), AF_INET);
+
+    if (host == NULL)
+    {
+     /*
+      * No hostname, so return the raw address...
+      */
+
+      if (h_errno == NO_RECOVERY)
+        cg->need_res_init = 1;
+
+      return (httpAddrString(addr, name, namelen));
+    }
+
+    strlcpy(name, host->h_name, (size_t)namelen);
+  }
+#endif /* HAVE_GETNAMEINFO */
+
+  DEBUG_printf(("1httpAddrLookup: returning \"%s\"...", name));
+
+  return (name);
+}
+
+
+/*
+ * 'httpAddrFamily()' - Get the address family of an address.
+ */
+
+int					/* O - Address family */
+httpAddrFamily(http_addr_t *addr)	/* I - Address */
+{
+  if (addr)
+    return (addr->addr.sa_family);
+  else
+    return (0);
+}
+
+
+/*
+ * 'httpAddrPort()' - Get the port number associated with an address.
+ *
+ * @since CUPS 1.7/macOS 10.9@
+ */
+
+int					/* O - Port number */
+httpAddrPort(http_addr_t *addr)		/* I - Address */
+{
+  if (!addr)
+    return (-1);
+#ifdef AF_INET6
+  else if (addr->addr.sa_family == AF_INET6)
+    return (ntohs(addr->ipv6.sin6_port));
+#endif /* AF_INET6 */
+  else if (addr->addr.sa_family == AF_INET)
+    return (ntohs(addr->ipv4.sin_port));
+  else
+    return (0);
+}
+
+
+/*
+ * '_httpAddrSetPort()' - Set the port number associated with an address.
+ */
+
+void
+_httpAddrSetPort(http_addr_t *addr,	/* I - Address */
+                 int         port)	/* I - Port */
+{
+  if (!addr || port <= 0)
+    return;
+
+#ifdef AF_INET6
+  if (addr->addr.sa_family == AF_INET6)
+    addr->ipv6.sin6_port = htons(port);
+  else
+#endif /* AF_INET6 */
+  if (addr->addr.sa_family == AF_INET)
+    addr->ipv4.sin_port = htons(port);
+}
+
+
+/*
+ * 'httpAddrString()' - Convert an address to a numeric string.
+ *
+ * @since CUPS 1.2/macOS 10.5@
+ */
+
+char *					/* O - Numeric address string */
+httpAddrString(const http_addr_t *addr,	/* I - Address to convert */
+               char              *s,	/* I - String buffer */
+	       int               slen)	/* I - Length of string */
+{
+  DEBUG_printf(("httpAddrString(addr=%p, s=%p, slen=%d)", (void *)addr, (void *)s, slen));
+
+ /*
+  * Range check input...
+  */
+
+  if (!addr || !s || slen <= 2)
+  {
+    if (s && slen >= 1)
+      *s = '\0';
+
+    return (NULL);
+  }
+
+#ifdef AF_LOCAL
+  if (addr->addr.sa_family == AF_LOCAL)
+  {
+    if (addr->un.sun_path[0] == '/')
+      strlcpy(s, addr->un.sun_path, (size_t)slen);
+    else
+      strlcpy(s, "localhost", (size_t)slen);
+  }
+  else
+#endif /* AF_LOCAL */
+  if (addr->addr.sa_family == AF_INET)
+  {
+    unsigned temp;			/* Temporary address */
+
+    temp = ntohl(addr->ipv4.sin_addr.s_addr);
+
+    snprintf(s, (size_t)slen, "%d.%d.%d.%d", (temp >> 24) & 255,
+             (temp >> 16) & 255, (temp >> 8) & 255, temp & 255);
+  }
+#ifdef AF_INET6
+  else if (addr->addr.sa_family == AF_INET6)
+  {
+    char	*sptr,			/* Pointer into string */
+		temps[64];		/* Temporary string for address */
+
+#  ifdef HAVE_GETNAMEINFO
+    if (getnameinfo(&addr->addr, (socklen_t)httpAddrLength(addr), temps, sizeof(temps), NULL, 0, NI_NUMERICHOST))
+    {
+     /*
+      * If we get an error back, then the address type is not supported
+      * and we should zero out the buffer...
+      */
+
+      s[0] = '\0';
+
+      return (NULL);
+    }
+    else if ((sptr = strchr(temps, '%')) != NULL)
+    {
+     /*
+      * Convert "%zone" to "+zone" to match URI form...
+      */
+
+      *sptr = '+';
+    }
+
+#  else
+    int		i;			/* Looping var */
+    unsigned	temp;			/* Current value */
+    const char	*prefix;		/* Prefix for address */
+
+
+    prefix = "";
+    for (sptr = temps, i = 0; i < 4 && addr->ipv6.sin6_addr.s6_addr32[i]; i ++)
+    {
+      temp = ntohl(addr->ipv6.sin6_addr.s6_addr32[i]);
+
+      snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s%x", prefix, (temp >> 16) & 0xffff);
+      prefix = ":";
+      sptr += strlen(sptr);
+
+      temp &= 0xffff;
+
+      if (temp || i == 3 || addr->ipv6.sin6_addr.s6_addr32[i + 1])
+      {
+        snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s%x", prefix, temp);
+	sptr += strlen(sptr);
+      }
+    }
+
+    if (i < 4)
+    {
+      while (i < 4 && !addr->ipv6.sin6_addr.s6_addr32[i])
+	i ++;
+
+      if (i < 4)
+      {
+        snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s:", prefix);
+	prefix = ":";
+	sptr += strlen(sptr);
+
+	for (; i < 4; i ++)
+	{
+          temp = ntohl(addr->ipv6.sin6_addr.s6_addr32[i]);
+
+          if ((temp & 0xffff0000) ||
+	      (i > 0 && addr->ipv6.sin6_addr.s6_addr32[i - 1]))
+	  {
+            snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s%x", prefix, (temp >> 16) & 0xffff);
+	    sptr += strlen(sptr);
+          }
+
+          snprintf(sptr, sizeof(temps) - (size_t)(sptr - temps), "%s%x", prefix, temp & 0xffff);
+	  sptr += strlen(sptr);
+	}
+      }
+      else if (sptr == s)
+      {
+       /*
+        * Empty address...
+	*/
+
+        strlcpy(temps, "::", sizeof(temps));
+      }
+      else
+      {
+       /*
+	* Empty at end...
+	*/
+
+        strlcpy(sptr, "::", sizeof(temps) - (size_t)(sptr - temps));
+      }
+    }
+#  endif /* HAVE_GETNAMEINFO */
+
+   /*
+    * Add "[v1." and "]" around IPv6 address to convert to URI form.
+    */
+
+    snprintf(s, (size_t)slen, "[v1.%s]", temps);
+  }
+#endif /* AF_INET6 */
+  else
+    strlcpy(s, "UNKNOWN", (size_t)slen);
+
+  DEBUG_printf(("1httpAddrString: returning \"%s\"...", s));
+
+  return (s);
+}
+
+
+/*
+ * 'httpGetAddress()' - Get the address of the connected peer of a connection.
+ *
+ * For connections created with @link httpConnect2@, the address is for the
+ * server.  For connections created with @link httpAccept@, the address is for
+ * the client.
+ *
+ * Returns @code NULL@ if the socket is currently unconnected.
+ *
+ * @since CUPS 2.0/OS 10.10@
+ */
+
+http_addr_t *				/* O - Connected address or @code NULL@ */
+httpGetAddress(http_t *http)		/* I - HTTP connection */
+{
+  if (http)
+    return (http->hostaddr);
+  else
+    return (NULL);
+}
+
+
+/*
+ * 'httpGetHostByName()' - Lookup a hostname or IPv4 address, and return
+ *                         address records for the specified name.
+ *
+ * @deprecated@ @exclude all@
+ */
+
+struct hostent *			/* O - Host entry */
+httpGetHostByName(const char *name)	/* I - Hostname or IP address */
+{
+  const char		*nameptr;	/* Pointer into name */
+  unsigned		ip[4];		/* IP address components */
+  _cups_globals_t	*cg = _cupsGlobals();
+  					/* Pointer to library globals */
+
+
+  DEBUG_printf(("httpGetHostByName(name=\"%s\")", name));
+
+ /*
+  * Avoid lookup delays and configuration problems when connecting
+  * to the localhost address...
+  */
+
+  if (!strcmp(name, "localhost"))
+    name = "127.0.0.1";
+
+ /*
+  * This function is needed because some operating systems have a
+  * buggy implementation of gethostbyname() that does not support
+  * IP addresses.  If the first character of the name string is a
+  * number, then sscanf() is used to extract the IP components.
+  * We then pack the components into an IPv4 address manually,
+  * since the inet_aton() function is deprecated.  We use the
+  * htonl() macro to get the right byte order for the address.
+  *
+  * We also support domain sockets when supported by the underlying
+  * OS...
+  */
+
+#ifdef AF_LOCAL
+  if (name[0] == '/')
+  {
+   /*
+    * A domain socket address, so make an AF_LOCAL entry and return it...
+    */
+
+    cg->hostent.h_name      = (char *)name;
+    cg->hostent.h_aliases   = NULL;
+    cg->hostent.h_addrtype  = AF_LOCAL;
+    cg->hostent.h_length    = (int)strlen(name) + 1;
+    cg->hostent.h_addr_list = cg->ip_ptrs;
+    cg->ip_ptrs[0]          = (char *)name;
+    cg->ip_ptrs[1]          = NULL;
+
+    DEBUG_puts("1httpGetHostByName: returning domain socket address...");
+
+    return (&cg->hostent);
+  }
+#endif /* AF_LOCAL */
+
+  for (nameptr = name; isdigit(*nameptr & 255) || *nameptr == '.'; nameptr ++);
+
+  if (!*nameptr)
+  {
+   /*
+    * We have an IPv4 address; break it up and provide the host entry
+    * to the caller.
+    */
+
+    if (sscanf(name, "%u.%u.%u.%u", ip, ip + 1, ip + 2, ip + 3) != 4)
+      return (NULL);			/* Must have 4 numbers */
+
+    if (ip[0] > 255 || ip[1] > 255 || ip[2] > 255 || ip[3] > 255)
+      return (NULL);			/* Invalid byte ranges! */
+
+    cg->ip_addr = htonl((((((((unsigned)ip[0] << 8) | (unsigned)ip[1]) << 8) |
+                           (unsigned)ip[2]) << 8) |
+                         (unsigned)ip[3]));
+
+   /*
+    * Fill in the host entry and return it...
+    */
+
+    cg->hostent.h_name      = (char *)name;
+    cg->hostent.h_aliases   = NULL;
+    cg->hostent.h_addrtype  = AF_INET;
+    cg->hostent.h_length    = 4;
+    cg->hostent.h_addr_list = cg->ip_ptrs;
+    cg->ip_ptrs[0]          = (char *)&(cg->ip_addr);
+    cg->ip_ptrs[1]          = NULL;
+
+    DEBUG_puts("1httpGetHostByName: returning IPv4 address...");
+
+    return (&cg->hostent);
+  }
+  else
+  {
+   /*
+    * Use the gethostbyname() function to get the IPv4 address for
+    * the name...
+    */
+
+    DEBUG_puts("1httpGetHostByName: returning domain lookup address(es)...");
+
+    return (gethostbyname(name));
+  }
+}
+
+
+/*
+ * 'httpGetHostname()' - Get the FQDN for the connection or local system.
+ *
+ * When "http" points to a connected socket, return the hostname or
+ * address that was used in the call to httpConnect() or httpConnectEncrypt(),
+ * or the address of the client for the connection from httpAcceptConnection().
+ * Otherwise, return the FQDN for the local system using both gethostname()
+ * and gethostbyname() to get the local hostname with domain.
+ *
+ * @since CUPS 1.2/macOS 10.5@
+ */
+
+const char *				/* O - FQDN for connection or system */
+httpGetHostname(http_t *http,		/* I - HTTP connection or NULL */
+                char   *s,		/* I - String buffer for name */
+                int    slen)		/* I - Size of buffer */
+{
+  if (http)
+  {
+    if (!s || slen <= 1)
+    {
+      if (http->hostname[0] == '/')
+	return ("localhost");
+      else
+	return (http->hostname);
+    }
+    else if (http->hostname[0] == '/')
+      strlcpy(s, "localhost", (size_t)slen);
+    else
+      strlcpy(s, http->hostname, (size_t)slen);
+  }
+  else
+  {
+   /*
+    * Get the hostname...
+    */
+
+    if (!s || slen <= 1)
+      return (NULL);
+
+    if (gethostname(s, (size_t)slen) < 0)
+      strlcpy(s, "localhost", (size_t)slen);
+
+    if (!strchr(s, '.'))
+    {
+#ifdef HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME
+     /*
+      * The hostname is not a FQDN, so use the local hostname from the
+      * SystemConfiguration framework...
+      */
+
+      SCDynamicStoreRef	sc = SCDynamicStoreCreate(kCFAllocatorDefault,
+                                                  CFSTR("libcups"), NULL, NULL);
+					/* System configuration data */
+      CFStringRef	local = sc ? SCDynamicStoreCopyLocalHostName(sc) : NULL;
+					/* Local host name */
+      char		localStr[1024];	/* Local host name C string */
+
+      if (local && CFStringGetCString(local, localStr, sizeof(localStr),
+                                      kCFStringEncodingUTF8))
+      {
+       /*
+        * Append ".local." to the hostname we get...
+	*/
+
+        snprintf(s, (size_t)slen, "%s.local.", localStr);
+      }
+
+      if (local)
+        CFRelease(local);
+      if (sc)
+        CFRelease(sc);
+
+#else
+     /*
+      * The hostname is not a FQDN, so look it up...
+      */
+
+      struct hostent	*host;		/* Host entry to get FQDN */
+
+      if ((host = gethostbyname(s)) != NULL && host->h_name)
+      {
+       /*
+        * Use the resolved hostname...
+	*/
+
+	strlcpy(s, host->h_name, (size_t)slen);
+      }
+#endif /* HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME */
+    }
+
+   /*
+    * Make sure .local hostnames end with a period...
+    */
+
+    if (strlen(s) > 6 && !strcmp(s + strlen(s) - 6, ".local"))
+      strlcat(s, ".", (size_t)slen);
+  }
+
+ /*
+  * Convert the hostname to lowercase as needed...
+  */
+
+  if (s[0] != '/')
+  {
+    char	*ptr;			/* Pointer into string */
+
+    for (ptr = s; *ptr; ptr ++)
+      *ptr = (char)_cups_tolower((int)*ptr);
+  }
+
+ /*
+  * Return the hostname with as much domain info as we have...
+  */
+
+  return (s);
+}
+
+
+/*
+ * 'httpResolveHostname()' - Resolve the hostname of the HTTP connection
+ *                           address.
+ *
+ * @since CUPS 2.0/OS 10.10@
+ */
+
+const char *				/* O - Resolved hostname or @code NULL@ */
+httpResolveHostname(http_t *http,	/* I - HTTP connection */
+                    char   *buffer,	/* I - Hostname buffer */
+                    size_t bufsize)	/* I - Size of buffer */
+{
+  if (!http)
+    return (NULL);
+
+  if (isdigit(http->hostname[0] & 255) || http->hostname[0] == '[')
+  {
+    char	temp[1024];		/* Temporary string */
+
+    if (httpAddrLookup(http->hostaddr, temp, sizeof(temp)))
+      strlcpy(http->hostname, temp, sizeof(http->hostname));
+    else
+      return (NULL);
+  }
+
+  if (buffer)
+  {
+    if (http->hostname[0] == '/')
+      strlcpy(buffer, "localhost", bufsize);
+    else
+      strlcpy(buffer, http->hostname, bufsize);
+
+    return (buffer);
+  }
+  else if (http->hostname[0] == '/')
+    return ("localhost");
+  else
+    return (http->hostname);
+}
Index: create-2.4.2-freebind-patch/cups-2.4.2-new/cups
===================================================================
--- create-2.4.2-freebind-patch/cups-2.4.2-new/cups	(nonexistent)
+++ create-2.4.2-freebind-patch/cups-2.4.2-new/cups	(revision 5)

Property changes on: create-2.4.2-freebind-patch/cups-2.4.2-new/cups
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-2.4.2-freebind-patch/cups-2.4.2-new
===================================================================
--- create-2.4.2-freebind-patch/cups-2.4.2-new	(nonexistent)
+++ create-2.4.2-freebind-patch/cups-2.4.2-new	(revision 5)

Property changes on: create-2.4.2-freebind-patch/cups-2.4.2-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-2.4.2-freebind-patch/file.list
===================================================================
--- create-2.4.2-freebind-patch/file.list	(nonexistent)
+++ create-2.4.2-freebind-patch/file.list	(revision 5)
@@ -0,0 +1 @@
+cups-2.4.2/cups/http-addr.c
Index: create-2.4.2-freebind-patch
===================================================================
--- create-2.4.2-freebind-patch	(nonexistent)
+++ create-2.4.2-freebind-patch	(revision 5)

Property changes on: create-2.4.2-freebind-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-2.4.2-statedir-patch/create.patch.sh
===================================================================
--- create-2.4.2-statedir-patch/create.patch.sh	(nonexistent)
+++ create-2.4.2-statedir-patch/create.patch.sh	(revision 5)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+VERSION=2.4.2
+
+tar --files-from=file.list -xJvf ../cups-$VERSION.tar.xz
+mv cups-$VERSION cups-$VERSION-orig
+
+cp -rf ./cups-$VERSION-new ./cups-$VERSION
+
+diff --unified -Nr  cups-$VERSION-orig  cups-$VERSION > cups-$VERSION-statedir.patch
+
+mv cups-$VERSION-statedir.patch ../patches
+
+rm -rf ./cups-$VERSION
+rm -rf ./cups-$VERSION-orig

Property changes on: create-2.4.2-statedir-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: create-2.4.2-statedir-patch/cups-2.4.2-new/config-scripts/cups-directories.m4
===================================================================
--- create-2.4.2-statedir-patch/cups-2.4.2-new/config-scripts/cups-directories.m4	(nonexistent)
+++ create-2.4.2-statedir-patch/cups-2.4.2-new/config-scripts/cups-directories.m4	(revision 5)
@@ -0,0 +1,275 @@
+dnl
+dnl Directory stuff for CUPS.
+dnl
+dnl Copyright © 2021-2022 by OpenPrinting.
+dnl Copyright © 2007-2017 by Apple Inc.
+dnl Copyright © 1997-2007 by Easy Software Products, all rights reserved.
+dnl
+dnl Licensed under Apache License v2.0.  See the file "LICENSE" for more information.
+dnl
+
+AC_PREFIX_DEFAULT(/)
+
+dnl Fix "prefix" variable if it hasn't been specified...
+AS_IF([test "$prefix" = "NONE"], [
+    prefix="/"
+])
+
+dnl Fix "exec_prefix" variable if it hasn't been specified...
+AS_IF([test "$exec_prefix" = "NONE"], [
+    AS_IF([test "$prefix" = "/"], [
+	exec_prefix="/usr"
+    ], [
+	exec_prefix="$prefix"
+    ])
+])
+
+dnl Fix "bindir" variable...
+AS_IF([test "$bindir" = "\${exec_prefix}/bin"], [
+    bindir="$exec_prefix/bin"
+])
+
+AC_DEFINE_UNQUOTED([CUPS_BINDIR], ["$bindir"], [Location of CUPS user programs.])
+
+dnl Fix "sbindir" variable...
+AS_IF([test "$sbindir" = "\${exec_prefix}/sbin"], [
+    sbindir="$exec_prefix/sbin"
+])
+
+AC_DEFINE_UNQUOTED([CUPS_SBINDIR], ["$sbindir"], [Location of CUPS admin programs.])
+
+dnl Fix "datarootdir" variable if it hasn't been specified...
+AS_IF([test "$datarootdir" = "\${prefix}/share"], [
+    AS_IF([test "$prefix" = "/"], [
+	datarootdir="/usr/share"
+    ], [
+	datarootdir="$prefix/share"
+    ])
+])
+
+dnl Fix "datadir" variable if it hasn't been specified...
+AS_IF([test "$datadir" = "\${prefix}/share"], [
+    AS_IF([test "$prefix" = "/"], [
+	datadir="/usr/share"
+    ], [
+	datadir="$prefix/share"
+    ])
+], [test "$datadir" = "\${datarootdir}"], [
+    datadir="$datarootdir"
+])
+
+dnl Fix "includedir" variable if it hasn't been specified...
+AS_IF([test "$includedir" = "\${prefix}/include" -a "$prefix" = "/"], [
+    includedir="/usr/include"
+])
+AS_IF([test "$includedir" != "/usr/include"], [
+    PKGCONFIG_CFLAGS="$PKGCONFIG_CFLAGS -I$includedir"
+])
+
+dnl Fix "localstatedir" variable if it hasn't been specified...
+AS_IF([test "$localstatedir" = "\${prefix}/var"], [
+    AS_IF([test "$prefix" = "/"], [
+	AS_IF([test "$host_os_name" = darwin], [
+	    localstatedir="/private/var"
+	], [
+	    localstatedir="/var"
+	])
+    ], [
+	localstatedir="$prefix/var"
+    ])
+])
+
+dnl Fix "sysconfdir" variable if it hasn't been specified...
+AS_IF([test "$sysconfdir" = "\${prefix}/etc"], [
+    AS_IF([test "$prefix" = "/"], [
+	AS_IF([test "$host_os_name" = darwin], [
+	    sysconfdir="/private/etc"
+	], [
+	    sysconfdir="/etc"
+	])
+    ], [
+	sysconfdir="$prefix/etc"
+    ])
+])
+
+dnl Fix "libdir" variable...
+AS_IF([test "$libdir" = "\${exec_prefix}/lib"], [
+    AS_CASE(["$host_os_name"], [linux*], [
+	AS_IF([test -d /usr/lib64 -a ! -d /usr/lib64/fakeroot], [
+	    libdir="$exec_prefix/lib64"
+	], [
+	    libdir="$exec_prefix/lib"
+	])
+    ], [*], [
+	libdir="$exec_prefix/lib"
+    ])
+])
+AS_IF([test "$libdir" = "/usr/lib"], [
+    PKGCONFIG_LIBS="-lcups"
+], [
+    PKGCONFIG_LIBS="-L$libdir -lcups"
+])
+
+dnl Setup default locations...
+# Cache data...
+AC_ARG_WITH([cachedir], AS_HELP_STRING([--with-cachedir], [set path for cache files]), [
+    cachedir="$withval"
+], [
+    cachedir=""
+])
+
+AS_IF([test x$cachedir = x], [
+    AS_IF([test "x$host_os_name" = xdarwin], [
+	CUPS_CACHEDIR="$localstatedir/spool/cups/cache"
+    ], [
+	CUPS_CACHEDIR="$localstatedir/cache/cups"
+    ])
+], [
+    CUPS_CACHEDIR="$cachedir"
+])
+AC_DEFINE_UNQUOTED([CUPS_CACHEDIR], ["$CUPS_CACHEDIR"], [Location of cache files.])
+AC_SUBST([CUPS_CACHEDIR])
+
+# Data files
+CUPS_DATADIR="$datadir/cups"
+AC_DEFINE_UNQUOTED([CUPS_DATADIR], ["$datadir/cups"], [Location of data files.])
+AC_SUBST([CUPS_DATADIR])
+
+# Icon directory
+AC_ARG_WITH([icondir], AS_HELP_STRING([--with-icondir], [set path for application icons]), [
+    icondir="$withval"
+], [
+    icondir=""
+])
+
+AS_IF([test "x$icondir" = x], [
+    ICONDIR="/usr/share/icons"
+], [
+    ICONDIR="$icondir"
+])
+
+AC_SUBST([ICONDIR])
+
+# Menu directory
+AC_ARG_WITH([menudir], AS_HELP_STRING([--with-menudir], [set path for application menus]), [
+    menudir="$withval"
+], [
+    menudir=""
+])
+
+AS_IF([test "x$menudir" = x], [
+    MENUDIR="/usr/share/applications"
+], [
+    MENUDIR="$menudir"
+])
+
+AC_SUBST([MENUDIR])
+
+# Documentation files
+AC_ARG_WITH([docdir], AS_HELP_STRING([--with-docdir], [set path for documentation]), [
+    docdir="$withval"
+], [
+    docdir=""
+])
+
+AS_IF([test x$docdir = x], [
+    CUPS_DOCROOT="$datadir/doc/cups"
+    docdir="$datadir/doc/cups"
+], [
+    CUPS_DOCROOT="$docdir"
+])
+
+AC_DEFINE_UNQUOTED([CUPS_DOCROOT], ["$docdir"], [Location of documentation files.])
+AC_SUBST([CUPS_DOCROOT])
+
+# Locale data
+AS_IF([test "$localedir" = "\${datarootdir}/locale"], [
+    AS_CASE(["$host_os_name"], [linux* | gnu* | *bsd* | darwin*], [
+	CUPS_LOCALEDIR="$datarootdir/locale"
+    ], [*], [
+	# This is the standard System V location...
+	CUPS_LOCALEDIR="$exec_prefix/lib/locale"
+    ])
+], [
+    CUPS_LOCALEDIR="$localedir"
+])
+
+AC_DEFINE_UNQUOTED([CUPS_LOCALEDIR], ["$CUPS_LOCALEDIR"], [Location of localization files.])
+AC_SUBST([CUPS_LOCALEDIR])
+
+
+# cups.pc file...
+AC_ARG_WITH([pkgconfpath], AS_HELP_STRING([--with-pkgconfpath], [set path for cups.pc file]), [
+    pkgconfpath="$withval"
+], [
+    pkgconfpath=""
+])
+
+AS_IF([test x$pkgconfpath = x], [
+    CUPS_PKGCONFPATH="$exec_prefix/lib/pkgconfig"
+], [
+    CUPS_PKGCONFPATH="$pkgconfpath"
+])
+AC_DEFINE_UNQUOTED([CUPS_PKGCONFPATH], ["$CUPS_PKGCONFPATH"], [Location of cups.pc file.])
+AC_SUBST([CUPS_PKGCONFPATH])
+
+
+
+# Log files...
+AC_ARG_WITH([logdir], AS_HELP_STRING([--with-logdir], [set path for log files]), [
+    logdir="$withval"
+], [
+    logdir=""
+])
+
+AS_IF([test x$logdir = x], [
+    CUPS_LOGDIR="$localstatedir/log/cups"
+], [
+    CUPS_LOGDIR="$logdir"
+])
+AC_DEFINE_UNQUOTED([CUPS_LOGDIR], ["$CUPS_LOGDIR"], [Location of log files.])
+AC_SUBST([CUPS_LOGDIR])
+
+# Longer-term spool data
+CUPS_REQUESTS="$localstatedir/spool/cups"
+AC_DEFINE_UNQUOTED([CUPS_REQUESTS], ["$localstatedir/spool/cups"], [Location of spool directory.])
+AC_SUBST([CUPS_REQUESTS])
+
+# Server executables...
+AS_CASE(["$host_os_name"], [*-gnu], [
+    # GNUs
+    INSTALL_SYSV="install-sysv"
+    CUPS_SERVERBIN="$exec_prefix/lib/cups"
+], [*bsd* | darwin*], [
+    # *BSD and Darwin (macOS)
+    INSTALL_SYSV=""
+    CUPS_SERVERBIN="$exec_prefix/libexec/cups"
+], [*], [
+    # All others
+    INSTALL_SYSV="install-sysv"
+    CUPS_SERVERBIN="$exec_prefix/lib/cups"
+])
+
+AC_DEFINE_UNQUOTED([CUPS_SERVERBIN], ["$CUPS_SERVERBIN"], [Location of server programs.])
+AC_SUBST([CUPS_SERVERBIN])
+AC_SUBST([INSTALL_SYSV])
+
+# Configuration files
+CUPS_SERVERROOT="$sysconfdir/cups"
+AC_DEFINE_UNQUOTED([CUPS_SERVERROOT], ["$sysconfdir/cups"], [Location of server configuration files.])
+AC_SUBST([CUPS_SERVERROOT])
+
+# Transient run-time state
+AC_ARG_WITH([rundir], AS_HELP_STRING([--with-rundir], [set transient run-time state directory]), [
+    CUPS_STATEDIR="$withval"
+], [
+    AS_CASE(["$host_os_name"], [darwin*], [
+	# Darwin (macOS)
+	CUPS_STATEDIR="$CUPS_SERVERROOT"
+    ], [*], [
+	# All others
+	CUPS_STATEDIR="/run/cups"
+    ])
+])
+AC_DEFINE_UNQUOTED([CUPS_STATEDIR], ["$CUPS_STATEDIR"], [Location of transient state files.])
+AC_SUBST([CUPS_STATEDIR])
Index: create-2.4.2-statedir-patch/cups-2.4.2-new/config-scripts
===================================================================
--- create-2.4.2-statedir-patch/cups-2.4.2-new/config-scripts	(nonexistent)
+++ create-2.4.2-statedir-patch/cups-2.4.2-new/config-scripts	(revision 5)

Property changes on: create-2.4.2-statedir-patch/cups-2.4.2-new/config-scripts
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-2.4.2-statedir-patch/cups-2.4.2-new
===================================================================
--- create-2.4.2-statedir-patch/cups-2.4.2-new	(nonexistent)
+++ create-2.4.2-statedir-patch/cups-2.4.2-new	(revision 5)

Property changes on: create-2.4.2-statedir-patch/cups-2.4.2-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-2.4.2-statedir-patch/file.list
===================================================================
--- create-2.4.2-statedir-patch/file.list	(nonexistent)
+++ create-2.4.2-statedir-patch/file.list	(revision 5)
@@ -0,0 +1 @@
+cups-2.4.2/config-scripts/cups-directories.m4
Index: create-2.4.2-statedir-patch
===================================================================
--- create-2.4.2-statedir-patch	(nonexistent)
+++ create-2.4.2-statedir-patch	(revision 5)

Property changes on: create-2.4.2-statedir-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-2.4.2-tls-openssl-patch/create.patch.sh
===================================================================
--- create-2.4.2-tls-openssl-patch/create.patch.sh	(nonexistent)
+++ create-2.4.2-tls-openssl-patch/create.patch.sh	(revision 5)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+VERSION=2.4.2
+
+tar --files-from=file.list -xJvf ../cups-$VERSION.tar.xz
+mv cups-$VERSION cups-$VERSION-orig
+
+cp -rf ./cups-$VERSION-new ./cups-$VERSION
+
+diff --unified -Nr  cups-$VERSION-orig  cups-$VERSION > cups-$VERSION-tls-openssl.patch
+
+mv cups-$VERSION-tls-openssl.patch ../patches
+
+rm -rf ./cups-$VERSION
+rm -rf ./cups-$VERSION-orig

Property changes on: create-2.4.2-tls-openssl-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: create-2.4.2-tls-openssl-patch/cups-2.4.2-new/cups/tls-openssl.c
===================================================================
--- create-2.4.2-tls-openssl-patch/cups-2.4.2-new/cups/tls-openssl.c	(nonexistent)
+++ create-2.4.2-tls-openssl-patch/cups-2.4.2-new/cups/tls-openssl.c	(revision 5)
@@ -0,0 +1,1597 @@
+/*
+ * TLS support code for CUPS using OpenSSL/LibreSSL.
+ *
+ * Copyright © 2020-2022 by OpenPrinting
+ * Copyright © 2007-2019 by Apple Inc.
+ * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
+ *
+ * Licensed under Apache License v2.0.  See the file "LICENSE" for more
+ * information.
+ */
+
+/**** This file is included from tls.c ****/
+
+/*
+ * Include necessary headers...
+ */
+
+#include <sys/stat.h>
+#include <openssl/x509v3.h>
+
+
+/*
+ * Local functions...
+ */
+
+static long		http_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int		http_bio_free(BIO *data);
+static int		http_bio_new(BIO *h);
+static int		http_bio_puts(BIO *h, const char *str);
+static int		http_bio_read(BIO *h, char *buf, int size);
+static int		http_bio_write(BIO *h, const char *buf, int num);
+
+static X509		*http_create_credential(http_credential_t *credential);
+static const char	*http_default_path(char *buffer, size_t bufsize);
+static time_t		http_get_date(X509 *cert, int which);
+//static void		http_load_crl(void);
+static const char	*http_make_path(char *buffer, size_t bufsize, const char *dirname, const char *filename, const char *ext);
+static void		http_x509_add_san(X509 *cert, const char *name);
+
+
+/*
+ * Local globals...
+ */
+
+static int		tls_auto_create = 0;
+					/* Auto-create self-signed certs? */
+static BIO_METHOD	*tls_bio_method = NULL;
+					/* OpenSSL BIO method */
+static char		*tls_common_name = NULL;
+					/* Default common name */
+//static X509_CRL		*tls_crl = NULL;/* Certificate revocation list */
+static char		*tls_keypath = NULL;
+					/* Server cert keychain path */
+static _cups_mutex_t	tls_mutex = _CUPS_MUTEX_INITIALIZER;
+					/* Mutex for keychain/certs */
+static int		tls_options = -1,/* Options for TLS connections */
+			tls_min_version = _HTTP_TLS_1_0,
+			tls_max_version = _HTTP_TLS_MAX;
+
+
+/*
+ * 'cupsMakeServerCredentials()' - Make a self-signed certificate and private key pair.
+ *
+ * @since CUPS 2.0/OS 10.10@
+ */
+
+int					// O - 1 on success, 0 on failure
+cupsMakeServerCredentials(
+    const char *path,			// I - Path to keychain/directory
+    const char *common_name,		// I - Common name
+    int        num_alt_names,		// I - Number of subject alternate names
+    const char **alt_names,		// I - Subject Alternate Names
+    time_t     expiration_date)		// I - Expiration date
+{
+  int		result = 0;		// Return value
+  EVP_PKEY	*pkey;			// Private key
+  RSA		*rsa;			// RSA key pair
+  X509		*cert;			// Certificate
+  cups_lang_t	*language;		// Default language info
+  time_t	curtime;		// Current time
+  X509_NAME	*name;			// Subject/issuer name
+  BIO		*bio;			// Output file
+  char		temp[1024],		// Temporary directory name
+ 		crtfile[1024],		// Certificate filename
+		keyfile[1024];		// Private key filename
+  const char	*common_ptr;		// Pointer into common name
+
+
+  DEBUG_printf(("cupsMakeServerCredentials(path=\"%s\", common_name=\"%s\", num_alt_names=%d, alt_names=%p, expiration_date=%d)", path, common_name, num_alt_names, alt_names, (int)expiration_date));
+
+  // Filenames...
+  if (!path)
+    path = http_default_path(temp, sizeof(temp));
+
+  if (!path || !common_name)
+  {
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
+    return (0);
+  }
+
+  http_make_path(crtfile, sizeof(crtfile), path, common_name, "crt");
+  http_make_path(keyfile, sizeof(keyfile), path, common_name, "key");
+
+  // Create the encryption key...
+  DEBUG_puts("1cupsMakeServerCredentials: Creating key pair.");
+
+  if ((rsa = RSA_generate_key(2048, RSA_F4, NULL, NULL)) == NULL)
+  {
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to create key pair."), 1);
+    return (0);
+  }
+
+  if ((pkey = EVP_PKEY_new()) == NULL)
+  {
+    RSA_free(rsa);
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to create private key."), 1);
+    return (0);
+  }
+
+  EVP_PKEY_assign_RSA(pkey, rsa);
+
+  DEBUG_puts("1cupsMakeServerCredentials: Key pair created.");
+
+  // Create the X.509 certificate...
+  DEBUG_puts("1cupsMakeServerCredentials: Generating self-signed X.509 certificate.");
+
+  if ((cert = X509_new()) == NULL)
+  {
+    EVP_PKEY_free(pkey);
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to create X.509 certificate."), 1);
+    return (0);
+  }
+
+  curtime  = time(NULL);
+  language = cupsLangDefault();
+
+  ASN1_TIME_set(X509_get_notBefore(cert), curtime);
+  ASN1_TIME_set(X509_get_notAfter(cert), expiration_date);
+  ASN1_INTEGER_set(X509_get_serialNumber(cert), (int)curtime);
+  X509_set_pubkey(cert, pkey);
+
+  name = X509_get_subject_name(cert);
+  if (strlen(language->language) == 5)
+    X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (unsigned char *)language->language + 3, -1, -1, 0);
+  else
+    X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (unsigned char *)"US", -1, -1, 0);
+  X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (unsigned char *)"Unknown", -1, -1, 0);
+  X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *)common_name, -1, -1, 0);
+
+  X509_set_issuer_name(cert, name);
+
+  http_x509_add_san(cert, common_name);
+  if ((common_ptr = strstr(common_name, ".local")) == NULL)
+  {
+    // Add common_name.local to the list, too...
+    char	localname[256],		// hostname.local
+		*localptr;		// Pointer into localname
+
+    strlcpy(localname, common_name, sizeof(localname));
+    if ((localptr = strchr(localname, '.')) != NULL)
+      *localptr = '\0';
+    strlcat(localname, ".local", sizeof(localname));
+
+    http_x509_add_san(cert, localname);
+  }
+
+  if (num_alt_names > 0)
+  {
+    int i;                              // Looping var...
+
+    for (i = 0; i < num_alt_names; i ++)
+    {
+      if (strcmp(alt_names[i], "localhost"))
+        http_x509_add_san(cert, alt_names[i]);
+    }
+  }
+
+  X509_sign(cert, pkey, EVP_sha256());
+
+  // Save them...
+  if ((bio = BIO_new_file(keyfile, "wb")) == NULL)
+  {
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
+    goto done;
+  }
+
+  if (!PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL))
+  {
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to write private key."), 1);
+    BIO_free(bio);
+    goto done;
+  }
+
+  BIO_free(bio);
+
+  if ((bio = BIO_new_file(crtfile, "wb")) == NULL)
+  {
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
+    goto done;
+  }
+
+  if (!PEM_write_bio_X509(bio, cert))
+  {
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to write X.509 certificate."), 1);
+    BIO_free(bio);
+    goto done;
+  }
+
+  BIO_free(bio);
+
+  result = 1;
+  DEBUG_puts("1cupsMakeServerCredentials: Successfully created credentials.");
+
+  // Cleanup...
+  done:
+
+  X509_free(cert);
+  EVP_PKEY_free(pkey);
+
+  return (result);
+}
+
+
+/*
+ * 'cupsSetServerCredentials()' - Set the default server credentials.
+ *
+ * Note: The server credentials are used by all threads in the running process.
+ * This function is threadsafe.
+ *
+ * @since CUPS 2.0/OS 10.10@
+ */
+
+int					// O - 1 on success, 0 on failure
+cupsSetServerCredentials(
+    const char *path,			// I - Path to keychain/directory
+    const char *common_name,		// I - Default common name for server
+    int        auto_create)		// I - 1 = automatically create self-signed certificates
+{
+  char	temp[1024];			// Default path buffer
+
+
+  DEBUG_printf(("cupsSetServerCredentials(path=\"%s\", common_name=\"%s\", auto_create=%d)", path, common_name, auto_create));
+
+ /*
+  * Use defaults as needed...
+  */
+
+  if (!path)
+    path = http_default_path(temp, sizeof(temp));
+
+ /*
+  * Range check input...
+  */
+
+  if (!path || !common_name)
+  {
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
+    return (0);
+  }
+
+  _cupsMutexLock(&tls_mutex);
+
+ /*
+  * Free old values...
+  */
+
+  if (tls_keypath)
+    _cupsStrFree(tls_keypath);
+
+  if (tls_common_name)
+    _cupsStrFree(tls_common_name);
+
+ /*
+  * Save the new values...
+  */
+
+  tls_keypath     = _cupsStrAlloc(path);
+  tls_auto_create = auto_create;
+  tls_common_name = _cupsStrAlloc(common_name);
+
+  _cupsMutexUnlock(&tls_mutex);
+
+  return (1);
+}
+
+
+/*
+ * 'httpCopyCredentials()' - Copy the credentials associated with the peer in
+ *                           an encrypted connection.
+ *
+ * @since CUPS 1.5/macOS 10.7@
+ */
+
+int					// O - Status of call (0 = success)
+httpCopyCredentials(
+    http_t	 *http,			// I - Connection to server
+    cups_array_t **credentials)		// O - Array of credentials
+{
+  STACK_OF(X509) *chain;		// Certificate chain
+
+
+  DEBUG_printf(("httpCopyCredentials(http=%p, credentials=%p)", http, credentials));
+
+  if (credentials)
+    *credentials = NULL;
+
+  if (!http || !http->tls || !credentials)
+    return (-1);
+
+  *credentials = cupsArrayNew(NULL, NULL);
+  chain        = SSL_get_peer_cert_chain(http->tls);
+
+  DEBUG_printf(("1httpCopyCredentials: chain=%p", chain));
+
+  if (chain)
+  {
+    int	i,				// Looping var
+	count;				// Number of certs
+
+    for (i = 0, count = sk_X509_num(chain); i < count; i ++)
+    {
+      X509	*cert = sk_X509_value(chain, i);
+					// Current certificate
+      BIO	*bio = BIO_new(BIO_s_mem());
+					// Memory buffer for cert
+
+      if (bio)
+      {
+	long	bytes;			// Number of bytes
+	char	*buffer;		// Pointer to bytes
+
+	if (PEM_write_bio_X509(bio, cert))
+	{
+	  bytes = BIO_get_mem_data(bio, &buffer);
+	  httpAddCredential(*credentials, buffer, (int)bytes);
+	}
+
+	BIO_free(bio);
+      }
+    }
+  }
+
+  return (0);
+}
+
+
+/*
+ * '_httpCreateCredentials()' - Create credentials in the internal format.
+ */
+
+http_tls_credentials_t			// O - Internal credentials
+_httpCreateCredentials(
+    cups_array_t *credentials)		// I - Array of credentials
+{
+  (void)credentials;
+
+  return (NULL);
+}
+
+
+/*
+ * '_httpFreeCredentials()' - Free internal credentials.
+ */
+
+void
+_httpFreeCredentials(
+    http_tls_credentials_t credentials)	// I - Internal credentials
+{
+  X509_free(credentials);
+}
+
+
+/*
+ * 'httpCredentialsAreValidForName()' - Return whether the credentials are valid for the given name.
+ *
+ * @since CUPS 2.0/OS 10.10@
+ */
+
+int					// O - 1 if valid, 0 otherwise
+httpCredentialsAreValidForName(
+    cups_array_t *credentials,		// I - Credentials
+    const char   *common_name)		// I - Name to check
+{
+  X509	*cert;				// Certificate
+  int	result = 0;			// Result
+
+
+  cert = http_create_credential((http_credential_t *)cupsArrayFirst(credentials));
+  if (cert)
+  {
+    result = X509_check_host(cert, common_name, strlen(common_name), 0, NULL);
+
+    X509_free(cert);
+  }
+
+  return (result);
+}
+
+
+/*
+ * 'httpCredentialsGetTrust()' - Return the trust of credentials.
+ *
+ * @since CUPS 2.0/OS 10.10@
+ */
+
+http_trust_t				// O - Level of trust
+httpCredentialsGetTrust(
+    cups_array_t *credentials,		// I - Credentials
+    const char   *common_name)		// I - Common name for trust lookup
+{
+  http_trust_t	trust = HTTP_TRUST_OK;	// Trusted?
+  X509		*cert;			// Certificate
+  cups_array_t	*tcreds = NULL;		// Trusted credentials
+  _cups_globals_t *cg = _cupsGlobals();	// Per-thread globals
+
+
+  if (!common_name)
+  {
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No common name specified."), 1);
+    return (HTTP_TRUST_UNKNOWN);
+  }
+
+  if ((cert = http_create_credential((http_credential_t *)cupsArrayFirst(credentials))) == NULL)
+  {
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to create credentials from array."), 1);
+    return (HTTP_TRUST_UNKNOWN);
+  }
+
+  if (cg->any_root < 0)
+  {
+    _cupsSetDefaults();
+//    http_load_crl();
+  }
+
+  // Look this common name up in the default keychains...
+  httpLoadCredentials(NULL, &tcreds, common_name);
+
+  if (tcreds)
+  {
+    char	credentials_str[1024],	/* String for incoming credentials */
+		tcreds_str[1024];	/* String for saved credentials */
+
+    httpCredentialsString(credentials, credentials_str, sizeof(credentials_str));
+    httpCredentialsString(tcreds, tcreds_str, sizeof(tcreds_str));
+
+    if (strcmp(credentials_str, tcreds_str))
+    {
+      // Credentials don't match, let's look at the expiration date of the new
+      // credentials and allow if the new ones have a later expiration...
+      if (!cg->trust_first)
+      {
+        // Do not trust certificates on first use...
+        _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Trust on first use is disabled."), 1);
+
+        trust = HTTP_TRUST_INVALID;
+      }
+      else if (httpCredentialsGetExpiration(credentials) <= httpCredentialsGetExpiration(tcreds))
+      {
+        // The new credentials are not newly issued...
+        _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("New credentials are older than stored credentials."), 1);
+
+        trust = HTTP_TRUST_INVALID;
+      }
+      else if (!httpCredentialsAreValidForName(credentials, common_name))
+      {
+        // The common name does not match the issued certificate...
+        _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("New credentials are not valid for name."), 1);
+
+        trust = HTTP_TRUST_INVALID;
+      }
+      else if (httpCredentialsGetExpiration(tcreds) < time(NULL))
+      {
+        // Save the renewed credentials...
+	trust = HTTP_TRUST_RENEWED;
+
+        httpSaveCredentials(NULL, credentials, common_name);
+      }
+    }
+
+    httpFreeCredentials(tcreds);
+  }
+  else if (cg->validate_certs && !httpCredentialsAreValidForName(credentials, common_name))
+  {
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No stored credentials, not valid for name."), 1);
+    trust = HTTP_TRUST_INVALID;
+  }
+  else if (!cg->trust_first)
+  {
+    // See if we have a site CA certificate we can compare...
+    if (!httpLoadCredentials(NULL, &tcreds, "site"))
+    {
+      if (cupsArrayCount(credentials) != (cupsArrayCount(tcreds) + 1))
+      {
+        // Certificate isn't directly generated from the CA cert...
+        trust = HTTP_TRUST_INVALID;
+      }
+      else
+      {
+        // Do a tail comparison of the two certificates...
+        http_credential_t	*a, *b;		// Certificates
+
+        for (a = (http_credential_t *)cupsArrayFirst(tcreds), b = (http_credential_t *)cupsArrayIndex(credentials, 1); a && b; a = (http_credential_t *)cupsArrayNext(tcreds), b = (http_credential_t *)cupsArrayNext(credentials))
+        {
+	  if (a->datalen != b->datalen || memcmp(a->data, b->data, a->datalen))
+	    break;
+	}
+
+        if (a || b)
+	  trust = HTTP_TRUST_INVALID;
+      }
+
+      if (trust != HTTP_TRUST_OK)
+	_cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Credentials do not validate against site CA certificate."), 1);
+    }
+    else
+    {
+      _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Trust on first use is disabled."), 1);
+      trust = HTTP_TRUST_INVALID;
+    }
+  }
+
+  if (trust == HTTP_TRUST_OK && !cg->expired_certs)
+  {
+    time_t	curtime;		// Current date/time
+
+    time(&curtime);
+    if (curtime < http_get_date(cert, 0) || curtime > http_get_date(cert, 1))
+    {
+      _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Credentials have expired."), 1);
+      trust = HTTP_TRUST_EXPIRED;
+    }
+  }
+
+  if (trust == HTTP_TRUST_OK && !cg->any_root && cupsArrayCount(credentials) == 1)
+  {
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Self-signed credentials are blocked."), 1);
+    trust = HTTP_TRUST_INVALID;
+  }
+
+  X509_free(cert);
+
+  return (trust);
+}
+
+
+/*
+ * 'httpCredentialsGetExpiration()' - Return the expiration date of the credentials.
+ *
+ * @since CUPS 2.0/OS 10.10@
+ */
+
+time_t					// O - Expiration date of credentials
+httpCredentialsGetExpiration(
+    cups_array_t *credentials)		// I - Credentials
+{
+  time_t	result = 0;		// Result
+  X509		*cert;			// Certificate
+
+
+  if ((cert = http_create_credential((http_credential_t *)cupsArrayFirst(credentials))) != NULL)
+  {
+    result = http_get_date(cert, 1);
+    X509_free(cert);
+  }
+
+  return (result);
+}
+
+
+/*
+ * 'httpCredentialsString()' - Return a string representing the credentials.
+ *
+ * @since CUPS 2.0/OS 10.10@
+ */
+
+size_t					// O - Total size of credentials string
+httpCredentialsString(
+    cups_array_t *credentials,		// I - Credentials
+    char         *buffer,		// I - Buffer
+    size_t       bufsize)		// I - Size of buffer
+{
+  http_credential_t	*first;		// First certificate
+  X509			*cert;		// Certificate
+
+
+  DEBUG_printf(("httpCredentialsString(credentials=%p, buffer=%p, bufsize=" CUPS_LLFMT ")", credentials, buffer, CUPS_LLCAST bufsize));
+
+  if (!buffer)
+    return (0);
+
+  if (bufsize > 0)
+    *buffer = '\0';
+
+  first = (http_credential_t *)cupsArrayFirst(credentials);
+  cert  = http_create_credential(first);
+
+  if (cert)
+  {
+    char		name[256],	// Common name associated with cert
+			issuer[256];	// Issuer associated with cert
+    time_t		expiration;	// Expiration date of cert
+    const char		*sigalg;	// Signature algorithm
+    unsigned char	md5_digest[16];	// MD5 result
+
+
+    X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_commonName, name, sizeof(name));
+    X509_NAME_get_text_by_NID(X509_get_issuer_name(cert), NID_commonName, issuer, sizeof(issuer));
+    expiration = http_get_date(cert, 1);
+
+    switch (X509_get_signature_nid(cert))
+    {
+      case NID_ecdsa_with_SHA1 :
+          sigalg = "SHA1WithECDSAEncryption";
+          break;
+      case NID_ecdsa_with_SHA224 :
+          sigalg = "SHA224WithECDSAEncryption";
+          break;
+      case NID_ecdsa_with_SHA256 :
+          sigalg = "SHA256WithECDSAEncryption";
+          break;
+      case NID_ecdsa_with_SHA384 :
+          sigalg = "SHA384WithECDSAEncryption";
+          break;
+      case NID_ecdsa_with_SHA512 :
+          sigalg = "SHA512WithECDSAEncryption";
+          break;
+      case NID_sha1WithRSAEncryption :
+          sigalg = "SHA1WithRSAEncryption";
+          break;
+      case NID_sha224WithRSAEncryption :
+          sigalg = "SHA224WithRSAEncryption";
+          break;
+      case NID_sha256WithRSAEncryption :
+          sigalg = "SHA256WithRSAEncryption";
+          break;
+      case NID_sha384WithRSAEncryption :
+          sigalg = "SHA384WithRSAEncryption";
+          break;
+      case NID_sha512WithRSAEncryption :
+          sigalg = "SHA512WithRSAEncryption";
+          break;
+      default :
+          sigalg = "Unknown";
+          break;
+    }
+
+    cupsHashData("md5", first->data, first->datalen, md5_digest, sizeof(md5_digest));
+
+    snprintf(buffer, bufsize, "%s (issued by %s) / %s / %s / %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", name, issuer, httpGetDateString(expiration), sigalg, md5_digest[0], md5_digest[1], md5_digest[2], md5_digest[3], md5_digest[4], md5_digest[5], md5_digest[6], md5_digest[7], md5_digest[8], md5_digest[9], md5_digest[10], md5_digest[11], md5_digest[12], md5_digest[13], md5_digest[14], md5_digest[15]);
+    X509_free(cert);
+  }
+
+  DEBUG_printf(("1httpCredentialsString: Returning \"%s\".", buffer));
+
+  return (strlen(buffer));
+}
+
+
+/*
+ * 'httpLoadCredentials()' - Load X.509 credentials from a keychain file.
+ *
+ * @since CUPS 2.0/OS 10.10@
+ */
+
+int					// O - 0 on success, -1 on error
+httpLoadCredentials(
+    const char   *path,			// I  - Keychain/PKCS#12 path
+    cups_array_t **credentials,		// IO - Credentials
+    const char   *common_name)		// I  - Common name for credentials
+{
+  cups_file_t		*fp;		// Certificate file
+  char			filename[1024],	// filename.crt
+			temp[1024],	// Temporary string
+			line[256];	// Base64-encoded line
+  unsigned char		*data = NULL;	// Buffer for cert data
+  size_t		alloc_data = 0,	// Bytes allocated
+			num_data = 0;	// Bytes used
+  int			decoded;	// Bytes decoded
+  int			in_certificate = 0;
+					// In a certificate?
+
+
+  if (!credentials || !common_name)
+    return (-1);
+
+  if (!path)
+    path = http_default_path(temp, sizeof(temp));
+  if (!path)
+    return (-1);
+
+  http_make_path(filename, sizeof(filename), path, common_name, "crt");
+
+  if ((fp = cupsFileOpen(filename, "r")) == NULL)
+    return (-1);
+
+  while (cupsFileGets(fp, line, sizeof(line)))
+  {
+    if (!strcmp(line, "-----BEGIN CERTIFICATE-----"))
+    {
+      if (in_certificate)
+      {
+       /*
+	* Missing END CERTIFICATE...
+	*/
+
+        httpFreeCredentials(*credentials);
+	*credentials = NULL;
+        break;
+      }
+
+      in_certificate = 1;
+    }
+    else if (!strcmp(line, "-----END CERTIFICATE-----"))
+    {
+      if (!in_certificate || !num_data)
+      {
+       /*
+	* Missing data...
+	*/
+
+        httpFreeCredentials(*credentials);
+	*credentials = NULL;
+        break;
+      }
+
+      if (!*credentials)
+        *credentials = cupsArrayNew(NULL, NULL);
+
+      if (httpAddCredential(*credentials, data, num_data))
+      {
+        httpFreeCredentials(*credentials);
+	*credentials = NULL;
+        break;
+      }
+
+      num_data       = 0;
+      in_certificate = 0;
+    }
+    else if (in_certificate)
+    {
+      if (alloc_data == 0)
+      {
+        data       = malloc(2048);
+	alloc_data = 2048;
+
+        if (!data)
+	  break;
+      }
+      else if ((num_data + strlen(line)) >= alloc_data)
+      {
+        unsigned char *tdata = realloc(data, alloc_data + 1024);
+					/* Expanded buffer */
+
+	if (!tdata)
+	{
+	  httpFreeCredentials(*credentials);
+	  *credentials = NULL;
+	  break;
+	}
+
+	data       = tdata;
+        alloc_data += 1024;
+      }
+
+      decoded = alloc_data - num_data;
+      httpDecode64_2((char *)data + num_data, &decoded, line);
+      num_data += (size_t)decoded;
+    }
+  }
+
+  cupsFileClose(fp);
+
+  if (in_certificate)
+  {
+   /*
+    * Missing END CERTIFICATE...
+    */
+
+    httpFreeCredentials(*credentials);
+    *credentials = NULL;
+  }
+
+  if (data)
+    free(data);
+
+  return (*credentials ? 0 : -1);
+}
+
+
+/*
+ * 'httpSaveCredentials()' - Save X.509 credentials to a keychain file.
+ *
+ * @since CUPS 2.0/OS 10.10@
+ */
+
+int					// O - -1 on error, 0 on success
+httpSaveCredentials(
+    const char   *path,			// I - Keychain/PKCS#12 path
+    cups_array_t *credentials,		// I - Credentials
+    const char   *common_name)		// I - Common name for credentials
+{
+  cups_file_t		*fp;		// Certificate file
+  char			filename[1024],	// filename.crt
+			nfilename[1024],// filename.crt.N
+			temp[1024],	// Temporary string
+			line[256];	// Base64-encoded line
+  const unsigned char	*ptr;		// Pointer into certificate
+  ssize_t		remaining;	// Bytes left
+  http_credential_t	*cred;		// Current credential
+
+
+  if (!credentials || !common_name)
+    return (-1);
+
+  if (!path)
+    path = http_default_path(temp, sizeof(temp));
+  if (!path)
+    return (-1);
+
+  http_make_path(filename, sizeof(filename), path, common_name, "crt");
+  snprintf(nfilename, sizeof(nfilename), "%s.N", filename);
+
+  if ((fp = cupsFileOpen(nfilename, "w")) == NULL)
+    return (-1);
+
+#ifndef _WIN32
+  fchmod(cupsFileNumber(fp), 0600);
+#endif // !_WIN32
+
+  for (cred = (http_credential_t *)cupsArrayFirst(credentials);
+       cred;
+       cred = (http_credential_t *)cupsArrayNext(credentials))
+  {
+    cupsFilePuts(fp, "-----BEGIN CERTIFICATE-----\n");
+    for (ptr = cred->data, remaining = (ssize_t)cred->datalen; remaining > 0; remaining -= 45, ptr += 45)
+    {
+      httpEncode64_2(line, sizeof(line), (char *)ptr, remaining > 45 ? 45 : remaining);
+      cupsFilePrintf(fp, "%s\n", line);
+    }
+    cupsFilePuts(fp, "-----END CERTIFICATE-----\n");
+  }
+
+  cupsFileClose(fp);
+
+  return (rename(nfilename, filename));
+}
+
+
+/*
+ * '_httpTLSInitialize()' - Initialize the TLS stack.
+ */
+
+void
+_httpTLSInitialize(void)
+{
+  // OpenSSL no longer requires explicit initialization...
+}
+
+
+/*
+ * '_httpTLSPending()' - Return the number of pending TLS-encrypted bytes.
+ */
+
+size_t					// O - Bytes available
+_httpTLSPending(http_t *http)		// I - HTTP connection
+{
+  return ((size_t)SSL_pending(http->tls));
+}
+
+
+/*
+ * '_httpTLSRead()' - Read from a SSL/TLS connection.
+ */
+
+int					// O - Bytes read
+_httpTLSRead(http_t *http,		// I - Connection to server
+	     char   *buf,		// I - Buffer to store data
+	     int    len)		// I - Length of buffer
+{
+  return (SSL_read((SSL *)(http->tls), buf, len));
+}
+
+
+/*
+ * '_httpTLSSetOptions()' - Set TLS protocol and cipher suite options.
+ */
+
+void
+_httpTLSSetOptions(int options,		// I - Options
+                   int min_version,	// I - Minimum TLS version
+                   int max_version)	// I - Maximum TLS version
+{
+  if (!(options & _HTTP_TLS_SET_DEFAULT) || tls_options < 0)
+  {
+    tls_options     = options;
+    tls_min_version = min_version;
+    tls_max_version = max_version;
+  }
+}
+
+
+/*
+ * '_httpTLSStart()' - Set up SSL/TLS support on a connection.
+ */
+
+int					// O - 0 on success, -1 on failure
+_httpTLSStart(http_t *http)		// I - Connection to server
+{
+  BIO		*bio;			// Basic input/output context
+  SSL_CTX	*context;		// Encryption context
+  char		hostname[256],		// Hostname
+		cipherlist[256];	// List of cipher suites
+  unsigned long	error;			// Error code, if any
+  static const int versions[] =		// SSL/TLS versions
+  {
+    TLS1_VERSION,			// No more SSL support in OpenSSL
+    TLS1_VERSION,			// TLS/1.0
+    TLS1_1_VERSION,			// TLS/1.1
+    TLS1_2_VERSION,			// TLS/1.2
+#ifdef TLS1_3_VERSION
+    TLS1_3_VERSION,			// TLS/1.3
+    TLS1_3_VERSION			// TLS/1.3 (max)
+#else
+    TLS1_2_VERSION,			// TLS/1.2
+    TLS1_2_VERSION			// TLS/1.2 (max)
+#endif // TLS1_3_VERSION
+  };
+
+
+  DEBUG_printf(("3_httpTLSStart(http=%p)", http));
+
+  if (tls_options < 0)
+  {
+    DEBUG_puts("4_httpTLSStart: Setting defaults.");
+    _cupsSetDefaults();
+    DEBUG_printf(("4_httpTLSStart: tls_options=%x", tls_options));
+  }
+
+  if (http->mode == _HTTP_MODE_SERVER && !tls_keypath)
+  {
+    DEBUG_puts("4_httpTLSStart: cupsSetServerCredentials not called.");
+    http->error  = errno = EINVAL;
+    http->status = HTTP_STATUS_ERROR;
+    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Server credentials not set."), 1);
+
+    return (-1);
+  }
+
+  if (http->mode == _HTTP_MODE_CLIENT)
+  {
+    // Negotiate a TLS connection as a client...
+    context = SSL_CTX_new(TLS_client_method());
+  }
+  else
+  {
+    // Negotiate a TLS connection as a server
+    char	crtfile[1024],		// Certificate file
+		keyfile[1024];		// Private key file
+    const char	*cn,			// Common name to lookup
+		*cnptr;			// Pointer into common name
+    int		have_creds = 0;		// Have credentials?
+
+    context = SSL_CTX_new(TLS_server_method());
+
+    // Find the TLS certificate...
+    if (http->fields[HTTP_FIELD_HOST])
+    {
+      // Use hostname for TLS upgrade...
+      strlcpy(hostname, http->fields[HTTP_FIELD_HOST], sizeof(hostname));
+    }
+    else
+    {
+      // Resolve hostname from connection address...
+      http_addr_t	addr;		// Connection address
+      socklen_t		addrlen;	// Length of address
+
+      addrlen = sizeof(addr);
+      if (getsockname(http->fd, (struct sockaddr *)&addr, &addrlen))
+      {
+        // Unable to get local socket address so use default...
+	DEBUG_printf(("4_httpTLSStart: Unable to get socket address: %s", strerror(errno)));
+	hostname[0] = '\0';
+      }
+      else if (httpAddrLocalhost(&addr))
+      {
+        // Local access top use default...
+	hostname[0] = '\0';
+      }
+      else
+      {
+        // Lookup the socket address...
+	httpAddrLookup(&addr, hostname, sizeof(hostname));
+        DEBUG_printf(("4_httpTLSStart: Resolved socket address to \"%s\".", hostname));
+      }
+    }
+
+    if (isdigit(hostname[0] & 255) || hostname[0] == '[')
+      hostname[0] = '\0';		// Don't allow numeric addresses
+
+    if (hostname[0])
+      cn = hostname;
+    else
+      cn = tls_common_name;
+
+    if (cn)
+    {
+      // First look in the CUPS keystore...
+      http_make_path(crtfile, sizeof(crtfile), tls_keypath, cn, "crt");
+      http_make_path(keyfile, sizeof(keyfile), tls_keypath, cn, "key");
+
+      if (access(crtfile, R_OK) || access(keyfile, R_OK))
+      {
+        // No CUPS-managed certs, look for CA certs...
+        char cacrtfile[1024], cakeyfile[1024];	// CA cert files
+
+        snprintf(cacrtfile, sizeof(cacrtfile), "/etc/letsencrypt/live/%s/fullchain.pem", cn);
+        snprintf(cakeyfile, sizeof(cakeyfile), "/etc/letsencrypt/live/%s/privkey.pem", cn);
+
+        if ((access(cacrtfile, R_OK) || access(cakeyfile, R_OK)) && (cnptr = strchr(cn, '.')) != NULL)
+        {
+          // Try just domain name...
+          cnptr ++;
+          if (strchr(cnptr, '.'))
+          {
+            snprintf(cacrtfile, sizeof(cacrtfile), "/etc/letsencrypt/live/%s/fullchain.pem", cnptr);
+            snprintf(cakeyfile, sizeof(cakeyfile), "/etc/letsencrypt/live/%s/privkey.pem", cnptr);
+          }
+        }
+
+        if (!access(cacrtfile, R_OK) && !access(cakeyfile, R_OK))
+        {
+          // Use the CA certs...
+          strlcpy(crtfile, cacrtfile, sizeof(crtfile));
+          strlcpy(keyfile, cakeyfile, sizeof(keyfile));
+        }
+      }
+
+      have_creds = !access(crtfile, R_OK) && !access(keyfile, R_OK);
+    }
+
+    if (!have_creds && tls_auto_create && cn)
+    {
+      DEBUG_printf(("4_httpTLSStart: Auto-create credentials for \"%s\".", cn));
+
+      if (!cupsMakeServerCredentials(tls_keypath, cn, 0, NULL, time(NULL) + 365 * 86400))
+      {
+	DEBUG_puts("4_httpTLSStart: cupsMakeServerCredentials failed.");
+	http->error  = errno = EINVAL;
+	http->status = HTTP_STATUS_ERROR;
+	_cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to create server credentials."), 1);
+        SSL_CTX_free(context);
+
+	return (-1);
+      }
+    }
+
+    SSL_CTX_use_PrivateKey_file(context, keyfile, SSL_FILETYPE_PEM);
+    SSL_CTX_use_certificate_file(context, crtfile, SSL_FILETYPE_PEM);
+  }
+
+  // Set TLS options...
+  strlcpy(cipherlist, "HIGH:!DH:+DHE", sizeof(cipherlist));
+  if ((tls_options & _HTTP_TLS_ALLOW_RC4) && http->mode == _HTTP_MODE_CLIENT)
+    strlcat(cipherlist, ":+RC4", sizeof(cipherlist));
+  else
+    strlcat(cipherlist, ":!RC4", sizeof(cipherlist));
+  if (tls_options & _HTTP_TLS_DENY_CBC)
+    strlcat(cipherlist, ":!SHA1:!SHA256:!SHA384", sizeof(cipherlist));
+  strlcat(cipherlist, ":@STRENGTH", sizeof(cipherlist));
+
+  SSL_CTX_set_min_proto_version(context, versions[tls_min_version]);
+  SSL_CTX_set_max_proto_version(context, versions[tls_max_version]);
+  SSL_CTX_set_cipher_list(context, cipherlist);
+
+  // Setup a TLS session
+  _cupsMutexLock(&tls_mutex);
+  if (!tls_bio_method)
+  {
+    tls_bio_method = BIO_meth_new(BIO_get_new_index(), "http");
+    BIO_meth_set_ctrl(tls_bio_method, http_bio_ctrl);
+    BIO_meth_set_create(tls_bio_method, http_bio_new);
+    BIO_meth_set_destroy(tls_bio_method, http_bio_free);
+    BIO_meth_set_read(tls_bio_method, http_bio_read);
+    BIO_meth_set_puts(tls_bio_method, http_bio_puts);
+    BIO_meth_set_write(tls_bio_method, http_bio_write);
+  }
+  _cupsMutexUnlock(&tls_mutex);
+
+  bio = BIO_new(tls_bio_method);
+  BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)http);
+
+  http->tls = SSL_new(context);
+  SSL_set_bio(http->tls, bio, bio);
+
+  if (http->mode == _HTTP_MODE_CLIENT)
+  {
+    // Negotiate as a server...
+    if (SSL_connect(http->tls) < 1)
+    {
+      // Failed
+      if ((error = ERR_get_error()) != 0)
+        _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI, ERR_error_string(error, NULL), 0);
+
+      http->status = HTTP_STATUS_ERROR;
+      http->error  = EPIPE;
+
+      SSL_CTX_free(context);
+
+      SSL_free(http->tls);
+      http->tls = NULL;
+
+      return (-1);
+    }
+  }
+  else
+  {
+    // Negotiate as a server...
+    if (SSL_accept(http->tls) < 1)
+    {
+      // Failed
+      if ((error = ERR_get_error()) != 0)
+        _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI, ERR_error_string(error, NULL), 0);
+
+      http->status = HTTP_STATUS_ERROR;
+      http->error  = EPIPE;
+
+      SSL_CTX_free(context);
+
+      SSL_free(http->tls);
+      http->tls = NULL;
+
+      return (-1);
+    }
+  }
+
+  return (0);
+}
+
+
+/*
+ * '_httpTLSStop()' - Shut down SSL/TLS on a connection.
+ */
+
+void
+_httpTLSStop(http_t *http)		// I - Connection to server
+{
+  SSL_CTX	*context;		// Context for encryption
+
+
+  context = SSL_get_SSL_CTX(http->tls);
+
+  SSL_shutdown(http->tls);
+  SSL_CTX_free(context);
+  SSL_free(http->tls);
+
+  http->tls = NULL;
+}
+
+
+/*
+ * '_httpTLSWrite()' - Write to a SSL/TLS connection.
+ */
+
+int					// O - Bytes written
+_httpTLSWrite(http_t     *http,		// I - Connection to server
+	      const char *buf,		// I - Buffer holding data
+	      int        len)		// I - Length of buffer
+{
+  return (SSL_write(http->tls, buf, len));
+}
+
+
+/*
+ * 'http_bio_ctrl()' - Control the HTTP connection.
+ */
+
+static long				// O - Result/data
+http_bio_ctrl(BIO  *h,			// I - BIO data
+              int  cmd,			// I - Control command
+	      long arg1,		// I - First argument
+	      void *arg2)		// I - Second argument
+{
+  switch (cmd)
+  {
+    default :
+        return (0);
+
+    case BIO_CTRL_RESET :
+        BIO_set_data(h, NULL);
+	return (0);
+
+    case BIO_C_SET_FILE_PTR :
+        BIO_set_data(h, arg2);
+        BIO_set_init(h, 1);
+	return (1);
+
+    case BIO_C_GET_FILE_PTR :
+        if (arg2)
+	{
+	  *((void **)arg2) = BIO_get_data(h);
+	  return (1);
+	}
+	else
+	  return (0);
+
+    case BIO_CTRL_DUP :
+    case BIO_CTRL_FLUSH :
+        return (1);
+  }
+}
+
+
+/*
+ * 'http_bio_free()' - Free OpenSSL data.
+ */
+
+static int				// O - 1 on success, 0 on failure
+http_bio_free(BIO *h)			// I - BIO data
+{
+  if (!h)
+    return (0);
+
+  if (BIO_get_shutdown(h))
+    BIO_set_init(h, 0);
+
+  return (1);
+}
+
+
+/*
+ * 'http_bio_new()' - Initialize an OpenSSL BIO structure.
+ */
+
+static int				// O - 1 on success, 0 on failure
+http_bio_new(BIO *h)			// I - BIO data
+{
+  if (!h)
+    return (0);
+
+  BIO_set_init(h, 0);
+  BIO_set_data(h, NULL);
+
+  return (1);
+}
+
+
+/*
+ * 'http_bio_puts()' - Send a string for OpenSSL.
+ */
+
+static int				// O - Bytes written
+http_bio_puts(BIO        *h,		// I - BIO data
+              const char *str)		// I - String to write
+{
+#ifdef WIN32
+  return (send(((http_t *)BIO_get_data(h))->fd, str, (int)strlen(str), 0));
+#else
+  return ((int)send(((http_t *)BIO_get_data(h))->fd, str, strlen(str), 0));
+#endif // WIN32
+}
+
+
+/*
+ * 'http_bio_read()' - Read data for OpenSSL.
+ */
+
+static int				// O - Bytes read
+http_bio_read(BIO  *h,			// I - BIO data
+              char *buf,		// I - Buffer
+	      int  size)		// I - Number of bytes to read
+{
+  http_t	*http;			// HTTP connection
+
+
+  http = (http_t *)BIO_get_data(h);
+
+  if (!http->blocking)
+  {
+   /*
+    * Make sure we have data before we read...
+    */
+
+    if (!_httpWait(http, 10000, 0))
+    {
+#ifdef WIN32
+      http->error = WSAETIMEDOUT;
+#else
+      http->error = ETIMEDOUT;
+#endif // WIN32
+
+      return (-1);
+    }
+  }
+
+  return ((int)recv(http->fd, buf, (size_t)size, 0));
+}
+
+
+/*
+ * 'http_bio_write()' - Write data for OpenSSL.
+ */
+
+static int				// O - Bytes written
+http_bio_write(BIO        *h,		// I - BIO data
+               const char *buf,		// I - Buffer to write
+	       int        num)		// I - Number of bytes to write
+{
+  return (send(((http_t *)BIO_get_data(h))->fd, buf, num, 0));
+}
+
+
+/*
+ * 'http_create_credential()' - Create a single credential in the internal format.
+ */
+
+static X509 *				// O - Certificate
+http_create_credential(
+    http_credential_t *credential)	// I - Credential
+{
+  X509	*cert = NULL;			// Certificate
+  BIO	*bio;				// Basic I/O for string
+
+
+  if (!credential)
+    return (NULL);
+
+  if ((bio = BIO_new_mem_buf(credential->data, credential->datalen)) == NULL)
+    return (NULL);
+
+  PEM_read_bio_X509(bio, &cert, NULL, (void *)"");
+
+  BIO_free(bio);
+
+  return (cert);
+}
+
+
+/*
+ * 'http_default_path()' - Get the default credential store path.
+ */
+
+static const char *			// O - Path or NULL on error
+http_default_path(
+    char   *buffer,			// I - Path buffer
+    size_t bufsize)			// I - Size of path buffer
+{
+  _cups_globals_t	*cg = _cupsGlobals();
+					// Pointer to library globals
+
+
+#ifdef _WIN32
+  if (cg->home)
+#else
+  if (cg->home && getuid())
+#endif // _WIN32
+  {
+    snprintf(buffer, bufsize, "%s/.cups", cg->home);
+    if (access(buffer, 0))
+    {
+      DEBUG_printf(("1http_default_path: Making directory \"%s\".", buffer));
+      if (mkdir(buffer, 0700))
+      {
+        DEBUG_printf(("1http_default_path: Failed to make directory: %s", strerror(errno)));
+        return (NULL);
+      }
+    }
+
+    snprintf(buffer, bufsize, "%s/.cups/ssl", cg->home);
+    if (access(buffer, 0))
+    {
+      DEBUG_printf(("1http_default_path: Making directory \"%s\".", buffer));
+      if (mkdir(buffer, 0700))
+      {
+        DEBUG_printf(("1http_default_path: Failed to make directory: %s", strerror(errno)));
+        return (NULL);
+      }
+    }
+  }
+  else
+    strlcpy(buffer, CUPS_SERVERROOT "/ssl", bufsize);
+
+  DEBUG_printf(("1http_default_path: Using default path \"%s\".", buffer));
+
+  return (buffer);
+}
+
+
+//
+// 'http_get_date()' - Get the notBefore or notAfter date of a certificate.
+//
+
+static time_t				// O - UNIX time in seconds
+http_get_date(X509 *cert,		// I - Certificate
+              int  which)		// I - 0 for notBefore, 1 for notAfter
+{
+  unsigned char	*expiration;		// Expiration date of cert
+  struct tm	exptm;			// Expiration date components
+
+
+  if (which)
+    ASN1_STRING_to_UTF8(&expiration, X509_get0_notAfter(cert));
+  else
+    ASN1_STRING_to_UTF8(&expiration, X509_get0_notBefore(cert));
+
+  memset(&exptm, 0, sizeof(exptm));
+  if (strlen((char *)expiration) > 13)
+  {
+    // 4-digit year
+    exptm.tm_year = (expiration[0] - '0') * 1000 + (expiration[1] - '0') * 100 + (expiration[2] - '0') * 10 + expiration[3] - '0' - 1900;
+    exptm.tm_mon  = (expiration[4] - '0') * 10 + expiration[5] - '0' - 1;
+    exptm.tm_mday = (expiration[6] - '0') * 10 + expiration[7] - '0';
+    exptm.tm_hour = (expiration[8] - '0') * 10 + expiration[9] - '0';
+    exptm.tm_min  = (expiration[10] - '0') * 10 + expiration[11] - '0';
+    exptm.tm_sec  = (expiration[12] - '0') * 10 + expiration[13] - '0';
+  }
+  else
+  {
+    // 2-digit year
+    exptm.tm_year = 100 + (expiration[0] - '0') * 10 + expiration[1] - '0';
+    exptm.tm_mon  = (expiration[2] - '0') * 10 + expiration[3] - '0' - 1;
+    exptm.tm_mday = (expiration[4] - '0') * 10 + expiration[5] - '0';
+    exptm.tm_hour = (expiration[6] - '0') * 10 + expiration[7] - '0';
+    exptm.tm_min  = (expiration[8] - '0') * 10 + expiration[9] - '0';
+    exptm.tm_sec  = (expiration[10] - '0') * 10 + expiration[11] - '0';
+  }
+
+  OPENSSL_free(expiration);
+
+  return (mktime(&exptm));
+}
+
+
+#if 0
+/*
+ * 'http_load_crl()' - Load the certificate revocation list, if any.
+ */
+
+static void
+http_load_crl(void)
+{
+  _cupsMutexLock(&tls_mutex);
+
+  if (!openssl_x509_crl_init(&tls_crl))
+  {
+    cups_file_t		*fp;		// CRL file
+    char		filename[1024],	// site.crl
+			line[256];	// Base64-encoded line
+    unsigned char	*data = NULL;	// Buffer for cert data
+    size_t		alloc_data = 0,	// Bytes allocated
+			num_data = 0;	// Bytes used
+    int			decoded;	// Bytes decoded
+    openssl_datum_t	datum;		// Data record
+
+
+    http_make_path(filename, sizeof(filename), CUPS_SERVERROOT, "site", "crl");
+
+    if ((fp = cupsFileOpen(filename, "r")) != NULL)
+    {
+      while (cupsFileGets(fp, line, sizeof(line)))
+      {
+	if (!strcmp(line, "-----BEGIN X509 CRL-----"))
+	{
+	  if (num_data)
+	  {
+	   /*
+	    * Missing END X509 CRL...
+	    */
+
+	    break;
+	  }
+	}
+	else if (!strcmp(line, "-----END X509 CRL-----"))
+	{
+	  if (!num_data)
+	  {
+	   /*
+	    * Missing data...
+	    */
+
+	    break;
+	  }
+
+          datum.data = data;
+	  datum.size = num_data;
+
+	  openssl_x509_crl_import(tls_crl, &datum, GNUTLS_X509_FMT_PEM);
+
+	  num_data = 0;
+	}
+	else
+	{
+	  if (alloc_data == 0)
+	  {
+	    data       = malloc(2048);
+	    alloc_data = 2048;
+
+	    if (!data)
+	      break;
+	  }
+	  else if ((num_data + strlen(line)) >= alloc_data)
+	  {
+	    unsigned char *tdata = realloc(data, alloc_data + 1024);
+					    // Expanded buffer
+
+	    if (!tdata)
+	      break;
+
+	    data       = tdata;
+	    alloc_data += 1024;
+	  }
+
+	  decoded = alloc_data - num_data;
+	  httpDecode64_2((char *)data + num_data, &decoded, line);
+	  num_data += (size_t)decoded;
+	}
+      }
+
+      cupsFileClose(fp);
+
+      if (data)
+	free(data);
+    }
+  }
+
+  _cupsMutexUnlock(&tls_mutex);
+}
+#endif // 0
+
+
+/*
+ * 'http_make_path()' - Format a filename for a certificate or key file.
+ */
+
+static const char *			// O - Filename
+http_make_path(
+    char       *buffer,			// I - Filename buffer
+    size_t     bufsize,			// I - Size of buffer
+    const char *dirname,		// I - Directory
+    const char *filename,		// I - Filename (usually hostname)
+    const char *ext)			// I - Extension
+{
+  char	*bufptr,			// Pointer into buffer
+	*bufend = buffer + bufsize - 1;	// End of buffer
+
+
+  snprintf(buffer, bufsize, "%s/", dirname);
+  bufptr = buffer + strlen(buffer);
+
+  while (*filename && bufptr < bufend)
+  {
+    if (_cups_isalnum(*filename) || *filename == '-' || *filename == '.')
+      *bufptr++ = *filename;
+    else
+      *bufptr++ = '_';
+
+    filename ++;
+  }
+
+  if (bufptr < bufend && filename[-1] != '.')
+    *bufptr++ = '.';
+
+  strlcpy(bufptr, ext, (size_t)(bufend - bufptr + 1));
+
+  return (buffer);
+}
+
+
+//
+// 'http_x509_add_san()' - Add a subjectAltName extension to an X.509 certificate.
+//
+
+static void
+http_x509_add_san(X509       *cert,	// I - Certificate
+                  const char *name)	// I - Hostname
+{
+  char		dns_name[1024];		// DNS: prefixed hostname
+  X509_EXTENSION *san_ext;		// Extension for subjectAltName
+  ASN1_OCTET_STRING *san_asn1;		// ASN1 string
+
+
+  // The subjectAltName value for DNS names starts with a DNS: prefix...
+  snprintf(dns_name, sizeof(dns_name), "DNS: %s", name);
+
+  if ((san_asn1 = ASN1_OCTET_STRING_new()) == NULL)
+    return;
+
+  ASN1_OCTET_STRING_set(san_asn1, (unsigned char *)dns_name, strlen(dns_name));
+  if ((san_ext = X509_EXTENSION_create_by_NID(NULL, NID_subject_alt_name, 0, san_asn1)) == NULL)
+  {
+    ASN1_OCTET_STRING_free(san_asn1);
+    return;
+  }
+
+  X509_add_ext(cert, san_ext, -1);
+  X509_EXTENSION_free(san_ext);
+  ASN1_OCTET_STRING_free(san_asn1);
+}
Index: create-2.4.2-tls-openssl-patch/cups-2.4.2-new/cups
===================================================================
--- create-2.4.2-tls-openssl-patch/cups-2.4.2-new/cups	(nonexistent)
+++ create-2.4.2-tls-openssl-patch/cups-2.4.2-new/cups	(revision 5)

Property changes on: create-2.4.2-tls-openssl-patch/cups-2.4.2-new/cups
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-2.4.2-tls-openssl-patch/cups-2.4.2-new
===================================================================
--- create-2.4.2-tls-openssl-patch/cups-2.4.2-new	(nonexistent)
+++ create-2.4.2-tls-openssl-patch/cups-2.4.2-new	(revision 5)

Property changes on: create-2.4.2-tls-openssl-patch/cups-2.4.2-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-2.4.2-tls-openssl-patch/file.list
===================================================================
--- create-2.4.2-tls-openssl-patch/file.list	(nonexistent)
+++ create-2.4.2-tls-openssl-patch/file.list	(revision 5)
@@ -0,0 +1 @@
+cups-2.4.2/cups/tls-openssl.c
Index: create-2.4.2-tls-openssl-patch
===================================================================
--- create-2.4.2-tls-openssl-patch	(nonexistent)
+++ create-2.4.2-tls-openssl-patch	(revision 5)

Property changes on: create-2.4.2-tls-openssl-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: patches/README
===================================================================
--- patches/README	(nonexistent)
+++ patches/README	(revision 5)
@@ -0,0 +1,6 @@
+
+/* begin *
+
+   TODO: Leave some comment here.
+
+ * end */
Index: patches
===================================================================
--- patches	(nonexistent)
+++ patches	(revision 5)

Property changes on: patches
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: .
===================================================================
--- .	(nonexistent)
+++ .	(revision 5)

Property changes on: .
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~