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
-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
-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
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
RMDIR = @RMDIR@
SED = @SED@
SHELL = /bin/sh
-STRIP = @STRIP@
+
#
# Installation programs...
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; \
*/
if (busy)
- {
_cupsLangPuts(stderr,
_("INFO: Printer busy; will retry in 5 seconds...\n"));
- sleep(5);
- }
+
+ sleep(5);
}
}
#elif defined(__sun) && defined(ECPPIOC_GETDEVID)
$(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
return;
}
+ /*
+ * Make sure we have a username...
+ */
+
+ if ((user = getenv("REMOTE_USER")) == NULL)
+ {
+ puts("Status: 401\n");
+ exit(0);
+ }
+
/*
* Validate the subscription name...
*/
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);
return;
}
+ /*
+ * Require a username...
+ */
+
+ if ((user = getenv("REMOTE_USER")) == NULL)
+ {
+ puts("Status: 401\n");
+ exit(0);
+ }
+
/*
* Cancel the subscription...
*/
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);
* 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)
{
</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 $".
#
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)
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.])
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"
LDARCHFLAGS="$ARCHFLAGS"
fi
else
- LDARCHFLAGS="$with_archflags"
+ LDARCHFLAGS="$with_ldarchflags"
fi
AC_SUBST(ARCHFLAGS)
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
# 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
$(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
if (have_drivers == 0)
{
_cupsSetError(IPP_NOT_FOUND, message);
+
+ unlink(authfile);
+
return (0);
}
# 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_ */
/*
* 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.
*/
#endif /* !HAVE_HSTRERROR */
+/*
+ * '_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.
*/
*dst++ = *src++;
}
+ *dst = '\0';
+
if (*src)
return (NULL);
else
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,
"TRACE",
"CLOSE"
};
- static const char hex[] = "0123456789ABCDEF";
- /* Hex digits */
DEBUG_printf(("http_send(http=%p, request=HTTP_%s, uri=\"%s\")\n",
* 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...
__cupsStrFree
__cupsStrScand
__cupsStrStatistics
+__httpEncodeURI
__httpReadCDSA
__httpWriteCDSA
__ippAddAttr
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);
*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"
<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>
<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>
<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>
$(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
* Include necessary headers...
*/
-#include "string.h"
+#include <cups/string.h>
#include "data/pcl.h"
*
* 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
* 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
#include "driver.h"
#include <cups/string.h>
#include "data/escp.h"
+#include <signal.h>
/*
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? */
/*
*/
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);
/*
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 */
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 */
}
+/*
+ * 'CancelJob()' - Cancel the current job...
+ */
+
+void
+CancelJob(int sig) /* I - Signal */
+{
+ (void)sig;
+
+ Canceled = 1;
+}
+
+
/*
* 'CompressData()' - Compress a line of graphics.
*/
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 */
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 */
{
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 */
/*
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...
*/
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);
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);
*
* 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.
#include "driver.h"
#include "pcl-common.h"
+#include <signal.h>
/*
{ 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);
/*
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 */
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 */
}
+/*
+ * 'CancelJob()' - Cancel the current job...
+ */
+
+void
+CancelJob(int sig) /* I - Signal */
+{
+ (void)sig;
+
+ Canceled = 1;
+}
+
+
/*
* 'CompressData()' - Compress a line of graphics.
*/
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 */
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 */
{
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 */
/*
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...
*/
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);
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);
$(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
#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];
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)
*
* 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
* 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...
*/
#include <cups/i18n.h>
#include <signal.h>
#include <sys/wait.h>
+#include <errno.h>
/*
static void cancel_job(int sig);
+/*
+ * Local globals...
+ */
+
+static int job_canceled = 0;
+
+
/*
* 'main()' - Main entry for filter...
*/
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 */
* 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;
{
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);
}
}
cancel_job(int sig) /* I - Signal number (unused) */
{
(void)sig;
+
+ job_canceled = 1;
}
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? */
/*
*/
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);
/*
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.
*/
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 */
putchar(12); /* Form feed */
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...
*/
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;
}
*/
void
-OutputLine(const cups_page_header_t *header) /* I - Page header */
+OutputLine(const cups_page_header2_t *header) /* I - Page header */
{
if (header->cupsRowCount)
{
*/
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 */
* '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 */
/*
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...
*/
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);
* 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);
*/
EndPage(&header);
+
+ if (Canceled)
+ break;
}
/*
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? */
/*
*/
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);
/*
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...
*/
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...
*/
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...
*/
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;
}
*/
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 */
* '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 */
/*
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...
*/
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);
* 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);
*/
EndPage();
+
+ if (Canceled)
+ break;
}
/*
*
* 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
*/
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);
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 */
/*
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 :
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 */
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...
*/
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 */
{
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 */
/*
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...
*/
* 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);
* 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);
# 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
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
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
:
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.$$#
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.
.\"
.\" 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
.\" 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
]
.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 $".
.\"
$(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
#include <cups/globals.h>
+//
+// 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.
//
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);
}
{
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);
}
+//
+// '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$".
//
} languages[] =
{
{ "chinese", "zh" },
+ { "czech", "cs" },
{ "danish", "da" },
{ "dutch", "nl" },
{ "english", "en" },
{ "french", "fr" },
{ "german", "de" },
{ "greek", "el" },
+ { "hungarian", "hu" },
{ "italian", "it" },
{ "japanese", "ja" },
{ "korean", "ko" },
$(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
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!
} languages[] =
{
{ "chinese", "zh" },
+ { "czech", "cs" },
{ "danish", "da" },
{ "dutch", "nl" },
{ "english", "en" },
{ "french", "fr" },
{ "german", "de" },
{ "greek", "el" },
+ { "hungarian", "hu" },
{ "italian", "it" },
{ "japanese", "ja" },
{ "korean", "ko" },
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);
}
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);
}
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);
}
}
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);
/*
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);
}
/*
};
+ /*
+ * Make sure we have a valid time...
+ */
+
+ if (!t)
+ t = time(NULL);
+
if (t != last_time)
{
last_time = t;
'd'
};
#ifdef HAVE_VSYSLOG
- static const int syslevels[] = /* SYSLOG levels... */
+ static const int syslevels[] = /* SYSLOG levels... */
{
0,
LOG_EMERG,
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 */
/*
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",
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 ?
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 ?
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); \
}
{
# 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
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
}
{
# 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
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
# 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
}
{
# 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
# 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
# What attributes do we expect?
EXPECT attributes-charset
EXPECT attributes-natural-language
+ EXPECT job-uri
+ EXPECT job-id
+ EXPECT job-state
}
#
#
# 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
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
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
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
fi
echo ""
+./waitjobs.sh
+
#
# End of "$Id: 5.5-lp.sh 6649 2007-07-11 21:46:42Z mike $".
#
#
# 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
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
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
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
fi
echo ""
+./waitjobs.sh
+
#
# End of "$Id: 5.6-lpr.sh 6649 2007-07-11 21:46:42Z mike $".
#
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
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
#
# 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
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
# 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
echo "Running the timid tests (1)"
nprinters1=0
nprinters2=0
- pjobs=0
+ pjobs=10
;;
esac
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
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
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...
#
$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 ""
# 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
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
echo "" >>$strfile
echo "\"$file\":" >>$strfile
- sh $file $pjobs >>$strfile
+ sh $file $pjobs | tee -a $strfile
status=$?
if test $status != 0; then
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...
#
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/&/&/g' -e '1,$s/</</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/&/&/g' -e '1,$s/</</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/&/&/g' -e '1,$s/</</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/&/&/g' -e '1,$s/</</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/&/&/g' -e '1,$s/</</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/&/&/g' -e '1,$s/</</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/&/&/g' -e '1,$s/</</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/&/&/g' -e '1,$s/</</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/&/&/g' -e '1,$s/</</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...
#
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
<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>
--- /dev/null
+#!/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$".
+#
# 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