Merge changes from CUPS trunk, r7566.


git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@761 a1ca3aef-8c08-0410-bb20-df032aa958be
diff --git a/CHANGES.txt b/CHANGES.txt
index bb2c8d6..64b2990 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,8 +1,10 @@
-CHANGES.txt - 2008-04-30
+CHANGES.txt - 2008-05-14
 ------------------------
 
 CHANGES IN CUPS V1.4b1
 
+	- Filters can now send PPD: messages to stderr to set PPD
+	  keywords like DefaultPageSize while a job is printing.
 	- Added a mdns backend for discovery and printing to printers
 	  that advertise themselves via DNS-SD (Bonjour)
 	- The ipp, lpd, and socket backends now support DNS-SD service
diff --git a/Makefile b/Makefile
index 3b2c44e..733c86b 100644
--- a/Makefile
+++ b/Makefile
@@ -31,13 +31,32 @@
 
 all:
 	chmod +x cups-config
+	echo Using ARCHFLAGS="$(ARCHFLAGS)"
 	echo Using ALL_CFLAGS="$(ALL_CFLAGS)"
 	echo Using ALL_CXXFLAGS="$(ALL_CXXFLAGS)"
+	echo Using DSOFLAGS="$(DSOFLAGS)"
 	echo Using LDFLAGS="$(LDFLAGS)"
 	echo Using LIBS="$(LIBS)"
 	for dir in $(DIRS); do\
 		echo Making all in $$dir... ;\
-		(cd $$dir ; $(MAKE) $(MFLAGS)) || exit 1;\
+		(cd $$dir ; $(MAKE) $(MFLAGS) all) || exit 1;\
+	done
+
+
+#
+# Make library targets...
+#
+
+libs:
+	echo Using ARCHFLAGS="$(ARCHFLAGS)"
+	echo Using ALL_CFLAGS="$(ALL_CFLAGS)"
+	echo Using ALL_CXXFLAGS="$(ALL_CXXFLAGS)"
+	echo Using DSOFLAGS="$(DSOFLAGS)"
+	echo Using LDFLAGS="$(LDFLAGS)"
+	echo Using LIBS="$(LIBS)"
+	for dir in $(DIRS); do\
+		echo Making all in $$dir... ;\
+		(cd $$dir ; $(MAKE) $(MFLAGS) libs) || exit 1;\
 	done
 
 
@@ -189,10 +208,10 @@
 # Install programs...
 #
 
-install-exec:
+install-exec:	all
 	for dir in $(DIRS); do\
 		echo Installing programs in $$dir... ;\
-		(cd $$dir; $(MAKE) $(MFLAGS) all install-exec) || exit 1;\
+		(cd $$dir; $(MAKE) $(MFLAGS) install-exec) || exit 1;\
 	done
 
 
@@ -200,10 +219,10 @@
 # Install libraries...
 #
 
-install-libs:
+install-libs:	libs
 	for dir in $(DIRS); do\
 		echo Installing libraries in $$dir... ;\
-		(cd $$dir; $(MAKE) $(MFLAGS) all install-libs) || exit 1;\
+		(cd $$dir; $(MAKE) $(MFLAGS) install-libs) || exit 1;\
 	done
 
 
diff --git a/backend/Makefile b/backend/Makefile
index 45bf74c..a5e1db3 100644
--- a/backend/Makefile
+++ b/backend/Makefile
@@ -34,6 +34,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:
+
+
+#
 # Clean all object files...
 #
 
diff --git a/backend/mdns.c b/backend/mdns.c
index f7f78aa..3678267 100644
--- a/backend/mdns.c
+++ b/backend/mdns.c
@@ -262,10 +262,9 @@
 	  DNSServiceRefDeallocate(device->ref);
 	  device->ref = 0;
 
