summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2008-04-09 22:42:49 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2008-04-09 22:42:49 +0000
commit839a51c83c61febe8d4c9ba56f6a05fce3d03710 (patch)
treef4a78140580870e06a5d95257d979990e12155ab
parent50fe720154d2af59cdeeaecf05cc868530e16248 (diff)
Merge changes from CUPS 1.4svn-r7394.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@702 a1ca3aef-8c08-0410-bb20-df032aa958be
-rw-r--r--CHANGES-1.3.txt26
-rw-r--r--CHANGES.txt12
-rw-r--r--INSTALL.txt4
-rw-r--r--Makedefs.in2
-rw-r--r--backend/Makefile2
-rw-r--r--backend/usb-unix.c5
-rw-r--r--cgi-bin/Makefile1
-rw-r--r--cgi-bin/admin.c26
-rw-r--r--cgi-bin/search.c4
-rw-r--r--conf/cupsd.conf.in39
-rw-r--r--config-scripts/cups-common.m411
-rw-r--r--config-scripts/cups-compiler.m416
-rw-r--r--config-scripts/cups-pap.m410
-rw-r--r--cups/Makefile1
-rw-r--r--cups/adminutil.c3
-rw-r--r--cups/http-private.h6
-rw-r--r--cups/http-support.c17
-rw-r--r--cups/http.c20
-rw-r--r--cups/libcups.exp1
-rw-r--r--cups/ppd.c2
-rw-r--r--doc/help/spec-ppd.html10
-rw-r--r--driver/Makefile1
-rw-r--r--driver/pcl-common.h2
-rw-r--r--driver/rastertoescpx.c86
-rw-r--r--driver/rastertopclx.c85
-rw-r--r--filter/Makefile1
-rw-r--r--filter/image-gif.c3
-rw-r--r--filter/image-png.c46
-rw-r--r--filter/pdftops.c35
-rw-r--r--filter/rastertoepson.c130
-rw-r--r--filter/rastertohp.c120
-rw-r--r--filter/rastertolabel.c85
-rwxr-xr-xinstall-sh18
-rw-r--r--man/ppdpo.man20
-rw-r--r--ppdc/Makefile1
-rw-r--r--ppdc/ppdc-catalog.cxx775
-rw-r--r--ppdc/ppdmerge.cxx2
-rw-r--r--scheduler/Makefile1
-rw-r--r--scheduler/client.c4
-rw-r--r--scheduler/cups-driverd.c14
-rw-r--r--scheduler/ipp.c10
-rw-r--r--scheduler/log.c19
-rw-r--r--scripting/php/Makefile2
-rw-r--r--test/4.3-job-ops.test50
-rw-r--r--test/5.5-lp.sh30
-rw-r--r--test/5.6-lpr.sh30
-rw-r--r--test/5.7-lprm.sh4
-rw-r--r--test/5.8-cancel.sh4
-rwxr-xr-xtest/run-stp-tests.sh215
-rw-r--r--test/str-header.html16
-rwxr-xr-xtest/waitjobs.sh37
-rwxr-xr-xtools/testosx2
52 files changed, 1520 insertions, 546 deletions
diff --git a/CHANGES-1.3.txt b/CHANGES-1.3.txt
index 0da640d7b..e2b84293e 100644
--- a/CHANGES-1.3.txt
+++ b/CHANGES-1.3.txt
@@ -1,8 +1,34 @@
CHANGES-1.3.txt
---------------
+CHANGES IN CUPS V1.3.8
+
+ - Documentation updates (STR #2785)
+ - The scheduler did not reject requests with an empty
+ Content-Length field (STR #2787)
+ - The web interface allowed the creation and cancellation
+ of RSS subscriptions without a username (STR #2774)
+ - The PNG image loading code would crash with large images
+ (STR #2790)
+ - The scheduler did not log the current date and time and
+ did not escape special characters in request URIs when
+ logging bad requests to the access_log file (STR #2788)
+
+
CHANGES IN CUPS V1.3.7
+ - CVE-2008-0047: cgiCompileSearch buffer overflow (STR #2729)
+ - CVE-2008-1373: CUPS GIF image filter overflow (STR #2765)
+ - Updated the "make check" tests to do a more thorough
+ automated test.
+ - cups-driverd complained about missing directories (STR
+ #2777)
+ - cupsaddsmb would leave the Samba username and password on
+ disk if no Windows drivers were installed (STR #2779)
+ - The Linux USB backend used 100% CPU when a printer was
+ disconnected (STR #2769)
+ - The sample raster drivers did not properly handle SIGTERM
+ (STR #2770)
- The scheduler sent notify_post() messages too often on
Mac OS X.
- Kerberos access to the web interface did not work
diff --git a/CHANGES.txt b/CHANGES.txt
index 5d4c25186..7c0a2f2b2 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,8 +1,18 @@
-CHANGES.txt - 2008-03-21
+CHANGES.txt - 2008-04-08
------------------------
CHANGES IN CUPS V1.4b1
+ - Added --enable-pap configure option.
+ - The default cupsd.conf file now includes an "authenticated"
+ policy which requires authentication for remote print jobs.
+ - Added support for Czech and Hungarian in PPD files
+ (STR #2735, STR #2736)
+ - The PPD compiler tools now support Mac OS X .strings files
+ for localization (STR #2737)
+ - ppdOpen*() now default the colorspace member to PPD_CS_N
+ when no DefaultColorSpace attribute is present in the PPD
+ file.
- The build system has been updated to support separate
installation of data, program, header, and library files.
- All support libraries are now built as shared libraries
diff --git a/INSTALL.txt b/INSTALL.txt
index 6ca73c64f..ba785ed4d 100644
--- a/INSTALL.txt
+++ b/INSTALL.txt
@@ -1,4 +1,4 @@
-INSTALL - CUPS v1.4svn - 2008-01-22
+INSTALL - CUPS v1.4svn - 2008-04-08
-----------------------------------
This file describes how to compile and install CUPS from source
@@ -33,7 +33,7 @@ BEFORE YOU BEGIN
many of the features provided by CUPS.
Kerberos support requires MIT Kerberos 1.6.3 or later or
- or Heimdal Kerberos, along with the corresponding GSSAPI
+ Heimdal Kerberos, along with the corresponding GSSAPI
pieces.
Also, please note that CUPS no longer includes the
diff --git a/Makedefs.in b/Makedefs.in
index cb771a0fa..d4a8929d6 100644
--- a/Makedefs.in
+++ b/Makedefs.in
@@ -35,7 +35,7 @@ RM = @RM@ -f
RMDIR = @RMDIR@
SED = @SED@
SHELL = /bin/sh
-STRIP = @STRIP@
+
#
# Installation programs...
diff --git a/backend/Makefile b/backend/Makefile
index ff3cdcf3a..c898b3db0 100644
--- a/backend/Makefile
+++ b/backend/Makefile
@@ -70,7 +70,7 @@ install-data:
install-exec:
$(INSTALL_DIR) -m 755 $(SERVERBIN)/backend
for file in $(RBACKENDS); do \
- $(LIBTOOL) $(INSTALL) -m 700 $$file $(SERVERBIN)/backend; \
+ $(LIBTOOL) $(INSTALL_BIN) -m 700 $$file $(SERVERBIN)/backend; \
done
for file in $(UBACKENDS); do \
$(INSTALL_BIN) $$file $(SERVERBIN)/backend; \
diff --git a/backend/usb-unix.c b/backend/usb-unix.c
index 64215815e..f18061065 100644
--- a/backend/usb-unix.c
+++ b/backend/usb-unix.c
@@ -415,11 +415,10 @@ open_device(const char *uri, /* I - Device URI */
*/
if (busy)
- {
_cupsLangPuts(stderr,
_("INFO: Printer busy; will retry in 5 seconds...\n"));
- sleep(5);
- }
+
+ sleep(5);
}
}
#elif defined(__sun) && defined(ECPPIOC_GETDEVID)
diff --git a/cgi-bin/Makefile b/cgi-bin/Makefile
index 4122d37ee..9a49370f6 100644
--- a/cgi-bin/Makefile
+++ b/cgi-bin/Makefile
@@ -139,7 +139,6 @@ install-libs: $(INSTALLSTATIC) $(INSTALL32) $(INSTALL64)
$(LN) $(LIBCUPSCGI) $(LIBDIR)/`basename $(LIBCUPSCGI) .1`; \
fi
if test $(LIBCUPSCGI) = "libcupscgi.1.dylib"; then \
- $(STRIP) -x $(LIBDIR)/$(LIBCUPSCGI); \
$(RM) $(LIBDIR)/libcupscgi.dylib; \
$(LN) $(LIBCUPSCGI) $(LIBDIR)/libcupscgi.dylib; \
fi
diff --git a/cgi-bin/admin.c b/cgi-bin/admin.c
index 6fa500d71..b54d27fdc 100644
--- a/cgi-bin/admin.c
+++ b/cgi-bin/admin.c
@@ -309,6 +309,16 @@ do_add_rss_subscription(http_t *http) /* I - HTTP connection */
}
/*
+ * Make sure we have a username...
+ */
+
+ if ((user = getenv("REMOTE_USER")) == NULL)
+ {
+ puts("Status: 401\n");
+ exit(0);
+ }
+
+ /*
* Validate the subscription name...
*/
@@ -352,9 +362,6 @@ do_add_rss_subscription(http_t *http) /* I - HTTP connection */
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, printer_uri);
- if ((user = getenv("REMOTE_USER")) == NULL)
- user = "guest";
-
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
NULL, user);
@@ -1306,6 +1313,16 @@ do_cancel_subscription(http_t *http)/* I - HTTP connection */
}
/*
+ * Require a username...
+ */
+
+ if ((user = getenv("REMOTE_USER")) == NULL)
+ {
+ puts("Status: 401\n");
+ exit(0);
+ }
+
+ /*
* Cancel the subscription...
*/
@@ -1316,9 +1333,6 @@ do_cancel_subscription(http_t *http)/* I - HTTP connection */
ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
"notify-subscription-id", id);
- if ((user = getenv("REMOTE_USER")) == NULL)
- user = "guest";
-
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
NULL, user);
diff --git a/cgi-bin/search.c b/cgi-bin/search.c
index 4ec4de397..4dc725859 100644
--- a/cgi-bin/search.c
+++ b/cgi-bin/search.c
@@ -167,7 +167,9 @@ cgiCompileSearch(const char *query) /* I - Query string */
* string + RE overhead...
*/
- wlen = (sptr - s) + 4 * wlen + 2 * strlen(prefix) + 4;
+ wlen = (sptr - s) + 2 * 4 * wlen + 2 * strlen(prefix) + 11;
+ if (lword)
+ wlen += strlen(lword);
if (wlen > slen)
{
diff --git a/conf/cupsd.conf.in b/conf/cupsd.conf.in
index 787c3a07a..40917e9b3 100644
--- a/conf/cupsd.conf.in
+++ b/conf/cupsd.conf.in
@@ -77,6 +77,45 @@ DefaultAuthType Basic
</Limit>
</Policy>
+# Set the authenticated printer/job policies...
+<Policy authenticated>
+ # Job-related operations must be done by the owner or an administrator...
+ <Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs Set-Job-Attributes Create-Job-Subscription Renew-Subscription Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job Suspend-Current-Job Resume-Job CUPS-Move-Job>
+ Require user @OWNER @SYSTEM
+ Order deny,allow
+ AuthType Default
+ Satisfy any
+ </Limit>
+
+ # All administration operations require an administrator to authenticate...
+ <Limit CUPS-Add-Modify-Printer CUPS-Delete-Printer CUPS-Add-Modify-Class CUPS-Delete-Class CUPS-Set-Default>
+ AuthType Default
+ Require user @SYSTEM
+ Order deny,allow
+ </Limit>
+
+ # All printer operations require a printer operator to authenticate...
+ <Limit Pause-Printer Resume-Printer Enable-Printer Disable-Printer Pause-Printer-After-Current-Job Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer Activate-Printer Restart-Printer Shutdown-Printer Startup-Printer Promote-Job Schedule-Job-After CUPS-Accept-Jobs CUPS-Reject-Jobs>
+ AuthType Default
+ Require user @CUPS_DEFAULT_PRINTADMIN_AUTH@
+ Order deny,allow
+ </Limit>
+
+ # Only the owner or an administrator can cancel or authenticate a job...
+ <Limit Cancel-Job CUPS-Authenticate-Job>
+ Require user @OWNER @CUPS_DEFAULT_PRINTADMIN_AUTH@
+ Order deny,allow
+ AuthType Default
+ Satisfy any
+ </Limit>
+
+ <Limit All>
+ Order deny,allow
+ AuthType Default
+ Satisfy any
+ </Limit>
+</Policy>
+
#
# End of "$Id: cupsd.conf.in 6720 2007-07-25 00:40:03Z mike $".
#
diff --git a/config-scripts/cups-common.m4 b/config-scripts/cups-common.m4
index 7236aebc0..c643663b0 100644
--- a/config-scripts/cups-common.m4
+++ b/config-scripts/cups-common.m4
@@ -42,11 +42,6 @@ AC_PROG_AWK
AC_PROG_CC
AC_PROG_CPP
AC_PROG_CXX
-AC_PROG_INSTALL
-if test "$INSTALL" = "$ac_install_sh"; then
- # Use full path to install-sh script...
- INSTALL="`pwd`/install-sh -c"
-fi
AC_PROG_RANLIB
AC_PATH_PROG(AR,ar)
AC_PATH_PROG(HTMLDOC,htmldoc)
@@ -56,7 +51,11 @@ AC_PATH_PROG(MV,mv)
AC_PATH_PROG(RM,rm)
AC_PATH_PROG(RMDIR,rmdir)
AC_PATH_PROG(SED,sed)
-AC_PATH_PROG(STRIP,strip)
+
+AC_MSG_CHECKING(for install-sh script)
+INSTALL="`pwd`/install-sh -c"
+AC_SUBST(INSTALL)
+AC_MSG_RESULT(using $INSTALL)
if test "x$AR" = x; then
AC_MSG_ERROR([Unable to find required library archive command.])
diff --git a/config-scripts/cups-compiler.m4 b/config-scripts/cups-compiler.m4
index 07faa0c4b..1fb08a520 100644
--- a/config-scripts/cups-compiler.m4
+++ b/config-scripts/cups-compiler.m4
@@ -21,12 +21,14 @@ AC_SUBST(INSTALL_STRIP)
AC_SUBST(OPTIM)
AC_ARG_WITH(optim, [ --with-optim="flags" set optimization flags ])
-AC_ARG_ENABLE(debug, [ --enable-debug turn on debugging, default=no],
- [if test x$enable_debug = xyes; then
- OPTIM="-g"
- else
- INSTALL_STRIP="-s"
- fi])
+AC_ARG_ENABLE(debug, [ --enable-debug turn on debugging, default=no])
+
+dnl For debugging, keep symbols, otherwise strip them...
+if test x$enable_debug = xyes; then
+ OPTIM="-g"
+else
+ INSTALL_STRIP="-s"
+fi
dnl Setup general architecture flags...
AC_ARG_WITH(archflags, [ --with-archflags="flags"
@@ -48,7 +50,7 @@ if test -z "$with_ldarchflags"; then
LDARCHFLAGS="$ARCHFLAGS"
fi
else
- LDARCHFLAGS="$with_archflags"
+ LDARCHFLAGS="$with_ldarchflags"
fi
AC_SUBST(ARCHFLAGS)
diff --git a/config-scripts/cups-pap.m4 b/config-scripts/cups-pap.m4
index b1fe05bc6..ec52d3c5f 100644
--- a/config-scripts/cups-pap.m4
+++ b/config-scripts/cups-pap.m4
@@ -3,7 +3,7 @@ dnl "$Id: cups-pam.m4 5466 2006-04-26 19:52:27Z mike $"
dnl
dnl PAP (AppleTalk) stuff for the Common UNIX Printing System (CUPS).
dnl
-dnl Copyright 2007 by Apple Inc.
+dnl Copyright 2007-2008 by Apple Inc.
dnl Copyright 2006 by Easy Software Products, all rights reserved.
dnl
dnl These coded instructions, statements, and computer programs are the
@@ -15,14 +15,16 @@ dnl
# Currently the PAP backend is only supported on MacOS X with the AppleTalk
# SDK installed...
+AC_ARG_ENABLE(pap, [ --enable-pap build with AppleTalk support, default=auto])
+
PAP=""
-if test $uname = Darwin; then
+AC_SUBST(PAP)
+
+if test x$enable_pap != xno -a $uname = Darwin; then
PAP="pap"
AC_CHECK_HEADER(AppleTalk/at_proto.h)
fi
-AC_SUBST(PAP)
-
dnl
dnl End of "$Id: cups-pam.m4 5466 2006-04-26 19:52:27Z mike $".
dnl
diff --git a/cups/Makefile b/cups/Makefile
index 2c8bdbdb9..5e66a122b 100644
--- a/cups/Makefile
+++ b/cups/Makefile
@@ -201,7 +201,6 @@ install-libs: $(INSTALLSTATIC) $(INSTALL32) $(INSTALL64)
$(LN) $(LIBCUPS) $(LIBDIR)/`basename $(LIBCUPS) .2`; \
fi
if test $(LIBCUPS) = "libcups.2.dylib"; then \
- $(STRIP) -x $(LIBDIR)/$(LIBCUPS); \
$(RM) $(LIBDIR)/libcups.dylib; \
$(LN) $(LIBCUPS) $(LIBDIR)/libcups.dylib; \
fi
diff --git a/cups/adminutil.c b/cups/adminutil.c
index c75b0d904..70fdce425 100644
--- a/cups/adminutil.c
+++ b/cups/adminutil.c
@@ -808,6 +808,9 @@ cupsAdminExportSamba(
if (have_drivers == 0)
{
_cupsSetError(IPP_NOT_FOUND, message);
+
+ unlink(authfile);
+
return (0);
}
diff --git a/cups/http-private.h b/cups/http-private.h
index 78348a4dd..ba416f666 100644
--- a/cups/http-private.h
+++ b/cups/http-private.h
@@ -257,6 +257,12 @@ extern void _cups_freeifaddrs(struct ifaddrs *addrs);
# endif /* HAVE_GETIFADDRS */
# endif /* !WIN32 */
+/*
+ * Common URI encoding function...
+ */
+
+extern char *_httpEncodeURI(char *dst, const char *src, size_t dstsize);
+
#endif /* !_CUPS_HTTP_PRIVATE_H_ */
/*
diff --git a/cups/http-support.c b/cups/http-support.c
index be6cfbe84..a8d58b0be 100644
--- a/cups/http-support.c
+++ b/cups/http-support.c
@@ -36,6 +36,7 @@
* httpStatus() - Return a short string describing a HTTP status code.
* _cups_hstrerror() - hstrerror() emulation function for Solaris and
* others...
+ * _httpEncodeURI() - Percent-encode a HTTP request URI.
* http_copy_decode() - Copy and decode a URI.
* http_copy_encode() - Copy and encode a URI.
*/
@@ -1204,6 +1205,20 @@ _cups_hstrerror(int error) /* I - Error number */
/*
+ * '_httpEncodeURI()' - Percent-encode a HTTP request URI.
+ */
+
+char * /* O - Encoded URI */
+_httpEncodeURI(char *dst, /* I - Destination buffer */
+ const char *src, /* I - Source URI */
+ size_t dstsize) /* I - Size of destination buffer */
+{
+ http_copy_encode(dst, src, dst + dstsize - 1, NULL, NULL, 1);
+ return (dst);
+}
+
+
+/*
* 'http_copy_decode()' - Copy and decode a URI.
*/
@@ -1311,6 +1326,8 @@ http_copy_encode(char *dst, /* O - Destination buffer */
*dst++ = *src++;
}
+ *dst = '\0';
+
if (*src)
return (NULL);
else
diff --git a/cups/http.c b/cups/http.c
index 2faa1262e..e48c174c6 100644
--- a/cups/http.c
+++ b/cups/http.c
@@ -2527,8 +2527,7 @@ http_send(http_t *http, /* I - Connection to server */
const char *uri) /* I - URI */
{
int i; /* Looping var */
- char *ptr, /* Pointer in buffer */
- buf[1024]; /* Encoded URI buffer */
+ char buf[1024]; /* Encoded URI buffer */
static const char * const codes[] =
{ /* Request code strings */
NULL,
@@ -2545,8 +2544,6 @@ http_send(http_t *http, /* I - Connection to server */
"TRACE",
"CLOSE"
};
- static const char hex[] = "0123456789ABCDEF";
- /* Hex digits */
DEBUG_printf(("http_send(http=%p, request=HTTP_%s, uri=\"%s\")\n",
@@ -2566,20 +2563,7 @@ http_send(http_t *http, /* I - Connection to server */
* Encode the URI as needed...
*/
- for (ptr = buf; *uri != '\0' && ptr < (buf + sizeof(buf) - 1); uri ++)
- if (*uri <= ' ' || *uri >= 127)
- {
- if (ptr < (buf + sizeof(buf) - 1))
- *ptr ++ = '%';
- if (ptr < (buf + sizeof(buf) - 1))
- *ptr ++ = hex[(*uri >> 4) & 15];
- if (ptr < (buf + sizeof(buf) - 1))
- *ptr ++ = hex[*uri & 15];
- }
- else
- *ptr ++ = *uri;
-
- *ptr = '\0';
+ _httpEncodeURI(buf, uri, sizeof(buf));
/*
* See if we had an error the last time around; if so, reconnect...
diff --git a/cups/libcups.exp b/cups/libcups.exp
index 35f309431..8271f59ac 100644
--- a/cups/libcups.exp
+++ b/cups/libcups.exp
@@ -26,6 +26,7 @@ __cupsStrFormatd
__cupsStrFree
__cupsStrScand
__cupsStrStatistics
+__httpEncodeURI
__httpReadCDSA
__httpWriteCDSA
__ippAddAttr
diff --git a/cups/ppd.c b/cups/ppd.c
index a70a0cfeb..f8c714d13 100644
--- a/cups/ppd.c
+++ b/cups/ppd.c
@@ -590,7 +590,7 @@ ppdOpen2(cups_file_t *fp) /* I - File to read from */
ppd->language_level = 2;
ppd->color_device = 0;
- ppd->colorspace = PPD_CS_GRAY;
+ ppd->colorspace = PPD_CS_N;
ppd->landscape = -90;
ppd->coptions = cupsArrayNew((cups_array_func_t)ppd_compare_coptions,
NULL);
diff --git a/doc/help/spec-ppd.html b/doc/help/spec-ppd.html
index f78693450..5aa7b357a 100644
--- a/doc/help/spec-ppd.html
+++ b/doc/help/spec-ppd.html
@@ -1185,7 +1185,7 @@ text:for%20all%20good%20men%20to%20come%20to%20the%20aid%20of%20their%20country.
*cupsIPPReason com.vendor-error/A serious error occurred: "http://www.vendor.com/help"
<em>*% Map com.vendor-error to text and a local, Apple help book, and remote page</em>
-*APHelpBook: "file:///Library/Printers/vendor/Help/filename"
+*APHelpBook: "file:///Library/Printers/vendor/Help.bundle"
*cupsIPPReason com.vendor-error/A serious error occurred: "/help/com.vendor/error.html
help:anchor='com.vendor-error'%20bookID=Vendor%20Help
http://www.vendor.com/help"
@@ -1446,9 +1446,9 @@ attribute.</p>
<h3><a name='APHelpBook'>APHelpBook</a></h3>
-<p class='summary'>*APHelpBook: "file URL"</p>
+<p class='summary'>*APHelpBook: "bundle URL"</p>
-<p>This string attribute specifies the Apple help book file to use when
+<p>This string attribute specifies the Apple help book bundle to use when
looking up IPP reason codes for this printer driver. The
<a href='#cupsIPPReason'><tt>cupsIPPReason</tt></a> attribute maps
"help" URIs to this file.</p>
@@ -1456,7 +1456,7 @@ looking up IPP reason codes for this printer driver. The
<p>Example:</p>
<pre class='command'>
-*APHelpBook: "file:///Library/Printers/vendor/Help/filename"
+*APHelpBook: "file:///Library/Printers/vendor/Help.bundle"
</pre>
<h3><span class='info'>Mac OS X 10.3</span><a name='APPrinterIconPath'>APPrinterIconPath</a></h3>
@@ -1634,7 +1634,7 @@ the device.</p>
<li>Added custom option values support</li>
- <li>Added <tt>APBookFile</tt> attribute</li>
+ <li>Added <tt>APHelpBook</tt> attribute</li>
<li>Added <tt>APDuplexRequiresFlippedMargin</tt> attribute</li>
diff --git a/driver/Makefile b/driver/Makefile
index 30715f805..ea4240acb 100644
--- a/driver/Makefile
+++ b/driver/Makefile
@@ -151,7 +151,6 @@ install-libs: $(INSTALLSTATIC) $(INSTALL32) $(INSTALL64)
$(LN) $(LIBCUPSDRIVER) $(LIBDIR)/`basename $(LIBCUPSDRIVER) .1`; \
fi
if test $(LIBCUPSDRIVER) = "libcupsdriver.1.dylib"; then \
- $(STRIP) -x $(LIBDIR)/$(LIBCUPSDRIVER); \
$(RM) $(LIBDIR)/libcupsdriver.dylib; \
$(LN) $(LIBCUPSDRIVER) $(LIBDIR)/libcupsdriver.dylib; \
fi
diff --git a/driver/pcl-common.h b/driver/pcl-common.h
index 78cf70168..17819ab01 100644
--- a/driver/pcl-common.h
+++ b/driver/pcl-common.h
@@ -17,7 +17,7 @@
* Include necessary headers...
*/
-#include "string.h"
+#include <cups/string.h>
#include "data/pcl.h"
diff --git a/driver/rastertoescpx.c b/driver/rastertoescpx.c
index f9cf22a61..362086e45 100644
--- a/driver/rastertoescpx.c
+++ b/driver/rastertoescpx.c
@@ -3,7 +3,7 @@
*
* Advanced EPSON ESC/P raster driver for CUPS.
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1993-2005 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -18,6 +18,7 @@
* StartPage() - Start a page of graphics.
* EndPage() - Finish a page of graphics.
* Shutdown() - Shutdown a printer.
+ * CancelJob() - Cancel the current job...
* CompressData() - Compress a line of graphics.
* OutputBand() - Output a band of graphics.
* ProcessLine() - Read graphics from the page stream and output
@@ -32,6 +33,7 @@
#include "driver.h"
#include <cups/string.h>
#include "data/escp.h"
+#include <signal.h>
/*
@@ -82,6 +84,7 @@ int PrinterPlanes, /* # of color planes */
cups_lut_t *DitherLuts[7]; /* Lookup tables for dithering */
cups_dither_t *DitherStates[7]; /* Dither state tables */
int OutputFeed; /* Number of lines to skip */
+int Canceled; /* Is the job canceled? */
/*
@@ -89,18 +92,19 @@ int OutputFeed; /* Number of lines to skip */
*/
void Setup(ppd_file_t *);
-void StartPage(ppd_file_t *, cups_page_header_t *);
-void EndPage(ppd_file_t *, cups_page_header_t *);
+void StartPage(ppd_file_t *, cups_page_header2_t *);
+void EndPage(ppd_file_t *, cups_page_header2_t *);
void Shutdown(ppd_file_t *);
void AddBand(cups_weave_t *band);
+void CancelJob(int sig);
void CompressData(ppd_file_t *, const unsigned char *, const int,
int, int, const int, const int, const int,
const int);
-void OutputBand(ppd_file_t *, cups_page_header_t *,
+void OutputBand(ppd_file_t *, cups_page_header2_t *,
cups_weave_t *band);
void ProcessLine(ppd_file_t *, cups_raster_t *,
- cups_page_header_t *, const int y);
+ cups_page_header2_t *, const int y);
/*
@@ -126,7 +130,7 @@ Setup(ppd_file_t *ppd) /* I - PPD file */
void
StartPage(ppd_file_t *ppd, /* I - PPD file */
- cups_page_header_t *header) /* I - Page header */
+ cups_page_header2_t *header) /* I - Page header */
{
int i, y; /* Looping vars */
int subrow, /* Current subrow */
@@ -1043,7 +1047,7 @@ StartPage(ppd_file_t *ppd, /* I - PPD file */
void
EndPage(ppd_file_t *ppd, /* I - PPD file */
- cups_page_header_t *header) /* I - Page header */
+ cups_page_header2_t *header) /* I - Page header */
{
int i; /* Looping var */
cups_weave_t *band, /* Current band */
@@ -1265,6 +1269,19 @@ AddBand(cups_weave_t *band) /* I - Band to add */
/*
+ * 'CancelJob()' - Cancel the current job...
+ */
+
+void
+CancelJob(int sig) /* I - Signal */
+{
+ (void)sig;
+
+ Canceled = 1;
+}
+
+
+/*
* 'CompressData()' - Compress a line of graphics.
*/
@@ -1467,7 +1484,7 @@ CompressData(ppd_file_t *ppd, /* I - PPD file information */
void
OutputBand(ppd_file_t *ppd, /* I - PPD file */
- cups_page_header_t *header, /* I - Page header */
+ cups_page_header2_t *header, /* I - Page header */
cups_weave_t *band) /* I - Current band */
{
int xstep, /* Spacing between columns */
@@ -1529,7 +1546,7 @@ OutputBand(ppd_file_t *ppd, /* I - PPD file */
void
ProcessLine(ppd_file_t *ppd, /* I - PPD file */
cups_raster_t *ras, /* I - Raster stream */
- cups_page_header_t *header, /* I - Page header */
+ cups_page_header2_t *header, /* I - Page header */
const int y) /* I - Current scanline */
{
int plane, /* Current color plane */
@@ -1725,12 +1742,15 @@ main(int argc, /* I - Number of command-line arguments */
{
int fd; /* File descriptor */
cups_raster_t *ras; /* Raster stream for printing */
- cups_page_header_t header; /* Page header from file */
+ cups_page_header2_t header; /* Page header from file */
int page; /* Current page */
int y; /* Current line */
ppd_file_t *ppd; /* PPD file */
int num_options; /* Number of options */
cups_option_t *options; /* Options */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
/*
@@ -1784,6 +1804,25 @@ main(int argc, /* I - Number of command-line arguments */
ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
/*
+ * Register a signal handler to eject the current page if the
+ * job is cancelled.
+ */
+
+ Canceled = 0;
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, CancelJob);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = CancelJob;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, CancelJob);
+#endif /* HAVE_SIGSET */
+
+ /*
* Initialize the print device...
*/
@@ -1795,8 +1834,15 @@ main(int argc, /* I - Number of command-line arguments */
page = 0;
- while (cupsRasterReadHeader(ras, &header))
+ while (cupsRasterReadHeader2(ras, &header))
{
+ /*
+ * Write a status message with the page number and number of copies.
+ */
+
+ if (Canceled)
+ break;
+
page ++;
fprintf(stderr, "PAGE: %d 1\n", page);
@@ -1806,16 +1852,34 @@ main(int argc, /* I - Number of command-line arguments */
for (y = 0; y < header.cupsHeight; y ++)
{
+ /*
+ * Let the user know how far we have progressed...
+ */
+
+ if (Canceled)
+ break;
+
if ((y & 127) == 0)
fprintf(stderr, "INFO: Printing page %d, %d%% complete...\n", page,
100 * y / header.cupsHeight);
+ /*
+ * Read and write a line of graphics or whitespace...
+ */
+
ProcessLine(ppd, ras, &header, y);
}
+ /*
+ * Eject the page...
+ */
+
fprintf(stderr, "INFO: Finished page %d...\n", page);
EndPage(ppd, &header);
+
+ if (Canceled)
+ break;
}
Shutdown(ppd);
diff --git a/driver/rastertopclx.c b/driver/rastertopclx.c
index 9c5097448..d021e2342 100644
--- a/driver/rastertopclx.c
+++ b/driver/rastertopclx.c
@@ -15,10 +15,10 @@
*
* Contents:
*
- * Setup() - Prepare a printer for graphics output.
* StartPage() - Start a page of graphics.
* EndPage() - Finish a page of graphics.
* Shutdown() - Shutdown a printer.
+ * CancelJob() - Cancel the current job...
* CompressData() - Compress a line of graphics.
* OutputLine() - Output the specified number of lines of graphics.
* ReadLine() - Read graphics from the page stream.
@@ -31,6 +31,7 @@
#include "driver.h"
#include "pcl-common.h"
+#include <signal.h>
/*
@@ -80,23 +81,25 @@ const int ColorOrders[7][7] = /* Order of color planes */
{ 5, 0, 1, 2, 3, 4, 0 }, /* KCMYcm */
{ 5, 0, 1, 2, 3, 4, 6 } /* KCMYcmk */
};
+int Canceled; /* Is the job canceled? */
/*
* Prototypes...
*/
-void StartPage(ppd_file_t *ppd, cups_page_header_t *header, int job_id,
+void StartPage(ppd_file_t *ppd, cups_page_header2_t *header, int job_id,
const char *user, const char *title, int num_options,
cups_option_t *options);
-void EndPage(ppd_file_t *ppd, cups_page_header_t *header);
+void EndPage(ppd_file_t *ppd, cups_page_header2_t *header);
void Shutdown(ppd_file_t *ppd, int job_id, const char *user,
const char *title, int num_options, cups_option_t *options);
+void CancelJob(int sig);
void CompressData(unsigned char *line, int length, int plane, int pend,
int type);
-void OutputLine(ppd_file_t *ppd, cups_page_header_t *header);
-int ReadLine(cups_raster_t *ras, cups_page_header_t *header);
+void OutputLine(ppd_file_t *ppd, cups_page_header2_t *header);
+int ReadLine(cups_raster_t *ras, cups_page_header2_t *header);
/*
@@ -105,7 +108,7 @@ int ReadLine(cups_raster_t *ras, cups_page_header_t *header);
void
StartPage(ppd_file_t *ppd, /* I - PPD file */
- cups_page_header_t *header, /* I - Page header */
+ cups_page_header2_t *header, /* I - Page header */
int job_id, /* I - Job ID */
const char *user, /* I - User printing job */
const char *title, /* I - Title of job */
@@ -807,7 +810,7 @@ StartPage(ppd_file_t *ppd, /* I - PPD file */
void
EndPage(ppd_file_t *ppd, /* I - PPD file */
- cups_page_header_t *header) /* I - Page header */
+ cups_page_header2_t *header) /* I - Page header */
{
int plane; /* Current plane */
@@ -917,6 +920,19 @@ Shutdown(ppd_file_t *ppd, /* I - PPD file */
/*
+ * 'CancelJob()' - Cancel the current job...
+ */
+
+void
+CancelJob(int sig) /* I - Signal */
+{
+ (void)sig;
+
+ Canceled = 1;
+}
+
+
+/*
* 'CompressData()' - Compress a line of graphics.
*/
@@ -1518,7 +1534,7 @@ CompressData(unsigned char *line, /* I - Data to compress */
void
OutputLine(ppd_file_t *ppd, /* I - PPD file */
- cups_page_header_t *header) /* I - Page header */
+ cups_page_header2_t *header) /* I - Page header */
{
int i, j; /* Looping vars */
int plane; /* Current plane */
@@ -1657,7 +1673,7 @@ OutputLine(ppd_file_t *ppd, /* I - PPD file */
int /* O - Number of lines (0 if blank) */
ReadLine(cups_raster_t *ras, /* I - Raster stream */
- cups_page_header_t *header) /* I - Page header */
+ cups_page_header2_t *header) /* I - Page header */
{
int plane, /* Current color plane */
width; /* Width of line */
@@ -1755,12 +1771,15 @@ main(int argc, /* I - Number of command-line arguments */
{
int fd; /* File descriptor */
cups_raster_t *ras; /* Raster stream for printing */
- cups_page_header_t header; /* Page header from file */
+ cups_page_header2_t header; /* Page header from file */
int y; /* Current line */
ppd_file_t *ppd; /* PPD file */
int job_id; /* Job ID */
int num_options; /* Number of options */
cups_option_t *options; /* Options */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
/*
@@ -1814,6 +1833,25 @@ main(int argc, /* I - Number of command-line arguments */
ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
/*
+ * Register a signal handler to eject the current page if the
+ * job is cancelled.
+ */
+
+ Canceled = 0;
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, CancelJob);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = CancelJob;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, CancelJob);
+#endif /* HAVE_SIGSET */
+
+ /*
* Process pages as needed...
*/
@@ -1821,8 +1859,15 @@ main(int argc, /* I - Number of command-line arguments */
Page = 0;
- while (cupsRasterReadHeader(ras, &header))
+ while (cupsRasterReadHeader2(ras, &header))
{
+ /*
+ * Write a status message with the page number and number of copies.
+ */
+
+ if (Canceled)
+ break;
+
Page ++;
fprintf(stderr, "PAGE: %d %d\n", Page, header.NumCopies);
@@ -1833,19 +1878,37 @@ main(int argc, /* I - Number of command-line arguments */
for (y = 0; y < (int)header.cupsHeight; y ++)
{
+ /*
+ * Let the user know how far we have progressed...
+ */
+
+ if (Canceled)
+ break;
+
if ((y & 127) == 0)
fprintf(stderr, "INFO: Printing page %d, %d%% complete...\n", Page,
100 * y / header.cupsHeight);
+ /*
+ * Read and write a line of graphics or whitespace...
+ */
+
if (ReadLine(ras, &header))
OutputLine(ppd, &header);
else
OutputFeed ++;
}
+ /*
+ * Eject the page...
+ */
+
fprintf(stderr, "INFO: Finished page %d...\n", Page);
EndPage(ppd, &header);
+
+ if (Canceled)
+ break;
}
Shutdown(ppd, job_id, argv[2], argv[3], num_options, options);
diff --git a/filter/Makefile b/filter/Makefile
index c0990f8dc..6bd1f556e 100644
--- a/filter/Makefile
+++ b/filter/Makefile
@@ -130,7 +130,6 @@ install-libs: $(INSTALLSTATIC) $(INSTALL32) $(INSTALL64)
$(LN) $(LIBCUPSIMAGE) $(LIBDIR)/`basename $(LIBCUPSIMAGE) .2`; \
fi
-if test $(LIBCUPSIMAGE) = "libcupsimage.2.dylib"; then \
- $(STRIP) -x $(LIBDIR)/$(LIBCUPSIMAGE); \
$(RM) $(LIBDIR)/libcupsimage.dylib; \
$(LN) $(LIBCUPSIMAGE) $(LIBDIR)/libcupsimage.dylib; \
fi
diff --git a/filter/image-gif.c b/filter/image-gif.c
index a391811fc..d78670d37 100644
--- a/filter/image-gif.c
+++ b/filter/image-gif.c
@@ -37,6 +37,7 @@
#define GIF_INTERLACE 0x40
#define GIF_COLORMAP 0x80
+#define GIF_MAX_BITS 12
typedef cups_ib_t gif_cmap_t[256][4];
typedef short gif_table_t[4096];
@@ -462,7 +463,7 @@ gif_read_image(FILE *fp, /* I - Input file */
pass = 0;
code_size = getc(fp);
- if (!pixels)
+ if (code_size > GIF_MAX_BITS || !pixels)
return (-1);
if (gif_read_lzw(fp, 1, code_size) < 0)
diff --git a/filter/image-png.c b/filter/image-png.c
index 1db19e2d7..332b3c39b 100644
--- a/filter/image-png.c
+++ b/filter/image-png.c
@@ -3,7 +3,7 @@
*
* PNG image routines for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1993-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -170,16 +170,56 @@ _cupsImageReadPNG(
* Interlaced images must be loaded all at once...
*/
+ size_t bufsize; /* Size of buffer */
+
+
if (color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- in = malloc(img->xsize * img->ysize);
+ {
+ bufsize = img->xsize * img->ysize;
+
+ if ((bufsize / img->ysize) != img->xsize)
+ {
+ fprintf(stderr, "DEBUG: PNG image dimensions (%ux%u) too large!\n",
+ (unsigned)width, (unsigned)height);
+ fclose(fp);
+ return (1);
+ }
+ }
else
- in = malloc(img->xsize * img->ysize * 3);
+ {
+ bufsize = img->xsize * img->ysize * 3;
+
+ if ((bufsize / (img->ysize * 3)) != img->xsize)
+ {
+ fprintf(stderr, "DEBUG: PNG image dimensions (%ux%u) too large!\n",
+ (unsigned)width, (unsigned)height);
+ fclose(fp);
+ return (1);
+ }
+ }
+
+ in = malloc(bufsize);
}
bpp = cupsImageGetDepth(img);
out = malloc(img->xsize * bpp);
+ if (!in || !out)
+ {
+ fputs("DEBUG: Unable to allocate memory for PNG image!\n", stderr);
+
+ if (in)
+ free(in);
+
+ if (out)
+ free(out);
+
+ fclose(fp);
+
+ return (1);
+ }
+
/*
* Read the image, interlacing as needed...
*/
diff --git a/filter/pdftops.c b/filter/pdftops.c
index 9db1e9168..f1abb52bf 100644
--- a/filter/pdftops.c
+++ b/filter/pdftops.c
@@ -28,6 +28,7 @@
#include <cups/i18n.h>
#include <signal.h>
#include <sys/wait.h>
+#include <errno.h>
/*
@@ -38,6 +39,13 @@ static void cancel_job(int sig);
/*
+ * Local globals...
+ */
+
+static int job_canceled = 0;
+
+
+/*
* 'main()' - Main entry for filter...
*/
@@ -57,6 +65,7 @@ main(int argc, /* I - Number of command-line args */
ppd_file_t *ppd; /* PPD file */
ppd_size_t *size; /* Current page size */
int pdfpid, /* Process ID for pdftops */
+ pdfwaitpid, /* Process ID from wait() */
pdfstatus, /* Status from pdftops */
pdfargc; /* Number of args for pdftops */
char *pdfargv[100], /* Arguments for pdftops */
@@ -261,7 +270,17 @@ main(int argc, /* I - Number of command-line args */
* Parent comes here...
*/
- if (wait(&pdfstatus) != pdfpid)
+ while ((pdfwaitpid = wait(&pdfstatus)) < 0 && errno == EINTR)
+ {
+ /*
+ * Wait until we get a valid process ID or the job is canceled...
+ */
+
+ if (job_canceled)
+ break;
+ }
+
+ if (pdfwaitpid != pdfpid)
{
kill(pdfpid, SIGTERM);
pdfstatus = 1;
@@ -270,18 +289,18 @@ main(int argc, /* I - Number of command-line args */
{
if (WIFEXITED(pdfstatus))
{
- pdfstatus = WEXITSTATUS(pdfstatus);
+ pdfstatus = WEXITSTATUS(pdfstatus);
- _cupsLangPrintf(stderr,
- _("ERROR: pdftops filter exited with status %d!\n"),
+ _cupsLangPrintf(stderr,
+ _("ERROR: pdftops filter exited with status %d!\n"),
pdfstatus);
}
else
{
- pdfstatus = WTERMSIG(pdfstatus);
+ pdfstatus = WTERMSIG(pdfstatus);
- _cupsLangPrintf(stderr,
- _("ERROR: pdftops filter crashed on signal %d!\n"),
+ _cupsLangPrintf(stderr,
+ _("ERROR: pdftops filter crashed on signal %d!\n"),
pdfstatus);
}
}
@@ -306,6 +325,8 @@ static void
cancel_job(int sig) /* I - Signal number (unused) */
{
(void)sig;
+
+ job_canceled = 1;
}
diff --git a/filter/rastertoepson.c b/filter/rastertoepson.c
index f1ad6547c..62ecb347b 100644
--- a/filter/rastertoepson.c
+++ b/filter/rastertoepson.c
@@ -77,7 +77,8 @@ int DotBit, /* Bit in buffers */
LineCount, /* # of lines processed */
EvenOffset, /* Offset into 'even' buffers */
OddOffset, /* Offset into 'odd' buffers */
- Shingling; /* Shingle output? */
+ Shingling, /* Shingle output? */
+ Canceled; /* Has the current job been canceled? */
/*
@@ -85,15 +86,15 @@ int DotBit, /* Bit in buffers */
*/
void Setup(void);
-void StartPage(const ppd_file_t *ppd, const cups_page_header_t *header);
-void EndPage(const cups_page_header_t *header);
+void StartPage(const ppd_file_t *ppd, const cups_page_header2_t *header);
+void EndPage(const cups_page_header2_t *header);
void Shutdown(void);
void CancelJob(int sig);
void CompressData(const unsigned char *line, int length, int plane,
int type, int xstep, int ystep);
-void OutputLine(const cups_page_header_t *header);
-void OutputRows(const cups_page_header_t *header, int row);
+void OutputLine(const cups_page_header2_t *header);
+void OutputRows(const cups_page_header2_t *header, int row);
/*
@@ -123,31 +124,11 @@ Setup(void)
void
StartPage(const ppd_file_t *ppd, /* I - PPD file */
- const cups_page_header_t *header) /* I - Page header */
+ const cups_page_header2_t *header) /* I - Page header */
{
int n, t; /* Numbers */
int plane; /* Looping var */
-#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
- struct sigaction action; /* Actions for POSIX signals */
-#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
-
-
- /*
- * Register a signal handler to eject the current page if the
- * job is cancelled.
- */
-#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
- sigset(SIGTERM, CancelJob);
-#elif defined(HAVE_SIGACTION)
- memset(&action, 0, sizeof(action));
-
- sigemptyset(&action.sa_mask);
- action.sa_handler = CancelJob;
- sigaction(SIGTERM, &action, NULL);
-#else
- signal(SIGTERM, CancelJob);
-#endif /* HAVE_SIGSET */
/*
* Send a reset sequence.
@@ -339,7 +320,7 @@ StartPage(const ppd_file_t *ppd, /* I - PPD file */
*/
void
-EndPage(const cups_page_header_t *header) /* I - Page header */
+EndPage(const cups_page_header2_t *header) /* I - Page header */
{
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
struct sigaction action; /* Actions for POSIX signals */
@@ -378,22 +359,6 @@ EndPage(const cups_page_header_t *header) /* I - Page header */
fflush(stdout);
/*
- * Unregister the signal handler...
- */
-
-#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
- sigset(SIGTERM, SIG_IGN);
-#elif defined(HAVE_SIGACTION)
- memset(&action, 0, sizeof(action));
-
- sigemptyset(&action.sa_mask);
- action.sa_handler = SIG_IGN;
- sigaction(SIGTERM, &action, NULL);
-#else
- signal(SIGTERM, SIG_IGN);
-#endif /* HAVE_SIGSET */
-
- /*
* Free memory...
*/
@@ -429,31 +394,9 @@ Shutdown(void)
void
CancelJob(int sig) /* I - Signal */
{
- int i; /* Looping var */
-
-
(void)sig;
- /*
- * Send out lots of NUL bytes to clear out any pending raster data...
- */
-
- if (DotBytes)
- i = DotBytes * 360 * 8;
- else
- i = 720;
-
- for (; i > 0; i --)
- putchar(0);
-
- /*
- * End the current page and exit...
- */
-
- EndPage(NULL);
- Shutdown();
-
- exit(0);
+ Canceled = 1;
}
@@ -670,7 +613,7 @@ CompressData(const unsigned char *line, /* I - Data to compress */
*/
void
-OutputLine(const cups_page_header_t *header) /* I - Page header */
+OutputLine(const cups_page_header2_t *header) /* I - Page header */
{
if (header->cupsRowCount)
{
@@ -838,7 +781,7 @@ OutputLine(const cups_page_header_t *header) /* I - Page header */
*/
void
-OutputRows(const cups_page_header_t *header, /* I - Page image header */
+OutputRows(const cups_page_header2_t *header, /* I - Page image header */
int row) /* I - Row number (0 or 1) */
{
unsigned i, n; /* Looping vars */
@@ -1012,16 +955,19 @@ OutputRows(const cups_page_header_t *header, /* I - Page image header */
* 'main()' - Main entry and processing of driver.
*/
-int /* O - Exit status */
-main(int argc, /* I - Number of command-line arguments */
- char *argv[]) /* I - Command-line arguments */
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
{
- int fd; /* File descriptor */
- cups_raster_t *ras; /* Raster stream for printing */
- cups_page_header_t header; /* Page header from file */
- ppd_file_t *ppd; /* PPD file */
- int page; /* Current page */
- int y; /* Current line */
+ int fd; /* File descriptor */
+ cups_raster_t *ras; /* Raster stream for printing */
+ cups_page_header2_t header; /* Page header from file */
+ ppd_file_t *ppd; /* PPD file */
+ int page; /* Current page */
+ int y; /* Current line */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
/*
@@ -1065,6 +1011,25 @@ main(int argc, /* I - Number of command-line arguments */
ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
/*
+ * Register a signal handler to eject the current page if the
+ * job is cancelled.
+ */
+
+ Canceled = 0;
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, CancelJob);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = CancelJob;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, CancelJob);
+#endif /* HAVE_SIGSET */
+
+ /*
* Initialize the print device...
*/
@@ -1080,12 +1045,15 @@ main(int argc, /* I - Number of command-line arguments */
page = 0;
- while (cupsRasterReadHeader(ras, &header))
+ while (cupsRasterReadHeader2(ras, &header))
{
/*
* Write a status message with the page number and number of copies.
*/
+ if (Canceled)
+ break;
+
page ++;
fprintf(stderr, "PAGE: %d %d\n", page, header.NumCopies);
@@ -1106,6 +1074,9 @@ main(int argc, /* I - Number of command-line arguments */
* Let the user know how far we have progressed...
*/
+ if (Canceled)
+ break;
+
if ((y & 127) == 0)
fprintf(stderr, _("INFO: Printing page %d, %d%% complete...\n"), page,
100 * y / header.cupsHeight);
@@ -1129,6 +1100,9 @@ main(int argc, /* I - Number of command-line arguments */
*/
EndPage(&header);
+
+ if (Canceled)
+ break;
}
/*
diff --git a/filter/rastertohp.c b/filter/rastertohp.c
index 04ac4017a..9f9b7bc45 100644
--- a/filter/rastertohp.c
+++ b/filter/rastertohp.c
@@ -52,7 +52,8 @@ int NumPlanes, /* Number of color planes */
ColorBits, /* Number of bits per color */
Feed, /* Number of lines to skip */
Duplex, /* Current duplex mode */
- Page; /* Current page number */
+ Page, /* Current page number */
+ Canceled; /* Has the current job been canceled? */
/*
@@ -60,13 +61,13 @@ int NumPlanes, /* Number of color planes */
*/
void Setup(void);
-void StartPage(ppd_file_t *ppd, cups_page_header_t *header);
+void StartPage(ppd_file_t *ppd, cups_page_header2_t *header);
void EndPage(void);
void Shutdown(void);
void CancelJob(int sig);
void CompressData(unsigned char *line, int length, int plane, int type);
-void OutputLine(cups_page_header_t *header);
+void OutputLine(cups_page_header2_t *header);
/*
@@ -91,32 +92,12 @@ Setup(void)
void
StartPage(ppd_file_t *ppd, /* I - PPD file */
- cups_page_header_t *header) /* I - Page header */
+ cups_page_header2_t *header) /* I - Page header */
{
int plane; /* Looping var */
-#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
- struct sigaction action; /* Actions for POSIX signals */
-#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
/*
- * Register a signal handler to eject the current page if the
- * job is cancelled.
- */
-
-#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
- sigset(SIGTERM, CancelJob);
-#elif defined(HAVE_SIGACTION)
- memset(&action, 0, sizeof(action));
-
- sigemptyset(&action.sa_mask);
- action.sa_handler = CancelJob;
- sigaction(SIGTERM, &action, NULL);
-#else
- signal(SIGTERM, CancelJob);
-#endif /* HAVE_SIGSET */
-
- /*
* Show page device dictionary...
*/
@@ -410,11 +391,6 @@ StartPage(ppd_file_t *ppd, /* I - PPD file */
void
EndPage(void)
{
-#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
- struct sigaction action; /* Actions for POSIX signals */
-#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
-
-
/*
* Eject the current page...
*/
@@ -437,22 +413,6 @@ EndPage(void)
fflush(stdout);
/*
- * Unregister the signal handler...
- */
-
-#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
- sigset(SIGTERM, SIG_IGN);
-#elif defined(HAVE_SIGACTION)
- memset(&action, 0, sizeof(action));
-
- sigemptyset(&action.sa_mask);
- action.sa_handler = SIG_IGN;
- sigaction(SIGTERM, &action, NULL);
-#else
- signal(SIGTERM, SIG_IGN);
-#endif /* HAVE_SIGSET */
-
- /*
* Free memory...
*/
@@ -489,26 +449,9 @@ Shutdown(void)
void
CancelJob(int sig) /* I - Signal */
{
- int i; /* Looping var */
-
-
(void)sig;
- /*
- * Send out lots of NUL bytes to clear out any pending raster data...
- */
-
- for (i = 0; i < 600; i ++)
- putchar(0);
-
- /*
- * End the current page and exit...
- */
-
- EndPage();
- Shutdown();
-
- exit(0);
+ Canceled = 1;
}
@@ -648,7 +591,7 @@ CompressData(unsigned char *line, /* I - Data to compress */
*/
void
-OutputLine(cups_page_header_t *header) /* I - Page header */
+OutputLine(cups_page_header2_t *header) /* I - Page header */
{
int plane, /* Current plane */
bytes, /* Bytes to write */
@@ -731,15 +674,18 @@ OutputLine(cups_page_header_t *header) /* I - Page header */
* 'main()' - Main entry and processing of driver.
*/
-int /* O - Exit status */
-main(int argc, /* I - Number of command-line arguments */
- char *argv[]) /* I - Command-line arguments */
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
{
- int fd; /* File descriptor */
- cups_raster_t *ras; /* Raster stream for printing */
- cups_page_header_t header; /* Page header from file */
- int y; /* Current line */
- ppd_file_t *ppd; /* PPD file */
+ int fd; /* File descriptor */
+ cups_raster_t *ras; /* Raster stream for printing */
+ cups_page_header2_t header; /* Page header from file */
+ int y; /* Current line */
+ ppd_file_t *ppd; /* PPD file */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
/*
@@ -783,6 +729,25 @@ main(int argc, /* I - Number of command-line arguments */
ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
/*
+ * Register a signal handler to eject the current page if the
+ * job is cancelled.
+ */
+
+ Canceled = 0;
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, CancelJob);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = CancelJob;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, CancelJob);
+#endif /* HAVE_SIGSET */
+
+ /*
* Initialize the print device...
*/
@@ -796,12 +761,15 @@ main(int argc, /* I - Number of command-line arguments */
Page = 0;
- while (cupsRasterReadHeader(ras, &header))
+ while (cupsRasterReadHeader2(ras, &header))
{
/*
* Write a status message with the page number and number of copies.
*/
+ if (Canceled)
+ break;
+
Page ++;
fprintf(stderr, "PAGE: %d %d\n", Page, header.NumCopies);
@@ -822,6 +790,9 @@ main(int argc, /* I - Number of command-line arguments */
* Let the user know how far we have progressed...
*/
+ if (Canceled)
+ break;
+
if ((y & 127) == 0)
fprintf(stderr, _("INFO: Printing page %d, %d%% complete...\n"), Page,
100 * y / header.cupsHeight);
@@ -849,6 +820,9 @@ main(int argc, /* I - Number of command-line arguments */
*/
EndPage();
+
+ if (Canceled)
+ break;
}
/*
diff --git a/filter/rastertolabel.c b/filter/rastertolabel.c
index 05adc0397..cb62278fd 100644
--- a/filter/rastertolabel.c
+++ b/filter/rastertolabel.c
@@ -3,7 +3,7 @@
*
* Label printer filter for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 2001-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -90,10 +90,10 @@ int ModelNumber, /* cupsModelNumber attribute */
*/
void Setup(ppd_file_t *ppd);
-void StartPage(ppd_file_t *ppd, cups_page_header_t *header);
-void EndPage(ppd_file_t *ppd, cups_page_header_t *header);
+void StartPage(ppd_file_t *ppd, cups_page_header2_t *header);
+void EndPage(ppd_file_t *ppd, cups_page_header2_t *header);
void CancelJob(int sig);
-void OutputLine(ppd_file_t *ppd, cups_page_header_t *header, int y);
+void OutputLine(ppd_file_t *ppd, cups_page_header2_t *header, int y);
void PCLCompress(unsigned char *line, int length);
void ZPLCompress(char repeat_char, int repeat_count);
@@ -166,13 +166,10 @@ Setup(ppd_file_t *ppd) /* I - PPD file */
void
StartPage(ppd_file_t *ppd, /* I - PPD file */
- cups_page_header_t *header) /* I - Page header */
+ cups_page_header2_t *header) /* I - Page header */
{
ppd_choice_t *choice; /* Marked choice */
int length; /* Actual label length */
-#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
- struct sigaction action; /* Actions for POSIX signals */
-#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
/*
@@ -226,23 +223,6 @@ StartPage(ppd_file_t *ppd, /* I - PPD file */
fprintf(stderr, "DEBUG: cupsRowFeed = %d\n", header->cupsRowFeed);
fprintf(stderr, "DEBUG: cupsRowStep = %d\n", header->cupsRowStep);
- /*
- * Register a signal handler to eject the current page if the
- * job is canceled.
- */
-
-#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
- sigset(SIGTERM, CancelJob);
-#elif defined(HAVE_SIGACTION)
- memset(&action, 0, sizeof(action));
-
- sigemptyset(&action.sa_mask);
- action.sa_handler = CancelJob;
- sigaction(SIGTERM, &action, NULL);
-#else
- signal(SIGTERM, CancelJob);
-#endif /* HAVE_SIGSET */
-
switch (ModelNumber)
{
case DYMO_3x0 :
@@ -498,7 +478,7 @@ StartPage(ppd_file_t *ppd, /* I - PPD file */
void
EndPage(ppd_file_t *ppd, /* I - PPD file */
- cups_page_header_t *header) /* I - Page header */
+ cups_page_header2_t *header) /* I - Page header */
{
int val; /* Option value */
ppd_choice_t *choice; /* Marked choice */
@@ -733,22 +713,6 @@ EndPage(ppd_file_t *ppd, /* I - PPD file */
fflush(stdout);
/*
- * Unregister the signal handler...
- */
-
-#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
- sigset(SIGTERM, SIG_IGN);
-#elif defined(HAVE_SIGACTION)
- memset(&action, 0, sizeof(action));
-
- sigemptyset(&action.sa_mask);
- action.sa_handler = SIG_IGN;
- sigaction(SIGTERM, &action, NULL);
-#else
- signal(SIGTERM, SIG_IGN);
-#endif /* HAVE_SIGSET */
-
- /*
* Free memory...
*/
@@ -779,7 +743,7 @@ CancelJob(int sig) /* I - Signal */
void
OutputLine(ppd_file_t *ppd, /* I - PPD file */
- cups_page_header_t *header, /* I - Page header */
+ cups_page_header2_t *header, /* I - Page header */
int y) /* I - Line number */
{
int i; /* Looping var */
@@ -1145,11 +1109,14 @@ main(int argc, /* I - Number of command-line arguments */
{
int fd; /* File descriptor */
cups_raster_t *ras; /* Raster stream for printing */
- cups_page_header_t header; /* Page header from file */
+ cups_page_header2_t header; /* Page header from file */
int y; /* Current line */
ppd_file_t *ppd; /* PPD file */
int num_options; /* Number of options */
cups_option_t *options; /* Options */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
/*
@@ -1193,6 +1160,25 @@ main(int argc, /* I - Number of command-line arguments */
ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
/*
+ * Register a signal handler to eject the current page if the
+ * job is cancelled.
+ */
+
+ Canceled = 0;
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, CancelJob);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = CancelJob;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, CancelJob);
+#endif /* HAVE_SIGSET */
+
+ /*
* Open the PPD file and apply options...
*/
@@ -1214,15 +1200,17 @@ main(int argc, /* I - Number of command-line arguments */
* Process pages as needed...
*/
- Page = 0;
- Canceled = 0;
+ Page = 0;
- while (cupsRasterReadHeader(ras, &header))
+ while (cupsRasterReadHeader2(ras, &header))
{
/*
* Write a status message with the page number and number of copies.
*/
+ if (Canceled)
+ break;
+
Page ++;
fprintf(stderr, "PAGE: %d 1\n", Page);
@@ -1243,6 +1231,9 @@ main(int argc, /* I - Number of command-line arguments */
* Let the user know how far we have progressed...
*/
+ if (Canceled)
+ break;
+
if ((y & 15) == 0)
fprintf(stderr, _("INFO: Printing page %d, %d%% complete...\n"), Page,
100 * y / header.cupsHeight);
diff --git a/install-sh b/install-sh
index 398a88e14..2c4a67c2d 100755
--- a/install-sh
+++ b/install-sh
@@ -3,6 +3,7 @@
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
+# Library stripping changes Copyright 2008 by Apple Inc.
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
@@ -181,7 +182,9 @@ while [ $# -ne 0 ] ; do
if [ ! -d "${pathcomp}" ] ;
then
- $mkdirprog "${pathcomp}"
+ $mkdirprog "${pathcomp}" &&
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd "$pathcomp"; else : ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$pathcomp"; else : ; fi
else
:
fi
@@ -196,7 +199,6 @@ then
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
else
@@ -219,6 +221,16 @@ else
:
fi
+# Check the destination file - for libraries just use the "-x" option to strip
+ case "$dstfile" in
+ *.a | *.dylib | *.sl | *.sl.* | *.so | *.so.*)
+ stripopt="-x"
+ ;;
+ *)
+ stripopt=""
+ ;;
+ esac
+
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
@@ -237,7 +249,7 @@ else
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $stripopt $dsttmp; else :;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
# Now rename the file to the real destination.
diff --git a/man/ppdpo.man b/man/ppdpo.man
index b5b43ebbe..dc84e846b 100644
--- a/man/ppdpo.man
+++ b/man/ppdpo.man
@@ -3,7 +3,7 @@
.\"
.\" ppdpo man page for the CUPS Driver Development Kit.
.\"
-.\" 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,9 +12,9 @@
.\" 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 ppdpo 1 "CUPS Driver Development Kit" "14 February 2007" "Apple Inc."
+.TH ppdpo 1 "Common UNIX Printing System" "27 March 2008" "Apple Inc."
.SH NAME
-ppdpo \- cups message catalog generator
+ppdpo \- ppd message catalog generator
.SH SYNOPSIS
.B ppdpo
[ \-I
@@ -24,18 +24,22 @@ ppdpo \- cups message catalog generator
]
.I source-file
.SH DESCRIPTION
-\fIppdpo\fR extracts UI strings from PPDC source files and writes them in
-a GNU gettext format message catalog source file for translation.
+\fIppdpo\fR extracts UI strings from PPDC source files and updates either
+a GNU gettext or Mac OS X strings format message catalog source file for
+translation.
.PP
The \fI-I\fR option specifies an alternate include directory;
multiple \fI-I\fR options can be supplied to add additional
directories.
.PP
-The \fI-o\fR option specifies the output file.
+The \fI-o\fR option specifies the output file. The supported extensions are
+".po" or ".po.gz" for GNU gettext format message catalogs and ".strings" for
+Mac OS X strings files.
.SH SEE ALSO
-cupsprofile(1), ppdc(1), ppdhtml(1), ppdi(1), ppdmerge(1), ppdcfile(5), CUPS Driver Developer Kit Manual.
+ppdc(1), ppdhtml(1), ppdi(1), ppdmerge(1), ppdcfile(5),
+http://localhost:631/help
.SH COPYRIGHT
-Copyright 2007 by Apple Inc.
+Copyright 2007-2008 by Apple Inc.
.\"
.\" End of "$Id: ppdpo.man 343 2007-07-13 19:52:48Z mike $".
.\"
diff --git a/ppdc/Makefile b/ppdc/Makefile
index edaafeceb..d67920817 100644
--- a/ppdc/Makefile
+++ b/ppdc/Makefile
@@ -165,7 +165,6 @@ install-libs: $(INSTALLSTATIC) $(INSTALL32) $(INSTALL64)
$(LN) $(LIBCUPSPPDC) $(LIBDIR)/`basename $(LIBCUPSPPDC) .1`; \
fi
if test $(LIBCUPSPPDC) = "libcupsppdc.1.dylib"; then \
- $(STRIP) -x $(LIBDIR)/$(LIBCUPSPPDC); \
$(RM) $(LIBDIR)/libcupsppdc.dylib; \
$(LN) $(LIBCUPSPPDC) $(LIBDIR)/libcupsppdc.dylib; \
fi
diff --git a/ppdc/ppdc-catalog.cxx b/ppdc/ppdc-catalog.cxx
index 96cd6e3aa..29de91f67 100644
--- a/ppdc/ppdc-catalog.cxx
+++ b/ppdc/ppdc-catalog.cxx
@@ -31,6 +31,29 @@
//
+// Character encodings...
+//
+
+typedef enum
+{
+ PPDC_CS_AUTO,
+ PPDC_CS_UTF8,
+ PPDC_CS_UTF16BE,
+ PPDC_CS_UTF16LE
+} ppdc_cs_t;
+
+
+//
+// Local functions...
+//
+
+static int get_utf8(char *&ptr);
+static int get_utf16(cups_file_t *fp, ppdc_cs_t &cs);
+static int put_utf8(int ch, char *&ptr, char *end);
+static int put_utf16(cups_file_t *fp, int ch);
+
+
+//
// 'ppdcCatalog::ppdcCatalog()' - Create a shared message catalog.
//
@@ -155,146 +178,260 @@ ppdcCatalog::load_messages(
if ((fp = cupsFileOpen(f, "r")) == NULL)
return (-1);
- /*
- * Read messages from the catalog file until EOF...
- *
- * The format is the GNU gettext .po format, which is fairly simple:
- *
- * msgid "some text"
- * msgstr "localized text"
- *
- * The ID and localized text can span multiple lines using the form:
- *
- * msgid ""
- * "some long text"
- * msgstr ""
- * "localized text spanning "
- * "multiple lines"
- */
+ if ((ptr = strrchr(f, '.')) == NULL)
+ goto unknown_load_format;
+ else if (!strcmp(ptr, ".strings"))
+ {
+ /*
+ * Read messages in Mac OS X ".strings" format, which are UTF-16 text
+ * files of the format:
+ *
+ * "id" = "str";
+ *
+ * Strings files can also contain C-style comments.
+ */
+
+ ppdc_cs_t cs = PPDC_CS_AUTO; // Character set for file
+ int ch; // Current character from file
+ char *end; // End of buffer
+
+
+ id[0] = '\0';
+ str[0] = '\0';
+ ptr = NULL;
+ end = NULL;
+
+ while ((ch = get_utf16(fp, cs)) != 0)
+ {
+ if (ptr)
+ {
+ if (ch == '\\')
+ {
+ if ((ch = get_utf16(fp, cs)) == 0)
+ break;
- linenum = 0;
- id[0] = '\0';
- str[0] = '\0';
+ if (ch == 'n')
+ ch = '\n';
+ else if (ch == 't')
+ ch = '\t';
+ }
- while (cupsFileGets(fp, line, sizeof(line)))
- {
- linenum ++;
+ put_utf8(ch, ptr, end);
+ }
+ else if (ch == '/')
+ {
+ // Start of a comment?
+ if ((ch = get_utf16(fp, cs)) == 0)
+ break;
- // Skip blank and comment lines...
- if (line[0] == '#' || !line[0])
- continue;
+ if (ch == '*')
+ {
+ // Skip C comment...
+ int lastch = 0;
- // Strip the trailing quote...
- if ((ptr = strrchr(line, '\"')) == NULL)
- {
- fprintf(stderr, "load_messages: Expected quoted string on line %d of %s!\n",
- linenum, f);
- cupsFileClose(fp);
- return (-1);
- }
+ while ((ch = get_utf16(fp, cs)) != 0)
+ {
+ if (ch == '/' && lastch == '*')
+ break;
- *ptr = '\0';
+ lastch = ch;
+ }
+ }
+ else if (ch == '/')
+ {
+ // Skip C++ comment...
+ while ((ch = get_utf16(fp, cs)) != 0)
+ if (ch == '\n')
+ break;
+ }
+ }
+ else if (ch == '\"')
+ {
+ // Start or finish quoted string...
+ if (ptr)
+ {
+ *ptr = '\0';
+ ptr = NULL;
+ }
+ else if (id[0])
+ {
+ ptr = str;
+ end = str + sizeof(str) - 1;
+ }
+ else
+ {
+ ptr = id;
+ end = id + sizeof(id) - 1;
+ }
+ }
+ else if (ch == ';')
+ {
+ // Add string...
+ temp = new ppdcMessage(id, str);
- // Find start of value...
- if ((ptr = strchr(line, '\"')) == NULL)
- {
- fprintf(stderr, "load_messages: Expected quoted string on line %d of %s!\n",
- linenum, f);
- cupsFileClose(fp);
- return (-1);
+ messages->add(temp);
+ }
}
+ }
+ else if (!strcmp(ptr, ".po") || !strcmp(ptr, ".gz"))
+ {
+ /*
+ * Read messages from the catalog file until EOF...
+ *
+ * The format is the GNU gettext .po format, which is fairly simple:
+ *
+ * msgid "some text"
+ * msgstr "localized text"
+ *
+ * The ID and localized text can span multiple lines using the form:
+ *
+ * msgid ""
+ * "some long text"
+ * msgstr ""
+ * "localized text spanning "
+ * "multiple lines"
+ */
+
+ linenum = 0;
+ id[0] = '\0';
+ str[0] = '\0';
+
+ while (cupsFileGets(fp, line, sizeof(line)))
+ {
+ linenum ++;
- ptr ++;
+ // Skip blank and comment lines...
+ if (line[0] == '#' || !line[0])
+ continue;
- // Unquote the text...
- char *sptr, *dptr; // Source/destination pointers
+ // Strip the trailing quote...
+ if ((ptr = strrchr(line, '\"')) == NULL)
+ {
+ fprintf(stderr, "ERROR: Expected quoted string on line %d of %s!\n",
+ linenum, f);
+ cupsFileClose(fp);
+ return (-1);
+ }
- for (sptr = ptr, dptr = ptr; *sptr;)
- {
- if (*sptr == '\\')
+ *ptr = '\0';
+
+ // Find start of value...
+ if ((ptr = strchr(line, '\"')) == NULL)
+ {
+ fprintf(stderr, "ERROR: Expected quoted string on line %d of %s!\n",
+ linenum, f);
+ cupsFileClose(fp);
+ return (-1);
+ }
+
+ ptr ++;
+
+ // Unquote the text...
+ char *sptr, *dptr; // Source/destination pointers
+
+ for (sptr = ptr, dptr = ptr; *sptr;)
{
- sptr ++;
- if (isdigit(*sptr))
+ if (*sptr == '\\')
{
- *dptr = 0;
+ sptr ++;
+ if (isdigit(*sptr))
+ {
+ *dptr = 0;
+
+ while (isdigit(*sptr))
+ {
+ *dptr = *dptr * 8 + *sptr - '0';
+ sptr ++;
+ }
- while (isdigit(*sptr))
+ dptr ++;
+ }
+ else
{
- *dptr = *dptr * 8 + *sptr - '0';
+ if (*sptr == 'n')
+ *dptr++ = '\n';
+ else if (*sptr == 'r')
+ *dptr++ = '\r';
+ else if (*sptr == 't')
+ *dptr++ = '\t';
+ else
+ *dptr++ = *sptr;
+
sptr ++;
}
-
- dptr ++;
}
else
- {
- if (*sptr == 'n')
- *dptr++ = '\n';
- else if (*sptr == 'r')
- *dptr++ = '\r';
- else if (*sptr == 't')
- *dptr++ = '\t';
- else
- *dptr++ = *sptr;
-
- sptr ++;
- }
+ *dptr++ = *sptr++;
}
- else
- *dptr++ = *sptr++;
- }
- *dptr = '\0';
+ *dptr = '\0';
- // Create or add to a message...
- if (!strncmp(line, "msgid", 5))
- {
- if (id[0] && str[0])
+ // Create or add to a message...
+ if (!strncmp(line, "msgid", 5))
{
- temp = new ppdcMessage(id, str);
+ if (id[0] && str[0])
+ {
+ temp = new ppdcMessage(id, str);
- messages->add(temp);
+ messages->add(temp);
+ }
+
+ strlcpy(id, ptr, sizeof(id));
+ str[0] = '\0';
}
+ else if (!strncmp(line, "msgstr", 6))
+ {
+ if (!id[0])
+ {
+ fprintf(stderr, "ERROR: Need a msgid line before any "
+ "translation strings on line %d of %s!\n",
+ linenum, f);
+ cupsFileClose(fp);
+ return (-1);
+ }
- strlcpy(id, ptr, sizeof(id));
- str[0] = '\0';
- }
- else if (!strncmp(line, "msgstr", 6))
- {
- if (!id[0])
+ strlcpy(str, ptr, sizeof(str));
+ }
+ else if (line[0] == '\"' && str[0])
+ strlcat(str, ptr, sizeof(str));
+ else if (line[0] == '\"' && id[0])
+ strlcat(id, ptr, sizeof(id));
+ else
{
- fprintf(stderr, "load_messages: Need a msgid line before any "
- "translation strings on line %d of %s!\n",
+ fprintf(stderr, "ERROR: Unexpected text on line %d of %s!\n",
linenum, f);
cupsFileClose(fp);
return (-1);
}
-
- strlcpy(str, ptr, sizeof(str));
}
- else if (line[0] == '\"' && str[0])
- strlcat(str, ptr, sizeof(str));
- else if (line[0] == '\"' && id[0])
- strlcat(id, ptr, sizeof(id));
- else
+
+ if (id[0] && str[0])
{
- fprintf(stderr, "load_messages: Unexpected text on line %d of %s!\n",
- linenum, f);
- cupsFileClose(fp);
- return (-1);
+ temp = new ppdcMessage(id, str);
+
+ messages->add(temp);
}
}
+ else
+ goto unknown_load_format;
- if (id[0] && str[0])
- {
- temp = new ppdcMessage(id, str);
-
- messages->add(temp);
- }
+ /*
+ * Close the file and return...
+ */
cupsFileClose(fp);
return (0);
+
+ /*
+ * Unknown format error...
+ */
+
+ unknown_load_format:
+
+ fprintf(stderr, "ERROR: Unknown message catalog format for \"%s\"!\n", f);
+ cupsFileClose(fp);
+ return (-1);
}
@@ -308,55 +445,132 @@ ppdcCatalog::save_messages(
{
cups_file_t *fp; // Message file
ppdcMessage *m; // Current message
- const char *ptr; // Pointer into string
+ char *ptr; // Pointer into string
+ int utf16; // Output UTF-16 .strings file?
+ int ch; // Current character
- if ((fp = cupsFileOpen(f, "w")) == NULL)
+ // Open the file...
+ if ((ptr = strrchr(f, '.')) == NULL)
return (-1);
+ if (!strcmp(ptr, ".gz"))
+ fp = cupsFileOpen(f, "w9");
+ else
+ fp = cupsFileOpen(f, "w");
+
+ if (!fp)
+ return (-1);
+
+ // For .strings files, write a BOM for big-endian output...
+ utf16 = !strcmp(ptr, ".strings");
+
+ if (utf16)
+ put_utf16(fp, 0xfeff);
+
+ // Loop through all of the messages...
for (m = (ppdcMessage *)messages->first();
m;
m = (ppdcMessage *)messages->next())
{
- cupsFilePuts(fp, "msgid \"");
- for (ptr = m->id->value; *ptr; ptr ++)
- switch (*ptr)
- {
- case '\n' :
- cupsFilePuts(fp, "\\n");
- break;
- case '\\' :
- cupsFilePuts(fp, "\\\\");
- break;
- case '\"' :
- cupsFilePuts(fp, "\\\"");
- break;
- default :
- cupsFilePutChar(fp, *ptr);
- break;
- }
- cupsFilePuts(fp, "\"\n");
+ if (utf16)
+ {
+ put_utf16(fp, '\"');
- cupsFilePuts(fp, "msgstr \"");
- for (ptr = m->string->value; *ptr; ptr ++)
- switch (*ptr)
- {
- case '\n' :
- cupsFilePuts(fp, "\\n");
- break;
- case '\\' :
- cupsFilePuts(fp, "\\\\");
- break;
- case '\"' :
- cupsFilePuts(fp, "\\\"");
- break;
- default :
- cupsFilePutChar(fp, *ptr);
- break;
- }
- cupsFilePuts(fp, "\"\n");
+ ptr = m->id->value;
+ while ((ch = get_utf8(ptr)) != 0)
+ switch (ch)
+ {
+ case '\n' :
+ put_utf16(fp, '\\');
+ put_utf16(fp, 'n');
+ break;
+ case '\\' :
+ put_utf16(fp, '\\');
+ put_utf16(fp, '\\');
+ break;
+ case '\"' :
+ put_utf16(fp, '\\');
+ put_utf16(fp, '\"');
+ break;
+ default :
+ put_utf16(fp, ch);
+ break;
+ }
+
+ put_utf16(fp, '\"');
+ put_utf16(fp, ' ');
+ put_utf16(fp, '=');
+ put_utf16(fp, ' ');
+ put_utf16(fp, '\"');
+
+ ptr = m->string->value;
+ while ((ch = get_utf8(ptr)) != 0)
+ switch (ch)
+ {
+ case '\n' :
+ put_utf16(fp, '\\');
+ put_utf16(fp, 'n');
+ break;
+ case '\\' :
+ put_utf16(fp, '\\');
+ put_utf16(fp, '\\');
+ break;
+ case '\"' :
+ put_utf16(fp, '\\');
+ put_utf16(fp, '\"');
+ break;
+ default :
+ put_utf16(fp, ch);
+ break;
+ }
- cupsFilePutChar(fp, '\n');
+ put_utf16(fp, '\"');
+ put_utf16(fp, ';');
+ put_utf16(fp, '\n');
+ }
+ else
+ {
+ cupsFilePuts(fp, "msgid \"");
+ for (ptr = m->id->value; *ptr; ptr ++)
+ switch (*ptr)
+ {
+ case '\n' :
+ cupsFilePuts(fp, "\\n");
+ break;
+ case '\\' :
+ cupsFilePuts(fp, "\\\\");
+ break;
+ case '\"' :
+ cupsFilePuts(fp, "\\\"");
+ break;
+ default :
+ cupsFilePutChar(fp, *ptr);
+ break;
+ }
+ cupsFilePuts(fp, "\"\n");
+
+ cupsFilePuts(fp, "msgstr \"");
+ for (ptr = m->string->value; *ptr; ptr ++)
+ switch (*ptr)
+ {
+ case '\n' :
+ cupsFilePuts(fp, "\\n");
+ break;
+ case '\\' :
+ cupsFilePuts(fp, "\\\\");
+ break;
+ case '\"' :
+ cupsFilePuts(fp, "\\\"");
+ break;
+ default :
+ cupsFilePutChar(fp, *ptr);
+ break;
+ }
+ cupsFilePuts(fp, "\"\n");
+
+ cupsFilePutChar(fp, '\n');
+ }
}
cupsFileClose(fp);
@@ -366,5 +580,286 @@ ppdcCatalog::save_messages(
//
+// 'get_utf8()' - Get a UTF-8 character.
+//
+
+static int // O - Unicode character or 0 on EOF
+get_utf8(char *&ptr) // IO - Pointer to character
+{
+ int ch; // Current character
+
+
+ if ((ch = *ptr++ & 255) < 0xc0)
+ return (ch);
+
+ if ((ch & 0xe0) == 0xc0)
+ {
+ // Two-byte UTF-8...
+ if ((*ptr & 0xc0) != 0x80)
+ return (0);
+
+ ch = ((ch & 0x1f) << 6) | (*ptr++ & 0x3f);
+ }
+ else if ((ch & 0xf0) == 0xe0)
+ {
+ // Three-byte UTF-8...
+ if ((*ptr & 0xc0) != 0x80)
+ return (0);
+
+ ch = ((ch & 0x0f) << 6) | (*ptr++ & 0x3f);
+
+ if ((*ptr & 0xc0) != 0x80)
+ return (0);
+
+ ch = (ch << 6) | (*ptr++ & 0x3f);
+ }
+ else if ((ch & 0xf8) == 0xf0)
+ {
+ // Four-byte UTF-8...
+ if ((*ptr & 0xc0) != 0x80)
+ return (0);
+
+ ch = ((ch & 0x07) << 6) | (*ptr++ & 0x3f);
+
+ if ((*ptr & 0xc0) != 0x80)
+ return (0);
+
+ ch = (ch << 6) | (*ptr++ & 0x3f);
+
+ if ((*ptr & 0xc0) != 0x80)
+ return (0);
+
+ ch = (ch << 6) | (*ptr++ & 0x3f);
+ }
+
+ return (ch);
+}
+
+
+//
+// 'get_utf16()' - Get a UTF-16 character...
+//
+
+static int // O - Unicode character or 0 on EOF
+get_utf16(cups_file_t *fp, // I - File to read from
+ ppdc_cs_t &cs) // IO - Character set of file
+{
+ int ch; // Current character
+ unsigned char buffer[3]; // Bytes
+
+
+ if (cs == PPDC_CS_AUTO)
+ {
+ // Get byte-order-mark, if present...
+ if (cupsFileRead(fp, (char *)buffer, 2) != 2)
+ return (0);
+
+ if (buffer[0] == 0xfe && buffer[1] == 0xff)
+ {
+ // Big-endian UTF-16...
+ cs = PPDC_CS_UTF16BE;
+
+ if (cupsFileRead(fp, (char *)buffer, 2) != 2)
+ return (0);
+ }
+ else if (buffer[0] == 0xff && buffer[1] == 0xfe)
+ {
+ // Little-endian UTF-16...
+ cs = PPDC_CS_UTF16LE;
+
+ if (cupsFileRead(fp, (char *)buffer, 2) != 2)
+ return (0);
+ }
+ else if (buffer[0] == 0x00 && buffer[1] != 0x00)
+ {
+ // No BOM, assume big-endian UTF-16...
+ cs = PPDC_CS_UTF16BE;
+ }
+ else if (buffer[0] != 0x00 && buffer[1] == 0x00)
+ {
+ // No BOM, assume little-endian UTF-16...
+ cs = PPDC_CS_UTF16LE;
+ }
+ else
+ {
+ // No BOM, assume UTF-8...
+ cs = PPDC_CS_UTF8;
+
+ cupsFileRewind(fp);
+ }
+ }
+ else if (cs != PPDC_CS_UTF8)
+ {
+ if (cupsFileRead(fp, (char *)buffer, 2) != 2)
+ return (0);
+ }
+
+ if (cs == PPDC_CS_UTF8)
+ {
+ // UTF-8 character...
+ ch = cupsFileGetChar(fp);
+
+ if ((ch & 0xe0) == 0xc0)
+ {
+ // Two-byte UTF-8...
+ if (cupsFileRead(fp, (char *)buffer, 1) != 1)
+ return (0);
+
+ if ((buffer[0] & 0xc0) != 0x80)
+ return (0);
+
+ ch = ((ch & 0x1f) << 6) | (buffer[0] & 0x3f);
+ }
+ else if ((ch & 0xf0) == 0xe0)
+ {
+ // Three-byte UTF-8...
+ if (cupsFileRead(fp, (char *)buffer, 2) != 2)
+ return (0);
+
+ if ((buffer[0] & 0xc0) != 0x80 ||
+ (buffer[1] & 0xc0) != 0x80)
+ return (0);
+
+ ch = ((((ch & 0x0f) << 6) | (buffer[0] & 0x3f)) << 6) |
+ (buffer[1] & 0x3f);
+ }
+ else if ((ch & 0xf8) == 0xf0)
+ {
+ // Four-byte UTF-8...
+ if (cupsFileRead(fp, (char *)buffer, 3) != 3)
+ return (0);
+
+ if ((buffer[0] & 0xc0) != 0x80 ||
+ (buffer[1] & 0xc0) != 0x80 ||
+ (buffer[2] & 0xc0) != 0x80)
+ return (0);
+
+ ch = ((((((ch & 0x07) << 6) | (buffer[0] & 0x3f)) << 6) |
+ (buffer[1] & 0x3f)) << 6) | (buffer[2] & 0x3f);
+ }
+ }
+ else
+ {
+ // UTF-16 character...
+ if (cs == PPDC_CS_UTF16BE)
+ ch = (buffer[0] << 8) | buffer[1];
+ else
+ ch = (buffer[1] << 8) | buffer[0];
+
+ if (ch >= 0xd800 && ch <= 0xdbff)
+ {
+ // Handle multi-word encoding...
+ int lch;
+
+ if (cupsFileRead(fp, (char *)buffer, 2) != 2)
+ return (0);
+
+ if (cs == PPDC_CS_UTF16BE)
+ lch = (buffer[0] << 8) | buffer[1];
+ else
+ lch = (buffer[1] << 8) | buffer[0];
+
+ if (lch < 0xdc00 || lch >= 0xdfff)
+ return (0);
+
+ ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000;
+ }
+ }
+
+ return (ch);
+}
+
+
+//
+// 'put_utf8()' - Add a UTF-8 character to a string.
+//
+
+static int // O - 0 on success, -1 on failure
+put_utf8(int ch, // I - Unicode character
+ char *&ptr, // IO - String pointer
+ char *end) // I - End of buffer
+{
+ if (ch < 0x80)
+ {
+ // One-byte ASCII...
+ if (ptr >= end)
+ return (-1);
+
+ *ptr++ = ch;
+ }
+ else if (ch < 0x800)
+ {
+ // Two-byte UTF-8...
+ if ((ptr + 1) >= end)
+ return (-1);
+
+ *ptr++ = 0xc0 | (ch >> 6);
+ *ptr++ = 0x80 | (ch & 0x3f);
+ }
+ else if (ch < 0x10000)
+ {
+ // Three-byte UTF-8...
+ if ((ptr + 2) >= end)
+ return (-1);
+
+ *ptr++ = 0xe0 | (ch >> 12);
+ *ptr++ = 0x80 | ((ch >> 6) & 0x3f);
+ *ptr++ = 0x80 | (ch & 0x3f);
+ }
+ else
+ {
+ // Four-byte UTF-8...
+ if ((ptr + 3) >= end)
+ return (-1);
+
+ *ptr++ = 0xf0 | (ch >> 18);
+ *ptr++ = 0x80 | ((ch >> 12) & 0x3f);
+ *ptr++ = 0x80 | ((ch >> 6) & 0x3f);
+ *ptr++ = 0x80 | (ch & 0x3f);
+ }
+
+ return (0);
+}
+
+
+//
+// 'put_utf16()' - Write a UTF-16 character to a file.
+//
+
+static int // O - 0 on success, -1 on failure
+put_utf16(cups_file_t *fp, // I - File to write to
+ int ch) // I - Unicode character
+{
+ unsigned char buffer[4]; // Output buffer
+
+
+ if (ch < 0x10000)
+ {
+ // One-word UTF-16 big-endian...
+ buffer[0] = ch >> 8;
+ buffer[1] = ch;
+
+ if (cupsFileWrite(fp, (char *)buffer, 2) == 2)
+ return (0);
+ }
+ else
+ {
+ // Two-word UTF-16 big-endian...
+ ch -= 0x10000;
+
+ buffer[0] = 0xd8 | (ch >> 18);
+ buffer[1] = ch >> 10;
+ buffer[2] = 0xdc | ((ch >> 8) & 0x03);
+ buffer[3] = ch;
+
+ if (cupsFileWrite(fp, (char *)buffer, 4) == 4)
+ return (0);
+ }
+
+ return (-1);
+}
+
+
+//
// End of "$Id$".
//
diff --git a/ppdc/ppdmerge.cxx b/ppdc/ppdmerge.cxx
index 598b4b8d6..1db93444f 100644
--- a/ppdc/ppdmerge.cxx
+++ b/ppdc/ppdmerge.cxx
@@ -297,6 +297,7 @@ ppd_locale(ppd_file_t *ppd) // I - PPD file
} languages[] =
{
{ "chinese", "zh" },
+ { "czech", "cs" },
{ "danish", "da" },
{ "dutch", "nl" },
{ "english", "en" },
@@ -304,6 +305,7 @@ ppd_locale(ppd_file_t *ppd) // I - PPD file
{ "french", "fr" },
{ "german", "de" },
{ "greek", "el" },
+ { "hungarian", "hu" },
{ "italian", "it" },
{ "japanese", "ja" },
{ "korean", "ko" },
diff --git a/scheduler/Makefile b/scheduler/Makefile
index faea0b37d..e359e05cb 100644
--- a/scheduler/Makefile
+++ b/scheduler/Makefile
@@ -212,7 +212,6 @@ install-libs: $(INSTALLSTATIC) $(INSTALL32) $(INSTALL64)
$(LN) $(LIBCUPSMIME) $(LIBDIR)/`basename $(LIBCUPSMIME) .1`; \
fi
if test $(LIBCUPSMIME) = "libcupsmime.1.dylib"; then \
- $(STRIP) -x $(LIBDIR)/$(LIBCUPSMIME); \
$(RM) $(LIBDIR)/libcupsmime.dylib; \
$(LN) $(LIBCUPSMIME) $(LIBDIR)/libcupsmime.dylib; \
fi
diff --git a/scheduler/client.c b/scheduler/client.c
index c2d772b6a..94ddc900a 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -1450,7 +1450,9 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
break;
}
- else if (con->http.data_remaining < 0)
+ else if (con->http.data_remaining < 0 ||
+ (!con->http.fields[HTTP_FIELD_CONTENT_LENGTH][0] &&
+ con->http.data_encoding == HTTP_ENCODE_LENGTH))
{
/*
* Negative content lengths are invalid!
diff --git a/scheduler/cups-driverd.c b/scheduler/cups-driverd.c
index c9a82044d..9a199b015 100644
--- a/scheduler/cups-driverd.c
+++ b/scheduler/cups-driverd.c
@@ -1079,6 +1079,7 @@ load_ppds(const char *d, /* I - Actual directory */
} languages[] =
{
{ "chinese", "zh" },
+ { "czech", "cs" },
{ "danish", "da" },
{ "dutch", "nl" },
{ "english", "en" },
@@ -1086,6 +1087,7 @@ load_ppds(const char *d, /* I - Actual directory */
{ "french", "fr" },
{ "german", "de" },
{ "greek", "el" },
+ { "hungarian", "hu" },
{ "italian", "it" },
{ "japanese", "ja" },
{ "korean", "ko" },
@@ -1102,9 +1104,11 @@ load_ppds(const char *d, /* I - Actual directory */
if ((dir = cupsDirOpen(d)) == NULL)
{
- fprintf(stderr,
- "ERROR: [cups-driverd] Unable to open PPD directory \"%s\": %s\n",
- d, strerror(errno));
+ if (errno != ENOENT)
+ fprintf(stderr,
+ "ERROR: [cups-driverd] Unable to open PPD directory \"%s\": %s\n",
+ d, strerror(errno));
+
return (0);
}
@@ -1582,8 +1586,8 @@ load_drivers(void)
if ((dir = cupsDirOpen(drivers)) == NULL)
{
fprintf(stderr, "ERROR: [cups-driverd] Unable to open driver directory "
- "\"%s\": %s\n",
- drivers, strerror(errno));
+ "\"%s\": %s\n",
+ drivers, strerror(errno));
return (0);
}
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
index 24ee885d3..9ecca1cde 100644
--- a/scheduler/ipp.c
+++ b/scheduler/ipp.c
@@ -8970,13 +8970,13 @@ save_auth_info(
cupsFilePrintf(fp, "%s\n", line);
if (!strcmp(dest->auth_info_required[i], "username"))
- cupsdSetStringf(&job->auth_username, "CUPSD_AUTH_USERNAME=%s",
+ cupsdSetStringf(&job->auth_username, "AUTH_USERNAME=%s",
auth_info->values[i].string.text);
else if (!strcmp(dest->auth_info_required[i], "domain"))
- cupsdSetStringf(&job->auth_domain, "CUPSD_AUTH_DOMAIN=%s",
+ cupsdSetStringf(&job->auth_domain, "AUTH_DOMAIN=%s",
auth_info->values[i].string.text);
else if (!strcmp(dest->auth_info_required[i], "password"))
- cupsdSetStringf(&job->auth_password, "CUPSD_AUTH_PASSWORD=%s",
+ cupsdSetStringf(&job->auth_password, "AUTH_PASSWORD=%s",
auth_info->values[i].string.text);
}
}
@@ -8989,7 +8989,7 @@ save_auth_info(
httpEncode64_2(line, sizeof(line), con->username, strlen(con->username));
cupsFilePrintf(fp, "%s\n", line);
- cupsdSetStringf(&job->auth_username, "CUPSD_AUTH_USERNAME=%s", con->username);
+ cupsdSetStringf(&job->auth_username, "AUTH_USERNAME=%s", con->username);
cupsdClearString(&job->auth_domain);
/*
@@ -8999,7 +8999,7 @@ save_auth_info(
httpEncode64_2(line, sizeof(line), con->password, strlen(con->password));
cupsFilePrintf(fp, "%s\n", line);
- cupsdSetStringf(&job->auth_password, "CUPSD_AUTH_PASSWORD=%s", con->password);
+ cupsdSetStringf(&job->auth_password, "AUTH_PASSWORD=%s", con->password);
}
/*
diff --git a/scheduler/log.c b/scheduler/log.c
index 77ab3e5e8..698f5eb70 100644
--- a/scheduler/log.c
+++ b/scheduler/log.c
@@ -65,6 +65,13 @@ cupsdGetDateTime(time_t t) /* I - Time value */
};
+ /*
+ * Make sure we have a valid time...
+ */
+
+ if (!t)
+ t = time(NULL);
+
if (t != last_time)
{
last_time = t;
@@ -174,7 +181,7 @@ cupsdLogMessage(int level, /* I - Log level */
'd'
};
#ifdef HAVE_VSYSLOG
- static const int syslevels[] = /* SYSLOG levels... */
+ static const int syslevels[] = /* SYSLOG levels... */
{
0,
LOG_EMERG,
@@ -188,8 +195,8 @@ cupsdLogMessage(int level, /* I - Log level */
LOG_DEBUG
};
#endif /* HAVE_VSYSLOG */
- static int linesize = 0; /* Size of line for output file */
- static char *line = NULL; /* Line for output file */
+ static int linesize = 0; /* Size of line for output file */
+ static char *line = NULL; /* Line for output file */
/*
@@ -388,6 +395,7 @@ int /* O - 1 on success, 0 on error */
cupsdLogRequest(cupsd_client_t *con, /* I - Request to log */
http_status_t code) /* I - Response code */
{
+ char temp[2048]; /* Temporary string for URI */
static const char * const states[] = /* HTTP client states... */
{
"WAITING",
@@ -417,7 +425,7 @@ cupsdLogRequest(cupsd_client_t *con, /* I - Request to log */
syslog(LOG_INFO,
"REQUEST %s - %s \"%s %s HTTP/%d.%d\" %d " CUPS_LLFMT " %s %s\n",
con->http.hostname, con->username[0] != '\0' ? con->username : "-",
- states[con->operation], con->uri,
+ states[con->operation], _httpEncodeURI(temp, con->uri, sizeof(temp)),
con->http.version / 100, con->http.version % 100,
code, CUPS_LLCAST con->bytes,
con->request ?
@@ -443,7 +451,8 @@ cupsdLogRequest(cupsd_client_t *con, /* I - Request to log */
cupsFilePrintf(AccessFile,
"%s - %s %s \"%s %s HTTP/%d.%d\" %d " CUPS_LLFMT " %s %s\n",
con->http.hostname, con->username[0] != '\0' ? con->username : "-",
- cupsdGetDateTime(con->start), states[con->operation], con->uri,
+ cupsdGetDateTime(con->start), states[con->operation],
+ _httpEncodeURI(temp, con->uri, sizeof(temp)),
con->http.version / 100, con->http.version % 100,
code, CUPS_LLCAST con->bytes,
con->request ?
diff --git a/scripting/php/Makefile b/scripting/php/Makefile
index bc07028fe..09b07fb24 100644
--- a/scripting/php/Makefile
+++ b/scripting/php/Makefile
@@ -82,7 +82,7 @@ install-data:
install-exec:
echo Installing $(PHPCUPS) in $(PHPDIR)
$(INSTALL_DIR) $(PHPDIR)
- $(INSTALL_BIN) $(PHPCUPS) $(PHPDIR)
+ $(INSTALL_LIB) $(PHPCUPS) $(PHPDIR)
if test "x$(SYMROOT)" != x; then \
$(INSTALL_DIR) $(SYMROOT); \
cp $(PHPCUPS) $(SYMROOT); \
diff --git a/test/4.3-job-ops.test b/test/4.3-job-ops.test
index f086ed369..0d3a42cf8 100644
--- a/test/4.3-job-ops.test
+++ b/test/4.3-job-ops.test
@@ -159,10 +159,10 @@
}
{
# The name of the test...
- NAME "Print Image Job to Test1"
+ NAME "Hold Job on Test1"
# The operation to use
- OPERATION print-job
+ OPERATION hold-job
RESOURCE /printers/Test1
# The attributes to send
@@ -170,24 +170,22 @@
ATTR charset attributes-charset utf-8
ATTR language attributes-natural-language en
ATTR uri printer-uri $method://$hostname:$port/printers/Test1
+ ATTR integer job-id $job-id
ATTR name requesting-user-name $user
- FILE testfile.jpg
-
# What statuses are OK?
STATUS successful-ok
# What attributes do we expect?
EXPECT attributes-charset
EXPECT attributes-natural-language
- EXPECT job-id
}
{
# The name of the test...
- NAME "Hold Job on Test1"
+ NAME "Release Job on Test1"
# The operation to use
- OPERATION hold-job
+ OPERATION release-job
RESOURCE /printers/Test1
# The attributes to send
@@ -207,10 +205,10 @@
}
{
# The name of the test...
- NAME "Release Job on Test1"
+ NAME "Print Held Image Job to Test1"
# The operation to use
- OPERATION release-job
+ OPERATION print-job
RESOURCE /printers/Test1
# The attributes to send
@@ -218,8 +216,11 @@
ATTR charset attributes-charset utf-8
ATTR language attributes-natural-language en
ATTR uri printer-uri $method://$hostname:$port/printers/Test1
- ATTR integer job-id $job-id
ATTR name requesting-user-name $user
+ GROUP job
+ ATTR keyword job-hold-until indefinite
+
+ FILE testfile.jpg
# What statuses are OK?
STATUS successful-ok
@@ -227,20 +228,22 @@
# What attributes do we expect?
EXPECT attributes-charset
EXPECT attributes-natural-language
+ EXPECT job-id
}
{
# The name of the test...
- NAME "Get Job List on Test1"
+ NAME "Cancel Job"
# The operation to use
- OPERATION get-jobs
- RESOURCE /printers/Test1
+ OPERATION cancel-job
+ RESOURCE /jobs
# The attributes to send
GROUP operation
ATTR charset attributes-charset utf-8
ATTR language attributes-natural-language en
- ATTR uri printer-uri $method://$hostname:$port/printers/Test1
+ ATTR uri job-uri $method://$hostname:$port/jobs/$job-id
+ ATTR name requesting-user-name $user
# What statuses are OK?
STATUS successful-ok
@@ -251,17 +254,17 @@
}
{
# The name of the test...
- NAME "Get All Jobs"
+ NAME "Get Job List on Test1"
# The operation to use
OPERATION get-jobs
- RESOURCE /jobs
+ RESOURCE /printers/Test1
# The attributes to send
GROUP operation
ATTR charset attributes-charset utf-8
ATTR language attributes-natural-language en
- ATTR uri job-uri $method://$hostname:$port/jobs
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test1
# What statuses are OK?
STATUS successful-ok
@@ -269,24 +272,20 @@
# What attributes do we expect?
EXPECT attributes-charset
EXPECT attributes-natural-language
- EXPECT job-uri
- EXPECT job-id
- EXPECT job-state
}
{
# The name of the test...
- NAME "Cancel Job"
+ NAME "Get All Jobs"
# The operation to use
- OPERATION cancel-job
+ OPERATION get-jobs
RESOURCE /jobs
# The attributes to send
GROUP operation
ATTR charset attributes-charset utf-8
ATTR language attributes-natural-language en
- ATTR uri job-uri $method://$hostname:$port/jobs/$job-id
- ATTR name requesting-user-name $user
+ ATTR uri job-uri $method://$hostname:$port/jobs
# What statuses are OK?
STATUS successful-ok
@@ -294,6 +293,9 @@
# What attributes do we expect?
EXPECT attributes-charset
EXPECT attributes-natural-language
+ EXPECT job-uri
+ EXPECT job-id
+ EXPECT job-state
}
#
diff --git a/test/5.5-lp.sh b/test/5.5-lp.sh
index 8c340f5e5..d1928eb54 100644
--- a/test/5.5-lp.sh
+++ b/test/5.5-lp.sh
@@ -4,7 +4,7 @@
#
# Test the lp command.
#
-# Copyright 2007 by Apple Inc.
+# Copyright 2007-2008 by Apple Inc.
# Copyright 1997-2005 by Easy Software Products, all rights reserved.
#
# These coded instructions, statements, and computer programs are the
@@ -16,8 +16,8 @@
echo "LP Default Test"
echo ""
-echo " lp testfile.jpg"
-../systemv/lp testfile.jpg 2>&1
+echo " lp testfile.pdf"
+../systemv/lp testfile.pdf 2>&1
if test $? != 0; then
echo " FAILED"
exit 1
@@ -28,8 +28,20 @@ echo ""
echo "LP Destination Test"
echo ""
-echo " lp -d Test1 testfile.jpg"
-../systemv/lp -d Test1 -o job-hold-until=indefinite testfile.jpg 2>&1
+echo " lp -d Test2 testfile.jpg"
+../systemv/lp -d Test2 testfile.jpg 2>&1
+if test $? != 0; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+echo "LP Options Test"
+echo ""
+echo " lp -d Test1 -P 1-4 -o job-sheets=classified,classified testfile.pdf"
+../systemv/lp -d Test1 -P 1-4 -o job-sheets=classified,classified testfile.pdf 2>&1
if test $? != 0; then
echo " FAILED"
exit 1
@@ -38,13 +50,15 @@ else
fi
echo ""
-echo "LP Flood Test"
+echo "LP Flood Test ($1 times in parallel)"
echo ""
-echo " lp -d Test1 testfile.jpg ($1 times in parallel)"
+echo " lp -d Test1 testfile.jpg"
+echo " lp -d Test2 testfile.jpg"
i=0
while test $i -lt $1; do
echo " flood copy $i..." 1>&2
../systemv/lp -d Test1 testfile.jpg 2>&1 &
+ ../systemv/lp -d Test2 testfile.jpg 2>&1 &
lppid=$!
i=`expr $i + 1`
done
@@ -57,6 +71,8 @@ else
fi
echo ""
+./waitjobs.sh
+
#
# End of "$Id: 5.5-lp.sh 6649 2007-07-11 21:46:42Z mike $".
#
diff --git a/test/5.6-lpr.sh b/test/5.6-lpr.sh
index 1de750fac..a1fe01d35 100644
--- a/test/5.6-lpr.sh
+++ b/test/5.6-lpr.sh
@@ -4,7 +4,7 @@
#
# Test the lpr command.
#
-# Copyright 2007 by Apple Inc.
+# Copyright 2007-2008 by Apple Inc.
# Copyright 1997-2005 by Easy Software Products, all rights reserved.
#
# These coded instructions, statements, and computer programs are the
@@ -16,8 +16,8 @@
echo "LPR Default Test"
echo ""
-echo " lpr testfile.jpg"
-../berkeley/lpr testfile.jpg 2>&1
+echo " lpr testfile.pdf"
+../berkeley/lpr testfile.pdf 2>&1
if test $? != 0; then
echo " FAILED"
exit 1
@@ -28,8 +28,20 @@ echo ""
echo "LPR Destination Test"
echo ""
-echo " lpr -P Test1 testfile.jpg"
-../berkeley/lpr -P Test1 testfile.jpg 2>&1
+echo " lpr -P Test2 testfile.jpg"
+../berkeley/lpr -P Test2 testfile.jpg 2>&1
+if test $? != 0; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+echo "LPR Options Test"
+echo ""
+echo " lpr -P Test1 -o number-up=4 -o job-sheets=standard,none testfile.pdf"
+../berkeley/lpr -P Test1 -o number-up=4 -o job-sheets=standard,none testfile.pdf 2>&1
if test $? != 0; then
echo " FAILED"
exit 1
@@ -38,13 +50,15 @@ else
fi
echo ""
-echo "LPR Flood Test"
+echo "LPR Flood Test ($1 times in parallel)"
echo ""
-echo " lpr -P Test1 testfile.jpg ($1 times in parallel)"
+echo " lpr -P Test1 testfile.jpg"
+echo " lpr -P Test2 testfile.jpg"
i=0
while test $i -lt $1; do
echo " flood copy $i..." 1>&2
../berkeley/lpr -P Test1 testfile.jpg 2>&1 &
+ ../berkeley/lpr -P Test2 testfile.jpg 2>&1 &
lprpid=$!
i=`expr $i + 1`
done
@@ -57,6 +71,8 @@ else
fi
echo ""
+./waitjobs.sh
+
#
# End of "$Id: 5.6-lpr.sh 6649 2007-07-11 21:46:42Z mike $".
#
diff --git a/test/5.7-lprm.sh b/test/5.7-lprm.sh
index f2848ed84..fe323db15 100644
--- a/test/5.7-lprm.sh
+++ b/test/5.7-lprm.sh
@@ -16,6 +16,8 @@
echo "LPRM Current Test"
echo ""
+echo " lpr -o job-hold-until=indefinite testfile.jpg"
+../berkeley/lpr -o job-hold-until=indefinite testfile.jpg 2>&1
echo " lprm"
../berkeley/lprm 2>&1
if test $? != 0; then
@@ -28,6 +30,8 @@ echo ""
echo "LPRM Destination Test"
echo ""
+echo " lpr -P Test1 -o job-hold-until=indefinite testfile.jpg"
+../berkeley/lpr -P Test1 -o job-hold-until=indefinite testfile.jpg 2>&1
echo " lprm Test1"
../berkeley/lprm Test1 2>&1
if test $? != 0; then
diff --git a/test/5.8-cancel.sh b/test/5.8-cancel.sh
index 9212d4387..90a688d52 100644
--- a/test/5.8-cancel.sh
+++ b/test/5.8-cancel.sh
@@ -4,7 +4,7 @@
#
# Test the cancel command.
#
-# Copyright 2007 by Apple Inc.
+# Copyright 2007-2008 by Apple Inc.
# Copyright 1997-2006 by Easy Software Products, all rights reserved.
#
# These coded instructions, statements, and computer programs are the
@@ -16,6 +16,8 @@
echo "Cancel Destination Test"
echo ""
+echo " lp -d Test1 -o job-hold-until=indefinite testfile.jpg"
+../systemv/lp -d Test1 -o job-hold-until=indefinite testfile.jpg 2>&1
echo " cancel Test1"
../systemv/cancel Test1 2>&1
if test $? != 0; then
diff --git a/test/run-stp-tests.sh b/test/run-stp-tests.sh
index ba5184cff..c9e5d28d2 100755
--- a/test/run-stp-tests.sh
+++ b/test/run-stp-tests.sh
@@ -5,7 +5,7 @@
# Perform the complete set of IPP compliance tests specified in the
# CUPS Software Test Plan.
#
-# Copyright 2007 by Apple Inc.
+# Copyright 2007-2008 by Apple Inc.
# Copyright 1997-2007 by Easy Software Products, all rights reserved.
#
# These coded instructions, statements, and computer programs are the
@@ -97,7 +97,7 @@ case "$testtype" in
echo "Running the timid tests (1)"
nprinters1=0
nprinters2=0
- pjobs=0
+ pjobs=10
;;
esac
@@ -207,6 +207,7 @@ rm -rf /tmp/cups-$user
mkdir /tmp/cups-$user
mkdir /tmp/cups-$user/bin
mkdir /tmp/cups-$user/bin/backend
+mkdir /tmp/cups-$user/bin/driver
mkdir /tmp/cups-$user/bin/filter
mkdir /tmp/cups-$user/certs
mkdir /tmp/cups-$user/share
@@ -228,17 +229,15 @@ ln -s $root/backend/snmp /tmp/cups-$user/bin/backend
ln -s $root/backend/socket /tmp/cups-$user/bin/backend
ln -s $root/backend/usb /tmp/cups-$user/bin/backend
ln -s $root/cgi-bin /tmp/cups-$user/bin
+ln -s $root/ppdc/drv /tmp/cups-$user/bin/driver
ln -s $root/monitor /tmp/cups-$user/bin
ln -s $root/notifier /tmp/cups-$user/bin
ln -s $root/scheduler /tmp/cups-$user/bin/daemon
ln -s $root/filter/hpgltops /tmp/cups-$user/bin/filter
-ln -s $root/filter/imagetops /tmp/cups-$user/bin/filter
-ln -s $root/filter/imagetoraster /tmp/cups-$user/bin/filter
ln -s $root/filter/pstops /tmp/cups-$user/bin/filter
ln -s $root/filter/rastertoepson /tmp/cups-$user/bin/filter
ln -s $root/filter/rastertohp /tmp/cups-$user/bin/filter
ln -s $root/filter/texttops /tmp/cups-$user/bin/filter
-ln -s $root/filter/pdftops /tmp/cups-$user/bin/filter
ln -s $root/data/classified /tmp/cups-$user/share/banners
ln -s $root/data/confidential /tmp/cups-$user/share/banners
@@ -272,9 +271,12 @@ if test `uname` = Darwin; then
ln -s /usr/libexec/cups/filter/pstopdffilter /tmp/cups-$user/bin/filter
ln -s /private/etc/cups/apple.* /tmp/cups-$user
+else
+ ln -s $root/filter/imagetops /tmp/cups-$user/bin/filter
+ ln -s $root/filter/imagetoraster /tmp/cups-$user/bin/filter
+ ln -s $root/filter/pdftops /tmp/cups-$user/bin/filter
fi
-
#
# Then create the necessary config files...
#
@@ -430,11 +432,6 @@ echo ""
$valgrind ../scheduler/cupsd -c /tmp/cups-$user/cupsd.conf -f >/tmp/cups-$user/log/debug_log 2>&1 &
cupsd=$!
-#if test -x /usr/bin/strace; then
-# # Trace system calls in cupsd if we have strace...
-# /usr/bin/strace -tt -o /tmp/cups-$user/log/cupsd.trace -p $cupsd &
-#fi
-
if test "x$testtype" = x0; then
echo "Scheduler is PID $cupsd and is listening on port 8631."
echo ""
@@ -469,7 +466,7 @@ done
# Create the test report source file...
#
-strfile=cups-str-1.4-`date +%Y-%m-%d`-$user.html
+strfile=/tmp/cups-$user/cups-str-1.4-`date +%Y-%m-%d`-$user.html
rm -f $strfile
cat str-header.html >$strfile
@@ -492,7 +489,7 @@ for file in 4*.test; do
echo "Performing $file..."
echo "" >>$strfile
- ./ipptest ipp://localhost:$port/printers $file >>$strfile
+ ./ipptest ipp://localhost:$port/printers $file | tee -a $strfile
status=$?
if test $status != 0; then
@@ -521,7 +518,7 @@ for file in 5*.sh; do
echo "" >>$strfile
echo "\"$file\":" >>$strfile
- sh $file $pjobs >>$strfile
+ sh $file $pjobs | tee -a $strfile
status=$?
if test $status != 0; then
@@ -533,20 +530,6 @@ done
echo "</PRE>" >>$strfile
#
-# Wait for jobs to complete...
-#
-
-while true; do
- jobs=`../systemv/lpstat 2>/dev/null`
- if test "x$jobs" = "x"; then
- break
- fi
-
- echo "Waiting for jobs to complete..."
- sleep 10
-done
-
-#
# Stop the server...
#
@@ -558,28 +541,182 @@ kill $cupsd
echo "<H1>3 - Log Files</H1>" >>$strfile
+#
+# Verify counts...
+#
+
+echo "Test Summary"
+echo ""
+echo "<H2>Summary</H2>" >>$strfile
+
+# Pages printed on Test1
+count=`grep '^Test1 ' /tmp/cups-$user/log/page_log | awk 'BEGIN{count=0}{count=count+$7}END{print count}'`
+expected=`expr $pjobs \* 2 + 35`
+if test $count != $expected; then
+ echo "FAIL: Printer 'Test1' produced $count page(s), expected $expected."
+ echo "<P>FAIL: Printer 'Test1' produced $count page(s), expected $expected.</P>" >>$strfile
+ fail=`expr $fail + 1`
+else
+ echo "PASS: Printer 'Test1' correctly produced $count page(s)."
+ echo "<P>PASS: Printer 'Test1' correctly produced $count page(s).</P>" >>$strfile
+fi
+
+# Paged printed on Test2
+count=`grep '^Test2 ' /tmp/cups-$user/log/page_log | awk 'BEGIN{count=0}{count=count+$7}END{print count}'`
+expected=`expr $pjobs \* 2 + 3`
+if test $count != $expected; then
+ echo "FAIL: Printer 'Test2' produced $count page(s), expected $expected."
+ echo "<P>FAIL: Printer 'Test2' produced $count page(s), expected $expected.</P>" >>$strfile
+ fail=`expr $fail + 1`
+else
+ echo "PASS: Printer 'Test2' correctly produced $count page(s)."
+ echo "<P>PASS: Printer 'Test2' correctly produced $count page(s).</P>" >>$strfile
+fi
+
+# Requested processed
+count=`wc -l /tmp/cups-$user/log/access_log | awk '{print $1}'`
+echo "PASS: $count requests processed."
+echo "<P>PASS: $count requests processed.</P>" >>$strfile
+
+# Emergency log messages
+count=`grep '^X ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'`
+if test $count != 0; then
+ echo "FAIL: $count emergency messages, expected 0."
+ grep '^X ' /tmp/cups-$user/log/error_log
+ echo "<P>FAIL: $count emergency messages, expected 0.</P>" >>$strfile
+ echo "<PRE>" >>$strfile
+ grep '^X ' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
+ echo "</PRE>" >>$strfile
+ fail=`expr $fail + 1`
+else
+ echo "PASS: $count emergency messages."
+ echo "<P>PASS: $count emergency messages.</P>" >>$strfile
+fi
+
+# Alert log messages
+count=`grep '^A ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'`
+if test $count != 0; then
+ echo "FAIL: $count alert messages, expected 0."
+ grep '^A ' /tmp/cups-$user/log/error_log
+ echo "<P>FAIL: $count alert messages, expected 0.</P>" >>$strfile
+ echo "<PRE>" >>$strfile
+ grep '^A ' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
+ echo "</PRE>" >>$strfile
+ fail=`expr $fail + 1`
+else
+ echo "PASS: $count alert messages."
+ echo "<P>PASS: $count alert messages.</P>" >>$strfile
+fi
+
+# Critical log messages
+count=`grep '^C ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'`
+if test $count != 0; then
+ echo "FAIL: $count critical messages, expected 0."
+ grep '^C ' /tmp/cups-$user/log/error_log
+ echo "<P>FAIL: $count critical messages, expected 0.</P>" >>$strfile
+ echo "<PRE>" >>$strfile
+ grep '^C ' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
+ echo "</PRE>" >>$strfile
+ fail=`expr $fail + 1`
+else
+ echo "PASS: $count critical messages."
+ echo "<P>PASS: $count critical messages.</P>" >>$strfile
+fi
+
+# Error log messages
+count=`grep '^E ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'`
+if test $count != 9; then
+ echo "FAIL: $count error messages, expected 9."
+ grep '^E ' /tmp/cups-$user/log/error_log
+ echo "<P>FAIL: $count error messages, expected 9.</P>" >>$strfile
+ echo "<PRE>" >>$strfile
+ grep '^E ' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
+ echo "</PRE>" >>$strfile
+ fail=`expr $fail + 1`
+else
+ echo "PASS: $count error messages."
+ echo "<P>PASS: $count error messages.</P>" >>$strfile
+fi
+
+# Warning log messages
+count=`grep '^W ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'`
+if test $count != 0; then
+ echo "FAIL: $count warning messages, expected 0."
+ grep '^W ' /tmp/cups-$user/log/error_log
+ echo "<P>FAIL: $count warning messages, expected 0.</P>" >>$strfile
+ echo "<PRE>" >>$strfile
+ grep '^W ' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
+ echo "</PRE>" >>$strfile
+ fail=`expr $fail + 1`
+else
+ echo "PASS: $count warning messages."
+ echo "<P>PASS: $count warning messages.</P>" >>$strfile
+fi
+
+# Notice log messages
+count=`grep '^N ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'`
+if test $count != 0; then
+ echo "FAIL: $count notice messages, expected 0."
+ grep '^N ' /tmp/cups-$user/log/error_log
+ echo "<P>FAIL: $count notice messages, expected 0.</P>" >>$strfile
+ echo "<PRE>" >>$strfile
+ grep '^N ' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
+ echo "</PRE>" >>$strfile
+ fail=`expr $fail + 1`
+else
+ echo "PASS: $count notice messages."
+ echo "<P>PASS: $count notice messages.</P>" >>$strfile
+fi
+
+# Info log messages
+count=`grep '^I ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'`
+if test $count = 0; then
+ echo "FAIL: $count info messages, expected more than 0."
+ echo "<P>FAIL: $count info messages, expected more than 0.</P>" >>$strfile
+ fail=`expr $fail + 1`
+else
+ echo "PASS: $count info messages."
+ echo "<P>PASS: $count info messages.</P>" >>$strfile
+fi
+
+# Debug log messages
+count=`grep '^D ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'`
+if test $count = 0; then
+ echo "FAIL: $count debug messages, expected more than 0."
+ echo "<P>FAIL: $count debug messages, expected more than 0.</P>" >>$strfile
+ fail=`expr $fail + 1`
+else
+ echo "PASS: $count debug messages."
+ echo "<P>PASS: $count debug messages.</P>" >>$strfile
+fi
+
+# Debug2 log messages
+count=`grep '^d ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'`
+if test $count != 0; then
+ echo "FAIL: $count debug2 messages, expected 0."
+ echo "<P>FAIL: $count debug2 messages, expected 0.</P>" >>$strfile
+ fail=`expr $fail + 1`
+else
+ echo "PASS: $count debug2 messages."
+ echo "<P>PASS: $count debug2 messages.</P>" >>$strfile
+fi
+
+# Log files...
echo "<H2>access_log</H2>" >>$strfile
echo "<PRE>" >>$strfile
-cat /tmp/cups-$user/log/access_log >>$strfile
+sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' /tmp/cups-$user/log/access_log >>$strfile
echo "</PRE>" >>$strfile
echo "<H2>error_log</H2>" >>$strfile
echo "<PRE>" >>$strfile
-cat /tmp/cups-$user/log/error_log >>$strfile
+sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' /tmp/cups-$user/log/error_log >>$strfile
echo "</PRE>" >>$strfile
echo "<H2>page_log</H2>" >>$strfile
echo "<PRE>" >>$strfile
-cat /tmp/cups-$user/log/page_log >>$strfile
+sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' /tmp/cups-$user/log/page_log >>$strfile
echo "</PRE>" >>$strfile
-if test -f /tmp/cups-$user/log/cupsd.trace; then
- echo "<H2>cupsd.trace</H2>" >>$strfile
- echo "<PRE>" >>$strfile
- cat /tmp/cups-$user/log/cupsd.trace >>$strfile
- echo "</PRE>" >>$strfile
-fi
-
#
# Format the reports and tell the user where to find them...
#
@@ -595,7 +732,7 @@ else
fi
echo "Log files can be found in /tmp/cups-$user/log."
-echo "A HTML report was created in test/$strfile."
+echo "A HTML report was created in $strfile."
echo ""
if test $fail != 0; then
diff --git a/test/str-header.html b/test/str-header.html
index ec06860c2..a584063e8 100644
--- a/test/str-header.html
+++ b/test/str-header.html
@@ -1,18 +1,24 @@
<HTML>
<HEAD>
<META NAME="Description" CONTENT="Common UNIX Printing System Software Test Report">
- <META NAME="COPYRIGHT" CONTENT="Copyright 2007, All Rights Reserved">
- <META NAME="DOCNUMBER" CONTENT="CUPS-STR-1.3">
+ <META NAME="COPYRIGHT" CONTENT="Copyright 2007-2008, All Rights Reserved">
+ <META NAME="DOCNUMBER" CONTENT="CUPS-STR-1.4">
<META NAME="Author" CONTENT="Apple Inc.">
- <TITLE>CUPS 1.3 Software Test Report</TITLE>
+ <TITLE>CUPS 1.4 Software Test Report</TITLE>
+ <STYLE TYPE="text/css"><!--
+ PRE {
+ font-size: 80%;
+ margin-left: 2em;
+ }
+ --></STYLE>
</HEAD>
<BODY>
-<H1>CUPS 1.3 Software Test Report</H1>
+<H1>CUPS 1.4 Software Test Report</H1>
<P>This software test report provides detailed test results that
are used to evaluate the stability and compliance of the Common
-UNIX Printing System ("CUPS") Version 1.3.
+UNIX Printing System ("CUPS") Version 1.4.
<H2>Document Overview</H2>
diff --git a/test/waitjobs.sh b/test/waitjobs.sh
new file mode 100755
index 000000000..d69e44080
--- /dev/null
+++ b/test/waitjobs.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+#
+# "$Id$"
+#
+# Script to wait for jobs to complete.
+#
+# Copyright 2008 by Apple Inc.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Apple Inc. and are protected by Federal copyright
+# law. Distribution and use rights are outlined in the file "LICENSE.txt"
+# 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/".
+#
+
+# Get timeout from command-line
+if test $# = 1; then
+ timeout=$1
+else
+ timeout=60
+fi
+
+echo "Waiting for jobs to complete..."
+
+while test $timeout -gt 0; do
+ jobs=`../systemv/lpstat 2>/dev/null`
+ if test "x$jobs" = "x"; then
+ break
+ fi
+
+ sleep 5
+ timeout=`expr $timeout - 5`
+done
+
+#
+# End of "$Id$".
+#
diff --git a/tools/testosx b/tools/testosx
index 13bf53da1..918e7a41c 100755
--- a/tools/testosx
+++ b/tools/testosx
@@ -105,7 +105,7 @@ done
# Install CUPS into the Package directory...
#make INSTALL=$topdir/install-sh BUILDROOT=$pkgdir/Package install
-make BUILDROOT=$pkgdir/Package install
+make BUILDROOT=$pkgdir/Package install || exit 1
# Figure out where PackageMaker is installled...
if test -d /Developer/Applications/Utilities/PackageMaker.app; then