-          httpAssembleURIf(HTTP_URI_CODING_ALL, device_uri, sizeof(device_uri),
-	                  schemes[device->type], NULL,
-			  device->cups_shared ? "cups" : "", 0,
-			  "/%s", device->fullName);
+          httpAssembleURI(HTTP_URI_CODING_ALL, device_uri, sizeof(device_uri),
+	                  schemes[device->type], NULL, device->fullName, 0,
+			  device->cups_shared ? "/cups" : "/");
 
           printf("network %s \"%s\" \"%s\"\n", device_uri,
 	         device->make_and_model ? device->make_and_model : "Unknown",
diff --git a/backend/network.c b/backend/network.c
index 68d346f..d83ea9c 100644
--- a/backend/network.c
+++ b/backend/network.c
@@ -197,12 +197,11 @@
   * Resolve it as needed...
   */
 
-  if (strstr(resource, "._tcp") || strstr(hostname, "._tcp"))
+  if (strstr(hostname, "._tcp"))
   {
 #ifdef HAVE_DNSSD
     DNSServiceRef	ref;		/* DNS-SD service reference */
-    char		*full_name,	/* Full (service) name */
-			*regtype,	/* Pointer to type in hostname */
+    char		*regtype,	/* Pointer to type in hostname */
 			*domain;	/* Pointer to domain in hostname */
     static char		resolved_uri[HTTP_MAX_URI];
     					/* Resolved device URI */
@@ -211,12 +210,7 @@
     * Separate the hostname into service name, registration type, and domain...
     */
 
-    if (strstr(resource, "._tcp"))
-      full_name = resource + 1;
-    else
-      full_name = hostname;
-
-    regtype = strchr(full_name, '.');
+    regtype = strchr(hostname, '.');
     *regtype++ = '\0';
 
     domain = regtype + strlen(regtype) - 1;
@@ -234,9 +228,9 @@
 
     fprintf(stderr,
             "DEBUG: Resolving service \"%s\", regtype \"%s\", domain \"%s\"\n",
-	    full_name, regtype, domain ? domain : "(null)");
+	    hostname, regtype, domain ? domain : "(null)");
 
-    if (DNSServiceResolve(&ref, 0, 0, full_name, regtype, domain,
+    if (DNSServiceResolve(&ref, 0, 0, hostname, regtype, domain,
 			  resolve_callback,
 			  resolved_uri) == kDNSServiceErr_NoError)
     {
diff --git a/berkeley/Makefile b/berkeley/Makefile
index 504796c..7531c01 100644
--- a/berkeley/Makefile
+++ b/berkeley/Makefile
@@ -27,6 +27,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:
+
+
+#
 # Clean all object files...
 #
 
diff --git a/cgi-bin/Makefile b/cgi-bin/Makefile
index 9a49370..d0c0c01 100644
--- a/cgi-bin/Makefile
+++ b/cgi-bin/Makefile
@@ -42,14 +42,17 @@
 		help.cgi \
 		jobs.cgi \
 		printers.cgi
-TARGETS	=	\
+LIBTARGETS =	\
 		libcupscgi.a \
 		$(LIBCUPSCGI) \
 		$(LIB32CUPSCGI) \
 		$(LIB32CUPSCGI) \
-		$(CGIS) \
 		testcgi \
-		testhi \
+		testhi
+
+TARGETS	=	\
+		$(LIBTARGETS) \
+		$(CGIS) \
 		testtemplate
 
 
@@ -61,6 +64,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:		$(LIBTARGETS)
+
+
+#
 # Clean all object files...
 #
 
@@ -352,8 +362,10 @@
 
 testcgi:	testcgi.o ../Makedefs libcupscgi.a ../cups/libcups.a
 	echo Linking $@...
-	$(CC) $(LDFLAGS) -o $@ testcgi.o libcupscgi.a ../cups/libcups.a \
-		$(COMMONLIBS) $(SSLLIBS) $(LIBZ) $(LIBGSSAPI)
+	$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testcgi.o libcupscgi.a \
+		../cups/libcups.a $(COMMONLIBS) $(SSLLIBS) $(LIBZ) $(LIBGSSAPI)
+	echo Testing CGI API...
+	./testcgi
 
 
 #
@@ -362,8 +374,10 @@
 
 testhi:	testhi.o ../Makedefs libcupscgi.a ../cups/libcups.a
 	echo Linking $@...
-	$(CC) $(LDFLAGS) -o $@ testhi.o libcupscgi.a ../cups/libcups.a \
-		$(COMMONLIBS) $(SSLLIBS) $(LIBZ) $(LIBGSSAPI)
+	$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testhi.o libcupscgi.a \
+		../cups/libcups.a $(COMMONLIBS) $(SSLLIBS) $(LIBZ) $(LIBGSSAPI)
+	echo Testing help index API...
+	./testhi
 
 
 #
diff --git a/conf/Makefile b/conf/Makefile
index 60154aa..90ab0cd 100644
--- a/conf/Makefile
+++ b/conf/Makefile
@@ -31,6 +31,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:
+
+
+#
 # Clean all config and object files...
 #
 
diff --git a/cups/Makefile b/cups/Makefile
index 95a3769..48e6ced 100644
--- a/cups/Makefile
+++ b/cups/Makefile
@@ -108,20 +108,23 @@
 # Targets in this directory...
 #
 
-TARGETS	=	\
+LIBTARGETS =	\
 		$(LIBCUPS) \
 		$(LIB32CUPS) \
 		$(LIB64CUPS) \
 		libcups.a \
-		testadmin \
 		testarray \
-		testcups \
 		testfile \
 		testhttp \
 		testi18n \
 		testipp \
 		testlang \
-		testppd \
+		testppd
+
+TARGETS	=	\
+		$(LIBTARGETS) \
+		testadmin \
+		testcups \
 		testsnmp
 
 
@@ -133,6 +136,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:		$(LIBTARGETS)
+
+
+#
 # Remove object and target files...
 #
 
@@ -382,8 +392,10 @@
 
 testarray:	testarray.o libcups.a
 	echo Linking $@...
-	$(CC) $(LDFLAGS) -o $@ testarray.o libcups.a \
+	$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testarray.o libcups.a \
 		$(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
+	echo Running array API tests...
+	./testarray
 
 
 #
@@ -402,8 +414,10 @@
 
 testfile:	testfile.o libcups.a
 	echo Linking $@...
-	$(CC) $(LDFLAGS) -o $@ testfile.o libcups.a \
+	$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testfile.o libcups.a \
 		$(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
+	echo Running file API tests...
+	./testfile
 
 
 #
@@ -412,8 +426,10 @@
 
 testhttp:	testhttp.o libcups.a
 	echo Linking $@...
-	$(CC) $(LDFLAGS) -o $@ testhttp.o libcups.a \
+	$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testhttp.o libcups.a \
 		$(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
+	echo Running HTTP API tests...
+	./testhttp
 
 
 #
@@ -422,8 +438,10 @@
 
 testipp:	testipp.o libcups.a
 	echo Linking $@...
-	$(CC) $(LDFLAGS) -o $@ testipp.o libcups.a \
+	$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testipp.o libcups.a \
 		$(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
+	echo Running IPP API tests...
+	./testipp
 
 
 #
@@ -432,8 +450,10 @@
 
 testi18n:	testi18n.o libcups.a
 	echo Linking $@...
-	$(CC) $(LDFLAGS) -o $@ testi18n.o libcups.a \
+	$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testi18n.o libcups.a \
 		$(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
+	echo Running internationalization API tests...
+	./testi18n
 
 
 #
@@ -442,8 +462,10 @@
 
 testlang:	testlang.o libcups.a
 	echo Linking $@...
-	$(CC) $(LDFLAGS) -o $@ testlang.o libcups.a \
+	$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testlang.o libcups.a \
 		$(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
+	echo Running language API tests...
+	./testlang
 
 
 #
@@ -452,8 +474,10 @@
 
 testppd:	testppd.o libcups.a
 	echo Linking $@...
-	$(CC) $(LDFLAGS) -o $@ testppd.o libcups.a \
+	$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testppd.o libcups.a \
 		$(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
+	echo Running PPD API tests...
+	./testppd
 
 
 #
diff --git a/cups/file.c b/cups/file.c
index 2845395..d3726cf 100644
--- a/cups/file.c
+++ b/cups/file.c
@@ -1413,7 +1413,11 @@
   }
 #endif /* HAVE_LIBZ */
 
-  lseek(fp->fd, 0, SEEK_SET);
+  if (lseek(fp->fd, 0, SEEK_SET))
+  {
+    DEBUG_printf(("cupsFileRewind: lseek failed: %s\n", strerror(errno)));
+    return (-1);
+  }
 
   fp->bufpos = 0;
   fp->pos    = 0;
@@ -1692,7 +1696,7 @@
 cupsFileTell(cups_file_t *fp)		/* I - CUPS file */
 {
   DEBUG_printf(("cupsFileTell(fp=%p)\n", fp));
-  DEBUG_printf(("cupsFileTell: pos=" CUPS_LLFMT "\n", CUPS_LLCAST fp->pos));
+  DEBUG_printf(("cupsFileTell: pos=" CUPS_LLFMT "\n", CUPS_LLCAST (fp ? fp->pos : -1)));
 
   return (fp ? fp->pos : 0);
 }
@@ -1867,7 +1871,7 @@
                 fp->ptr, fp->end, fp->buf, CUPS_LLCAST fp->bufpos, fp->eof));
 
   if (fp->ptr && fp->end)
-    fp->bufpos += fp->end - fp->ptr;
+    fp->bufpos += fp->end - fp->buf;
 
 #ifdef HAVE_LIBZ
   DEBUG_printf(("cups_fill: fp->compressed=%d\n", fp->compressed));
@@ -1915,7 +1919,8 @@
 	fp->ptr = fp->buf;
 	fp->end = fp->buf + bytes;
 
-        DEBUG_printf(("    returning " CUPS_LLFMT "!\n", CUPS_LLCAST bytes));
+        DEBUG_printf(("cups_fill: Returning " CUPS_LLFMT "!\n",
+	              CUPS_LLCAST bytes));
 
 	return (bytes);
       }
diff --git a/cups/http-support.c b/cups/http-support.c
index a8d58b0..145f199 100644
--- a/cups/http-support.c
+++ b/cups/http-support.c
@@ -195,15 +195,17 @@
 
    /*
     * Then add the hostname.  Since IPv6 is a particular pain to deal
-    * with, we have several special cases to deal with...  If we get
+    * with, we have several special cases to deal with.  If we get
     * an IPv6 address with brackets around it, assume it is already in
-    * URI format...
+    * URI format.  Since DNS-SD service names can sometimes look like
+    * raw IPv6 addresses, we specifically look for "._tcp" in the name,
+    * too...
     */
 
-    if (host[0] != '[' && strchr(host, ':'))
+    if (host[0] != '[' && strchr(host, ':') && !strstr(host, "._tcp"))
     {
      /*
-      * We have an IPv6 address...
+      * We have a raw IPv6 address...
       */
 
       if (strchr(host, '%'))
@@ -263,7 +265,7 @@
       * Otherwise, just copy the host string...
       */
 
-      ptr = http_copy_encode(ptr, host, end, NULL, NULL,
+      ptr = http_copy_encode(ptr, host, end, ":/?#[]@", NULL,
                              encoding & HTTP_URI_CODING_HOSTNAME);
 
       if (!ptr)
diff --git a/cups/language.c b/cups/language.c
index eb041b0..2949b35 100644
--- a/cups/language.c
+++ b/cups/language.c
@@ -441,8 +441,13 @@
   * preference so we have to look it up this way...
   */
 
-  if (!language && (language = getenv("LANG")) == NULL)
-    language = appleLangDefault();
+  if (!language)
+  {
+    if ((language = getenv("LANG")) == NULL)
+      language = appleLangDefault();
+
+    DEBUG_printf(("cupsLangGet: language=\"%s\"\n", language));
+  }
 
 #else
  /*
@@ -705,6 +710,8 @@
     pthread_mutex_unlock(&lang_mutex);
 #endif /* HAVE_PTHREAD_H */
 
+    DEBUG_printf(("cupsLangGet: Using cached copy of \"%s\"...\n", real));
+
     return (lang);
   }
 
@@ -892,14 +899,21 @@
   */
 
   if ((a = cupsArrayNew((cups_array_func_t)cups_message_compare, NULL)) == NULL)
+  {
+    DEBUG_puts("_cupsMessageLoad: Unable to allocate array!");
     return (NULL);
+  }
 
  /*
   * Open the message catalog file...
   */
 
   if ((fp = cupsFileOpen(filename, "r")) == NULL)
+  {
+    DEBUG_printf(("_cupsMessageLoad: Unable to open file: %s\n",
+                  strerror(errno)));
     return (a);
+  }
 
  /*
   * Read messages from the catalog file until EOF...
@@ -1050,6 +1064,9 @@
 
   cupsFileClose(fp);
 
+  DEBUG_printf(("_cupsMessageLoad: Returning %d messages...\n",
+                cupsArrayCount(a)));
+
   return (a);
 }
 
diff --git a/cups/localize.c b/cups/localize.c
index 1745396..3136d4b 100644
--- a/cups/localize.c
+++ b/cups/localize.c
@@ -574,7 +574,7 @@
   snprintf(lkeyword, sizeof(lkeyword), "%s.%s", ll_CC, keyword);
   if ((attr = ppdFindAttr(ppd, lkeyword, spec)) == NULL)
   {
-    snprintf(lkeyword, sizeof(lkeyword), "%2s.%s", ll_CC, keyword);
+    snprintf(lkeyword, sizeof(lkeyword), "%2.2s.%s", ll_CC, keyword);
     attr = ppdFindAttr(ppd, lkeyword, spec);
 
     if (!attr)
diff --git a/cups/testfile.c b/cups/testfile.c
index d8a1b88..2140765 100644
--- a/cups/testfile.c
+++ b/cups/testfile.c
@@ -17,6 +17,7 @@
  * Contents:
  *
  *   main()             - Main entry.
+ *   count_lines()      - Count the number of lines in a file.
  *   random_tests()     - Do random access tests.
  *   read_write_tests() - Perform read/write tests.
  */
@@ -43,6 +44,7 @@
  * Local functions...
  */
 
+static int	count_lines(cups_file_t *fp);
 static int	random_tests(void);
 static int	read_write_tests(int compression);
 
@@ -57,8 +59,10 @@
 {
   int		status;			/* Exit status */
   char		filename[1024];		/* Filename buffer */
+  cups_file_t	*fp;			/* File pointer */
   int		fds[2];			/* Open file descriptors */
   cups_file_t	*fdfile;		/* File opened with cupsFileOpenFd() */
+  int		count;			/* Number of lines in file */
 
 
   if (argc == 1)
@@ -120,6 +124,55 @@
     }
 
    /*
+    * Count lines in euc-jp.txt, rewind, then count again.
+    */
+
+    fputs("\ncupsFileOpen(\"../data/euc-jp.txt\", \"r\"): ", stdout);
+
+    if ((fp = cupsFileOpen("../data/euc-jp.txt", "r")) == NULL)
+    {
+      puts("FAIL");
+      status ++;
+    }
+    else
+    {
+      puts("PASS");
+      fputs("cupsFileGets: ", stdout);
+
+      if ((count = count_lines(fp)) != 15184)
+      {
+        printf("FAIL (got %d lines, expected 15184)\n", count);
+	status ++;
+      }
+      else
+      {
+        puts("PASS");
+	fputs("cupsFileRewind: ", stdout);
+
+	if (cupsFileRewind(fp) != 0)
+	{
+	  puts("FAIL");
+	  status ++;
+	}
+	else
+	{
+	  puts("PASS");
+	  fputs("cupsFileGets: ", stdout);
+
+	  if ((count = count_lines(fp)) != 15184)
+	  {
+	    printf("FAIL (got %d lines, expected 15184)\n", count);
+	    status ++;
+	  }
+	  else
+	    puts("PASS");
+        }
+      }
+
+      cupsFileClose(fp);
+    }
+
+   /*
     * Test path functions...
     */
 
@@ -153,10 +206,8 @@
     * Cat the filename on the command-line...
     */
 
-    cups_file_t	*fp;			/* File pointer */
     char	line[1024];		/* Line from file */
 
-
     if ((fp = cupsFileOpen(argv[1], "r")) == NULL)
     {
       perror(argv[1]);
@@ -181,6 +232,23 @@
 
 
 /*
+ * 'count_lines()' - Count the number of lines in a file.
+ */
+
+static int				/* O - Number of lines */
+count_lines(cups_file_t *fp)		/* I - File to read from */
+{
+  int	count;				/* Number of lines */
+  char	line[1024];			/* Line buffer */
+
+
+  for (count = 0; cupsFileGets(fp, line, sizeof(line)); count ++);
+
+  return (count);
+}
+
+
+/*
  * 'random_tests()' - Do random access tests.
  */
 
diff --git a/cups/testhttp.c b/cups/testhttp.c
index 37f850c..fa9282f 100644
--- a/cups/testhttp.c
+++ b/cups/testhttp.c
@@ -93,6 +93,8 @@
 			    "ipp", "username:password", "fe80::200:1234:5678:9abc%eth0", "/ipp", 999, 999 },
 			  { HTTP_URI_OK, "http://server/admin?DEVICE_URI=usb://HP/Photosmart%25202600%2520series?serial=MY53OK70V10400",
 			    "http", "", "server", "/admin?DEVICE_URI=usb://HP/Photosmart%25202600%2520series?serial=MY53OK70V10400", 80, 0 },
+			  { HTTP_URI_OK, "lpd://Acme%20Laser%20(01%3A23%3A45).local._tcp._printer/",
+			    "lpd", "", "Acme Laser (01:23:45).local._tcp._printer", "/", 515, 0 },
 
 			  /* Missing scheme */
 			  { HTTP_URI_MISSING_SCHEME, "/path/to/file/index.html",
diff --git a/cups/testppd.c b/cups/testppd.c
index 9efa851..46e070c 100644
--- a/cups/testppd.c
+++ b/cups/testppd.c
@@ -26,6 +26,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <cups/string.h>
+#include <sys/stat.h>
 #include <errno.h>
 #include "ppd.h"
 #ifdef WIN32
@@ -106,6 +107,25 @@
 
   if (argc == 1)
   {
+   /*
+    * Setup directories for locale stuff...
+    */
+
+    if (access("locale", 0))
+    {
+      mkdir("locale", 0777);
+      mkdir("locale/fr", 0777);
+      symlink("../../../locale/cups_fr.po", "locale/fr/cups_fr.po");
+      mkdir("locale/zh_TW", 0777);
+      symlink("../../../locale/cups_zh_TW.po", "locale/zh_TW/cups_zh_TW.po");
+    }
+
+    putenv("LOCALEDIR=locale");
+
+   /*
+    * Do tests with test.ppd...
+    */
+
     fputs("ppdOpenFile: ", stdout);
 
     if ((ppd = ppdOpenFile("test.ppd")) != NULL)
diff --git a/cups/transcode.c b/cups/transcode.c
index 036106e..7a79b2a 100644
--- a/cups/transcode.c
+++ b/cups/transcode.c
@@ -473,11 +473,18 @@
   * Check for valid arguments and clear output...
   */
 
+  DEBUG_printf(("cupsUTF8ToUTF32(dest=%p, src=\"%s\", maxout=%d)\n", dest,
+                src ? (const char *)src : "(null)", maxout));
+
   if (dest)
     *dest = 0;
 
   if (!dest || !src || maxout < 1 || maxout > CUPS_MAX_USTRING)
+  {
+    DEBUG_puts("cupsUTF8ToUTF32: Returning -1 (bad arguments)");
+
     return (-1);
+  }
 
  /*
   * Convert input UTF-8 to output UTF-32 (and insert BOM)...
@@ -500,6 +507,8 @@
       */
 
       *dest++ = ch;
+
+      DEBUG_printf(("cupsUTF8ToUTF32: %02x => %08X\n", src[-1], ch));
       continue;
     }
     else if ((ch & 0xe0) == 0xc0)
@@ -509,8 +518,12 @@
       */
 
       next = *src++;
-      if (!next)
+      if ((next & 0xc0) != 0x80)
+      {
+        DEBUG_puts("cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)");
+
 	return (-1);
+      }
 
       ch32 = ((ch & 0x1f) << 6) | (next & 0x3f);
 
@@ -519,9 +532,16 @@
       */
 
       if (ch32 < 0x80)
+      {
+        DEBUG_puts("cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)");
+
 	return (-1);
+      }
 
       *dest++ = ch32;
+
+      DEBUG_printf(("cupsUTF8ToUTF32: %02x %02x => %08X\n",
+                    src[-2], src[-1], (unsigned)ch32));
     }
     else if ((ch & 0xf0) == 0xe0)
     {
@@ -530,14 +550,22 @@
       */
 
       next = *src++;
-      if (!next)
+      if ((next & 0xc0) != 0x80)
+      {
+        DEBUG_puts("cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)");
+
 	return (-1);
+      }
 
       ch32 = ((ch & 0x0f) << 6) | (next & 0x3f);
 
       next = *src++;
-      if (!next)
+      if ((next & 0xc0) != 0x80)
+      {
+        DEBUG_puts("cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)");
+
 	return (-1);
+      }
 
       ch32 = (ch32 << 6) | (next & 0x3f);
 
@@ -546,9 +574,16 @@
       */
 
       if (ch32 < 0x800)
+      {
+        DEBUG_puts("cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)");
+
 	return (-1);
+      }
 
       *dest++ = ch32;
+
+      DEBUG_printf(("cupsUTF8ToUTF32: %02x %02x %02x => %08X\n",
+                    src[-3], src[-2], src[-1], (unsigned)ch32));
     }
     else if ((ch & 0xf8) == 0xf0)
     {
@@ -557,20 +592,32 @@
       */
 
       next = *src++;
-      if (!next)
+      if ((next & 0xc0) != 0x80)
+      {
+        DEBUG_puts("cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)");
+
 	return (-1);
+      }
 
       ch32 = ((ch & 0x07) << 6) | (next & 0x3f);
 
       next = *src++;
-      if (!next)
+      if ((next & 0xc0) != 0x80)
+      {
+        DEBUG_puts("cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)");
+
 	return (-1);
+      }
 
       ch32 = (ch32 << 6) | (next & 0x3f);
 
       next = *src++;
-      if (!next)
+      if ((next & 0xc0) != 0x80)
+      {
+        DEBUG_puts("cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)");
+
 	return (-1);
+      }
 
       ch32 = (ch32 << 6) | (next & 0x3f);
 
@@ -579,9 +626,16 @@
       */
 
       if (ch32 < 0x10000)
+      {
+        DEBUG_puts("cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)");
+
 	return (-1);
+      }
 
       *dest++ = ch32;
+
+      DEBUG_printf(("cupsUTF8ToUTF32: %02x %02x %02x %02x => %08X\n",
+                    src[-4], src[-3], src[-2], src[-1], (unsigned)ch32));
     }
     else
     {
@@ -589,6 +643,8 @@
       * More than 4-octet (invalid UTF-8 sequence)...
       */
 
+      DEBUG_puts("cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)");
+
       return (-1);
     }
 
@@ -602,7 +658,9 @@
 
   *dest = 0;
 
-  return (i);
+  DEBUG_printf(("cupsUTF8ToUTF32: Returning %d characters\n", maxout - 1 - i));
+
+  return (maxout - 1 - i);
 }
 
 
@@ -638,11 +696,18 @@
   * Check for valid arguments and clear output...
   */
 
+  DEBUG_printf(("cupsUTF32ToUTF8(dest=%p, src=%p, maxout=%d)\n", dest, src,
+                maxout));
+
   if (dest)
     *dest = '\0';
 
   if (!dest || !src || maxout < 1)
+  {
+    DEBUG_puts("cupsUTF32ToUTF8: Returning -1 (bad args)");
+
     return (-1);
+  }
 
  /*
   * Check for leading BOM in UTF-32 and inverted BOM...
@@ -651,6 +716,8 @@
   start = dest;
   swap  = *src == 0xfffe0000;
 
+  DEBUG_printf(("cupsUTF32ToUTF8: swap=%d\n", swap));
+
   if (*src == 0xfffe0000 || *src == 0xfeff)
     src ++;
 
@@ -675,7 +742,11 @@
     */
 
     if (ch > 0x10ffff)
+    {
+      DEBUG_puts("cupsUTF32ToUTF8: Returning -1 (character out of range)");
+
       return (-1);
+    }
 
    /*
     * Convert UTF-32 character to UTF-8 character(s)...
@@ -689,6 +760,8 @@
 
       *dest++ = (cups_utf8_t)ch;
       i --;
+
+      DEBUG_printf(("cupsUTF32ToUTF8: %08x => %02x\n", (unsigned)ch, dest[-1]));
     }
     else if (ch < 0x800)
     {
@@ -697,11 +770,18 @@
       */
 
       if (i < 2)
+      {
+        DEBUG_puts("cupsUTF32ToUTF8: Returning -1 (too long 2)");
+
         return (-1);
+      }
 
       *dest++ = (cups_utf8_t)(0xc0 | ((ch >> 6) & 0x1f));
       *dest++ = (cups_utf8_t)(0x80 | (ch & 0x3f));
       i -= 2;
+
+      DEBUG_printf(("cupsUTF32ToUTF8: %08x => %02x %02x\n", (unsigned)ch,
+                    dest[-2], dest[-1]));
     }
     else if (ch < 0x10000)
     {
@@ -710,12 +790,19 @@
       */
 
       if (i < 3)
+      {
+        DEBUG_puts("cupsUTF32ToUTF8: Returning -1 (too long 3)");
+
         return (-1);
+      }
 
       *dest++ = (cups_utf8_t)(0xe0 | ((ch >> 12) & 0x0f));
       *dest++ = (cups_utf8_t)(0x80 | ((ch >> 6) & 0x3f));
       *dest++ = (cups_utf8_t)(0x80 | (ch & 0x3f));
       i -= 3;
+
+      DEBUG_printf(("cupsUTF32ToUTF8: %08x => %02x %02x %02x\n", (unsigned)ch,
+                    dest[-3], dest[-2], dest[-1]));
     }
     else
     {
@@ -731,11 +818,16 @@
       *dest++ = (cups_utf8_t)(0x80 | ((ch >> 6) & 0x3f));
       *dest++ = (cups_utf8_t)(0x80 | (ch & 0x3f));
       i -= 4;
+
+      DEBUG_printf(("cupsUTF32ToUTF8: %08x => %02x %02x %02x %02x\n",
+                    (unsigned)ch, dest[-4], dest[-3], dest[-2], dest[-1]));
     }
   }
 
   *dest = '\0';
 
+  DEBUG_printf(("cupsUTF32ToUTF8: Returning %d\n", (int)(dest - start)));
+
   return ((int)(dest - start));
 }
 
@@ -922,19 +1014,30 @@
 		*workptr;		/* Pointer into string */
 
 
+  DEBUG_printf(("conv_utf8_to_vbcs(dest=%p, src=\"%s\", maxout=%d, "
+                "encoding=%d)\n", dest, src, maxout, encoding));
+
  /*
   * Find legacy charset map in cache...
   */
 
   if ((vmap = (_cups_vmap_t *)get_charmap(encoding)) == NULL)
+  {
+    DEBUG_puts("conv_utf8_to_vbcs: Returning -1 (no charmap)");
+
     return (-1);
+  }
 
  /*
   * Convert input UTF-8 to internal UCS-4 (and insert BOM)...
   */
 
   if (cupsUTF8ToUTF32(work, src, CUPS_MAX_USTRING) < 0)
+  {
+    DEBUG_puts("conv_utf8_to_vbcs: Returning -1 (Unable to convert to UTF-32)");
+
     return (-1);
+  }
 
  /*
   * Convert internal UCS-4 to VBCS legacy charset (and delete BOM)...
@@ -943,8 +1046,6 @@
   for (start = dest, workptr = work + 1; *workptr && maxout > 1; maxout --)
   {
     unichar = *workptr++;
-    if (!unichar)
-      break;
 
    /*
     * Convert ASCII verbatim (optimization)...
@@ -953,6 +1054,10 @@
     if (unichar < 0x80)
     {
       *dest++ = (cups_sbcs_t)unichar;
+
+      DEBUG_printf(("conv_utf8_to_vbcs: %08x => %02X\n", (unsigned)unichar,
+                    dest[-1]));
+
       continue;
     }
 
@@ -977,7 +1082,11 @@
     if (legchar > 0xffffff)
     {
       if (maxout < 5)
+      {
+        DEBUG_puts("conv_utf8_to_vbcs: Returning -1 (out of space)");
+
         return (-1);
+      }
 
       *dest++ = (cups_sbcs_t)(legchar >> 24);
       *dest++ = (cups_sbcs_t)(legchar >> 16);
@@ -985,17 +1094,27 @@
       *dest++ = (cups_sbcs_t)legchar;
 
       maxout -= 3;
+
+      DEBUG_printf(("conv_utf8_to_vbcs: %08x => %02X %02X %02X %02X\n",
+                    (unsigned)unichar, dest[-4], dest[-3], dest[-2], dest[-1]));
     }
     else if (legchar > 0xffff)
     {
       if (maxout < 4)
+      {
+        DEBUG_puts("conv_utf8_to_vbcs: Returning -1 (out of space)");
+
         return (-1);
+      }
 
       *dest++ = (cups_sbcs_t)(legchar >> 16);
       *dest++ = (cups_sbcs_t)(legchar >> 8);
       *dest++ = (cups_sbcs_t)legchar;
 
       maxout -= 2;
+
+      DEBUG_printf(("conv_utf8_to_vbcs: %08x => %02X %02X %02X\n",
+                    (unsigned)unichar, dest[-3], dest[-2], dest[-1]));
     }
     else if (legchar > 0xff)
     {
@@ -1003,6 +1122,16 @@
       *dest++ = (cups_sbcs_t)legchar;
 
       maxout --;
+
+      DEBUG_printf(("conv_utf8_to_vbcs: %08x => %02X %02X\n",
+                    (unsigned)unichar, dest[-2], dest[-1]));
+    }
+    else
+    {
+      *dest++ = legchar;
+
+      DEBUG_printf(("conv_utf8_to_vbcs: %08x => %02X\n",
+                    (unsigned)unichar, dest[-1]));
     }
   }
 
@@ -1010,6 +1139,9 @@
 
   vmap->used --;
 
+  DEBUG_printf(("conv_utf8_to_vbcs: Returning %d characters\n",
+                (int)(dest - start)));
+
   return ((int)(dest - start));
 }
 
@@ -1038,8 +1170,15 @@
   * Find legacy charset map in cache...
   */
 
+  DEBUG_printf(("conv_vbcs_to_utf8(dest=%p, src=%p, maxout=%d, encoding=%d)\n",
+                dest, src, maxout, encoding));
+
   if ((vmap = (_cups_vmap_t *)get_charmap(encoding)) == NULL)
+  {
+    DEBUG_puts("conv_vbcs_to_utf8: Returning -1 (NULL vmap)");
+
     return (-1);
+  }
 
  /*
   * Convert input legacy charset to internal UCS-4 (and insert BOM)...
@@ -1058,6 +1197,9 @@
     if (legchar < 0x80)
     {
       *workptr++ = (cups_utf32_t)legchar;
+
+      DEBUG_printf(("conv_vbcs_to_utf8: %02X => %08X\n", src[-1],
+                    (unsigned)legchar));
       continue;
     }
 
@@ -1068,7 +1210,11 @@
     if (vmap->lead2char[(int)leadchar] == leadchar)
     {
       if (!*src)
+      {
+        DEBUG_puts("conv_vbcs_to_utf8: Returning -1 (short string)");
+
 	return (-1);
+      }
 
       legchar = (legchar << 8) | *src++;
   
@@ -1084,6 +1230,9 @@
 	*workptr++ = 0xfffd;
       else
 	*workptr++ = (cups_utf32_t)*crow;
+
+      DEBUG_printf(("conv_vbcs_to_utf8: %02X %02X => %08X\n",
+                    src[-2], src[-1], (unsigned)workptr[-1]));
       continue;
     }
 
@@ -1094,7 +1243,11 @@
     if (vmap->lead3char[(int)leadchar] == leadchar)
     {
       if (!*src || !src[1])
+      {
+        DEBUG_puts("conv_vbcs_to_utf8: Returning -1 (short string 2)");
+
 	return (-1);
+      }
 
       legchar = (legchar << 8) | *src++;
       legchar = (legchar << 8) | *src++;
@@ -1102,14 +1255,22 @@
     else if (vmap->lead4char[(int)leadchar] == leadchar)
     {
       if (!*src || !src[1] || !src[2])
+      {
+        DEBUG_puts("conv_vbcs_to_utf8: Returning -1 (short string 3)");
+
 	return (-1);
+      }
 
       legchar = (legchar << 8) | *src++;
       legchar = (legchar << 8) | *src++;
       legchar = (legchar << 8) | *src++;
     }
     else
+    {
+      DEBUG_puts("conv_vbcs_to_utf8: Returning -1 (bad character)");
+
       return (-1);
+    }
 
    /*
     * Find 3-byte or 4-byte legacy character...
@@ -1129,12 +1290,22 @@
       *workptr++ = 0xfffd;
     else
       *workptr++ = wide2uni->unichar;
+
+    if (vmap->lead3char[(int)leadchar] == leadchar)
+      DEBUG_printf(("conv_vbcs_to_utf8: %02X %02X %02X => %08X\n",
+		    src[-3], src[-2], src[-1], (unsigned)workptr[-1]));
+    else
+      DEBUG_printf(("conv_vbcs_to_utf8: %02X %02X %02X %02X => %08X\n",
+		    src[-4], src[-3], src[-2], src[-1], (unsigned)workptr[-1]));
   }
 
   *workptr = 0;
 
   vmap->used --;
 
+  DEBUG_printf(("conv_vbcs_to_utf8: Converting %d UTF-32 characters to UTF-8\n",
+                (int)(workptr - work)));
+
  /*
   * Convert internal UCS-4 to output UTF-8 (and delete BOM)...
   */
@@ -1204,6 +1375,8 @@
   _cups_globals_t *cg = _cupsGlobals();	/* Global data */
 
 
+  DEBUG_printf(("get_charmap(encoding=%d)\n", encoding));
+
  /*
   * Get the data directory and charset map name...
   */
@@ -1211,7 +1384,7 @@
   snprintf(filename, sizeof(filename), "%s/charmaps/%s.txt",
 	   cg->cups_datadir, _cupsEncodingName(encoding));
 
-  DEBUG_printf(("    filename=\"%s\"\n", filename));
+  DEBUG_printf(("get_charmap: filename=\"%s\"\n", filename));
 
  /*
   * Read charset map input file into cache...
@@ -1281,12 +1454,15 @@
   * See if we already have this SBCS charset map loaded...
   */
 
+  DEBUG_printf(("get_sbcs_charmap(encoding=%d, filename=\"%s\")\n", encoding,
+                filename));
+
   for (cmap = cmap_cache; cmap; cmap = cmap->next)
   {
     if (cmap->encoding == encoding)
     {
       cmap->used ++;
-      DEBUG_printf(("    returning existing cmap=%p\n", cmap));
+      DEBUG_printf(("get_sbcs_charmap: Returning existing cmap=%p\n", cmap));
 
       return ((void *)cmap);
     }
@@ -1297,7 +1473,11 @@
   */
 
   if ((fp = cupsFileOpen(filename, "r")) == NULL)
+  {
+    DEBUG_printf(("get_sbcs_charmap: Returning NULL (%s)\n", strerror(errno)));
+
     return (NULL);
+  }
 
  /*
   * Allocate memory for SBCS charset map...
@@ -1306,7 +1486,7 @@
   if ((cmap = (_cups_cmap_t *)calloc(1, sizeof(_cups_cmap_t))) == NULL)
   {
     cupsFileClose(fp);
-    DEBUG_puts("    Unable to allocate memory!");
+    DEBUG_puts("get_sbcs_charmap: Returning NULL (Unable to allocate memory)");
 
     return (NULL);
   }
@@ -1378,7 +1558,7 @@
   cmap->next = cmap_cache;
   cmap_cache = cmap;
 
-  DEBUG_printf(("    returning new cmap=%p\n", cmap));
+  DEBUG_printf(("get_sbcs_charmap: Returning new cmap=%p\n", cmap));
 
   return (cmap);
 
@@ -1392,7 +1572,7 @@
 
   cupsFileClose(fp);
 
-  DEBUG_puts("    Error, returning NULL!");
+  DEBUG_puts("get_sbcs_charmap: Returning NULL (Read/format error)");
 
   return (NULL);
 }
@@ -1434,7 +1614,7 @@
     if (vmap->encoding == encoding)
     {
       vmap->used ++;
-      DEBUG_printf(("    returning existing vmap=%p\n", vmap));
+      DEBUG_printf(("get_vbcs_charmap: Returning existing vmap=%p\n", vmap));
 
       return ((void *)vmap);
     }
@@ -1446,7 +1626,7 @@
 
   if ((fp = cupsFileOpen(filename, "r")) == NULL)
   {
-    DEBUG_printf(("    Unable to open file: %s\n", strerror(errno)));
+    DEBUG_printf(("get_vbcs_charmap: Returning NULL (%s)\n", strerror(errno)));
 
     return (NULL);
   }
@@ -1457,14 +1637,14 @@
 
   if ((mapcount = get_charmap_count(fp)) <= 0)
   {
-    DEBUG_puts("    Unable to get charmap count!");
+    DEBUG_puts("get_vbcs_charmap: Unable to get charmap count!");
 
     cupsFileClose(fp);
 
     return (NULL);
   }
 
-  DEBUG_printf(("    mapcount=%d\n", mapcount));
+  DEBUG_printf(("get_vbcs_charmap: mapcount=%d\n", mapcount));
 
  /*
   * Allocate memory for DBCS/VBCS charset map...
@@ -1472,7 +1652,7 @@
 
   if ((vmap = (_cups_vmap_t *)calloc(1, sizeof(_cups_vmap_t))) == NULL)
   {
-    DEBUG_puts("    Unable to allocate memory!");
+    DEBUG_puts("get_vbcs_charmap: Unable to allocate memory!");
 
     cupsFileClose(fp);
 
@@ -1516,23 +1696,21 @@
     * Save lead char of 2/3/4-byte legacy char...
     */
 
-    if (legchar > 0xff && legchar <= 0xffff)
-    {
-      leadchar                  = (cups_sbcs_t)(legchar >> 8);
-      vmap->lead2char[leadchar] = leadchar;
-    }
-
-    if (legchar > 0xffff && legchar <= 0xffffff)
-    {
-      leadchar                  = (cups_sbcs_t)(legchar >> 16);
-      vmap->lead3char[leadchar] = leadchar;
-    }
-
     if (legchar > 0xffffff)
     {
       leadchar                  = (cups_sbcs_t)(legchar >> 24);
       vmap->lead4char[leadchar] = leadchar;
     }
+    else if (legchar > 0xffff)
+    {
+      leadchar                  = (cups_sbcs_t)(legchar >> 16);
+      vmap->lead3char[leadchar] = leadchar;
+    }
+    else if (legchar > 0xff)
+    {
+      leadchar                  = (cups_sbcs_t)(legchar >> 8);
+      vmap->lead2char[leadchar] = leadchar;
+    }
 
    /*
     * Save Legacy to Unicode mapping...
@@ -1618,10 +1796,10 @@
   * Add it to the cache and return...
   */
 
-  vmap->next     = vmap_cache;
+  vmap->next = vmap_cache;
   vmap_cache = vmap;
 
-  DEBUG_printf(("    returning new vmap=%p\n", vmap));
+  DEBUG_printf(("get_vbcs_charmap: Returning new vmap=%p\n", vmap));
 
   return (vmap);
 
@@ -1635,7 +1813,7 @@
 
   cupsFileClose(fp);
 
-  DEBUG_puts("    Error, returning NULL!");
+  DEBUG_puts("get_vbcs_charmap: Returning NULL (Read/format error)");
 
   return (NULL);
 }
diff --git a/data/Makefile b/data/Makefile
index 810be4c..3722a17 100644
--- a/data/Makefile
+++ b/data/Makefile
@@ -93,6 +93,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:
+
+
+#
 # Clean all config and object files...
 #
 
diff --git a/doc/Makefile b/doc/Makefile
index 122d915..950f4bb 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -126,6 +126,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:
+
+
+#
 # Remove all generated files...
 #
 
diff --git a/doc/cups.css b/doc/cups.css
index faaef12..637f3d8 100644
--- a/doc/cups.css
+++ b/doc/cups.css
@@ -91,8 +91,7 @@
 }
 
 TD.sel, TD.unsel {
-  border-left: thin solid #aaaaaa;
-  font-size: 120%;
+  border-left: thin solid #cccccc;
   padding: 0px 5px;
   text-align: center;
   vertical-align: middle;
@@ -107,24 +106,9 @@
   background: url(images/unsel.gif);
 }
 
-TD.sel A, TD.sel A:hover {
-  color: white;
-  font-weight: normal;
-  text-decoration: none;
-}
-
-TD.unsel A, TD.unsel A:visited {
-  color: #333333;
-  font-weight: normal;
-}
-
-TD.unsel:hover {
-  background: url(images/unsel-hover.gif);
-  color: white;
-}
-
-TD.unsel A:link:hover, TD.unsel A:visited:hover, TD.unsel A:active {
-  color: white;
+TD.sel A, TD.sel A:hover, TD.unsel A:link:hover, TD.unsel A:visited:hover,
+TD.unsel A:active, TD.unsel A, TD.unsel A:visited {
+  color: #666666;
   font-weight: normal;
   text-decoration: none;
 }
@@ -280,7 +264,7 @@
 
 TABLE.inset {
   background: #f0f0f0;
-  border: inset 1px #eeeeee;
+  border: thin solid #e0e0e0;
   padding: 0;
   /* These are not implemented by all browsers, but that's OK */
   border-radius: 5px;
diff --git a/doc/index.html.in b/doc/index.html.in
index 401df41..c5aa362 100644
--- a/doc/index.html.in
+++ b/doc/index.html.in
@@ -10,9 +10,9 @@
 <TABLE CLASS="page" SUMMARY="{title}">
 <TR><TD CLASS="body">
 <TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
-<TR HEIGHT="32">
+<TR HEIGHT="36">
 <TD><A HREF="http://www.cups.org/" TARGET="_blank"><IMG
-SRC="/images/left.gif" WIDTH="64" HEIGHT="32" BORDER="0" ALT=""></A></TD>
+SRC="/images/left.gif" WIDTH="64" HEIGHT="36" BORDER="0" ALT=""></A></TD>
 <TD CLASS="sel"><A HREF="/">&nbsp;&nbsp;Home&nbsp;&nbsp;</A></TD>
 <TD CLASS="unsel"><A HREF="/admin">&nbsp;&nbsp;Administration&nbsp;&nbsp;</A></TD>
 <TD CLASS="unsel"><A HREF="/classes/">&nbsp;&nbsp;Classes&nbsp;&nbsp;</A></TD>
@@ -22,10 +22,9 @@
 <TD CLASS="unsel" WIDTH="100%"><FORM ACTION="/help/" METHOD="GET"><INPUT
 TYPE="SEARCH" NAME="QUERY" SIZE="20" PLACEHOLDER="Search Help"
 AUTOSAVE="org.cups.help" RESULTS="20"></FORM></TD>
-<TD><IMG SRC="/images/right.gif" WIDTH="16" HEIGHT="32" ALT=""></TD>
+<TD><IMG SRC="/images/right.gif" WIDTH="4" HEIGHT="36" ALT=""></TD>
 </TR>
 </TABLE>
-<IMG SRC="/images/shadow.png" WIDTH="100%" HEIGHT="4" ALT="">
 
 <H1>Common UNIX Printing System @CUPS_VERSION@@CUPS_REVISION@</H1>
 
diff --git a/driver/Makefile b/driver/Makefile
index f94ec6f..accaacc 100644
--- a/driver/Makefile
+++ b/driver/Makefile
@@ -49,18 +49,20 @@
 		$(LIB32OBJS) \
 		$(LIB64OBJS)
 
-TARGETS		= \
+LIBTARGETS =	\
 		$(LIBCUPSDRIVER) \
 		$(LIB32CUPSDRIVER) \
 		$(LIB64CUPSDRIVER) \
 		libcupsdriver.a \
-		commandtoescpx \
-		commandtopclx \
-		rastertoescpx \
-		rastertopclx \
 		testcmyk \
 		testdither \
 		testrgb
+TARGETS =	\
+		$(LIBTARGETS) \
+		commandtoescpx \
+		commandtopclx \
+		rastertoescpx \
+		rastertopclx
 
 
 #
@@ -71,6 +73,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:		$(LIBTARGETS)
+
+
+#
 # Clean everything...
 #
 
@@ -273,12 +282,13 @@
 
 testcmyk:		testcmyk.o libcupsdriver.a ../cups/libcups.a
 	echo Linking $@...
-	$(CC) $(LDFLAGS) -o $@ testcmyk.o libcupsdriver.a ../cups/libcups.a \
-		$(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
+	$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testcmyk.o libcupsdriver.a \
+		../cups/libcups.a $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
 	if test ! -d test; then \
 		mkdir test; \
 	fi
-	./testcmyk > test/testcmyk.log 2>&1 || echo "CMYK tests failed!"
+	echo Running CMYK API tests...
+	./testcmyk > test/testcmyk.log
 
 
 #
@@ -287,19 +297,20 @@
 
 testdither:		testdither.o libcupsdriver.a ../cups/libcups.a
 	echo Linking $@...
-	$(CC) $(LDFLAGS) -o $@ testdither.o libcupsdriver.a ../cups/libcups.a \
-		$(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
+	$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testdither.o libcupsdriver.a \
+		../cups/libcups.a $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
 	if test ! -d test; then \
 		mkdir test; \
 	fi
-	./testdither > test/0-255.pgm 2>test/0-255.log || echo "Dither 0-255 test failed!"
-	./testdither 0 127 255 > test/0-127-255.pgm 2>test/0-127-255.log || echo "Dither 0-127-255 test failed!"
-	./testdither 0 85 170 255 > test/0-85-170-255.pgm 2>test/0-85-170-255.log || echo "Dither 0-85-170-255 test failed!"
-	./testdither 0 63 127 170 198 227 255 > test/0-63-127-170-198-227-255.pgm 2>test/0-63-127-170-198-227-255.log || echo "Dither 0-63-127-170-198-227-255 test failed!"
-	./testdither 0 210 383 > test/0-210-383.pgm 2>test/0-210-383.log || echo "Dither 0-210-383 test failed!"
-	./testdither 0 82 255 > test/0-82-255.pgm 2>test/0-82-255.log || echo "Dither 0-82-255 test failed!"
-	./testdither 0 510 > test/0-510.pgm 2>test/0-510.log || echo "Dither 0-510 test failed!"
-	./testdither 0 1020 > test/0-1020.pgm 2>test/0-1020.log || echo "Dither 0-1020 test failed!"
+	echo Running dither API tests...
+	./testdither > test/0-255.pgm 2>test/0-255.log
+	./testdither 0 127 255 > test/0-127-255.pgm 2>test/0-127-255.log
+	./testdither 0 85 170 255 > test/0-85-170-255.pgm 2>test/0-85-170-255.log
+	./testdither 0 63 127 170 198 227 255 > test/0-63-127-170-198-227-255.pgm 2>test/0-63-127-170-198-227-255.log
+	./testdither 0 210 383 > test/0-210-383.pgm 2>test/0-210-383.log
+	./testdither 0 82 255 > test/0-82-255.pgm 2>test/0-82-255.log
+	./testdither 0 510 > test/0-510.pgm 2>test/0-510.log
+	./testdither 0 1020 > test/0-1020.pgm 2>test/0-1020.log
 
 
 #
@@ -308,11 +319,12 @@
 
 testrgb:		testrgb.o libcupsdriver.a ../cups/libcups.a
 	echo Linking $@...
-	$(CC) $(LDFLAGS) -o $@ testrgb.o libcupsdriver.a ../cups/libcups.a \
-		$(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
+	$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testrgb.o libcupsdriver.a \
+		../cups/libcups.a $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
 	if test ! -d test; then \
 		mkdir test; \
 	fi
+	echo Running RGB API tests...
 	./testrgb > test/testrgb.log 2>&1 || echo "RGB tests failed!"
 
 
diff --git a/filter/Makefile b/filter/Makefile
index 09df330..61d578c 100644
--- a/filter/Makefile
+++ b/filter/Makefile
@@ -18,16 +18,28 @@
 include ../Makedefs
 
 
-FILTERS	=	commandtops gziptoany hpgltops texttops pstops $(IMGFILTERS) \
-		$(PDFTOPS) rastertolabel rastertoepson rastertohp
-TARGETS	=	$(FILTERS) \
+FILTERS	=	\
+		commandtops \
+		gziptoany \
+		hpgltops \
+		texttops \
+		pstops \
+		$(IMGFILTERS) \
+		$(PDFTOPS) \
+		rastertolabel \
+		rastertoepson \
+		rastertohp
+LIBTARGETS =	\
 		$(LIBCUPSIMAGE) \
 		libcupsimage.a \
 		$(LIB32CUPSIMAGE) \
 		$(LIB64CUPSIMAGE) \
-		rasterbench \
-		testimage \
 		testraster
+TARGETS	=	\
+		$(LIBTARGETS) \
+		$(FILTERS) \
+		rasterbench \
+		testimage
 
 HPGLOBJS =	hpgl-attr.o hpgl-config.o hpgl-main.o hpgl-prolog.o \
 		hpgl-char.o hpgl-input.o hpgl-polygon.o hpgl-vector.o
@@ -53,6 +65,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:		$(LIBTARGETS)
+
+
+#
 # Clean all object files...
 #
 
@@ -408,8 +427,11 @@
 
 testraster:	testraster.o ../cups/libcups.a libcupsimage.a
 	echo Linking $@...
-	$(CC) $(LDFLAGS) -o $@ testraster.o libcupsimage.a ../cups/libcups.a \
-		$(IMGLIBS) $(DSOLIBS) $(COMMONLIBS) $(SSLLIBS) $(LIBGSSAPI)
+	$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testraster.o libcupsimage.a \
+		../cups/libcups.a $(IMGLIBS) $(DSOLIBS) $(COMMONLIBS) \
+		$(SSLLIBS) $(LIBGSSAPI)
+	echo Running raster API tests...
+	./testraster
 
 
 #
diff --git a/fonts/Makefile b/fonts/Makefile
index dedf74e..4aee789 100644
--- a/fonts/Makefile
+++ b/fonts/Makefile
@@ -31,6 +31,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:
+
+
+#
 # Clean all config and object files...
 #
 
diff --git a/locale/Makefile b/locale/Makefile
index 1eba2b2..a948cf9 100644
--- a/locale/Makefile
+++ b/locale/Makefile
@@ -28,6 +28,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:
+
+
+#
 # Clean all config and object files...
 #
 
diff --git a/man/Makefile b/man/Makefile
index 8588d34..ee93d94 100644
--- a/man/Makefile
+++ b/man/Makefile
@@ -76,6 +76,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:
+
+
+#
 # Clean all config and object files...
 #
 
diff --git a/man/filter.man b/man/filter.man
index 9131da0..17849f6 100644
--- a/man/filter.man
+++ b/man/filter.man
@@ -3,7 +3,7 @@
 .\"
 .\"   filter man page for the Common UNIX Printing System (CUPS).
 .\"
-.\"   Copyright 2007 by Apple Inc.
+.\"   Copyright 2007-2008 by Apple Inc.
 .\"   Copyright 1997-2007 by Easy Software Products.
 .\"
 .\"   These coded instructions, statements, and computer programs are the
@@ -12,7 +12,7 @@
 .\"   which should have been included with this file.  If this file is
 .\"   file is missing or damaged, see the license at "http://www.cups.org/".
 .\"
-.TH filter 7 "Common UNIX Printing System" "6 July 2007" "Apple Inc."
+.TH filter 7 "Common UNIX Printing System" "14 May 2008" "Apple Inc."
 .SH NAME
 filter \- cups file conversion filter interface
 .SH SYNOPSIS
@@ -102,6 +102,13 @@
 form sets the job-media-sheets-completed attribute to #-pages.
 
 .TP 5
+PPD: Keyword=Value ... KeywordN=Value
+.br
+Sets the named keywords in the printer's PPD file. This is typically
+used to update default option keywords such as DefaultPageSize and
+the various installable options in the PPD file.
+
+.TP 5
 STATE: printer-state-reason [printer-state-reason ...]
 .TP 5
 STATE: + printer-state-reason [printer-state-reason ...]
diff --git a/monitor/Makefile b/monitor/Makefile
index a1c75b6..8f3b583 100644
--- a/monitor/Makefile
+++ b/monitor/Makefile
@@ -30,6 +30,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:
+
+
+#
 # Clean all object files...
 #
 
diff --git a/notifier/Makefile b/notifier/Makefile
index 812fcbd..365a620 100644
--- a/notifier/Makefile
+++ b/notifier/Makefile
@@ -28,6 +28,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:
+
+
+#
 # Clean all object files...
 #
 
diff --git a/ppdc/Makefile b/ppdc/Makefile
index 24611c4..aed8208 100644
--- a/ppdc/Makefile
+++ b/ppdc/Makefile
@@ -56,13 +56,15 @@
 		ppdi.o \
 		ppdmerge.o \
 		ppdpo.o
-TARGETS	=	\
+LIBTARGETS =	\
 		$(LIBCUPSPPDC) \
 		$(LIB32CUPSPPDC) \
 		$(LIB64CUPSPPDC) \
 		libcupsppdc.a \
+		ppdc-static
+TARGETS	=	\
+		$(LIBTARGETS) \
 		drv \
-		ppdc-static \
 		ppdc \
 		ppdhtml \
 		ppdi \
@@ -78,6 +80,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:		$(LIBTARGETS)
+
+
+#
 # Clean everything...
 #
 
@@ -275,8 +284,8 @@
 
 ppdc-static:		ppdc.o libcupsppdc.a  ../cups/libcups.a foo.drv foo-fr.po
 	echo Linking $@...
-	$(CXX) $(LDFLAGS) -o ppdc-static ppdc.o libcupsppdc.a ../cups/libcups.a \
-		$(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
+	$(CXX) $(ARCHFLAGS) $(LDFLAGS) -o ppdc-static ppdc.o libcupsppdc.a \
+		../cups/libcups.a $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ)
 	echo Testing PPD compiler...
 	./ppdc-static -l en,fr -I ../data foo.drv
 	./ppdc-static -l en,fr -z -I ../data foo.drv
diff --git a/scheduler/Makefile b/scheduler/Makefile
index e359e05..256a93a 100644
--- a/scheduler/Makefile
+++ b/scheduler/Makefile
@@ -62,20 +62,24 @@
 		testspeed.o \
 		testsub.o \
 		util.o
+
+LIBTARGETS =	\
+		$(LIBCUPSMIME) \
+		$(LIB32CUPSMIME) \
+		$(LIB64CUPSMIME) \
+		libcupsmime.a \
+		testmime
+
 TARGETS	=	\
+		$(LIBTARGETS) \
 		cupsd \
 		cupsfilter \
 		cups-deviced \
 		cups-driverd \
 		cups-lpd \
 		cups-polld \
-		$(LIBCUPSMIME) \
-		$(LIB32CUPSMIME) \
-		$(LIB64CUPSMIME) \
-		libcupsmime.a \
 		testdirsvc \
 		testlpd \
-		testmime \
 		testspeed \
 		testsub
 
@@ -88,6 +92,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:		$(LIBTARGETS)
+
+
+#
 # Clean all object files...
 #
 
@@ -480,8 +491,10 @@
 
 testmime:	testmime.o libcupsmime.a ../cups/libcups.a
 	echo Linking $@...
-	$(CC) $(LDFLAGS) -o $@ testmime.o libcupsmime.a ../cups/libcups.a \
-		$(COMMONLIBS) $(LIBZ) $(SSLLIBS) $(LIBGSSAPI)
+	$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testmime.o libcupsmime.a \
+		../cups/libcups.a $(COMMONLIBS) $(LIBZ) $(SSLLIBS) $(LIBGSSAPI)
+	echo Running MIME tests...
+	./testmime
 
 
 #
diff --git a/scheduler/auth.c b/scheduler/auth.c
index 9516f28..8d551ab 100644
--- a/scheduler/auth.c
+++ b/scheduler/auth.c
@@ -1404,12 +1404,24 @@
   * Check group membership through MacOS X membership API...
   */
 
-  if (user && group)
+  if (group)
+  {
+    if (mbr_gid_to_uuid(group->gr_gid, groupuuid))
+      uuid_clear(groupuuid);
+  }
+  else if (groupname[0] == '#')
+  {
+    if (uuid_parse((char *)groupname + 1, groupuuid))
+      uuid_clear(groupuuid);
+  }
+  else
+    uuid_clear(groupuuid);
+
+  if (user && !uuid_is_null(groupuuid))
     if (!mbr_uid_to_uuid(user->pw_uid, useruuid))
-      if (!mbr_gid_to_uuid(group->gr_gid, groupuuid))
-	if (!mbr_check_membership(useruuid, groupuuid, &is_member))
-	  if (is_member)
-	    return (1);
+      if (!mbr_check_membership(useruuid, groupuuid, &is_member))
+	if (is_member)
+	  return (1);
 #endif /* HAVE_MBR_UID_TO_UUID */
 
  /*
diff --git a/scheduler/conf.h b/scheduler/conf.h
index 764cc62..30f87f6 100644
--- a/scheduler/conf.h
+++ b/scheduler/conf.h
@@ -21,7 +21,8 @@
 
 typedef enum
 {
-  CUPSD_LOG_ATTR = -3,			/* Used internally for attributes */
+  CUPSD_LOG_PPD = -4,			/* Used internally for PPD keywords */
+  CUPSD_LOG_ATTR,			/* Used internally for attributes */
   CUPSD_LOG_STATE,			/* Used internally for state-reasons */
   CUPSD_LOG_PAGE,			/* Used internally for page logging */
   CUPSD_LOG_NONE,
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
index f660dc2..23f55f5 100644
--- a/scheduler/ipp.c
+++ b/scheduler/ipp.c
@@ -2970,7 +2970,11 @@
 	 language = (char *)cupsArrayNext(languages))
     {
       if (iccfile)
-        attr = _ppdLocalizedAttr(ppd, "cupsICCProfile", name, language);
+      {
+        if ((attr = _ppdLocalizedAttr(ppd, "cupsICCProfile", name,
+	                              language)) == NULL)
+	  attr = _ppdLocalizedAttr(ppd, "APTiogaProfile", name, language);
+      }
       else
         attr = _ppdLocalizedAttr(ppd, "ColorModel", name, language);
 
@@ -3030,6 +3034,7 @@
   ppd_file_t		*ppd;		/* PPD file */
   ppd_attr_t		*attr,		/* cupsICCProfile attributes */
 			*profileid_attr;/* cupsProfileID attribute */
+  const char		*profile_key;	/* Profile keyword */
   ppd_option_t		*cm_option;	/* Color model option */
   ppd_choice_t		*cm_choice,	/* Color model choice */
 			*q1_choice,	/* ColorModel (or other) qualifier */
@@ -3074,9 +3079,15 @@
   * See if we have any profiles...
   */
 
-  for (num_profiles = 0, attr = ppdFindAttr(ppd, "cupsICCProfile", NULL);
-       attr;
-       attr = ppdFindNextAttr(ppd, "cupsICCProfile", NULL))
+  if ((attr = ppdFindAttr(ppd, "APTiogaProfile", NULL)) != NULL)
+    profile_key = "APTiogaProfile";
+  else
+  {
+    attr = ppdFindAttr(ppd, "cupsICCProfile", NULL);
+    profile_key = "cupsICCProfile";
+  }
+
+  for (num_profiles = 0; attr; attr = ppdFindNextAttr(ppd, profile_key, NULL))
     if (attr->spec[0] && attr->value && attr->value[0])
     {
       if (attr->value[0] != '/')
@@ -3091,6 +3102,7 @@
       num_profiles ++;
     }
 
+  
  /*
   * If we have profiles, add them...
   */
@@ -3138,9 +3150,9 @@
     languages              = _ppdGetLanguages(ppd);
 
     for (profile = profiles->profiles,
-             attr = ppdFindAttr(ppd, "cupsICCProfile", NULL);
+             attr = ppdFindAttr(ppd, profile_key, NULL);
 	 attr;
-	 attr = ppdFindNextAttr(ppd, "cupsICCProfile", NULL))
+	 attr = ppdFindNextAttr(ppd, profile_key, NULL))
       if (attr->spec[0] && attr->value && attr->value[0])
       {
        /*
@@ -3156,16 +3168,21 @@
         if (access(iccfile, 0))
 	  continue;
 
-        cupsArraySave(ppd->sorted_attrs);
+        if (profile_key[0] == 'c')
+	{
+	  cupsArraySave(ppd->sorted_attrs);
 
-	if ((profileid_attr = ppdFindAttr(ppd, "cupsProfileID",
-	                                  attr->spec)) != NULL &&
-            profileid_attr->value && isdigit(profileid_attr->value[0] & 255))
-          profile_id = (unsigned)strtoul(profileid_attr->value, NULL, 10);
+	  if ((profileid_attr = ppdFindAttr(ppd, "cupsProfileID",
+					    attr->spec)) != NULL &&
+	      profileid_attr->value && isdigit(profileid_attr->value[0] & 255))
+	    profile_id = (unsigned)strtoul(profileid_attr->value, NULL, 10);
+	  else
+	    profile_id = _ppdHashName(attr->spec);
+
+	  cupsArrayRestore(ppd->sorted_attrs);
+        }
 	else
-	  profile_id = _ppdHashName(attr->spec);
-
-	cupsArrayRestore(ppd->sorted_attrs);
+	  profile_id = atoi(attr->spec);
 
         apple_init_profile(ppd, languages, profile, profile_id, attr->spec,
 	                   attr->text[0] ? attr->text : attr->spec, iccfile);
@@ -4166,8 +4183,13 @@
 	*/
 
 #ifdef HAVE_MBR_UID_TO_UUID
-	if ((mbr_err = mbr_group_name_to_uuid((char *)p->users[i] + 1,
-	                                      grp_uuid)) != 0)
+        if (p->users[i][1] == '#')
+	{
+	  if (uuid_parse((char *)p->users[i] + 2, grp_uuid))
+	    uuid_clear(grp_uuid);
+	}
+	else if ((mbr_err = mbr_group_name_to_uuid((char *)p->users[i] + 1,
+	                                           grp_uuid)) != 0)
 	{
 	 /*
 	  * Invalid ACL entries are ignored for matching; just record a
@@ -4181,28 +4203,27 @@
 	                  "Access control entry \"%s\" not a valid group name; "
 			  "entry ignored", p->users[i]);
 	}
-	else
+
+	if ((mbr_err = mbr_check_membership(usr_uuid, grp_uuid,
+					    &is_member)) != 0)
 	{
-	  if ((mbr_err = mbr_check_membership(usr_uuid, grp_uuid,
-	                                      &is_member)) != 0)
-	  {
-	   /*
-	    * At this point, there should be no errors, but check anyways...
-	    */
-
-	    cupsdLogMessage(CUPSD_LOG_DEBUG,
-	                    "check_quotas: group \"%s\" membership check "
-			    "failed (err=%d)", p->users[i] + 1, mbr_err);
-            is_member = 0;
-	  }
-
-         /*
-	  * Stop if we found a match...
+	 /*
+	  * At this point, there should be no errors, but check anyways...
 	  */
 
-	  if (is_member)
-	    break;
+	  cupsdLogMessage(CUPSD_LOG_DEBUG,
+			  "check_quotas: group \"%s\" membership check "
+			  "failed (err=%d)", p->users[i] + 1, mbr_err);
+	  is_member = 0;
 	}
+
+       /*
+	* Stop if we found a match...
+	*/
+
+	if (is_member)
+	  break;
+
 #else
         if (cupsdCheckGroup(username, pw, p->users[i] + 1))
 	  break;
@@ -4211,8 +4232,13 @@
 #ifdef HAVE_MBR_UID_TO_UUID
       else
       {
-        if ((mbr_err = mbr_user_name_to_uuid((char *)p->users[i],
-					     usr2_uuid)) != 0)
+        if (p->users[i][0] == '#')
+	{
+	  if (uuid_parse((char *)p->users[i] + 1, usr2_uuid))
+	    uuid_clear(usr2_uuid);
+        }
+        else if ((mbr_err = mbr_user_name_to_uuid((char *)p->users[i],
+					          usr2_uuid)) != 0)
     	{
 	 /*
 	  * Invalid ACL entries are ignored for matching; just record a
@@ -4226,20 +4252,18 @@
 	                  "Access control entry \"%s\" not a valid user name; "
 			  "entry ignored", p->users[i]);
 	}
-	else
-	{
-	  if ((mbr_err = mbr_check_membership(usr_uuid, usr2_uuid,
-	                                      &is_member)) != 0)
-          {
-	    cupsdLogMessage(CUPSD_LOG_DEBUG,
-			    "check_quotas: User \"%s\" identity check failed "
-			    "(err=%d)", p->users[i], mbr_err);
-	    is_member = 0;
-	  }
 
-	  if (is_member)
-	    break;
+	if ((mbr_err = mbr_check_membership(usr_uuid, usr2_uuid,
+					    &is_member)) != 0)
+	{
+	  cupsdLogMessage(CUPSD_LOG_DEBUG,
+			  "check_quotas: User \"%s\" identity check failed "
+			  "(err=%d)", p->users[i], mbr_err);
+	  is_member = 0;
 	}
+
+	if (is_member)
+	  break;
       }
 #else
       else if (!strcasecmp(username, p->users[i]))
diff --git a/scheduler/job.c b/scheduler/job.c
index 0e4e94a..5795a88 100644
--- a/scheduler/job.c
+++ b/scheduler/job.c
@@ -3779,6 +3779,23 @@
 
       cupsFreeOptions(num_attrs, attrs);
     }
+    else if (loglevel == CUPSD_LOG_PPD)
+    {
+     /*
+      * Set attribute(s)...
+      */
+
+      int		num_keywords;	/* Number of keywords */
+      cups_option_t	*keywords;	/* Keywords */
+
+
+      num_keywords = cupsParseOptions(message, 0, &keywords);
+
+      if (cupsdUpdatePrinterPPD(job->printer, num_keywords, keywords))
+        cupsdSetPrinterAttrs(job->printer);
+
+      cupsFreeOptions(num_keywords, keywords);
+    }
 #ifdef __APPLE__
     else if (!strncmp(message, "recoverable:", 12))
     {
diff --git a/scheduler/printers.c b/scheduler/printers.c
index 8cd2e6e..640f02a 100644
--- a/scheduler/printers.c
+++ b/scheduler/printers.c
@@ -2857,6 +2857,118 @@
 
 
 /*
+ * 'cupsdUpdatePrinterPPD()' - Update keywords in a printer's PPD file.
+ */
+
+int					/* O - 1 if successful, 0 otherwise */
+cupsdUpdatePrinterPPD(
+    cupsd_printer_t *p,			/* I - Printer */
+    int             num_keywords,	/* I - Number of keywords */
+    cups_option_t   *keywords)		/* I - Keywords */
+{
+  int		i;			/* Looping var */
+  cups_file_t	*src,			/* Original file */
+		*dst;			/* New file */
+  char		srcfile[1024],		/* Original filename */
+		dstfile[1024],		/* New filename */
+		line[1024],		/* Line from file */
+		keystring[41];		/* Keyword from line */
+  cups_option_t	*keyword;		/* Current keyword */
+
+
+  cupsdLogMessage(CUPSD_LOG_INFO, "Updating keywords in PPD file for %s...",
+                  p->name);
+
+ /*
+  * Get the old and new PPD filenames...
+  */
+
+  snprintf(srcfile, sizeof(srcfile), "%s/ppd/%s.ppd.O", ServerRoot, p->name);
+  snprintf(dstfile, sizeof(srcfile), "%s/ppd/%s.ppd", ServerRoot, p->name);
+
+ /*
+  * Rename the old file and open the old and new...
+  */
+
+  if (rename(dstfile, srcfile))
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to backup PPD file for %s: %s",
+                    p->name, strerror(errno));
+    return (0);
+  }
+
+  if ((src = cupsFileOpen(srcfile, "r")) == NULL)
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open PPD file \"%s\": %s",
+                    srcfile, strerror(errno));
+    rename(srcfile, dstfile);
+    return (0);
+  }
+
+  if ((dst = cupsFileOpen(dstfile, "w")) == NULL)
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create PPD file \"%s\": %s",
+                    dstfile, strerror(errno));
+    cupsFileClose(src);
+    rename(srcfile, dstfile);
+    return (0);
+  }
+
+ /*
+  * Copy the first line and then write out all of the keywords...
+  */
+
+  if (!cupsFileGets(src, line, sizeof(line)))
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to read PPD file \"%s\": %s",
+                    srcfile, strerror(errno));
+    cupsFileClose(src);
+    cupsFileClose(dst);
+    rename(srcfile, dstfile);
+    return (0);
+  }
+
+  cupsFilePrintf(dst, "%s\n", line);
+
+  for (i = num_keywords, keyword = keywords; i > 0; i --, keyword ++)
+  {
+    cupsdLogMessage(CUPSD_LOG_DEBUG, "*%s: %s", keyword->name, keyword->value);
+    cupsFilePrintf(dst, "*%s: %s\n", keyword->name, keyword->value);
+  }
+
+ /*
+  * Then copy the rest of the PPD file, dropping any keywords we changed.
+  */
+
+  while (cupsFileGets(src, line, sizeof(line)))
+  {
+   /*
+    * Skip keywords we've already set...
+    */
+
+    if (sscanf(line, "*%40[^:]:", keystring) == 1 &&
+        cupsGetOption(keystring, num_keywords, keywords))
+      continue;
+
+   /*
+    * Otherwise write the line...
+    */
+
+    cupsFilePrintf(dst, "%s\n", line);
+  }
+
+ /*
+  * Close files and return...
+  */
+
+  cupsFileClose(src);
+  cupsFileClose(dst);
+
+  return (1);
+}
+
+
+/*
  * 'cupsdUpdatePrinters()' - Update printers after a partial reload.
  */
 
diff --git a/scheduler/printers.h b/scheduler/printers.h
index d28789b..b14b1b1 100644
--- a/scheduler/printers.h
+++ b/scheduler/printers.h
@@ -162,6 +162,9 @@
 			                     int update);
 #define			cupsdStartPrinter(p,u) cupsdSetPrinterState((p), IPP_PRINTER_IDLE, (u))
 extern void		cupsdStopPrinter(cupsd_printer_t *p, int update);
+extern int		cupsdUpdatePrinterPPD(cupsd_printer_t *p,
+			                      int num_keywords,
+					      cups_option_t *keywords);
 extern void		cupsdUpdatePrinters(void);
 extern cupsd_quota_t	*cupsdUpdateQuota(cupsd_printer_t *p,
 			                  const char *username, int pages,
diff --git a/scheduler/statbuf.c b/scheduler/statbuf.c
index 699a5c8..a650f86 100644
--- a/scheduler/statbuf.c
+++ b/scheduler/statbuf.c
@@ -266,6 +266,11 @@
     *loglevel = CUPSD_LOG_ATTR;
     message   = sb->buffer + 5;
   }
+  else if (!strncmp(sb->buffer, "PPD:", 4))
+  {
+    *loglevel = CUPSD_LOG_PPD;
+    message   = sb->buffer + 4;
+  }
   else
   {
     *loglevel = CUPSD_LOG_DEBUG;
diff --git a/scripting/php/Makefile b/scripting/php/Makefile
index b213580..36b5766 100644
--- a/scripting/php/Makefile
+++ b/scripting/php/Makefile
@@ -46,6 +46,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:
+
+
+#
 # Remove object and target files...
 #
 
diff --git a/standards/Makefile b/standards/Makefile
index 74d8785..23b498f 100644
--- a/standards/Makefile
+++ b/standards/Makefile
@@ -69,6 +69,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:
+
+
+#
 # Clean all config and object files...
 #
 
@@ -131,7 +138,7 @@
 #
 
 rfctohtml:	rfctohtml.o ../cups/libcups.a
-	$(CC) $(LDFLAGS) -o $@ rfctohtml.o ../cups/libcups.a \
+	$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ rfctohtml.o ../cups/libcups.a \
 		$(SSLLIBS) $(COMMONLIBS) $(LIBZ)
 
 
diff --git a/systemv/Makefile b/systemv/Makefile
index ee9290b..4c5775e 100644
--- a/systemv/Makefile
+++ b/systemv/Makefile
@@ -30,6 +30,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:
+
+
+#
 # Clean all object files...
 #
 
diff --git a/templates/Makefile b/templates/Makefile
index ea2c108..3bd01c8 100644
--- a/templates/Makefile
+++ b/templates/Makefile
@@ -97,6 +97,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:
+
+
+#
 # Clean all config and object files...
 #
 
diff --git a/templates/header.tmpl.in b/templates/header.tmpl.in
index ea1c47f..5b87d36 100644
--- a/templates/header.tmpl.in
+++ b/templates/header.tmpl.in
@@ -11,9 +11,9 @@
 <TABLE CLASS="page" SUMMARY="{title}">
 <TR><TD CLASS="body">
 <TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
-<TR HEIGHT="32">
+<TR HEIGHT="36">
 <TD><A HREF="http://www.cups.org/" TARGET="_blank"><IMG
-SRC="/images/left.gif" WIDTH="64" HEIGHT="32" BORDER="0" ALT=""></A></TD>
+SRC="/images/left.gif" WIDTH="64" HEIGHT="36" BORDER="0" ALT=""></A></TD>
 <TD CLASS="unsel"><A HREF="/">&nbsp;&nbsp;Home&nbsp;&nbsp;</A></TD>
 <TD CLASS="{SECTION=admin?:un}sel"><A HREF="/admin">&nbsp;&nbsp;Administration&nbsp;&nbsp;</A></TD>
 <TD CLASS="{SECTION=classes?:un}sel"><A HREF="/classes/">&nbsp;&nbsp;Classes&nbsp;&nbsp;</A></TD>
@@ -23,9 +23,8 @@
 <TD CLASS="unsel" WIDTH="100%"><FORM ACTION="/help/" METHOD="GET"><INPUT
 TYPE="SEARCH" NAME="QUERY" SIZE="20" PLACEHOLDER="Search Help"
 VALUE="{SECTION=help?{?QUERY}:}" AUTOSAVE="org.cups.help" RESULTS="20"></FORM></TD>
-<TD><IMG SRC="/images/right.gif" WIDTH="16" HEIGHT="32" ALT=""></TD>
+<TD><IMG SRC="/images/right.gif" WIDTH="4" HEIGHT="36" ALT=""></TD>
 </TR>
 </TABLE>
-<IMG SRC="/images/shadow.png" WIDTH="100%" HEIGHT="4" ALT="">
 
 <H1>{title}</H1>
diff --git a/test/Makefile b/test/Makefile
index 49fabb3..99f8fa9 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -24,6 +24,13 @@
 
 
 #
+# Make library targets...
+#
+
+libs:
+
+
+#
 # Clean all object files...
 #