From: mike Date: Wed, 26 Dec 2001 16:52:58 +0000 (+0000) Subject: Merge changes from 1.1.x into 1.2 devel. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=753453e49d278582de7dd6250842259ed620b0b4;p=thirdparty%2Fcups.git Merge changes from 1.1.x into 1.2 devel. git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/branches/branch-1.2@1981 7a7537e8-13f0-0310-91df-b6672ffda945 --- diff --git a/CHANGES.txt b/CHANGES.txt index bafb94a85c..5fbf7f170a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,453 @@ -CHANGES.txt - 05/07/2001 +CHANGES.txt - 12/26/2001 ------------------------ +CHANGES IN CUPS V1.2.0a1 + + +CHANGES IN CUPS V1.1.13 + + - The cups-lpd mini-daemon now supports LPD clients that + send multiple control files. + - httpConnectEncrypt() now always uses encryption for + connections on port 443, since port 443 is reserved + for the "https" scheme. + - Group authentication via certificates did not work + from the web interface for accounts other than + "root". + - The serial port backend did not clear the OPOST + option, which could cause problems with some printers. + - The cups-lpd mini-daemon didn't lookup the client IP + address properly. + - The parallel backend now identifies the polled and + interrupt-driven devices under *BSD. + - The scheduler allowed the "always" encryption mode + inside a Location, which is not valid. + - The CUPS startup script now checks for the timezone + information under Linux. + - Now also map the sides attribute to the JCLDuplex + option (if present) in PPD files. + - Updated pdftops to Xpdf 0.93a. + - Added support for MD5 passwords under Slackware. + - Added new AuthType BasicDigest that does Basic + authentication using the MD5 password file managed by + the lppasswd command. + - The banner page attribute substitution code now + retains {name} sequences in banner files when the + named attribute is undefined. Use {?name} to + conditionally substitute an IPP attribute. + - The scheduler now ensures that the ServerRoot + directory and configuration files are owned by and + writable by the User and Group in cupsd.conf. + - The USB backend now lists all USB printer devices + regardless of whether a printer is connected or not. + This allows new USB printers to be connected without + restarting cupsd. + - Added some more minor performance tweeks to the IPP + protocol code to reduce copying and array indexing. + - The cupsaddsmb utility now uses the -c option with + smbclient and rpcclient to avoid the read length limit + for commands on the standard input. + - Added an include file to the CRD handling code in + pstoraster so that it would compile properly on 64-bit + pointer platforms... + + +CHANGES IN CUPS V1.1.12 + + - Added "Polish" to the list of known languages for PPD + files. + - Added missing directory definition to cups-config. + - The CUPS-Move-Job operation did not set the + destination type for the new destination. + - The CUPS-Add-Printer operation did not support the + allow=all or deny=none values to clear the per-user + printer ACLs. + - The SetPrinterAttrs() function did not handle invalid + PPD files that were missing the required NickName + attribute. It now looks for NickName, ModelName, and + then substitutes the string "Bad PPD File" for the + printer-make-and-model attribute. + + +CHANGES IN CUPS V1.1.11 + + - Added support for embedded TrueType fonts in PDF + files. + - Added support for PostScript functions in PDF + files. + - Added new "cupsaddsmb" utility for exporting + CUPS printer drivers to SAMBA/Windows clients. + - Added preliminary support for Darwin/MacOS X. + - The CUPS-Add-Printer operation no longer allows + arbitrary scheme names in device URIs to be used - it + now restricts the available schemes to those found in + the device list (lpinfo -m). + - The ippRead() and ipp_read_file() functions could not + handle more than IPP_MAX_VALUES (100) values in a + 1setOf attribute. These functions have been updated + to dynamically allocate more memory as needed, and the + IPP_MAX_VALUES constant now represents the allocation + increment. [this caused some versions of the + GIMP-print drivers to fail since the number of media + options exceeded 100...] + - The scheduler could crash when BrowseShortNames + was set to "No". + - The scheduler did not prevent MaxClients from being + set to 0, which could cause the scheduler to go in an + infinite loop when accepting a request. + - Made some performance optimizations in the ippRead() + functions to make IPP request/response processing + faster. + - The accept/reject/enable/disable command did not + support properly support the "-h" or default + server name. + - The scheduler did not save the quota configuration + when the job-quota-period attribute was set to 0. + - The LPDEST and PRINTER environment variables did not + support printer instances. + - The text filter now handles more types of boldface and + underline formatting. + - The cupsTempFd() function did not fail if the + temporary directory did not exist; this would cause it + to loop indefinitely instead of returning an error + (-1). + - Stopping (disabling) a printer class did not stop jobs + from printing to printers in that class. + - The cupsGetDests() function was sending the + requested-attributes attribute as a name instead of a + keyword; this caused a serious performance problem on + slower systems since more information had to be + transferred from server to client. + - The web interfaces did not always quote < and & in + things like the job title. This had the potential for + browser-based security violations (on the browser's + machine); bug report from SuSE. + - The scheduler now treats unauthenticated usernames as + case-insensitive when doing quota and allow/deny + processing. + - The lp command sent the "request ID is ..." message + to stderr instead of stdout... + - The PostScript filter (pstops) now handles EPS files, + adding a showpage command to the files as needed. + - The configure script checked for the header + file before the JPEG libraries; since the JPEG headers + can define HAVE_STDLIB_H, the configure check would + cause the JPEG check to fail on some systems. + - The scheduler now supports localized banner files, + using the subdirectory approach, e.g. the "es" + subdirectory under /usr/share/cups/banners is used for + the Spanish banner files. + - Updated the scheduler so it knows the correct + language abbreviation to use for all supported + PPD LanguageVersion values. The new code also + supports country codes as well, so "English-GB" + maps to the "en_GB" locale. + - The cups-lpd mini-daemon did not support + anonymous printing (no username specified). + While the username is REQUIRED by RFC-1179, + MacOS clients do not send the REQUIRED username + information when printing via LPD. + - Added many warning and informational messages + to cups-lpd where they were missing. + - Added Czech message file contributed by SuSE. + - The cups-lpd mini-daemon now returns a non-zero + status if an invalid destination or job ID is + provided. + - The scheduler did not honor the KeepAlive setting in + cupsd.conf. + - Increased the size of the file read/write buffers to + 32k. + - *BSD static library creation fixes. + - Use mkstemps() instead of tmpnam() in pdftops whenever + possible. + - Added httpGetHostByName() function as a wrapper around + gethostbyname() - some implementations of this + function do not support IP addresses (e.g. MacOS X.) + - Added casts to all printf's of file lengths, since + there is currently no standard way of formatting long + long values. + - The client filename field was not cleared in all + instances, resulting in old form data being submitted + to CGIs. + - The httpConnect*() functions now try all available + addresses for a host when connecting for the first + time. + - The pstoraster filter would "lose" all drawing + commands when the PageSize was set but the printer + bitmap was not reallocated. This was most noticeable + with the output from StarOffice 6 beta and would + result in a blank page being output... + - The IPP backend was sending a PAGE comment even when + printing the output from a filter (it should only send + page comments when printing files directly...) + - The pdftops filter didn't properly map glyph names of + embedded Asian TrueType fonts. + - Changed the CUPS startup script to look for a program + named "cupsd", not just any program with "cupsd" in + the name (this caused the apcupsd UPS monitoring + daemon to be stopped/restarted...) + - The CUPS-Move-Job operation did not change the + internal destination name for held jobs, so moved (but + held) jobs would still show up as queued on the + original destination. + - The cups-polld program didn't send the + requested-attributes attribute in the + CUPS-Get-Printers and CUPS-Get-Classes requests, which + made it use more CPU and bandwidth than required. + - The scheduler and CUPS API incorrectly added a + job-sheets-default attribute for remote printers. This + caused banner pages to be omitted from client system + prints. + + +CHANGES IN CUPS V1.1.10-1 + + - Minor fixes to the filter, systemv, and template + makefiles to install files properly. + + +CHANGES IN CUPS V1.1.10 + + - Added a driver for DYMO label printers. + - Added new ClassifyOverride directive to allow users + to override the classification of individual jobs. + - Added new BrowseProtocols directive to control which + browse protocols are used (currently CUPS and SLP). + - Added SLPv2 support (thanks to Matt Peterson for + contributing the initial implementation for CUPS.) + - Adding a raw printer on a remote CUPS server now + correctly redirects PPD file requests to the remote + server. + - The serial backend now limits writes to 1/10th + second worth of data to avoid buffer overflows + with some types of flow control. + - The scheduler did not properly process PUT requests, + so configuration files could not be uploaded to the + server. + - The scheduler did not strip trailing whitespace on + lines in the configuration files. + - The httpWrite() function did not transition the PUT + request to the HTTP_STATUS state to get the status + from the server. + - The scheduler did not properly handle trailing null + ("-") filters when testing a driver that sent data + to the file: pseudo-backend. + - The IPP backend now only sends a document-format of + "application/vnd.cups-raw" when printing to another + CUPS server using a local printer driver or interface + script. Previously the job's document format was + used, which was incorrect. + - The lpadmin command didn't use the ppd-name attribute + with the -m option; this prevented the use of the + "raw" model from the command-line. + - The pstoraster filter output draft (1-bit) 6-color + output in the wrong order; this resulted in yellow + being printed instead of black on Stylus Photo + printers. + - The pdftops filter did not have the Japanese and + Chinese text support compiled into it. + - The IPP and AppSocket backends did not clear the + "waiting for print job to complete" status message, + which caused some confusion... :) + - The serial backend now opens the port in "no delay" + mode to avoid DCD detection problems with some OS's. + + +CHANGES IN CUPS V1.1.9-1 + + - The configure script did not substitute the + correct user and group names. + - The configure script did not use the full path + to the install-sh script when it was used. + - The pstoraster filter did not correctly support + DuplexTumble mode for printers that used flip + duplexing. + - The cups.list.in file was missing from the + distribution. + - The New DeskJet series driver did not use the + correct OrderDependency for the Duplex option. + - Use read() instead of fread() to read piped + print files in lpr/lp. This avoids a bug in the + HP-UX 10.20 fread() function. + - Updated the pstoraster filter to use the MIPS_FIXADE + system call under IRIX to fix bus error problems on + R12000 processors (Ghostscript is not 64-bit clean...) + - Some Xerox PPD files (most notably the Phaser 790) + have illegal whitespace in the option keyword in the + OpenUI line. This caused the PageRegion option to not + be recognized properly for the Phaser 790. + + +CHANGES IN CUPS V1.1.9 + + - Revamped the configure script to use a modular + approach for the various tests. + - Added --with-openssl-* options to properly reference + the OpenSSL libraries in DSOs. + - Added --with-cups-user and --with-cups-group + options to specify the default user and group for + CUPS. + - Added AIX shared library support. + - Added AIX device discovery for the serial and + parallel ports. + - Now use install program or script to install + directories, files, and symlinks. + - Updated pstops filter to use strict handling of EPS + files embedded in a PostScript document. The %%EOF + handling in 1.1.8 caused some dvips files not to + print. + - Fixed yet another memory allocation bug in pstoraster + that would cause it to crash. This fix also ensures + that all memory allocations are done on (at least) a + 64-bit boundary. + - Fixed Digest authentication - httpGetSubField() didn't + skip the Digest keyword. + - The scheduler did not properly handle Digest + authentication with the new multiple-group support. + - The scheduler did not allow usernames that were + not in the UNIX password file to be used for Digest + authentication from passwd.md5. + - The scheduler could not scan PPD files that only used + a carriage return (i.e. MacOS PPD files); the new code + is also about 40% faster, so servers with thousands of + PPD files should start much faster now. + - The scheduler now stores the PPD file size and + modification times in the ppds.dat file, so it can now + incrementally update the PPD database from the model + directory, resulting in significantly faster startup + times. + - The lpinfo command did not return a non-zero status + code if an error occurred. + - Fixed a bug in the scheduler's UpdateJob() function. + Basically, all jobs shared the same status buffer, and + the "buffer start" pointer could point to 1 byte + before the beginning of the buffer. The new + implementation uses a separate buffer for each job and + eliminates the buffer start bug. + - The IPP backend would send N copies of a document if + the receiving device didn't support the copies + attribute, even if the upstream driver already added + the necessary commands to generate the copies. This + was most noticeable with HP printers where N * N + copies would come out instead of N. + - The PostScript filter (pstops) did not properly handle + duplex printing on inkjet printers that provide this + option. Copies would be put on the front and back + sides of the duplexed page, and the filter did not + output an even number of pages. + - The backends always caught SIGTERM after they + connected to the printer. This prevented raw jobs + from being cancelled early. + - The cupsSetDests() function now removes any printers, + instances, and options that are not defined by the + user or server. This should prevent old system-wide + options from being used in individual user accounts. + - Updated the EPSON printer driver and added PPDs for + the newer EPSON Stylus printers that only support the + "ESC i" graphics command. + - The lpadmin command didn't allow you to add remote + printers to a local class. + - The lpadmin command didn't allow you to set the + options (quotas, etc.) for a class. + - The scheduler did not load or save the + job-sheets-default attribute for classes. + - The scheduler did not automatically recreate remote + printers that were part of a class. + - It was possible for a printer class to list the same + printer more than once. + - The scheduler now makes a backup copy of classes.conf + and printers.conf before writing the new file. + - The lppasswd program incorrectly asked for a new + password when deleting an existing MD5 password + account. + - The scheduler did not match "/printers/name.ppd" + against a location of "/printers/name". + - The client code did not always handle HTTP encryption + upgrades properly. + - The client code now caches the last Digest password so + it can retry using a new resource path or nonce value, + which are included in the MD5 sum sent to the server. + This should eliminate unnecessary password prompts + when using Digest authentication. + - The lppasswd command didn't have a man page. + - Updated the PJL detection rules to allow the universal + escape to occur anywhere in the first 128 bytes of the + file. + - The cups-polld program would poll servers continuously + with no delay if there was an error contacting the + server. + - The IPP backend would send an empty job-name or + requesting-user-name attribute if the corresponding + job attribute was an empty string. While this is + allowed by the IPP specification, some HP JetDirect + implementations return a client-error-bad-request + error if an empty name attribute value is received. + The new code only sends these attributes if they are + not the empty string. + - At least some versions of the HP JetDirect firmware + do not correctly implement IPP. Added additional + checks to the IPP backend to eliminate extra, + unsupported attributes which should normally be + ignored by a compliant IPP device. + - The scheduler did not copy the complete list of + supported file types into the + document-format-supported attribute. This caused + clients to not send the local file type (such as + application/vnd.cups-raw for raw print files) and the + corresponding bad output in some cases. + - The scheduler did not fully copy attributes from a + set-job-attributes request - string attributes were + only referenced, which could cause cupsd to crash + or behave irratically. + - The lp command didn't send the right value for the + job-hold-until attribute when "-H resume" was + specified. + - The IPP backend now returns as soon as a job is + completed or reported as "pending-held". + - Added new ImplicitAnyClasses and HideImplicitMembers + directives to the cupsd.conf file to make implicit + classes more usable/transparent to the user. + - Clients can now (with the appropriate authentication) + retrieve and update the server configuration files + using HTTP GET and PUT requests. + - The web interface didn't allow you to modify the + location or description of the printer. + - The pdftops filter now uses its own temporary file + function to work with PDF files using LZW compression + (which use the uncompress program or gunzip) + - The SystemGroup directive now supports specification of + multiple groups. + - Added new Include directive to cupsd.conf, a la + Apache. + - Added new pseudo-driver/PPD called "raw" that can be + used to create/convert a raw queue. This also allows + raw queues to be created in the web interface. + - The pdftops filter didn't handle image objects that + used JPEG and Flate compression together. + - The pstops filter counted pages wrong when using the + N-up and even/odd printing options. This prevented + the page-ranges option from working properly. + - Added another fix to pstoraster for a bus error + condition caused by a lack of parenthesis in the + Ghostscript code. + - Added new "natural-scaling" option which scales the + natural size of the image (percent of natural image + size instead of percent of page size.) + - The lppasswd program is now setuid to the CUPS user + instead of root. + - The PPD functions did not allow for PPD files that + defined the page sizes and margins before the page + size options. + - The mime.types file now checks for the PJL "LANGUAGE = + Postscript" command for PostScript files. + - The scheduler did not truncate file: output files. + - The PPD file reading code did not handle options with + raw quotes (") in the human-readable names. + - The pdftops filter now remaps the space character when + (bad) PDF files contain a .notdef glyph for the space + character. + + CHANGES IN CUPS V1.1.8 - Updated spec file to generate separate cups-pstoraster diff --git a/INSTALL.txt b/INSTALL.txt index bcfb5e2654..1a91cdfa90 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -1,4 +1,4 @@ -INSTALL - CUPS v1.1.7 - 05/01/2001 +INSTALL - CUPS v1.2.0 - 12/26/2001 ---------------------------------- This file describes how to compile and install CUPS from source @@ -48,11 +48,12 @@ another location: If the PNG, JPEG, TIFF, and ZLIB libraries are not installed in a system default location (typically "/usr/include" and -"/usr/lib") you'll need to set the CFLAGS, CXXFLAGS, and LDFLAGS -environment variables prior to running configure: +"/usr/lib") you'll need to set the CFLAGS, CXXFLAGS, DSOFLAGS, +and LDFLAGS environment variables prior to running configure: setenv CFLAGS "-I/some/directory" ENTER setenv CXXFLAGS "-I/some/directory" ENTER + setenv DSOFLAGS "-L/some/directory" ENTER setenv LDFLAGS "-L/some/directory" ENTER ./configure ... ENTER @@ -60,6 +61,7 @@ or: CFLAGS="-I/some/directory"; export CFLAGS ENTER CXXFLAGS="-I/some/directory"; export CXXFLAGS ENTER + DSOFLAGS="-L/some/directory"; export DSOFLAGS ENTER LDFLAGS="-L/some/directory"; export LDFLAGS ENTER ./configure ... ENTER @@ -72,6 +74,14 @@ SSL and TLS support require the OpenSSL library, available at: http://www.openssl.org +If the OpenSSL header files and libraries are not in a standard +location, specify the locations of these files using the +--with-openssl-includes and --with-openssl-libs directives: + + ./configure --enable-ssl \ + --with-openssl-includes=/foo/bar/include \ + --with-openssl-libs=/foo/bar/lib + See the file "ENCRYPTION.txt" for information on using the encryption support in CUPS. @@ -79,7 +89,7 @@ Once you have configured things, just type: make ENTER -or if you have FreeBSD: +or if you have FreeBSD, NetBSD, or OpenBSD type: gmake ENTER @@ -94,7 +104,7 @@ your local system: make install ENTER -or for FreeBSD: +or for FreeBSD, NetBSD, or OpenBSD: gmake install ENTER @@ -124,16 +134,19 @@ or gmake ENTER -for FreeBSD, where is one of the following: +for FreeBSD, NetBSD, and OpenBSD. The target is one of +the following: epm - Builds a portable shell script and tar file based distribution. This format will also backup your existing printing system if you decide to remove CUPS at some future time. - rpm - Builds a RPM binary distribution. + aix - Builds an AIX binary distribution. + bsd - Builds a *BSD binary distribution. deb - Builds a Debian binary distribution. depot - Builds a HP-UX binary distribution. pkg - Builds a Solaris binary distribution. + rpm - Builds a RPM binary distribution. tardist - Builds an IRIX binary distribution. diff --git a/LICENSE.html b/LICENSE.html index 1bf924e80a..da8647fc2a 100644 --- a/LICENSE.html +++ b/LICENSE.html @@ -24,12 +24,12 @@ licenses follow this introduction.

The GNU LGPL applies to the CUPS API library, located in the "cups" subdirectory of the CUPS source distribution and in the -"/usr/include/cups" directory and "libcups.a", "libcups.sl", or -"libcups.so" files in the binary distributions. +"/usr/include/cups" directory and "libcups.a", "libcups_s.a", +"libcups.sl", or "libcups.so" files in the binary distributions.

The GNU GPL applies to the remainder of the CUPS distribution, including the "pstoraster" filter which is based upon GNU Ghostscript -5.50 and the "pdftops" filter which is based upon Xpdf 0.90. +5.50 and the "pdftops" filter which is based upon Xpdf 0.93a.

For those not familiar with the GNU GPL, the license basically allows you to: @@ -93,7 +93,7 @@ Fax: +1.415.492.9862
EMail: info@arsoft.com -

The "pdftops" filter is based on the Xpdf 0.90 software. For binary +

The "pdftops" filter is based on the Xpdf 0.93a software. For binary distribution licensing of this software, please contact:

diff --git a/LICENSE.txt b/LICENSE.txt index e05c045686..a28160c957 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -17,12 +17,12 @@ General Public License ("GPL") and GNU Library General Public License The GNU LGPL applies to the CUPS API library, located in the "cups" subdirectory of the CUPS source distribution and in the "/usr/include/cups" -directory and "libcups.a", "libcups.sl", or "libcups.so" files in the binary -distributions. +directory and "libcups.a", "libcups_s.a", "libcups.sl", or "libcups.so" +files in the binary distributions. The GNU GPL applies to the remainder of the CUPS distribution, including the "pstoraster" filter which is based upon GNU Ghostscript 5.50 and the -"pdftops" filter which is based upon Xpdf 0.90. +"pdftops" filter which is based upon Xpdf 0.93a. For those not familiar with the GNU GPL, the license basically allows you to: @@ -75,7 +75,7 @@ contact: Fax: +1.415.492.9862 EMail: info@arsoft.com -The "pdftops" filter is based on the Xpdf 0.90 software. For binary +The "pdftops" filter is based on the Xpdf 0.93a software. For binary distribution licensing of this software, please contact: Derek B. Noonburg diff --git a/Makedefs.in b/Makedefs.in index 8b5bd4d221..731d6ad4ea 100644 --- a/Makedefs.in +++ b/Makedefs.in @@ -1,5 +1,5 @@ # -# "$Id: Makedefs.in,v 1.36.2.1 2001/05/13 18:37:58 mike Exp $" +# "$Id: Makedefs.in,v 1.36.2.2 2001/12/26 16:52:05 mike Exp $" # # Common makefile definitions for the Common UNIX Printing System (CUPS). # @@ -29,14 +29,12 @@ AR = @AR@ AWK = @AWK@ CC = @LIBTOOL@ @CC@ -CHMOD = @CHMOD@ -CP = @CP@ CXX = @LIBTOOL@ @CXX@ DSO = @DSO@ HTMLDOC = @HTMLDOC@ +INSTALL = @INSTALL@ LIBTOOL = @LIBTOOL@ LN = /bin/ln -sf -MKDIR = @MKDIR@ -p MV = @MV@ NROFF = @NROFF@ RANLIB = @RANLIB@ @@ -48,12 +46,19 @@ SHELL = /bin/sh # Installation programs... # -INSTALL_BIN = $(LIBTOOL) $(CP) -INSTALL_DATA = $(CP) -INSTALL_LIB = $(LIBTOOL) $(CP) -INSTALL_MAN = $(CP) -INSTALL_SCRIPT = $(CP) -INSTALL_SYSV = @INSTALL_SYSV@ +INSTALL_BIN = $(LIBTOOL) $(INSTALL) -m 755 -s +INSTALL_DATA = $(INSTALL) -m 644 +INSTALL_DIR = $(INSTALL) -d +INSTALL_LIB = $(LIBTOOL) $(INSTALL) -m 755 +INSTALL_MAN = $(INSTALL) -m 644 +INSTALL_SCRIPT = $(INSTALL) -m 755 + +# +# Default user and group for the scheduler... +# + +CUPS_USER = @CUPS_USER@ +CUPS_GROUP = @CUPS_GROUP@ # # Libraries... @@ -64,6 +69,7 @@ LIBCUPSIMAGE = @LIBCUPSIMAGE@ LIBJPEG = @LIBJPEG@ LIBMALLOC = @LIBMALLOC@ LIBPNG = @LIBPNG@ +LIBSLP = @LIBSLP@ LIBTIFF = @LIBTIFF@ LIBZ = @LIBZ@ @@ -75,7 +81,7 @@ LIBZ = @LIBZ@ # extra debug info) # -ARFLAGS = crvs +ARFLAGS = @ARFLAGS@ CFLAGS = @CFLAGS@ -I.. $(OPTIONS) CXXFLAGS = @CXXFLAGS@ -I.. $(OPTIONS) DSOFLAGS = @DSOFLAGS@ @@ -88,6 +94,7 @@ LIBS = $(LINKCUPS) $(NETLIBS) @LIBS@ NETLIBS = @NETLIBS@ OPTIM = @OPTIM@ OPTIONS = +PAMLIBS = @PAMLIBS@ SSLLIBS = @SSLLIBS@ # @@ -119,41 +126,44 @@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ top_srcdir = @top_srcdir@ -AMANDIR = @AMANDIR@ -BINDIR = @bindir@ -DATADIR = @CUPS_DATADIR@ -DOCDIR = @CUPS_DOCROOT@ -INCLUDEDIR = $(includedir) +AMANDIR = $(BUILDROOT)@AMANDIR@ +BINDIR = $(BUILDROOT)@bindir@ +DATADIR = $(BUILDROOT)@CUPS_DATADIR@ +DOCDIR = $(BUILDROOT)@CUPS_DOCROOT@ +INCLUDEDIR = $(BUILDROOT)$(includedir) INITDIR = @INITDIR@ INITDDIR = @INITDDIR@ -LIBDIR = $(libdir) -LOCALEDIR = @CUPS_LOCALEDIR@ -LOGDIR = @CUPS_LOGDIR@ -MANDIR = @mandir@ -PAMDIR = @PAMDIR@ -REQUESTS = @CUPS_REQUESTS@ -SBINDIR = @sbindir@ -SERVERBIN = @CUPS_SERVERBIN@ -SERVERROOT = @CUPS_SERVERROOT@ +LIBDIR = $(BUILDROOT)$(libdir) +LOCALEDIR = $(BUILDROOT)@CUPS_LOCALEDIR@ +LOGDIR = $(BUILDROOT)@CUPS_LOGDIR@ +MANDIR = $(BUILDROOT)@mandir@ +PAMDIR = $(BUILDROOT)@PAMDIR@ +PMANDIR = $(BUILDROOT)@PMANDIR@ +REQUESTS = $(BUILDROOT)@CUPS_REQUESTS@ +SBINDIR = $(BUILDROOT)@sbindir@ +SERVERBIN = $(BUILDROOT)@CUPS_SERVERBIN@ +SERVERROOT = $(BUILDROOT)@CUPS_SERVERROOT@ CAT1EXT = @CAT1EXT@ +CAT3EXT = @CAT3EXT@ CAT5EXT = @CAT5EXT@ CAT8EXT = @CAT8EXT@ MAN8EXT = @MAN8EXT@ +MAN8DIR = @MAN8DIR@ # # Rules... # .SILENT: -.SUFFIXES: .a .c .cxx .h .man .o .0 .1 .1m .5 .8 .z +.SUFFIXES: .a .c .cxx .h .man .o .0 .1 .1m .3 .5 .8 .z .c.o: echo Compiling $<... $(CC) $(OPTIM) $(CFLAGS) -c $< .cxx.o: echo Compiling $<... $(CXX) $(OPTIM) $(CXXFLAGS) -c $< -.man.0 .man.1 .man.1m .man.5 .man.8: +.man.0 .man.1 .man.1m .man.3 .man.5 .man.8: echo Formatting $<... $(RM) $@ $(NROFF) -man $< >$@ @@ -165,5 +175,5 @@ MAN8EXT = @MAN8EXT@ $(MV) t.z $@ # -# End of "$Id: Makedefs.in,v 1.36.2.1 2001/05/13 18:37:58 mike Exp $" +# End of "$Id: Makedefs.in,v 1.36.2.2 2001/12/26 16:52:05 mike Exp $" # diff --git a/Makefile b/Makefile index db0cfa236b..b40afe2b93 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.31.2.1 2001/05/13 18:37:58 mike Exp $" +# "$Id: Makefile,v 1.31.2.2 2001/12/26 16:52:05 mike Exp $" # # Top-level Makefile for the Common UNIX Printing System (CUPS). # @@ -74,30 +74,32 @@ install: (cd ppd; $(MAKE) $(MFLAGS) install) echo Installing in templates... (cd templates; $(MAKE) $(MFLAGS) install) + echo Installing cups-config script... + $(INSTALL_DIR) $(BINDIR) + $(INSTALL_SCRIPT) cups-config $(BINDIR)/cups-config echo Installing startup script... if test "x$(INITDIR)" != "x"; then \ - $(MKDIR) $(prefix)/$(INITDIR)/init.d; \ - $(RM) $(prefix)/$(INITDIR)/init.d/cups; \ - $(INSTALL_SCRIPT) cups.sh $(prefix)/$(INITDIR)/init.d/cups; \ - $(CHMOD) ugo+rx $(prefix)/$(INITDIR)/init.d/cups; \ - $(MKDIR) $(prefix)/$(INITDIR)/rc0.d; \ - $(RM) $(prefix)/$(INITDIR)/rc0.d/K00cups; \ - ln -s $(INITDDIR)/cups $(prefix)/$(INITDIR)/rc0.d/K00cups; \ - $(MKDIR) $(prefix)/$(INITDIR)/rc2.d; \ - $(RM) $(prefix)/$(INITDIR)/rc2.d/S99cups; \ - ln -s $(INITDDIR)/cups $(prefix)/$(INITDIR)/rc2.d/S99cups; \ - $(MKDIR) $(prefix)/$(INITDIR)/rc3.d; \ - $(RM) $(prefix)/$(INITDIR)/rc3.d/S99cups; \ - ln -s $(INITDDIR)/cups $(prefix)/$(INITDIR)/rc3.d/S99cups; \ - $(MKDIR) $(prefix)/$(INITDIR)/rc5.d; \ - $(RM) $(prefix)/$(INITDIR)/rc5.d/S99cups; \ - ln -s $(INITDDIR)/cups $(prefix)/$(INITDIR)/rc5.d/S99cups; \ + $(INSTALL_DIR) $(BUILDROOT)$(INITDIR)/init.d; \ + $(INSTALL_SCRIPT) cups.sh $(BUILDROOT)$(INITDIR)/init.d/cups; \ + $(INSTALL_DIR) $(BUILDROOT)$(INITDIR)/rc0.d; \ + $(INSTALL_SCRIPT) cups.sh $(BUILDROOT)$(INITDIR)/rc0.d/K00cups; \ + $(INSTALL_DIR) $(BUILDROOT)$(INITDIR)/rc2.d; \ + $(INSTALL_SCRIPT) cups.sh $(BUILDROOT)$(INITDIR)/rc2.d/S99cups; \ + $(INSTALL_DIR) $(BUILDROOT)$(INITDIR)/rc3.d; \ + $(INSTALL_SCRIPT) cups.sh $(BUILDROOT)$(INITDIR)/rc3.d/S99cups; \ + $(INSTALL_DIR) $(BUILDROOT)$(INITDIR)/rc5.d; \ + $(INSTALL_SCRIPT) cups.sh $(BUILDROOT)$(INITDIR)/rc5.d/S99cups; \ fi if test "x$(INITDIR)" = "x" -a "x$(INITDDIR)" != "x"; then \ - $(MKDIR) $(prefix)/$(INITDDIR); \ - $(RM) $(prefix)/$(INITDDIR)/cups; \ - $(INSTALL_SCRIPT) cups.sh $(prefix)/$(INITDDIR)/cups; \ - $(CHMOD) ugo+rx $(prefix)/$(INITDDIR)/cups; \ + $(INSTALL_DIR) $(BUILDROOT)$(INITDDIR); \ + if test "$(INITDDIR)" = "/System/Library/StartupItems/CUPS"; then \ + $(INSTALL_SCRIPT) cups.sh $(BUILDROOT)$(INITDDIR)/CUPS; \ + $(INSTALL_DATA) cups.plist $(BUILDROOT)$(INITDDIR)/StartupParameters.plist; \ + $(INSTALL_DIR) $(BUILDROOT)$(INITDDIR)/Resources/English.lproj; \ + $(INSTALL_DATA) cups.strings $(BUILDROOT)$(INITDDIR)/Resources/English.lproj/Localizable.strings; \ + else \ + $(INSTALL_SCRIPT) cups.sh $(BUILDROOT)$(INITDDIR)/cups; \ + fi \ fi @@ -114,15 +116,13 @@ test: all # Make software distributions using EPM (http://www.easysw.com/epm)... # -EPMFLAGS = -v \ - AMANDIR=$(AMANDIR) \ - BINDIR=$(BINDIR) DATADIR=$(DATADIR) \ - DOCDIR=$(DOCDIR) INCLUDEDIR=$(INCLUDEDIR) \ - LIBDIR=$(LIBDIR) LOCALEDIR=$(LOCALEDIR) \ - LOGDIR=$(LOGDIR) MANDIR=$(MANDIR) \ - PAMDIR=$(PAMDIR) REQUESTS=$(REQUESTS) \ - SBINDIR=$(SBINDIR) SERVERBIN=$(SERVERBIN) \ - SERVERROOT=$(SERVERROOT) +EPMFLAGS = -v + +aix: + epm $(EPMFLAGS) -f aix cups + +bsd: + epm $(EPMFLAGS) -f bsd cups epm: epm $(EPMFLAGS) cups @@ -143,5 +143,5 @@ tardist: epm $(EPMFLAGS) -f tardist cups # -# End of "$Id: Makefile,v 1.31.2.1 2001/05/13 18:37:58 mike Exp $". +# End of "$Id: Makefile,v 1.31.2.2 2001/12/26 16:52:05 mike Exp $". # diff --git a/README.txt b/README.txt index 1dad6ea499..1a245aeea7 100644 --- a/README.txt +++ b/README.txt @@ -1,4 +1,4 @@ -README - CUPS v1.1.7 - 05/01/2001 +README - CUPS v1.2.0 - 12/26/2001 --------------------------------- Looking for compile instructions? Read the file "INSTALL.txt" @@ -27,8 +27,8 @@ that are used to support non-PostScript printers. Sample drivers for HP and EPSON printers are included that use these filters. -Drivers for over 2300 printers are provided with our ESP Print -Pro software, available at: +Drivers for thousands of printers are provided with our ESP +Print Pro software, available at: http://www.easysw.com/printpro @@ -55,7 +55,8 @@ SOFTWARE REQUIREMENTS The following operating system software is required to install one of the binary distributions from Easy Software Products: - - Digital UNIX (aka OSF1 aka Compaq Tru64 UNIX) 4.0 or higher + - AIX 4.3 or higher + - Compaq Tru64 UNIX (aka OSF1 aka Digital UNIX) 4.0 or higher - HP-UX 10.20 or higher - IRIX 5.3 or higher - Linux 2.0 with glibc2 or higher @@ -188,14 +189,20 @@ the following commands: Similarly, for the other sample drivers you can use: - Driver PPD File - -------------------------- ------------ - HP DeskJet Series deskjet.ppd - HP LaserJet Series laserjet.ppd - EPSON Stylus Color Series stcolor.ppd - EPSON Stylus Photo Series stphoto.ppd - EPSON 9-pin Series epson9.ppd - EPSON 24-pin Series epson24.ppd + Driver PPD File + ----------------------------- ------------ + Dymo Label Printers dymo.ppd + EPSON Stylus Color Series stcolor.ppd + EPSON Stylus Photo Series stphoto.ppd + EPSON Stylus New Color Series stcolor2.ppd + EPSON Stylus New Photo Series stphoto2.ppd + EPSON 9-pin Series epson9.ppd + EPSON 24-pin Series epson24.ppd + HP DeskJet Series deskjet.ppd + HP New DeskJet Series deskjet2.ppd + HP LaserJet Series laserjet.ppd + OKIDATA 9-Pin Series okidata9.ppd + OKIDATA 24-Pin Series okidat24.ppd These sample drivers provide basic printing capabilities, but generally do not exercise the full potential of the printers or @@ -246,8 +253,8 @@ The PostScript RIP software (pstoraster) is based on the GNU Ghostscript 5.50 core, Copyright 1986-1998 by Aladdin Enterprises. -The PDF filter (pdftops) is based on the Xpdf 0.90 software, -Copyright 1996-1999 by Derek B. Noonburg. +The PDF filter (pdftops) is based on the Xpdf 0.92 software, +Copyright 1996-2001 by Derek B. Noonburg. This software is based in part on the work of the Independent JPEG Group. diff --git a/backend/Makefile b/backend/Makefile index 6152f31f48..fee32117af 100644 --- a/backend/Makefile +++ b/backend/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.25.2.1 2001/04/02 19:51:42 mike Exp $" +# "$Id: Makefile,v 1.25.2.2 2001/12/26 16:52:06 mike Exp $" # # Backend makefile for the Common UNIX Printing System (CUPS). # @@ -49,10 +49,10 @@ clean: # install: - -$(MKDIR) $(SERVERBIN)/backend - $(CHMOD) ugo+rx $(SERVERBIN) - $(CHMOD) ugo+rx $(SERVERBIN)/backend - $(INSTALL_BIN) $(BACKENDS) $(SERVERBIN)/backend + $(INSTALL_DIR) $(SERVERBIN)/backend + for file in $(BACKENDS); do \ + $(INSTALL_BIN) $$file $(SERVERBIN)/backend; \ + done $(RM) $(SERVERBIN)/backend/http $(LN) ipp $(SERVERBIN)/backend/http @@ -139,5 +139,5 @@ usb.o: ../cups/cups.h $(OBJS): ../config.h ../Makedefs # -# End of "$Id: Makefile,v 1.25.2.1 2001/04/02 19:51:42 mike Exp $". +# End of "$Id: Makefile,v 1.25.2.2 2001/12/26 16:52:06 mike Exp $". # diff --git a/backend/ipp.c b/backend/ipp.c index 7c10ea60f8..6e29cdd209 100644 --- a/backend/ipp.c +++ b/backend/ipp.c @@ -1,5 +1,5 @@ /* - * "$Id: ipp.c,v 1.38.2.1 2001/05/13 18:37:59 mike Exp $" + * "$Id: ipp.c,v 1.38.2.2 2001/12/26 16:52:06 mike Exp $" * * IPP backend for the Common UNIX Printing System (CUPS). * @@ -408,13 +408,15 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ fprintf(stderr, "DEBUG: printer-uri = \"%s\"\n", uri); - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", - NULL, argv[2]); + if (argv[2][0]) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, argv[2]); fprintf(stderr, "DEBUG: requesting-user-name = \"%s\"\n", argv[2]); - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, - argv[3]); + if (argv[3][0]) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, + argv[3]); fprintf(stderr, "DEBUG: job-name = \"%s\"\n", argv[3]); @@ -425,7 +427,12 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ options = NULL; num_options = cupsParseOptions(argv[5], 0, &options); - if ((content_type = getenv("CONTENT_TYPE")) != NULL && format_sup != NULL) + if (argc > 6) + content_type = getenv("CONTENT_TYPE"); + else + content_type = "application/vnd.cups-raw"; + + if (content_type != NULL && format_sup != NULL) { for (i = 0; i < format_sup->num_values; i ++) if (strcasecmp(content_type, format_sup->values[i].string.text) == 0) @@ -436,11 +443,24 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ num_options, &options); } - cupsEncodeOptions(request, num_options, options); + if (copies_sup) + { + /* + * Only send options if the destination printer supports the copies + * attribute. This is a hack for the HP JetDirect implementation of + * IPP, which does not accept extension attributes and incorrectly + * reports a client-error-bad-request error instead of the + * successful-ok-unsupported-attributes status. In short, at least + * some HP implementations of IPP are non-compliant. + */ + + cupsEncodeOptions(request, num_options, options); + ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "copies", + atoi(argv[4])); + } + cupsFreeOptions(num_options, options); - if (copies_sup) - ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "copies", atoi(argv[4])); /* * Do the request... @@ -453,6 +473,8 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ if (ipp_status > IPP_OK_CONFLICT) { + job_id = 0; + if (ipp_status == IPP_SERVICE_UNAVAILABLE || ipp_status == IPP_PRINTER_BUSY) { @@ -478,7 +500,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ if (response) ippDelete(response); - if (ipp_status <= IPP_OK_CONFLICT) + if (ipp_status <= IPP_OK_CONFLICT && argc > 6) { fprintf(stderr, "PAGE: 1 %d\n", copies_sup ? atoi(argv[4]) : 1); copies --; @@ -558,10 +580,11 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ else if ((job_state = ippFindAttribute(response, "job-state", IPP_TAG_ENUM)) != NULL) { /* - * Stop polling if the job is finished... + * Stop polling if the job is finished or pending-held... */ - if (job_state->values[0].integer > IPP_JOB_PROCESSING) + if (job_state->values[0].integer > IPP_JOB_PROCESSING || + job_state->values[0].integer == IPP_JOB_HELD) { ippDelete(response); break; @@ -600,7 +623,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ */ if (ipp_status <= IPP_OK_CONFLICT) - fputs("INFO: " CUPS_SVERSION " is ready to print.\n", stderr); + fputs("INFO: Ready to print.\n", stderr); return (ipp_status > IPP_OK_CONFLICT); } @@ -620,5 +643,5 @@ password_cb(const char *prompt) /* I - Prompt (not used) */ /* - * End of "$Id: ipp.c,v 1.38.2.1 2001/05/13 18:37:59 mike Exp $". + * End of "$Id: ipp.c,v 1.38.2.2 2001/12/26 16:52:06 mike Exp $". */ diff --git a/backend/lpd.c b/backend/lpd.c index 5c4ce28258..e4f405244f 100644 --- a/backend/lpd.c +++ b/backend/lpd.c @@ -1,5 +1,5 @@ /* - * "$Id: lpd.c,v 1.28 2001/03/08 15:13:13 mike Exp $" + * "$Id: lpd.c,v 1.28.2.1 2001/12/26 16:52:06 mike Exp $" * * Line Printer Daemon backend for the Common UNIX Printing System (CUPS). * @@ -398,7 +398,7 @@ lpd_queue(char *hostname, /* I - Host to connect to */ * First try to reserve a port for this connection... */ - if ((hostaddr = gethostbyname(hostname)) == NULL) + if ((hostaddr = httpGetHostByName(hostname)) == NULL) { fprintf(stderr, "ERROR: Unable to locate printer \'%s\' - %s", hostname, strerror(errno)); @@ -669,5 +669,5 @@ lpd_write(int lpd_fd, /* I - LPD socket */ /* - * End of "$Id: lpd.c,v 1.28 2001/03/08 15:13:13 mike Exp $". + * End of "$Id: lpd.c,v 1.28.2.1 2001/12/26 16:52:06 mike Exp $". */ diff --git a/backend/parallel.c b/backend/parallel.c index b8474a4cf4..a876da9158 100644 --- a/backend/parallel.c +++ b/backend/parallel.c @@ -1,5 +1,5 @@ /* - * "$Id: parallel.c,v 1.29 2001/03/23 13:58:17 mike Exp $" + * "$Id: parallel.c,v 1.29.2.1 2001/12/26 16:52:07 mike Exp $" * * Parallel port backend for the Common UNIX Printing System (CUPS). * @@ -604,11 +604,26 @@ list_devices(void) if ((fd = open(device, O_WRONLY)) >= 0) { close(fd); - printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d\"\n", device, i + 1); + printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d (interrupt-driven)\"\n", device, i + 1); } sprintf(device, "/dev/lpa%d", i); if ((fd = open(device, O_WRONLY)) >= 0) + { + close(fd); + printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d (polled)\"\n", device, i + 1); + } + } +#elif defined(_AIX) + int i; /* Looping var */ + int fd; /* File descriptor */ + char device[255]; /* Device filename */ + + + for (i = 0; i < 8; i ++) + { + sprintf(device, "/dev/lp%d", i); + if ((fd = open(device, O_WRONLY)) >= 0) { close(fd); printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d\"\n", device, i + 1); @@ -619,5 +634,5 @@ list_devices(void) /* - * End of "$Id: parallel.c,v 1.29 2001/03/23 13:58:17 mike Exp $". + * End of "$Id: parallel.c,v 1.29.2.1 2001/12/26 16:52:07 mike Exp $". */ diff --git a/backend/serial.c b/backend/serial.c index 192bbc2cdd..050a1f8628 100644 --- a/backend/serial.c +++ b/backend/serial.c @@ -1,5 +1,5 @@ /* - * "$Id: serial.c,v 1.32 2001/03/13 14:05:35 mike Exp $" + * "$Id: serial.c,v 1.32.2.1 2001/12/26 16:52:07 mike Exp $" * * Serial port backend for the Common UNIX Printing System (CUPS). * @@ -189,7 +189,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ do { - if ((fd = open(resource, O_WRONLY | O_NOCTTY | O_EXCL)) == -1) + if ((fd = open(resource, O_WRONLY | O_NOCTTY | O_EXCL | O_NDELAY)) == -1) { if (errno == EBUSY) { @@ -212,8 +212,9 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ tcgetattr(fd, &opts); opts.c_lflag &= ~(ICANON | ECHO | ISIG); /* Raw mode */ + opts.c_oflag &= ~OPOST; /* Don't post-process */ - bufsize = 480; /* 9600 baud / 10 bits/char / 2Hz */ + bufsize = 96; /* 9600 baud / 10 bits/char / 10Hz */ dtrdsr = 0; /* No dtr/dsr flow control */ if (options != NULL) @@ -255,7 +256,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ * Set the baud rate... */ - bufsize = atoi(value) / 20; + bufsize = atoi(value) / 100; #if B19200 == 19200 cfsetispeed(&opts, atoi(value)); @@ -378,6 +379,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ } tcsetattr(fd, TCSANOW, &opts); + fcntl(fd, F_SETFL, 0); /* * Now that we are "connected" to the port, ignore SIGTERM so that we @@ -476,7 +478,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ } /* - * Close the socket connection and input file and return... + * Close the serial port and input file and return... */ close(fd); @@ -852,5 +854,5 @@ list_devices(void) /* - * End of "$Id: serial.c,v 1.32 2001/03/13 14:05:35 mike Exp $". + * End of "$Id: serial.c,v 1.32.2.1 2001/12/26 16:52:07 mike Exp $". */ diff --git a/backend/socket.c b/backend/socket.c index e48fe08c86..115296bb0a 100644 --- a/backend/socket.c +++ b/backend/socket.c @@ -1,5 +1,5 @@ /* - * "$Id: socket.c,v 1.17.2.1 2001/05/13 18:37:59 mike Exp $" + * "$Id: socket.c,v 1.17.2.2 2001/12/26 16:52:07 mike Exp $" * * AppSocket backend for the Common UNIX Printing System (CUPS). * @@ -146,7 +146,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ * Then try to connect to the remote host... */ - if ((hostaddr = gethostbyname(hostname)) == NULL) + if ((hostaddr = httpGetHostByName(hostname)) == NULL) { fprintf(stderr, "ERROR: Unable to locate printer \'%s\' - %s\n", hostname, strerror(errno)); @@ -332,12 +332,12 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ if (fp != stdin) fclose(fp); - fputs("INFO: " CUPS_SVERSION " is ready to print.\n", stderr); + fputs("INFO: Ready to print.\n", stderr); return (0); } /* - * End of "$Id: socket.c,v 1.17.2.1 2001/05/13 18:37:59 mike Exp $". + * End of "$Id: socket.c,v 1.17.2.2 2001/12/26 16:52:07 mike Exp $". */ diff --git a/backend/usb.c b/backend/usb.c index c3ecc700bc..3d6ea82ae2 100644 --- a/backend/usb.c +++ b/backend/usb.c @@ -1,5 +1,5 @@ /* - * "$Id: usb.c,v 1.18 2001/02/08 18:46:00 mike Exp $" + * "$Id: usb.c,v 1.18.2.1 2001/12/26 16:52:07 mike Exp $" * * USB port backend for the Common UNIX Printing System (CUPS). * @@ -363,35 +363,55 @@ list_devices(void) } fclose(probe); + + /* + * Write empty device listings for unused USB devices... + */ + + for (; i < 16; i ++) + { + sprintf(device, "/dev/usb/lp%d", i); + + if (access(device, 0)) + { + sprintf(device, "/dev/usb/usblp%d", i); + + if (access(device, 0)) + { + sprintf(device, "/dev/usblp%d", i); + + if (access(device, 0)) + continue; + } + } + + printf("direct usb:%s \"Unknown\" \"USB Printer #%d\"\n", device, i + 1); + } } else { /* - * Just probe manually for USB devices... + * Just check manually for USB devices... */ - for (i = 0; i < 8; i ++) + for (i = 0; i < 16; i ++) { sprintf(device, "/dev/usb/lp%d", i); - if ((fd = open(device, O_WRONLY)) >= 0) - { - close(fd); - printf("direct usb:%s \"Unknown\" \"USB Printer #%d\"\n", device, i + 1); - } - sprintf(device, "/dev/usb/usblp%d", i); - if ((fd = open(device, O_WRONLY)) >= 0) + if (access(device, 0)) { - close(fd); - printf("direct usb:%s \"Unknown\" \"USB Printer #%d\"\n", device, i + 1); - } + sprintf(device, "/dev/usb/usblp%d", i); - sprintf(device, "/dev/usblp%d", i); - if ((fd = open(device, O_WRONLY)) >= 0) - { - close(fd); - printf("direct usb:%s \"Unknown\" \"USB Printer #%d\"\n", device, i + 1); + if (access(device, 0)) + { + sprintf(device, "/dev/usblp%d", i); + + if (access(device, 0)) + continue; + } } + + printf("direct usb:%s \"Unknown\" \"USB Printer #%d\"\n", device, i + 1); } } #elif defined(__sgi) @@ -400,38 +420,30 @@ list_devices(void) #elif defined(__osf) #elif defined(__FreeBSD__) int i; /* Looping var */ - int fd; /* File descriptor */ char device[255]; /* Device filename */ for (i = 0; i < 3; i ++) { sprintf(device, "/dev/unlpt%d", i); - if ((fd = open(device, O_WRONLY)) >= 0) - { - close(fd); - printf("direct usb:%s \"Unknown\" \"USB Port #%d\"\n", device, i + 1); - } + if (!access(device, 0)) + printf("direct usb:%s \"Unknown\" \"USB Printer #%d\"\n", device, i + 1); } #elif defined(__NetBSD__) || defined(__OpenBSD__) int i; /* Looping var */ - int fd; /* File descriptor */ char device[255]; /* Device filename */ for (i = 0; i < 3; i ++) { sprintf(device, "/dev/ulpt%d", i); - if ((fd = open(device, O_WRONLY)) >= 0) - { - close(fd); - printf("direct usb:%s \"Unknown\" \"USB Port #%d\"\n", device, i + 1); - } + if (!access(device, 0)) + printf("direct usb:%s \"Unknown\" \"USB Printer #%d\"\n", device, i + 1); } #endif } /* - * End of "$Id: usb.c,v 1.18 2001/02/08 18:46:00 mike Exp $". + * End of "$Id: usb.c,v 1.18.2.1 2001/12/26 16:52:07 mike Exp $". */ diff --git a/berkeley/Makefile b/berkeley/Makefile index ad830e109b..8ba055ac1a 100644 --- a/berkeley/Makefile +++ b/berkeley/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.13 2001/01/22 15:03:20 mike Exp $" +# "$Id: Makefile,v 1.13.2.1 2001/12/26 16:52:07 mike Exp $" # # Berkeley commands makefile for the Common UNIX Printing System (CUPS). # @@ -48,11 +48,11 @@ clean: # install: - -$(MKDIR) $(BINDIR) - $(CHMOD) ugo+rx $(BINDIR) - $(INSTALL_BIN) lpq lpr lprm $(BINDIR) - -$(MKDIR) $(SBINDIR) - $(CHMOD) ugo+rx $(SBINDIR) + $(INSTALL_DIR) $(BINDIR) + $(INSTALL_BIN) lpq $(BINDIR) + $(INSTALL_BIN) lpr $(BINDIR) + $(INSTALL_BIN) lprm $(BINDIR) + $(INSTALL_DIR) $(SBINDIR) $(INSTALL_BIN) lpc $(SBINDIR) @@ -101,5 +101,5 @@ lprm.o: ../cups/cups.h ../Makedefs # -# End of "$Id: Makefile,v 1.13 2001/01/22 15:03:20 mike Exp $". +# End of "$Id: Makefile,v 1.13.2.1 2001/12/26 16:52:07 mike Exp $". # diff --git a/berkeley/lpq.c b/berkeley/lpq.c index cae40a4d31..2de3622177 100644 --- a/berkeley/lpq.c +++ b/berkeley/lpq.c @@ -1,5 +1,5 @@ /* - * "$Id: lpq.c,v 1.17.2.1 2001/05/13 18:38:00 mike Exp $" + * "$Id: lpq.c,v 1.17.2.2 2001/12/26 16:52:08 mike Exp $" * * "lpq" command for the Common UNIX Printing System (CUPS). * @@ -72,7 +72,9 @@ main(int argc, /* I - Number of command-line arguments */ longstatus; /* Show file details */ int num_dests; /* Number of destinations */ cups_dest_t *dests; /* Destinations */ +#ifdef HAVE_LIBSSL http_encryption_t encryption; /* Encryption? */ +#endif /* HAVE_LIBSSL */ /* @@ -536,5 +538,5 @@ show_printer(http_t *http, /* I - HTTP connection to server */ /* - * End of "$Id: lpq.c,v 1.17.2.1 2001/05/13 18:38:00 mike Exp $". + * End of "$Id: lpq.c,v 1.17.2.2 2001/12/26 16:52:08 mike Exp $". */ diff --git a/berkeley/lpr.c b/berkeley/lpr.c index 949a9f3cbc..d25b7c35b3 100644 --- a/berkeley/lpr.c +++ b/berkeley/lpr.c @@ -1,5 +1,5 @@ /* - * "$Id: lpr.c,v 1.20.2.1 2001/05/13 18:38:00 mike Exp $" + * "$Id: lpr.c,v 1.20.2.2 2001/12/26 16:52:08 mike Exp $" * * "lpr" command for the Common UNIX Printing System (CUPS). * @@ -366,7 +366,7 @@ main(int argc, /* I - Number of command-line arguments */ return (1); } - while ((i = fread(buffer, 1, sizeof(buffer), stdin)) > 0) + while ((i = read(0, buffer, sizeof(buffer))) > 0) write(temp, buffer, i); i = lseek(temp, 0, SEEK_CUR); @@ -421,5 +421,5 @@ sighandler(int s) /* I - Signal number */ /* - * End of "$Id: lpr.c,v 1.20.2.1 2001/05/13 18:38:00 mike Exp $". + * End of "$Id: lpr.c,v 1.20.2.2 2001/12/26 16:52:08 mike Exp $". */ diff --git a/cgi-bin/Makefile b/cgi-bin/Makefile index 7a4e487293..ca74ac487a 100644 --- a/cgi-bin/Makefile +++ b/cgi-bin/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.15 2001/02/21 17:01:16 mike Exp $" +# "$Id: Makefile,v 1.15.2.1 2001/12/26 16:52:08 mike Exp $" # # CGI makefile for the Common UNIX Printing System (CUPS). # @@ -50,10 +50,10 @@ clean: # install: - -$(MKDIR) $(SERVERBIN)/cgi-bin - $(CHMOD) ugo+rx $(SERVERBIN) - $(CHMOD) ugo+rx $(SERVERBIN)/cgi-bin - $(INSTALL_BIN) $(CGIS) $(SERVERBIN)/cgi-bin + $(INSTALL_DIR) $(SERVERBIN)/cgi-bin + for file in $(CGIS); do \ + $(INSTALL_BIN) $$file $(SERVERBIN)/cgi-bin; \ + done # @@ -117,5 +117,5 @@ $(OBJS): ../Makedefs # -# End of "$Id: Makefile,v 1.15 2001/02/21 17:01:16 mike Exp $". +# End of "$Id: Makefile,v 1.15.2.1 2001/12/26 16:52:08 mike Exp $". # diff --git a/cgi-bin/admin.c b/cgi-bin/admin.c index bd4fc28eb6..781a800973 100644 --- a/cgi-bin/admin.c +++ b/cgi-bin/admin.c @@ -1,5 +1,5 @@ /* - * "$Id: admin.c,v 1.22.2.1 2001/05/13 18:38:01 mike Exp $" + * "$Id: admin.c,v 1.22.2.2 2001/12/26 16:52:08 mike Exp $" * * Administration CGI for the Common UNIX Printing System (CUPS). * @@ -549,7 +549,8 @@ do_am_printer(http_t *http, /* I - HTTP connection */ else oldinfo = NULL; - if ((name = cgiGetVariable("PRINTER_NAME")) == NULL) + if ((name = cgiGetVariable("PRINTER_NAME")) == NULL || + cgiGetVariable("PRINTER_LOCATION") == NULL) { if (modify) { @@ -1594,5 +1595,5 @@ get_line(char *buf, /* I - Line buffer */ /* - * End of "$Id: admin.c,v 1.22.2.1 2001/05/13 18:38:01 mike Exp $". + * End of "$Id: admin.c,v 1.22.2.2 2001/12/26 16:52:08 mike Exp $". */ diff --git a/cgi-bin/template.c b/cgi-bin/template.c index b95e0f356a..088cbb122d 100644 --- a/cgi-bin/template.c +++ b/cgi-bin/template.c @@ -1,5 +1,5 @@ /* - * "$Id: template.c,v 1.22 2001/01/22 15:03:22 mike Exp $" + * "$Id: template.c,v 1.22.2.1 2001/12/26 16:52:09 mike Exp $" * * CGI template function. * @@ -480,11 +480,13 @@ cgi_puts(const char *s, { while (*s) { - if (s[0] == '<' && s[1] != '/' && !isalpha(s[1])) + if (s[0] == '<') fputs("<", out); + else if (s[0] == '>') + fputs(">", out); else if (*s == '\"') fputs(""", out); - else if (s[0] == '&' && isspace(s[1])) + else if (s[0] == '&') fputs("&", out); else putc(*s, out); @@ -495,5 +497,5 @@ cgi_puts(const char *s, /* - * End of "$Id: template.c,v 1.22 2001/01/22 15:03:22 mike Exp $". + * End of "$Id: template.c,v 1.22.2.1 2001/12/26 16:52:09 mike Exp $". */ diff --git a/conf/Makefile b/conf/Makefile index 47c71ff88b..539626579e 100644 --- a/conf/Makefile +++ b/conf/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.10 2001/01/22 15:03:23 mike Exp $" +# "$Id: Makefile,v 1.10.2.1 2001/12/26 16:52:09 mike Exp $" # # Configuration file makefile for the Common UNIX Printing System (CUPS). # @@ -51,8 +51,7 @@ clean: # install: - -$(MKDIR) $(SERVERROOT) - $(CHMOD) ugo+rx $(SERVERROOT) + $(INSTALL_DIR) $(SERVERROOT) for file in $(KEEP); do \ if test -r $(SERVERROOT)/$$file ; then \ $(INSTALL_DATA) $$file $(SERVERROOT)/$$file.N ; \ @@ -69,5 +68,5 @@ install: # -# End of "$Id: Makefile,v 1.10 2001/01/22 15:03:23 mike Exp $". +# End of "$Id: Makefile,v 1.10.2.1 2001/12/26 16:52:09 mike Exp $". # diff --git a/conf/cupsd.conf b/conf/cupsd.conf index 462abc1502..e03f97e079 100644 --- a/conf/cupsd.conf +++ b/conf/cupsd.conf @@ -1,5 +1,5 @@ # -# "$Id: cupsd.conf,v 1.32.2.1 2001/04/02 19:51:42 mike Exp $" +# "$Id: cupsd.conf,v 1.32.2.2 2001/12/26 16:52:09 mike Exp $" # # Sample configuration file for the Common UNIX Printing System (CUPS) # scheduler. @@ -75,6 +75,7 @@ # Classification: the classification level of the server. If set, this # classification is displayed on all pages, and raw printing is disabled. # The default is the empty string. +# #Classification classified #Classification confidential @@ -82,6 +83,17 @@ #Classification topsecret #Classification unclassified +# +# ClassifyOverride: whether to allow users to override the classification +# on printouts. If enabled, users can limit banner pages to before or +# after the job, and can change the classification of a job, but cannot +# completely eliminate the classification or banners. +# +# The default is off. +# + +#ClassifyOverride off + # # DataDir: the root directory for the CUPS data files. # By default /usr/share/cups. @@ -184,10 +196,10 @@ LogLevel info # # MaxJobs: maximum number of jobs to keep in memory (active and completed.) -# Default is 0 (no limit.) +# Default is 500; the value 0 is used for no limit. # -#MaxJobs 0 +#MaxJobs 500 # # Printcap: the name of the printcap file. Default is /etc/printcap. @@ -370,6 +382,25 @@ Port 631 #Browsing On +# +# BrowseProtocols: which protocols to use for browsing. Can be +# any of the following separated by whitespace and/or commas: +# +# all - Use all supported protocols. +# cups - Use the CUPS browse protocol. +# slp - Use the SLPv2 protocol. +# +# The default is "cups". +# +# NOTE: If you choose to use SLPv2, it is *strongly* recommended that +# you have at least one SLP Directory Agent (DA) on your +# network. Otherwise, browse updates can take several seconds, +# during which the scheduler will not response to client +# requests. +# + +#BrowseProtocols cups + # # BrowseAddress: specifies a broadcast address to be used. By # default browsing information is not sent! @@ -494,6 +525,36 @@ Port 631 #ImplicitClasses On +# +# ImplicitAnyClasses: whether or not to create "AnyPrinter" implicit +# classes. +# +# When ImplicitAnyClasses is On and a local queue of the same name +# exists, e.g. "printer", "printer@server1", "printer@server1", then +# an implicit class called "Anyprinter" is created instead. +# +# When ImplicitAnyClasses is Off, implicit classes are not created +# when there is a local queue of the same name. +# +# Disabled by default. +# + +#ImplicitAnyCLasses Off + +# +# HideImplicitMembers: whether or not to show the members of an +# implicit class. +# +# When HideImplicitMembers is On, any remote printers that are +# part of an implicit class are hidden from the user, who will +# then only see a single queue even though many queues will be +# supporting the implicit class. +# +# Enabled by default. +# + +#HideImplicitMembers On + ######## ######## Security Options @@ -654,5 +715,5 @@ Allow From 127.0.0.1 # -# End of "$Id: cupsd.conf,v 1.32.2.1 2001/04/02 19:51:42 mike Exp $". +# End of "$Id: cupsd.conf,v 1.32.2.2 2001/12/26 16:52:09 mike Exp $". # diff --git a/conf/mime.types b/conf/mime.types index fadc5aad4b..12dc0c7a31 100644 --- a/conf/mime.types +++ b/conf/mime.types @@ -1,5 +1,5 @@ # -# "$Id: mime.types,v 1.17.2.1 2001/05/13 18:38:02 mike Exp $" +# "$Id: mime.types,v 1.17.2.2 2001/12/26 16:52:09 mike Exp $" # # MIME types file for the Common UNIX Printing System (CUPS). # @@ -131,6 +131,7 @@ text/plain txt printable(0,1024) application/vnd.cups-form string(0,"") application/vnd.cups-postscript string(0,<1B>%-12345X) + \ (contains(9,512,"LANGUAGE=POSTSCRIPT") \ + contains(9,512,"LANGUAGE = Postscript") \ contains(9,512,"LANGUAGE = POSTSCRIPT")) application/vnd.cups-raster string(0,"RaSt") string(0,"tSaR") application/vnd.cups-raw (string(0,<1B>E) + !string(2,<1B>%0B)) \ @@ -151,5 +152,5 @@ application/vnd.cups-raw (string(0,<1B>E) + !string(2,<1B>%0B)) \ #application/octet-stream # -# End of "$Id: mime.types,v 1.17.2.1 2001/05/13 18:38:02 mike Exp $". +# End of "$Id: mime.types,v 1.17.2.2 2001/12/26 16:52:09 mike Exp $". # diff --git a/config-scripts/cups-common.m4 b/config-scripts/cups-common.m4 index e7bf3eec25..12e3192529 100644 --- a/config-scripts/cups-common.m4 +++ b/config-scripts/cups-common.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-common.m4,v 1.12 2001/11/02 17:34:54 mike Exp $" +dnl "$Id: cups-common.m4,v 1.12.2.1 2001/12/26 16:52:10 mike Exp $" dnl dnl Common configuration stuff for the Common UNIX Printing System (CUPS). dnl @@ -150,5 +150,5 @@ esac AC_SUBST(ARFLAGS) dnl -dnl End of "$Id: cups-common.m4,v 1.12 2001/11/02 17:34:54 mike Exp $". +dnl End of "$Id: cups-common.m4,v 1.12.2.1 2001/12/26 16:52:10 mike Exp $". dnl diff --git a/config-scripts/cups-compiler.m4 b/config-scripts/cups-compiler.m4 index c5b4a90f33..cdb1c714a5 100644 --- a/config-scripts/cups-compiler.m4 +++ b/config-scripts/cups-compiler.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-compiler.m4,v 1.9 2001/11/02 17:34:54 mike Exp $" +dnl "$Id: cups-compiler.m4,v 1.9.2.1 2001/12/26 16:52:10 mike Exp $" dnl dnl Common configuration stuff for the Common UNIX Printing System (CUPS). dnl @@ -148,5 +148,5 @@ case $uname in esac dnl -dnl End of "$Id: cups-compiler.m4,v 1.9 2001/11/02 17:34:54 mike Exp $". +dnl End of "$Id: cups-compiler.m4,v 1.9.2.1 2001/12/26 16:52:10 mike Exp $". dnl diff --git a/config-scripts/cups-directories.m4 b/config-scripts/cups-directories.m4 index dd8cd0ff18..b43675641c 100644 --- a/config-scripts/cups-directories.m4 +++ b/config-scripts/cups-directories.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-directories.m4,v 1.5 2001/11/02 17:34:54 mike Exp $" +dnl "$Id: cups-directories.m4,v 1.5.2.1 2001/12/26 16:52:10 mike Exp $" dnl dnl Directory stuff for the Common UNIX Printing System (CUPS). dnl @@ -232,5 +232,5 @@ dnl Set the CUPS_FONTPATH directory... AC_DEFINE_UNQUOTED(CUPS_FONTPATH, "$fontpath") dnl -dnl End of "$Id: cups-directories.m4,v 1.5 2001/11/02 17:34:54 mike Exp $". +dnl End of "$Id: cups-directories.m4,v 1.5.2.1 2001/12/26 16:52:10 mike Exp $". dnl diff --git a/config-scripts/cups-image.m4 b/config-scripts/cups-image.m4 index d861a0d049..1e6a176fb0 100644 --- a/config-scripts/cups-image.m4 +++ b/config-scripts/cups-image.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-image.m4,v 1.2 2001/10/04 16:50:18 mike Exp $" +dnl "$Id: cups-image.m4,v 1.2.2.1 2001/12/26 16:52:10 mike Exp $" dnl dnl Image library stuff for the Common UNIX Printing System (CUPS). dnl @@ -68,5 +68,5 @@ LIBS="$SAVELIBS" AC_CHECK_HEADER(stdlib.h,AC_DEFINE(HAVE_STDLIB_H)) dnl -dnl End of "$Id: cups-image.m4,v 1.2 2001/10/04 16:50:18 mike Exp $". +dnl End of "$Id: cups-image.m4,v 1.2.2.1 2001/12/26 16:52:10 mike Exp $". dnl diff --git a/config-scripts/cups-libtool.m4 b/config-scripts/cups-libtool.m4 index 8329c1d42f..6904e4bd75 100644 --- a/config-scripts/cups-libtool.m4 +++ b/config-scripts/cups-libtool.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-libtool.m4,v 1.2 2001/08/06 19:37:09 mike Exp $" +dnl "$Id: cups-libtool.m4,v 1.2.2.1 2001/12/26 16:52:10 mike Exp $" dnl dnl Libtool stuff for the Common UNIX Printing System (CUPS). dnl @@ -45,5 +45,5 @@ if test x$LIBTOOL != x; then fi dnl -dnl End of "$Id: cups-libtool.m4,v 1.2 2001/08/06 19:37:09 mike Exp $". +dnl End of "$Id: cups-libtool.m4,v 1.2.2.1 2001/12/26 16:52:10 mike Exp $". dnl diff --git a/config-scripts/cups-manpages.m4 b/config-scripts/cups-manpages.m4 index 61f0da585e..b418de610a 100644 --- a/config-scripts/cups-manpages.m4 +++ b/config-scripts/cups-manpages.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-manpages.m4,v 1.5 2001/11/02 17:34:54 mike Exp $" +dnl "$Id: cups-manpages.m4,v 1.5.2.1 2001/12/26 16:52:10 mike Exp $" dnl dnl Manpage stuff for the Common UNIX Printing System (CUPS). dnl @@ -100,5 +100,5 @@ AC_SUBST(MAN8EXT) AC_SUBST(MAN8DIR) dnl -dnl End of "$Id: cups-manpages.m4,v 1.5 2001/11/02 17:34:54 mike Exp $". +dnl End of "$Id: cups-manpages.m4,v 1.5.2.1 2001/12/26 16:52:10 mike Exp $". dnl diff --git a/config-scripts/cups-network.m4 b/config-scripts/cups-network.m4 index 473996e931..282c13f287 100644 --- a/config-scripts/cups-network.m4 +++ b/config-scripts/cups-network.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-network.m4,v 1.1 2001/06/27 19:06:45 mike Exp $" +dnl "$Id: cups-network.m4,v 1.1.2.1 2001/12/26 16:52:10 mike Exp $" dnl dnl Networking stuff for the Common UNIX Printing System (CUPS). dnl @@ -32,5 +32,5 @@ fi AC_SUBST(NETLIBS) dnl -dnl End of "$Id: cups-network.m4,v 1.1 2001/06/27 19:06:45 mike Exp $". +dnl End of "$Id: cups-network.m4,v 1.1.2.1 2001/12/26 16:52:10 mike Exp $". dnl diff --git a/config-scripts/cups-openslp.m4 b/config-scripts/cups-openslp.m4 index 25a0985e5f..c077e06eba 100644 --- a/config-scripts/cups-openslp.m4 +++ b/config-scripts/cups-openslp.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-openslp.m4,v 1.2 2001/07/24 20:23:03 mike Exp $" +dnl "$Id: cups-openslp.m4,v 1.2.2.1 2001/12/26 16:52:10 mike Exp $" dnl dnl OpenSLP configuration stuff for the Common UNIX Printing System (CUPS). dnl @@ -43,5 +43,5 @@ AC_SUBST(LIBSLP) dnl -dnl End of "$Id: cups-openslp.m4,v 1.2 2001/07/24 20:23:03 mike Exp $". +dnl End of "$Id: cups-openslp.m4,v 1.2.2.1 2001/12/26 16:52:10 mike Exp $". dnl diff --git a/config-scripts/cups-openssl.m4 b/config-scripts/cups-openssl.m4 index 1177c9b522..7aea86c05b 100644 --- a/config-scripts/cups-openssl.m4 +++ b/config-scripts/cups-openssl.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-openssl.m4,v 1.4 2001/07/24 20:23:03 mike Exp $" +dnl "$Id: cups-openssl.m4,v 1.4.2.1 2001/12/26 16:52:10 mike Exp $" dnl dnl OpenSSL stuff for the Common UNIX Printing System (CUPS). dnl @@ -65,5 +65,5 @@ fi AC_SUBST(SSLLIBS) dnl -dnl End of "$Id: cups-openssl.m4,v 1.4 2001/07/24 20:23:03 mike Exp $". +dnl End of "$Id: cups-openssl.m4,v 1.4.2.1 2001/12/26 16:52:10 mike Exp $". dnl diff --git a/config-scripts/cups-opsys.m4 b/config-scripts/cups-opsys.m4 index 17b7dea299..eef9c81579 100644 --- a/config-scripts/cups-opsys.m4 +++ b/config-scripts/cups-opsys.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-opsys.m4,v 1.5 2001/07/24 20:23:03 mike Exp $" +dnl "$Id: cups-opsys.m4,v 1.5.2.1 2001/12/26 16:52:10 mike Exp $" dnl dnl Operating system stuff for the Common UNIX Printing System (CUPS). dnl @@ -81,5 +81,5 @@ AC_DEFINE_UNQUOTED(CUPS_DEFAULT_USER, "$CUPS_USER") AC_DEFINE_UNQUOTED(CUPS_DEFAULT_GROUP, "$CUPS_GROUP") dnl -dnl "$Id: cups-opsys.m4,v 1.5 2001/07/24 20:23:03 mike Exp $" +dnl "$Id: cups-opsys.m4,v 1.5.2.1 2001/12/26 16:52:10 mike Exp $" dnl diff --git a/config-scripts/cups-pam.m4 b/config-scripts/cups-pam.m4 index 7beeba8725..4cfc2df183 100644 --- a/config-scripts/cups-pam.m4 +++ b/config-scripts/cups-pam.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-pam.m4,v 1.2 2001/07/24 20:23:03 mike Exp $" +dnl "$Id: cups-pam.m4,v 1.2.2.1 2001/12/26 16:52:11 mike Exp $" dnl dnl PAM stuff for the Common UNIX Printing System (CUPS). dnl @@ -55,5 +55,5 @@ AC_SUBST(PAMDIR) AC_SUBST(PAMLIBS) dnl -dnl End of "$Id: cups-pam.m4,v 1.2 2001/07/24 20:23:03 mike Exp $". +dnl End of "$Id: cups-pam.m4,v 1.2.2.1 2001/12/26 16:52:11 mike Exp $". dnl diff --git a/config-scripts/cups-sharedlibs.m4 b/config-scripts/cups-sharedlibs.m4 index 13bf562cf0..05a42c7b9f 100644 --- a/config-scripts/cups-sharedlibs.m4 +++ b/config-scripts/cups-sharedlibs.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-sharedlibs.m4,v 1.6 2001/10/26 03:16:47 mike Exp $" +dnl "$Id: cups-sharedlibs.m4,v 1.6.2.1 2001/12/26 16:52:11 mike Exp $" dnl dnl Shared library support for the Common UNIX Printing System (CUPS). dnl @@ -30,26 +30,26 @@ AC_ARG_ENABLE(shared, [ --enable-shared turn on shared libraries [defau if test x$enable_shared != xno; then case "$uname" in SunOS* | UNIX_S*) - LIBCUPS="libcups.so.2" - LIBCUPSIMAGE="libcupsimage.so.2" + LIBCUPS="libcups.so.3" + LIBCUPSIMAGE="libcupsimage.so.3" DSO="\$(CC)" DSOFLAGS="$DSOFLAGS -Wl,-h,\$@ -G \$(OPTIM)" ;; HP-UX*) - LIBCUPS="libcups.sl.2" - LIBCUPSIMAGE="libcupsimage.sl.2" + LIBCUPS="libcups.sl.3" + LIBCUPSIMAGE="libcupsimage.sl.3" DSO="ld" DSOFLAGS="$DSOFLAGS -b -z +h \$@" ;; OSF1* | Linux* | IRIX* | FreeBSD* | NetBSD* | OpenBSD*) - LIBCUPS="libcups.so.2" - LIBCUPSIMAGE="libcupsimage.so.2" + LIBCUPS="libcups.so.3" + LIBCUPSIMAGE="libcupsimage.so.3" DSO="\$(CC)" DSOFLAGS="$DSOFLAGS -Wl,-soname,\$@ -shared \$(OPTIM)" ;; Darwin*) - LIBCUPS="libcups.2.dylib" - LIBCUPSIMAGE="libcupsimage.2.dylib" + LIBCUPS="libcups.3.dylib" + LIBCUPSIMAGE="libcupsimage.3.dylib" DSO="ld" DSOFLAGS="$DSOFLAGS -dylib /usr/lib/dylib1.o -lc" ;; @@ -62,8 +62,8 @@ if test x$enable_shared != xno; then *) echo "Warning: shared libraries may not be supported. Trying -shared" echo " option with compiler." - LIBCUPS="libcups.so.2" - LIBCUPSIMAGE="libcupsimage.so.2" + LIBCUPS="libcups.so.3" + LIBCUPSIMAGE="libcupsimage.so.3" DSO="\$(CC)" DSOFLAGS="$DSOFLAGS -Wl,-soname,\$@ -shared \$(OPTIM)" ;; @@ -141,5 +141,5 @@ AC_SUBST(DSOLIBS) AC_SUBST(IMGLIBS) dnl -dnl End of "$Id: cups-sharedlibs.m4,v 1.6 2001/10/26 03:16:47 mike Exp $". +dnl End of "$Id: cups-sharedlibs.m4,v 1.6.2.1 2001/12/26 16:52:11 mike Exp $". dnl diff --git a/config.h.in b/config.h.in index 369de49c62..cc8798850c 100644 --- a/config.h.in +++ b/config.h.in @@ -1,5 +1,5 @@ /* - * "$Id: config.h.in,v 1.39.2.2 2001/05/13 18:37:58 mike Exp $" + * "$Id: config.h.in,v 1.39.2.3 2001/12/26 16:52:05 mike Exp $" * * Configuration file for the Common UNIX Printing System (CUPS). * @@ -30,6 +30,15 @@ #define CUPS_SVERSION "CUPS v1.2.0" + +/* + * Default user and group... + */ + +#define CUPS_DEFAULT_USER "lp" +#define CUPS_DEFAULT_GROUP "sys" + + /* * Where are files stored? */ @@ -43,12 +52,14 @@ #define CUPS_DATADIR "/usr/share/cups" #define CUPS_FONTPATH "/usr/share/cups/fonts" + /* * What is the format string for strftime? */ #define CUPS_STRFTIME_FORMAT NULL + /* * Do we have various image libraries? */ @@ -58,12 +69,14 @@ #undef HAVE_LIBJPEG #undef HAVE_LIBTIFF + /* * Does this machine store words in big-endian (MSB-first) order? */ #undef WORDS_BIGENDIAN + /* * Which directory functions and headers do we use? */ @@ -73,6 +86,7 @@ #undef HAVE_SYS_NDIR_H #undef HAVE_NDIR_H + /* * Do we have PAM stuff? */ @@ -81,18 +95,21 @@ #define HAVE_LIBPAM 0 #endif /* !HAVE_LIBPAM */ + /* * Do we have ? */ #undef HAVE_SHADOW_H + /* * Do we have ? */ #undef HAVE_CRYPT_H + /* * Use , , or both? */ @@ -100,6 +117,7 @@ #undef HAVE_STRING_H #undef HAVE_STRINGS_H + /* * Do we have the strXXX() functions? */ @@ -108,12 +126,14 @@ #undef HAVE_STRCASECMP #undef HAVE_STRNCASECMP + /* * Do we have the vsyslog() function? */ #undef HAVE_VSYSLOG + /* * Do we have the (v)snprintf() functions? */ @@ -121,6 +141,7 @@ #undef HAVE_SNPRINTF #undef HAVE_VSNPRINTF + /* * What signal functions to use? */ @@ -128,6 +149,7 @@ #undef HAVE_SIGSET #undef HAVE_SIGACTION + /* * What wait functions to use? */ @@ -135,6 +157,7 @@ #undef HAVE_WAITPID #undef HAVE_WAIT3 + /* * Do we have the mallinfo function and malloc.h? */ @@ -142,18 +165,43 @@ #undef HAVE_MALLINFO #undef HAVE_MALLOC_H + /* * Do we have the OpenSSL library? */ #undef HAVE_LIBSSL + +/* + * Do we have the OpenSLP library? + */ + +#undef HAVE_LIBSLP + + /* * Do we have ? */ #undef HAVE_SYS_IOCTL_H + +/* + * Do we have mkstemp() and/or mkstemps()? + */ + +#undef HAVE_MKSTEMP +#undef HAVE_MKSTEMPS + + +/* + * Does the "tm" structure contain the "tm_gmtoff" member? + */ + +#undef HAVE_TM_GMTOFF + + /* - * End of "$Id: config.h.in,v 1.39.2.2 2001/05/13 18:37:58 mike Exp $". + * End of "$Id: config.h.in,v 1.39.2.3 2001/12/26 16:52:05 mike Exp $". */ diff --git a/configure.in b/configure.in index 0491dcdf31..344d3e63bb 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl -dnl "$Id: configure.in,v 1.83.2.2 2001/05/13 18:37:58 mike Exp $" +dnl "$Id: configure.in,v 1.83.2.3 2001/12/26 16:52:05 mike Exp $" dnl dnl Configuration script for the Common UNIX Printing System (CUPS). dnl @@ -23,680 +23,26 @@ dnl WWW: http://www.cups.org dnl AC_INIT(cups/cups.h) -AC_CONFIG_HEADER(config.h) -AC_PREFIX_DEFAULT(/) -dnl Get the operating system and version number... +sinclude(config-scripts/cups-opsys.m4) +sinclude(config-scripts/cups-common.m4) +sinclude(config-scripts/cups-directories.m4) +sinclude(config-scripts/cups-manpages.m4) -uname=`uname` -uversion=`uname -r | sed -e '1,$s/[[^0-9]]//g'` -if test "$uname" = "IRIX64"; then - uname="IRIX" -fi +sinclude(config-scripts/cups-sharedlibs.m4) +sinclude(config-scripts/cups-libtool.m4) +sinclude(config-scripts/cups-compiler.m4) -dnl Clear the debugging and non-shared library options unless the user asks -dnl for them... +sinclude(config-scripts/cups-image.m4) +sinclude(config-scripts/cups-network.m4) +sinclude(config-scripts/cups-openslp.m4) +sinclude(config-scripts/cups-openssl.m4) +sinclude(config-scripts/cups-pam.m4) -OPTIM="" -AC_SUBST(OPTIM) -PICFLAG=1 -CFLAGS="${CFLAGS:=}" -CXXFLAGS="${CXXFLAGS:=}" -DSOFLAGS="${DSOFLAGS:=}" -AC_SUBST(DSOFLAGS) +AC_OUTPUT(Makedefs cups.list cups.sh cups-config) -AC_ARG_ENABLE(debug, [ --enable-debug turn on debugging [default=no]],[if eval "test x$enable_debug = xyes"; then - OPTIM="-g" -fi]) -AC_ARG_ENABLE(shared, [ --enable-shared turn on shared libraries [default=yes]]) -AC_ARG_ENABLE(ssl, [ --enable-ssl turn on SSL/TLS support [default=yes]]) -AC_ARG_ENABLE(libtool_unsupported, [ --enable-libtool-unsupported=LIBTOOL_PATH - turn on building with libtool (UNSUPPORTED!) [default=no]],[if eval "test x$enable_libtool_unsupported != xno"; then - LIBTOOL="$enable_libtool_unsupported" - enable_shared=no - echo "WARNING: libtool is not supported or endorsed by Easy Software Products." - echo " WE DO NOT PROVIDE TECHNICAL SUPPORT FOR LIBTOOL PROBLEMS." - echo " (even if you have a support contract)" -else - LIBTOOL="" -fi]) - -if test "$enable_shared" != "no"; then - case "$uname" in - SunOS* | UNIX_S*) - LIBCUPS="libcups.so.3" - LIBCUPSIMAGE="libcupsimage.so.2" - DSO="\$(CC)" - DSOFLAGS="$DSOFLAGS -Wl,-h,\$@ -G \$(OPTIM)" - ;; - HP-UX*) - LIBCUPS="libcups.sl.3" - LIBCUPSIMAGE="libcupsimage.sl.2" - DSO="ld" - DSOFLAGS="$DSOFLAGS -b -z +h \$@" - ;; - FreeBSD* | NetBSD* | OpenBSD*) - LIBCUPS="libcups.so.3" - LIBCUPSIMAGE="libcupsimage.so.2" - DSO="\$(CC)" - DSOFLAGS="$DSOFLAGS -Wl,-soname,\$@ -shared \$(OPTIM)" - ;; - OSF1* | Linux*) - LIBCUPS="libcups.so.3" - LIBCUPSIMAGE="libcupsimage.so.2" - DSO="\$(CC)" - DSOFLAGS="$DSOFLAGS -Wl,-soname,\$@ -shared \$(OPTIM)" - ;; - IRIX*) - LIBCUPS="libcups.so.3" - LIBCUPSIMAGE="libcupsimage.so.2" - DSO="\$(CC)" - DSOFLAGS="$DSOFLAGS -soname \$@ -shared \$(OPTIM)" - ;; - AIX*) - AC_MSG_WARN(Shared library support for AIX not available yet - defaulting to static) - enable_shared=no - PICFLAG=0 - LIBCUPS="libcups.a" - LIBCUPSIMAGE="libcupsimage.a" - DSO=":" - ;; - *) - echo "Warning: shared libraries may not be supported. Trying -shared" - echo " option with compiler." - LIBCUPS="libcups.so.3" - LIBCUPSIMAGE="libcupsimage.so.2" - DSO="\$(CC)" - DSOFLAGS="$DSOFLAGS -Wl,-soname,\$@ -shared \$(OPTIM)" - ;; - esac -else - PICFLAG=0 - LIBCUPS="libcups.a" - LIBCUPSIMAGE="libcupsimage.a" - DSO=":" -fi - -if test "$LIBTOOL" != ""; then - LIBCUPS="libcups.la" - LIBCUPSIMAGE="libcupsimage.la" - LINKCUPS="../cups/\$(LIBCUPS)" - LINKCUPSIMAGE="../filter/\$(LIBCUPSIMAGE)" - DSO=":" - DSOFLAGS="" -else - LINKCUPS="-L../cups -lcups" - LINKCUPSIMAGE="-L../filter -lcupsimage" -fi - -AC_ARG_ENABLE(pam, [ --enable-pam turn on PAM support [default=yes]]) - -# Don't use PAM with AIX... -if test $uname = AIX; then - enable_pam=no -fi - -AC_ARG_WITH(fontpath, [ --with-fontpath set font path for pstoraster],fontpath="$withval",fontpath="") -AC_ARG_WITH(docdir, [ --with-docdir set path for documentation],docdir="$withval",docdir="") -AC_ARG_WITH(logdir, [ --with-logdir set path for log files],logdir="$withval",logdir="") - -dnl Checks for programs... -AC_PROG_AWK -AC_PROG_CC -AC_PROG_CXX -AC_PROG_CPP -AC_PROG_RANLIB -AC_PATH_PROG(AR,ar) -AC_PATH_PROG(CHMOD,chmod) -AC_PATH_PROG(CHOWN,chown) -AC_PATH_PROG(CP,cp) -AC_PATH_PROG(MV,mv) -AC_PATH_PROG(NROFF,nroff) -if test "$NROFF" = ""; then - AC_PATH_PROG(GROFF,groff) - if test "$GROFF" = ""; then - NROFF="echo" - else - NROFF="$GROFF -T ascii" - fi -fi -AC_PATH_PROG(HTMLDOC,htmldoc) -AC_PATH_PROG(MKDIR,mkdir) -AC_PATH_PROG(RM,rm) -AC_PATH_PROG(SED,sed) - -dnl Architecture checks... -AC_C_BIGENDIAN - -dnl Check for libraries... -AC_CHECK_LIB(c,crypt,LIBS="$LIBS") -if test "$ac_cv_lib_c_crypt" = "no"; then - AC_CHECK_LIB(crypt,crypt) -fi -AC_CHECK_LIB(sec,getspent) - -LIBMALLOC="" -AC_CHECK_LIB(c,mallinfo,LIBS="$LIBS"; AC_DEFINE(HAVE_MALLINFO),LIBS="$LIBS") -if test "$ac_cv_lib_c_mallinfo" = "no"; then - AC_CHECK_LIB(malloc,mallinfo, - LIBS="$LIBS" - LIBMALLOC="-lmalloc" - AC_DEFINE(HAVE_MALLINFO), - LIBS="$LIBS") -fi -AC_SUBST(LIBMALLOC) - -if test "$enable_pam" != "no"; then - OLDLIBS="$LIBS" - AC_CHECK_LIB(dl,dlopen) - AC_CHECK_LIB(pam,pam_start) - if test "$ac_cv_lib_pam_pam_start" != "no"; then - PAMDIR="/etc/pam.d" - else - PAMDIR="" - LIBS="$OLDLIBS" - fi - AC_SUBST(PAMDIR) -fi - -NETLIBS="" -AC_SUBST(NETLIBS) -AC_CHECK_LIB(socket,socket, -if test "$uname" != "IRIX"; then - NETLIBS="-lsocket" -else - echo "Not using -lsocket since you are running IRIX." -fi) -AC_CHECK_LIB(nsl,gethostbyaddr, -if test "$uname" != "IRIX"; then - NETLIBS="$NETLIBS -lnsl" -else - echo "Not using -lnsl since you are running IRIX." -fi) - -dnl Encryption support... - -SSLLIBS="" -AC_SUBST(SSLLIBS) - -if test "$enable_ssl" != "no"; then - dnl Save the current libraries so the crypto stuff isn't always - dnl included... - SAVELIBS="$LIBS" - - dnl Some ELF systems can't resolve all the symbols in libcrypto - dnl if libcrypto was linked against RSAREF, and fail to link the - dnl test program correctly, even though a correct installation - dnl of OpenSSL exists. So we test the linking three times in - dnl case the RSAREF libraries are needed. - - for libcrypto in \ - "-lcrypto" \ - "-lcrypto -lrsaref" \ - "-lcrypto -lRSAglue -lrsaref" - do - AC_CHECK_LIB(ssl,SSL_new, - [SSLLIBS="-lssl $libcrypto" - AC_DEFINE(HAVE_LIBSSL)],, - $libcrypto - ) - if test "x${SSLLIBS}" != "x"; then - break - fi - done - - LIBS="$SAVELIBS" -fi - -dnl Save the current libraries since we don't want the image libraries -dnl included with every program... -SAVELIBS="$LIBS" - -dnl Check for image libraries... -LIBJPEG="" -LIBPNG="" -LIBTIFF="" -LIBZ="" - -AC_SUBST(LIBJPEG) -AC_SUBST(LIBPNG) -AC_SUBST(LIBTIFF) -AC_SUBST(LIBZ) - -AC_CHECK_LIB(jpeg, jpeg_destroy_decompress, - AC_DEFINE(HAVE_LIBJPEG) - LIBJPEG="-ljpeg" - LIBS="$LIBS -ljpeg") - -AC_CHECK_LIB(z, gzgets, - AC_DEFINE(HAVE_LIBZ) - LIBZ="-lz" - LIBS="$LIBS -lz") - -dnl PNG library uses math library functions... -AC_CHECK_LIB(m, pow) - -AC_CHECK_LIB(png, png_set_tRNS_to_alpha, - AC_DEFINE(HAVE_LIBPNG) - LIBPNG="-lpng") - -AC_CHECK_LIB(tiff, TIFFReadScanline, - AC_DEFINE(HAVE_LIBTIFF) - LIBTIFF="-ltiff") - -dnl Restore original LIBS settings... -LIBS="$SAVELIBS" - -dnl Checks for header files. -AC_HEADER_STDC -AC_HEADER_DIRENT -AC_CHECK_HEADER(crypt.h,AC_DEFINE(HAVE_CRYPT_H)) -AC_CHECK_HEADER(malloc.h,AC_DEFINE(HAVE_MALLOC_H)) -AC_CHECK_HEADER(shadow.h,AC_DEFINE(HAVE_SHADOW_H)) -AC_CHECK_HEADER(stddef.h,AC_DEFINE(HAVE_STDDEF_H)) -AC_CHECK_HEADER(stdlib.h,AC_DEFINE(HAVE_STDLIB_H)) -AC_CHECK_HEADER(string.h,AC_DEFINE(HAVE_STRING_H)) -AC_CHECK_HEADER(strings.h,AC_DEFINE(HAVE_STRINGS_H)) -AC_CHECK_HEADER(usersec.h,AC_DEFINE(HAVE_USERSEC_H)) -AC_CHECK_HEADER(sys/ioctl.h,AC_DEFINE(HAVE_SYS_IOCTL_H)) - -dnl Checks for string functions. -AC_CHECK_FUNCS(strdup) -AC_CHECK_FUNCS(strcasecmp) -AC_CHECK_FUNCS(strncasecmp) -if test "$uname" = "HP-UX" -a "$uversion" = "1020"; then - echo Forcing snprintf emulation for HP-UX. -else - AC_CHECK_FUNCS(snprintf) - AC_CHECK_FUNCS(vsnprintf) -fi - -dnl Check OS version and use appropriate format string for strftime... -AC_MSG_CHECKING(for correct format string to use with strftime) - -case "$uname" in - IRIX* | SunOS*) - # IRIX and SunOS - AC_MSG_RESULT(NULL) - AC_DEFINE(CUPS_STRFTIME_FORMAT, NULL) - ;; - *) - # All others - AC_MSG_RESULT("%c") - AC_DEFINE(CUPS_STRFTIME_FORMAT, "%c") - ;; -esac - -dnl Checks for vsyslog function. -AC_CHECK_FUNCS(vsyslog) - -dnl Checks for signal functions. -if test "$uname" != "Linux"; then - AC_CHECK_FUNCS(sigset) -fi - -AC_CHECK_FUNCS(sigaction) - -dnl Checks for wait functions. -AC_CHECK_FUNCS(waitpid) -AC_CHECK_FUNCS(wait3) - -dnl Update compiler options... -if test -n "$GCC"; then - CXX="$CC" - - if test -z "$OPTIM"; then - OPTIM="-O2" - fi - if test $PICFLAG = 1; then - OPTIM="-fPIC $OPTIM" - fi - OPTIM="-Wall $OPTIM" -else - case $uname in - AIX*) - if test -z "$OPTIM"; then - OPTIM="-O2 -qmaxmem=6000" - fi - ;; - HP-UX*) - if test -z "$OPTIM"; then - OPTIM="+O2" - fi - CFLAGS="-Ae $CFLAGS" - OPTIM="+DAportable $OPTIM" - if test $PICFLAG = 1; then - OPTIM="+z $OPTIM" - fi - ;; - IRIX*) - if test -z "$OPTIM"; then - OPTIM="-O2" - fi - if test $uversion -ge 62; then - OPTIM="$OPTIM -n32 -mips3" - fi - OPTIM="-fullwarn $OPTIM" - ;; - SunOS*) - # Solaris - if test -z "$OPTIM"; then - OPTIM="-xO4" - fi - OPTIM="$OPTIM -xarch=generic" - if test $PICFLAG = 1; then - OPTIM="-KPIC $OPTIM" - fi - ;; - *) - # Running some other operating system; inform the user they - # should contribute the necessary options to - # cups-support@cups.org... - echo "Building CUPS with default compiler optimizations; contact" - echo "cups-support@cups.org with uname and compiler options needed" - echo "for your platform, or set the CFLAGS environment variable" - echo "before running configure." - ;; - esac -fi - -if test "$DSO" != ":"; then - # When using DSOs the image libraries are linked to libcupsimage.so - # rather than to the executables. This makes things smaller if you - # are using any static libraries, and it also allows us to distribute - # a single DSO rather than a bunch... - DSOLIBS="\$(LIBPNG) \$(LIBTIFF) \$(LIBJPEG) \$(LIBZ)" - IMGLIBS="" - - # The *BSD, HP-UX, and Solaris run-time linkers need help when - # deciding where to find a DSO. Add linker options to tell them - # where to find the DSO (usually in /usr/lib... duh!) - case $uname in - HP-UX*) - # HP-UX - DSOFLAGS="+b $libdir +fb $DSOFLAGS" - LDFLAGS="$LDFLAGS -Wl,+b,$libdir,+fb" - ;; - SunOS*) - # Solaris - DSOFLAGS="-R$libdir $DSOFLAGS" - LDFLAGS="$LDFLAGS -R$libdir" - ;; - FreeBSD* | NetBSD* | OpenBSD*) - # *BSD - DSOFLAGS="-Wl,-R$libdir $DSOFLAGS" - LDFLAGS="$LDFLAGS -Wl,-R$libdir" - ;; - esac -else - DSOLIBS="" - IMGLIBS="\$(LIBPNG) \$(LIBTIFF) \$(LIBJPEG) \$(LIBZ)" -fi - -AC_SUBST(DSO) -AC_SUBST(DSOLIBS) -AC_SUBST(IMGLIBS) -AC_SUBST(LIBCUPS) -AC_SUBST(LIBCUPSIMAGE) -AC_SUBST(LIBTOOL) -AC_SUBST(LINKCUPS) -AC_SUBST(LINKCUPSIMAGE) - -dnl Fix "prefix" variable if it hasn't been specified... -if test "$prefix" = "NONE"; then - prefix="/" -fi - -dnl Fix "exec_prefix" variable if it hasn't been specified... -if test "$exec_prefix" = "NONE"; then - if test "$prefix" = "/"; then - exec_prefix="/usr" - else - exec_prefix="$prefix" - fi -fi - -dnl Fix "sharedstatedir" variable if it hasn't been specified... -if test "$sharedstatedir" = "\${prefix}/com" -a "$prefix" = "/"; then - sharedstatedir="/usr/com" -fi - -dnl Fix "datadir" variable if it hasn't been specified... -if test "$datadir" = "\${prefix}/share"; then - if test "$prefix" = "/"; then - datadir="/usr/share" - else - datadir="$prefix/share" - fi -fi - -dnl Fix "includedir" variable if it hasn't been specified... -if test "$includedir" = "\${prefix}/include" -a "$prefix" = "/"; then - includedir="/usr/include" -fi - -dnl Fix "localstatedir" variable if it hasn't been specified... -if test "$localstatedir" = "\${prefix}/var"; then - if test "$prefix" = "/"; then - localstatedir="/var" - else - localstatedir="$prefix/var" - fi -fi - -dnl Fix "sysconfdir" variable if it hasn't been specified... -if test "$sysconfdir" = "\${prefix}/etc"; then - if test "$prefix" = "/"; then - sysconfdir="/etc" - else - sysconfdir="$prefix/etc" - fi -fi - -dnl Fix "libdir" variable for IRIX 6.x... -if test "$uname" = "IRIX" -a $uversion -ge 62; then - libdir="$exec_prefix/lib32" -fi - -dnl Fix "mandir" variable... -if test "$mandir" = "\${prefix}/man" -a "$prefix" = "/"; then - case "$uname" in - FreeBSD* | NetBSD* | OpenBSD* | AIX*) - # *BSD + AIX - mandir="/usr/share/man" - AMANDIR="/usr/share/man" - ;; - IRIX*) - # SGI IRIX - mandir="/usr/share/catman/u_man" - AMANDIR="/usr/share/catman/a_man" - ;; - *) - # All others - mandir="/usr/man" - AMANDIR="/usr/man" - ;; - esac -else - AMANDIR="$mandir" -fi - -AC_SUBST(AMANDIR) - -dnl Fix "fontpath" variable... -if test "x$fontpath" = "x"; then - fontpath="$datadir/cups/fonts" -fi - -dnl Setup manpage extensions... -case "$uname" in - FreeBSD* | NetBSD* | OpenBSD*) - # *BSD - CAT1EXT=0 - CAT5EXT=0 - CAT8EXT=0 - MAN8EXT=8 - ;; - IRIX*) - # SGI IRIX - CAT1EXT=z - CAT5EXT=z - CAT8EXT=z - MAN8EXT=1m - ;; - SunOS* | HP-UX*) - # Solaris and HP-UX - CAT1EXT=1 - CAT5EXT=5 - CAT8EXT=1m - MAN8EXT=1m - ;; - *) - # All others - CAT1EXT=1 - CAT5EXT=5 - CAT8EXT=8 - MAN8EXT=8 - ;; -esac - -AC_SUBST(CAT1EXT) -AC_SUBST(CAT5EXT) -AC_SUBST(CAT8EXT) -AC_SUBST(MAN8EXT) - -dnl Setup init.d locations... -case "$uname" in - FreeBSD* | OpenBSD*) - # FreeBSD and OpenBSD - INITDIR="" - INITDDIR="" - ;; - - NetBSD*) - # NetBSD - INITDIR="" - INITDDIR="/etc/rc.d" - ;; - - Linux*) - # Linux seems to choose an init.d directory at random... - if test -d /sbin/init.d; then - # SuSE - INITDIR="/sbin/init.d" - INITDDIR=".." - else - if test -d /etc/rc.d; then - # RedHat - INITDIR="/etc/rc.d" - INITDDIR="../init.d" - else - # Others - INITDIR="/etc" - INITDDIR="../init.d" - fi - fi - ;; - - OSF1* | HP-UX*) - INITDIR="/sbin" - INITDDIR="../init.d" - ;; - - AIX*) - INITDIR="/etc/rc.d" - INITDDIR=".." - ;; - - *) - INITDIR="/etc" - INITDDIR="../init.d" - ;; - -esac - -AC_SUBST(INITDIR) -AC_SUBST(INITDDIR) - -dnl Setup default locations... -CUPS_SERVERROOT='${sysconfdir}/cups' -CUPS_REQUESTS='${localstatedir}/spool/cups' - -AC_DEFINE_UNQUOTED(CUPS_SERVERROOT, "$sysconfdir/cups") -AC_DEFINE_UNQUOTED(CUPS_REQUESTS, "$localstatedir/spool/cups") - -if test x$logdir = x; then - CUPS_LOGDIR='${localstatedir}/log/cups' - AC_DEFINE_UNQUOTED(CUPS_LOGDIR, "$localstatedir/log/cups") -else - CUPS_LOGDIR="$logdir" - AC_DEFINE_UNQUOTED(CUPS_LOGDIR, "$logdir") -fi - -dnl See what directory to put server executables... -case "$uname" in - FreeBSD* | NetBSD* | OpenBSD*) - # *BSD - INSTALL_SYSV="" - CUPS_SERVERBIN='${exec_prefix}/libexec/cups' - AC_DEFINE_UNQUOTED(CUPS_SERVERBIN, "$exec_prefix/libexec/cups") - ;; - *) - # All others - INSTALL_SYSV="install-sysv" - CUPS_SERVERBIN='${exec_prefix}/lib/cups' - AC_DEFINE_UNQUOTED(CUPS_SERVERBIN, "$exec_prefix/lib/cups") - ;; -esac - -AC_SUBST(INSTALL_SYSV) -AC_SUBST(CUPS_SERVERROOT) -AC_SUBST(CUPS_SERVERBIN) -AC_SUBST(CUPS_LOGDIR) -AC_SUBST(CUPS_REQUESTS) - -dnl Set the CUPS_LOCALE directory... -case "$uname" in - Linux* | FreeBSD* | NetBSD* | OpenBSD*) - CUPS_LOCALEDIR='${datadir}/locale' - AC_DEFINE_UNQUOTED(CUPS_LOCALEDIR, "$datadir/locale") - ;; - - OSF1* | AIX*) - CUPS_LOCALEDIR='${exec_prefix}/lib/nls/msg' - AC_DEFINE_UNQUOTED(CUPS_LOCALEDIR, "$exec_prefix/lib/nls/msg") - ;; - - *) - # This is the standard System V location... - CUPS_LOCALEDIR='${exec_prefix}/lib/locale' - AC_DEFINE_UNQUOTED(CUPS_LOCALEDIR, "$exec_prefix/lib/locale") - ;; -esac - -AC_SUBST(CUPS_LOCALEDIR) - -dnl Set the CUPS_DATADIR directory... -CUPS_DATADIR='${datadir}/cups' -AC_DEFINE_UNQUOTED(CUPS_DATADIR, "$datadir/cups") -AC_SUBST(CUPS_DATADIR) - -dnl Set the CUPS_DOCROOT directory... -if test x$docdir = x; then - CUPS_DOCROOT='${datadir}/doc/cups' - docdir="$datadir/doc/cups" -else - CUPS_DOCROOT="$docdir" -fi - -AC_DEFINE_UNQUOTED(CUPS_DOCROOT, "$docdir") -AC_SUBST(CUPS_DOCROOT) - -dnl Set the CUPS_FONTPATH directory... -AC_DEFINE_UNQUOTED(CUPS_FONTPATH, "$fontpath") - -AC_OUTPUT(Makedefs cups.sh) +chmod +x cups-config dnl -dnl End of "$Id: configure.in,v 1.83.2.2 2001/05/13 18:37:58 mike Exp $". +dnl End of "$Id: configure.in,v 1.83.2.3 2001/12/26 16:52:05 mike Exp $". dnl diff --git a/cups-config.in b/cups-config.in index 74e1abfae5..7d75654881 100755 --- a/cups-config.in +++ b/cups-config.in @@ -1,6 +1,6 @@ #! /bin/sh # -# "$Id: cups-config.in,v 1.3 2001/11/16 18:05:21 mike Exp $" +# "$Id: cups-config.in,v 1.3.2.1 2001/12/26 16:52:05 mike Exp $" # # CUPS configuration utility. # @@ -129,5 +129,5 @@ while test $# -gt 0; do done # -# End of "$Id: cups-config.in,v 1.3 2001/11/16 18:05:21 mike Exp $". +# End of "$Id: cups-config.in,v 1.3.2.1 2001/12/26 16:52:05 mike Exp $". # diff --git a/cups.list b/cups.list deleted file mode 100644 index 8d78311b47..0000000000 --- a/cups.list +++ /dev/null @@ -1,320 +0,0 @@ -# -# "$Id: cups.list,v 1.85.2.1 2001/05/13 18:37:58 mike Exp $" -# -# ESP Package Manager (EPM) file list for the Common UNIX Printing -# System (CUPS). -# -# Copyright 1997-2001 by Easy Software Products, all rights reserved. -# -# These coded instructions, statements, and computer programs are the -# property of Easy Software Products 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 missing or damaged please contact Easy Software Products -# at: -# -# Attn: CUPS Licensing Information -# Easy Software Products -# 44141 Airport View Drive, Suite 204 -# Hollywood, Maryland 20636-3111 USA -# -# Voice: (301) 373-9603 -# EMail: cups-info@cups.org -# WWW: http://www.cups.org -# - -# Product information -%product Common UNIX Printing System -%copyright 1993-2001 by Easy Software Products, All Rights Reserved. -%vendor Easy Software Products -%license LICENSE.txt -%readme README.txt -%version 1.1.7 -%incompat printpro - -# Server programs -%system all -# Server files -f 0555 root sys $SBINDIR/cupsd scheduler/cupsd - -d 0555 root sys $SERVERBIN - -d 0555 root sys $SERVERBIN/backend - -f 0555 root sys $SERVERBIN/backend/ipp backend/ipp -l 0555 root sys $SERVERBIN/backend/http ipp -f 0555 root sys $SERVERBIN/backend/lpd backend/lpd -f 0555 root sys $SERVERBIN/backend/parallel backend/parallel -f 0555 root sys $SERVERBIN/backend/serial backend/serial -f 0555 root sys $SERVERBIN/backend/socket backend/socket -f 0555 root sys $SERVERBIN/backend/usb backend/usb -d 0555 root sys $SERVERBIN/cgi-bin - -f 0555 root sys $SERVERBIN/cgi-bin/admin.cgi cgi-bin/admin.cgi -f 0555 root sys $SERVERBIN/cgi-bin/classes.cgi cgi-bin/classes.cgi -f 0555 root sys $SERVERBIN/cgi-bin/jobs.cgi cgi-bin/jobs.cgi -f 0555 root sys $SERVERBIN/cgi-bin/printers.cgi cgi-bin/printers.cgi -d 0555 root sys $SERVERBIN/daemon - -f 0555 root sys $SERVERBIN/daemon/cups-lpd scheduler/cups-lpd -f 0555 root sys $SERVERBIN/daemon/cups-polld scheduler/cups-polld -d 0555 root sys $SERVERBIN/filter - -f 0555 root sys $SERVERBIN/filter/pstoraster pstoraster/pstoraster -f 0555 root sys $SERVERBIN/filter/pdftops pdftops/pdftops -f 0555 root sys $SERVERBIN/filter/imagetops filter/imagetops -f 0555 root sys $SERVERBIN/filter/pstops filter/pstops -f 0555 root sys $SERVERBIN/filter/texttops filter/texttops -f 0555 root sys $SERVERBIN/filter/rastertoepson filter/rastertoepson -f 0555 root sys $SERVERBIN/filter/rastertohp filter/rastertohp -f 0555 root sys $SERVERBIN/filter/hpgltops filter/hpgltops -f 0555 root sys $SERVERBIN/filter/imagetoraster filter/imagetoraster - -# Admin commands -l 0555 root sys $BINDIR/disable $SBINDIR/accept -l 0555 root sys $BINDIR/enable $SBINDIR/accept -l 0555 root sys $LIBDIR/accept $SBINDIR/accept -l 0555 root sys $LIBDIR/lpadmin $SBINDIR/lpadmin -l 0555 root sys $LIBDIR/reject accept -f 0555 root sys $SBINDIR/accept systemv/accept -f 0555 root sys $SBINDIR/lpadmin systemv/lpadmin -f 0555 root sys $SBINDIR/lpc berkeley/lpc -f 0555 root sys $SBINDIR/lpinfo systemv/lpinfo -f 0555 root sys $SBINDIR/lpmove systemv/lpmove -l 0555 root sys $SBINDIR/reject accept - -%system irix -l 0555 root sys /usr/etc/lpc $SBINDIR/lpc -%system all - -# User commands -f 0555 root sys $BINDIR/cancel systemv/cancel -f 0555 root sys $BINDIR/lp systemv/lp -f 0555 root sys $BINDIR/lpoptions systemv/lpoptions -f 4555 root sys $BINDIR/lppasswd systemv/lppasswd -f 0555 root sys $BINDIR/lpq berkeley/lpq -f 0555 root sys $BINDIR/lpr berkeley/lpr -f 0555 root sys $BINDIR/lprm berkeley/lprm -f 0555 root sys $BINDIR/lpstat systemv/lpstat - -%system irix -l 0555 root sys /usr/bsd/lpq $BINDIR/lpq -l 0555 root sys /usr/bsd/lpr $BINDIR/lpr -l 0555 root sys /usr/bsd/lprm $BINDIR/lprm -%system all - -# DSOs -%system hpux -f 0555 root sys $LIBDIR/libcups.sl.2 cups/libcups.sl.2 -l 0555 root sys $LIBDIR/libcups.sl libcups.sl.2 -f 0555 root sys $LIBDIR/libcupsimage.sl.2 filter/libcupsimage.sl.2 -l 0555 root sys $LIBDIR/libcupsimage.sl libcupsimage.sl.2 -%system !hpux -f 0555 root sys $LIBDIR/libcups.so.2 cups/libcups.so.2 -l 0555 root sys $LIBDIR/libcups.so libcups.so.2 -f 0555 root sys $LIBDIR/libcupsimage.so.2 filter/libcupsimage.so.2 -l 0555 root sys $LIBDIR/libcupsimage.so libcupsimage.so.2 -%system all - -# Directories -d 0755 root sys $LOGDIR - -d 0700 lp sys $REQUESTS - -d 1700 lp sys $REQUESTS/tmp - - -# Data files -f 0444 root sys $LOCALEDIR/C/cups_C locale/C/cups_C -f 0444 root sys $LOCALEDIR/de/cups_de locale/de/cups_de -f 0444 root sys $LOCALEDIR/en/cups_en locale/en/cups_en -f 0444 root sys $LOCALEDIR/es/cups_es locale/es/cups_es -f 0444 root sys $LOCALEDIR/fr/cups_fr locale/fr/cups_fr -f 0444 root sys $LOCALEDIR/it/cups_it locale/it/cups_it - -d 0555 root sys $DATADIR - - -d 0555 root sys $DATADIR/banners - -f 0444 root sys $DATADIR/banners/classified data/classified -f 0444 root sys $DATADIR/banners/confidential data/confidential -f 0444 root sys $DATADIR/banners/secret data/secret -f 0444 root sys $DATADIR/banners/standard data/standard -f 0444 root sys $DATADIR/banners/topsecret data/topsecret -f 0444 root sys $DATADIR/banners/unclassified data/unclassified - -d 0555 root sys $DATADIR/charsets - -f 0444 root sys $DATADIR/charsets/windows-874 data/windows-874 -f 0444 root sys $DATADIR/charsets/windows-1250 data/windows-1250 -f 0444 root sys $DATADIR/charsets/windows-1251 data/windows-1251 -f 0444 root sys $DATADIR/charsets/windows-1252 data/windows-1252 -f 0444 root sys $DATADIR/charsets/windows-1253 data/windows-1253 -f 0444 root sys $DATADIR/charsets/windows-1254 data/windows-1254 -f 0444 root sys $DATADIR/charsets/windows-1255 data/windows-1255 -f 0444 root sys $DATADIR/charsets/windows-1256 data/windows-1256 -f 0444 root sys $DATADIR/charsets/windows-1257 data/windows-1257 -f 0444 root sys $DATADIR/charsets/windows-1258 data/windows-1258 -f 0444 root sys $DATADIR/charsets/iso-8859-1 data/iso-8859-1 -f 0444 root sys $DATADIR/charsets/iso-8859-14 data/iso-8859-14 -f 0444 root sys $DATADIR/charsets/iso-8859-15 data/iso-8859-15 -f 0444 root sys $DATADIR/charsets/iso-8859-2 data/iso-8859-2 -f 0444 root sys $DATADIR/charsets/iso-8859-3 data/iso-8859-3 -f 0444 root sys $DATADIR/charsets/iso-8859-4 data/iso-8859-4 -f 0444 root sys $DATADIR/charsets/iso-8859-5 data/iso-8859-5 -f 0444 root sys $DATADIR/charsets/iso-8859-6 data/iso-8859-6 -f 0444 root sys $DATADIR/charsets/iso-8859-7 data/iso-8859-7 -f 0444 root sys $DATADIR/charsets/iso-8859-8 data/iso-8859-8 -f 0444 root sys $DATADIR/charsets/iso-8859-9 data/iso-8859-9 -f 0444 root sys $DATADIR/charsets/utf-8 data/utf-8 - -d 0555 root sys $DATADIR/data - -f 0444 root sys $DATADIR/data/HPGLprolog data/HPGLprolog -f 0444 root sys $DATADIR/data/psglyphs data/psglyphs -f 0444 root sys $DATADIR/data/testprint.ps data/testprint.ps - -d 0555 root sys $DATADIR/fonts - -f 0444 root sys $DATADIR/fonts fonts/* - -d 0555 root sys $DATADIR/pstoraster - -f 0444 root sys $DATADIR/pstoraster/Fontmap pstoraster/Fontmap -f 0444 root sys $DATADIR/pstoraster pstoraster/gs*.ps - -d 0555 root sys $DATADIR/model - -f 0444 root sys $DATADIR/model ppd/*.ppd - -d 0555 root sys $DATADIR/templates - -f 0444 root sys $DATADIR/templates templates/*.tmpl - -# Config files -d 0555 root sys $SERVERROOT - -d 0711 root sys $SERVERROOT/certs - -d 0755 root sys $SERVERROOT/interfaces - -d 0755 root sys $SERVERROOT/ppd - -c 0644 root sys $SERVERROOT conf/*.conf -f 0644 root sys $SERVERROOT/mime.convs conf/mime.convs -f 0644 root sys $SERVERROOT/mime.types conf/mime.types - -%system linux -d 0555 root sys $PAMDIR - -c 0644 root sys $PAMDIR/cups data/cups.pam -c 0644 root sys $PAMDIR/cups.suse data/cups.suse -%install if test -f /lib/security/pam_unix.so; then -%install mv $PAMDIR/cups.suse $PAMDIR/cups -%install fi -%system all - -# Developer files -d 0555 root sys $INCLUDEDIR/cups - -f 0444 root sys $INCLUDEDIR/cups/cups.h cups/cups.h -f 0444 root sys $INCLUDEDIR/cups/http.h cups/http.h -f 0444 root sys $INCLUDEDIR/cups/image.h filter/image.h -f 0444 root sys $INCLUDEDIR/cups/ipp.h cups/ipp.h -f 0444 root sys $INCLUDEDIR/cups/language.h cups/language.h -f 0444 root sys $INCLUDEDIR/cups/md5.h cups/md5.h -f 0444 root sys $INCLUDEDIR/cups/ppd.h cups/ppd.h -f 0444 root sys $INCLUDEDIR/cups/raster.h filter/raster.h - -f 0444 root sys $LIBDIR/libcups.a cups/libcups.a - -# Documentation files -d 0555 root sys $DOCDIR - -f 0444 root sys $DOCDIR/cups.css doc/cups.css -f 0444 root sys $DOCDIR doc/*.html -f 0444 root sys $DOCDIR doc/*.pdf -d 0555 root sys $DOCDIR/images - -f 0444 root sys $DOCDIR/images doc/images/*.gif - -# Man pages -%system irix -d 0555 root sys $AMANDIR - -d 0555 root sys $AMANDIR/cat1 - -d 0555 root sys $MANDIR - -d 0555 root sys $MANDIR/cat1 - -d 0555 root sys $MANDIR/cat5 - - -f 0444 root sys $AMANDIR/cat1/accept.z man/accept.z -l 0444 root sys $AMANDIR/cat1/reject.z accept.z -f 0444 root sys $MANDIR/cat1/backend.z man/backend.z -f 0444 root sys $MANDIR/cat5/classes.conf.z man/classes.conf.z -f 0444 root sys $AMANDIR/cat1/cups-lpd.z man/cups-lpd.z -f 0444 root sys $AMANDIR/cat1/cups-polld.z man/cups-polld.z -f 0444 root sys $MANDIR/cat5/cupsd.conf.z man/cupsd.conf.z -f 0444 root sys $AMANDIR/cat1/cupsd.z man/cupsd.z -f 0444 root sys $AMANDIR/cat1/enable.z man/enable.z -l 0444 root sys $AMANDIR/cat1/disable.z enable.z -f 0444 root sys $MANDIR/cat1/filter.z man/filter.z -f 0444 root sys $AMANDIR/cat1/lpadmin.z man/lpadmin.z -f 0444 root sys $AMANDIR/cat1/lpc.z man/lpc.z -f 0444 root sys $AMANDIR/cat1/lpinfo.z man/lpinfo.z -f 0444 root sys $AMANDIR/cat1/lpmove.z man/lpmove.z -f 0444 root sys $MANDIR/cat1/lpoptions.z man/lpoptions.z -f 0444 root sys $MANDIR/cat1/lpq.z man/lpq.z -f 0444 root sys $MANDIR/cat1/lprm.z man/lprm.z -f 0444 root sys $MANDIR/cat1/lpr.z man/lpr.z -f 0444 root sys $MANDIR/cat1/lpstat.z man/lpstat.z -f 0444 root sys $MANDIR/cat1/lp.z man/lp.z -l 0444 root sys $MANDIR/cat1/cancel.z lp.z -f 0444 root sys $MANDIR/cat5/mime.convs.z man/mime.convs.z -f 0444 root sys $MANDIR/cat5/mime.types.z man/mime.types.z -f 0444 root sys $MANDIR/cat5/printers.conf.z man/printers.conf.z - -%system solaris hpux -d 0555 root sys $MANDIR/man1 - -d 0555 root sys $MANDIR/man5 - -d 0555 root sys $MANDIR/man1m - - -f 0444 root sys $MANDIR/man1m/accept.1m man/accept.man -l 0444 root sys $MANDIR/man1m/reject.1m accept.1m -f 0444 root sys $MANDIR/man1/backend.1 man/backend.man -f 0444 root sys $MANDIR/man1/classes.conf.5 man/classes.conf.man -f 0444 root sys $MANDIR/man1m/cups-lpd.1m man/cups-lpd.man -f 0444 root sys $MANDIR/man1m/cups-polld.1m man/cups-polld.man -f 0444 root sys $MANDIR/man1m/cupsd.1m man/cupsd.man -f 0444 root sys $MANDIR/man5/cupsd.conf.5 man/cupsd.conf.man -f 0444 root sys $MANDIR/man1m/enable.1m man/enable.man -l 0444 root sys $MANDIR/man1m/disable.1m enable.1m -f 0444 root sys $MANDIR/man1/filter.1 man/filter.man -f 0444 root sys $MANDIR/man1m/lpadmin.1m man/lpadmin.man -f 0444 root sys $MANDIR/man1m/lpc.1m man/lpc.man -f 0444 root sys $MANDIR/man1m/lpinfo.1m man/lpinfo.man -f 0444 root sys $MANDIR/man1m/lpmove.1m man/lpmove.man -f 0444 root sys $MANDIR/man1/lpoptions.1 man/lpoptions.man -f 0444 root sys $MANDIR/man1/lpq.1 man/lpq.man -f 0444 root sys $MANDIR/man1/lprm.1 man/lprm.man -f 0444 root sys $MANDIR/man1/lpr.1 man/lpr.man -f 0444 root sys $MANDIR/man1/lpstat.1 man/lpstat.man -f 0444 root sys $MANDIR/man1/lp.1 man/lp.man -l 0444 root sys $MANDIR/man1/cancel.1 lp.1 -f 0444 root sys $MANDIR/man5/mime.convs.5 man/mime.convs.man -f 0444 root sys $MANDIR/man5/mime.types.5 man/mime.types.man -f 0444 root sys $MANDIR/man5/printers.conf.5 man/printers.conf.man - -%system !irix !solaris !hpux -d 0555 root sys $MANDIR/man1 - -d 0555 root sys $MANDIR/man5 - -d 0555 root sys $MANDIR/man8 - - -f 0444 root sys $MANDIR/man8/accept.8 man/accept.man -l 0444 root sys $MANDIR/man8/reject.8 accept.8 -f 0444 root sys $MANDIR/man1/backend.1 man/backend.man -f 0444 root sys $MANDIR/man1/classes.conf.5 man/classes.conf.man -f 0444 root sys $MANDIR/man8/cups-lpd.8 man/cups-lpd.man -f 0444 root sys $MANDIR/man8/cups-polld.8 man/cups-polld.man -f 0444 root sys $MANDIR/man8/cupsd.8 man/cupsd.man -f 0444 root sys $MANDIR/man5/cupsd.conf.5 man/cupsd.conf.man -f 0444 root sys $MANDIR/man8/enable.8 man/enable.man -l 0444 root sys $MANDIR/man8/disable.8 enable.8 -f 0444 root sys $MANDIR/man1/filter.1 man/filter.man -f 0444 root sys $MANDIR/man8/lpadmin.8 man/lpadmin.man -f 0444 root sys $MANDIR/man8/lpc.8 man/lpc.man -f 0444 root sys $MANDIR/man8/lpinfo.8 man/lpinfo.man -f 0444 root sys $MANDIR/man8/lpmove.8 man/lpmove.man -f 0444 root sys $MANDIR/man1/lpoptions.1 man/lpoptions.man -f 0444 root sys $MANDIR/man1/lpq.1 man/lpq.man -f 0444 root sys $MANDIR/man1/lprm.1 man/lprm.man -f 0444 root sys $MANDIR/man1/lpr.1 man/lpr.man -f 0444 root sys $MANDIR/man1/lpstat.1 man/lpstat.man -f 0444 root sys $MANDIR/man1/lp.1 man/lp.man -l 0444 root sys $MANDIR/man1/cancel.1 lp.1 -f 0444 root sys $MANDIR/man5/mime.convs.5 man/mime.convs.man -f 0444 root sys $MANDIR/man5/mime.types.5 man/mime.types.man -f 0444 root sys $MANDIR/man5/printers.conf.5 man/printers.conf.man - -# Startup script -%system all -i 0555 root sys cups cups.sh - -# -# End of "$Id: cups.list,v 1.85.2.1 2001/05/13 18:37:58 mike Exp $". -# diff --git a/cups.list.in b/cups.list.in index 0886f401a0..055e12c091 100644 --- a/cups.list.in +++ b/cups.list.in @@ -1,5 +1,5 @@ # -# "$Id: cups.list.in,v 1.13 2001/12/18 17:34:06 mike Exp $" +# "$Id: cups.list.in,v 1.13.2.1 2001/12/26 16:52:05 mike Exp $" # # ESP Package Manager (EPM) file list for the Common UNIX Printing # System (CUPS). @@ -369,5 +369,5 @@ f 0444 root sys $AMANDIR/man$MAN8DIR/lpmove.$MAN8EXT man/lpmove.man i 0555 root sys cups cups.sh # -# End of "$Id: cups.list.in,v 1.13 2001/12/18 17:34:06 mike Exp $". +# End of "$Id: cups.list.in,v 1.13.2.1 2001/12/26 16:52:05 mike Exp $". # diff --git a/cups.sh.in b/cups.sh.in index b310eedbe0..2734ffbed1 100755 --- a/cups.sh.in +++ b/cups.sh.in @@ -1,6 +1,6 @@ #!/bin/sh # -# "$Id: cups.sh.in,v 1.9.2.1 2001/05/13 18:37:58 mike Exp $" +# "$Id: cups.sh.in,v 1.9.2.2 2001/12/26 16:52:05 mike Exp $" # # Startup/shutdown script for the Common UNIX Printing System (CUPS). # @@ -43,6 +43,7 @@ #### OS-Dependent Configuration + case "`uname`" in IRIX*) IS_ON=/sbin/chkconfig @@ -52,6 +53,31 @@ case "`uname`" in IS_ON=: ;; + Darwin*) + . /etc/rc.common + + if test "${CUPS:=-YES-}" = "-NO-"; then + exit 0 + fi + + IS_ON=: + ;; + + Linux*) + # Set the timezone, if possible... + if test -f /etc/TIMEZONE; then + . /etc/TIMEZONE + else + if test -f /etc/sysconfig/clock; then + . /etc/sysconfig/clock + TZ="$ZONE" + export TZ + fi + fi + + IS_ON=/bin/true + ;; + *) IS_ON=/bin/true ;; @@ -65,10 +91,14 @@ esac # all but IRIX, which can configure verbose bootup messages. # -if $IS_ON verbose; then - ECHO=echo +if test "`uname`" = "Darwin"; then + ECHO=ConsoleMessage else - ECHO=: + if $IS_ON verbose; then + ECHO=echo + else + ECHO=: + fi fi # @@ -76,14 +106,22 @@ fi # case "`uname`" in - IRIX* | HP-UX* | SunOS* | AIX*) - pid=`ps -e | awk '{print $1,$4}' | grep cupsd | awk '{print $1}'` +<<<<<<< cups.sh.in + IRIX* | HP-UX* | AIX* | SINIX*) + pid=`ps -e | awk '{if (match($4, ".*/cupsd$") || $4 == "cupsd") print $1}'` + ;; + SunOS*) + pid=`ps -e | nawk '{if (match($4, ".*/cupsd$") || $4 == "cupsd") print $1}'` + ;; + UnixWare*) + pid=`ps -e | awk '{if (match($6, ".*/cupsd$") || $6 == "cupsd") print $1}'` + . /etc/TIMEZONE ;; OSF1*) - pid=`ps -e | awk '{print $1,$5}' | grep cupsd | awk '{print $1}'` + pid=`ps -e | awk '{if (match($5, ".*/cupsd$") || $5 == "cupsd") print $1}'` ;; - Linux* | NetBSD*) - pid=`ps ax | awk '{print $1,$5}' | grep cupsd | awk '{print $1}'` + Linux* | *BSD* | Darwin*) + pid=`ps ax | awk '{if (match($5, ".*/cupsd$") || $5 == "cupsd") print $1}'` ;; *) pid="" @@ -139,5 +177,5 @@ exit 0 # -# End of "$Id: cups.sh.in,v 1.9.2.1 2001/05/13 18:37:58 mike Exp $". +# End of "$Id: cups.sh.in,v 1.9.2.2 2001/12/26 16:52:05 mike Exp $". # diff --git a/cups.spec b/cups.spec index 707a39cf15..5d321ee6b9 100644 --- a/cups.spec +++ b/cups.spec @@ -1,5 +1,5 @@ # -# "$Id: cups.spec,v 1.30.2.1 2001/05/13 18:37:58 mike Exp $" +# "$Id: cups.spec,v 1.30.2.2 2001/12/26 16:52:05 mike Exp $" # # RPM "spec" file for the Common UNIX Printing System (CUPS). # @@ -26,24 +26,28 @@ Summary: Common Unix Printing System Name: cups -Version: 1.1.7 -Release: 1 +Version: 1.2 +Release: 0 Copyright: GPL Group: System Environment/Daemons Source: ftp://ftp.easysw.com/pub/cups/%{version}/cups-%{version}-source.tar.gz Url: http://www.cups.org Packager: Michael Sweet Vendor: Easy Software Products -# use buildroot so as not to disturb the version already installed + +# Use buildroot so as not to disturb the version already installed BuildRoot: /var/tmp/%{name}-root + +# Dependencies... Conflicts: lpr, LPRng Provides: libcups.so.2 Provides: libcupsimage.so.2 -Provides: cupsd +Provides: cups %package devel Summary: Common Unix Printing System - development environment Group: Development/Libraries +Provides: libcups1 %package pstoraster Summary: Common Unix Printing System - PostScript RIP @@ -59,7 +63,7 @@ CUPS provides the System V and Berkeley command-line interfaces. %description devel The Common UNIX Printing System provides a portable printing layer for UNIX® operating systems. This is the development package for creating -additional printer drivers, and other CUPS services. +additional printer drivers and other CUPS services. %description devel The Common UNIX Printing System provides a portable printing layer for @@ -70,7 +74,7 @@ supporting non-PostScript printer drivers. %setup %build -./configure +CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_OPT_FLAGS" ./configure # If we got this far, all prerequisite libraries must be here. make @@ -79,25 +83,11 @@ make # Make sure the RPM_BUILD_ROOT directory exists. rm -rf $RPM_BUILD_ROOT -make prefix=$RPM_BUILD_ROOT \ - exec_prefix=$RPM_BUILD_ROOT/usr \ - AMANDIR=$RPM_BUILD_ROOT/usr/man \ - BINDIR=$RPM_BUILD_ROOT/usr/bin \ - DATADIR=$RPM_BUILD_ROOT/usr/share/cups \ - DOCDIR=$RPM_BUILD_ROOT/usr/share/doc/cups \ - INCLUDEDIR=$RPM_BUILD_ROOT/usr/include \ - LIBDIR=$RPM_BUILD_ROOT/usr/lib \ - LOGDIR=$RPM_BUILD_ROOT/var/log/cups \ - LOCALEDIR=$RPM_BUILD_ROOT/usr/share/locale \ - MANDIR=$RPM_BUILD_ROOT/usr/man \ - PAMDIR=$RPM_BUILD_ROOT/etc/pam.d \ - REQUESTS=$RPM_BUILD_ROOT/var/spool/cups \ - SBINDIR=$RPM_BUILD_ROOT/usr/sbin \ - SERVERBIN=$RPM_BUILD_ROOT/usr/lib/cups \ - SERVERROOT=$RPM_BUILD_ROOT/etc/cups \ - install +make BUILDROOT=$RPM_BUILD_ROOT install %post +ldconfig + if test -x /sbin/chkconfig; then /sbin/chkconfig --add cups /sbin/chkconfig cups on @@ -163,7 +153,10 @@ rm -rf $RPM_BUILD_ROOT #/sbin/rc.d/rc3.d/* #/sbin/rc.d/rc5.d/* -/usr/bin/* +/usr/bin/cancel +/usr/bin/disable +/usr/bin/enable +/usr/bin/lp* /usr/lib/*.so* %dir /usr/lib/cups %dir /usr/lib/cups/backend @@ -179,7 +172,6 @@ rm -rf $RPM_BUILD_ROOT /usr/lib/cups/filter/rastertoepson /usr/lib/cups/filter/rastertohp /usr/lib/cups/filter/texttops -/usr/man/* /usr/sbin/* %dir /usr/share/cups %dir /usr/share/cups/banners @@ -196,6 +188,19 @@ rm -rf $RPM_BUILD_ROOT /usr/share/doc/cups/* %dir /usr/share/locale /usr/share/locale/* +%dir /usr/share/man/cat1 +/usr/share/man/cat1/* +%dir /usr/share/man/cat5 +/usr/share/man/cat5/* +%dir /usr/share/man/cat8 +/usr/share/man/cat8/* +%dir /usr/share/man/man1 +/usr/share/man/man1/* +%dir /usr/share/man/man5 +/usr/share/man/man5/* +%dir /usr/share/man/man8 +/usr/share/man/man8/* + %attr(0700,lp,root) %dir /var/spool/cups %attr(1700,lp,root) %dir /var/spool/cups/tmp @@ -203,6 +208,10 @@ rm -rf $RPM_BUILD_ROOT %dir /usr/include/cups /usr/include/cups/* /usr/lib/*.a +%dir /usr/share/man/cat3 +/usr/share/man/cat3/* +%dir /usr/share/man/man3 +/usr/share/man/man1/* %files pstoraster %dir /usr/lib/cups/filter @@ -213,5 +222,5 @@ rm -rf $RPM_BUILD_ROOT /usr/share/cups/pstoraster/* # -# End of "$Id: cups.spec,v 1.30.2.1 2001/05/13 18:37:58 mike Exp $". +# End of "$Id: cups.spec,v 1.30.2.2 2001/12/26 16:52:05 mike Exp $". # diff --git a/cups/Makefile b/cups/Makefile index dfb72083b3..9b44b09335 100644 --- a/cups/Makefile +++ b/cups/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.53.2.1 2001/04/02 19:51:43 mike Exp $" +# "$Id: Makefile,v 1.53.2.2 2001/12/26 16:52:11 mike Exp $" # # Support library Makefile for the Common UNIX Printing System (CUPS). # @@ -68,18 +68,25 @@ clean: # install: all - -$(MKDIR) $(INCLUDEDIR)/cups - $(CHMOD) ugo+rx $(INCLUDEDIR) - $(CHMOD) ugo+rx $(INCLUDEDIR)/cups - $(INSTALL_DATA) $(HEADERS) $(INCLUDEDIR)/cups - -$(MKDIR) $(LIBDIR) - $(CHMOD) ugo+rx $(LIBDIR) + $(INSTALL_DIR) $(INCLUDEDIR)/cups + for file in $(HEADERS); do \ + $(INSTALL_DATA) $$file $(INCLUDEDIR)/cups; \ + done + $(INSTALL_DIR) $(LIBDIR) $(INSTALL_LIB) $(LIBCUPS) $(LIBDIR) - if test $(LIBCUPS) != "libcups.a" -a $(LIBCUPS) != "libcups.la"; then \ + if test $(LIBCUPS) = "libcups.so.2" -o $(LIBCUPS) = "libcups.sl.2"; then \ $(INSTALL_LIB) libcups.a $(LIBDIR); \ $(RM) $(LIBDIR)/`basename $(LIBCUPS) .3`; \ $(LN) $(LIBCUPS) $(LIBDIR)/`basename $(LIBCUPS) .3`; \ fi + if test $(LIBCUPS) = "libcups.2.dylib"; then \ + $(INSTALL_LIB) libcups.a $(LIBDIR); \ + $(RM) $(LIBDIR)/libcups.dylib; \ + $(LN) $(LIBCUPS) $(LIBDIR)/libcups.dylib; \ + fi + if test $(LIBCUPS) = "libcups_s.a"; then \ + $(INSTALL_LIB) libcups.a $(LIBDIR); \ + fi # @@ -93,6 +100,30 @@ libcups.so.3 libcups.sl.3: $(LIBOBJS) ../Makedefs $(LN) $@ `basename $@ .3` +# +# libcups.2.dylib +# + +libcups.3.dylib: $(LIBOBJS) ../Makedefs + echo Linking $@... + $(DSO) $(DSOFLAGS) -o $@ $(LIBOBJS) $(SSLLIBS) + $(RM) libcups.dylib + $(LN) $@ libcups.dylib + + +# +# libcups_s.a +# + +libcups_s.a: $(LIBOBJS) ../Makedefs + echo Creating $@... + $(RM) libcups_s.exp + (echo _ipp_add_attr; echo _ipp_free_attr) >libcups_s.exp + $(DSO) $(DSOFLAGS) -Wl,-bexport:libcups_s.exp -o libcups_s.o $(LIBOBJS) $(SSLLIBS) -lm + $(RM) $@ + $(AR) $(ARFLAGS) $@ libcups_s.o + + # # libcups.la # @@ -167,5 +198,5 @@ $(OBJS): ../Makedefs ../config.h # -# End of "$Id: Makefile,v 1.53.2.1 2001/04/02 19:51:43 mike Exp $". +# End of "$Id: Makefile,v 1.53.2.2 2001/12/26 16:52:11 mike Exp $". # diff --git a/cups/cups.h b/cups/cups.h index 94e9adfb36..b89717a264 100644 --- a/cups/cups.h +++ b/cups/cups.h @@ -1,5 +1,5 @@ /* - * "$Id: cups.h,v 1.32.2.1 2001/05/13 18:38:02 mike Exp $" + * "$Id: cups.h,v 1.32.2.2 2001/12/26 16:52:11 mike Exp $" * * API definitions for the Common UNIX Printing System (CUPS). * @@ -46,7 +46,7 @@ extern "C" { * Constants... */ -# define CUPS_VERSION 1.0103 +# define CUPS_VERSION 1.0200 # define CUPS_DATE_ANY -1 @@ -171,5 +171,5 @@ extern const char *cupsUser(void); #endif /* !_CUPS_CUPS_H_ */ /* - * End of "$Id: cups.h,v 1.32.2.1 2001/05/13 18:38:02 mike Exp $". + * End of "$Id: cups.h,v 1.32.2.2 2001/12/26 16:52:11 mike Exp $". */ diff --git a/cups/dest.c b/cups/dest.c index c0e2018b85..d972d17b8f 100644 --- a/cups/dest.c +++ b/cups/dest.c @@ -1,5 +1,5 @@ /* - * "$Id: dest.c,v 1.18 2001/03/30 22:23:00 mike Exp $" + * "$Id: dest.c,v 1.18.2.1 2001/12/26 16:52:11 mike Exp $" * * User-defined destination (and option) support for the Common UNIX * Printing System (CUPS). @@ -275,6 +275,15 @@ cupsGetDests(cups_dest_t **dests) /* O - Destinations */ if ((dest = cupsGetDest(name, instance, num_dests, *dests)) != NULL) dest->is_default = 1; } + else + { + /* + * This initialization of "instance" is unnecessary, but avoids a + * compiler warning... + */ + + instance = NULL; + } /* * Load the /etc/cups/lpoptions and ~/.lpoptions files... @@ -294,6 +303,21 @@ cupsGetDests(cups_dest_t **dests) /* O - Destinations */ num_dests = cups_get_dests(filename, num_dests, dests); } + /* + * Reset the default destination if the LPDEST or PRINTER environment + * variables are set... + */ + + if (getenv("LPDEST") != NULL || getenv("PRINTER") != NULL) + { + /* + * Lookup the printer and instance and make it the default... + */ + + if ((dest = cupsGetDest(name, instance, num_dests, *dests)) != NULL) + dest->is_default = 1; + } + /* * Return the number of destinations... */ @@ -542,5 +566,147 @@ cups_get_dests(const char *filename, /* I - File to read from */ /* - * End of "$Id: dest.c,v 1.18 2001/03/30 22:23:00 mike Exp $". + * 'cups_get_sdests()' - Get destinations from a server. + */ + +static int /* O - Number of destinations */ +cups_get_sdests(ipp_op_t op, /* I - get-printers or get-classes */ + int num_dests, /* I - Number of destinations */ + cups_dest_t **dests) /* IO - Destinations */ +{ + cups_dest_t *dest; /* Current destination */ + http_t *http; /* HTTP connection */ + ipp_t *request, /* IPP Request */ + *response; /* IPP Response */ + ipp_attribute_t *attr; /* Current attribute */ + cups_lang_t *language; /* Default language */ + const char *name; /* printer-name attribute */ + char job_sheets[1024]; /* job-sheets option */ + static const char *pattrs[] = /* Attributes we're interested in */ + { + "printer-name", + "job-sheets-default" + }; + + + /* + * Connect to the CUPS server... + */ + + if ((http = httpConnect(cupsServer(), ippPort())) == NULL) + return (num_dests); + + /* + * Build a CUPS_GET_PRINTERS or CUPS_GET_CLASSES request, which require + * the following attributes: + * + * attributes-charset + * attributes-natural-language + */ + + request = ippNew(); + + request->request.op.operation_id = op; + request->request.op.request_id = 1; + + language = cupsLangDefault(); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]), + NULL, pattrs); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + for (attr = response->attrs; attr != NULL; attr = attr->next) + { + /* + * Skip leading attributes until we hit a printer... + */ + + while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) + attr = attr->next; + + if (attr == NULL) + break; + + /* + * Pull the needed attributes from this job... + */ + + name = NULL; + + strcpy(job_sheets, ""); + + while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) + { + if (strcmp(attr->name, "printer-name") == 0 && + attr->value_tag == IPP_TAG_NAME) + name = attr->values[0].string.text; + + if (strcmp(attr->name, "job-sheets-default") == 0 && + (attr->value_tag == IPP_TAG_KEYWORD || + attr->value_tag == IPP_TAG_NAME)) + { + if (attr->num_values == 2) + snprintf(job_sheets, sizeof(job_sheets), "%s,%s", + attr->values[0].string.text, attr->values[1].string.text); + else + strcpy(job_sheets, attr->values[0].string.text); + } + + attr = attr->next; + } + + /* + * See if we have everything needed... + */ + + if (!name) + { + if (attr == NULL) + break; + else + continue; + } + + num_dests = cupsAddDest(name, NULL, num_dests, dests); + + if ((dest = cupsGetDest(name, NULL, num_dests, *dests)) != NULL) + if (job_sheets[0]) + dest->num_options = cupsAddOption("job-sheets", job_sheets, 0, + &(dest->options)); + + if (attr == NULL) + break; + } + + ippDelete(response); + } + + /* + * Close the server connection... + */ + + httpClose(http); + + /* + * Return the count... + */ + + return (num_dests); +} + + +/* + * End of "$Id: dest.c,v 1.18.2.1 2001/12/26 16:52:11 mike Exp $". */ diff --git a/cups/http.c b/cups/http.c index c10e3998e6..9c7ea32e6f 100644 --- a/cups/http.c +++ b/cups/http.c @@ -1,5 +1,5 @@ /* - * "$Id: http.c,v 1.82.2.2 2001/05/13 18:38:03 mike Exp $" + * "$Id: http.c,v 1.82.2.3 2001/12/26 16:52:11 mike Exp $" * * HTTP routines for the Common UNIX Printing System (CUPS). * @@ -32,6 +32,8 @@ * httpConnectEncrypt() - Connect to a HTTP server using encryption. * httpEncryption() - Set the required encryption on the link. * httpReconnect() - Reconnect to a HTTP server... + * httpGetHostByName() - Lookup a hostname or IP address, and return + * address records for the specified name. * httpSeparate() - Separate a Universal Resource Identifier into its * components. * httpSetField() - Set the value of an HTTP header. @@ -352,7 +354,7 @@ httpConnectEncrypt(const char *host, /* I - Host to connect to */ * Lookup the host... */ - if ((hostaddr = gethostbyname(host)) == NULL) + if ((hostaddr = httpGetHostByName(host)) == NULL) { /* * This hack to make users that don't have a localhost entry in @@ -361,7 +363,7 @@ httpConnectEncrypt(const char *host, /* I - Host to connect to */ if (strcasecmp(host, "localhost") != 0) return (NULL); - else if ((hostaddr = gethostbyname("127.0.0.1")) == NULL) + else if ((hostaddr = httpGetHostByName("127.0.0.1")) == NULL) return (NULL); } @@ -396,24 +398,22 @@ httpConnectEncrypt(const char *host, /* I - Host to connect to */ */ strncpy(http->hostname, host, sizeof(http->hostname) - 1); - memset(&(http->hostaddr), 0, sizeof(http->hostaddr)); - http->hostaddr.addr.sa_family = hostaddr->h_addrtype; - - if (port == 443) - { - /* - * Set the default encryption status... - */ - - http->encryption = HTTP_ENCRYPT_ALWAYS; - } + http->hostaddr.sin_family = hostaddr->h_addrtype; +#ifdef WIN32 + http->hostaddr.sin_port = htons((u_short)port); +#else + http->hostaddr.sin_port = htons(port); +#endif /* WIN32 */ /* * Set the encryption status... */ - http->encryption = encrypt; + if (port == 443) /* Always use encryption for https */ + http->encryption = HTTP_ENCRYPT_ALWAYS; + else + http->encryption = encrypt; /* * Loop through the addresses we have until one of them connects... @@ -614,6 +614,69 @@ httpReconnect(http_t *http) /* I - HTTP data */ } +/* + * 'httpGetHostByName()' - Lookup a hostname or IP address, and return + * address records for the specified name. + */ + +struct hostent * /* O - Host entry */ +httpGetHostByName(const char *name) /* I - Hostname or IP address */ +{ + unsigned ip[4]; /* IP address components */ + static unsigned packed_ip; /* Packed IPv4 address */ + static char *packed_ptr[2]; /* Pointer to packed address */ + static struct hostent host_ip; /* Host entry for IP address */ + + + /* + * This function is needed because some operating systems have a + * buggy implementation of httpGetHostByName() that does not support + * IP addresses. If the first character of the name string is a + * number, then sscanf() is used to extract the IP components. + * We then pack the components into an IPv4 address manually, + * since the inet_aton() function is deprecated. We use the + * htonl() macro to get the right byte order for the address. + */ + + if (isdigit(name[0])) + { + /* + * We have an IP address; break it up and provide the host entry + * to the caller. Currently only supports IPv4 addresses, although + * it should be trivial to support IPv6 in CUPS 1.2. + */ + + if (sscanf(name, "%u.%u.%u.%u", ip, ip + 1, ip + 2, ip + 3) != 4) + return (NULL); /* Must have 4 numbers */ + + packed_ip = htonl(((((((ip[0] << 8) | ip[1]) << 8) | ip[2]) << 8) | ip[3])); + + /* + * Fill in the host entry and return it... + */ + + host_ip.h_name = (char *)name; + host_ip.h_aliases = NULL; + host_ip.h_addrtype = AF_INET; + host_ip.h_length = 4; + host_ip.h_addr_list = packed_ptr; + packed_ptr[0] = (char *)(&packed_ip); + packed_ptr[1] = NULL; + + return (&host_ip); + } + else + { + /* + * Use the gethostbyname() function to get the IP address for + * the name... + */ + + return (gethostbyname(name)); + } +} + + /* * 'httpSeparate()' - Separate a Universal Resource Identifier into its * components. @@ -1115,6 +1178,47 @@ httpRead(http_t *http, /* I - HTTP data */ else if (length > http->data_remaining) length = http->data_remaining; + if (http->used == 0 && length <= 256) + { + /* + * Buffer small reads for better performance... + */ + + if (http->data_remaining > sizeof(http->buffer)) + bytes = sizeof(http->buffer); + else + bytes = http->data_remaining; + +#ifdef HAVE_LIBSSL + if (http->tls) + bytes = SSL_read((SSL *)(http->tls), http->buffer, bytes); + else +#endif /* HAVE_LIBSSL */ + { + DEBUG_printf(("httpRead: reading %d bytes from socket into buffer...\n", + bytes)); + + bytes = recv(http->fd, http->buffer, bytes, 0); + + DEBUG_printf(("httpRead: read %d bytes from socket into buffer...\n", + bytes)); + } + + if (bytes > 0) + http->used = bytes; + else if (bytes < 0) + { +#if defined(WIN32) || defined(__EMX__) + http->error = WSAGetLastError(); +#else + http->error = errno; +#endif /* WIN32 || __EMX__ */ + return (-1); + } + else + return (0); + } + if (http->used > 0) { if (length > http->used) @@ -1202,6 +1306,8 @@ httpWrite(http_t *http, /* I - HTTP data */ if (http->state == HTTP_POST_RECV) http->state ++; + else if (http->state == HTTP_PUT_RECV) + http->state = HTTP_STATUS; else http->state = HTTP_WAITING; @@ -2096,5 +2202,5 @@ http_upgrade(http_t *http) /* I - HTTP data */ /* - * End of "$Id: http.c,v 1.82.2.2 2001/05/13 18:38:03 mike Exp $". + * End of "$Id: http.c,v 1.82.2.3 2001/12/26 16:52:11 mike Exp $". */ diff --git a/cups/http.h b/cups/http.h index a6f7cdcddc..32f90d8af0 100644 --- a/cups/http.h +++ b/cups/http.h @@ -1,5 +1,5 @@ /* - * "$Id: http.h,v 1.33.2.2 2001/05/13 18:38:03 mike Exp $" + * "$Id: http.h,v 1.33.2.3 2001/12/26 16:52:12 mike Exp $" * * Hyper-Text Transport Protocol definitions for the Common UNIX Printing * System (CUPS). @@ -315,6 +315,7 @@ extern char *httpGets(char *line, int length, http_t *http); extern const char *httpGetDateString(time_t t); extern time_t httpGetDateTime(const char *s); # define httpGetField(http,field) (http)->fields[field] +extern struct hostent *httpGetHostByName(const char *name); extern char *httpGetSubField(http_t *http, http_field_t field, const char *name, char *value); extern int httpHead(http_t *http, const char *uri); @@ -364,5 +365,5 @@ extern char *httpAddrString(const http_addr_t *addr, #endif /* !_CUPS_HTTP_H_ */ /* - * End of "$Id: http.h,v 1.33.2.2 2001/05/13 18:38:03 mike Exp $". + * End of "$Id: http.h,v 1.33.2.3 2001/12/26 16:52:12 mike Exp $". */ diff --git a/cups/ipp.c b/cups/ipp.c index 1e268d47ed..f2d0fc5e64 100644 --- a/cups/ipp.c +++ b/cups/ipp.c @@ -1,5 +1,5 @@ /* - * "$Id: ipp.c,v 1.55.2.2 2001/05/13 18:38:03 mike Exp $" + * "$Id: ipp.c,v 1.55.2.3 2001/12/26 16:52:12 mike Exp $" * * Internet Printing Protocol support functions for the Common UNIX * Printing System (CUPS). @@ -125,6 +125,7 @@ ippAddBooleans(ipp_t *ipp, /* I - IPP request */ { int i; /* Looping var */ ipp_attribute_t *attr; /* New attribute */ + ipp_value_t *value; /* Current value */ DEBUG_printf(("ippAddBooleans(%p, %02x, \'%s\', %d, %p)\n", ipp, @@ -141,8 +142,10 @@ ippAddBooleans(ipp_t *ipp, /* I - IPP request */ attr->value_tag = IPP_TAG_BOOLEAN; if (values != NULL) - for (i = 0; i < num_values; i ++) - attr->values[i].boolean = values[i]; + for (i = 0, value = attr->values; + i < num_values; + i ++, value ++) + value->boolean = values[i]; return (attr); } @@ -225,6 +228,7 @@ ippAddIntegers(ipp_t *ipp, /* I - IPP request */ { int i; /* Looping var */ ipp_attribute_t *attr; /* New attribute */ + ipp_value_t *value; /* Current value */ if (ipp == NULL || name == NULL) @@ -238,8 +242,10 @@ ippAddIntegers(ipp_t *ipp, /* I - IPP request */ attr->value_tag = type; if (values != NULL) - for (i = 0; i < num_values; i ++) - attr->values[i].integer = values[i]; + for (i = 0, value = attr->values; + i < num_values; + i ++, value ++) + value->integer = values[i]; return (attr); } @@ -269,8 +275,10 @@ ippAddString(ipp_t *ipp, /* I - IPP request */ attr->name = strdup(name); attr->group_tag = group; attr->value_tag = type; - attr->values[0].string.charset = charset ? strdup(charset) : NULL; - attr->values[0].string.text = value ? strdup(value) : NULL; + attr->values[0].string.charset = ((int)type & IPP_TAG_COPY) ? (char *)charset : + charset ? strdup(charset) : NULL; + attr->values[0].string.text = ((int)type & IPP_TAG_COPY) ? (char *)value : + value ? strdup(value) : NULL; if ((type == IPP_TAG_LANGUAGE || type == IPP_TAG_CHARSET) && attr->values[0].string.text) @@ -308,6 +316,7 @@ ippAddStrings(ipp_t *ipp, /* I - IPP request */ { int i; /* Looping var */ ipp_attribute_t *attr; /* New attribute */ + ipp_value_t *value; /* Current value */ if (ipp == NULL || name == NULL) @@ -320,16 +329,20 @@ ippAddStrings(ipp_t *ipp, /* I - IPP request */ attr->group_tag = group; attr->value_tag = type; - if (values != NULL) - for (i = 0; i < num_values; i ++) - { - if (i == 0) - attr->values[0].string.charset = charset ? strdup(charset) : NULL; - else - attr->values[i].string.charset = attr->values[0].string.charset; - - attr->values[i].string.text = strdup(values[i]); - } + for (i = 0, value = attr->values; + i < num_values; + i ++, value ++) + { + if (i == 0) + value->string.charset = ((int)type & IPP_TAG_COPY) ? (char *)charset : + charset ? strdup(charset) : NULL; + else + value->string.charset = attr->values[0].string.charset; + + if (values != NULL) + value->string.text = ((int)type & IPP_TAG_COPY) ? (char *)values[i] : + strdup(values[i]); + } return (attr); } @@ -379,6 +392,7 @@ ippAddRanges(ipp_t *ipp, /* I - IPP request */ { int i; /* Looping var */ ipp_attribute_t *attr; /* New attribute */ + ipp_value_t *value; /* Current value */ if (ipp == NULL || name == NULL) @@ -392,10 +406,12 @@ ippAddRanges(ipp_t *ipp, /* I - IPP request */ attr->value_tag = IPP_TAG_RANGE; if (lower != NULL && upper != NULL) - for (i = 0; i < num_values; i ++) + for (i = 0, value = attr->values; + i < num_values; + i ++, value ++) { - attr->values[i].range.lower = lower[i]; - attr->values[i].range.upper = upper[i]; + value->range.lower = lower[i]; + value->range.upper = upper[i]; } return (attr); @@ -449,6 +465,7 @@ ippAddResolutions(ipp_t *ipp, /* I - IPP request */ { int i; /* Looping var */ ipp_attribute_t *attr; /* New attribute */ + ipp_value_t *value; /* Current value */ if (ipp == NULL || name == NULL) @@ -462,11 +479,13 @@ ippAddResolutions(ipp_t *ipp, /* I - IPP request */ attr->value_tag = IPP_TAG_RESOLUTION; if (xres != NULL && yres != NULL) - for (i = 0; i < num_values; i ++) + for (i = 0, value = attr->values; + i < num_values; + i ++, value ++) { - attr->values[i].resolution.xres = xres[i]; - attr->values[i].resolution.yres = yres[i]; - attr->values[i].resolution.units = units; + value->resolution.xres = xres[i]; + value->resolution.yres = yres[i]; + value->resolution.units = units; } return (attr); @@ -558,7 +577,7 @@ ippDelete(ipp_t *ipp) /* I - IPP request */ *next; /* Next attribute */ - DEBUG_printf(("ippNew(): %p\n", ipp)); + DEBUG_printf(("ippDelete(): %p\n", ipp)); if (ipp == NULL) return; @@ -704,6 +723,7 @@ ippLength(ipp_t *ipp) /* I - IPP request */ int bytes; /* Number of bytes */ ipp_attribute_t *attr; /* Current attribute */ ipp_tag_t group; /* Current group */ + ipp_value_t *value; /* Current value */ if (ipp == NULL) @@ -760,8 +780,10 @@ ippLength(ipp_t *ipp) /* I - IPP request */ case IPP_TAG_CHARSET : case IPP_TAG_LANGUAGE : case IPP_TAG_MIMETYPE : - for (i = 0; i < attr->num_values; i ++) - bytes += strlen(attr->values[i].string.text); + for (i = 0, value = attr->values; + i < attr->num_values; + i ++, value ++) + bytes += strlen(value->string.text); break; case IPP_TAG_DATE : @@ -779,13 +801,17 @@ ippLength(ipp_t *ipp) /* I - IPP request */ case IPP_TAG_TEXTLANG : case IPP_TAG_NAMELANG : bytes += 4 * attr->num_values;/* Charset + text length */ - for (i = 0; i < attr->num_values; i ++) - bytes += strlen(attr->values[i].string.charset) + - strlen(attr->values[i].string.text); + for (i = 0, value = attr->values; + i < attr->num_values; + i ++, value ++) + bytes += strlen(value->string.charset) + + strlen(value->string.text); break; default : - for (i = 0; i < attr->num_values; i ++) + for (i = 0, value = attr->values; + i < attr->num_values; + i ++, value ++) bytes += attr->values[0].unknown.length; break; } @@ -840,6 +866,7 @@ ippRead(http_t *http, /* I - HTTP data */ *bufptr; /* Pointer into buffer */ ipp_attribute_t *attr; /* Current attribute */ ipp_tag_t tag; /* Current tag */ + ipp_value_t *value; /* Current value */ DEBUG_printf(("ippRead(%p, %p)\n", http, ipp)); @@ -983,12 +1010,37 @@ ippRead(http_t *http, /* I - HTTP data */ return (IPP_ERROR); /* - * Finally, make sure we don't have too many elements in the - * attribute array... + * Finally, reallocate the attribute array as needed... */ - if (attr->num_values >= IPP_MAX_VALUES) - return (IPP_ERROR); + if ((attr->num_values % IPP_MAX_VALUES) == 0) + { + ipp_attribute_t *temp, /* Pointer to new buffer */ + *ptr; /* Pointer in attribute list */ + + + /* + * Reallocate memory... + */ + + if ((temp = realloc(attr, sizeof(ipp_attribute_t) + + (attr->num_values + IPP_MAX_VALUES - 1) * + sizeof(ipp_value_t))) == NULL) + return (IPP_ERROR); + + /* + * Reset pointers in the list... + */ + + for (ptr = ipp->attrs; ptr && ptr->next != attr; ptr = ptr->next); + + if (ptr) + ptr->next = temp; + else + ipp->attrs = temp; + + attr = ipp->current = ipp->last = temp; + } } else { @@ -1013,6 +1065,8 @@ ippRead(http_t *http, /* I - HTTP data */ attr->num_values = 0; } + value = attr->values + attr->num_values; + if (ipp_read(http, buffer, 2) < 2) { DEBUG_puts("ippRead: unable to read value length!"); @@ -1032,13 +1086,13 @@ ippRead(http_t *http, /* I - HTTP data */ n = (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) | buffer[3]; - attr->values[attr->num_values].integer = n; + value->integer = n; break; case IPP_TAG_BOOLEAN : if (ipp_read(http, buffer, 1) < 1) return (IPP_ERROR); - attr->values[attr->num_values].boolean = buffer[0]; + value->boolean = buffer[0]; break; case IPP_TAG_TEXT : case IPP_TAG_NAME : @@ -1049,41 +1103,39 @@ ippRead(http_t *http, /* I - HTTP data */ case IPP_TAG_CHARSET : case IPP_TAG_LANGUAGE : case IPP_TAG_MIMETYPE : - if (ipp_read(http, buffer, n) < n) - return (IPP_ERROR); + value->string.text = calloc(n + 1, 1); - buffer[n] = '\0'; - DEBUG_printf(("ippRead: value = \'%s\'\n", buffer)); + if (ipp_read(http, value->string.text, n) < n) + return (IPP_ERROR); - attr->values[attr->num_values].string.text = strdup((char *)buffer); + DEBUG_printf(("ippRead: value = \'%s\'\n", + value->string.text)); break; case IPP_TAG_DATE : - if (ipp_read(http, buffer, 11) < 11) + if (ipp_read(http, value->date, 11) < 11) return (IPP_ERROR); - - memcpy(attr->values[attr->num_values].date, buffer, 11); break; case IPP_TAG_RESOLUTION : if (ipp_read(http, buffer, 9) < 9) return (IPP_ERROR); - attr->values[attr->num_values].resolution.xres = + value->resolution.xres = (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) | buffer[3]; - attr->values[attr->num_values].resolution.yres = + value->resolution.yres = (((((buffer[4] << 8) | buffer[5]) << 8) | buffer[6]) << 8) | buffer[7]; - attr->values[attr->num_values].resolution.units = + value->resolution.units = (ipp_res_t)buffer[8]; break; case IPP_TAG_RANGE : if (ipp_read(http, buffer, 8) < 8) return (IPP_ERROR); - attr->values[attr->num_values].range.lower = + value->range.lower = (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) | buffer[3]; - attr->values[attr->num_values].range.upper = + value->range.upper = (((((buffer[4] << 8) | buffer[5]) << 8) | buffer[6]) << 8) | buffer[7]; break; @@ -1106,31 +1158,30 @@ ippRead(http_t *http, /* I - HTTP data */ n = (bufptr[0] << 8) | bufptr[1]; - attr->values[attr->num_values].string.charset = calloc(n + 1, 1); + value->string.charset = calloc(n + 1, 1); - memcpy(attr->values[attr->num_values].string.charset, + memcpy(value->string.charset, bufptr + 2, n); bufptr += 2 + n; n = (bufptr[0] << 8) | bufptr[1]; - attr->values[attr->num_values].string.text = calloc(n + 1, 1); + value->string.text = calloc(n + 1, 1); - memcpy(attr->values[attr->num_values].string.text, + memcpy(value->string.text, bufptr + 2, n); - break; default : /* Other unsupported values */ - attr->values[attr->num_values].unknown.length = n; + value->unknown.length = n; if (n > 0) { - attr->values[attr->num_values].unknown.data = malloc(n); - if (ipp_read(http, attr->values[attr->num_values].unknown.data, n) < n) + value->unknown.data = malloc(n); + if (ipp_read(http, value->unknown.data, n) < n) return (IPP_ERROR); } else - attr->values[attr->num_values].unknown.data = NULL; + value->unknown.data = NULL; break; } @@ -2158,7 +2209,9 @@ ippWriteFile(int fd, /* I - File to write to */ break; case IPP_TAG_BOOLEAN : - for (i = 0; i < attr->num_values; i ++) + for (i = 0, value = attr->values; + i < attr->num_values; + i ++, value ++) { if ((sizeof(buffer) - (bufptr - buffer)) < 6) { @@ -2185,7 +2238,7 @@ ippWriteFile(int fd, /* I - File to write to */ *bufptr++ = 0; *bufptr++ = 1; - *bufptr++ = attr->values[i].boolean; + *bufptr++ = value->boolean; } break; @@ -2198,7 +2251,9 @@ ippWriteFile(int fd, /* I - File to write to */ case IPP_TAG_CHARSET : case IPP_TAG_LANGUAGE : case IPP_TAG_MIMETYPE : - for (i = 0; i < attr->num_values; i ++) + for (i = 0, value = attr->values; + i < attr->num_values; + i ++, value ++) { if (i) { @@ -2227,7 +2282,7 @@ ippWriteFile(int fd, /* I - File to write to */ *bufptr++ = 0; } - n = strlen(attr->values[i].string.text); + n = strlen(value->string.text); if (n > sizeof(buffer)) return (IPP_ERROR); @@ -2248,13 +2303,15 @@ ippWriteFile(int fd, /* I - File to write to */ *bufptr++ = n >> 8; *bufptr++ = n; - memcpy(bufptr, attr->values[i].string.text, n); + memcpy(bufptr, value->string.text, n); bufptr += n; } break; case IPP_TAG_DATE : - for (i = 0; i < attr->num_values; i ++) + for (i = 0, value = attr->values; + i < attr->num_values; + i ++, value ++) { if ((sizeof(buffer) - (bufptr - buffer)) < 16) { @@ -2281,13 +2338,15 @@ ippWriteFile(int fd, /* I - File to write to */ *bufptr++ = 0; *bufptr++ = 11; - memcpy(bufptr, attr->values[i].date, 11); + memcpy(bufptr, value->date, 11); bufptr += 11; } break; case IPP_TAG_RESOLUTION : - for (i = 0; i < attr->num_values; i ++) + for (i = 0, value = attr->values; + i < attr->num_values; + i ++, value ++) { if ((sizeof(buffer) - (bufptr - buffer)) < 14) { @@ -2314,20 +2373,22 @@ ippWriteFile(int fd, /* I - File to write to */ *bufptr++ = 0; *bufptr++ = 9; - *bufptr++ = attr->values[i].resolution.xres >> 24; - *bufptr++ = attr->values[i].resolution.xres >> 16; - *bufptr++ = attr->values[i].resolution.xres >> 8; - *bufptr++ = attr->values[i].resolution.xres; - *bufptr++ = attr->values[i].resolution.yres >> 24; - *bufptr++ = attr->values[i].resolution.yres >> 16; - *bufptr++ = attr->values[i].resolution.yres >> 8; - *bufptr++ = attr->values[i].resolution.yres; - *bufptr++ = attr->values[i].resolution.units; + *bufptr++ = value->resolution.xres >> 24; + *bufptr++ = value->resolution.xres >> 16; + *bufptr++ = value->resolution.xres >> 8; + *bufptr++ = value->resolution.xres; + *bufptr++ = value->resolution.yres >> 24; + *bufptr++ = value->resolution.yres >> 16; + *bufptr++ = value->resolution.yres >> 8; + *bufptr++ = value->resolution.yres; + *bufptr++ = value->resolution.units; } break; case IPP_TAG_RANGE : - for (i = 0; i < attr->num_values; i ++) + for (i = 0, value = attr->values; + i < attr->num_values; + i ++, value ++) { if ((sizeof(buffer) - (bufptr - buffer)) < 13) { @@ -2354,20 +2415,22 @@ ippWriteFile(int fd, /* I - File to write to */ *bufptr++ = 0; *bufptr++ = 8; - *bufptr++ = attr->values[i].range.lower >> 24; - *bufptr++ = attr->values[i].range.lower >> 16; - *bufptr++ = attr->values[i].range.lower >> 8; - *bufptr++ = attr->values[i].range.lower; - *bufptr++ = attr->values[i].range.upper >> 24; - *bufptr++ = attr->values[i].range.upper >> 16; - *bufptr++ = attr->values[i].range.upper >> 8; - *bufptr++ = attr->values[i].range.upper; + *bufptr++ = value->range.lower >> 24; + *bufptr++ = value->range.lower >> 16; + *bufptr++ = value->range.lower >> 8; + *bufptr++ = value->range.lower; + *bufptr++ = value->range.upper >> 24; + *bufptr++ = value->range.upper >> 16; + *bufptr++ = value->range.upper >> 8; + *bufptr++ = value->range.upper; } break; case IPP_TAG_TEXTLANG : case IPP_TAG_NAMELANG : - for (i = 0; i < attr->num_values; i ++) + for (i = 0, value = attr->values; + i < attr->num_values; + i ++, value ++) { if (i) { @@ -2392,8 +2455,8 @@ ippWriteFile(int fd, /* I - File to write to */ *bufptr++ = 0; } - n = strlen(attr->values[i].string.charset) + - strlen(attr->values[i].string.text) + + n = strlen(value->string.charset) + + strlen(value->string.text) + 4; if (n > sizeof(buffer)) @@ -2415,27 +2478,29 @@ ippWriteFile(int fd, /* I - File to write to */ *bufptr++ = n; /* Length of charset */ - n = strlen(attr->values[i].string.charset); + n = strlen(value->string.charset); *bufptr++ = n >> 8; *bufptr++ = n; /* Charset */ - memcpy(bufptr, attr->values[i].string.charset, n); + memcpy(bufptr, value->string.charset, n); bufptr += n; /* Length of text */ - n = strlen(attr->values[i].string.text); + n = strlen(value->string.text); *bufptr++ = n >> 8; *bufptr++ = n; /* Text */ - memcpy(bufptr, attr->values[i].string.text, n); + memcpy(bufptr, value->string.text, n); bufptr += n; } break; default : - for (i = 0; i < attr->num_values; i ++) + for (i = 0, value = attr->values; + i < attr->num_values; + i ++, value ++) { if (i) { @@ -2460,7 +2525,7 @@ ippWriteFile(int fd, /* I - File to write to */ *bufptr++ = 0; } - n = attr->values[i].unknown.length; + n = value->unknown.length; if (n > sizeof(buffer)) return (IPP_ERROR); @@ -2483,7 +2548,7 @@ ippWriteFile(int fd, /* I - File to write to */ /* Value */ if (n > 0) { - memcpy(bufptr, attr->values[i].unknown.data, n); + memcpy(bufptr, value->unknown.data, n); bufptr += n; } } @@ -2609,7 +2674,8 @@ _ipp_add_attr(ipp_t *ipp, /* I - IPP request */ void _ipp_free_attr(ipp_attribute_t *attr) /* I - Attribute to free */ { - int i; /* Looping var */ + int i; /* Looping var */ + ipp_value_t *value; /* Current value */ DEBUG_printf(("_ipp_free_attr(): %p\n", attr)); @@ -2625,17 +2691,21 @@ _ipp_free_attr(ipp_attribute_t *attr) /* I - Attribute to free */ case IPP_TAG_CHARSET : case IPP_TAG_LANGUAGE : case IPP_TAG_MIMETYPE : - for (i = 0; i < attr->num_values; i ++) - free(attr->values[i].string.text); + for (i = 0, value = attr->values; + i < attr->num_values; + i ++, value ++) + free(value->string.text); break; case IPP_TAG_TEXTLANG : case IPP_TAG_NAMELANG : - for (i = 0; i < attr->num_values; i ++) + for (i = 0, value = attr->values; + i < attr->num_values; + i ++, value ++) { - if (attr->values[i].string.charset && i == 0) - free(attr->values[i].string.charset); - free(attr->values[i].string.text); + if (value->string.charset && i == 0) + free(value->string.charset); + free(value->string.text); } break; @@ -2661,6 +2731,7 @@ ipp_read(http_t *http, /* I - Client connection */ { int tbytes, /* Total bytes read */ bytes; /* Bytes read this pass */ + char len[32]; /* Length string */ /* @@ -2668,8 +2739,46 @@ ipp_read(http_t *http, /* I - Client connection */ */ for (tbytes = 0, bytes = 0; tbytes < length; tbytes += bytes, buffer += bytes) - if ((bytes = httpRead(http, (char *)buffer, length - tbytes)) <= 0) + { + if (http->used > 0) + { + /* + * Do "fast read" from HTTP buffer directly... + */ + + if (http->used > (length - tbytes)) + bytes = length - tbytes; + else + bytes = http->used; + + if (bytes == 1) + buffer[0] = http->buffer[0]; + else + memcpy(buffer, http->buffer, bytes); + + http->used -= bytes; + http->data_remaining -= bytes; + + if (http->used > 0) + memcpy(http->buffer, http->buffer + bytes, http->used); + + if (http->data_remaining == 0) + { + if (http->data_encoding == HTTP_ENCODE_CHUNKED) + httpGets(len, sizeof(len), http); + + if (http->data_encoding != HTTP_ENCODE_CHUNKED) + { + if (http->state == HTTP_POST_RECV) + http->state ++; + else + http->state = HTTP_WAITING; + } + } + } + else if ((bytes = httpRead(http, (char *)buffer, length - tbytes)) <= 0) break; + } /* * Return the number of bytes read... @@ -2683,5 +2792,5 @@ ipp_read(http_t *http, /* I - Client connection */ /* - * End of "$Id: ipp.c,v 1.55.2.2 2001/05/13 18:38:03 mike Exp $". + * End of "$Id: ipp.c,v 1.55.2.3 2001/12/26 16:52:12 mike Exp $". */ diff --git a/cups/ipp.h b/cups/ipp.h index fa00ad172f..3ed98c3211 100644 --- a/cups/ipp.h +++ b/cups/ipp.h @@ -1,5 +1,5 @@ /* - * "$Id: ipp.h,v 1.36.2.2 2001/05/13 18:38:04 mike Exp $" + * "$Id: ipp.h,v 1.36.2.3 2001/12/26 16:52:12 mike Exp $" * * Internet Printing Protocol definitions for the Common UNIX Printing * System (CUPS). @@ -61,7 +61,7 @@ extern "C" { */ # define IPP_MAX_NAME 256 -# define IPP_MAX_VALUES 100 +# define IPP_MAX_VALUES 10 /* Now just an allocation increment */ /* @@ -364,8 +364,7 @@ typedef union /**** Attribute Value ****/ typedef struct ipp_attribute_s /**** Attribute ****/ { - struct ipp_attribute_s *next; - /* Next atrtribute in list */ + struct ipp_attribute_s *next; /* Next attribute in list */ ipp_tag_t group_tag, /* Job/Printer/Operation group tag */ value_tag; /* What type of value is it? */ char *name; /* Name of attribute */ @@ -428,5 +427,5 @@ extern void _ipp_free_attr(ipp_attribute_t *); #endif /* !_CUPS_IPP_H_ */ /* - * End of "$Id: ipp.h,v 1.36.2.2 2001/05/13 18:38:04 mike Exp $". + * End of "$Id: ipp.h,v 1.36.2.3 2001/12/26 16:52:12 mike Exp $". */ diff --git a/cups/language.h b/cups/language.h index 6e64f7966e..eb429a8b89 100644 --- a/cups/language.h +++ b/cups/language.h @@ -1,5 +1,5 @@ /* - * "$Id: language.h,v 1.18 2001/01/22 15:03:26 mike Exp $" + * "$Id: language.h,v 1.18.2.1 2001/12/26 16:52:13 mike Exp $" * * Multi-language support for the Common UNIX Printing System (CUPS). * @@ -201,8 +201,8 @@ typedef struct cups_lang_str /**** Language Cache Structure ****/ # ifdef WIN32 # define cupsLangDefault() cupsLangGet(setlocale(LC_ALL, "")) -# else /* This fix works around bugs in the Linux and HP-UX setlocale() */ -# define cupsLangDefault() cupsLangGet(getenv("LANG")) +# else +# define cupsLangDefault() cupsLangGet(setlocale(LC_MESSAGES, "")) # endif /* WIN32 */ extern char *cupsLangEncoding(cups_lang_t *lang); @@ -218,5 +218,5 @@ extern cups_lang_t *cupsLangGet(const char *language); #endif /* !_CUPS_LANGUAGE_H_ */ /* - * End of "$Id: language.h,v 1.18 2001/01/22 15:03:26 mike Exp $". + * End of "$Id: language.h,v 1.18.2.1 2001/12/26 16:52:13 mike Exp $". */ diff --git a/cups/options.c b/cups/options.c index e2caef283e..4f8ac77c7d 100644 --- a/cups/options.c +++ b/cups/options.c @@ -1,5 +1,5 @@ /* - * "$Id: options.c,v 1.21.2.1 2001/05/13 18:38:04 mike Exp $" + * "$Id: options.c,v 1.21.2.2 2001/12/26 16:52:13 mike Exp $" * * Option routines for the Common UNIX Printing System (CUPS). * @@ -366,6 +366,8 @@ cupsMarkOptions(ppd_file_t *ppd, /* I - PPD file */ { if (ppdMarkOption(ppd, "Duplex", "None")) conflict = 1; + if (ppdMarkOption(ppd, "JCLDuplex", "None")) /* Samsung */ + conflict = 1; if (ppdMarkOption(ppd, "EFDuplex", "None")) /* EFI */ conflict = 1; if (ppdMarkOption(ppd, "KD03Duplex", "None")) /* Kodak */ @@ -375,6 +377,8 @@ cupsMarkOptions(ppd_file_t *ppd, /* I - PPD file */ { if (ppdMarkOption(ppd, "Duplex", "DuplexNoTumble")) conflict = 1; + if (ppdMarkOption(ppd, "JCLDuplex", "DuplexNoTumble")) /* Samsung */ + conflict = 1; if (ppdMarkOption(ppd, "EFDuplex", "DuplexNoTumble")) /* EFI */ conflict = 1; if (ppdMarkOption(ppd, "KD03Duplex", "DuplexNoTumble")) /* Kodak */ @@ -384,6 +388,8 @@ cupsMarkOptions(ppd_file_t *ppd, /* I - PPD file */ { if (ppdMarkOption(ppd, "Duplex", "DuplexTumble")) conflict = 1; + if (ppdMarkOption(ppd, "JCLDuplex", "DuplexTumble")) /* Samsung */ + conflict = 1; if (ppdMarkOption(ppd, "EFDuplex", "DuplexTumble")) /* EFI */ conflict = 1; if (ppdMarkOption(ppd, "KD03Duplex", "DuplexTumble")) /* Kodak */ @@ -416,5 +422,5 @@ cupsMarkOptions(ppd_file_t *ppd, /* I - PPD file */ /* - * End of "$Id: options.c,v 1.21.2.1 2001/05/13 18:38:04 mike Exp $". + * End of "$Id: options.c,v 1.21.2.2 2001/12/26 16:52:13 mike Exp $". */ diff --git a/cups/ppd.c b/cups/ppd.c index 0e8c20fb88..9880168752 100644 --- a/cups/ppd.c +++ b/cups/ppd.c @@ -1,5 +1,5 @@ /* - * "$Id: ppd.c,v 1.51.2.2 2001/05/13 18:38:04 mike Exp $" + * "$Id: ppd.c,v 1.51.2.3 2001/12/26 16:52:13 mike Exp $" * * PPD file routines for the Common UNIX Printing System (CUPS). * @@ -284,12 +284,16 @@ ppd_get_group(ppd_file_t *ppd, /* I - PPD file */ ppd_group_t *group; /* Group */ + DEBUG_printf(("ppd_get_group(%p, \"%s\")\n", ppd, name)); + for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++) if (strcmp(group->text, name) == 0) break; if (i == 0) { + DEBUG_printf(("Adding group %s...\n", name)); + if (ppd->num_groups == 0) group = malloc(sizeof(ppd_group_t)); else @@ -525,6 +529,21 @@ ppdOpen(FILE *fp) /* I - File to read from */ puts(""); #endif /* DEBUG */ + if (strcmp(keyword, "CloseUI") != 0 && + strcmp(keyword, "JCLCloseUI") != 0 && + strcmp(keyword, "CloseGroup") != 0 && + strcmp(keyword, "CloseSubGroup") != 0 && + strncmp(keyword, "Default", 7) != 0 && + string == NULL) + { + /* + * Need a string value! + */ + + ppdClose(ppd); + return (NULL); + } + if (strcmp(keyword, "LanguageLevel") == 0) ppd->language_level = atoi(string); else if (strcmp(keyword, "LanguageEncoding") == 0) @@ -916,13 +935,13 @@ ppdOpen(FILE *fp) /* I - File to read from */ */ if (name[0] == '*') - strcpy(name, name + 1); + strcpy(name, name + 1); /* Eliminate leading asterisk */ - if (string == NULL) - { - ppdClose(ppd); - return (NULL); - } + for (i = strlen(name) - 1; i > 0 && isspace(name[i]); i --) + name[i] = '\0'; /* Eliminate trailing spaces */ + + DEBUG_printf(("OpenUI of %s in group %s...\n", name, + group ? group->text : "(null)")); if (subgroup != NULL) option = ppd_get_option(subgroup, name); @@ -951,6 +970,7 @@ ppdOpen(FILE *fp) /* I - File to read from */ return (NULL); } + DEBUG_printf(("Adding to group %s...\n", group->text)); option = ppd_get_option(group, name); group = NULL; } @@ -1245,14 +1265,40 @@ ppdOpen(FILE *fp) /* I - File to read from */ } else if (strcmp(keyword, "PaperDimension") == 0) { - if ((size = ppdPageSize(ppd, name)) != NULL) - sscanf(string, "%f%f", &(size->width), &(size->length)); + if ((size = ppdPageSize(ppd, name)) == NULL) + size = ppd_add_size(ppd, name); + + if (size == NULL) + { + /* + * Unable to add or find size! + */ + + ppdClose(ppd); + safe_free(string); + return (NULL); + } + + sscanf(string, "%f%f", &(size->width), &(size->length)); } else if (strcmp(keyword, "ImageableArea") == 0) { - if ((size = ppdPageSize(ppd, name)) != NULL) - sscanf(string, "%f%f%f%f", &(size->left), &(size->bottom), - &(size->right), &(size->top)); + if ((size = ppdPageSize(ppd, name)) == NULL) + size = ppd_add_size(ppd, name); + + if (size == NULL) + { + /* + * Unable to add or find size! + */ + + ppdClose(ppd); + safe_free(string); + return (NULL); + } + + sscanf(string, "%f%f%f%f", &(size->left), &(size->bottom), + &(size->right), &(size->top)); } else if (option != NULL && (mask & (PPD_KEYWORD | PPD_OPTION | PPD_STRING)) == @@ -1266,7 +1312,8 @@ ppdOpen(FILE *fp) /* I - File to read from */ * Add a page size... */ - ppd_add_size(ppd, name); + if (ppdPageSize(ppd, name) == NULL) + ppd_add_size(ppd, name); } /* @@ -1584,6 +1631,7 @@ ppd_read(FILE *fp, /* I - File to read from */ char **string) /* O - Code/string data */ { int ch, /* Character from file */ + colon, /* Colon seen? */ endquote, /* Waiting for an end quote */ mask; /* Mask to be returned */ char *keyptr, /* Keyword pointer */ @@ -1616,6 +1664,7 @@ ppd_read(FILE *fp, /* I - File to read from */ lineptr = line; endquote = 0; + colon = 0; while ((ch = getc(fp)) != EOF && (lineptr - line) < (sizeof(line) - 1)) @@ -1656,7 +1705,10 @@ ppd_read(FILE *fp, /* I - File to read from */ *lineptr++ = ch; - if (ch == '\"') + if (ch == ':') + colon = 1; + + if (ch == '\"' && colon) { endquote = !endquote; @@ -1728,6 +1780,8 @@ ppd_read(FILE *fp, /* I - File to read from */ *lineptr = '\0'; +/* DEBUG_printf(("LINE = \"%s\"\n", line));*/ + if (ch == EOF && lineptr == line) return (0); @@ -1746,7 +1800,8 @@ ppd_read(FILE *fp, /* I - File to read from */ if (line[0] != '*') /* All lines start with an asterisk */ continue; - if (strncmp(line, "*%", 2) == 0 || /* Comment line */ + if (strcmp(line, "*") == 0 || /* (Bad) comment line */ + strncmp(line, "*%", 2) == 0 || /* Comment line */ strncmp(line, "*?", 2) == 0 || /* Query line */ strcmp(line, "*End") == 0) /* End of multi-line string */ continue; @@ -1762,15 +1817,21 @@ ppd_read(FILE *fp, /* I - File to read from */ *keyptr++ = *lineptr++; *keyptr = '\0'; + + if (strcmp(keyword, "End") == 0) + continue; + mask |= PPD_KEYWORD; - if (*lineptr == ' ' || *lineptr == '\t') +/* DEBUG_printf(("keyword = \"%s\", lineptr = \"%s\"\n", keyword, lineptr));*/ + + if (isspace(*lineptr)) { /* * Get an option name... */ - while (*lineptr == ' ' || *lineptr == '\t') + while (isspace(*lineptr)) lineptr ++; optptr = option; @@ -1782,6 +1843,8 @@ ppd_read(FILE *fp, /* I - File to read from */ *optptr = '\0'; mask |= PPD_OPTION; +/* DEBUG_printf(("option = \"%s\", lineptr = \"%s\"\n", option, lineptr));*/ + if (*lineptr == '/') { /* @@ -1801,6 +1864,8 @@ ppd_read(FILE *fp, /* I - File to read from */ mask |= PPD_TEXT; } + +/* DEBUG_printf(("text = \"%s\", lineptr = \"%s\"\n", text, lineptr));*/ } if (*lineptr == ':') @@ -1826,6 +1891,8 @@ ppd_read(FILE *fp, /* I - File to read from */ *strptr = '\0'; +/* DEBUG_printf(("string = \"%s\", lineptr = \"%s\"\n", *string, lineptr));*/ + mask |= PPD_STRING; } } @@ -1940,5 +2007,5 @@ ppd_fix(char *string) /* IO - String to fix */ /* - * End of "$Id: ppd.c,v 1.51.2.2 2001/05/13 18:38:04 mike Exp $". + * End of "$Id: ppd.c,v 1.51.2.3 2001/12/26 16:52:13 mike Exp $". */ diff --git a/cups/tempfile.c b/cups/tempfile.c index 3f10352106..d76eff3062 100644 --- a/cups/tempfile.c +++ b/cups/tempfile.c @@ -1,5 +1,5 @@ /* - * "$Id: tempfile.c,v 1.1 2001/03/09 20:06:07 mike Exp $" + * "$Id: tempfile.c,v 1.1.2.1 2001/12/26 16:52:13 mike Exp $" * * Temp file utilities for the Common UNIX Printing System (CUPS). * @@ -139,8 +139,8 @@ cupsTempFd(char *filename, /* I - Pointer to buffer */ fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600); #endif /* O_NOFOLLOW */ - if (fd < 0 && errno == EPERM) - break; /* Stop immediately if permission denied! */ + if (fd < 0 && (errno == EPERM || errno == ENOENT)) + break; /* Stop immediately if permission denied or the dir doesn't exist! */ } while (fd < 0); @@ -196,5 +196,5 @@ cupsTempFile(char *filename, /* I - Pointer to buffer */ /* - * End of "$Id: tempfile.c,v 1.1 2001/03/09 20:06:07 mike Exp $". + * End of "$Id: tempfile.c,v 1.1.2.1 2001/12/26 16:52:13 mike Exp $". */ diff --git a/cups/testppd.c b/cups/testppd.c index 46e2ccec31..5c5d2b1258 100644 --- a/cups/testppd.c +++ b/cups/testppd.c @@ -1,5 +1,5 @@ /* - * "$Id: testppd.c,v 1.18 2001/01/22 15:03:31 mike Exp $" + * "$Id: testppd.c,v 1.18.2.1 2001/12/26 16:52:13 mike Exp $" * * PPD test program for the Common UNIX Printing System (CUPS). * @@ -56,6 +56,8 @@ main(int argc, /* I - Number of command-line arguments */ "JCL", "PAGE", "PROLOG" }; + setbuf(stdout, NULL); + /* * Display PPD files for each file listed on the command-line... */ @@ -127,9 +129,10 @@ main(int argc, /* I - Number of command-line arguments */ for (k = 0, option = group->options; k < group->num_options; k ++, option ++) { - printf(" options[%d] = %s (%s) %s %s %.0f\n", k, + printf(" options[%d] = %s (%s) %s %s %.0f (%d choices)\n", k, option->keyword, option->text, uis[option->ui], - sections[option->section], option->order); + sections[option->section], option->order, + option->num_choices); if (strcmp(option->keyword, "PageSize") == 0 || strcmp(option->keyword, "PageRegion") == 0) @@ -194,5 +197,5 @@ main(int argc, /* I - Number of command-line arguments */ /* - * End of "$Id: testppd.c,v 1.18 2001/01/22 15:03:31 mike Exp $". + * End of "$Id: testppd.c,v 1.18.2.1 2001/12/26 16:52:13 mike Exp $". */ diff --git a/cups/util.c b/cups/util.c index 210c4d61b2..083cd5a643 100644 --- a/cups/util.c +++ b/cups/util.c @@ -1,5 +1,5 @@ /* - * "$Id: util.c,v 1.81.2.2 2001/05/13 18:38:05 mike Exp $" + * "$Id: util.c,v 1.81.2.3 2001/12/26 16:52:13 mike Exp $" * * Printing utilities for the Common UNIX Printing System (CUPS). * @@ -172,7 +172,7 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */ FILE *file; /* File to send */ struct stat fileinfo; /* File information */ int bytes; /* Number of bytes read/written */ - char buffer[8192]; /* Output buffer */ + char buffer[32768]; /* Output buffer */ const char *password; /* Password string */ char realm[HTTP_MAX_VALUE], /* realm="xyz" string */ nonce[HTTP_MAX_VALUE], /* nonce="xyz" string */ @@ -240,9 +240,10 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */ */ if (filename != NULL) - sprintf(length, "%u", ippLength(request) + (size_t)fileinfo.st_size); + sprintf(length, "%lu", (unsigned long)(ippLength(request) + + (size_t)fileinfo.st_size)); else - sprintf(length, "%u", ippLength(request)); + sprintf(length, "%lu", (unsigned long)ippLength(request)); httpClearFields(http); httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, length); @@ -1677,5 +1678,5 @@ cups_local_auth(http_t *http) /* I - Connection */ /* - * End of "$Id: util.c,v 1.81.2.2 2001/05/13 18:38:05 mike Exp $". + * End of "$Id: util.c,v 1.81.2.3 2001/12/26 16:52:13 mike Exp $". */ diff --git a/data/Makefile b/data/Makefile index 9b4b1e4b30..f7e3767cae 100644 --- a/data/Makefile +++ b/data/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.12 2001/01/22 15:03:32 mike Exp $" +# "$Id: Makefile,v 1.12.2.1 2001/12/26 16:52:14 mike Exp $" # # Datafile makefile for the Common UNIX Printing System (CUPS). # @@ -81,19 +81,20 @@ clean: # install: - -$(MKDIR) $(DATADIR)/banners - $(CHMOD) ugo+rx $(DATADIR) - $(CHMOD) ugo+rx $(DATADIR)/banners - $(INSTALL_DATA) $(BANNERS) $(DATADIR)/banners - -$(MKDIR) $(DATADIR)/charsets - $(CHMOD) ugo+rx $(DATADIR)/charsets - $(INSTALL_DATA) $(CHARSETS) $(DATADIR)/charsets - -$(MKDIR) $(DATADIR)/data - $(CHMOD) ugo+rx $(DATADIR)/data - $(INSTALL_DATA) $(DATAFILES) $(DATADIR)/data - -if test "$(PAMDIR)" != ""; then \ - $(MKDIR) $(PAMDIR); \ - $(CHMOD) ugo+rx $(PAMDIR); \ + $(INSTALL_DIR) $(DATADIR)/banners + for file in $(BANNERS); do \ + $(INSTALL_DATA) $$file $(DATADIR)/banners; \ + done + $(INSTALL_DIR) $(DATADIR)/charsets + for file in $(CHARSETS); do \ + $(INSTALL_DATA) $$file $(DATADIR)/charsets; \ + done + $(INSTALL_DIR) $(DATADIR)/data + for file in $(DATAFILES); do \ + $(INSTALL_DATA) $$file $(DATADIR)/data; \ + done + -if test x$(PAMDIR) != x; then \ + $(INSTALL_DIR) $(PAMDIR); \ if test -f /lib/security/pam_unix.so; then \ $(INSTALL_DATA) cups.suse $(PAMDIR)/cups; \ else \ @@ -103,5 +104,5 @@ install: # -# End of "$Id: Makefile,v 1.12 2001/01/22 15:03:32 mike Exp $". +# End of "$Id: Makefile,v 1.12.2.1 2001/12/26 16:52:14 mike Exp $". # diff --git a/doc/Makefile b/doc/Makefile index f0ff35cec3..c293368c86 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.33 2001/03/02 03:45:34 andy Exp $" +# "$Id: Makefile,v 1.33.2.1 2001/12/26 16:52:14 mike Exp $" # # Documentation makefile for the Common UNIX Printing System (CUPS). # @@ -118,16 +118,22 @@ clean: # install: - -$(MKDIR) $(DOCDIR) - $(CHMOD) ugo+rx $(DOCDIR) - $(INSTALL_MAN) $(WEBPAGES) $(DOCDIR) - $(INSTALL_MAN) overview.html overview.pdf $(DOCDIR) - $(INSTALL_MAN) $(DOCUMENTS:.shtml=.html) $(DOCDIR) - $(INSTALL_MAN) $(DOCUMENTS:.shtml=.pdf) $(DOCDIR) - -$(MKDIR) $(DOCDIR)/images - $(CHMOD) ugo+rx $(DOCDIR)/images - $(INSTALL_MAN) $(WEBIMAGES) $(DOCDIR)/images - $(INSTALL_MAN) $(DOCIMAGES) $(DOCDIR)/images + $(INSTALL_DIR) $(DOCDIR) + for file in $(WEBPAGES); do \ + $(INSTALL_MAN) $$file $(DOCDIR); \ + done + $(INSTALL_MAN) overview.html $(DOCDIR) + $(INSTALL_MAN) overview.pdf $(DOCDIR) + for file in $(DOCUMENTS:.shtml=.html); do \ + $(INSTALL_MAN) $$file $(DOCDIR); \ + done + for file in $(DOCUMENTS:.shtml=.pdf); do \ + $(INSTALL_MAN) $$file $(DOCDIR); \ + done + $(INSTALL_DIR) $(DOCDIR)/images + for file in $(WEBIMAGES) $(DOCIMAGES); do \ + $(INSTALL_MAN) $$file $(DOCDIR)/images; \ + done # diff --git a/doc/cmp.html b/doc/cmp.html index a950f872b8..022fb47022 100644 --- a/doc/cmp.html +++ b/doc/cmp.html @@ -1,27 +1,27 @@ - CUPS Configuration Management Plan +CUPS Configuration Management Plan -

-

CUPS Configuration Management Plan


+

+

CUPS Configuration Management Plan


CUPS-CMP-1.1
Easy Software Products
Copyright 1997-2001, All Rights Reserved
@@ -116,28 +116,28 @@ Copyright 1997-2001, All Rights Reserved
C Software Trouble Report Form

1 Scope

1.1 Identification

- This configuration management plan document provides the guidelines -for development and maintenance of the Common UNIX Printing System -("CUPS") Version 1.1 software. + This configuration management plan document provides the guidelines for + development and maintenance of the Common UNIX Printing System ("CUPS") + Version 1.1 software.

1.2 System Overview

-

CUPS provides a portable printing layer for UNIX®-based operating -systems. It has been developed by Easy -Software Products to promote a standard printing solution for all -UNIX vendors and users. CUPS provides the System V and Berkeley -command-line interfaces.

-

CUPS uses the Internet Printing Protocol ("IPP") as the basis for -managing print jobs and queues. The Line Printer Daemon ("LPD") Server -Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are -also supported with reduced functionality. CUPS adds network printer -browsing and PostScript Printer Description ("PPD") based printing -options to support real-world printing under UNIX.

-

CUPS also includes a customized version of GNU Ghostscript -(currently based off GNU Ghostscript 5.50) and an image file RIP that -are used to support non-PostScript printers. Sample drivers for HP and -EPSON printers are included that use these filters.

+

CUPS provides a portable printing layer for UNIX®-based operating + systems. It has been developed by Easy + Software Products to promote a standard printing solution for all + UNIX vendors and users. CUPS provides the System V and Berkeley + command-line interfaces.

+

CUPS uses the Internet Printing Protocol ("IPP") as the basis for + managing print jobs and queues. The Line Printer Daemon ("LPD") Server + Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are + also supported with reduced functionality. CUPS adds network printer + browsing and PostScript Printer Description ("PPD") based printing + options to support real-world printing under UNIX.

+

CUPS also includes a customized version of GNU Ghostscript (currently + based off GNU Ghostscript 5.50) and an image file RIP that are used to + support non-PostScript printers. Sample drivers for HP and EPSON + printers are included that use these filters.

1.3 Document Overview

- This configuration management document is organized into the following -sections: + This configuration management document is organized into the following + sections:
  • 1 - Scope
  • 2 - References
  • @@ -149,74 +149,74 @@ sections:

2 References

2.1 CUPS Documentation

-

The following CUPS documentation is referenced by this document:

-
    -
  • CUPS-CMP-1.1: CUPS Configuration Management Plan
  • -
  • CUPS-IDD-1.1: CUPS System Interface Design Description
  • -
  • CUPS-IPP-1.1: CUPS Implementation of IPP
  • -
  • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
  • -
  • CUPS-SDD-1.1: CUPS Software Design Description
  • -
  • CUPS-SPM-1.1.x: CUPS Software Programming Manual
  • -
  • CUPS-SSR-1.1: CUPS Software Security Report
  • -
  • CUPS-STP-1.1: CUPS Software Test Plan
  • -
  • CUPS-SUM-1.1.x: CUPS Software Users Manual
  • -
  • CUPS-SVD-1.1: CUPS Software Version Description
  • +

    The following CUPS documentation is referenced by this document:

    +
      +
    • CUPS-CMP-1.1: CUPS Configuration Management Plan
    • +
    • CUPS-IDD-1.1: CUPS System Interface Design Description
    • +
    • CUPS-IPP-1.1: CUPS Implementation of IPP
    • +
    • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
    • +
    • CUPS-SDD-1.1: CUPS Software Design Description
    • +
    • CUPS-SPM-1.1.x: CUPS Software Programming Manual
    • +
    • CUPS-SSR-1.1: CUPS Software Security Report
    • +
    • CUPS-STP-1.1: CUPS Software Test Plan
    • +
    • CUPS-SUM-1.1.x: CUPS Software Users Manual
    • +
    • CUPS-SVD-1.1: CUPS Software Version Description

    2.2 Other Documents

    -

    The following non-CUPS documents are referenced by this document:

    +

    The following non-CUPS documents are referenced by this document:

    3 File Management

    3.1 Directory Structure

    - Each source file shall be placed a sub-directory corresponding to the -software sub-system it belongs to ("scheduler", "cups", etc.) To remain -compatible with older UNIX filesystems, directory names shall not -exceed 16 characters in length. + Each source file shall be placed a sub-directory corresponding to the + software sub-system it belongs to ("scheduler", "cups", etc.) To remain + compatible with older UNIX filesystems, directory names shall not + exceed 16 characters in length.

    3.2 Source Files

    - Source files shall be documented and formatted as described in -Appendix B, Coding Requirements. + Source files shall be documented and formatted as described in Appendix + B, Coding Requirements.

    3.3 Configuration Management

    - Source files shall be placed under the control of the Concurrent -Versions System ("CVS") software. Source files shall be "checked in" -with each change so that modifications can be tracked. -

    Documentation on the CVS software is included with the whitepaper, -"CVS II: Parallelizing Software Development".

    + Source files shall be placed under the control of the Concurrent + Versions System ("CVS") software. Source files shall be "checked in" + with each change so that modifications can be tracked. +

    Documentation on the CVS software is included with the whitepaper, + "CVS II: Parallelizing Software Development".

    4 Trouble Report Processing

    - A Software Trouble Report ("STR") shall be submitted every time a user -or vendor experiences a problem with the CUPS software. Trouble reports -are maintained in a database with one of the following states: + A Software Trouble Report ("STR") shall be submitted every time a user + or vendor experiences a problem with the CUPS software. Trouble reports + are maintained in a database with one of the following states:
    1. STR is closed with complete resolution
    2. STR is closed without resolution
    3. STR is active
    4. STR is pending (new STR or additional information available)
    - Trouble reports shall be processed using the following steps. + Trouble reports shall be processed using the following steps.

    4.1 Classification

    - When a trouble report is received it must be classified at one of the -following levels: + When a trouble report is received it must be classified at one of the + following levels:
    1. Request for enhancement
    2. Documentation error
    3. @@ -224,61 +224,61 @@ following levels:
    4. Unable to print to a printer
    5. Unable to print at all
    - The scope of the problem should also be determined as: + The scope of the problem should also be determined as:
    1. Specific to a machine
    2. Specific to an operating system
    3. Applies to all machines and operating systems

    4.2 Identification

    - Once the level and scope of the trouble report is determined the -software sub-system(s) involved with the problem are determined. This -may involve additional communication with the user or vendor to isolate -the problem to a specific cause. -

    When the sub-system(s) involved have been identified, an engineer -will then determine the change(s) needed and estimate the time required -for the change(s).

    + Once the level and scope of the trouble report is determined the + software sub-system(s) involved with the problem are determined. This + may involve additional communication with the user or vendor to isolate + the problem to a specific cause. +

    When the sub-system(s) involved have been identified, an engineer + will then determine the change(s) needed and estimate the time required + for the change(s).

    4.3 Correction

    - Corrections are scheduled based upon the severity and complexity of -the problem. Once all changes have been made, documented, and tested -successfully a new software release snapshot is generated. Additional -tests are added as necessary for proper testing of the changes. + Corrections are scheduled based upon the severity and complexity of the + problem. Once all changes have been made, documented, and tested + successfully a new software release snapshot is generated. Additional + tests are added as necessary for proper testing of the changes.

    4.4 Notification

    - The user or vendor is notified when the fix is available or if the -problem was caused by user error. + The user or vendor is notified when the fix is available or if the + problem was caused by user error.

    5 Software Releases

    5.1 Version Numbering

    - CUPS uses a three-part version number separated by periods to -represent the major, minor, and patch release numbers: + CUPS uses a three-part version number separated by periods to represent + the major, minor, and patch release numbers:
       major.minor.patch
       1.1.0
       
    - Beta-test releases are indentified by appending the letter B followed -by the build number: + Beta-test releases are indentified by appending the letter B followed + by the build number:
       major.minor.patchbbuild
       1.1.0b1
       
    - A CVS snapshot is generated for every beta and final release and uses -the version number preceded by the letter "v" and with the decimal -points replaced by underscores: + A CVS snapshot is generated for every beta and final release and uses + the version number preceded by the letter "v" and with the decimal + points replaced by underscores:
       v1_0_0b1
       v1_0_0
       
    - Each change that corrects a fault in a software sub-system increments -the patch release number. If a change affects the software design of -CUPS then the minor release number will be incremented and the patch -release number reset to 0. If CUPS is completely redesigned the major -release number will be incremented and the minor and patch release -numbers reset to 0: + Each change that corrects a fault in a software sub-system increments + the patch release number. If a change affects the software design of + CUPS then the minor release number will be incremented and the patch + release number reset to 0. If CUPS is completely redesigned the major + release number will be incremented and the minor and patch release + numbers reset to 0:
       1.1.0b1    First beta release
      @@ -293,82 +293,82 @@ numbers reset to 0:
       

    5.2 Generation

    - Software releases shall be generated for each successfully completed -software trouble report. All object and executable files shall be -deleted prior to performing a full build to ensure that source files -are recompiled. + Software releases shall be generated for each successfully completed + software trouble report. All object and executable files shall be + deleted prior to performing a full build to ensure that source files + are recompiled.

    5.3 Testing

    - Software testing shall be conducted according to the CUPS Software -Test Plan, CUPS-STP-1.1. Failed tests cause STRs to be generated to -correct the problems found. + Software testing shall be conducted according to the CUPS Software Test + Plan, CUPS-STP-1.1. Failed tests cause STRs to be generated to correct + the problems found.

    5.4 Release

    - When testing has been completed successfully a new distribution image -is created from the current CVS code "snapshot". No production release -shall contain software that has not passed the appropriate software -tests. + When testing has been completed successfully a new distribution image + is created from the current CVS code "snapshot". No production release + shall contain software that has not passed the appropriate software + tests.

    A Glossary

    A.1 Terms

    -
    C
    -
    A computer language.
    -
    parallel
    -
    Sending or receiving data more than 1 bit at a time.
    -
    pipe
    -
    A one-way communications channel between two programs.
    -
    serial
    -
    Sending or receiving data 1 bit at a time.
    -
    socket
    -
    A two-way network communications channel.
    +
    C
    +
    A computer language.
    +
    parallel
    +
    Sending or receiving data more than 1 bit at a time.
    +
    pipe
    +
    A one-way communications channel between two programs.
    +
    serial
    +
    Sending or receiving data 1 bit at a time.
    +
    socket
    +
    A two-way network communications channel.

    A.2 Acronyms

    -
    ASCII
    -
    American Standard Code for Information Interchange
    -
    CUPS
    -
    Common UNIX Printing System
    -
    ESC/P
    -
    EPSON Standard Code for Printers
    -
    FTP
    -
    File Transfer Protocol
    -
    HP-GL
    -
    Hewlett-Packard Graphics Language
    -
    HP-PCL
    -
    Hewlett-Packard Page Control Language
    -
    HP-PJL
    -
    Hewlett-Packard Printer Job Language
    -
    IETF
    -
    Internet Engineering Task Force
    -
    IPP
    -
    Internet Printing Protocol
    -
    ISO
    -
    International Standards Organization
    -
    LPD
    -
    Line Printer Daemon
    -
    MIME
    -
    Multimedia Internet Mail Exchange
    -
    PPD
    -
    PostScript Printer Description
    -
    SMB
    -
    Server Message Block
    -
    TFTP
    -
    Trivial File Transfer Protocol
    +
    ASCII
    +
    American Standard Code for Information Interchange
    +
    CUPS
    +
    Common UNIX Printing System
    +
    ESC/P
    +
    EPSON Standard Code for Printers
    +
    FTP
    +
    File Transfer Protocol
    +
    HP-GL
    +
    Hewlett-Packard Graphics Language
    +
    HP-PCL
    +
    Hewlett-Packard Page Control Language
    +
    HP-PJL
    +
    Hewlett-Packard Printer Job Language
    +
    IETF
    +
    Internet Engineering Task Force
    +
    IPP
    +
    Internet Printing Protocol
    +
    ISO
    +
    International Standards Organization
    +
    LPD
    +
    Line Printer Daemon
    +
    MIME
    +
    Multimedia Internet Mail Exchange
    +
    PPD
    +
    PostScript Printer Description
    +
    SMB
    +
    Server Message Block
    +
    TFTP
    +
    Trivial File Transfer Protocol

    B Coding Requirements

    - These coding requirements provide detailed information on source file -formatting and documentation content. These guidelines shall be applied -to all C and C++ source files provided with CUPS. + These coding requirements provide detailed information on source file + formatting and documentation content. These guidelines shall be applied + to all C and C++ source files provided with CUPS.

    B.1 Source Files

    B.1.1 Naming

    - All source files names shall be 16 characters or less in length to -ensure compatibility with older UNIX filesystems. Source files -containing functions shall have an extension of ".c" for ANSI C and -".cxx" for C++ source files. All other "include" files shall have an -extension of ".h". + All source files names shall be 16 characters or less in length to + ensure compatibility with older UNIX filesystems. Source files + containing functions shall have an extension of ".c" for ANSI C and + ".cxx" for C++ source files. All other "include" files shall have an + extension of ".h".

    B.1.2 Documentation

    - The top of each source file shall contain a header giving the name of -the file, the purpose or nature of the source file, the copyright and -licensing notice, and the functions contained in the file. The file -name and revision information is provided by the CVS "$Id$" tag: + The top of each source file shall contain a header giving the name of + the file, the purpose or nature of the source file, the copyright and + licensing notice, and the functions contained in the file. The file + name and revision information is provided by the CVS "$Id$" tag:
       /*
      @@ -403,10 +403,10 @@ name and revision information is provided by the CVS "$Id$" tag:
        */
       
    - The bottom of each source file shall contain a trailer giving the name -of the file using the CVS "$Id$" tag. The primary purpose of this is to -mark the end of a source file; if the trailer is missing it is possible -that code has been lost near the end of the file: + The bottom of each source file shall contain a trailer giving the name + of the file using the CVS "$Id$" tag. The primary purpose of this is to + mark the end of a source file; if the trailer is missing it is possible + that code has been lost near the end of the file:
       /*
      @@ -416,17 +416,17 @@ that code has been lost near the end of the file:
       

    B.2 Functions

    B.2.1 Naming

    - Functions with a global scope shall be capitalized ("DoThis", -"DoThat", "DoSomethingElse", etc.) The only exception to this rule -shall be the CUPS interface library functions which may begin with a -prefix word in lowercase ("cupsDoThis", "cupsDoThat", etc.) -

    Functions with a local scope shall be declared "static" and be -lowercase with underscores between words ("do_this", "do_that", -"do_something_else", etc.)

    + Functions with a global scope shall be capitalized ("DoThis", "DoThat", + "DoSomethingElse", etc.) The only exception to this rule shall be the + CUPS interface library functions which may begin with a prefix word in + lowercase ("cupsDoThis", "cupsDoThat", etc.) +

    Functions with a local scope shall be declared "static" and be + lowercase with underscores between words ("do_this", "do_that", + "do_something_else", etc.)

    B.2.2 Documentation

    - Each function shall begin with a comment header describing what the -function does, the possible input limits (if any), and the possible -output values (if any), and any special information needed: + Each function shall begin with a comment header describing what the + function does, the possible input limits (if any), and the possible + output values (if any), and any special information needed:
       /*
      @@ -445,12 +445,12 @@ do_this(float x) /* I - Power value (0.0 <= x <= 1.1) */
       

    B.3 Methods

    B.3.1 Naming

    - Methods shall be in lowercase with underscores between words -("do_this", "do_that", "do_something_else", etc.) + Methods shall be in lowercase with underscores between words + ("do_this", "do_that", "do_something_else", etc.)

    B.3.2 Documentation

    - Each method shall begin with a comment header describing what the -method does, the possible input limits (if any), and the possible -output values (if any), and any special information needed: + Each method shall begin with a comment header describing what the + method does, the possible input limits (if any), and the possible + output values (if any), and any special information needed:
       /*
      @@ -469,19 +469,19 @@ class::do_this(float x) /* I - Power value (0.0 <= x <= 1.0) */
       

    B.4 Variables

    B.4.1 Naming

    - Variables with a global scope shall be capitalized ("ThisVariable", -"ThatVariable", "ThisStateVariable", etc.) The only exception to this -rule shall be the CUPS interface library global variables which must -begin with the prefix "cups" ("cupsThisVariable", "cupsThatVariable", -etc.) Global variables shall be replaced by function arguments whenever -possible. -

    Variables with a local scope shall be lowercase with underscores -between words ("this_variable", "that_variable", etc.) Any local -variables shared by functions within a source file shall be declared -"static".

    + Variables with a global scope shall be capitalized ("ThisVariable", + "ThatVariable", "ThisStateVariable", etc.) The only exception to this + rule shall be the CUPS interface library global variables which must + begin with the prefix "cups" ("cupsThisVariable", "cupsThatVariable", + etc.) Global variables shall be replaced by function arguments whenever + possible. +

    Variables with a local scope shall be lowercase with underscores + between words ("this_variable", "that_variable", etc.) Any local + variables shared by functions within a source file shall be declared + "static".

    B.4.2 Documentation

    - Each variable shall be declared on a separate line and shall be -immediately followed by a comment block describing the variable: + Each variable shall be declared on a separate line and shall be + immediately followed by a comment block describing the variable:
       int this_variable;   /* The current state of this */
      @@ -490,11 +490,11 @@ int that_variable;   /* The current state of that */
       

    B.5 Types

    B.5.1 Naming

    - All type names shall be lowercase with underscores between words and -"_t" appended to the end of the name ("this_type_t", "that_type_t", -etc.) + All type names shall be lowercase with underscores between words and + "_t" appended to the end of the name ("this_type_t", "that_type_t", + etc.)

    B.5.2 Documentation

    - Each type shall have a comment block immediately before the typedef: + Each type shall have a comment block immediately before the typedef:
       /*
      @@ -505,13 +505,13 @@ typedef int cups_this_type_t;
       

    B.6 Structures

    B.6.1 Naming

    - All structure names shall be lowercase with underscores between words -and "_str" appended to the end of the name ("this_struct_str", -"that_struct_str", etc.) + All structure names shall be lowercase with underscores between words + and "_str" appended to the end of the name ("this_struct_str", + "that_struct_str", etc.)

    B.6.2 Documentation

    - Each structure shall have a comment block immediately before the -struct and each member shall be documented in accordance with the -variable naming policy above: + Each structure shall have a comment block immediately before the struct + and each member shall be documented in accordance with the variable + naming policy above:
       /*
      @@ -526,12 +526,12 @@ struct cups_this_struct_str
       

    B.7 Classes

    B.7.1 Naming

    - All class names shall be lowercase with underscores between words -("this_class", "that_class", etc.) + All class names shall be lowercase with underscores between words + ("this_class", "that_class", etc.)

    B.7.2 Documentation

    - Each class shall have a comment block immediately before the class and -each member shall be documented in accordance with the variable naming -policy above: + Each class shall have a comment block immediately before the class and + each member shall be documented in accordance with the variable naming + policy above:
       /*
      @@ -546,14 +546,14 @@ class cups_this_class
       

    B.8 Constants

    B.8.1 Naming

    - All constant names shall be uppercase with underscored between words -("THIS_CONSTANT", "THAT_CONSTANT", etc.) Constants defined for the CUPS -interface library must begin with an uppercase prefix -("CUPS_THIS_CONSTANT", "CUPS_THAT_CONSTANT", etc.) -

    Typed enumerations shall be used whenever possible to allow for type -checking by the compiler.

    + All constant names shall be uppercase with underscored between words + ("THIS_CONSTANT", "THAT_CONSTANT", etc.) Constants defined for the CUPS + interface library must begin with an uppercase prefix + ("CUPS_THIS_CONSTANT", "CUPS_THAT_CONSTANT", etc.) +

    Typed enumerations shall be used whenever possible to allow for type + checking by the compiler.

    B.8.2 Documentation

    - Comment blocks shall immediately follow each constant: + Comment blocks shall immediately follow each constant:
       enum
      @@ -565,8 +565,8 @@ enum
       

    B.9 Code

    B.9.1 Documentation

    - All source code shall utilize block comments within functions to -describe the operations being performed by a group of statements: + All source code shall utilize block comments within functions to + describe the operations being performed by a group of statements:
       /*
      @@ -593,10 +593,10 @@ do
       

    B.9.2 Style

    B.9.2.a Indentation

    - All code blocks enclosed by brackets shall begin with the opening -brace on a new line. The code then follows starting on a new line after -the brace and is indented 2 spaces. The closing brace is then placed on -a new line following the code at the original indentation: + All code blocks enclosed by brackets shall begin with the opening brace + on a new line. The code then follows starting on a new line after the + brace and is indented 2 spaces. The closing brace is then placed on a + new line following the code at the original indentation:
       {
      @@ -614,10 +614,9 @@ a new line following the code at the original indentation:
       }
       
    - Single-line statements following "do", "else", "for", "if", and -"while" shall be indented 2 spaces as well. Blocks of code in a -"switch" block shall be indented 4 spaces after each "case" and -"default" case: + Single-line statements following "do", "else", "for", "if", and "while" + shall be indented 2 spaces as well. Blocks of code in a "switch" block + shall be indented 4 spaces after each "case" and "default" case:
       switch (array[i])
      @@ -633,20 +632,20 @@ switch (array[i])
       

    B.9.2.b Spacing

    - A space shall follow each reserved word ("if", "while", etc.) Spaces -shall not be inserted between a function name and the arguments in -parenthesis. + A space shall follow each reserved word ("if", "while", etc.) Spaces + shall not be inserted between a function name and the arguments in + parenthesis.

    B.9.2.c Return Values

    - Parenthesis shall surround values returned from a function using -"return": + Parenthesis shall surround values returned from a function using + "return":
       return (STATE_IDLE);
       

    B.9.2.d Loops

    - Whenever convenient loops should count downward to zero to improve -program performance: + Whenever convenient loops should count downward to zero to improve + program performance:
       for (i = sizeof(array) / sizeof(array[0]) - 1; i >= 0; i --)
      @@ -658,19 +657,19 @@ for (i = sizeof(array) / sizeof(array[0]) - 1; i >= 0; i --)
       
      -
      -
      +
      Summary of Problem: ________________________________________
      Problem Severity:__1=RFE -
      __2=Documentation-Error -
      __3=Unable-to-Print-a-File -
      __4=Unable-to-Print-to-a-Printer +
      Problem Severity:__1=RFE +
      __2=Documentation-Error +
      __3=Unable-to-Print-a-File +
      __4=Unable-to-Print-to-a-Printer
      __5=Unable-to-Print-at-All
      Problem Scope:__1=Machine -__2=Operating-System __3=All
      Problem Scope:__1=Machine + __2=Operating-System __3=All
      Detailed Description of Problem:________________________________________ -
      ________________________________________ -
      ________________________________________ -
      ________________________________________ -
      ________________________________________ +ALIGN="LEFT">________________________________________ +
      ________________________________________ +
      ________________________________________ +
      ________________________________________ +
      ________________________________________
      ________________________________________
diff --git a/doc/cmp.pdf b/doc/cmp.pdf index 990f61b966..81a8f32eb1 100644 Binary files a/doc/cmp.pdf and b/doc/cmp.pdf differ diff --git a/doc/idd.html b/doc/idd.html index e8505391a0..dba4fa674d 100644 --- a/doc/idd.html +++ b/doc/idd.html @@ -1,27 +1,27 @@ - CUPS Interface Design Description +CUPS Interface Design Description -

-

CUPS Interface Design Description


+

+

CUPS Interface Design Description


CUPS-IDD-1.1
Easy Software Products
Copyright 1997-2001, All Rights Reserved
@@ -91,197 +91,197 @@ Copyright 1997-2001, All Rights Reserved

1 Scope

1.1 Identification

-

This interface design description document provides detailed file -formats, message formats, and program conventions for the Common UNIX -Printing System ("CUPS") Version 1.1.

+

This interface design description document provides detailed file + formats, message formats, and program conventions for the Common UNIX + Printing System ("CUPS") Version 1.1.

1.2 System Overview

-

CUPS provides a portable printing layer for UNIX®-based operating -systems. It has been developed by Easy -Software Products to promote a standard printing solution for all -UNIX vendors and users. CUPS provides the System V and Berkeley -command-line interfaces.

-

CUPS uses the Internet Printing Protocol ("IPP") as the basis for -managing print jobs and queues. The Line Printer Daemon ("LPD") Server -Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are -also supported with reduced functionality. CUPS adds network printer -browsing and PostScript Printer Description ("PPD") based printing -options to support real-world printing under UNIX.

-

CUPS also includes a customized version of GNU Ghostscript -(currently based off GNU Ghostscript 5.50) and an image file RIP that -are used to support non-PostScript printers. Sample drivers for HP and -EPSON printers are included that use these filters.

+

CUPS provides a portable printing layer for UNIX®-based operating + systems. It has been developed by Easy + Software Products to promote a standard printing solution for all + UNIX vendors and users. CUPS provides the System V and Berkeley + command-line interfaces.

+

CUPS uses the Internet Printing Protocol ("IPP") as the basis for + managing print jobs and queues. The Line Printer Daemon ("LPD") Server + Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are + also supported with reduced functionality. CUPS adds network printer + browsing and PostScript Printer Description ("PPD") based printing + options to support real-world printing under UNIX.

+

CUPS also includes a customized version of GNU Ghostscript (currently + based off GNU Ghostscript 5.50) and an image file RIP that are used to + support non-PostScript printers. Sample drivers for HP and EPSON + printers are included that use these filters.

1.3 Document Overview

-

This interface design description document is organized into the -following sections:

+

This interface design description document is organized into the + following sections:

    -
  • 1 - Scope
  • -
  • 2 - References
  • -
  • 3 - Internal Interfaces
  • -
  • 4 - External Interfaces
  • -
  • 5 - Directories
  • -
  • A - Glossary
  • +
  • 1 - Scope
  • +
  • 2 - References
  • +
  • 3 - Internal Interfaces
  • +
  • 4 - External Interfaces
  • +
  • 5 - Directories
  • +
  • A - Glossary

2 References

2.1 CUPS Documentation

-

The following CUPS documentation is referenced by this document:

+

The following CUPS documentation is referenced by this document:

    -
  • CUPS-CMP-1.1: CUPS Configuration Management Plan
  • -
  • CUPS-IDD-1.1: CUPS System Interface Design Description
  • -
  • CUPS-IPP-1.1: CUPS Implementation of IPP
  • -
  • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
  • -
  • CUPS-SDD-1.1: CUPS Software Design Description
  • -
  • CUPS-SPM-1.1.x: CUPS Software Programming Manual
  • -
  • CUPS-SSR-1.1: CUPS Software Security Report
  • -
  • CUPS-STP-1.1: CUPS Software Test Plan
  • -
  • CUPS-SUM-1.1.x: CUPS Software Users Manual
  • -
  • CUPS-SVD-1.1: CUPS Software Version Description
  • +
  • CUPS-CMP-1.1: CUPS Configuration Management Plan
  • +
  • CUPS-IDD-1.1: CUPS System Interface Design Description
  • +
  • CUPS-IPP-1.1: CUPS Implementation of IPP
  • +
  • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
  • +
  • CUPS-SDD-1.1: CUPS Software Design Description
  • +
  • CUPS-SPM-1.1.x: CUPS Software Programming Manual
  • +
  • CUPS-SSR-1.1: CUPS Software Security Report
  • +
  • CUPS-STP-1.1: CUPS Software Test Plan
  • +
  • CUPS-SUM-1.1.x: CUPS Software Users Manual
  • +
  • CUPS-SVD-1.1: CUPS Software Version Description

2.2 Other Documents

-

The following non-CUPS documents are referenced by this document:

+

The following non-CUPS documents are referenced by this document:

3 Internal Interfaces

3.1 Character Set Files

-

The character set files define a mapping between 8-bit characters -and the Unicode character set, or between Unicode and printer fonts. -They are named using the IETF charset names defined in RFCnnnn. These -files are ASCII text, the content of which is described below. Comments -can be included by using the # character in the first column -of a line.

+

The character set files define a mapping between 8-bit characters and + the Unicode character set, or between Unicode and printer fonts. They + are named using the IETF charset names defined in RFCnnnn. These files + are ASCII text, the content of which is described below. Comments can + be included by using the # character in the first column of a + line.

3.1.1 8-Bit Character Set Files

-

8-bit character set files start with a line reading:

+

8-bit character set files start with a line reading:

     charset 8bit
     
-

Following this are lines that define the font information:

+

Following this are lines that define the font information:

     first last direction width normal bold italic bold-italic
     
-

First and last are the first and last glyphs -in the font mapping that correspond to that font; a maximum of 256 -characters can be mapped within each group, with a maximum of 256 -mappings (this is a PostScript limitation.) The glyph values are -hexadecimal.

-

Direction is the string "ltor", "rtol", or "rtola" -indicating left-to-right, right-to-left, or right-to-left Arabic text.

-

Width is the string "single" or "double"; double means -that the glyphs are twice as wide as ASCII characters in the Courier -typeface.

-

Normal, bold, italic, and bold-italic are the -typefaces to use for each presentation. If characters are only -available in a single style then only one typeface should be listed -(e.g. "Symbol".) Each font that is listed will be used (and downloaded -if needed) when printing.

-

The remaining lines define a character to Unicode glyph mapping for -the character set. The character and glyph values are hexadecimal:

+

First and last are the first and last glyphs in + the font mapping that correspond to that font; a maximum of 256 + characters can be mapped within each group, with a maximum of 256 + mappings (this is a PostScript limitation.) The glyph values are + hexadecimal.

+

Direction is the string "ltor", "rtol", or "rtola" + indicating left-to-right, right-to-left, or right-to-left Arabic text.

+

Width is the string "single" or "double"; double means + that the glyphs are twice as wide as ASCII characters in the Courier + typeface.

+

Normal, bold, italic, and bold-italic are the + typefaces to use for each presentation. If characters are only + available in a single style then only one typeface should be listed + (e.g. "Symbol".) Each font that is listed will be used (and downloaded + if needed) when printing.

+

The remaining lines define a character to Unicode glyph mapping for + the character set. The character and glyph values are hexadecimal:

     xx yyyy
     

3.1.2 Unicode Character Set Files

-

Unicode character set files start with a line reading:

+

Unicode character set files start with a line reading:

     charset encoding
     
-

Encoding is the encoding to use for the text; currently -only the string "utf8" is supported.

-

Following this are lines defining the font information:

+

Encoding is the encoding to use for the text; currently + only the string "utf8" is supported.

+

Following this are lines defining the font information:

     first last direction width normal bold italic bold-italic
     
-

First and last are the first and last glyphs -in the font mapping that correspond to that font; a maximum of 256 -characters can be mapped within each group, with a maximum of 256 -mappings (this is a PostScript limitation.) The glyph values are -hexadecimal.

-

Direction is the string "ltor", "rtol", or "rtola" -indicating left-to-right, right-to-left, or right-to-left Arabic text.

-

Width is the string "single" or "double"; double means -that the glyphs are twice as wide as ASCII characters in the Courier -typeface.

-

Normal, bold, italic, and bold-italic are the -typefaces to use for each presentation. If characters are only -available in a single style then only one typeface should be listed -(e.g. "Symbol".) Each font that is listed will be used (and downloaded -if needed) when printing.

+

First and last are the first and last glyphs in + the font mapping that correspond to that font; a maximum of 256 + characters can be mapped within each group, with a maximum of 256 + mappings (this is a PostScript limitation.) The glyph values are + hexadecimal.

+

Direction is the string "ltor", "rtol", or "rtola" + indicating left-to-right, right-to-left, or right-to-left Arabic text.

+

Width is the string "single" or "double"; double means + that the glyphs are twice as wide as ASCII characters in the Courier + typeface.

+

Normal, bold, italic, and bold-italic are the + typefaces to use for each presentation. If characters are only + available in a single style then only one typeface should be listed + (e.g. "Symbol".) Each font that is listed will be used (and downloaded + if needed) when printing.

3.2 Language Files

-

The language files define the default character set and a collection -of text messages in that language. They are named by prefixing the -string "cups_" to the front of the language specifier (e.g. "cups_en", -"cups_fr", etc.) Each file consists of two or more lines of ASCII text.

-

The first line identifies the character set to be used for the -messages. The currently recognized values are:

+

The language files define the default character set and a collection + of text messages in that language. They are named by prefixing the + string "cups_" to the front of the language specifier (e.g. "cups_en", + "cups_fr", etc.) Each file consists of two or more lines of ASCII text.

+

The first line identifies the character set to be used for the + messages. The currently recognized values are:

    -
  • iso-8859-1
  • -
  • iso-8859-2
  • -
  • iso-8859-3
  • -
  • iso-8859-4
  • -
  • iso-8859-5
  • -
  • iso-8859-6
  • -
  • iso-8859-7
  • -
  • iso-8859-8
  • -
  • iso-8859-9
  • -
  • iso-8859-10
  • -
  • iso-8859-13
  • -
  • iso-8859-14
  • -
  • iso-8859-15
  • -
  • us-ascii
  • -
  • utf-8
  • -
  • windows-874
  • -
  • windows-1250
  • -
  • windows-1251
  • -
  • windows-1252
  • -
  • windows-1253
  • -
  • windows-1254
  • -
  • windows-1255
  • -
  • windows-1256
  • -
  • windows-1257
  • -
  • windows-1258
  • +
  • iso-8859-1
  • +
  • iso-8859-2
  • +
  • iso-8859-3
  • +
  • iso-8859-4
  • +
  • iso-8859-5
  • +
  • iso-8859-6
  • +
  • iso-8859-7
  • +
  • iso-8859-8
  • +
  • iso-8859-9
  • +
  • iso-8859-10
  • +
  • iso-8859-13
  • +
  • iso-8859-14
  • +
  • iso-8859-15
  • +
  • us-ascii
  • +
  • utf-8
  • +
  • windows-874
  • +
  • windows-1250
  • +
  • windows-1251
  • +
  • windows-1252
  • +
  • windows-1253
  • +
  • windows-1254
  • +
  • windows-1255
  • +
  • windows-1256
  • +
  • windows-1257
  • +
  • windows-1258
-

The second and succeeding lines define text messages. If the message -text is preceded by a number, then the current message number is -updated and the text after the number is used.

+

The second and succeeding lines define text messages. If the message + text is preceded by a number, then the current message number is + updated and the text after the number is used.

3.3 MIME Files

-

CUPS uses two MIME files in its standard configuration.

+

CUPS uses two MIME files in its standard configuration.

3.3.1 mime.types

-

The mime.types file defines the recognized file types and consists -of 1 or more lines of ASCII text. Comment lines start with the pound -("#") character. The backslash ("\") character can be used at the end -of a line to continue that line to the next.

-

Each non-blank line starts with a MIME type identifier -("super/type") as registered with the IANA. All text following the MIME -type is treated as a series of type recognition rules:

+

The mime.types file defines the recognized file types and consists of + 1 or more lines of ASCII text. Comment lines start with the pound ("#") + character. The backslash ("\") character can be used at the end of a + line to continue that line to the next.

+

Each non-blank line starts with a MIME type identifier ("super/type") + as registered with the IANA. All text following the MIME type is + treated as a series of type recognition rules:

     mime-type := super "/" type { SP rule }*
    @@ -303,31 +303,31 @@ operator := "+" |	[ logical AND ]
     	    "!"         [ unary NOT ]
     
-

The int and short rules match look for -integers in network byte order (a.k.a. big-endian) with the -most-significant byte first.

+

The int and short rules match look for + integers in network byte order (a.k.a. big-endian) with the + most-significant byte first.

3.3.2 mime.convs

-

The mime.types file defines the recognized file filters and consists -of 1 or more lines of ASCII text. Comment lines start with the pound -("#") character.

-

Each non-blank line starts with two MIME type identifiers -("super/type") representing the source and destination types. Following -the MIME types are a cost value (0 to 100) and the filter program to -use. If the filter program is not specified using the full path then it -must reside in the CUPS filter directory:

+

The mime.types file defines the recognized file filters and consists + of 1 or more lines of ASCII text. Comment lines start with the pound + ("#") character.

+

Each non-blank line starts with two MIME type identifiers + ("super/type") representing the source and destination types. Following + the MIME types are a cost value (0 to 100) and the filter program to + use. If the filter program is not specified using the full path then it + must reside in the CUPS filter directory:

     super/type SP super/type2 SP cost SP program
     

3.4 Option Files

-

CUPS maintains user-defined printer and option files for each -printer and user on the system. The printers and options defined in the -system option file (/etc/cups/lpoptions) are loaded first, -followed by the user option file ($HOME/.lpoptions). -Options in the user file replace those defined in the system file for -the same destination. Each line in the files can be one of the -following:

+

CUPS maintains user-defined printer and option files for each printer + and user on the system. The printers and options defined in the system + option file (/etc/cups/lpoptions) are loaded first, + followed by the user option file ($HOME/.lpoptions). + Options in the user file replace those defined in the system file for + the same destination. Each line in the files can be one of the + following:

     Dest name option=value option=value ... option=value
    @@ -336,300 +336,295 @@ Default name option=value option=value ... option=value
     Default name/instance option=value option=value ... option=value
     
-

The line beginning with "Default" indicates the default destination -for print jobs; a default line in the user option file overrides the -default defined in the system option file.

-

Name is the name of a printer known to the local server.

-

Instance can be any string of letters, numbers, and the -underscore up to 127 characters in length.

-

The remainder of the line contains a list of space-separated options -and their values.

+

The line beginning with "Default" indicates the default destination + for print jobs; a default line in the user option file overrides the + default defined in the system option file.

+

Name is the name of a printer known to the local server.

+

Instance can be any string of letters, numbers, and the + underscore up to 127 characters in length.

+

The remainder of the line contains a list of space-separated options + and their values.

3.5 PostScript Printer Description Files

-

PostScript Printer Description ("PPD") files describe the -capabilities of each printer and are used by CUPS to support -printer-specific features and intelligent filtering.

+

PostScript Printer Description ("PPD") files describe the + capabilities of each printer and are used by CUPS to support + printer-specific features and intelligent filtering.

3.5.1 PPD Specification

-

The PPD file format is described in - Adobe TechNote #5003: PostScript Printer Description File Format -Specification Version 4.3.

+

The PPD file format is described in + Adobe TechNote #5003: PostScript Printer Description File Format + Specification Version 4.3.

3.5.2 CUPS Extensions to PPD Files

-

CUPS adds several new attributes that are described below.

+

CUPS adds several new attributes that are described below.

3.5.2.1 cupsFilter

-

This string attribute provides a conversion rule of the form:

+

This string attribute provides a conversion rule of the form:

     source/type cost program
     
-

The destination type is assumed to the printer's type. If a printer -supports the source type directly the special filter program "-" may be -specified.

+

The destination type is assumed to the printer's type. If a printer + supports the source type directly the special filter program "-" may be + specified.

3.5.2.2 cupsManualCopies

-

This boolean attribute notifies the RIP filters that the destination -printer does not support copy generation in hardware. The default value -is false.

+

This boolean attribute notifies the RIP filters that the destination + printer does not support copy generation in hardware. The default value + is false.

3.5.2.3 cupsModelNumber

-

This integer attribute specifies a printer-specific model number. -This number can be used by a filter program to adjust the output for a -specific model of printer.

+

This integer attribute specifies a printer-specific model number. + This number can be used by a filter program to adjust the output for a + specific model of printer.

3.5.2.4 cupsProfile

-

This string attribute specifies a color profile of the form:

+

This string attribute specifies a color profile of the form:

     resolution/type density gamma m00 m01 m02 m10 m11 m12 m20 m21 m22
     
-

The resolution and type values may be "-" to act as a -wildcard. Otherwise they must match one of the Resolution - or MediaType attributes defined in the PPD file.

-

The density and gamma values define gamma and density -adjustment function such that:

+

The resolution and type values may be "-" to act as a + wildcard. Otherwise they must match one of the Resolution + or MediaType attributes defined in the PPD file.

+

The density and gamma values define gamma and density + adjustment function such that:

     f(x) = density * xgamma
     
-

The m00 through m22 values define a 3x3 transformation -matrix for the CMY color values. The density function is applied -after the CMY transformation.

+

The m00 through m22 values define a 3x3 transformation + matrix for the CMY color values. The density function is applied + after the CMY transformation.

3.5.2.5 cupsVersion

-

This required attribute describes which version of the CUPS IDD was -used for the PPD file extensions. Currently it must be the string "1.0" -or "1.1".

+

This required attribute describes which version of the CUPS IDD was + used for the PPD file extensions. Currently it must be the string "1.0" + or "1.1".

3.6 Scheduler Configuration Files

-

The scheduler reads three configuration files that define the -available printers, classes, and services:

+

The scheduler reads three configuration files that define the + available printers, classes, and services:

-
classes.conf
-
This file defines all of the printer classes known to the system.
-
cupsd.conf
-
This file defines the files, directories, passwords, etc. used by -the scheduler.
-
printers.conf
-
This file defines all of the printers known to the system.
+
classes.conf
+
This file defines all of the printer classes known to the system.
+
cupsd.conf
+
This file defines the files, directories, passwords, etc. used by + the scheduler.
+
printers.conf
+
This file defines all of the printers known to the system.

3.6.1 classes.conf

-

The classes.conf file consists of 1 or more lines of ASCII text. - Comment lines start with the pound ("#") character.

-

Each non-blank line starts with the name of a configuration -directive followed by its value. The following directives are -understood: +

The classes.conf file consists of 1 or more lines of ASCII text. + Comment lines start with the pound ("#") character.

+

Each non-blank line starts with the name of a configuration directive + followed by its value. The following directives are understood:

- - - - - +
</Class> + + + + + - - - + + +
DirectiveDescription
<Class name>
</Class>
Surrounds a class definition.
<DefaultClass name> -
</Class>
Surrounds a class definition for the default -destination.
AcceptingSpecifies whether the class is accepting new -jobs. May be the names "Yes" or "No".
AllowUsersSpecifies a list of users that are allowed -to access the class.
BannerStartSpecifies the banner that is printed before -other files in a job.
BannerEndSpecifies the banner that is printed after -other files in a job.
DenyUsersSpecifies a list of users that are not -allowed to access the class.
Surrounds a class definition for the default + destination.
AcceptingSpecifies whether the class is accepting new + jobs. May be the names "Yes" or "No".
AllowUsersSpecifies a list of users that are allowed to + access the class.
BannerStartSpecifies the banner that is printed before + other files in a job.
BannerEndSpecifies the banner that is printed after + other files in a job.
DenyUsersSpecifies a list of users that are not allowed + to access the class.
InfoA textual description of the class.
LocationA textual location of the class.
PrinterSpecifies a printer that is a member of the -class.
StateSpecifies the initial state of the class; can be -"Idle" or "Stopped".
StateMessageSpecifies a textual message for the -current class state.
PrinterSpecifies a printer that is a member of the + class.
StateSpecifies the initial state of the class; can be + "Idle" or "Stopped".
StateMessageSpecifies a textual message for the current + class state.

3.6.2 cupsd.conf

-

The cupsd.conf file consists of 1 or more lines of ASCII text. - Comment lines start with the pound ("#") character.

-

Each non-blank line starts with the name of a configuration -directive followed by its value. The following directives are -understood: +

The cupsd.conf file consists of 1 or more lines of ASCII text. + Comment lines start with the pound ("#") character.

+

Each non-blank line starts with the name of a configuration directive + followed by its value. The following directives are understood:

- - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - +
</Location> + + + + + + + + + + + + + + + + +
DirectiveDefaultDescription
AccessLogaccess_logSpecifies the location of -the access log file. The special name "syslog" can be used to send -access log information to the system log.
Allow-Allows connections from the specified -host, network, or domain.
AuthClass-Specifies what level of -authentication is required; may be "User", "System", or "Group".
AuthTypeNoneSpecifies the type of -authentication to perform; may be "None", "Basic", or "Digest".
BrowseAddress255.255.255.255Specifies a -broadcast address to send CUPS browsing packets to.
BrowseAllow-Specifies hosts or addresses from -which browsing information should be used.
BrowseDeny-Specifies hosts or addresses from -which browsing information should not be used.
BrowseInterval30Specifies the number of -seconds between browsing updates. A browse interval of 0 seconds -disables outgoing packets.
BrowseOrderAllow,DenySpecifies the order of -BrowseAllow and BrowseDeny directive processing; can be "Deny,Allow" -to implicitly deny hosts unless they are allowed by a BrowseAllow -line, or "Allow,Deny" to implicitly allow hosts unless they are denied -by a BrowseDeny line.
BrowsePoll-Specifies a server to poll for -available printers and classes.
BrowsePort631Specifies the UDP port number to -use for browse packets.
BrowseRelay-Specifies a source and -destination address for relaying browser information from one subnet -to another.
BrowseShortNamesyesSpecifies whether or not -to provide short names (without the "@server" part) for remote -printers.
BrowseTimeout300Specifies the number of -seconds to wait until remote destinations are removed from the local -destination list.
BrowsingOnSpecifies whether or not printer -and class browsing is enabled; can be "On" or "Off".
DataDir/usr/share/cupsSpecifies the directory -where CUPS data files are stored.
DefaultCharsetiso-8859-1Specifies the default -character set.
DefaultLanguagecurrent localeSpecifies the -default language.
Deny-Refuses connections from the specified -host, network, or domain.
DocumentRoot/usr/share/doc/cupsSpecifies the -document data root directory.
ErrorLogerror_logSpecifies the error log file -location. The special name "syslog" can be used to send error log -information to the system log.
Grouproot, sys, systemSpecifies the group -name or ID that is used when running external programs.
HostNameLookupsOffSpecifies whether or not to -perform reverse IP address lookups to get the actual hostname; may be -"On" or "Off". Hostname lookups can significantly degrade the -performance of the CUPS server if one or more DNS servers is not -functioning properly.
ImplicitClassesOnSpecifies whether or not to -automatically create printer classes when more than one printer or -class of the same name is detected on the network; may be "On" or -"Off".
KeepAliveOnSpecifies whether or not to use -the HTTP Keep-Alive feature; may be "On" or "Off".
KeepAliveTimeout30Specifies the amount of -time to keep the HTTP connection alive before closing it.
AccessLogaccess_logSpecifies the location of + the access log file. The special name "syslog" can be used to send + access log information to the system log.
Allow-Allows connections from the specified + host, network, or domain.
AuthClass-Specifies what level of + authentication is required; may be "User", "System", or "Group".
AuthTypeNoneSpecifies the type of + authentication to perform; may be "None", "Basic", or "Digest".
BrowseAddress255.255.255.255Specifies a + broadcast address to send CUPS browsing packets to.
BrowseAllow-Specifies hosts or addresses from + which browsing information should be used.
BrowseDeny-Specifies hosts or addresses from + which browsing information should not be used.
BrowseInterval30Specifies the number of + seconds between browsing updates. A browse interval of 0 seconds + disables outgoing packets.
BrowseOrderAllow,DenySpecifies the order of + BrowseAllow and BrowseDeny directive processing; can be "Deny,Allow" to + implicitly deny hosts unless they are allowed by a BrowseAllow line, or + "Allow,Deny" to implicitly allow hosts unless they are denied by a + BrowseDeny line.
BrowsePoll-Specifies a server to poll for + available printers and classes.
BrowsePort631Specifies the UDP port number to + use for browse packets.
BrowseRelay-Specifies a source and destination + address for relaying browser information from one subnet to another.
BrowseShortNamesyesSpecifies whether or not to + provide short names (without the "@server" part) for remote printers.
BrowseTimeout300Specifies the number of + seconds to wait until remote destinations are removed from the local + destination list.
BrowsingOnSpecifies whether or not printer and + class browsing is enabled; can be "On" or "Off".
DataDir/usr/share/cupsSpecifies the directory + where CUPS data files are stored.
DefaultCharsetiso-8859-1Specifies the default + character set.
DefaultLanguagecurrent localeSpecifies the + default language.
Deny-Refuses connections from the specified + host, network, or domain.
DocumentRoot/usr/share/doc/cupsSpecifies the + document data root directory.
ErrorLogerror_logSpecifies the error log file + location. The special name "syslog" can be used to send error log + information to the system log.
Grouproot, sys, systemSpecifies the group name + or ID that is used when running external programs.
HostNameLookupsOffSpecifies whether or not to + perform reverse IP address lookups to get the actual hostname; may be + "On" or "Off". Hostname lookups can significantly degrade the + performance of the CUPS server if one or more DNS servers is not + functioning properly.
ImplicitClassesOnSpecifies whether or not to + automatically create printer classes when more than one printer or + class of the same name is detected on the network; may be "On" or + "Off".
KeepAliveOnSpecifies whether or not to use the + HTTP Keep-Alive feature; may be "On" or "Off".
KeepAliveTimeout30Specifies the amount of time + to keep the HTTP connection alive before closing it.
<Location path> -
</Location>
-Specifies a location to restrict -access to.
LogLevelinfoControls the amount of -information that is logged in the error log file. Can be one of -"debug", "info", "warn", "error", or "none", in decreasing order or -verbosity.
MaxClients100Specifies the maximum number of -simultaneous active clients. This value is internally limited to 1/3 -of the total number of available file descriptors.
MaxLogSize0Specifies the maximum size of the -access, error, and page log files in bytes. If set to 0 then no -maximum size is set. Log files are rotated automatically when this -size is exceeded.
MaxRequestSize0Specifies the maximum size of -HTTP requests in bytes. If set to 0 then there is no maximum.
OrderAllow,DenySpecifies the order of Allow -and Deny directive processing; can be "Deny,Allow" to implicitly deny -hosts unless they are allowed by an Allow line, or "Allow,Deny" to -implicitly allow hosts unless they are denied by a Deny line.
PageLogpage_logSpecifies the location of the -page log file. The special name "syslog" can be used to send page log -information to the system log.
Port631Specifies a port number to listen to -for HTTP connections.
Printcap/etc/printcapSpecifies the location -of a Berkeley printcap file to update with a list of current printers -and classes. If no filename is supplied then this automatic generation -is disabled.
RequestRoot/var/spool/cupsSpecifies the -location of request files.
RIPCache8mSpecifies the size of the memory -cache in bytes that is used by RIP filters.
ServerAdminroot@ServerNameSpecifies the -person to contact with problems.
ServerNamehostnameSpecifies the hostname that -is supplied to HTTP clients. This is also used to determine the -default CUPS server for the CUPS IPP client applications.
ServerRoot/etc/cupsSpecifies the root -directory for server configuration files.
SystemGrouproot, sys, systemSpecifies the -group name used for System class authentication.
TempDir/var/tmpSpecifies the temporary -directory to use.
Timeout300The timeout in seconds before -client connections are closed in the middle of a request.
UserlpSpecifies the user that is used when -running external programs.
-Specifies a location to restrict + access to.
LogLevelinfoControls the amount of information + that is logged in the error log file. Can be one of "debug", "info", + "warn", "error", or "none", in decreasing order or verbosity.
MaxClients100Specifies the maximum number of + simultaneous active clients. This value is internally limited to 1/3 of + the total number of available file descriptors.
MaxLogSize0Specifies the maximum size of the + access, error, and page log files in bytes. If set to 0 then no maximum + size is set. Log files are rotated automatically when this size is + exceeded.
MaxRequestSize0Specifies the maximum size of + HTTP requests in bytes. If set to 0 then there is no maximum.
OrderAllow,DenySpecifies the order of Allow + and Deny directive processing; can be "Deny,Allow" to implicitly deny + hosts unless they are allowed by an Allow line, or "Allow,Deny" to + implicitly allow hosts unless they are denied by a Deny line.
PageLogpage_logSpecifies the location of the + page log file. The special name "syslog" can be used to send page log + information to the system log.
Port631Specifies a port number to listen to + for HTTP connections.
Printcap/etc/printcapSpecifies the location of + a Berkeley printcap file to update with a list of current printers and + classes. If no filename is supplied then this automatic generation is + disabled.
RequestRoot/var/spool/cupsSpecifies the + location of request files.
RIPCache8mSpecifies the size of the memory + cache in bytes that is used by RIP filters.
ServerAdminroot@ServerNameSpecifies the person + to contact with problems.
ServerNamehostnameSpecifies the hostname that + is supplied to HTTP clients. This is also used to determine the default + CUPS server for the CUPS IPP client applications.
ServerRoot/etc/cupsSpecifies the root + directory for server configuration files.
SystemGrouproot, sys, systemSpecifies the + group name used for System class authentication.
TempDir/var/tmpSpecifies the temporary + directory to use.
Timeout300The timeout in seconds before client + connections are closed in the middle of a request.
UserlpSpecifies the user that is used when + running external programs.

3.6.3 printers.conf

-

The printers.conf file consists of 1 or more lines of ASCII text. - Comment lines start with the pound ("#") character.

-

Each non-blank line starts with the name of a configuration -directive followed by its value. The following directives are -understood: +

The printers.conf file consists of 1 or more lines of ASCII text. + Comment lines start with the pound ("#") character.

+

Each non-blank line starts with the name of a configuration directive + followed by its value. The following directives are understood:

- + - - - - - +
</Printer> + + + + + - - + +
DirectiveDescription
AcceptingSpecifies whether the printer is accepting -new jobs. May be the names "Yes" or "No".
AcceptingSpecifies whether the printer is accepting new + jobs. May be the names "Yes" or "No".
<DefaultPrinter name> -
</Printer>
Surrounds the printer definition for a default -destination.
AllowUsersSpecifies a list of users that are allowed -to access the printer.
BannerStartSpecifies the banner that is printed before -other files in a job.
BannerEndSpecifies the banner that is printed after -other files in a job.
DenyUsersSpecifies a list of users that are not -allowed to access the printer.
DeviceURISpecifies the device-uri attribute for the -printer.
Surrounds the printer definition for a default + destination.
AllowUsersSpecifies a list of users that are allowed to + access the printer.
BannerStartSpecifies the banner that is printed before + other files in a job.
BannerEndSpecifies the banner that is printed after + other files in a job.
DenyUsersSpecifies a list of users that are not allowed + to access the printer.
DeviceURISpecifies the device-uri attribute for the + printer.
InfoA textual description of the printer.
LocationA textual location of the printer.
<Printer name>
</Printer>
Surrounds the printer definition.
StateSpecifies the initial state of the printer; can -be "Idle" or "Stopped".
StateMessageSpecifies a textual message for the -current printer state.
StateSpecifies the initial state of the printer; can be + "Idle" or "Stopped".
StateMessageSpecifies a textual message for the current + printer state.

4 External Interfaces

4.1 AppSocket Protocol

-

The AppSocket protocol is an 8-bit clean TCP/IP socket connection. -The default IP service port is 9100. The URI method name is "socket".

-

The AppSocket protocol is used by the Hewlett Packard JetDirect -network interfaces and print servers, as well as many other vendors' -products. See the CUPS Software Administrators Manual for a list of -supported products.

+

The AppSocket protocol is an 8-bit clean TCP/IP socket connection. + The default IP service port is 9100. The URI method name is "socket".

+

The AppSocket protocol is used by the Hewlett Packard JetDirect + network interfaces and print servers, as well as many other vendors' + products. See the CUPS Software Administrators Manual for a list of + supported products.

4.2 CUPS Browsing Protocol

-

The CUPS Browsing Protocol is a UDP/IP-based broadcast service. By -default this service operates on IP service port 631.

-

Each broadcast packet describes the state of a single printer or -class and is an ASCII text string of up to 1450 bytes ending with a -newline (0x0a). The string is formatted as follows:

+

The CUPS Browsing Protocol is a UDP/IP-based broadcast service. By + default this service operates on IP service port 631.

+

Each broadcast packet describes the state of a single printer or + class and is an ASCII text string of up to 1450 bytes ending with a + newline (0x0a). The string is formatted as follows:

     type SP state SP uri SP "location" SP "info" SP "make-and-model" NL
     
-

State, uri, location, info, and make-and-model -, correspond to the IPP printer-state, +

State, uri, location, info, and make-and-model, + correspond to the IPP printer-state, printer-uri-supported, printer-location, -printer-info, and printer-make-and-model - attributes.

-

Type is a hexadecimal number string representing -capability/type bits: +printer-info, and printer-make-and-model attributes.

+

Type is a hexadecimal number string representing + capability/type bits:

@@ -657,12 +652,12 @@ capability/type bits:

4.3 CUPS Form File

CUPS Form files are XML files used by the CUPS formtops - filter to produce dynamic banner pages and support preprinted forms.

+ filter to produce dynamic banner pages and support preprinted forms.

The MIME type for CUPS Form files is application/vnd.cups-form -.

+.

4.3.1 CUPS Form DTD

-

The following DTD describes the available elements and attributes in -a CUPS Form file: +

The following DTD describes the available elements and attributes in + a CUPS Form file:

BitDescription
@@ -840,27 +835,27 @@ a CUPS Form file:

4.4 CUPS PostScript File

-

CUPS PostScript files are device-dependent Adobe PostScript program -files. The PostScript language is described in the - Adobe PostScript Language Reference Manual, Third Edition.

+

CUPS PostScript files are device-dependent Adobe PostScript program + files. The PostScript language is described in the + Adobe PostScript Language Reference Manual, Third Edition.

The MIME type for CUPS PostScript files is -application/vnd.cups-postscript.

+application/vnd.cups-postscript.

4.5 CUPS Raster File

-

CUPS raster files are device-dependent raster image files that -contain a PostScript page device dictionary and device-dependent raster -imagery for each page in the document. These files are used to transfer -raster data from the PostScript and image file RIPs to device-dependent -filters that convert the raster data to a printable format.

-

A raster file begins with a four byte synchronization word: -0x52615374 ("RaSt") for big-endian architectures and 0x74536152 -("tSaR") for little-endian architectures. The writer of the raster -file will use the native word order, and the reader is responsible for -detecting a reversed word order file and swapping bytes as needed. The -CUPS Image Library raster functions perform this function -automatically.

-

Following the synchronization word are a series of raster pages. - Each page starts with a page device dictionary header and is followed -immediately by the raster data for that page. +

CUPS raster files are device-dependent raster image files that + contain a PostScript page device dictionary and device-dependent raster + imagery for each page in the document. These files are used to transfer + raster data from the PostScript and image file RIPs to device-dependent + filters that convert the raster data to a printable format.

+

A raster file begins with a four byte synchronization word: + 0x52615374 ("RaSt") for big-endian architectures and 0x74536152 + ("tSaR") for little-endian architectures. The writer of the raster file + will use the native word order, and the reader is responsible for + detecting a reversed word order file and swapping bytes as needed. The + CUPS Image Library raster functions perform this function + automatically.

+

Following the synchronization word are a series of raster pages. Each + page starts with a page device dictionary header and is followed + immediately by the raster data for that page.

@@ -872,8 +867,8 @@ immediately by the raster data for that page. - +
4 = Cut roll after page - - - + + - - + - - + + - - - + - - +
BytesDescriptionValues
192-255OutputTypeNul-terminated ASCII string
256-259AdvanceDistance0 to 232 - 1 -points
256-259AdvanceDistance0 to 232 - 1 + points
260-263AdvanceMedia0 = Never advance roll
1 = Advance roll after file
2 = Advance roll after job @@ -888,13 +883,13 @@ points
272-275Duplex0 = Print single-sided
1 = Print double-sided
276-283HWResolutionHorizontal and vertical -resolution in dots-per-inch.
284-299ImagingBoundingBoxFour integers giving -the left, bottom, right, and top positions of the page bounding box in -points
300-303InsertSheet0 = Do not insert separator -sheets +
276-283HWResolutionHorizontal and vertical + resolution in dots-per-inch.
284-299ImagingBoundingBoxFour integers giving + the left, bottom, right, and top positions of the page bounding box in + points
300-303InsertSheet0 = Do not insert separator + sheets
1 = Insert separator sheets
304-307Jog0 = Do no jog pages
1 = Jog pages after file @@ -904,15 +899,15 @@ sheets
1 = Right edge is first
2 = Bottom edge is first
3 = Left edge is first
312-319MarginsLeft and bottom origin of image -in points
320-323ManualFeed0 = Do not manually feed -media +
312-319MarginsLeft and bottom origin of image + in points
320-323ManualFeed0 = Do not manually feed + media
1 = Manually feed media
324-327MediaPositionInput slot position from -0 to N
328-331MediaWeightMedia weight in grams per -meter squared
324-327MediaPositionInput slot position from 0 + to N
328-331MediaWeightMedia weight in grams per + meter squared
332-335MirrorPrint0 = Do not mirror prints
1 = Mirror prints
336-339NegativePrint0 = Do not invert prints @@ -927,24 +922,24 @@ meter squared
352-359PageSizeWidth and length in points
360-363Separations0 = Print composite image
1 = Print color separations
364-367TraySwitch0 = Do not change trays if -selected tray is empty +
364-367TraySwitch0 = Do not change trays if + selected tray is empty
1 = Change trays if selected tray is empty
368-371Tumble0 = Do not rotate even pages -when duplexing +
368-371Tumble0 = Do not rotate even pages when + duplexing
1 = Rotate even pages when duplexing
372-375cupsWidthWidth of page image in pixels
376-379cupsHeightHeight of page image in -pixels
376-379cupsHeightHeight of page image in + pixels
380-383cupsMediaTypeDriver-specific 0 to 2 32 - 1
384-387cupsBitsPerColor1, 2, 4, 8 bits
388-391cupsBitsPerPixel1 to 32 bits
392-395cupsBytesPerLine1 to 232 - -1 bytes
396-399cupsColorOrder0 = chunky pixels (CMYK -CMYK CMYK) +
392-395cupsBytesPerLine1 to 232 - 1 + bytes
396-399cupsColorOrder0 = chunky pixels (CMYK + CMYK CMYK)
1 = banded pixels (CCC MMM YYY KKK)
2 = planar pixels (CCC... MMM... YYY... KKK...)
400-403cupsColorSpace0 = white @@ -969,118 +964,118 @@ CMYK CMYK)

The MIME type for CUPS Raster files is -application/vnd.cups-raster.

+application/vnd.cups-raster.

4.6 CUPS Raw Files

-

Raw files are printer-dependent print files that are in a format -suitable to the destination printer (e.g. HP-PCL, HP-RTL, etc.) The -MIME type for CUPS Raw files is application/vnd.cups-raw.

+

Raw files are printer-dependent print files that are in a format + suitable to the destination printer (e.g. HP-PCL, HP-RTL, etc.) The + MIME type for CUPS Raw files is application/vnd.cups-raw.

4.7 Internet Printing Protocol

-

The Internet Printing Protocol and the CUPS extensions to it are -described in the CUPS Implementation of IPP document.

+

The Internet Printing Protocol and the CUPS extensions to it are + described in the CUPS Implementation of IPP document.

4.8 Line Printer Daemon Protocol

-

The Line Printer Daemon (LPD) protocol is described by -RFC 1179: Line Printer Daemon Protocol.

-

The URI method name for LPD is "lpd".

+

The Line Printer Daemon (LPD) protocol is described by + RFC 1179: Line Printer Daemon Protocol.

+

The URI method name for LPD is "lpd".

4.9 Server Message Block Protocol

-

The Server Message Block (SMB) and related Common Internet File -System (CIFS) protocols are described at -http://anu.samba.org/cifs.

-

The URI method name for SMB is "smb". Support for this protocol is -provided via the SAMBA smbspool(1) program provided with -SAMBA 2.0.6 and higher.

+

The Server Message Block (SMB) and related Common Internet File + System (CIFS) protocols are described at + http://anu.samba.org/cifs.

+

The URI method name for SMB is "smb". Support for this protocol is + provided via the SAMBA smbspool(1) program provided with + SAMBA 2.0.6 and higher.

5 Directories

-
/etc/cups
-
The scheduler configuration and MIME files reside here.
-
/etc/cups/certs
-
The authentication certificates reside here.
-
/etc/cups/interfaces
-
System V interface scripts reside here.
-
/etc/cups/ppd
-
This directory contains PPD files for each printer.
-
/usr/bin
+
/etc/cups
+
The scheduler configuration and MIME files reside here.
+
/etc/cups/certs
+
The authentication certificates reside here.
+
/etc/cups/interfaces
+
System V interface scripts reside here.
+
/etc/cups/ppd
+
This directory contains PPD files for each printer.
+
/usr/bin
The cancel, lp, lpq, - lpr, lprm, and lpstat commands - reside here.
-
/usr/lib, /usr/lib32
-
The shared libraries (DSOs) reside here.
-
/usr/lib/cups/backend
-
The backend filters reside here.
-
/usr/lib/cups/cgi-bin
-
The CGI programs reside here.
-
/usr/lib/cups/daemon
-
The polling and LPD daemons reside here.
-
/usr/lib/cups/filter
-
The file filters reside here.
-
/usr/sbin
-
The accept, cupsd, lpadmin, -lpc, and reject commands reside here.
-
/usr/share/cups
-
This is the root directory of the CUPS static data.
-
/usr/share/cups/charsets
-
The character set files reside here.
-
/usr/share/cups/data
-
The filter data files reside here.
-
/usr/share/cups/fonts
-
The pstoraster font files reside here.
-
/usr/share/cups/model
-
The sample PPD files reside here.
-
/usr/share/cups/pstoraster
-
The pstoraster data files reside here.
-
/usr/share/doc/cups
-
The scheduler documentation files reside here.
-
/var/log/cups
+lpr, lprm, and lpstat commands reside + here. +
/usr/lib, /usr/lib32
+
The shared libraries (DSOs) reside here.
+
/usr/lib/cups/backend
+
The backend filters reside here.
+
/usr/lib/cups/cgi-bin
+
The CGI programs reside here.
+
/usr/lib/cups/daemon
+
The polling and LPD daemons reside here.
+
/usr/lib/cups/filter
+
The file filters reside here.
+
/usr/sbin
+
The accept, cupsd, lpadmin, +lpc, and reject commands reside here.
+
/usr/share/cups
+
This is the root directory of the CUPS static data.
+
/usr/share/cups/charsets
+
The character set files reside here.
+
/usr/share/cups/data
+
The filter data files reside here.
+
/usr/share/cups/fonts
+
The pstoraster font files reside here.
+
/usr/share/cups/model
+
The sample PPD files reside here.
+
/usr/share/cups/pstoraster
+
The pstoraster data files reside here.
+
/usr/share/doc/cups
+
The scheduler documentation files reside here.
+
/var/log/cups
The access_log, error_log, and - page_log files reside here.
-
/var/spool/cups
-
This directory contains print job files.
+page_log files reside here. +
/var/spool/cups
+
This directory contains print job files.

A Glossary

A.1 Terms

-
C
-
A computer language.
-
parallel
-
Sending or receiving data more than 1 bit at a time.
-
pipe
-
A one-way communications channel between two programs.
-
serial
-
Sending or receiving data 1 bit at a time.
-
socket
-
A two-way network communications channel.
+
C
+
A computer language.
+
parallel
+
Sending or receiving data more than 1 bit at a time.
+
pipe
+
A one-way communications channel between two programs.
+
serial
+
Sending or receiving data 1 bit at a time.
+
socket
+
A two-way network communications channel.

A.2 Acronyms

-
ASCII
-
American Standard Code for Information Interchange
-
CUPS
-
Common UNIX Printing System
-
ESC/P
-
EPSON Standard Code for Printers
-
FTP
-
File Transfer Protocol
-
HP-GL
-
Hewlett-Packard Graphics Language
-
HP-PCL
-
Hewlett-Packard Page Control Language
-
HP-PJL
-
Hewlett-Packard Printer Job Language
-
IETF
-
Internet Engineering Task Force
-
IPP
-
Internet Printing Protocol
-
ISO
-
International Standards Organization
-
LPD
-
Line Printer Daemon
-
MIME
-
Multimedia Internet Mail Exchange
-
PPD
-
PostScript Printer Description
-
SMB
-
Server Message Block
-
TFTP
-
Trivial File Transfer Protocol
+
ASCII
+
American Standard Code for Information Interchange
+
CUPS
+
Common UNIX Printing System
+
ESC/P
+
EPSON Standard Code for Printers
+
FTP
+
File Transfer Protocol
+
HP-GL
+
Hewlett-Packard Graphics Language
+
HP-PCL
+
Hewlett-Packard Page Control Language
+
HP-PJL
+
Hewlett-Packard Printer Job Language
+
IETF
+
Internet Engineering Task Force
+
IPP
+
Internet Printing Protocol
+
ISO
+
International Standards Organization
+
LPD
+
Line Printer Daemon
+
MIME
+
Multimedia Internet Mail Exchange
+
PPD
+
PostScript Printer Description
+
SMB
+
Server Message Block
+
TFTP
+
Trivial File Transfer Protocol
diff --git a/doc/idd.pdf b/doc/idd.pdf index 8857c0288f..6b174d49a8 100644 Binary files a/doc/idd.pdf and b/doc/idd.pdf differ diff --git a/doc/ipp.html b/doc/ipp.html index 6a468e4f9b..c27b5fb438 100644 --- a/doc/ipp.html +++ b/doc/ipp.html @@ -1,27 +1,27 @@ - CUPS Implementation of IPP +CUPS Implementation of IPP -

-

CUPS Implementation of IPP


+

+

CUPS Implementation of IPP


CUPS-IPP-1.1
Easy Software Products
Copyright 1997-2001 All Rights Reserved
@@ -148,23 +148,24 @@ Copyright 1997-2001 All Rights Reserved
  • 5.2.7 hue (integer(-180:180))
  • 5.2.8 job-billing (text(MAX))
  • 5.2.9 job-hold-until (keyword | name(MAX))
  • -
  • 5.2.10 job-sheets (1setof type3 keyword | -name(MAX))
  • +
  • 5.2.10 job-sheets (1setof type3 keyword | + name(MAX))
  • 5.2.11 job-originating-host-name (name(MAX))
  • 5.2.12 lpi (type2 enum)
  • -
  • 5.2.13 page-bottom (integer(0:MAX))
  • -
  • 5.2.14 page-label (text(MAX))
  • -
  • 5.2.15 page-left (integer(0:MAX))
  • -
  • 5.2.16 page-right (integer(0:MAX))
  • -
  • 5.2.17 page-set (type2 keyword)
  • -
  • 5.2.18 page-top (integer(0:MAX))
  • -
  • 5.2.19 penwidth (integer(0:MAX))
  • -
  • 5.2.20 position (type2 keyword)
  • -
  • 5.2.21 ppi (integer(1:MAX))
  • -
  • 5.2.22 prettyprint (boolean)
  • -
  • 5.2.23 saturation (integer(0:200))
  • -
  • 5.2.24 scaling (integer(1:1000))
  • -
  • 5.2.25 wrap (boolean)
  • +
  • 5.2.13 natural-scaling (integer(1:1000))
  • +
  • 5.2.14 page-bottom (integer(0:MAX))
  • +
  • 5.2.15 page-label (text(MAX))
  • +
  • 5.2.16 page-left (integer(0:MAX))
  • +
  • 5.2.17 page-right (integer(0:MAX))
  • +
  • 5.2.18 page-set (type2 keyword)
  • +
  • 5.2.19 page-top (integer(0:MAX))
  • +
  • 5.2.20 penwidth (integer(0:MAX))
  • +
  • 5.2.21 position (type2 keyword)
  • +
  • 5.2.22 ppi (integer(1:MAX))
  • +
  • 5.2.23 prettyprint (boolean)
  • +
  • 5.2.24 saturation (integer(0:200))
  • +
  • 5.2.25 scaling (integer(1:1000))
  • +
  • 5.2.26 wrap (boolean)
  • 5.3 PPD Attributes
  • 5.5 Printer Class Attributes
    • @@ -201,27 +202,27 @@ name(127))

      1 Scope

      1.1 Identification

      -

      This document provides an overview of the Internet Printing Protocol -("IPP") version 1.1 as implemented in the Common UNIX Printing System -("CUPS") version 1.1.

      +

      This document provides an overview of the Internet Printing Protocol + ("IPP") version 1.1 as implemented in the Common UNIX Printing System + ("CUPS") version 1.1.

      1.2 System Overview

      -

      CUPS provides a portable printing layer for UNIX®-based operating -systems. It has been developed by Easy -Software Products to promote a standard printing solution for all -UNIX vendors and users. CUPS provides the System V and Berkeley -command-line interfaces.

      -

      CUPS uses the Internet Printing Protocol ("IPP") as the basis for -managing print jobs and queues. The Line Printer Daemon ("LPD") Server -Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are -also supported with reduced functionality. CUPS adds network printer -browsing and PostScript Printer Description ("PPD") based printing -options to support real-world printing under UNIX.

      -

      CUPS also includes a customized version of GNU Ghostscript -(currently based off GNU Ghostscript 5.50) and an image file RIP that -are used to support non-PostScript printers. Sample drivers for HP and -EPSON printers are included that use these filters.

      +

      CUPS provides a portable printing layer for UNIX®-based operating + systems. It has been developed by Easy + Software Products to promote a standard printing solution for all + UNIX vendors and users. CUPS provides the System V and Berkeley + command-line interfaces.

      +

      CUPS uses the Internet Printing Protocol ("IPP") as the basis for + managing print jobs and queues. The Line Printer Daemon ("LPD") Server + Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are + also supported with reduced functionality. CUPS adds network printer + browsing and PostScript Printer Description ("PPD") based printing + options to support real-world printing under UNIX.

      +

      CUPS also includes a customized version of GNU Ghostscript (currently + based off GNU Ghostscript 5.50) and an image file RIP that are used to + support non-PostScript printers. Sample drivers for HP and EPSON + printers are included that use these filters.

      1.3 Document Overview

      -

      This document is organized into the following sections:

      +

      This document is organized into the following sections:

      2 References

      2.1 CUPS Documentation

      -

      The following CUPS documentation is referenced by this document:

      -
        -
      • CUPS-CMP-1.1: CUPS Configuration Management Plan
      • -
      • CUPS-IDD-1.1: CUPS System Interface Design Description
      • -
      • CUPS-IPP-1.1: CUPS Implementation of IPP
      • -
      • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
      • -
      • CUPS-SDD-1.1: CUPS Software Design Description
      • -
      • CUPS-SPM-1.1.x: CUPS Software Programming Manual
      • -
      • CUPS-SSR-1.1: CUPS Software Security Report
      • -
      • CUPS-STP-1.1: CUPS Software Test Plan
      • -
      • CUPS-SUM-1.1.x: CUPS Software Users Manual
      • -
      • CUPS-SVD-1.1: CUPS Software Version Description
      • +

        The following CUPS documentation is referenced by this document:

        +
          +
        • CUPS-CMP-1.1: CUPS Configuration Management Plan
        • +
        • CUPS-IDD-1.1: CUPS System Interface Design Description
        • +
        • CUPS-IPP-1.1: CUPS Implementation of IPP
        • +
        • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
        • +
        • CUPS-SDD-1.1: CUPS Software Design Description
        • +
        • CUPS-SPM-1.1.x: CUPS Software Programming Manual
        • +
        • CUPS-SSR-1.1: CUPS Software Security Report
        • +
        • CUPS-STP-1.1: CUPS Software Test Plan
        • +
        • CUPS-SUM-1.1.x: CUPS Software Users Manual
        • +
        • CUPS-SVD-1.1: CUPS Software Version Description

        2.2 Other Documents

        -

        The following non-CUPS documents are referenced by this document:

        +

        The following non-CUPS documents are referenced by this document:

        3 Overview

        -

        CUPS 1.1 implements IPP/1.1 and the operations and attributes -defined in the "IPP: Job and Printer Set Operations", "IPP/1.1: -Output-bin Attribute Extension", and "IPP/1.1: finishings 'fold',' -trim', and 'bale' attribute values extension" specifications.

        -

        CUPS also provides 13 new operations and many new attributes to -support multiple IPP printers and printer classes on a single host.

        +

        CUPS 1.1 implements IPP/1.1 and the operations and attributes defined + in the "IPP: Job and Printer Set Operations", "IPP/1.1: Output-bin + Attribute Extension", and "IPP/1.1: finishings 'fold',' trim', and + 'bale' attribute values extension" specifications.

        +

        CUPS also provides 13 new operations and many new attributes to + support multiple IPP printers and printer classes on a single host.

        3.1 IPP URIs

        -

        CUPS supports both the "http" and "ipp" methods. The following -resource names are used:

        +

        CUPS supports both the "http" and "ipp" methods. The following + resource names are used:

        -
        method://hostname:port/
        -
        Can be used for all "get" operations.
        -
        method://hostname:port/admin
        -
        Used for all administrative operations.
        -
        method://hostname:port/classes/name
        -
        Specifies a printer class.
        -
        method://hostname:port/jobs/id
        -
        Specifies a job.
        -
        method://hostname:port/printers/name
        -
        Specifies a printer.
        +
        method://hostname:port/
        +
        Can be used for all "get" operations.
        +
        method://hostname:port/admin
        +
        Used for all administrative operations.
        +
        method://hostname:port/classes/name
        +
        Specifies a printer class.
        +
        method://hostname:port/jobs/id
        +
        Specifies a job.
        +
        method://hostname:port/printers/name
        +
        Specifies a printer.
        -

        So a typical printer URI would be -"ipp://foo.bar.com/printers/LaserJet".

        -

        In addition, the CUPS server also supports normal browser access to -"method://hostname:port/admin/", "method://hostname:port/classes/", -"method://hostname:port/jobs/", and "method://hostname:port/printers/" -to view and manage resources on the server dynamically.

        +

        So a typical printer URI would be + "ipp://foo.bar.com/printers/LaserJet".

        +

        In addition, the CUPS server also supports normal browser access to + "method://hostname:port/admin/", "method://hostname:port/classes/", + "method://hostname:port/jobs/", and "method://hostname:port/printers/" + to view and manage resources on the server dynamically.

        3.2 CUPS IPP Operations

        -

        CUPS provides 13 extension operations in addition to most of the -standard IPP and registered extension operations: +

        CUPS provides 13 extension operations in addition to most of the + standard IPP and registered extension operations:

        4 Operations

        -

        The following sections describe the operations supported by CUPS. In -the interest of brevity, operations which use only the standard IPP -attributes are not described.

        +

        The following sections describe the operations supported by CUPS. In + the interest of brevity, operations which use only the standard IPP + attributes are not described.

        4.1 Print-Job Operation

        -

        The Print-Job operation (0x0002) prints a file.

        +

        The Print-Job operation (0x0002) prints a file.

        4.1.1 Print-Job Request

        -

        The following groups of attributes are supplied as part of the -Print-Job request:

        -

        Group 1: Operation Attributes

        +

        The following groups of attributes are supplied as part of the + Print-Job request:

        +

        Group 1: Operation Attributes

          -

          Natural Language and Character Set:

          -

          The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.1 of the IPP Model and - Semantics document.

          -

          "printer-uri" (uri):

          -

          The client MUST supply a URI for the specified printer.

          +

          Natural Language and Character Set:

          +

          The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.1 of the IPP Model and Semantics + document.

          +

          "printer-uri" (uri):

          +

          The client MUST supply a URI for the specified printer.

        -

        Group 2: Job Template Attributes

        +

        Group 2: Job Template Attributes

          -

          "job-billing" (text(MAX)):

          +

          "job-billing" (text(MAX)):

          (CUPS 1.1 and higher)

          -

          The client OPTIONALLY supplies a billing string that is logged with -the page accounting information.

          -

          "job-sheets" (1setof type3 keyword | name(MAX)):

          +

          The client OPTIONALLY supplies a billing string that is logged with + the page accounting information.

          +

          "job-sheets" (1setof type3 keyword | name(MAX)):

          (CUPS 1.1 and higher)

          -

          The client OPTIONALLY supplies one or two banner pages that are -printed before and after any files in the print job. The name of -"none" is reserved to indicate that no banner page should be printed. -If the client does not specify this attribute then the value of the -"job-sheets-default" printer object attribute is used.

          -

          Note: Standard IPP only allows specification of a single - job-sheets attribute value.

          -

          "media" (1setof type3 keyword | name(MAX)):

          -

          The client OPTIONALLY supplies one or more media attributes - specifying the size, type, source, and color of the output media. If -the client does not specify this attribute then the value of the -"media-default" printer object attribute is used.

          -

          Note: Standard IPP only allows specification of a single - media attribute value.

          -

          Other Job Template Attributes

          -
        -

        The Print-Job request is followed by a file to be printed.

        +

        The client OPTIONALLY supplies one or two banner pages that are + printed before and after any files in the print job. The name of "none" + is reserved to indicate that no banner page should be printed. If the + client does not specify this attribute then the value of the + "job-sheets-default" printer object attribute is used.

        +

        Note: Standard IPP only allows specification of a single + job-sheets attribute value.

        +

        "media" (1setof type3 keyword | name(MAX)):

        +

        The client OPTIONALLY supplies one or more media attributes + specifying the size, type, source, and color of the output media. If + the client does not specify this attribute then the value of the + "media-default" printer object attribute is used.

        +

        Note: Standard IPP only allows specification of a single media + attribute value.

        +

        Other Job Template Attributes

        + +

        The Print-Job request is followed by a file to be printed.

        4.1.2 Print-Job Response

        -

        The following groups of attributes are send as part of the Print-Job -Response:

        -

        Group 1: Operation Attributes

        +

        The following groups of attributes are send as part of the Print-Job + Response:

        +

        Group 1: Operation Attributes

          -

          Status Message:

          -

          The standard response status message.

          -

          Natural Language and Character Set:

          -

          The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.2 of the IPP Model and - Semantics document.

          +

          Status Message:

          +

          The standard response status message.

          +

          Natural Language and Character Set:

          +

          The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.2 of the IPP Model and Semantics + document.

        -

        Group 2: Job Attributes

        +

        Group 2: Job Attributes

          -

          Standard Job Attributes

          +

          Standard Job Attributes

        4.2 Create-Job Operation

        -

        The Create-Job operation (0x0005) creates a new, empty print job.

        +

        The Create-Job operation (0x0005) creates a new, empty print job.

        4.2.1 Create-Job Request

        -

        The following groups of attributes are supplied as part of the -Create-Job request:

        -

        Group 1: Operation Attributes

        +

        The following groups of attributes are supplied as part of the + Create-Job request:

        +

        Group 1: Operation Attributes

          -

          Natural Language and Character Set:

          -

          The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.1 of the IPP Model and - Semantics document.

          -

          "printer-uri" (uri):

          -

          The client MUST supply a URI for the specified printer.

          +

          Natural Language and Character Set:

          +

          The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.1 of the IPP Model and Semantics + document.

          +

          "printer-uri" (uri):

          +

          The client MUST supply a URI for the specified printer.

        -

        Group 2: Job Template Attributes

        +

        Group 2: Job Template Attributes

          -

          "job-billing" (text(MAX)):

          +

          "job-billing" (text(MAX)):

          (CUPS 1.1 and higher)

          -

          The client OPTIONALLY supplies a billing string that is logged with -the page accounting information.

          -

          "job-sheets" (1setof type3 keyword | name(MAX)):

          +

          The client OPTIONALLY supplies a billing string that is logged with + the page accounting information.

          +

          "job-sheets" (1setof type3 keyword | name(MAX)):

          (CUPS 1.1 and higher)

          -

          The client OPTIONALLY supplies one or two banner pages that are -printed before and after any files in the print job. The name of -"none" is reserved to indicate that no banner page should be printed. -If the client does not specify this attribute then the value of the -"job-sheets-default" printer object attribute is used.

          -

          Note: Standard IPP only allows specification of a single - job-sheets attribute value.

          -

          "media" (1setof type3 keyword | name(MAX)):

          -

          The client OPTIONALLY supplies one or more media attributes - specifying the size, type, source, and color of the output media. If -the client does not specify this attribute then the value of the -"media-default" printer object attribute is used.

          -

          Note: Standard IPP only allows specification of a single - media attribute value.

          -

          Standard Job Template Attributes

          +

          The client OPTIONALLY supplies one or two banner pages that are + printed before and after any files in the print job. The name of "none" + is reserved to indicate that no banner page should be printed. If the + client does not specify this attribute then the value of the + "job-sheets-default" printer object attribute is used.

          +

          Note: Standard IPP only allows specification of a single + job-sheets attribute value.

          +

          "media" (1setof type3 keyword | name(MAX)):

          +

          The client OPTIONALLY supplies one or more media attributes + specifying the size, type, source, and color of the output media. If + the client does not specify this attribute then the value of the + "media-default" printer object attribute is used.

          +

          Note: Standard IPP only allows specification of a single media + attribute value.

          +

          Standard Job Template Attributes

        4.2.2 Create-Job Response

        -

        The following groups of attributes are send as part of the -Create-Job Response:

        -

        Group 1: Operation Attributes

        +

        The following groups of attributes are send as part of the Create-Job + Response:

        +

        Group 1: Operation Attributes

          -

          Status Message:

          -

          The standard response status message.

          -

          Natural Language and Character Set:

          -

          The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.2 of the IPP Model and - Semantics document.

          +

          Status Message:

          +

          The standard response status message.

          +

          Natural Language and Character Set:

          +

          The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.2 of the IPP Model and Semantics + document.

        -

        Group 2: Job Attributes

        +

        Group 2: Job Attributes

          -

          Standard Job Attributes

          +

          Standard Job Attributes

        4.3 Set-Job-Attributes Operation

        -

        The Set-Job-Attributes operation (0x0014) changes the attributes of -an active (not completed) job.

        +

        The Set-Job-Attributes operation (0x0014) changes the attributes of + an active (not completed) job.

        4.3.1 Set-Job-Attributes Request

        -

        The following groups of attributes are supplied as part of the -Set-Job-Attributes request:

        -

        Group 1: Operation Attributes

        -
          -

          Natural Language and Character Set:

          -

          The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.1 of the IPP Model and - Semantics document.

          -

          "printer-uri" (uri) and "job-id" (integer)

          +

          The following groups of attributes are supplied as part of the + Set-Job-Attributes request:

          +

          Group 1: Operation Attributes

          +
            +

            Natural Language and Character Set:

            +

            The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.1 of the IPP Model and Semantics + document.

            +

            "printer-uri" (uri) and "job-id" (integer)

            OR

            -

            "job-uri":

            -

            The client MUST supply a URI for the specified printer and a job ID -number, or the job URI.

            +

            "job-uri":

            +

            The client MUST supply a URI for the specified printer and a job ID + number, or the job URI.

          -

          Group 2: Job Template Attributes

          +

          Group 2: Job Template Attributes

            -

            "job-sheets" (1setof type3 keyword | name(MAX)):

            +

            "job-sheets" (1setof type3 keyword | name(MAX)):

            (CUPS 1.1 and higher)

            -

            The client OPTIONALLY supplies one or two banner pages that are -printed before and after any files in the print job. The name of -"none" is reserved to indicate that no banner page should be printed. -If the client does not specify this attribute then the value of the -"job-sheets-default" printer object attribute is used.

            -

            Note: Standard IPP only allows specification of a single - job-sheets attribute value.

            -

            "media" (1setof type3 keyword | name(MAX)):

            -

            The client OPTIONALLY supplies one or more media attributes - specifying the size, type, source, and color of the output media. If -the client does not specify this attribute then the value of the -"media-default" printer object attribute is used.

            -

            Note: Standard IPP only allows specification of a single - media attribute value.

            -

            Other Job Template Attributes

            +

            The client OPTIONALLY supplies one or two banner pages that are + printed before and after any files in the print job. The name of "none" + is reserved to indicate that no banner page should be printed. If the + client does not specify this attribute then the value of the + "job-sheets-default" printer object attribute is used.

            +

            Note: Standard IPP only allows specification of a single + job-sheets attribute value.

            +

            "media" (1setof type3 keyword | name(MAX)):

            +

            The client OPTIONALLY supplies one or more media attributes + specifying the size, type, source, and color of the output media. If + the client does not specify this attribute then the value of the + "media-default" printer object attribute is used.

            +

            Note: Standard IPP only allows specification of a single media + attribute value.

            +

            Other Job Template Attributes

          4.3.2 Set-Job-Attributes Response

          -

          The following groups of attributes are send as part of the -Set-Job-Attributes Response:

          -

          Group 1: Operation Attributes

          +

          The following groups of attributes are send as part of the + Set-Job-Attributes Response:

          +

          Group 1: Operation Attributes

            -

            Status Message:

            -

            The standard response status message.

            -

            Natural Language and Character Set:

            -

            The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.2 of the IPP Model and - Semantics document.

            +

            Status Message:

            +

            The standard response status message.

            +

            Natural Language and Character Set:

            +

            The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.2 of the IPP Model and Semantics + document.

          4.4 CUPS-Get-Default Operation

          -

          The CUPS-Get-Default operation (0x4001) returns the default printer -URI and attributes.

          +

          The CUPS-Get-Default operation (0x4001) returns the default printer + URI and attributes.

          4.4.1 CUPS-Get-Default Request

          -

          The following groups of attributes are supplied as part of the -CUPS-Get-Default request:

          -

          Group 1: Operation Attributes

          -
            -

            Natural Language and Character Set:

            -

            The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.1 of the IPP Model and - Semantics document.

            -

            "requested-attributes" (1setOf keyword) :

            -

            The client OPTIONALLY supplies a set of attribute names and/or -attribute group names in whose values the requester is interested. If -the client omits this attribute, the server responds as if this -attribute had been supplied with a value of 'all'.

            +

            The following groups of attributes are supplied as part of the + CUPS-Get-Default request:

            +

            Group 1: Operation Attributes

            +
              +

              Natural Language and Character Set:

              +

              The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.1 of the IPP Model and Semantics + document.

              +

              "requested-attributes" (1setOf keyword) :

              +

              The client OPTIONALLY supplies a set of attribute names and/or + attribute group names in whose values the requester is interested. If + the client omits this attribute, the server responds as if this + attribute had been supplied with a value of 'all'.

            4.4.2 CUPS-Get-Default Response

            -

            The following groups of attributes are send as part of the -CUPS-Get-Default Response:

            -

            Group 1: Operation Attributes

            +

            The following groups of attributes are send as part of the + CUPS-Get-Default Response:

            +

            Group 1: Operation Attributes

              -

              Status Message:

              -

              The standard response status message.

              -

              Natural Language and Character Set:

              -

              The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.2 of the IPP Model and - Semantics document.

              +

              Status Message:

              +

              The standard response status message.

              +

              Natural Language and Character Set:

              +

              The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.2 of the IPP Model and Semantics + document.

            -

            Group 2: Printer Object Attributes

            +

            Group 2: Printer Object Attributes

              -

              The set of requested attributes and their current values.

              +

              The set of requested attributes and their current values.

            4.5 CUPS-Get-Printers Operation

            -

            The CUPS-Get-Printers operation (0x4002) returns the printer -attributes for every printer known to the system. This may include -printers that are not served directly by the server.

            +

            The CUPS-Get-Printers operation (0x4002) returns the printer + attributes for every printer known to the system. This may include + printers that are not served directly by the server.

            4.5.1 CUPS-Get-Printers Request

            -

            The following groups of attributes are supplied as part of the -CUPS-Get-Printers request:

            -

            Group 1: Operation Attributes

            -
              -

              Natural Language and Character Set:

              -

              The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.1 of the IPP Model and - Semantics document.

              -

              "limit" (integer (1:MAX)):

              -

              The client OPTIONALLY supplies this attribute limiting the number -of printers that are returned.

              -

              "printer-info" (text(127)):

              +

              The following groups of attributes are supplied as part of the + CUPS-Get-Printers request:

              +

              Group 1: Operation Attributes

              +
                +

                Natural Language and Character Set:

                +

                The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.1 of the IPP Model and Semantics + document.

                +

                "limit" (integer (1:MAX)):

                +

                The client OPTIONALLY supplies this attribute limiting the number of + printers that are returned.

                +

                "printer-info" (text(127)):

                (CUPS 1.1 and higher)

                -

                The client OPTIONALLY supplies this attribute to select which -printers are returned.

                -

                "printer-location" (text(127)):

                +

                The client OPTIONALLY supplies this attribute to select which + printers are returned.

                +

                "printer-location" (text(127)):

                (CUPS 1.1 and higher)

                -

                The client OPTIONALLY supplies this attribute to select which -printers are returned.

                -

                "printer-type" (type2 enum):

                +

                The client OPTIONALLY supplies this attribute to select which + printers are returned.

                +

                "printer-type" (type2 enum):

                (CUPS 1.1 and higher)

                -

                The client OPTIONALLY supplies a printer type enumeration to select -which printers are returned.

                -

                "printer-type-mask" (type2 enum):

                +

                The client OPTIONALLY supplies a printer type enumeration to select + which printers are returned.

                +

                "printer-type-mask" (type2 enum):

                (CUPS 1.1 and higher)

                -

                The client OPTIONALLY supplies a printer type mask enumeration to -select which bits are used in the "printer-type" attribute.

                -

                "requested-attributes" (1setOf keyword) :

                -

                The client OPTIONALLY supplies a set of attribute names and/or -attribute group names in whose values the requester is interested. If -the client omits this attribute, the server responds as if this -attribute had been supplied with a value of 'all'.

                +

                The client OPTIONALLY supplies a printer type mask enumeration to + select which bits are used in the "printer-type" attribute.

                +

                "requested-attributes" (1setOf keyword) :

                +

                The client OPTIONALLY supplies a set of attribute names and/or + attribute group names in whose values the requester is interested. If + the client omits this attribute, the server responds as if this + attribute had been supplied with a value of 'all'.

              4.5.2 CUPS-Get-Printers Response

              -

              The following groups of attributes are send as part of the -CUPS-Get-Printers Response:

              -

              Group 1: Operation Attributes

              +

              The following groups of attributes are send as part of the + CUPS-Get-Printers Response:

              +

              Group 1: Operation Attributes

                -

                Status Message:

                -

                The standard response status message.

                -

                Natural Language and Character Set:

                -

                The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.2 of the IPP Model and - Semantics document.

                +

                Status Message:

                +

                The standard response status message.

                +

                Natural Language and Character Set:

                +

                The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.2 of the IPP Model and Semantics + document.

              -

              Group 2: Printer Object Attributes

              +

              Group 2: Printer Object Attributes

                -

                The set of requested attributes and their current values for each -printer.

                +

                The set of requested attributes and their current values for each + printer.

              4.6 CUPS-Add-Printer Operation

              -

              The CUPS-Add-Printer operation (0x4003) adds a new printer or -modifies an existing printer on the system.

              +

              The CUPS-Add-Printer operation (0x4003) adds a new printer or + modifies an existing printer on the system.

              4.6.1 CUPS-Add-Printer Request

              -

              The following groups of attributes are supplied as part of the -CUPS-Add-Printer request:

              -

              Group 1: Operation Attributes

              +

              The following groups of attributes are supplied as part of the + CUPS-Add-Printer request:

              +

              Group 1: Operation Attributes

                -

                Natural Language and Character Set:

                -

                The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.1 of the IPP Model and - Semantics document.

                -

                "printer-uri" (uri):

                -

                The client MUST supply a URI for the specified printer.

                +

                Natural Language and Character Set:

                +

                The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.1 of the IPP Model and Semantics + document.

                +

                "printer-uri" (uri):

                +

                The client MUST supply a URI for the specified printer.

              -

              Group 2: Printer Object Attributes

              +

              Group 2: Printer Object Attributes

                -

                "banner-end-default" (name(127)):

                +

                "banner-end-default" (name(127)):

                (CUPS 1.1 and higher)

                -

                The client OPTIONALLY supplies a banner page name that is printed -after files in a job. The reserved name "none" is used to specify that -no banner page should be printed.

                -

                "banner-start-default" (name(127)):

                +

                The client OPTIONALLY supplies a banner page name that is printed + after files in a job. The reserved name "none" is used to specify that + no banner page should be printed.

                +

                "banner-start-default" (name(127)):

                (CUPS 1.1 and higher)

                -

                The client OPTIONALLY supplies a banner page name that is printed -before files in a job. The reserved name "none" is used to specify -that no banner page should be printed.

                -

                "device-uri" (uri):

                -

                The client OPTIONALLY supplies a device URI for the specified -printer.

                -

                "ppd-name" (name(127)):

                -

                The client OPTIONALLY supplies a PPD name for the specified - printer.

                -

                "printer-is-accepting-jobs" (boolean):

                -

                The client OPTIONALLY supplies this boolean attribute indicating -whether or not the printer object should accept new jobs.

                -

                "printer-info" (text(127)):

                -

                The client OPTIONALLY supplies this attribute indicating the - printer information string.

                -

                "printer-location" (text(127)):

                -

                The client OPTIONALLY supplies this attribute indicating a textual -location of the printer.

                -

                "printer-more-info" (uri):

                -

                The client OPTIONALLY supplies this attribute indicating a URI for -additional printer information.

                -

                "printer-state" (type2 enum):

                -

                The client OPTIONALLY supplies this attribute indicating the - initial/current state of the printer. Only the "idle" and "stopped" - enumerations are recognized.

                -

                "printer-state-message" (text(MAX)):

                -

                The client OPTIONALLY supplies this attribute indicating a textual -reason for the current printer state.

                -

                "requesting-user-name-allowed" (1setof name(127) | delete)

                +

                The client OPTIONALLY supplies a banner page name that is printed + before files in a job. The reserved name "none" is used to specify that + no banner page should be printed.

                +

                "device-uri" (uri):

                +

                The client OPTIONALLY supplies a device URI for the specified + printer.

                +

                "ppd-name" (name(127)):

                +

                The client OPTIONALLY supplies a PPD name for the specified printer.

                +

                "printer-is-accepting-jobs" (boolean):

                +

                The client OPTIONALLY supplies this boolean attribute indicating + whether or not the printer object should accept new jobs.

                +

                "printer-info" (text(127)):

                +

                The client OPTIONALLY supplies this attribute indicating the printer + information string.

                +

                "printer-location" (text(127)):

                +

                The client OPTIONALLY supplies this attribute indicating a textual + location of the printer.

                +

                "printer-more-info" (uri):

                +

                The client OPTIONALLY supplies this attribute indicating a URI for + additional printer information.

                +

                "printer-state" (type2 enum):

                +

                The client OPTIONALLY supplies this attribute indicating the + initial/current state of the printer. Only the "idle" and "stopped" + enumerations are recognized.

                +

                "printer-state-message" (text(MAX)):

                +

                The client OPTIONALLY supplies this attribute indicating a textual + reason for the current printer state.

                +

                "requesting-user-name-allowed" (1setof name(127) | delete)

                OR

                -

                "requesting-user-name-denied" (1setof name(127) | delete):

                -

                The client OPTIONALLY supplies one of these attributes to specify -an access control list for incoming print jobs. To allow all users -access to a printer, use the delete tag for the attribute value.

                -
              -

              The CUPS-Add-Printer request can optionally be followed by a PPD -file or System V interface script to be used for the printer. The -"ppd-name" attribute overrides any file that is attached to the end of -the request with a local CUPS PPD file.

              +

              "requesting-user-name-denied" (1setof name(127) | delete):

              +

              The client OPTIONALLY supplies one of these attributes to specify an + access control list for incoming print jobs. To allow all users access + to a printer, use the delete tag for the attribute value.

              +
            +

            The CUPS-Add-Printer request can optionally be followed by a PPD file + or System V interface script to be used for the printer. The "ppd-name" + attribute overrides any file that is attached to the end of the request + with a local CUPS PPD file.

            4.6.2 CUPS-Add-Printer Response

            -

            The following groups of attributes are send as part of the -CUPS-Add-Printer Response:

            -

            Group 1: Operation Attributes

            +

            The following groups of attributes are send as part of the + CUPS-Add-Printer Response:

            +

            Group 1: Operation Attributes

              -

              Status Message:

              -

              The standard response status message.

              -

              Natural Language and Character Set:

              -

              The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.2 of the IPP Model and - Semantics document.

              +

              Status Message:

              +

              The standard response status message.

              +

              Natural Language and Character Set:

              +

              The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.2 of the IPP Model and Semantics + document.

            4.7 CUPS-Delete-Printer Operation

            -

            The CUPS-Delete-Printer operation (0x4004) removes an existing -printer from the system.

            +

            The CUPS-Delete-Printer operation (0x4004) removes an existing + printer from the system.

            4.7.1 CUPS-Delete-Printer Request

            -

            The following groups of attributes are supplied as part of the -CUPS-Delete-Printer request:

            -

            Group 1: Operation Attributes

            +

            The following groups of attributes are supplied as part of the + CUPS-Delete-Printer request:

            +

            Group 1: Operation Attributes

              -

              Natural Language and Character Set:

              -

              The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.1 of the IPP Model and - Semantics document.

              -

              "printer-uri" (uri):

              -

              The client MUST supply a URI for the specified printer.

              +

              Natural Language and Character Set:

              +

              The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.1 of the IPP Model and Semantics + document.

              +

              "printer-uri" (uri):

              +

              The client MUST supply a URI for the specified printer.

            4.7.2 CUPS-Delete-Printer Response

            -

            The following groups of attributes are send as part of the -CUPS-Delete-Printer Response:

            -

            Group 1: Operation Attributes

            +

            The following groups of attributes are send as part of the + CUPS-Delete-Printer Response:

            +

            Group 1: Operation Attributes

              -

              Status Message:

              -

              The standard response status message.

              -

              Natural Language and Character Set:

              -

              The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.2 of the IPP Model and - Semantics document.

              +

              Status Message:

              +

              The standard response status message.

              +

              Natural Language and Character Set:

              +

              The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.2 of the IPP Model and Semantics + document.

            4.8 CUPS-Get-Classes Operation

            -

            The CUPS-Get-Classes operation (0x4005) returns the printer -attributes for every printer class known to the system. This may -include printer classes that are not served directly by the server.

            +

            The CUPS-Get-Classes operation (0x4005) returns the printer + attributes for every printer class known to the system. This may + include printer classes that are not served directly by the server.

            4.8.1 CUPS-Get-Classes Request

            -

            The following groups of attributes are supplied as part of the -CUPS-Get-Classes request:

            -

            Group 1: Operation Attributes

            -
              -

              Natural Language and Character Set:

              -

              The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.1 of the IPP Model and - Semantics document.

              -

              "limit" (integer (1:MAX)):

              -

              The client OPTIONALLY supplies this attribute limiting the number -of printer classes that are returned.

              -

              "printer-info" (text(127)):

              +

              The following groups of attributes are supplied as part of the + CUPS-Get-Classes request:

              +

              Group 1: Operation Attributes

              +
                +

                Natural Language and Character Set:

                +

                The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.1 of the IPP Model and Semantics + document.

                +

                "limit" (integer (1:MAX)):

                +

                The client OPTIONALLY supplies this attribute limiting the number of + printer classes that are returned.

                +

                "printer-info" (text(127)):

                (CUPS 1.1 and higher)

                -

                The client OPTIONALLY supplies this attribute to select which -printer classes are returned.

                -

                "printer-location" (text(127)):

                +

                The client OPTIONALLY supplies this attribute to select which printer + classes are returned.

                +

                "printer-location" (text(127)):

                (CUPS 1.1 and higher)

                -

                The client OPTIONALLY supplies this attribute to select which -printer classes are returned.

                -

                "printer-type" (type2 enum):

                +

                The client OPTIONALLY supplies this attribute to select which printer + classes are returned.

                +

                "printer-type" (type2 enum):

                (CUPS 1.1 and higher)

                -

                The client OPTIONALLY supplies a printer type enumeration to select -which printer classes are returned.

                -

                "printer-type-mask" (type2 enum):

                +

                The client OPTIONALLY supplies a printer type enumeration to select + which printer classes are returned.

                +

                "printer-type-mask" (type2 enum):

                (CUPS 1.1 and higher)

                -

                The client OPTIONALLY supplies a printer type mask enumeration to -select which bits are used in the "printer-type" attribute.

                -

                "requested-attributes" (1setOf keyword) :

                -

                The client OPTIONALLY supplies a set of attribute names and/or -attribute group names in whose values the requester is interested. If -the client omits this attribute, the server responds as if this -attribute had been supplied with a value of 'all'.

                +

                The client OPTIONALLY supplies a printer type mask enumeration to + select which bits are used in the "printer-type" attribute.

                +

                "requested-attributes" (1setOf keyword) :

                +

                The client OPTIONALLY supplies a set of attribute names and/or + attribute group names in whose values the requester is interested. If + the client omits this attribute, the server responds as if this + attribute had been supplied with a value of 'all'.

              4.8.2 CUPS-Get-Classes Response

              -

              The following groups of attributes are send as part of the -CUPS-Get-Classes Response:

              -

              Group 1: Operation Attributes

              +

              The following groups of attributes are send as part of the + CUPS-Get-Classes Response:

              +

              Group 1: Operation Attributes

                -

                Status Message:

                -

                The standard response status message.

                -

                Natural Language and Character Set:

                -

                The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.2 of the IPP Model and - Semantics document.

                +

                Status Message:

                +

                The standard response status message.

                +

                Natural Language and Character Set:

                +

                The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.2 of the IPP Model and Semantics + document.

              -

              Group 2: Printer Class Object Attributes

              +

              Group 2: Printer Class Object Attributes

                -

                The set of requested attributes and their current values for each -printer class.

                +

                The set of requested attributes and their current values for each + printer class.

              4.9 CUPS-Add-Class Operation

              -

              The CUPS-Add-Class operation (0x4006) adds a new printer class or -modifies and existing printer class on the system.

              +

              The CUPS-Add-Class operation (0x4006) adds a new printer class or + modifies and existing printer class on the system.

              4.9.1 CUPS-Add-Class Request

              -

              The following groups of attributes are supplied as part of the -CUPS-Add-Class request:

              -

              Group 1: Operation Attributes

              -
                -

                Natural Language and Character Set:

                -

                The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.1 of the IPP Model and - Semantics document.

                -

                "printer-uri" (uri):

                -

                The client MUST supply a URI for the specified printer class.

                -
              -

              Group 2: Printer Object Attributes

              -
                -

                "member-uris" (1setof uri):

                -

                The client OPTIONALLY supplies the "member-uris" set specifying the -printers and printer classes that are part of the class.

                -

                "printer-is-accepting-jobs" (boolean):

                -

                The client OPTIONALLY supplies this boolean attribute indicating -whether or not the class object should accept new jobs.

                -

                "printer-info" (text(127)):

                -

                The client OPTIONALLY supplies this attribute indicating the - printer information string.

                -

                "printer-location" (text(127)):

                -

                The client OPTIONALLY supplies this attribute indicating a textual -location of the class.

                -

                "printer-more-info" (uri):

                -

                The client OPTIONALLY supplies this attribute indicating a URI for -additional class information.

                -

                "printer-state" (type2 enum):

                -

                The client OPTIONALLY supplies this attribute indicating the - initial/current state of the class. Only the "idle" and "stopped" - enumerations are recognized.

                -

                "printer-state-message" (text(MAX)):

                -

                The client OPTIONALLY supplies this attribute indicating a textual -reason for the current class state.

                -

                "requesting-user-name-allowed" (1setof name(127))

                +

                The following groups of attributes are supplied as part of the + CUPS-Add-Class request:

                +

                Group 1: Operation Attributes

                +
                  +

                  Natural Language and Character Set:

                  +

                  The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.1 of the IPP Model and Semantics + document.

                  +

                  "printer-uri" (uri):

                  +

                  The client MUST supply a URI for the specified printer class.

                  +
                +

                Group 2: Printer Object Attributes

                +
                  +

                  "member-uris" (1setof uri):

                  +

                  The client OPTIONALLY supplies the "member-uris" set specifying the + printers and printer classes that are part of the class.

                  +

                  "printer-is-accepting-jobs" (boolean):

                  +

                  The client OPTIONALLY supplies this boolean attribute indicating + whether or not the class object should accept new jobs.

                  +

                  "printer-info" (text(127)):

                  +

                  The client OPTIONALLY supplies this attribute indicating the printer + information string.

                  +

                  "printer-location" (text(127)):

                  +

                  The client OPTIONALLY supplies this attribute indicating a textual + location of the class.

                  +

                  "printer-more-info" (uri):

                  +

                  The client OPTIONALLY supplies this attribute indicating a URI for + additional class information.

                  +

                  "printer-state" (type2 enum):

                  +

                  The client OPTIONALLY supplies this attribute indicating the + initial/current state of the class. Only the "idle" and "stopped" + enumerations are recognized.

                  +

                  "printer-state-message" (text(MAX)):

                  +

                  The client OPTIONALLY supplies this attribute indicating a textual + reason for the current class state.

                  +

                  "requesting-user-name-allowed" (1setof name(127))

                  OR

                  -

                  "requesting-user-name-denied" (1setof name(127)):

                  -

                  The client OPTIONALLY supplies one of these attributes to specify -an access control list for incoming print jobs. To allow all users -access to a class, use the delete tag for the attribute value.

                  +

                  "requesting-user-name-denied" (1setof name(127)):

                  +

                  The client OPTIONALLY supplies one of these attributes to specify an + access control list for incoming print jobs. To allow all users access + to a class, use the delete tag for the attribute value.

                4.9.2 CUPS-Add-Class Response

                -

                The following groups of attributes are send as part of the -CUPS-Add-Class Response:

                -

                Group 1: Operation Attributes

                +

                The following groups of attributes are send as part of the + CUPS-Add-Class Response:

                +

                Group 1: Operation Attributes

                  -

                  Status Message:

                  -

                  The standard response status message.

                  -

                  Natural Language and Character Set:

                  -

                  The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.2 of the IPP Model and - Semantics document.

                  +

                  Status Message:

                  +

                  The standard response status message.

                  +

                  Natural Language and Character Set:

                  +

                  The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.2 of the IPP Model and Semantics + document.

                4.10 CUPS-Delete-Class Operation

                -

                The CUPS-Delete-Class operation (0x4007) removes an existing printer -class from the system.

                +

                The CUPS-Delete-Class operation (0x4007) removes an existing printer + class from the system.

                4.10.1 CUPS-Delete-Class Request

                -

                The following groups of attributes are supplied as part of the -CUPS-Delete-Class request:

                -

                Group 1: Operation Attributes

                +

                The following groups of attributes are supplied as part of the + CUPS-Delete-Class request:

                +

                Group 1: Operation Attributes

                  -

                  Natural Language and Character Set:

                  -

                  The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.1 of the IPP Model and - Semantics document.

                  -

                  "printer-uri" (uri):

                  -

                  The client MUST supply a URI for the specified printer class.

                  +

                  Natural Language and Character Set:

                  +

                  The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.1 of the IPP Model and Semantics + document.

                  +

                  "printer-uri" (uri):

                  +

                  The client MUST supply a URI for the specified printer class.

                4.10.2 CUPS-Delete-Class Response

                -

                The following groups of attributes are send as part of the -CUPS-Delete-Class Response:

                -

                Group 1: Operation Attributes

                +

                The following groups of attributes are send as part of the + CUPS-Delete-Class Response:

                +

                Group 1: Operation Attributes

                  -

                  Status Message:

                  -

                  The standard response status message.

                  -

                  Natural Language and Character Set:

                  -

                  The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.2 of the IPP Model and - Semantics document.

                  +

                  Status Message:

                  +

                  The standard response status message.

                  +

                  Natural Language and Character Set:

                  +

                  The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.2 of the IPP Model and Semantics + document.

                4.11 CUPS-Accept-Jobs Operation

                -

                The CUPS-Accept-Jobs operation (0x4008) sets the -"printer-is-accepting-jobs" attribute to true for the specified printer -or printer class.

                +

                The CUPS-Accept-Jobs operation (0x4008) sets the + "printer-is-accepting-jobs" attribute to true for the specified printer + or printer class.

                4.11.1 CUPS-Accept-Jobs Request

                -

                The following groups of attributes are supplied as part of the -CUPS-Accept-Jobs request:

                -

                Group 1: Operation Attributes

                -
                  -

                  Natural Language and Character Set:

                  -

                  The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.1 of the IPP Model and - Semantics document.

                  -

                  "printer-uri" (uri):

                  -

                  The client MUST supply a URI for the specified printer or printer -class.

                  +

                  The following groups of attributes are supplied as part of the + CUPS-Accept-Jobs request:

                  +

                  Group 1: Operation Attributes

                  +
                    +

                    Natural Language and Character Set:

                    +

                    The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.1 of the IPP Model and Semantics + document.

                    +

                    "printer-uri" (uri):

                    +

                    The client MUST supply a URI for the specified printer or printer + class.

                  4.11.2 CUPS-Accept-Jobs Response

                  -

                  The following groups of attributes are send as part of the -CUPS-Accept-Jobs Response:

                  -

                  Group 1: Operation Attributes

                  +

                  The following groups of attributes are send as part of the + CUPS-Accept-Jobs Response:

                  +

                  Group 1: Operation Attributes

                    -

                    Status Message:

                    -

                    The standard response status message.

                    -

                    Natural Language and Character Set:

                    -

                    The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.2 of the IPP Model and - Semantics document.

                    +

                    Status Message:

                    +

                    The standard response status message.

                    +

                    Natural Language and Character Set:

                    +

                    The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.2 of the IPP Model and Semantics + document.

                  4.12 CUPS-Reject-Jobs Operation

                  -

                  The CUPS-Reject-Jobs operation (0x4009) sets -the"printer-is-accepting-jobs" attribute to false for the specified -printer or printer class.

                  +

                  The CUPS-Reject-Jobs operation (0x4009) sets + the"printer-is-accepting-jobs" attribute to false for the specified + printer or printer class.

                  4.12.1 CUPS-Reject-Jobs Request

                  -

                  The following groups of attributes are supplied as part of the -CUPS-Reject-Jobs request:

                  -

                  Group 1: Operation Attributes

                  +

                  The following groups of attributes are supplied as part of the + CUPS-Reject-Jobs request:

                  +

                  Group 1: Operation Attributes

                    -

                    Natural Language and Character Set:

                    -

                    The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.1 of the IPP Model and - Semantics document.

                    -

                    "printer-uri" (uri):

                    -

                    The client MUST supply a URI for the specified printer or printer -class.

                    +

                    Natural Language and Character Set:

                    +

                    The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.1 of the IPP Model and Semantics + document.

                    +

                    "printer-uri" (uri):

                    +

                    The client MUST supply a URI for the specified printer or printer + class.

                  -

                  Group 2: Printer Object Attributes

                  +

                  Group 2: Printer Object Attributes

                    -

                    "printer-state-message" (text(MAX)):

                    -

                    The client OPTIONALLY supplies this attribute indicating a textual -reason for the current printer state.

                    +

                    "printer-state-message" (text(MAX)):

                    +

                    The client OPTIONALLY supplies this attribute indicating a textual + reason for the current printer state.

                  4.12.2 CUPS-Reject-Jobs Response

                  -

                  The following groups of attributes are send as part of the -CUPS-Reject-Jobs Response:

                  -

                  Group 1: Operation Attributes

                  +

                  The following groups of attributes are send as part of the + CUPS-Reject-Jobs Response:

                  +

                  Group 1: Operation Attributes

                    -

                    Status Message:

                    -

                    The standard response status message.

                    -

                    Natural Language and Character Set:

                    -

                    The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.2 of the IPP Model and - Semantics document.

                    +

                    Status Message:

                    +

                    The standard response status message.

                    +

                    Natural Language and Character Set:

                    +

                    The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.2 of the IPP Model and Semantics + document.

                  4.13 CUPS-Set-Default Operation

                  -

                  The CUPS-Set-Default operation (0x400A) sets the default printer -destination for all clients when a resource name of "/printers" is -specified.

                  +

                  The CUPS-Set-Default operation (0x400A) sets the default printer + destination for all clients when a resource name of "/printers" is + specified.

                  4.13.1 CUPS-Set-Default Request

                  -

                  The following groups of attributes are supplied as part of the -CUPS-Set-Default request:

                  -

                  Group 1: Operation Attributes

                  -
                    -

                    Natural Language and Character Set:

                    -

                    The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.1 of the IPP Model and - Semantics document.

                    -

                    "printer-uri" (uri):

                    -

                    The client MUST supply a URI for the specified printer or printer -class.

                    +

                    The following groups of attributes are supplied as part of the + CUPS-Set-Default request:

                    +

                    Group 1: Operation Attributes

                    +
                      +

                      Natural Language and Character Set:

                      +

                      The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.1 of the IPP Model and Semantics + document.

                      +

                      "printer-uri" (uri):

                      +

                      The client MUST supply a URI for the specified printer or printer + class.

                    4.13.2 CUPS-Set-Default Response

                    -

                    The following groups of attributes are send as part of the -CUPS-Set-Default Response:

                    -

                    Group 1: Operation Attributes

                    +

                    The following groups of attributes are send as part of the + CUPS-Set-Default Response:

                    +

                    Group 1: Operation Attributes

                      -

                      Status Message:

                      -

                      The standard response status message.

                      -

                      Natural Language and Character Set:

                      -

                      The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.2 of the IPP Model and - Semantics document.

                      +

                      Status Message:

                      +

                      The standard response status message.

                      +

                      Natural Language and Character Set:

                      +

                      The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.2 of the IPP Model and Semantics + document.

                    4.14 CUPS-Get-Devices Operation

                    -

                    The CUPS-Get-Devices operation (0x400B) returns all of the supported -device-uri's for the server (CUPS 1.1 and higher).

                    +

                    The CUPS-Get-Devices operation (0x400B) returns all of the supported + device-uri's for the server (CUPS 1.1 and higher).

                    4.14.1 CUPS-Get-Devices Request

                    -

                    The following groups of attributes are supplied as part of the -CUPS-Get-Devices request:

                    -

                    Group 1: Operation Attributes

                    -
                      -

                      Natural Language and Character Set:

                      -

                      The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.1 of the IPP Model and - Semantics document.

                      -

                      "device-class" (type1 keyword):

                      -

                      The client OPTIONALLY supplies a device class keyword to select - which devices are returned.

                      -

                      "limit" (integer (1:MAX)):

                      -

                      The client OPTIONALLY supplies this attribute limiting the number of - devices that are returned.

                      -

                      "requested-attributes" (1setOf keyword) :

                      -

                      The client OPTIONALLY supplies a set of attribute names and/or - attribute group names in whose values the requester is interested. If - the client omits this attribute, the server responds as if this - attribute had been supplied with a value of 'all'.

                      +

                      The following groups of attributes are supplied as part of the + CUPS-Get-Devices request:

                      +

                      Group 1: Operation Attributes

                      +
                        +

                        Natural Language and Character Set:

                        +

                        The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.1 of the IPP Model and Semantics + document.

                        +

                        "device-class" (type1 keyword):

                        +

                        The client OPTIONALLY supplies a device class keyword to select which + devices are returned.

                        +

                        "limit" (integer (1:MAX)):

                        +

                        The client OPTIONALLY supplies this attribute limiting the number of + devices that are returned.

                        +

                        "requested-attributes" (1setOf keyword) :

                        +

                        The client OPTIONALLY supplies a set of attribute names and/or + attribute group names in whose values the requester is interested. If + the client omits this attribute, the server responds as if this + attribute had been supplied with a value of 'all'.

                      4.14.2 CUPS-Get-Devices Response

                      -

                      The following groups of attributes are send as part of the -CUPS-Get-Devices Response:

                      -

                      Group 1: Operation Attributes

                      +

                      The following groups of attributes are send as part of the + CUPS-Get-Devices Response:

                      +

                      Group 1: Operation Attributes

                        -

                        Status Message:

                        -

                        The standard response status message.

                        -

                        Natural Language and Character Set:

                        -

                        The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.2 of the IPP Model and - Semantics document.

                        +

                        Status Message:

                        +

                        The standard response status message.

                        +

                        Natural Language and Character Set:

                        +

                        The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.2 of the IPP Model and Semantics + document.

                      -

                      Group 2: Device Object Attributes

                      +

                      Group 2: Device Object Attributes

                        -

                        The set of requested attributes and their current values for each -device.

                        +

                        The set of requested attributes and their current values for each + device.

                      4.15 CUPS-Get-PPDs Operation

                      -

                      The CUPS-Get-PPDs operation (0x400C) returns all of the locally -available PPD files on the system (CUPS 1.1 and higher).

                      +

                      The CUPS-Get-PPDs operation (0x400C) returns all of the locally + available PPD files on the system (CUPS 1.1 and higher).

                      4.15.1 CUPS-Get-PPDs Request

                      -

                      The following groups of attributes are supplied as part of the -CUPS-Get-PPDs request:

                      -

                      Group 1: Operation Attributes

                      -
                        -

                        Natural Language and Character Set:

                        -

                        The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.1 of the IPP Model and - Semantics document.

                        -

                        "limit" (integer (1:MAX)):

                        -

                        The client OPTIONALLY supplies this attribute limiting the number of - PPDs that are returned.

                        -

                        "ppd-make" (text(127)):

                        -

                        The client OPTIONALLY supplies a printer manufacturer to select - which PPDs are returned.

                        -

                        "requested-attributes" (1setOf keyword) :

                        -

                        The client OPTIONALLY supplies a set of attribute names and/or - attribute group names in whose values the requester is interested. If - the client omits this attribute, the server responds as if this - attribute had been supplied with a value of 'all'.

                        +

                        The following groups of attributes are supplied as part of the + CUPS-Get-PPDs request:

                        +

                        Group 1: Operation Attributes

                        +
                          +

                          Natural Language and Character Set:

                          +

                          The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.1 of the IPP Model and Semantics + document.

                          +

                          "limit" (integer (1:MAX)):

                          +

                          The client OPTIONALLY supplies this attribute limiting the number of + PPDs that are returned.

                          +

                          "ppd-make" (text(127)):

                          +

                          The client OPTIONALLY supplies a printer manufacturer to select which + PPDs are returned.

                          +

                          "requested-attributes" (1setOf keyword) :

                          +

                          The client OPTIONALLY supplies a set of attribute names and/or + attribute group names in whose values the requester is interested. If + the client omits this attribute, the server responds as if this + attribute had been supplied with a value of 'all'.

                        4.15.2 CUPS-Get-PPDs Response

                        -

                        The following groups of attributes are send as part of the -CUPS-Get-PPDs Response:

                        -

                        Group 1: Operation Attributes

                        +

                        The following groups of attributes are send as part of the + CUPS-Get-PPDs Response:

                        +

                        Group 1: Operation Attributes

                          -

                          Status Message:

                          -

                          The standard response status message.

                          -

                          Natural Language and Character Set:

                          -

                          The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.2 of the IPP Model and - Semantics document.

                          +

                          Status Message:

                          +

                          The standard response status message.

                          +

                          Natural Language and Character Set:

                          +

                          The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.2 of the IPP Model and Semantics + document.

                        -

                        Group 2: PPD Attributes

                        +

                        Group 2: PPD Attributes

                          -

                          The set of requested attributes and their current values for each - PPD file.

                          +

                          The set of requested attributes and their current values for each PPD + file.

                        4.16 CUPS-Move-Job Operation

                        -

                        The CUPS-Move-Job operation (0x400D) moves an active print job to a -different printer (CUPS 1.1 and higher).

                        +

                        The CUPS-Move-Job operation (0x400D) moves an active print job to a + different printer (CUPS 1.1 and higher).

                        4.16.1 CUPS-Move-Job Request

                        -

                        The following groups of attributes are supplied as part of the -CUPS-Move-Job request:

                        -

                        Group 1: Operation Attributes

                        -
                          -

                          Natural Language and Character Set:

                          -

                          The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.1 of the IPP Model and - Semantics document.

                          -

                          "printer-uri" (uri) and "job-id" (integer)

                          +

                          The following groups of attributes are supplied as part of the + CUPS-Move-Job request:

                          +

                          Group 1: Operation Attributes

                          +
                            +

                            Natural Language and Character Set:

                            +

                            The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.1 of the IPP Model and Semantics + document.

                            +

                            "printer-uri" (uri) and "job-id" (integer)

                            OR

                            -

                            "job-uri":

                            -

                            The client MUST supply a URI for the specified printer and a job ID -number, or the job URI.

                            +

                            "job-uri":

                            +

                            The client MUST supply a URI for the specified printer and a job ID + number, or the job URI.

                          -

                          Group 2: Job Template Attributes

                          +

                          Group 2: Job Template Attributes

                            -

                            "job-printer-uri" (uri)

                            -

                            The client MUST supply a URI for a printer on the same server.

                            +

                            "job-printer-uri" (uri)

                            +

                            The client MUST supply a URI for a printer on the same server.

                          4.16.2 CUPS-Move-Job Response

                          -

                          The following groups of attributes are send as part of the -CUPS-Move-Job Response:

                          -

                          Group 1: Operation Attributes

                          +

                          The following groups of attributes are send as part of the + CUPS-Move-Job Response:

                          +

                          Group 1: Operation Attributes

                            -

                            Status Message:

                            -

                            The standard response status message.

                            -

                            Natural Language and Character Set:

                            -

                            The "attributes-charset" and "attributes-natural-language" - attributes as described in section 3.1.4.2 of the IPP Model and - Semantics document.

                            +

                            Status Message:

                            +

                            The standard response status message.

                            +

                            Natural Language and Character Set:

                            +

                            The "attributes-charset" and "attributes-natural-language" attributes + as described in section 3.1.4.2 of the IPP Model and Semantics + document.

                          5 Attributes

                          -

                          CUPS provides many extension attributes to support multiple devices, -PPD files, standard job filters, printers, and printer classes.

                          +

                          CUPS provides many extension attributes to support multiple devices, + PPD files, standard job filters, printers, and printer classes.

                          5.1 Device Attributes

                          -

                          Device attributes are returned by the CUPS-Get-Devices operation and -enumerate all of the available hardware devices and network protocols -that are supported by the server.

                          +

                          Device attributes are returned by the CUPS-Get-Devices operation and + enumerate all of the available hardware devices and network protocols + that are supported by the server.

                          5.1.1 device-class (type2 keyword)

                          -

                          The device-class attribute specifies the class of device and can be -one of the following:

                          +

                          The device-class attribute specifies the class of device and can be + one of the following:

                            -
                          • "file" - a disk file.
                          • -
                          • "direct" - a parallel or fixed-rate serial data port, currently -used for Centronics, IEEE-1284, and USB printer ports.
                          • -
                          • "serial" - a variable-rate serial port.
                          • -
                          • "network" - a network connection, typically via AppSocket, HTTP, -IPP, LPD, or SMB/CIFS protocols.
                          • +
                          • "file" - a disk file.
                          • +
                          • "direct" - a parallel or fixed-rate serial data port, currently used + for Centronics, IEEE-1284, and USB printer ports.
                          • +
                          • "serial" - a variable-rate serial port.
                          • +
                          • "network" - a network connection, typically via AppSocket, HTTP, + IPP, LPD, or SMB/CIFS protocols.

                          5.1.2 device-info (text(127))

                          -

                          The device-info attribute specifies a human-readable string -describing the device, e.g. "Parallel Port #1".

                          +

                          The device-info attribute specifies a human-readable string + describing the device, e.g. "Parallel Port #1".

                          5.1.3 device-make-and-model (text(127))

                          -

                          The device-makr-and-model attribute specifies a device -identification string provided by the printer connected to the device. -If the device or printer does not support identification then this -attribute contains the string "unknown".

                          +

                          The device-makr-and-model attribute specifies a device identification + string provided by the printer connected to the device. If the device + or printer does not support identification then this attribute contains + the string "unknown".

                          5.1.4 device-uri (uri)

                          -

                          The device-uri attribute specifies a unique identifier for the -device. The actual format of the device-uri string depends on the value -of the device-class attribute:

                          -
                            -
                          • "file" - The device-uri will be of the form - "file:/path/to/filename".
                          • -
                          • "direct" - The device-uri will be of the form - "method:/dev/filename", where method may be "parallel" or "usb" in -the current implementation.
                          • -
                          • "serial" - The device-uri will be of the form - "serial:/dev/filename?baud=value+parity=value+flow=value". The baud -value is the data rate in bits per second; the supported values depend -on the underlying hardware. The parity value can be one of "none", -"even", or "odd". The flow value can be one of "none", "soft" -(XON/XOFF handshaking), "hard" or "rts/cts" (RTS/CTS handshaking), or -"dtrdsr" (DTR/DSR handshaking).
                          • -

                            The URI returned by CUPS-Get-Devices will contain the maximum baud -rate supported by the device and the best type of flow control -available ("soft" or "hard").

                            -
                          • "network" - The device-uri will be of the form - "method://[username:password@]hostname[:port]/[resource]", where -method may be "http", "ipp", "lpd", "smb", or "socket" in the current -implementation.
                          • -

                            The URI returned by CUPS-Get-Devices will only contain the method -name followed by two slashes ("method://"). It is up to the client -application to add the appropriate host and other information when -adding a new printer.

                            -

                            The URI returned by Get-Printer-Attributes and CUPS-Get-Printers -has any username and password information stripped; the information is -still stored and used by the server internally to perform any needed -authentication.

                            +

                            The device-uri attribute specifies a unique identifier for the + device. The actual format of the device-uri string depends on the value + of the device-class attribute:

                            +
                              +
                            • "file" - The device-uri will be of the form + "file:/path/to/filename".
                            • +
                            • "direct" - The device-uri will be of the form + "method:/dev/filename", where method may be "parallel" or "usb" in the + current implementation.
                            • +
                            • "serial" - The device-uri will be of the form + "serial:/dev/filename?baud=value+parity=value+flow=value". The baud + value is the data rate in bits per second; the supported values depend + on the underlying hardware. The parity value can be one of "none", + "even", or "odd". The flow value can be one of "none", "soft" (XON/XOFF + handshaking), "hard" or "rts/cts" (RTS/CTS handshaking), or "dtrdsr" + (DTR/DSR handshaking).
                            • +

                              The URI returned by CUPS-Get-Devices will contain the maximum baud + rate supported by the device and the best type of flow control + available ("soft" or "hard").

                              +
                            • "network" - The device-uri will be of the form + "method://[username:password@]hostname[:port]/[resource]", where method + may be "http", "ipp", "lpd", "smb", or "socket" in the current + implementation.
                            • +

                              The URI returned by CUPS-Get-Devices will only contain the method + name followed by two slashes ("method://"). It is up to the client + application to add the appropriate host and other information when + adding a new printer.

                              +

                              The URI returned by Get-Printer-Attributes and CUPS-Get-Printers has + any username and password information stripped; the information is + still stored and used by the server internally to perform any needed + authentication.

                            5.2 Job Template Attributes

                            5.2.1 blackplot (boolean)

                            -

                            The blackplot attribute specifies whether HP-GL/2 plot files should -be rendered entirely in black ink (blackplot=true) or using the colors -and shades specified in the file (blackplot=false). The default value -is false.

                            +

                            The blackplot attribute specifies whether HP-GL/2 plot files should + be rendered entirely in black ink (blackplot=true) or using the colors + and shades specified in the file (blackplot=false). The default value + is false.

                            5.2.2 brightness (integer(0:200))

                            -

                            The brightness attribute specifies the overall brightness of the -printed output in percent. A brightness of 100 is normal, while 200 is -twice as bright and 50 is half as bright. The default value is 100.

                            -

                            Brightness is applied to the Cyan, Magenta, Yellow, and Black values -using the function "f(x) = brightness / 100 * x".

                            +

                            The brightness attribute specifies the overall brightness of the + printed output in percent. A brightness of 100 is normal, while 200 is + twice as bright and 50 is half as bright. The default value is 100.

                            +

                            Brightness is applied to the Cyan, Magenta, Yellow, and Black values + using the function "f(x) = brightness / 100 * x".

                            5.2.3 columns (integer(1:4))

                            -

                            The columns attribute specifies the number of columns to generate -when printing text files. The default value is 1.

                            +

                            The columns attribute specifies the number of columns to generate + when printing text files. The default value is 1.

                            5.2.4 cpi (type2 enum)

                            -

                            The cpi attribute specifies the number of characters per inch when -printing text files. Only the values 10, 12, and 17 are currently -supported. The default value is 10.

                            +

                            The cpi attribute specifies the number of characters per inch when + printing text files. Only the values 10, 12, and 17 are currently + supported. The default value is 10.

                            5.2.5 fitplot (boolean)

                            -

                            The fitplot attribute specifies whether to scale HP-GL/2 plot files -to fit on the selected media (fitplot=true) or use the physical scale -specified in the plot file (fitplot=false). The default value is false.

                            +

                            The fitplot attribute specifies whether to scale HP-GL/2 plot files + to fit on the selected media (fitplot=true) or use the physical scale + specified in the plot file (fitplot=false). The default value is false.

                            5.2.6 gamma (integer(1:10000))

                            -

                            The gamma attribute specifies the luminance correction for the -output. A value of 1000 specifies no correction, while values of 2000 -and 500 will generate lighter and darker output, respectively. The -default value is 1000.

                            -

                            Gamma is applied to the Red, Green, and Blue values (or luminance -for grayscale output) using the function "f(x) = x(1000/gamma) -".

                            +

                            The gamma attribute specifies the luminance correction for the + output. A value of 1000 specifies no correction, while values of 2000 + and 500 will generate lighter and darker output, respectively. The + default value is 1000.

                            +

                            Gamma is applied to the Red, Green, and Blue values (or luminance for + grayscale output) using the function "f(x) = x(1000/gamma)".

                            5.2.7 hue (integer(-180:180))

                            -

                            The hue attribute specifies a color hue rotation when printing image -files. The default value is 0.

                            +

                            The hue attribute specifies a color hue rotation when printing image + files. The default value is 0.

                            5.2.8 job-billing (text(MAX))

                            (CUPS 1.1 and higher)

                            -

                            The job-billing attribute provides a text value to associate with a -job for billing purposes.

                            +

                            The job-billing attribute provides a text value to associate with a + job for billing purposes.

                            5.2.9 job-hold-until (keyword | name(MAX))

                            (CUPS 1.1 and higher)

                            -

                            The job-hold-until attribute specifies a hold time. In addition to -the standard IPP/1.1 keyword names, CUPS supports name values of the -form "HH:MM" and "HH:MM:SS" that specify a hold time. The hold time is -in Greenwich Mean Time (GMT) and not in the local time zone. If -the specified time is less than the current time, the job is held until -the next day.

                            -

                            5.2.10 job-sheets (1setof type3 keyword | -name(MAX))

                            +

                            The job-hold-until attribute specifies a hold time. In addition to + the standard IPP/1.1 keyword names, CUPS supports name values of the + form "HH:MM" and "HH:MM:SS" that specify a hold time. The hold time is + in Greenwich Mean Time (GMT) and not in the local time zone. If + the specified time is less than the current time, the job is held until + the next day.

                            +

                            5.2.10 job-sheets (1setof type3 keyword | + name(MAX))

                            (CUPS 1.1 and higher)

                            -

                            The job-sheets attribute specifies one or two banner files that are -printed before and after a job. The reserved value of "none" disables -banner printing. The default value is stored in the job-sheets-default -attribute.

                            -

                            If only one value is supplied, the banner file is printed before the -job. If two values are supplied, the first value is used as the -starting banner file and the second as the ending banner file.

                            +

                            The job-sheets attribute specifies one or two banner files that are + printed before and after a job. The reserved value of "none" disables + banner printing. The default value is stored in the job-sheets-default + attribute.

                            +

                            If only one value is supplied, the banner file is printed before the + job. If two values are supplied, the first value is used as the + starting banner file and the second as the ending banner file.

                            5.2.11 job-originating-host-name (name(MAX))

                            (CUPS 1.1.5 and higher)

                            -

                            The job-originating-host-name attribute specifies the host from -which the job was queued. The value will be the hostname or IP address -of the client depending on whether hostname resolution is enabled. The -localhost address (127.0.0.1) is always resolved to the name -"localhost".

                            -

                            This attribute is read-only.

                            +

                            The job-originating-host-name attribute specifies the host from which + the job was queued. The value will be the hostname or IP address of the + client depending on whether hostname resolution is enabled. The + localhost address (127.0.0.1) is always resolved to the name + "localhost".

                            +

                            This attribute is read-only.

                            5.2.12 lpi (type2 enum)

                            -

                            The lpi attribute specifies the number of lines per inch when -printing text files. Only the values 6 and 8 are currently supported. -The default value is 6.

                            -

                            5.2.13 page-bottom (integer(0:MAX))

                            -

                            The page-bottom attribute specifies the bottom margin in points (72 -points equals 1 inch). The default value is the device physical margin.

                            -

                            5.2.14 page-label (text(MAX))

                            +

                            The lpi attribute specifies the number of lines per inch when + printing text files. Only the values 6 and 8 are currently supported. + The default value is 6.

                            +

                            5.2.13 natural-scaling (integer(1:1000))

                            +

                            (CUPS 1.1.9 and higher)

                            +

                            The natural-scaling attribute specifies the scaling of image files + with respect to the natural image size. A value of 100 specifies that + the image file should exactly the natural size, while 50 is half the + natural size and 200 is twice the natural size. The default value is + 100.

                            +

                            The ppi option can be used to override the natural resolution of the + image, which controls the natural size.

                            +

                            5.2.14 page-bottom (integer(0:MAX))

                            +

                            The page-bottom attribute specifies the bottom margin in points (72 + points equals 1 inch). The default value is the device physical margin.

                            +

                            5.2.15 page-label (text(MAX))

                            (CUPS 1.1.7 and higher)

                            -

                            The page-label attribute provides a text value to place in the -header and footer on each page. If a classification level is set on the -server, then this classification is printed before the page label.

                            -

                            5.2.15 page-left (integer(0:MAX))

                            -

                            The page-left attribute specifies the left margin in points (72 -points equals 1 inch). The default value is the device physical margin.

                            -

                            5.2.16 page-right (integer(0:MAX))

                            -

                            The page-right attribute specifies the right margin in points (72 -points equals 1 inch). The default value is the device physical margin.

                            -

                            5.2.17 page-set (type2 keyword)

                            -

                            The page-set attribute specifies which pages to print in a file. The -supported keywords are "all", "even", and "odd". The default value is -"all".

                            -

                            5.2.18 page-top (integer(0:MAX))

                            -

                            The page-top attribute specifies the top margin in points (72 points -equals 1 inch). The default value is the device physical margin.

                            -

                            5.2.19 penwidth (integer(0:MAX))

                            -

                            The penwidth attribute specifies the default pen width in -micrometers when printing HP-GL/2 plot files. The default value is 1000 -(1 millimeter).

                            -

                            5.2.20 position (type2 keyword)

                            -

                            The position attribute specifies the location of image files on the -media. The following keyword values are recognized:

                            -
                              -
                            • center - Center the image on the page (default)
                            • -
                            • top - Print the image centered at the top of the page
                            • -
                            • left - Print the image centered on the left of page
                            • -
                            • right - Print the image centered on the right of the -page
                            • -
                            • top-left - Print the image at the top left corner of - the page
                            • -
                            • top-right - Print the image at the top right corner of - the page
                            • -
                            • bottom - Print the image centered at the bottom of - the page
                            • -
                            • bottom-left - Print the image at the bottom left - corner of the page
                            • -
                            • bottom-right - Print the image at the bottom right - corner of the page
                            • -
                            -

                            5.2.21 ppi (integer(1:MAX))

                            -

                            The ppi attribute specifies the resolution of an image file in -pixels per inch. The default value is the resolution included with the -file or 128 if no resolution information is available.

                            -

                            5.2.22 prettyprint (boolean)

                            -

                            The prettyprint attribute specifies whether text files should be -printed with a shaded header and keyword highlighting -(prettyprint=true) or without additional formatting -(prettyprint=false). The default value is false.

                            -

                            5.2.23 saturation (integer(0:200))

                            -

                            The saturation attribute specifies the color saturation when -printing image files. A saturation of 100 is normal, while values of 50 -and 200 will be half and twice as colorful, respectively. The default -value is 100.

                            -

                            5.2.24 scaling (integer(1:1000))

                            -

                            The scaling attribute specifies the scaling of image files with -respect to the selected media. A value of 100 specifies that the image -file should fit 100% of the page, or as much as possible given the -image dimensions. The default value is unspecified.

                            -

                            The scaling attribute overrides the ppi attribute if specified.

                            -

                            5.2.25 wrap (boolean)

                            -

                            The wrap attribute specifies whether long lines should be wrapped -(wrap=true) or not (wrap=false) when printing text files. The default -value is true.

                            +

                            The page-label attribute provides a text value to place in the header + and footer on each page. If a classification level is set on the + server, then this classification is printed before the page label.

                            +

                            5.2.16 page-left (integer(0:MAX))

                            +

                            The page-left attribute specifies the left margin in points (72 + points equals 1 inch). The default value is the device physical margin.

                            +

                            5.2.17 page-right (integer(0:MAX))

                            +

                            The page-right attribute specifies the right margin in points (72 + points equals 1 inch). The default value is the device physical margin.

                            +

                            5.2.18 page-set (type2 keyword)

                            +

                            The page-set attribute specifies which pages to print in a file. The + supported keywords are "all", "even", and "odd". The default value is + "all".

                            +

                            5.2.19 page-top (integer(0:MAX))

                            +

                            The page-top attribute specifies the top margin in points (72 points + equals 1 inch). The default value is the device physical margin.

                            +

                            5.2.20 penwidth (integer(0:MAX))

                            +

                            The penwidth attribute specifies the default pen width in micrometers + when printing HP-GL/2 plot files. The default value is 1000 (1 + millimeter).

                            +

                            5.2.21 position (type2 keyword)

                            +

                            The position attribute specifies the location of image files on the + media. The following keyword values are recognized:

                            +
                              +
                            • center - Center the image on the page (default)
                            • +
                            • top - Print the image centered at the top of the page
                            • +
                            • left - Print the image centered on the left of page
                            • +
                            • right - Print the image centered on the right of the + page
                            • +
                            • top-left - Print the image at the top left corner of + the page
                            • +
                            • top-right - Print the image at the top right corner of + the page
                            • +
                            • bottom - Print the image centered at the bottom of the + page
                            • +
                            • bottom-left - Print the image at the bottom left corner + of the page
                            • +
                            • bottom-right - Print the image at the bottom right + corner of the page
                            • +
                            +

                            5.2.22 ppi (integer(1:MAX))

                            +

                            The ppi attribute specifies the resolution of an image file in pixels + per inch. The default value is the resolution included with the file or + 128 if no resolution information is available.

                            +

                            5.2.23 prettyprint (boolean)

                            +

                            The prettyprint attribute specifies whether text files should be + printed with a shaded header and keyword highlighting + (prettyprint=true) or without additional formatting + (prettyprint=false). The default value is false.

                            +

                            5.2.24 saturation (integer(0:200))

                            +

                            The saturation attribute specifies the color saturation when printing + image files. A saturation of 100 is normal, while values of 50 and 200 + will be half and twice as colorful, respectively. The default value is + 100.

                            +

                            5.2.25 scaling (integer(1:1000))

                            +

                            The scaling attribute specifies the scaling of image files with + respect to the selected media. A value of 100 specifies that the image + file should fit 100% of the page, or as much as possible given the + image dimensions. The default value is unspecified.

                            +

                            The scaling attribute overrides the ppi attribute if specified.

                            +

                            5.2.26 wrap (boolean)

                            +

                            The wrap attribute specifies whether long lines should be wrapped + (wrap=true) or not (wrap=false) when printing text files. The default + value is true.

                            5.3 PPD Attributes

                            5.3.1 ppd-natural-language (naturalLanguage)

                            -

                            The ppd-natural-language attribute specifies the language encoding -of the PPD file (the LanguageVersion attribute in the PPD file). If the -language is unknown or undefined then "en" (English) is assumed.

                            +

                            The ppd-natural-language attribute specifies the language encoding of + the PPD file (the LanguageVersion attribute in the PPD file). If the + language is unknown or undefined then "en" (English) is assumed.

                            5.3.2 ppd-make (text(127))

                            -

                            The ppd-make attribute specifies the manufacturer of the printer -(the Manufacturer attribute in the PPD file). If the manufacturer is -not specified in the PPD file then an educated guess is made using the -NickName attribute in the PPD file.

                            +

                            The ppd-make attribute specifies the manufacturer of the printer (the + Manufacturer attribute in the PPD file). If the manufacturer is not + specified in the PPD file then an educated guess is made using the + NickName attribute in the PPD file.

                            5.3.3 ppd-make-and-model (text(127))

                            -

                            The ppd-make-and-model attribute specifies the manufacturer and -model name of the PPD file (the NickName attribute in the PPD file). If -the make and model is not specified in the PPD file then the ModelName -or ShortNickName attributes are used instead.

                            +

                            The ppd-make-and-model attribute specifies the manufacturer and model + name of the PPD file (the NickName attribute in the PPD file). If the + make and model is not specified in the PPD file then the ModelName or + ShortNickName attributes are used instead.

                            5.3.4 ppd-name (name(255))

                            -

                            The ppd-name attribute specifies the PPD filename on the server -relative to the model directory. The forward slash (/) is used to -delineate directories.

                            +

                            The ppd-name attribute specifies the PPD filename on the server + relative to the model directory. The forward slash (/) is used to + delineate directories.

                            5.4 Printer Attributes

                            5.4.1 job-k-limit (integer)

                            (CUPS 1.1 and higher)

                            -

                            The job-k-limit attribute specifies the maximum number of kilobytes -that may be printed by a user, including banner files. The default -value of 0 specifies that there is no limit.

                            +

                            The job-k-limit attribute specifies the maximum number of kilobytes + that may be printed by a user, including banner files. The default + value of 0 specifies that there is no limit.

                            5.4.2 job-page-limit (integer)

                            (CUPS 1.1 and higher)

                            -

                            The job-page-limit attribute specifies the maximum number of pages -that may be printed by a user, including banner files. The default -value of 0 specifies that there is no limit.

                            +

                            The job-page-limit attribute specifies the maximum number of pages + that may be printed by a user, including banner files. The default + value of 0 specifies that there is no limit.

                            5.4.3 job-quota-period (integer)

                            (CUPS 1.1 and higher)

                            -

                            The job-quota-period attribute specifies the time period used for -quota calculations, in seconds. The default value of 0 specifies that -the limits apply to all jobs that have been printed by a user that are -still known to the system.

                            -

                            5.4.4 job-sheets-supported (1setof type3 keyword | -name(MAX))

                            +

                            The job-quota-period attribute specifies the time period used for + quota calculations, in seconds. The default value of 0 specifies that + the limits apply to all jobs that have been printed by a user that are + still known to the system.

                            +

                            5.4.4 job-sheets-supported (1setof type3 keyword | + name(MAX))

                            (CUPS 1.1 and higher)

                            -

                            The job-sheets-supported attribute specifies the available banner -files. There will always be at least one banner file available called -"none".

                            +

                            The job-sheets-supported attribute specifies the available banner + files. There will always be at least one banner file available called + "none".

                            5.4.5 printer-type (type2 enum)

                            -

                            The printer-type attribute specifies printer type and capability -bits for the printer or class. The default value is computed from -internal state information and the PPD file for the printer. The -following bits are defined: +

                            The printer-type attribute specifies printer type and capability bits + for the printer or class. The default value is computed from internal + state information and the PPD file for the printer. The following bits + are defined:

        Operation NameCUPS @@ -368,971 +369,978 @@ VALIGN="TOP">0x4004Delete a printer.
        - + - + - - + + @@ -1341,94 +1349,94 @@ collation in hardware. - - - - - + + + + +
        BitDescription
        0x00000001Is a printer class.
        0x00000002Is a remote -destination.
        0x00000002Is a remote + destination.
        0x00000004Can print in black.
        0x00000008Can print in color.
        0x00000010Can print on both -sides of the page in hardware.
        0x00000010Can print on both + sides of the page in hardware.
        0x00000020Can staple output.
        0x00000040Can do fast copies -in hardware.
        0x00000080Can do fast copy -collation in hardware.
        0x00000040Can do fast copies + in hardware.
        0x00000080Can do fast copy + collation in hardware.
        0x00000100Can punch output.
        0x00000200Can cover output.
        0x00000800Can sort output.
        0x00001000Can handle media -up to US-Legal/A4.
        0x00002000Can handle media -from US-Legal/A4 to ISO-C/A2.
        0x00004000Can handle media -larger than ISO-C/A2.
        0x00008000Can handle -user-defined media sizes.
        0x00010000Is an implicit -(server-generated) class.
        0x00001000Can handle media up + to US-Legal/A4.
        0x00002000Can handle media + from US-Legal/A4 to ISO-C/A2.
        0x00004000Can handle media + larger than ISO-C/A2.
        0x00008000Can handle + user-defined media sizes.
        0x00010000Is an implicit + (server-generated) class.

        5.4.6 printer-type-mask (type2 enum)

        (CUPS 1.1 and higher)

        -

        The printer-type-mask attribute is used to choose printers or -classes with the CUPS-Get-Printers and CUPS-Get-Classes operations. The -bits are defined identically to the printer-type attribute and default -to all 1's.

        -

        5.4.7 requesting-user-name-allowed (1setof -name(127))

        +

        The printer-type-mask attribute is used to choose printers or classes + with the CUPS-Get-Printers and CUPS-Get-Classes operations. The bits + are defined identically to the printer-type attribute and default to + all 1's.

        +

        5.4.7 requesting-user-name-allowed (1setof + name(127))

        (CUPS 1.1 and higher)

        -

        The requesting-user-name-allowed attribute lists all of the users -that are allowed to access a printer or class. Either this attribute or -the requesting-user-name-denied attribute will be defined, but not -both.

        +

        The requesting-user-name-allowed attribute lists all of the users + that are allowed to access a printer or class. Either this attribute or + the requesting-user-name-denied attribute will be defined, but not + both.

        5.4.8 requesting-user-name-denied (1setof name(127))

        (CUPS 1.1 and higher)

        -

        The requesting-user-name-denied attribute lists all of the users -that are not allowed to access a printer or class. Either this -attribute or the requesting-user-name-allowed attribute will be -defined, but not both.

        +

        The requesting-user-name-denied attribute lists all of the users that + are not allowed to access a printer or class. Either this attribute or + the requesting-user-name-allowed attribute will be defined, but not + both.

        5.5 Printer Class Attributes

        5.5.1 member-names (1setof name(127))

        -

        The member-names attribute specifies each of the printer-name -attributes of the member printers and classes. Each name corresponds to -the same element of the member-uris attribute.

        +

        The member-names attribute specifies each of the printer-name + attributes of the member printers and classes. Each name corresponds to + the same element of the member-uris attribute.

        5.5.2 member-uris (1setof uri)

        -

        The member-uris attribute specifies each of the printer-uri -attributes of the member printers and classes. Each URI corresponds to -the same element of the member-names attribute.

        +

        The member-uris attribute specifies each of the printer-uri + attributes of the member printers and classes. Each URI corresponds to + the same element of the member-names attribute.

        A Glossary

        A.1 Terms

        -
        C
        -
        A computer language.
        -
        parallel
        -
        Sending or receiving data more than 1 bit at a time.
        -
        pipe
        -
        A one-way communications channel between two programs.
        -
        serial
        -
        Sending or receiving data 1 bit at a time.
        -
        socket
        -
        A two-way network communications channel.
        +
        C
        +
        A computer language.
        +
        parallel
        +
        Sending or receiving data more than 1 bit at a time.
        +
        pipe
        +
        A one-way communications channel between two programs.
        +
        serial
        +
        Sending or receiving data 1 bit at a time.
        +
        socket
        +
        A two-way network communications channel.

        A.2 Acronyms

        -
        ASCII
        -
        American Standard Code for Information Interchange
        -
        CUPS
        -
        Common UNIX Printing System
        -
        ESC/P
        -
        EPSON Standard Code for Printers
        -
        FTP
        -
        File Transfer Protocol
        -
        HP-GL
        -
        Hewlett-Packard Graphics Language
        -
        HP-PCL
        -
        Hewlett-Packard Page Control Language
        -
        HP-PJL
        -
        Hewlett-Packard Printer Job Language
        -
        IETF
        -
        Internet Engineering Task Force
        -
        IPP
        -
        Internet Printing Protocol
        -
        ISO
        -
        International Standards Organization
        -
        LPD
        -
        Line Printer Daemon
        -
        MIME
        -
        Multimedia Internet Mail Exchange
        -
        PPD
        -
        PostScript Printer Description
        -
        SMB
        -
        Server Message Block
        -
        TFTP
        -
        Trivial File Transfer Protocol
        +
        ASCII
        +
        American Standard Code for Information Interchange
        +
        CUPS
        +
        Common UNIX Printing System
        +
        ESC/P
        +
        EPSON Standard Code for Printers
        +
        FTP
        +
        File Transfer Protocol
        +
        HP-GL
        +
        Hewlett-Packard Graphics Language
        +
        HP-PCL
        +
        Hewlett-Packard Page Control Language
        +
        HP-PJL
        +
        Hewlett-Packard Printer Job Language
        +
        IETF
        +
        Internet Engineering Task Force
        +
        IPP
        +
        Internet Printing Protocol
        +
        ISO
        +
        International Standards Organization
        +
        LPD
        +
        Line Printer Daemon
        +
        MIME
        +
        Multimedia Internet Mail Exchange
        +
        PPD
        +
        PostScript Printer Description
        +
        SMB
        +
        Server Message Block
        +
        TFTP
        +
        Trivial File Transfer Protocol
        diff --git a/doc/ipp.pdf b/doc/ipp.pdf index 4036884ec9..c41d324c40 100644 Binary files a/doc/ipp.pdf and b/doc/ipp.pdf differ diff --git a/doc/ipp.shtml b/doc/ipp.shtml index a08063b0bb..f7fc33d04e 100644 --- a/doc/ipp.shtml +++ b/doc/ipp.shtml @@ -1633,6 +1633,18 @@ resolution is enabled. The localhost address (127.0.0.1) is printing text files. Only the values 6 and 8 are currently supported. The default value is 6. +

        natural-scaling (integer(1:1000))

        + +

        (CUPS 1.1.9 and higher) + +

        The natural-scaling attribute specifies the scaling of image files with +respect to the natural image size. A value of 100 specifies that the image +file should exactly the natural size, while 50 is half the natural size +and 200 is twice the natural size. The default value is 100. + +

        The ppi option can be used to override the natural resolution of the +image, which controls the natural size. +

        page-bottom (integer(0:MAX))

        The page-bottom attribute specifies the bottom margin in points (72 points diff --git a/doc/overview.pdf b/doc/overview.pdf index 20259176fa..37fb88810b 100644 Binary files a/doc/overview.pdf and b/doc/overview.pdf differ diff --git a/doc/sam.html b/doc/sam.html index 5a45b1dace..1f133b40c7 100644 --- a/doc/sam.html +++ b/doc/sam.html @@ -119,11 +119,13 @@ Copyright 1997-2001, All Rights Reserved

      • BrowseInterval
      • BrowsePoll
      • BrowsePort
      • +
      • BrowseProtocols
      • BrowseRelay
      • BrowseShortNames
      • BrowseTimeout
      • Browsing
      • Classification
      • +
      • ClassifyOverride
      • DataDir
      • DefaultCharset
      • DefaultLanguage
      • @@ -134,8 +136,11 @@ Copyright 1997-2001, All Rights Reserved
      • FilterLimit
      • FontPath
      • Group
      • +
      • HideImplicitMembers
      • HostNameLookups
      • ImplicitClasses
      • +
      • ImplicitAnyClasses
      • +
      • Include
      • KeepAlive
      • KeepAliveTimeout
      • Limit
      • @@ -252,8 +257,8 @@ Copyright 1997-2001, All Rights Reserved

        Preface

        -

        This software administrators manual provides printer administration -information for the Common UNIX Printing SystemTM ("CUPS -TM"), version 1.1.7.

        +

        This software administrators manual provides printer administration + information for the Common UNIX Printing SystemTM <<<<<<< + sam.shtml ("CUPSTM"), version 1.1.7. ======= ("CUPSTM +"), version 1.1.13. >>>>>>> 1.48

        System Overview

        -

        CUPS provides a portable printing layer for UNIX®-based operating -systems. It has been developed by Easy -Software Products to promote a standard printing solution for all -UNIX vendors and users. CUPS provides the System V and Berkeley -command-line interfaces.

        -

        CUPS uses the Internet Printing Protocol ("IPP") as the basis for -managing print jobs and queues. The Line Printer Daemon ("LPD") Server -Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are -also supported with reduced functionality. CUPS adds network printer -browsing and PostScript Printer Description ("PPD") based printing -options to support real-world printing under UNIX.

        -

        CUPS also includes a customized version of GNU Ghostscript -(currently based off GNU Ghostscript 5.50) and an image file RIP that -are used to support non-PostScript printers. Sample drivers for HP and -EPSON printers are included that use these filters.

        +

        CUPS provides a portable printing layer for UNIX®-based operating + systems. It has been developed by Easy + Software Products to promote a standard printing solution for all + UNIX vendors and users. CUPS provides the System V and Berkeley + command-line interfaces.

        +

        CUPS uses the Internet Printing Protocol ("IPP") as the basis for + managing print jobs and queues. The Line Printer Daemon ("LPD") Server + Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are + also supported with reduced functionality. CUPS adds network printer + browsing and PostScript Printer Description ("PPD") based printing + options to support real-world printing under UNIX.

        +

        CUPS also includes a customized version of GNU Ghostscript (currently + based off GNU Ghostscript 5.50) and an image file RIP that are used to + support non-PostScript printers. Sample drivers for HP and EPSON + printers are included that use these filters.

        Document Overview

        -

        This software administrators manual is organized into the following -sections:

        +

        This software administrators manual is organized into the following + sections:

        Notation Conventions

        -

        Various font and syntax conventions are used in this guide. Examples -and their meanings and uses are explained below: +

        Various font and syntax conventions are used in this guide. Examples + and their meanings and uses are explained below:

        +
        lpstat(1)     - +
        Example   Description
         
        lpstat -
        lpstat(1)
           The names of commands; -the first mention of a command or function in a chapter is followed by -a manual page section number.
           The names of commands; + the first mention of a command or function in a chapter is followed by + a manual page section number.
         
        /var
        /usr/share/cups/data/testprint.ps
            @@ -319,204 +325,206 @@ File and directory names.
        Screen output.
         
        lp -d printer filename ENTER -   Literal user input; special keys like ENTER are +   Literal user input; special keys like ENTER are in ALL CAPS.
         
        12.3   Numbers in the text are -written using the period (.) to indicate the decimal point.
        12.3   Numbers in the text are + written using the period (.) to indicate the decimal point.

        Abbreviations

        - The following abbreviations are used throughout this manual: + The following abbreviations are used throughout this manual:
          -
          kb
          +
          kb
          Kilobytes, or 1024 bytes -
           
          -
          Mb
          +
            +
          Mb
          Megabytes, or 1048576 bytes -
           
          -
          Gb
          +
            +
          Gb
          Gigabytes, or 1073741824 bytes -
           
          +
           

        Other References

          -
          CUPS Software Programmers Manual
          -
          A programmer guide for interfacing with and/or extending the CUPS +
          CUPS Software Programmers Manual
          +
          A programmer guide for interfacing with and/or extending the CUPS software. -
           
          -
          CUPS Software Users Manual
          +
            +
          CUPS Software Users Manual
          An end-user guide for using the CUPS software. -
           
          +
           

        1 - Printing System Overview

        -

        This chapter provides an overview of how the Common UNIX Printing -System works.

        +

        This chapter provides an overview of how the Common UNIX Printing + System works.

        The Printing Problem

        -

        For years the printing problem has plagued UNIX. Unlike -Microsoft® Windows® or Mac OS, UNIX has no standard interface or system -in place for supporting printers. Among the solutions currently -available, the Berkeley and System V printing systems are the most -prevalent.

        -

        These printing systems support line printers (text only) or -PostScript printers (text and graphics), and with some coaxing they can -be made to support a full range of printers and file formats. However, -because each varient of the UNIX operating system uses a different -printing system than the next developing printer drivers for a wide -range of printers and operating systems is extremely difficult. That -combined with the limited volume of customers for each UNIX varient has -forced most printer vendors to give up supporting UNIX entirely.

        -

        CUPS is designed to eliminate the printing problem. One -common printing system can be used by all UNIX varients to support the -printing needs of users. Printer vendors can use its modular filter -interface to develop a single driver program that supports a wide range -of file formats with little or no effort. Since CUPS provides both the -System V and Berkeley printing commands, users (and applications) can -reap the benefits of this new technology with no changes.

        +

        For years the printing problem has plagued UNIX. Unlike + Microsoft® Windows® or Mac OS, UNIX has no standard interface or system + in place for supporting printers. Among the solutions currently + available, the Berkeley and System V printing systems are the most + prevalent.

        +

        These printing systems support line printers (text only) or + PostScript printers (text and graphics), and with some coaxing they can + be made to support a full range of printers and file formats. However, + because each varient of the UNIX operating system uses a different + printing system than the next developing printer drivers for a wide + range of printers and operating systems is extremely difficult. That + combined with the limited volume of customers for each UNIX varient has + forced most printer vendors to give up supporting UNIX entirely.

        +

        CUPS is designed to eliminate the printing problem. One common + printing system can be used by all UNIX varients to support the + printing needs of users. Printer vendors can use its modular filter + interface to develop a single driver program that supports a wide range + of file formats with little or no effort. Since CUPS provides both the + System V and Berkeley printing commands, users (and applications) can + reap the benefits of this new technology with no changes.

        The Technology

        -

        CUPS is based upon an emerging Internet standard called the Internet -Printing Protocol. IPP has been embraced by dozens of printer and -printer server manufacturers and is supported by Microsoft Windows -2000.

        -

        IPP defines a standard protocol for printing as well as managing -print jobs and printer options like media size, resolution, and so -forth. Like all IP-based protocols, IPP can be used locally or over the -Internet to printers hundreds or thousands of miles away. Unlike other -protocols, however, IPP also supports access control, authentication, -and encryption, making it a much more capable and secure printing -solution than older ones.

        -

        IPP is layered on top of the Hyper-Text Transport Protocol ("HTTP") -which is the basis of web servers on the Internet. This allows users to -view documentation, check status information on a printer or server, -and manage their printers, classes, and jobs using their web browser.

        -

        CUPS provides a complete IPP/1.1 based printing system that provides -Basic, Digest, and local certificate authentication and user, domain, -or IP-based access control. TLS encryption will be available in future -versions of CUPS.

        +

        CUPS is based upon an emerging Internet standard called the Internet + Printing Protocol. IPP has been embraced by dozens of printer and + printer server manufacturers and is supported by Microsoft Windows + 2000.

        +

        IPP defines a standard protocol for printing as well as managing + print jobs and printer options like media size, resolution, and so + forth. Like all IP-based protocols, IPP can be used locally or over the + Internet to printers hundreds or thousands of miles away. Unlike other + protocols, however, IPP also supports access control, authentication, + and encryption, making it a much more capable and secure printing + solution than older ones.

        +

        IPP is layered on top of the Hyper-Text Transport Protocol ("HTTP") + which is the basis of web servers on the Internet. This allows users to + view documentation, check status information on a printer or server, + and manage their printers, classes, and jobs using their web browser.

        +

        CUPS provides a complete IPP/1.1 based printing system that provides + Basic, Digest, and local certificate authentication and user, domain, + or IP-based access control. TLS encryption will be available in future + versions of CUPS.

        Jobs

        -

        Each file or set of files that is submitted for printing is called a -job. Jobs are identified by a unique number starting at 1 and are -assigned to a particular destination, usually a printer. Jobs can also -have options associated with them such as media size, number of copies, -and priority.

        +

        Each file or set of files that is submitted for printing is called a + job. Jobs are identified by a unique number starting at 1 and are + assigned to a particular destination, usually a printer. Jobs can also + have options associated with them such as media size, number of copies, + and priority.

        Classes

        -

        CUPS supports collections of printers known as classes. Jobs -sent to a class are forwarded to the first available printer in the -class.

        +

        CUPS supports collections of printers known as classes. Jobs + sent to a class are forwarded to the first available printer in the + class.

        Filters

        -

        Filters allow a user or application to print many types of files -without extra effort. Print jobs sent to a CUPS server are filtered -before sending them to a printer. Some filters convert job files to -different formats that the printer can understand. Others perform page -selection and ordering tasks.

        -

        CUPS provides filters for printing many types of image files, -HP-GL/2 files, PDF files, and text files. CUPS also supplies PostScript -and image file Raster Image Processor ("RIP") filters that convert -PostScript or image files into bitmaps that can be sent to a raster -printer.

        +

        Filters allow a user or application to print many types of files + without extra effort. Print jobs sent to a CUPS server are filtered + before sending them to a printer. Some filters convert job files to + different formats that the printer can understand. Others perform page + selection and ordering tasks.

        +

        CUPS provides filters for printing many types of image files, HP-GL/2 + files, PDF files, and text files. CUPS also supplies PostScript and + image file Raster Image Processor ("RIP") filters that convert + PostScript or image files into bitmaps that can be sent to a raster + printer.

        Backends

        -

        Backends perform the most important task of all - they send the -filtered print data to the printer.

        -

        CUPS provides backends for printing over parallel, serial, and USB -ports, and over the network via the IPP, JetDirect (AppSocket), and -Line Printer Daemon ("LPD") protocols. Additional backends are -available in network service packages such as the SMB backend included -with the popular SAMBA software.

        -

        Backends are also used to determine the available devices. On -startup each backend is asked for a list of devices it supports, and -any information that is available. This allows the parallel backend to -tell CUPS that an EPSON Stylus Color 600 printer is attached to -parallel port 1, for example.

        +

        Backends perform the most important task of all - they send the + filtered print data to the printer.

        +

        CUPS provides backends for printing over parallel, serial, and USB + ports, and over the network via the IPP, JetDirect (AppSocket), and + Line Printer Daemon ("LPD") protocols. Additional backends are + available in network service packages such as the SMB backend included + with the popular SAMBA software.

        +

        Backends are also used to determine the available devices. On startup + each backend is asked for a list of devices it supports, and any + information that is available. This allows the parallel backend to tell + CUPS that an EPSON Stylus Color 600 printer is attached to parallel + port 1, for example.

        Printer Drivers

        -

        Printer drivers in CUPS consist of one of more filters specific to a -printer. CUPS includes sample printer drivers for Hewlett-Packard -LaserJet and DeskJet printers and EPSON 9-pin, 24-pin, Stylus Color, -and Stylus Photo printers. While these drivers do not generate optimal -output for the different printer models, they do provide basic printing -and demonstrate how you can write your own printer drivers and -incorporate them into CUPS.

        +

        Printer drivers in CUPS consist of one of more filters specific to a + printer. CUPS includes sample printer drivers for Hewlett-Packard + LaserJet and DeskJet printers and EPSON 9-pin, 24-pin, Stylus Color, + and Stylus Photo printers. While these drivers do not generate optimal + output for the different printer models, they do provide basic printing + and demonstrate how you can write your own printer drivers and + incorporate them into CUPS.

        Networking

        -

        Printers and classes on the local system are automatically shared -with other systems on the network. This allows you to setup one system -to print to a printer and use this system as a printer server or spool -host for all of the others. Users may then select a local printer by -name or a remote printer using "name@server".

        -

        CUPS also provides implicit classes, which are collections of -printers and/or classes with the same name. This allows you to setup -multiple servers pointing to the same physical network printer, for -example, so that you aren't relying on a single system for printing. -Because this also works with printer classes, you can setup multiple -servers and printers and never worry about a single point of failure -unless all of the printers and servers go down!

        -

        2 - Building and -Installing CUPS

        -

        This chapter shows how to build and install the Common UNIX Printing -System. If you are installing a binary distribution from the CUPS web -site, proceed to the section titled, Installing a -Binary Distribution.

        +

        Printers and classes on the local system are automatically shared + with other systems on the network. This allows you to setup one system + to print to a printer and use this system as a printer server or spool + host for all of the others. Users may then select a local printer by + name or a remote printer using "name@server".

        +

        CUPS also provides implicit classes, which are collections of + printers and/or classes with the same name. This allows you to setup + multiple servers pointing to the same physical network printer, for + example, so that you aren't relying on a single system for printing. + Because this also works with printer classes, you can setup multiple + servers and printers and never worry about a single point of failure + unless all of the printers and servers go down!

        +

        2 - Building and + Installing CUPS

        +

        This chapter shows how to build and install the Common UNIX Printing + System. If you are installing a binary distribution from the CUPS web + site, proceed to the section titled, Installing a + Binary Distribution.

        Installing a Source Distribution

        -

        This section describes how to compile and install CUPS on your -system from the source code.

        +

        This section describes how to compile and install CUPS on your system + from the source code.

        Requirements

        -

        You'll need ANSI-compliant C and C++ compilers to build CUPS on your -system. As its name implies, CUPS is designed to run on the UNIX -operating system, however the CUPS interface library and most of the -filters and backends supplied with CUPS should also compile and run -under Microsoft Windows.

        -

        For the image file filters and PostScript RIP, you'll need the JPEG, -PNG, TIFF, and ZLIB libraries. CUPS will build without these, but with -significantly reduced functionality. Easy Software Products maintains a -mirror of the current versions of these libraries at:

        +

        You'll need ANSI-compliant C and C++ compilers to build CUPS on your + system. As its name implies, CUPS is designed to run on the UNIX + operating system, however the CUPS interface library and most of the + filters and backends supplied with CUPS should also compile and run + under Microsoft Windows.

        +

        For the image file filters and PostScript RIP, you'll need the JPEG, + PNG, TIFF, and ZLIB libraries. CUPS will build without these, but with + significantly reduced functionality. Easy Software Products maintains a + mirror of the current versions of these libraries at:

        -

        If you make changes to the man pages you'll need GNU groff or -another nroff-like package. GNU groff is available from:

        +

        If you make changes to the man pages you'll need GNU groff or another + nroff-like package. GNU groff is available from:

        -

        The documentation is formatted using the HTMLDOC software. If you -need to make changes you can get the HTMLDOC software from:

        +

        The documentation is formatted using the HTMLDOC software. If you + need to make changes you can get the HTMLDOC software from:

        +

        Finally, you'll need a make program that understands the + include directive - FreeBSD, NetBSD, and OpenBSD + developers should use the gmake program.

        Compiling CUPS

        -

        CUPS uses GNU autoconf to configure the makefiles and source code -for your system. Type the following command to configure CUPS for your -system:

        +

        CUPS uses GNU autoconf to configure the makefiles and source code for + your system. Type the following command to configure CUPS for your + system:

           ./configure ENTER
           
        -

        The default installation will put the CUPS software in the /etc -, /usr, and /var directories on your system, -which will overwrite any existing printing commands on your system. Use -the --prefix option to install the CUPS software in -another location:

        +

        The default installation will put the CUPS software in the /etc +, /usr, and /var directories on your system, which + will overwrite any existing printing commands on your system. Use the +--prefix option to install the CUPS software in another location:

           ./configure --prefix=/some/directory ENTER
           
        -

        If the PNG, JPEG, TIFF, and ZLIB libraries are not installed in a -system default location (typically /usr/include and -/usr/lib) you'll need to set the CFLAGS, -CXXFLAGS, and LDFLAGS environment variables prior -to running configure:

        +

        If the PNG, JPEG, TIFF, and ZLIB libraries are not installed in a + system default location (typically /usr/include and + /usr/lib) you'll need to set the CFLAGS, +CXXFLAGS, and LDFLAGS environment variables prior to + running configure:

           setenv CFLAGS "-I/some/directory" ENTER
          @@ -526,7 +534,7 @@ to running configure: 

          ./configure ... ENTER
        -

        or:

        +

        or:

           CFLAGS="-I/some/directory"; export CFLAGS ENTER
          @@ -536,30 +544,40 @@ to running configure: 

          ./configure ... ENTER
        -

        To enable support for encryption, you'll also want to add the -"--enable-ssl" option:

        +

        To enable support for encryption, you'll also want to add the + "--enable-ssl" option:

           ./configure --enable-ssl
           
        -

        SSL and TLS support require the OpenSSL library, available at:

        +

        SSL and TLS support require the OpenSSL library, available at:

        -

        Once you have configured things, just type:

        +

        If the OpenSSL headers and libraries are not installed in the + standard directories, use the --with-openssl-includes and +--with-openssl-libs options:

        +
          +
          +./configure --enable-ssl \
          +    --with-openssl-includes=/foo/bar/include \
          +    --with-openssl-libs=/foo/bar/lib
          +
          +
        +

        Once you have configured things, just type:

           make ENTER
           
        -

        to build the software. +

        to build the software.

        Installing the Software

        -

        Use the "install" target to install the software:

        +

        Use the "install" target to install the software:

           make install ENTER
          @@ -568,16 +586,16 @@ to running configure: 

          WARNING: -

          Installing CUPS will overwrite your existing printing system. If -you experience difficulties with the CUPS software and need to go back -to your old printing system, you will need to reinstall the old -printing system from your operating system CDs.

          +

          Installing CUPS will overwrite your existing printing system. If you + experience difficulties with the CUPS software and need to go back to + your old printing system, you will need to reinstall the old printing + system from your operating system CDs.

          Running the Software

          -

          Once you have installed the software you can start the CUPS server -by typing:

          +

          Once you have installed the software you can start the CUPS server by + typing:

             /usr/sbin/cupsd ENTER
            @@ -586,79 +604,79 @@ by typing: 

            Installing a Binary Distribution

            -

            CUPS comes in a variety of binary distribution formats. Easy -Software Products provides binaries in TAR format with installation and -removal scripts ("portable" distributions), and in RPM and DPKG formats -for Red Hat and Debian-based distributions. Portable distributions are -available for all platforms, while the RPM and DPKG distributions are -only available for Linux. +

            CUPS comes in a variety of binary distribution formats. Easy Software + Products provides binaries in TAR format with installation and removal + scripts ("portable" distributions), and in RPM and DPKG formats for Red + Hat and Debian-based distributions. Portable distributions are + available for all platforms, while the RPM and DPKG distributions are + only available for Linux.

            WARNING: -

            Installing CUPS will overwrite your existing printing system. If -you experience difficulties with the CUPS software and need to go back -to your old printing system, you will need to remove the CUPS software -with the provided script and/or reinstall the old printing system from -your operating system CDs.

            +

            Installing CUPS will overwrite your existing printing system. If you + experience difficulties with the CUPS software and need to go back to + your old printing system, you will need to remove the CUPS software + with the provided script and/or reinstall the old printing system from + your operating system CDs.

            Installing a Portable Distribution

            -

            To install the CUPS software from a portable distribution you will -need to be logged in as root; doing an su is good enough. -Once you are the root user, run the installation script with:

            +

            To install the CUPS software from a portable distribution you will + need to be logged in as root; doing an su is good enough. + Once you are the root user, run the installation script with:

               ./cups.install ENTER
               
            -

            After asking you a few yes/no questions the CUPS software will be -installed and the scheduler will be started automatically. +

            After asking you a few yes/no questions the CUPS software will be + installed and the scheduler will be started automatically.

            Installing an RPM Distribution

            -

            To install the CUPS software from an RPM distribution you will need -to be logged in as root; doing an su is good enough. Once -you are the root user, run RPM with:

            +

            To install the CUPS software from an RPM distribution you will need + to be logged in as root; doing an su is good enough. Once + you are the root user, run RPM with:

               rpm -e lpr
               rpm -i cups-1.1-linux-M.m.n-intel.rpm ENTER
               
            -

            After a short delay the CUPS software will be installed and the -scheduler will be started automatically.

            +

            After a short delay the CUPS software will be installed and the + scheduler will be started automatically.

            Installing an Debian Distribution

            -

            To install the CUPS software from a Debian distribution you will -need to be logged in as root; doing an su is good enough. -Once you are the root user, run dpkg with:

            +

            To install the CUPS software from a Debian distribution you will need + to be logged in as root; doing an su is good enough. Once + you are the root user, run dpkg with:

               dpkg -i cups-1.1-linux-M.m.n-intel.deb ENTER
               
            -

            After a short delay the CUPS software will be installed and the -scheduler will be started automatically.

            +

            After a short delay the CUPS software will be installed and the + scheduler will be started automatically.

            3 - Printer Management

            -

            This chapter describes how to add your first printer and how to -manage your printers.

            +

            This chapter describes how to add your first printer and how to + manage your printers.

            The Basics

            -

            Each printer queue has a name associated with it; the printer name -must start with a letter and can contain up to 127 letters, numbers, -and the underscore (_). Case is not significant, e.g. "PRINTER", -"Printer", and "printer" are considered to be the same name.

            -

            Printer queues also have a device associated with them. The device -can be a parallel port, a network interface, and so forth. Devices -within CUPS use Uniform Resource Identifiers ("URIs") which are a more -general form of Uniform Resource Locators ("URLs") that are used in -your web browser. For example, the first parallel port in Linux usually -uses a device URI of parallel:/dev/lp1. +

            Each printer queue has a name associated with it; the printer name + must start with a letter and can contain up to 127 letters, numbers, + and the underscore (_). Case is not significant, e.g. "PRINTER", + "Printer", and "printer" are considered to be the same name.

            +

            Printer queues also have a device associated with them. The device + can be a parallel port, a network interface, and so forth. Devices + within CUPS use Uniform Resource Identifiers ("URIs") which are a more + general form of Uniform Resource Locators ("URLs") that are used in + your web browser. For example, the first parallel port in Linux usually + uses a device URI of parallel:/dev/lp1.

            You can see a complete list of supported devices by running the -lpinfo(8) command:

            +lpinfo(8) command:

               lpinfo -v ENTER
              @@ -674,240 +692,249 @@ direct usb:/dev/usb/lp0
               network smb
               
            -

            The -v option specifies that you want a list of -available devices. The first word in each line is the type of device -(direct, file, network, or serial) and is followed by the device URI or -method name for that device. File devices have device URIs of the form -file:/directory/filename while network devices use the more -familiar method://server or method://server/path - format.

            -

            Finally, printer queues usually have a PostScript Printer -Description ("PPD") file associated with them. PPD files describe the -capabilities of each printer, the page sizes supported, etc., and are -used for PostScript and non-PostScript printers. CUPS includes PPD -files for HP LaserJet, HP DeskJet, EPSON 9-pin, EPSON 24-pin, and EPSON -Stylus printers.

            +

            The -v option specifies that you want a list of + available devices. The first word in each line is the type of device + (direct, file, network, or serial) and is followed by the device URI or + method name for that device. File devices have device URIs of the form +file:/directory/filename while network devices use the more + familiar method://server or method://server/path + format.

            +

            Finally, printer queues usually have a PostScript Printer Description + ("PPD") file associated with them. PPD files describe the capabilities + of each printer, the page sizes supported, etc., and are used for + PostScript and non-PostScript printers. CUPS includes PPD files for HP + LaserJet, HP DeskJet, EPSON 9-pin, EPSON 24-pin, and EPSON Stylus + printers.

            Adding Your First Printer

            -

            CUPS provides two methods for adding printers: a command-line -program called lpadmin(8) and a Web interface. The -lpadmin command allows you to perform most printer -administration tasks from the command-line and is located in -/usr/sbin. The Web interface is located at:

            +

            CUPS provides two methods for adding printers: a command-line program + called lpadmin(8) and a Web interface. The lpadmin + command allows you to perform most printer administration tasks from + the command-line and is located in /usr/sbin. The Web + interface is located at:

            -

            and steps you through printer configuration. If you don't like -command-line interfaces, try the Web interface - instead.

            +

            and steps you through printer configuration. If you don't like + command-line interfaces, try the Web interface + instead.

            Adding Your First Printer from the Command-Line

            -

            Run the lpadmin command with the -p option -to add a printer to CUPS:

            +

            Run the lpadmin command with the -p option + to add a printer to CUPS:

               /usr/sbin/lpadmin -p printer -E -v device -m ppd ENTER
               
            -

            For an HP DeskJet printer connected to the parallel port this would -look like:

            +

            For an HP DeskJet printer connected to the parallel port this would + look like:

               /usr/sbin/lpadmin -p DeskJet -E -v parallel:/dev/lp1 -m deskjet.ppd ENTER
               
            -

            Similarly, an HP LaserJet printer using a JetDirect network -interface at IP address 11.22.33.44 would be added with the command:

            +

            Similarly, an HP LaserJet printer using a JetDirect network interface + at IP address 11.22.33.44 would be added with the command:

               /usr/sbin/lpadmin -p LaserJet -E -v socket://11.22.33.44 -m laserjet.ppd ENTER
               

            As you can see, deskjet.ppd and laserjet.ppd - are the PPD files for the HP DeskJet and HP LaserJet drivers included -with CUPS. You'll find a complete list of PPD files and the printers -they will work with in Appendix C, "Printer -Drivers".

            + are the PPD files for the HP DeskJet and HP LaserJet drivers included + with CUPS. You'll find a complete list of PPD files and the printers + they will work with in Appendix C, "Printer + Drivers".

            +

            For a dot matrix printer connected to the serial port this would + might look like:

            +
              +
              +/usr/sbin/lpadmin -p DotMatrix -E -v serial:/dev/ttyS0?baud=9600+size=8+parity=none+flow=soft deskjet.ppd ENTER
              +
              +
            +

            Here you specify the serial port (e.g. S0,S1, d0, d1), baud rate + (e.g. 9600, 19200, 38400, 115200, etc.), number of bits, parity, and + flow control. If you do not need flow control, delete the "+flow=soft" + portion.

            Adding Your First Printer from the Web

            -

            The CUPS web server provides a user-friendly "wizard" interface for -adding your printers. Rather than figuring out which device URI and PPD -file to use, you can instead click on the appropriate listings and fill -in some simple information. Enter the following URL in your web browser -to begin:

            +

            The CUPS web server provides a user-friendly "wizard" interface for + adding your printers. Rather than figuring out which device URI and PPD + file to use, you can instead click on the appropriate listings and fill + in some simple information. Enter the following URL in your web browser + to begin:

            -

            Click on the Add Printer button to add a printer.

            +

            Click on the Add Printer button to add a printer.

            Managing Printers from the Command-Line

            -

            The lpadmin command enables you to perform most printer -administration tasks from the command-line. You'll find lpadmin - in the /usr/sbin directory.

            +

            The lpadmin command enables you to perform most printer + administration tasks from the command-line. You'll find lpadmin + in the /usr/sbin directory.

            Adding and Modifying Printers

            -

            Run the lpadmin command with the -p option -to add or modify a printer:

            +

            Run the lpadmin command with the -p option + to add or modify a printer:

               /usr/sbin/lpadmin -p printer options ENTER
               
            -

            The options arguments can be any of the following:

            +

            The options arguments can be any of the following:

              -
              -c class
              -
              Adds the named printer to printer class class. If the -class does not exist then it is created.
              -
              -i interface
              -
              Copies the named interface script to the printer. - Interface scripts are used by System V printer drivers. Since all -filtering is disabled when using an interface script, scripts - generally should not be used unless there is no other driver for a -printer.
              -
              -m model
              -
              Specifies a standard printer driver which is usually a PPD file. A -list of all available models can be displayed using the lpinfo - command with the -m option. A list of printer drivers -included with CUPS can be found in Appendix -C, "Printer Drivers".
              -
              -r class
              -
              Removes the named printer from printer class class. If the -resulting class becomes empty then it is removed.
              -
              -v device-uri
              -
              Sets the device for communicating with the printer. If a job is -currently printing on the named printer then the job will be restarted -and sent to the new device.
              -
              -D info
              -
              Provides a textual description of the printer, e.g. "John's -Personal Printer".
              -
              -E
              -
              Enables the printer and accepts job. This option is equivalent to -running the enable(1) and accept(8) commands -on the printer.
              -
              -L location
              -
              Provides a textual location for the printer, e.g. "Computer Lab -5".
              -
              -P ppd-file
              -
              Specifies a local PPD file for the printer driver.
              +
              -c class
              +
              Adds the named printer to printer class class. If the + class does not exist then it is created.
              +
              -i interface
              +
              Copies the named interface script to the printer. + Interface scripts are used by System V printer drivers. Since all + filtering is disabled when using an interface script, scripts generally + should not be used unless there is no other driver for a printer.
              +
              -m model
              +
              Specifies a standard printer driver which is usually a PPD file. A + list of all available models can be displayed using the lpinfo + command with the -m option. A list of printer drivers + included with CUPS can be found in Appendix + C, "Printer Drivers".
              +
              -r class
              +
              Removes the named printer from printer class class. If the + resulting class becomes empty then it is removed.
              +
              -v device-uri
              +
              Sets the device for communicating with the printer. If a job is + currently printing on the named printer then the job will be restarted + and sent to the new device.
              +
              -D info
              +
              Provides a textual description of the printer, e.g. "John's Personal + Printer".
              +
              -E
              +
              Enables the printer and accepts job. This option is equivalent to + running the enable(1) and accept(8) commands + on the printer.
              +
              -L location
              +
              Provides a textual location for the printer, e.g. "Computer Lab 5".
              +
              -P ppd-file
              +
              Specifies a local PPD file for the printer driver.

            Deleting Printers

            -

            Run the lpadmin command with the -x option -to delete a printer:

            +

            Run the lpadmin command with the -x option + to delete a printer:

               /usr/sbin/lpadmin -x printer ENTER
               

            Setting the Default Printer

            -

            Run the lpadmin command with the -d option -to set a default printer:

            +

            Run the lpadmin command with the -d option + to set a default printer:

               /usr/sbin/lpadmin -d printer ENTER
               

            The default printer can be overridden by the user using the -lpoptions(1) command.

            +lpoptions(1) command.

            Starting and Stopping Printers

            -

            The enable and disable commands start and -stop printer queues, respectively:

            +

            The enable and disable commands start and + stop printer queues, respectively:

               /usr/bin/enable printer ENTER
               /usr/bin/disable printer ENTER
               
            -

            Printers that are disabled may still accept jobs for printing, but -won't actually print any files until they are restarted. This is useful -if the printer malfunctions and you need time to correct the problem. -Any queued jobs are printed after the printer is enabled (started).

            +

            Printers that are disabled may still accept jobs for printing, but + won't actually print any files until they are restarted. This is useful + if the printer malfunctions and you need time to correct the problem. + Any queued jobs are printed after the printer is enabled (started).

            Accepting and Rejecting Print Jobs

            -

            The accept and reject commands accept and -reject print jobs for the named printer, respectively:

            +

            The accept and reject commands accept and + reject print jobs for the named printer, respectively:

               /usr/sbin/accept printer ENTER
               /usr/sbin/reject printer ENTER
               
            -

            As noted above, a printer can be stopped but accepting new print -jobs. A printer can also be rejecting new print jobs while it finishes -those that have been queued. This is useful for when you must perform -maintenance on the printer and will not have it available to users for -a long period of time.

            +

            As noted above, a printer can be stopped but accepting new print + jobs. A printer can also be rejecting new print jobs while it finishes + those that have been queued. This is useful for when you must perform + maintenance on the printer and will not have it available to users for + a long period of time.

            Managing Printers from the Web

            -

            The Web interface is located at:

            +

            The Web interface is located at:

            -

            From there you can perform all printer management tasks with a few -simple mouse clicks.

            +

            From there you can perform all printer management tasks with a few + simple mouse clicks.

            4 - Printer Classes

            -

            This chapter describes what printer classes are and how to manage -them.

            +

            This chapter describes what printer classes are and how to manage + them.

            The Basics

            -

            CUPS provides collections of printers called printer classes. -Jobs sent to a class are forwarded to the first available printer in -the class. Classes can themselves be members of other classes, so it is -possible for you to define very large, distributed printer classes for -high-availability printing.

            -

            CUPS also supports implicit classes. Implicit classes work -just like printer classes, but they are created automatically based -upon the available printers and classes on the network. This allows you -to setup multiple print servers with identical printer configurations -and have the client machines send their print jobs to the first -available server. If one or more servers go down, the jobs are -automatically redirected to the servers that are running, providing -fail-safe printing.

            +

            CUPS provides collections of printers called printer classes. + Jobs sent to a class are forwarded to the first available printer in + the class. Classes can themselves be members of other classes, so it is + possible for you to define very large, distributed printer classes for + high-availability printing.

            +

            CUPS also supports implicit classes. Implicit classes work + just like printer classes, but they are created automatically based + upon the available printers and classes on the network. This allows you + to setup multiple print servers with identical printer configurations + and have the client machines send their print jobs to the first + available server. If one or more servers go down, the jobs are + automatically redirected to the servers that are running, providing + fail-safe printing.

            Managing Printer Classes from the Command-Line

            Run the lpadmin command with the -p and --c options to add a printer to a class:

            +-c options to add a printer to a class:

               /usr/sbin/lpadmin -p printer -c class ENTER
               
            -

            The class is created automatically if it doesn't exist. To -remove a printer from a class use the -r option:

            +

            The class is created automatically if it doesn't exist. To + remove a printer from a class use the -r option:

               /usr/sbin/lpadmin -p printer -r class ENTER
               
            -

            To remove the entire class just use the -x option:

            +

            To remove the entire class just use the -x option:

               /usr/sbin/lpadmin -x class ENTER
               

            Managing Printer Classes from the Web Interface

            -

            The Web interface is located at:

            +

            The Web interface is located at:

            -

            The Add Class and Modify Class interfaces -provide a list of available printers; click on the printers of interest -to add them to the class.

            +

            The Add Class and Modify Class interfaces + provide a list of available printers; click on the printers of interest + to add them to the class.

            Implicit Classes

            -

            A noted earlier, implicit classes are created automatically from the -available network printers and classes. To disable this functionality, -set the ImplicitClasses - directive to Off in the cupsd.conf file. You -will find more information on doing this in -Chapter 6, "Printing System Management".

            +

            A noted earlier, implicit classes are created automatically from the + available network printers and classes. To disable this functionality, + set the ImplicitClasses + directive to Off in the cupsd.conf file. You + will find more information on doing this in + Chapter 6, "Printing System Management".

            5 - Client Setup

            -

            This chapter discusses several ways to configure CUPS clients for -printing.

            +

            This chapter discusses several ways to configure CUPS clients for + printing.

            The Basics

            -

            A client is any machine that sends print jobs to another machine for -final printing. Clients can also be servers if they communicate -directly with any printers of their own.

            -

            CUPS supports several methods of configuring client machines:

            +

            A client is any machine that sends print jobs to another machine for + final printing. Clients can also be servers if they communicate + directly with any printers of their own.

            +

            CUPS supports several methods of configuring client machines:

            Manual Configuration of Print Queues

            -

            The most tedious method of configuring client machines is to -configure each remote queue by hand using the lpadmin - command:

            +

            The most tedious method of configuring client machines is to + configure each remote queue by hand using the lpadmin + command:

               lpadmin -p printer -E -v ipp://server/printers/printer ENTER
               
            -

            The printer name is the name of the printer on the -server machine. The server name is the hostname or IP -address of the server machine. Repeat the lpadmin command -for each remote printer you wish to use.

            +

            The printer name is the name of the printer on the + server machine. The server name is the hostname or IP + address of the server machine. Repeat the lpadmin command + for each remote printer you wish to use.

            Specifying a Single Server for Printing

            -

            CUPS can be configured to run without a local spooler and send all -jobs to a single server. However, if that server goes down then all -printing will be disabled. Use this configuration only as absolutely -needed.

            -

            The default server is normally "localhost". To override the default -server create a file named /etc/cups/client.conf and add a -line reading:

            +

            CUPS can be configured to run without a local spooler and send all + jobs to a single server. However, if that server goes down then all + printing will be disabled. Use this configuration only as absolutely + needed.

            +

            The default server is normally "localhost". To override the default + server create a file named /etc/cups/client.conf and add a + line reading:

               ServerName server
               
            -

            to the file. The server name can be the hostname or IP -address of the default server.

            -

            The default server can also be customized on a per-user basis. To -set a user-specific server create a file named ~/.cupsrc and -add a line reading:

            +

            to the file. The server name can be the hostname or IP + address of the default server.

            +

            The default server can also be customized on a per-user basis. To set + a user-specific server create a file named ~/.cupsrc and add + a line reading:

               ServerName server
               
            -

            to the file. The server name can be the hostname or IP -address of the default server.

            +

            to the file. The server name can be the hostname or IP + address of the default server.

            Automatic Configuration of Print Queues

            -

            CUPS supports automatic client configuration of printers on the same -subnet. To configure printers on the same subnet, do nothing. -Each client should see the available printers within 30 seconds -automatically. The printer and class lists are updated automatically as -printers and servers are added or removed.

            -

            If you want to see printers on other subnets as well, use the -BrowsePoll directive as described next.

            +

            CUPS supports automatic client configuration of printers on the same + subnet. To configure printers on the same subnet, do nothing. + Each client should see the available printers within 30 seconds + automatically. The printer and class lists are updated automatically as + printers and servers are added or removed.

            +

            If you want to see printers on other subnets as well, use the + BrowsePoll directive as described next.

            Specifying Multiple Servers for Printing

            -

            If you have CUPS servers on different subnets, then you should -configure CUPS to poll those servers. Polling provides the benefits of -automatic configuration without significant configuration on the -clients, and multiple clients on the same subnet can share the same -configuration information.

            -

            Polling is enabled by specifying one or more -BrowsePoll directives in the /etc/cups/cupsd.conf - file. For information on making these changes, see -Chapter 6, "Printing System Management".

            -

            6 - Printing System -Management

            -

            This chapter shows how you can configure the CUPS server.

            +

            If you have CUPS servers on different subnets, then you should + configure CUPS to poll those servers. Polling provides the benefits of + automatic configuration without significant configuration on the + clients, and multiple clients on the same subnet can share the same + configuration information.

            +

            Polling is enabled by specifying one or more +BrowsePoll directives in the /etc/cups/cupsd.conf + file. For information on making these changes, see + Chapter 6, "Printing System Management".

            +

            6 - Printing System + Management

            +

            This chapter shows how you can configure the CUPS server.

            The Basics

            -

            Several text files are used to configure CUPS. All of the server -configuration files are located in the /etc/cups directory:

            +

            Several text files are used to configure CUPS. All of the server + configuration files are located in the /etc/cups directory:

              -
              classes.conf
              -
              This file contains information on each printer class. Normally you -manipulate this file using the lpadmin command or the Web -interface. -
                +
              classes.conf
              +
              This file contains information on each printer class. Normally you + manipulate this file using the lpadmin command or the Web + interface. +
               
              -
              client.conf
              -
              This file provides the default server name for client machines. -See Chapter 5, "Client Setup" for more -information. -
                +
              client.conf
              +
              This file provides the default server name for client machines. See Chapter 5, "Client Setup" for more + information. +
               
              -
              cupsd.conf
              -
              This file controls how the CUPS server (/usr/sbin/cupsd -) operates and is normally edited by hand. -
                +
              cupsd.conf
              +
              This file controls how the CUPS server (/usr/sbin/cupsd) + operates and is normally edited by hand. +
               
              -
              mime.convs
              -
              This file contains a list of standard file conversion filters and -their costs. You normally do not edit this file. -
                +
              mime.convs
              +
              This file contains a list of standard file conversion filters and + their costs. You normally do not edit this file. +
               
              -
              mime.types
              -
              This file contains a list of standard file formats and how to +
              mime.types
              +
              This file contains a list of standard file formats and how to recognize them. You normally do not edit this file. -
                +
               
              -
              printers.conf
              -
              This file contains information on each printer. Normally you -manipulate this file using the lpadmin command or the Web -Interface. -
               
              +
              printers.conf
              +
              This file contains information on each printer. Normally you + manipulate this file using the lpadmin command or the Web + Interface. +
               

            Restarting the CUPS Server

            -

            Once you have made a change to a configuration file you need to -restart the CUPS server by sending it a HUP signal or -using the supplied initialization script. The CUPS distributions -install the script in the init.d directory with the name -cups. The location varies based upon the operating system:

            +

            Once you have made a change to a configuration file you need to + restart the CUPS server by sending it a HUP signal or + using the supplied initialization script. The CUPS distributions + install the script in the init.d directory with the name + cups. The location varies based upon the operating system:

               /etc/rc.d/init.d/cups restart ENTER
              @@ -1034,17 +1061,17 @@ cups. The location varies based upon the operating system: 

            Changing the Server Configuration

            -

            The /etc/cups/cupsd.conf file contains configuration -directives that control how the server functions. Each directive is -listed on a line by itself followed by its value. Comments are -introduced using the number sign ("#") character at the beginning of a -line. Since the server configuration file consists of plain text, you -can use your favorite text editor to make changes to it. +

            The /etc/cups/cupsd.conf file contains configuration + directives that control how the server functions. Each directive is + listed on a line by itself followed by its value. Comments are + introduced using the number sign ("#") character at the beginning of a + line. Since the server configuration file consists of plain text, you + can use your favorite text editor to make changes to it.

            Server Directives

            -

            The cupsd.conf file contains many directives that -determine how the server operates:

            +

            The cupsd.conf file contains many directives that + determine how the server operates:

              @@ -1061,24 +1088,29 @@ determine how the server operates:

            • BrowseOrder
            • BrowsePoll
            • BrowsePort
            • +
            • BrowseProtocols
            • BrowseRelay
            • BrowseShortNames
            • BrowseTimeout
            • Browsing
            • Classification
            • +
            • ClassifyOverride
            • DataDir
            • DefaultCharset
            • DefaultLanguage
            • Deny
            • DocumentRoot
            • -
                  +    
            • Encryption
            • ErrorLog
            • FilterLimit
            • FontPath
            • Group
            • +
            • HideImplicitMembers
            • HostNameLookups
            • ImplicitClasses
            • +
            • ImplicitAnyClasses
            • +
            • Include
            • KeepAliveTimeout
            • KeepAlive
            • Limit
            • @@ -1094,8 +1126,8 @@ determine how the server operates:

            • MaxLogSize
            • MaxRequestSize
            • Order
            • +
                 
            • PageLog
            • -
                 
            • Port
            • PreserveJobFiles
            • PreserveJobHistory
            • @@ -1135,16 +1167,16 @@ AccessLog syslog

              Description

              -

              The AccessLog directive sets the name of the access log -file. If the filename is not absolute then it is assumed to be relative -to the ServerRoot directory. The -access log file is stored in "common log format" and can be used by any -web access reporting tool to generate a report on CUPS server activity.

              +

              The AccessLog directive sets the name of the access log + file. If the filename is not absolute then it is assumed to be relative + to the ServerRoot directory. The + access log file is stored in "common log format" and can be used by any + web access reporting tool to generate a report on CUPS server activity.

              The server name can be included in the filename by using %s - in the name.

              -

              The special name "syslog" can be used to send the access information -to the system log instead of a plain file.

              -

              The default access log file is /var/log/cups/access_log. + in the name.

              +

              The special name "syslog" can be used to send the access information + to the system log instead of a plain file.

              +

              The default access log file is /var/log/cups/access_log.

              Allow

              @@ -1166,11 +1198,11 @@ Allow from nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm

              Description

              -

              The Allow directive specifies a hostname, IP address, -or network that is allowed access to the server. Allow - directives are cummulative, so multiple Allow directives -can be used to allow access for multiple hosts or networks. The -/mm notation specifies a CIDR netmask: +

              The Allow directive specifies a hostname, IP address, or + network that is allowed access to the server. Allow + directives are cummulative, so multiple Allow directives + can be used to allow access for multiple hosts or networks. The +/mm notation specifies a CIDR netmask:

              mmnetmask @@ -1186,8 +1218,8 @@ mmnetmask

              -

              The Allow directive must appear inside a -Location directive. +

              The Allow directive must appear inside a + Location directive.

              AuthClass

              @@ -1202,22 +1234,21 @@ AuthClass Group

              Description

              -

              The AuthClass directive defines what level of -authentication is required:

              -
                -
              • Anonymous - No authentication should be performed - (default.)
              • -
              • User - A valid username and password is required.
              • -
              • System - A valid username and password is required, -and the username must belong to the "sys" group; this can be changed -using the SystemGroup - directive.
              • -
              • Group - A valid username and password is required, -and the username must belong to the group named by the -AuthGroupName directive.
              • -
              -

              The AuthClass directive must appear inside a -Location directive. +

              The AuthClass directive defines what level of + authentication is required:

              +
                +
              • Anonymous - No authentication should be performed + (default.)
              • +
              • User - A valid username and password is required.
              • +
              • System - A valid username and password is required, and + the username must belong to the "sys" group; this can be changed using + the SystemGroup directive.
              • +
              • Group - A valid username and password is required, and + the username must belong to the group named by the AuthGroupName + directive.
              • +
              +

              The AuthClass directive must appear inside a + Location directive.

              AuthGroupName

              @@ -1231,9 +1262,9 @@ AuthGroupName lp

              Description

              The AuthGroupName directive sets the group to use for -Group authentication.

              -

              The AuthGroupName directive must appear inside a -Location directive. +Group authentication.

              +

              The AuthGroupName directive must appear inside a + Location directive.

              AuthType

              @@ -1244,24 +1275,27 @@ Group authentication.

              AuthType None AuthType Basic AuthType Digest +AuthType BasicDigest

              Description

              -

              The AuthType directive defines the type of -authentication to perform:

              -
                -
              • None - No authentication should be performed - (default.)
              • -
              • Basic - Basic authentication should be performed -using the UNIX password and group files.
              • -
              • Digest - Digest authentication should be performed -using the /etc/cups/passwd.md5 file.
              • -
              -

              When using Basic or Digest authentication, -clients connecting through the localhost interface can -also authenticate using certificates.

              -

              The AuthType directive must appear inside a -Location directive. +

              The AuthType directive defines the type of + authentication to perform:

              +
                +
              • None - No authentication should be performed (default.)
              • +
              • Basic - Basic authentication should be performed using + the UNIX password and group files.
              • +
              • Digest - Digest authentication should be performed + using the /etc/cups/passwd.md5 file.
              • +
              • BasicDigest - Basic authentication should be performed + using the /etc/cups/passwd.md5 file.
              • +
              +

              When using Basic, Digest, or +BasicDigest authentication, clients connecting through the +localhost interface can also authenticate using + certificates.

              +

              The AuthType directive must appear inside a + Location directive.

              AutoPurgeJobs

              @@ -1274,10 +1308,10 @@ AutoPurgeJobs No

              Description

              -

              The AutoPurgeJobs directive specifies whether or not to -purge completed jobs once they are no longer required for quotas. This -option has no effect if quotas are not enabled. The default setting is -No. +

              The AutoPurgeJobs directive specifies whether or not to + purge completed jobs once they are no longer required for quotas. This + option has no effect if quotas are not enabled. The default setting is +No.

              BrowseAddress

              @@ -1291,18 +1325,18 @@ BrowseAddress host.domain.com:631

              Description

              -

              The BrowseAddress directive specifies an address to -send browsing information to. Multiple BrowseAddress - directives can be specified to send browsing information to different -networks or systems.

              -

              The default address is 255.255.255.255:631 which will -broadcast the information to all networks the server is connected to. +

              The BrowseAddress directive specifies an address to send + browsing information to. Multiple BrowseAddress directives + can be specified to send browsing information to different networks or + systems.

              +

              The default address is 255.255.255.255:631 which will + broadcast the information to all networks the server is connected to.

              NOTE: -

              If you are using HP-UX 10.20 and a subnet that is not 24, 16, or 8 -bits, printer browsing (and in fact all broadcast reception) will not -work. This problem appears to be fixed in HP-UX 11.0.

              +

              If you are using HP-UX 10.20 and a subnet that is not 24, 16, or 8 + bits, printer browsing (and in fact all broadcast reception) will not + work. This problem appears to be fixed in HP-UX 11.0.

              @@ -1323,15 +1357,15 @@ BrowseAllow from *.domain.com

              Description

              -

              The BrowseAllow directive specifies a system or network -to accept browse packets from. The default is to accept browse packets -from all hosts.

              -

              Host and domain name matching require that you enable the -HostNameLookups directive.

              -

              IP address matching supports exact matches, partial addresses that -match networks using netmasks of 255.0.0.0, 255.255.0.0, and -255.255.255.0, or network addresses using the specified netmask or bit -count. +

              The BrowseAllow directive specifies a system or network + to accept browse packets from. The default is to accept browse packets + from all hosts.

              +

              Host and domain name matching require that you enable the + HostNameLookups directive.

              +

              IP address matching supports exact matches, partial addresses that + match networks using netmasks of 255.0.0.0, 255.255.0.0, and + 255.255.255.0, or network addresses using the specified netmask or bit + count.

              BrowseDeny

              @@ -1348,15 +1382,15 @@ BrowseDeny from *.domain.com

              Description

              -

              The BrowseDeny directive specifies a system or network -to reject browse packets from. The default is to deny browse packets -from no hosts.

              -

              Host and domain name matching require that you enable the -HostNameLookups directive.

              -

              IP address matching supports exact matches, partial addresses that -match networks using netmasks of 255.0.0.0, 255.255.0.0, and -255.255.255.0, or network addresses using the specified netmask or bit -count. +

              The BrowseDeny directive specifies a system or network + to reject browse packets from. The default is to deny browse packets + from no hosts.

              +

              Host and domain name matching require that you enable the + HostNameLookups directive.

              +

              IP address matching supports exact matches, partial addresses that + match networks using netmasks of 255.0.0.0, 255.255.0.0, and + 255.255.255.0, or network addresses using the specified netmask or bit + count.

              BrowseOrder

              @@ -1369,13 +1403,13 @@ BrowseOrder deny,allow

              Description

              -

              The BrowseOrder directive specifies the order of -allow/deny processing. The default order is deny,allow:

              +

              The BrowseOrder directive specifies the order of + allow/deny processing. The default order is deny,allow:

                -
              • allow,deny - Browse packets are accepted unless - specifically denied.
              • -
              • deny,allow - Browse packets are rejected unless - specifically allowed.
              • +
              • allow,deny - Browse packets are accepted unless + specifically denied.
              • +
              • deny,allow - Browse packets are rejected unless + specifically allowed.
              @@ -1389,14 +1423,14 @@ BrowseInterval 30

              Description

              -

              The BrowseInterval directive specifies the maximum -amount of time between browsing updates. Specifying a value of 0 -seconds disables outgoing browse updates but allows a server to receive -printer information from other hosts.

              -

              The BrowseInterval value should always be less than the BrowseTimeout value. Otherwise -printers and classes will disappear from client systems between -updates. +

              The BrowseInterval directive specifies the maximum + amount of time between browsing updates. Specifying a value of 0 + seconds disables outgoing browse updates but allows a server to receive + printer information from other hosts.

              +

              The BrowseInterval value should always be less than the BrowseTimeout value. Otherwise + printers and classes will disappear from client systems between + updates.

              BrowsePoll

              @@ -1409,12 +1443,12 @@ BrowsePoll host.domain.com:631

              Description

              -

              The BrowsePoll directive polls a server for available -printers once every BrowseInterval - seconds. Multiple BrowsePoll directives can be -specified to poll multiple servers.

              -

              If BrowseInterval is set to 0 then the server is polled -once every 30 seconds. +

              The BrowsePoll directive polls a server for available + printers once every BrowseInterval + seconds. Multiple BrowsePoll directives can be + specified to poll multiple servers.

              +

              If BrowseInterval is set to 0 then the server is polled + once every 30 seconds.

              BrowsePort

              @@ -1427,13 +1461,42 @@ BrowsePort 9999

              Description

              -

              The BrowsePort directive specifies the UDP port number -used for browse packets. The default port number is 631. +

              The BrowsePort directive specifies the UDP port number + used for browse packets. The default port number is 631. +

              + + +
              NOTE: +

              You must set the BrowsePort to the same value on all of + the systems that you want to see.

              +
              +
              + + +

              +

              BrowseProtocols

              +
              +

              Examples

              +
                +
                +BrowseProtocols CUPS
                +BrowseProtocols SLP
                +BrowseProtocols CUPS SLP
                +BrowseProtocols all
                +
                +
              +

              Description

              +

              The BrowseProtocols directive specifies the protocols to + use when collecting and distributing shared printers on the local + network. The default protocol is CUPS, which is a + broadcast-based protocol.

              NOTE: -

              You must set the BrowsePort to the same value on all -of the systems that you want to see.

              +

              When using the SLP protocol, you must have at least one + Directory Agent (DA) server on your network. Otherwise the CUPS + scheduler (cupsd) will not respond to client requests for + several seconds while polling the network.

              @@ -1453,20 +1516,20 @@ BrowseRelay host.domain.com 192.0.2.255

              Description

              -

              The BrowseRelay directive specifies source and -destination addresses for relaying browsing information from one host -or network to another. Multiple BrowseRelay directives can -be specified as needed.

              -

              BrowseRelay is typically used on systems that bridge -multiple subnets using one or more network interfaces. It can also be -used to relay printer information from polled servers with the line:

              +

              The BrowseRelay directive specifies source and + destination addresses for relaying browsing information from one host + or network to another. Multiple BrowseRelay directives can + be specified as needed.

              +

              BrowseRelay is typically used on systems that bridge + multiple subnets using one or more network interfaces. It can also be + used to relay printer information from polled servers with the line:

                 BrowseRelay 127.0.0.1 255.255.255.255
                 
              -

              This effectively provides access to printers on a WAN for all -clients on the LAN(s). +

              This effectively provides access to printers on a WAN for all clients + on the LAN(s).

              BrowseShortNames

              @@ -1479,12 +1542,12 @@ BrowseShortNames No

              Description

              -

              The BrowseShortNames directive specifies whether or not -short names are used for remote printers when possible. Short names are -just the remote printer name, without the server ("printer"). If more -than one remote printer is detected with the same name, the printers -will have long names ("printer@server1", "printer@server2".)

              -

              The default value for this option is Yes. +

              The BrowseShortNames directive specifies whether or not + short names are used for remote printers when possible. Short names are + just the remote printer name, without the server ("printer"). If more + than one remote printer is detected with the same name, the printers + will have long names ("printer@server1", "printer@server2".)

              +

              The default value for this option is Yes.

              BrowseTimeout

              @@ -1497,14 +1560,14 @@ BrowseTimeout 60

              Description

              -

              The BrowseTimeout directive sets the timeout for -printer or class information that is received in browse packets. Once a -printer or class times out it is removed from the list of available -destinations.

              -

              The BrowseTimeout value should always be greater than -the BrowseInterval value. -Otherwise printers and classes will disappear from client systems -between updates. +

              The BrowseTimeout directive sets the timeout for printer + or class information that is received in browse packets. Once a printer + or class times out it is removed from the list of available + destinations.

              +

              The BrowseTimeout value should always be greater than + the BrowseInterval value. + Otherwise printers and classes will disappear from client systems + between updates.

              Browsing

              @@ -1517,14 +1580,14 @@ Browsing Off

              Description

              -

              The Browsing directive controls whether or not network -printer browsing is enabled. The default setting is On. +

              The Browsing directive controls whether or not network + printer browsing is enabled. The default setting is On.

              NOTE: -

              If you are using HP-UX 10.20 and a subnet that is not 24, 16, or 8 -bits, printer browsing (and in fact all broadcast reception) will not -work. This problem appears to be fixed in HP-UX 11.0.

              +

              If you are using HP-UX 10.20 and a subnet that is not 24, 16, or 8 + bits, printer browsing (and in fact all broadcast reception) will not + work. This problem appears to be fixed in HP-UX 11.0.

              @@ -1545,11 +1608,31 @@ Classification unclassified

              Description

              -

              The Classification directive sets the classification -level on the server. When this option is set, at least one of the -banner pages is forced to the classification level, and the -classification is placed on each page of output. The default is no -classification level. +

              The Classification directive sets the classification + level on the server. When this option is set, at least one of the + banner pages is forced to the classification level, and the + classification is placed on each page of output. The default is no + classification level. + +

              +

              ClassifyOverride

              +
              +

              Examples

              +
                +
                +ClassifyOverride Yes
                +ClassifyOverride No
                +
                +
              +

              Description

              +

              The ClassifyOverride directive specifies whether users + can override the default classification level on the server. When the + server classification is set, users can change the classification using + the job-sheets option and can choose to only print one + security banner before or after the job. If the job-sheets + option is set to none then the server default + classification is used.

              +

              The default is to not allow classification overrides.

              DataDir

              @@ -1561,8 +1644,8 @@ DataDir /usr/share/cups

              Description

              -

              The DataDir directive sets the directory to use for -data files. +

              The DataDir directive sets the directory to use for data + files.

              DefaultCharset

              @@ -1576,10 +1659,10 @@ DefaultCharset windows-1251

              Description

              -

              The DefaultCharset directive sets the default character -set to use for client connections. The default character set is -utf-8 but is overridden by the character set for the language -specified by the client or the DefaultLanguage directive. +

              The DefaultCharset directive sets the default character + set to use for client connections. The default character set is +utf-8 but is overridden by the character set for the language + specified by the client or the DefaultLanguage directive.

              DefaultLanguage

              @@ -1595,10 +1678,10 @@ DefaultLanguage it

              Description

              -

              The DefaultLanguage directive specifies the default -language to use for client connections. Setting the default language -also sets the default character set if a language localization file -exists for it. The default language is "en" for English. +

              The DefaultLanguage directive specifies the default + language to use for client connections. Setting the default language + also sets the default character set if a language localization file + exists for it. The default language is "en" for English.

              Deny

              @@ -1620,11 +1703,11 @@ Deny from nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm

              Description

              -

              The Deny directive specifies a hostname, IP address, or -network that is allowed access to the server. Deny - directives are cummulative, so multiple Deny directives -can be used to allow access for multiple hosts or networks. The -/mm notation specifies a CIDR netmask: +

              The Deny directive specifies a hostname, IP address, or + network that is allowed access to the server. Deny + directives are cummulative, so multiple Deny directives + can be used to allow access for multiple hosts or networks. The +/mm notation specifies a CIDR netmask:

              mmnetmask @@ -1640,8 +1723,8 @@ mmnetmask

              -

              The Deny directive must appear inside a -Location directive. +

              The Deny directive must appear inside a + Location directive.

              DocumentRoot

              @@ -1654,16 +1737,16 @@ DocumentRoot /foo/bar/doc/cups

              Description

              -

              The DocumentRoot directive specifies the location of -web content for the HTTP server in CUPS. If an absolute path is not -specified then it is assumed to be relative to the -ServerRoot directory. The default directory is -/usr/share/doc/cups.

              -

              Documents are first looked up in a sub-directory for the primary -language requested by the client (e.g. /usr/share/doc/cups/fr/... -) and then directly under the DocumentRoot directory (e.g. -/usr/share/doc/cups/...), so it is possible to localize the web -content by providing subdirectories for each language needed. +

              The DocumentRoot directive specifies the location of web + content for the HTTP server in CUPS. If an absolute path is not + specified then it is assumed to be relative to the + ServerRoot directory. The default directory is + /usr/share/doc/cups.

              +

              Documents are first looked up in a sub-directory for the primary + language requested by the client (e.g. /usr/share/doc/cups/fr/... +) and then directly under the DocumentRoot directory (e.g. + /usr/share/doc/cups/...), so it is possible to localize the web + content by providing subdirectories for each language needed.

              Encryption

              @@ -1678,10 +1761,10 @@ Encryption Always

              Description

              -

              The Encryption directive must appear instead a -Location section and specifies the encryption settings -for that location. The default setting is IfRequested for -all locations. +

              The Encryption directive must appear instead a + Location section and specifies the encryption settings + for that location. The default setting is IfRequested for + all locations.

              ErrorLog

              @@ -1695,14 +1778,14 @@ ErrorLog syslog

              Description

              -

              The ErrorLog directive sets the name of the error log -file. If the filename is not absolute then it is assumed to be relative -to the ServerRoot directory. The -default error log file is /var/log/cups/error_log.

              +

              The ErrorLog directive sets the name of the error log + file. If the filename is not absolute then it is assumed to be relative + to the ServerRoot directory. The + default error log file is /var/log/cups/error_log.

              The server name can be included in the filename by using %s - in the name.

              -

              The special name "syslog" can be used to send the error information -to the system log instead of a plain file. + in the name.

              +

              The special name "syslog" can be used to send the error information + to the system log instead of a plain file.

              FilterLimit

              @@ -1716,15 +1799,15 @@ FilterLimit 1000

              Description

              -

              The FilterLimit directive sets the maximum cost of all -running job filters. It can be used to limit the number of filter -programs that are run on a server to minimize disk, memory, and CPU -resource problems. A limit of 0 disables filter limiting.

              -

              An average print to a non-PostScript printer needs a filter limit of -about 200. A PostScript printer needs about half that (100). Setting -the limit below these thresholds will effectively limit the scheduler -to printing a single job at any time.

              -

              The default limit is 0. +

              The FilterLimit directive sets the maximum cost of all + running job filters. It can be used to limit the number of filter + programs that are run on a server to minimize disk, memory, and CPU + resource problems. A limit of 0 disables filter limiting.

              +

              An average print to a non-PostScript printer needs a filter limit of + about 200. A PostScript printer needs about half that (100). Setting + the limit below these thresholds will effectively limit the scheduler + to printing a single job at any time.

              +

              The default limit is 0.

              FontPath

              @@ -1737,9 +1820,9 @@ FontPath /usr/share/cups/fonts:/foo/bar/fonts

              Description

              -

              The FontPath directive specifies the font path to use -when searching for fonts. The default font path is -/usr/share/cups/fonts. +

              The FontPath directive specifies the font path to use + when searching for fonts. The default font path is +/usr/share/cups/fonts.

              Group

              @@ -1753,11 +1836,28 @@ Group root

              Description

              -

              The Group directive specifies the UNIX group that -filter and CGI programs run as. The default group is sys, -system, or root depending on the operating system. +

              The Group directive specifies the UNIX group that filter + and CGI programs run as. The default group is sys, +system, or root depending on the operating system.

              +

              HideImplicitMembers

              +
              +

              Examples

              +
                +
                +HideImplicitMembers Yes
                +HideImplicitMembers No
                +
                +
              +

              Description

              +

              The HideImplicitMembers directive controls whether the + individual printers in an implicit class are shown to the user. The + default is No.

              +

              ImplicitClasses must be + enabled for this directive to have any effect.

              + +

              HostNameLookups


              Examples

              @@ -1769,15 +1869,15 @@ HostNameLookups Double

              Description

              -

              The HostNameLookups directive controls whether or not -CUPS looks up the hostname for connecting clients. The Double - setting causes CUPS to verify that the hostname resolved from the -address matches one of the addresses returned for that hostname. -Double lookups also prevent clients with unregistered addresses -from connecting to your server. The default is Off to -avoid the potential server performance problems with hostname lookups. -Set this option to On or Double only if -absolutely required. +

              The HostNameLookups directive controls whether or not + CUPS looks up the hostname for connecting clients. The Double + setting causes CUPS to verify that the hostname resolved from the + address matches one of the addresses returned for that hostname. +Double lookups also prevent clients with unregistered addresses + from connecting to your server. The default is Off to + avoid the potential server performance problems with hostname lookups. + Set this option to On or Double only if + absolutely required.

              ImplicitClasses

              @@ -1790,13 +1890,46 @@ ImplicitClasses Off

              Description

              -

              The ImplicitClasses directive controls whether implicit -classes are created based upon the available network printers and -classes. The default setting is On but is automatically -turned Off if Browsing - is turned Off. +

              The ImplicitClasses directive controls whether implicit + classes are created based upon the available network printers and + classes. The default setting is On but is automatically + turned Off if Browsing + is turned Off.

              +

              ImplicitAnyClasses

              +
              +

              Examples

              +
                +
                +ImplicitAnyClasses On
                +ImplicitAnyClasses Off
                +
                +
              +

              Description

              +

              The ImplicitAnyClasses directive controls whether + implicit classes for local and remote printers are created with the + name AnyPrinter. The default setting is Off.

              +

              ImplicitClasses must be + enabled for this directive to have any effect.

              + + +

              Include

              +
              +

              Examples

              +
                +
                +Include filename
                +Include /foo/bar/filename
                +
                +
              +

              Description

              +

              The Include directive includes the named file in the +cupsd.conf file. If no leading path is provided, the file is + assumed to be relative to the ServerRoot + directory.

              + +

              KeepAlive


              Examples

              @@ -1807,12 +1940,12 @@ KeepAlive Off

              Description

              -

              The KeepAlive directive controls whether or not to -support persistent HTTP connections. The default is On.

              -

              HTTP/1.1 clients automatically support persistent connections, while -HTTP/1.0 clients must specifically request them using the -Keep-Alive attribute in the Connection: field of -each request. +

              The KeepAlive directive controls whether or not to + support persistent HTTP connections. The default is On.

              +

              HTTP/1.1 clients automatically support persistent connections, while + HTTP/1.0 clients must specifically request them using the +Keep-Alive attribute in the Connection: field of + each request.

              KeepAliveTimeout

              @@ -1825,9 +1958,9 @@ KeepAliveTimeout 30

              Description

              -

              The KeepAliveTimeout directive controls how long a -persistent HTTP connection will remain open after the last request. The -default is 60 seconds. +

              The KeepAliveTimeout directive controls how long a + persistent HTTP connection will remain open after the last request. The + default is 60 seconds.

              Limit

              @@ -1845,13 +1978,13 @@ default is 60 seconds.

              Description

              -

              The Limit directive groups access control directives -for specific types of HTTP requests and must appear inside a -Location section. Access can be limited for individual -request types (DELETE, GET, HEAD +

              The Limit directive groups access control directives for + specific types of HTTP requests and must appear inside a + Location section. Access can be limited for individual + request types (DELETE, GET, HEAD , OPTIONS, POST, PUT, and -TRACE) or for all request types (ALL). The request -type names are case-sensitive for compatibility with Apache. +TRACE) or for all request types (ALL). The request + type names are case-sensitive for compatibility with Apache.

              LimitExcept

              @@ -1865,12 +1998,12 @@ type names are case-sensitive for compatibility with Apache.

              Description

              -

              The LimitExcept directive groups access control -directives for specific types of HTTP requests and must appear inside a Location section. Unlike the -Limit directive, LimitExcept restricts -access for all requests except those listed on the -LimitExcept line. +

              The LimitExcept directive groups access control + directives for specific types of HTTP requests and must appear inside a Location section. Unlike the + Limit directive, LimitExcept restricts + access for all requests except those listed on the +LimitExcept line.

              LimitRequestBody

              @@ -1884,11 +2017,11 @@ LimitRequestBody 0

              Description

              -

              The LimitRequestBody directive controls the maximum -size of print files, IPP requests, and HTML form data in HTTP POST -requests. The default limit is 0 which disables the limit check.

              -

              Also see the identical MaxRequestSize - directive. +

              The LimitRequestBody directive controls the maximum size + of print files, IPP requests, and HTML form data in HTTP POST requests. + The default limit is 0 which disables the limit check.

              +

              Also see the identical MaxRequestSize + directive.

              Listen

              @@ -1901,12 +2034,12 @@ Listen 192.0.2.1:631

              Description

              -

              The Listen directive specifies a network address and -port to listen for connections. Multiple Listen directives -can be provided to listen on multiple addresses.

              -

              The Listen directive is similar to the -Port directive but allows you to restrict access to specific -interfaces or networks. +

              The Listen directive specifies a network address and + port to listen for connections. Multiple Listen directives + can be provided to listen on multiple addresses.

              +

              The Listen directive is similar to the +Port directive but allows you to restrict access to specific + interfaces or networks.

              Location

              @@ -1928,10 +2061,10 @@ interfaces or networks.

              Description

              -

              The Location directive specifies access control and -authentication options for the specified HTTP resource or path. More -information can be found later in this chapter in -"Printing System Security". +

              The Location directive specifies access control and + authentication options for the specified HTTP resource or path. More + information can be found later in this chapter in + "Printing System Security".

              LogLevel

              @@ -1952,23 +2085,23 @@ LogLevel debug2

              Description

              -

              The LogLevel directive specifies the level of logging -for the ErrorLog file. The -following values are recognized (each level logs everything under the -preceding levels):

              -
                -
              • none - Log nothing.
              • -
              • emerg - Log emergency conditions that prevent the - server from running.
              • -
              • alert - Log alerts that must be handled immediately.
              • -
              • crit - Log critical errors that don't prevent the -server from running.
              • -
              • error - Log general errors.
              • -
              • warn - Log errors and warnings.
              • -
              • notice - Log temporary error conditions.
              • -
              • info - Log all requests and state changes (default).
              • -
              • debug - Log basic debugging information.
              • -
              • debug2 - Log all debugging information.
              • +

                The LogLevel directive specifies the level of logging + for the ErrorLog file. The + following values are recognized (each level logs everything under the + preceding levels):

                +
                  +
                • none - Log nothing.
                • +
                • emerg - Log emergency conditions that prevent the + server from running.
                • +
                • alert - Log alerts that must be handled immediately.
                • +
                • crit - Log critical errors that don't prevent the + server from running.
                • +
                • error - Log general errors.
                • +
                • warn - Log errors and warnings.
                • +
                • notice - Log temporary error conditions.
                • +
                • info - Log all requests and state changes (default).
                • +
                • debug - Log basic debugging information.
                • +
                • debug2 - Log all debugging information.
                @@ -1982,16 +2115,16 @@ MaxClients 1024

              Description

              -

              The MaxClients directive controls the maximum number of -simultaneous clients that will be allowed by the server. The default is -100 clients. +

              The MaxClients directive controls the maximum number of + simultaneous clients that will be allowed by the server. The default is + 100 clients.

              NOTE: -

              Since each print job requires a file descriptor for the status -pipe, the CUPS server internally limits the MaxClients - value to 1/3 of the available file descriptors to avoid possible -problems when printing large numbers of jobs.

              +

              Since each print job requires a file descriptor for the status pipe, + the CUPS server internally limits the MaxClients value to + 1/3 of the available file descriptors to avoid possible problems when + printing large numbers of jobs.

              @@ -2009,13 +2142,13 @@ MaxJobs 0

              Description

              -

              The MaxJobs directive controls the maximum number of -jobs that are kept in memory. Once the number of jobs reaches the -limit, the oldest completed job is automatically purged from the system -to make room for the new one. If all of the known jobs are still -pending or active then the new job will be rejected.

              -

              Setting the maximum to 0 disables this functionality. The default -setting is 0. +

              The MaxJobs directive controls the maximum number of + jobs that are kept in memory. Once the number of jobs reaches the + limit, the oldest completed job is automatically purged from the system + to make room for the new one. If all of the known jobs are still + pending or active then the new job will be rejected.

              +

              Setting the maximum to 0 disables this functionality. The default + setting is 0.

              MaxJobsPerPrinter

              @@ -2029,12 +2162,12 @@ MaxJobsPerPrinter 0

              Description

              -

              The MaxJobsPerPrinter directive controls the maximum -number of active jobs that are allowed for each printer or class. Once -a printer or class reaches the limit, new jobs will be rejected until -one of the active jobs is completed, stopped, aborted, or cancelled.

              -

              Setting the maximum to 0 disables this functionality. The default -setting is 0. +

              The MaxJobsPerPrinter directive controls the maximum + number of active jobs that are allowed for each printer or class. Once + a printer or class reaches the limit, new jobs will be rejected until + one of the active jobs is completed, stopped, aborted, or cancelled.

              +

              Setting the maximum to 0 disables this functionality. The default + setting is 0.

              MaxJobsPerUser

              @@ -2048,12 +2181,12 @@ MaxJobsPerUser 0

              Description

              -

              The MaxJobsPerUser directive controls the maximum -number of active jobs that are allowed for each user. Once a user -reaches the limit, new jobs will be rejected until one of the active -jobs is completed, stopped, aborted, or cancelled.

              -

              Setting the maximum to 0 disables this functionality. The default -setting is 0. +

              The MaxJobsPerUser directive controls the maximum number + of active jobs that are allowed for each user. Once a user reaches the + limit, new jobs will be rejected until one of the active jobs is + completed, stopped, aborted, or cancelled.

              +

              Setting the maximum to 0 disables this functionality. The default + setting is 0.

              MaxLogSize

              @@ -2067,11 +2200,11 @@ MaxLogSize 0

              Description

              -

              The MaxLogSize directive controls the maximum size of -each log file. Once a log file reaches or exceeds the maximum size it -is closed and renamed to filename.O. This allows you to -rotate the logs automatically. The default size is 1048576 bytes (1MB).

              -

              Setting the maximum size to 0 disables log rotation. +

              The MaxLogSize directive controls the maximum size of + each log file. Once a log file reaches or exceeds the maximum size it + is closed and renamed to filename.O. This allows you to + rotate the logs automatically. The default size is 1048576 bytes (1MB).

              +

              Setting the maximum size to 0 disables log rotation.

              MaxRequestSize

              @@ -2085,11 +2218,11 @@ MaxRequestSize 0

              Description

              -

              The MaxRequestSize directive controls the maximum size -of print files, IPP requests, and HTML form data in HTTP POST requests. -The default limit is 0 which disables the limit check.

              -

              Also see the identical -LimitRequestBody directive. +

              The MaxRequestSize directive controls the maximum size + of print files, IPP requests, and HTML form data in HTTP POST requests. + The default limit is 0 which disables the limit check.

              +

              Also see the identical +LimitRequestBody directive.

              Order

              @@ -2102,16 +2235,16 @@ Order Deny,Allow

              Description

              -

              The Order directive defines the default access control. -The following values are supported:

              +

              The Order directive defines the default access control. + The following values are supported:

                -
              • Allow,Deny - Allow requests from all systems except - for those listed in a Deny directive.
              • -
              • Deny,Allow - Allow requests only from those listed in -an Allow directive.
              • +
              • Allow,Deny - Allow requests from all systems except + for those listed in a Deny directive.
              • +
              • Deny,Allow - Allow requests only from those listed in + an Allow directive.
              -

              The Order directive must appear inside a -Location directive. +

              The Order directive must appear inside a + Location directive.

              PageLog

              @@ -2125,14 +2258,14 @@ PageLog syslog

              Description

              -

              The PageLog directive sets the name of the page log -file. If the filename is not absolute then it is assumed to be relative -to the ServerRoot directory. The -default page log file is /var/log/cups/page_log.

              +

              The PageLog directive sets the name of the page log + file. If the filename is not absolute then it is assumed to be relative + to the ServerRoot directory. The + default page log file is /var/log/cups/page_log.

              The server name can be included in the filename by using %s - in the name.

              -

              The special name "syslog" can be used to send the page information -to the system log instead of a plain file. + in the name.

              +

              The special name "syslog" can be used to send the page information to + the system log instead of a plain file.

              Port

              @@ -2145,9 +2278,9 @@ Port 80

              Description

              -

              The Port directive specifies a port to listen on. -Multiple Port lines can be specified to listen on multiple -ports. The default port is 631. +

              The Port directive specifies a port to listen on. + Multiple Port lines can be specified to listen on multiple + ports. The default port is 631.

              PreserveJobHistory

              @@ -2160,13 +2293,13 @@ PreserveJobHistory Off

              Description

              -

              The PreserveJobHistory directive controls whether the -history of completed, cancelled, or aborted print jobs is stored on -disk.

              -

              A value of On (the default) preserves job information -until the administrator purges it with the cancel command.

              -

              A value of Off removes the job information as soon as -each job is completed, cancelled, or aborted. +

              The PreserveJobHistory directive controls whether the + history of completed, cancelled, or aborted print jobs is stored on + disk.

              +

              A value of On (the default) preserves job information + until the administrator purges it with the cancel command.

              +

              A value of Off removes the job information as soon as + each job is completed, cancelled, or aborted.

              PreserveJobFiles

              @@ -2179,14 +2312,14 @@ PreserveJobFiles Off

              Description

              -

              The PreserveJobFiles directive controls whether the -document files of completed, cancelled, or aborted print jobs are -stored on disk.

              -

              A value of On preserves job files until the -administrator purges them with the cancel command. Jobs -can be restarted (and reprinted) as desired until they are purged.

              -

              A value of Off (the default) removes the job files as -soon as each job is completed, cancelled, or aborted. +

              The PreserveJobFiles directive controls whether the + document files of completed, cancelled, or aborted print jobs are + stored on disk.

              +

              A value of On preserves job files until the + administrator purges them with the cancel command. Jobs + can be restarted (and reprinted) as desired until they are purged.

              +

              A value of Off (the default) removes the job files as + soon as each job is completed, cancelled, or aborted.

              Printcap

              @@ -2200,15 +2333,15 @@ Printcap /etc/printers.conf

              Description

              -

              The Printcap directive controls whether or not a -printcap file is automatically generated and updated with a list of -available printers. If specified with no value, then no printcap file -will be generated. The default is to generate a file named -/etc/printcap.

              -

              When a filename is specified (e.g. /etc/printcap), the -printcap file is written whenever a printer is added or removed. The -printcap file can then be used by applications that are hardcoded to -look at the printcap file for the available printers. +

              The Printcap directive controls whether or not a + printcap file is automatically generated and updated with a list of + available printers. If specified with no value, then no printcap file + will be generated. The default is to generate a file named + /etc/printcap.

              +

              When a filename is specified (e.g. /etc/printcap), the + printcap file is written whenever a printer is added or removed. The + printcap file can then be used by applications that are hardcoded to + look at the printcap file for the available printers.

              PrintcapFormat

              @@ -2221,8 +2354,8 @@ PrintcapFormat Solaris

              Description

              -

              The PrintcapFormat directive controls the output format -of the printcap file. The default is to generate a BSD printcap file. +

              The PrintcapFormat directive controls the output format + of the printcap file. The default is to generate a BSD printcap file.

              RemoteRoot

              @@ -2235,10 +2368,10 @@ RemoteRoot root

              Description

              -

              The RemoteRoot directive sets the username for -unauthenticated root requests from remote hosts. The default username -is remroot. Setting RemoteRoot to root - effectively disables this security mechanism. +

              The RemoteRoot directive sets the username for + unauthenticated root requests from remote hosts. The default username + is remroot. Setting RemoteRoot to root + effectively disables this security mechanism.

              RequestRoot

              @@ -2251,11 +2384,11 @@ RequestRoot /foo/bar/spool/cups

              Description

              -

              The RequestRoot directive sets the directory for -incoming IPP requests and HTML forms. If an absolute path is not -provided then it is assumed to be relative to the -ServerRoot directory. The default request directory is -/var/spool/cups. +

              The RequestRoot directive sets the directory for + incoming IPP requests and HTML forms. If an absolute path is not + provided then it is assumed to be relative to the + ServerRoot directory. The default request directory is + /var/spool/cups.

              RIPCache

              @@ -2269,11 +2402,11 @@ RIPCache 2048k

              Description

              -

              The RIPCache directive sets the size of the memory -cache used by Raster Image Processor ("RIP") filters such as -imagetoraster and pstoraster. The size can be -suffixed with a "k" for kilobytes, "m" for megabytes, or "g" for -gigabytes. The default cache size is "8m", or 8 megabytes. +

              The RIPCache directive sets the size of the memory cache + used by Raster Image Processor ("RIP") filters such as +imagetoraster and pstoraster. The size can be + suffixed with a "k" for kilobytes, "m" for megabytes, or "g" for + gigabytes. The default cache size is "8m", or 8 megabytes.

              RunAsUser

              @@ -2286,16 +2419,16 @@ RunAsUser No

              Description

              -

              The RunAsUser directive controls whether the scheduler -runs as the unpriviledged user account (usually lp). The -default is No which leaves the scheduler running as the -root user.

              -

              Note: Running as a non-priviledged user may prevent LPD and -locally connected printers from working due to permission problems. The -lpd backend will automatically use a non-priviledged mode that -is not 100% compliant with RFC 1179. The parallel, -serial, and usb backends will need write access to -the corresponding device files. +

              The RunAsUser directive controls whether the scheduler + runs as the unpriviledged user account (usually lp). The + default is No which leaves the scheduler running as the +root user.

              +

              Note: Running as a non-priviledged user may prevent LPD and + locally connected printers from working due to permission problems. The + lpd backend will automatically use a non-priviledged mode + that is not 100% compliant with RFC 1179. The parallel, +serial, and usb backends will need write access to + the corresponding device files.

              ServerAdmin

              @@ -2308,10 +2441,10 @@ ServerAdmin root@foo.bar.com

              Description

              -

              The ServerAdmin directive identifies the email address -for the administrator on the system. By default the administrator email -address is root@server, where server is the -server name. +

              The ServerAdmin directive identifies the email address + for the administrator on the system. By default the administrator email + address is root@server, where server is the + server name.

              ServerBin

              @@ -2324,11 +2457,11 @@ ServerBin /foo/bar/lib/cups

              Description

              -

              The ServerBin directive sets the directory for -server-run executables. If an absolute path is not provided then it is -assumed to be relative to the ServerRoot - directory. The default executable directory is /usr/lib/cups - or /usr/lib32/cups (IRIX 6.5). +

              The ServerBin directive sets the directory for + server-run executables. If an absolute path is not provided then it is + assumed to be relative to the ServerRoot + directory. The default executable directory is /usr/lib/cups + or /usr/lib32/cups (IRIX 6.5).

              ServerCertificate

              @@ -2340,12 +2473,12 @@ ServerCertificate /etc/cups/ssl/server.crt

              Description

              -

              The ServerCertificate directive specifies the location -of the SSL certificate file used by the server when negotiating -encrypted connections. The certificate must not be encrypted (password -protected) since the scheduler normally runs in the background and will -be unable to ask for a password. The default certificate file is -/etc/cups/ssl/server.crt. +

              The ServerCertificate directive specifies the location + of the SSL certificate file used by the server when negotiating + encrypted connections. The certificate must not be encrypted (password + protected) since the scheduler normally runs in the background and will + be unable to ask for a password. The default certificate file is + /etc/cups/ssl/server.crt.

              ServerKey

              @@ -2357,10 +2490,10 @@ ServerKey /etc/cups/ssl/server.key

              Description

              -

              The ServerKey directive specifies the location of the -SSL private key file used by the server when negotiating encrypted -connections. The default key file is /etc/cups/ssl/server.crt -. +

              The ServerKey directive specifies the location of the + SSL private key file used by the server when negotiating encrypted + connections. The default key file is /etc/cups/ssl/server.crt +.

              ServerName

              @@ -2373,8 +2506,8 @@ ServerName myserver.domain.com

              Description

              -

              The ServerName directive specifies the hostname that is -reported to clients. By default the server name is the hostname. +

              The ServerName directive specifies the hostname that is + reported to clients. By default the server name is the hostname.

              ServerRoot

              @@ -2387,10 +2520,10 @@ ServerRoot /foo/bar/cups

              Description

              -

              The ServerRoot directive specifies the absolute path to -the server configuration and state files. It is also used to resolve -relative paths in the cupsd.conf file. The default server -directory is /etc/cups. +

              The ServerRoot directive specifies the absolute path to + the server configuration and state files. It is also used to resolve + relative paths in the cupsd.conf file. The default server + directory is /etc/cups.

              SSLListen

              @@ -2403,12 +2536,12 @@ SSLListen 192.0.2.1:443

              Description

              -

              The SSLListen directive specifies a network address and -port to listen for secure connections. Multiple SSLListen - directives can be provided to listen on multiple addresses.

              -

              The SSLListen directive is similar to the -SSLPort directive but allows you to restrict access to -specific interfaces or networks. +

              The SSLListen directive specifies a network address and + port to listen for secure connections. Multiple SSLListen + directives can be provided to listen on multiple addresses.

              +

              The SSLListen directive is similar to the + SSLPort directive but allows you to restrict access to + specific interfaces or networks.

              SSLPort

              @@ -2420,9 +2553,9 @@ SSLPort 443

              Description

              -

              The SSLPort directive specifies a port to listen on for -secure connections. Multiple SSLPort lines can be -specified to listen on multiple ports. +

              The SSLPort directive specifies a port to listen on for + secure connections. Multiple SSLPort lines can be + specified to listen on multiple ports.

              SystemGroup

              @@ -2436,10 +2569,10 @@ SystemGroup root

              Description

              -

              The SystemGroup directive specifies the system -administration group for System authentication. More -information can be found later in this chapter in -"Printing System Security". +

              The SystemGroup directive specifies the system + administration group for System authentication. More + information can be found later in this chapter in + "Printing System Security".

              TempDir

              @@ -2452,13 +2585,13 @@ TempDir /foo/bar/tmp

              Description

              -

              The TempDir directive specifies an absolute path for -the directory to use for temporary files. The default directory is -/var/tmp.

              -

              Temporary directories must be world-writable and should have the -"sticky" permission bit enabled so that other users cannot delete -filter temporary files. The following commands will create an -appropriate temporary directory called /foo/bar/tmp:

              +

              The TempDir directive specifies an absolute path for the + directory to use for temporary files. The default directory is + /var/tmp.

              +

              Temporary directories must be world-writable and should have the + "sticky" permission bit enabled so that other users cannot delete + filter temporary files. The following commands will create an + appropriate temporary directory called /foo/bar/tmp:

                 mkdir /foo/bar/tmp ENTER
                @@ -2477,9 +2610,9 @@ Timeout 90
                 

              Description

              -

              The Timeout directive controls the amount of time to -wait before an active HTTP or IPP request times out. The default -timeout is 300 seconds. +

              The Timeout directive controls the amount of time to + wait before an active HTTP or IPP request times out. The default + timeout is 300 seconds.

              User

              @@ -2492,22 +2625,22 @@ User guest

              Description

              -

              The User directive specifies the UNIX user that filter -and CGI programs run as. The default user is lp. +

              The User directive specifies the UNIX user that filter + and CGI programs run as. The default user is lp.

              Printing System Security

              -

              CUPS provides support for address, certificate, and password (Basic -and Digest) based authentication and access control. Certificate and -password authentication provide ways to limit access to individual -people or groups.

              -

              Address based access control allows you to limit access to specific -systems, networks, or domains. While this does not provide -authentication, it does allow you to limit the potential users of your -system efficiently.

              -

              CUPS maintains a list of locations that have access control and/or -authentication enabled. Locations are specified using the -Location directive:

              +

              CUPS provides support for address, certificate, and password (Basic + and Digest) based authentication and access control. Certificate and + password authentication provide ways to limit access to individual + people or groups.

              +

              Address based access control allows you to limit access to specific + systems, networks, or domains. While this does not provide + authentication, it does allow you to limit the potential users of your + system efficiently.

              +

              CUPS maintains a list of locations that have access control and/or + authentication enabled. Locations are specified using the + Location directive:

                 <Location /resource>
                @@ -2521,9 +2654,9 @@ authentication enabled. Locations are specified using the 
                 </Location>
                 
              -

              Locations generally follow the directory structure of the -DocumentRoot directory, however CUPS does have several -virtual locations for administration, classes, jobs, and printers: +

              Locations generally follow the directory structure of the + DocumentRoot directory, however CUPS does have several + virtual locations for administration, classes, jobs, and printers:

              @@ -2542,69 +2675,68 @@ name.

              Authentication Using Certificates

              -

              CUPS supports a local certificate-based authentication scheme that -can be used in place of Basic or Digest +

              CUPS supports a local certificate-based authentication scheme that + can be used in place of Basic or Digest authentication by clients connecting through the localhost - interface. Certificate authentication is not supported or allowed from -clients on any other interface.

              -

              Certificates are 128-bit random numbers that refer to an internal -authentication record in the server. A client connecting via the -localhost interface sends a request with an authorization header -of:

              + interface. Certificate authentication is not supported or allowed from + clients on any other interface.

              +

              Certificates are 128-bit random numbers that refer to an internal + authentication record in the server. A client connecting via the +localhost interface sends a request with an authorization header + of:

                 Authorization: Local 0123456789ABCDEF0123456789ABCDEF
                 
              -

              The server then looks up the local certificate and authenticates -using the username associated with it.

              -

              Certificates are generated by the server automatically and stored in -the /etc/cups/certs directory using the process ID of the -CGI program started by the server. Certificate files are only readable -by the User and -Group defined in the cupsd.conf file. When the -CGI program ends the certificate is removed and invalidated -automatically.

              -

              The special file /etc/cups/certs/0 defines the root -certificate which can be used by any client running as the -super-user or another user that is part of the group defined by the -SystemGroup directive. The root certificate is -automatically regenerated every 5 minutes.

              +

              The server then looks up the local certificate and authenticates + using the username associated with it.

              +

              Certificates are generated by the server automatically and stored in + the /etc/cups/certs directory using the process ID of the + CGI program started by the server. Certificate files are only readable + by the User and +Group defined in the cupsd.conf file. When the CGI + program ends the certificate is removed and invalidated automatically.

              +

              The special file /etc/cups/certs/0 defines the root + certificate which can be used by any client running as the + super-user or another user that is part of the group defined by the + SystemGroup directive. The root certificate is + automatically regenerated every 5 minutes.

              Using Basic Authentication

              -

              Basic authentication uses UNIX users and passwords to authenticate -access to resources such as printers and classes, and to limit access -to administrative functions. +

              Basic authentication uses UNIX users and passwords to authenticate + access to resources such as printers and classes, and to limit access + to administrative functions.

              LocationDescription
              NOTE: -

              Basic authentication sends the username and password Base64 encoded -from the client to the server, so it offers no protection against -eavesdropping. This means that a malicious user can monitor network -packets and discover valid users and passwords that could result in a -serious compromise in network security. Use Basic authentication with -extreme care.

              +

              Basic authentication sends the username and password Base64 encoded + from the client to the server, so it offers no protection against + eavesdropping. This means that a malicious user can monitor network + packets and discover valid users and passwords that could result in a + serious compromise in network security. Use Basic authentication with + extreme care.

              -

              The CUPS implementation of Basic authentication does not allow -access through user accounts without a password. If you try to -authenticate using an account without a password, your access will be -immediately blocked.

              -

              Once a valid username and password is authenticated by CUPS, any -additional group membership requirements are checked. +

              The CUPS implementation of Basic authentication does not allow access + through user accounts without a password. If you try to authenticate + using an account without a password, your access will be immediately + blocked.

              +

              Once a valid username and password is authenticated by CUPS, any + additional group membership requirements are checked.

              NOTE: -

              The root user is considered by CUPS to be a member of every group.

              +

              The root user is considered by CUPS to be a member of every group.

              -

              Use the AuthType directive to enable Basic -authentication:

              +

              Use the AuthType directive to enable Basic + authentication:

                 AuthType Basic
                @@ -2613,42 +2745,41 @@ AuthType Basic
                 
                 
                 

                Using Digest Authentication

                -

                Digest authentication uses users and passwords defined in the -/etc/cups/passwd.md5 file to authenticate access to resources -such as printers and classes, and to limit access to administrative -functions. +

                Digest authentication uses users and passwords defined in the + /etc/cups/passwd.md5 file to authenticate access to resources + such as printers and classes, and to limit access to administrative + functions.

                NOTE: -

                Unlike Basic authentication, Digest passes the MD5 sum (basically a -complicated checksum) of the username and password instead of the -strings themselves. Also, Digest authentication does not use the UNIX -password file, so if an attacker does discover the original password -it is less likely to result in a serious security problem so long as -you use a different UNIX password than the corresponding Digest -password.

                -

                The current CUPS implementation of Digest authentication uses the -client's hostname or IP address for the "nonce" value. The nonce value -is an additional string added to the username and password to make -guessing the password more difficult. The server checks that the nonce -value matches the client's hostname or address and rejects the MD5 sum -if it doesn't. Future versions of CUPS will support Digest "session" -authentication which adds the request data to the MD5 sum, providing -even better authentication and security.

                -

                Digest authentication does not guarantee that an attacker cannot -gain unauthorized access, but it is safer than Basic authentication -and should be used in place of Basic authentication whenever possible. -Support for Digest authentication in web browsers is not yet -universally available.

                +

                Unlike Basic authentication, Digest passes the MD5 sum (basically a + complicated checksum) of the username and password instead of the + strings themselves. Also, Digest authentication does not use the UNIX + password file, so if an attacker does discover the original password it + is less likely to result in a serious security problem so long as you + use a different UNIX password than the corresponding Digest password.

                +

                The current CUPS implementation of Digest authentication uses the + client's hostname or IP address for the "nonce" value. The nonce value + is an additional string added to the username and password to make + guessing the password more difficult. The server checks that the nonce + value matches the client's hostname or address and rejects the MD5 sum + if it doesn't. Future versions of CUPS will support Digest "session" + authentication which adds the request data to the MD5 sum, providing + even better authentication and security.

                +

                Digest authentication does not guarantee that an attacker cannot gain + unauthorized access, but it is safer than Basic authentication and + should be used in place of Basic authentication whenever possible. + Support for Digest authentication in web browsers is not yet + universally available.

                -

                The lppasswd(1) command is used to add, change, or -remove accounts from the passwd.md5 file. To add a user to -the default system group, type:

                +

                The lppasswd(1) command is used to add, change, or + remove accounts from the passwd.md5 file. To add a user to + the default system group, type:

                   lppasswd -a user ENTER
                  @@ -2658,7 +2789,7 @@ Password again: (password) ENTER [password is not echoed]
                   
                -

                Once added, a user can change his/her password by typing:

                +

                Once added, a user can change his/her password by typing:

                   lppasswd ENTER
                  @@ -2669,40 +2800,40 @@ Password again: (password) ENTER [password is not echoed]
                   
                -

                To remove a user from the password file, type:

                +

                To remove a user from the password file, type:

                   lppasswd -x user ENTER
                   
                -

                Once a valid username and password is authenticated by CUPS, any -additional group membership requirements are checked. +

                Once a valid username and password is authenticated by CUPS, any + additional group membership requirements are checked.

                NOTE: -

                The root user is considered by CUPS to be a member of every group.

                +

                The root user is considered by CUPS to be a member of every group.

                -

                Use the AuthType directive to enable Digest -authentication:

                +

                Use the AuthType directive to enable Digest + authentication:

                   AuthType Digest
                   

                System and Group Authentication

                -

                The AuthClass directive -controls the level of authentication to perform. System - and Group authentication extend the normal user-based -authentication to require membership in a UNIX group. For System +

                The AuthClass directive + controls the level of authentication to perform. System + and Group authentication extend the normal user-based + authentication to require membership in a UNIX group. For System authentication each user must belong to the sys, -system, or root group; the actual group depends on -the operating system.

                -

                For Group authentication each user must belong to the -group named by the AuthGroupName - directive:

                +system, or root group; the actual group depends on + the operating system.

                +

                For Group authentication each user must belong to the + group named by the AuthGroupName + directive:

                   <Location /path>
                  @@ -2712,10 +2843,10 @@ AuthGroupName mygroup
                   </Location>
                   
                -

                The named group must be a valid UNIX user group, usually defined in -the /etc/group or /etc/netgroup files. -Additionally, when using Digest authentication you need to create user -accounts with the named group:

                +

                The named group must be a valid UNIX user group, usually defined in + the /etc/group or /etc/netgroup files. + Additionally, when using Digest authentication you need to create user + accounts with the named group:

                   lppasswd -g mygroup -a user ENTER
                  @@ -2726,15 +2857,15 @@ Password again: (password) ENTER [password is not echoed]
                   
                   
                   

                  Printer Accounting

                  -

                  ESP Print Pro maintains a log of all accesses, errors, and pages -that are printed. The log files are normally stored in the -/var/log/cups directory. You can change this by editing the -/etc/cups/cupsd.conf configuration file.

                  +

                  ESP Print Pro maintains a log of all accesses, errors, and pages that + are printed. The log files are normally stored in the + /var/log/cups directory. You can change this by editing the + /etc/cups/cupsd.conf configuration file.

                  The access_log File

                  -

                  The access_log file lists each HTTP resource that is -accessed by a web browser or CUPS/IPP client. Each line is in the -so-called "Common Log Format" used by many web servers and web -reporting tools:

                  +

                  The access_log file lists each HTTP resource that is + accessed by a web browser or CUPS/IPP client. Each line is in the + so-called "Common Log Format" used by many web servers and web + reporting tools:

                     host group user date-time \"method resource version\" status bytes
                    @@ -2743,37 +2874,37 @@ host group user date-time \"method resource version\" status bytes
                     127.0.0.1 - mike [20/May/1999:19:20:31 +0000] "POST /admin/ HTTP/1.1" 200 0
                     
                  -

                  The host field will normally only be an IP address unless you -have enabled the HostNameLookups - directive in the cupsd.conf file.

                  -

                  The group field always contains "-" in CUPS.

                  -

                  The user field is the authenticated username of the -requesting user. If no username and password is supplied for the -request then this field contains "-".

                  -

                  The date-time field is the date and time of the request in -local time and is in the format:

                  +

                  The host field will normally only be an IP address unless you + have enabled the HostNameLookups + directive in the cupsd.conf file.

                  +

                  The group field always contains "-" in CUPS.

                  +

                  The user field is the authenticated username of the requesting + user. If no username and password is supplied for the request then this + field contains "-".

                  +

                  The date-time field is the date and time of the request in + local time and is in the format:

                     [DD/MON/YYYY:HH:MM:SS +ZZZZ]
                     
                  -

                  where ZZZZ is the timezone offset in hours and minutes from -Greenwich Mean Time (a.k.a. GMT a.k.a. ZULU.)

                  -

                  The method field is the HTTP method used ("GET", "PUT", -"POST", etc.)

                  -

                  The resource field is the filename of the requested resource.

                  -

                  The version field is the HTTP specification version used by -the client. For CUPS clients this will always be "HTTP/1.1".

                  -

                  The status field contains the HTTP result status of the -request. Usually it is "200", but other HTTP status codes are possible. -For example, 401 is the "unauthorized access" status in the example -above.

                  -

                  The bytes field contains the number of bytes in the request. -For POST requests the bytes field contains the number of bytes -that was received from the client.

                  +

                  where ZZZZ is the timezone offset in hours and minutes from + Greenwich Mean Time (a.k.a. GMT a.k.a. ZULU.)

                  +

                  The method field is the HTTP method used ("GET", "PUT", + "POST", etc.)

                  +

                  The resource field is the filename of the requested resource.

                  +

                  The version field is the HTTP specification version used by + the client. For CUPS clients this will always be "HTTP/1.1".

                  +

                  The status field contains the HTTP result status of the + request. Usually it is "200", but other HTTP status codes are possible. + For example, 401 is the "unauthorized access" status in the example + above.

                  +

                  The bytes field contains the number of bytes in the request. + For POST requests the bytes field contains the number of bytes + that was received from the client.

                  The error_log File

                  -

                  The error_log file lists messages from the scheduler -(errors, warnings, etc.):

                  +

                  The error_log file lists messages from the scheduler + (errors, warnings, etc.):

                     level date-time message
                    @@ -2783,20 +2914,20 @@ I [20/May/1999:19:21:02 +0000] Job 2 queued on 'DeskJet' by 'mike'.
                     I [20/May/1999:19:22:24 +0000] Job 2 was cancelled by 'mike'.
                     
                  -

                  The level field contains the type of message:

                  +

                  The level field contains the type of message:

                    -
                  • E - An error occurred.
                  • -
                  • W - The server was unable to perform some action.
                  • -
                  • I - Informational message.
                  • -
                  • D - Debugging message.
                  • +
                  • E - An error occurred.
                  • +
                  • W - The server was unable to perform some action.
                  • +
                  • I - Informational message.
                  • +
                  • D - Debugging message.
                  -

                  The date-time field contains the date and time of when the -page started printing. The format of this field is identical to the -data-time field in the access_log file.

                  -

                  The message fields contains a free-form textual message.

                  +

                  The date-time field contains the date and time of when the + page started printing. The format of this field is identical to the + data-time field in the access_log file.

                  +

                  The message fields contains a free-form textual message.

                  The page_log File

                  -

                  The page_log file lists each page that is sent to a -printer. Each line contains the following information:

                  +

                  The page_log file lists each page that is sent to a + printer. Each line contains the following information:

                     printer user job-id date-time page-number num-copies job-billing
                    @@ -2804,42 +2935,42 @@ printer user job-id date-time page-number num-copies job-billing
                     DeskJet root 2 [20/May/1999:19:21:05 +0000] 1 0 acme-123
                     
                  -

                  The printer field contains the name of the printer that -printed the page. If you send a job to a printer class, this field will -contain the name of the printer that was assigned the job.

                  -

                  The user field contains the name of the user (the IPP -requesting-user-name attribute) that submitted this file for -printing.

                  -

                  The job-id field contains the job number of the page being -printed. Job numbers are reset to 1 whenever the CUPS server is -started, so don't depend on this number being unique!

                  -

                  The date-time field contains the date and time of when the -page started printing. The format of this field is identical to the -data-time field in the access_log file.

                  -

                  The page-number and num-pages fields contain the page -number and number of copies being printed of that page. For printer -that can not produce copies on their own, the num-pages field -will always be 1.

                  -

                  The job-billing field contains a copy of the job-billing +

                  The printer field contains the name of the printer that + printed the page. If you send a job to a printer class, this field will + contain the name of the printer that was assigned the job.

                  +

                  The user field contains the name of the user (the IPP +requesting-user-name attribute) that submitted this file for + printing.

                  +

                  The job-id field contains the job number of the page being + printed. Job numbers are reset to 1 whenever the CUPS server is + started, so don't depend on this number being unique!

                  +

                  The date-time field contains the date and time of when the + page started printing. The format of this field is identical to the + data-time field in the access_log file.

                  +

                  The page-number and num-pages fields contain the page + number and number of copies being printed of that page. For printer + that can not produce copies on their own, the num-pages field + will always be 1.

                  +

                  The job-billing field contains a copy of the job-billing attribute provided with the IPP create-job or -print-job requests or "-" if none was provided. +print-job requests or "-" if none was provided.

                  File Typing and Filtering

                  -

                  CUPS provides a MIME-based file typing and filtering mechanism to -convert files to a printable format for each printer. On startup the -CUPS server reads MIME database files from the /etc/cups - directory (or a directory specified by the -ServerRoot directive) to build a file type and conversion -database in memory. These database files are plain ASCII text and can -be edited with your favorite text editor.

                  -

                  The mime.types and mime.convs files define the -standard file types and filters that are available on the system.

                  +

                  CUPS provides a MIME-based file typing and filtering mechanism to + convert files to a printable format for each printer. On startup the + CUPS server reads MIME database files from the /etc/cups + directory (or a directory specified by the +ServerRoot directive) to build a file type and conversion + database in memory. These database files are plain ASCII text and can + be edited with your favorite text editor.

                  +

                  The mime.types and mime.convs files define the + standard file types and filters that are available on the system.

                  mime.types

                  -

                  The mime.types file defines the known file types. Each -line of the file starts with the MIME type and may be followed by one -or more file type recognition rules. For example, the text/html - file type is defined as:

                  +

                  The mime.types file defines the known file types. Each + line of the file starts with the MIME type and may be followed by one + or more file type recognition rules. For example, the text/html + file type is defined as:

                     text/html       html htm \
                    @@ -2847,46 +2978,46 @@ text/html       html htm \
                                     (string(0,"<HTML>") string(0,"<!DOCTYPE"))
                     
                  -

                  The first two rules say that any file with an extension of .html - or .htm is a HTML file. The third rule says that any file -whose first 1024 characters are printable text and starts with the -strings <HTML> or <!DOCTYPE is a HTML file as -well.

                  -

                  The first two rules deal solely with the name of the file being -typed. This is useful when the original filename is known, however for -print files the server doesn't have a filename to work with. The third -rule takes care of this possibility and automatically figures out the -file type based upon the contents of the file instead.

                  -

                  The available tests are:

                  -
                    -
                  • ( expr ) - Parenthesis for expression grouping
                  • -
                  • + - Logical AND
                  • -
                  • , or whitespace - Logical OR
                  • -
                  • ! - Logical NOT
                  • -
                  • match("pattern") - Pattern match on filename
                  • -
                  • extension - Pattern match on "*.extension"
                  • -
                  • ascii(offset,length) - True if bytes are valid - printable ASCII (CR, NL, TAB, BS, 32-126)
                  • -
                  • printable(offset,length) - True if bytes are - printable 8-bit chars (CR, NL, TAB, BS, 32-126, 160-254)
                  • -
                  • string(offset,"string") - True if bytes are identical -to string
                  • -
                  • contains(offset,range,"string") - True if the range -of bytes contains the string
                  • -
                  • char(offset,value) - True if byte is identical
                  • -
                  • short(offset,value) - True if 16-bit integer is -identical (network or "big-endian" byte order)
                  • -
                  • int(offset,value) - True if 32-bit integer is - identical (network or "big-endian" byte order)
                  • -
                  • locale("string") - True if current locale matches -string
                  • -
                  -

                  All numeric values can be in decimal (123), octal (0123), or -hexadecimal (0x123) as desired. +

                  The first two rules say that any file with an extension of .html + or .htm is a HTML file. The third rule says that any file + whose first 1024 characters are printable text and starts with the + strings <HTML> or <!DOCTYPE is a HTML file as + well.

                  +

                  The first two rules deal solely with the name of the file being + typed. This is useful when the original filename is known, however for + print files the server doesn't have a filename to work with. The third + rule takes care of this possibility and automatically figures out the + file type based upon the contents of the file instead.

                  +

                  The available tests are:

                  +
                    +
                  • ( expr ) - Parenthesis for expression grouping
                  • +
                  • + - Logical AND
                  • +
                  • , or whitespace - Logical OR
                  • +
                  • ! - Logical NOT
                  • +
                  • match("pattern") - Pattern match on filename
                  • +
                  • extension - Pattern match on "*.extension"
                  • +
                  • ascii(offset,length) - True if bytes are valid + printable ASCII (CR, NL, TAB, BS, 32-126)
                  • +
                  • printable(offset,length) - True if bytes are printable + 8-bit chars (CR, NL, TAB, BS, 32-126, 160-254)
                  • +
                  • string(offset,"string") - True if bytes are identical + to string
                  • +
                  • contains(offset,range,"string") - True if the range of + bytes contains the string
                  • +
                  • char(offset,value) - True if byte is identical
                  • +
                  • short(offset,value) - True if 16-bit integer is + identical (network or "big-endian" byte order)
                  • +
                  • int(offset,value) - True if 32-bit integer is identical + (network or "big-endian" byte order)
                  • +
                  • locale("string") - True if current locale matches + string
                  • +
                  +

                  All numeric values can be in decimal (123), octal (0123), or + hexadecimal (0x123) as desired.

                  -

                  Strings can be in quotes, all by themselves, as a string of -hexadecimal values, or some combination:

                  +

                  Strings can be in quotes, all by themselves, as a string of + hexadecimal values, or some combination:

                     "string"
                    @@ -2896,9 +3027,9 @@ string
                     <7374>ring
                     
                  -

                  As shown in the text/html example, rules can continue -on multiple lines using the backslash (\) character. A more complex -example is the image/jpeg rules:

                  +

                  As shown in the text/html example, rules can continue on + multiple lines using the backslash (\) character. A more complex + example is the image/jpeg rules:

                     image/jpeg      jpeg jpg jpe string(0,<FFD8FF>) &&\
                    @@ -2908,14 +3039,15 @@ image/jpeg      jpeg jpg jpe string(0,<FFD8FF>) &&\
                                      char(3,0xec) char(3,0xed) char(3,0xee) char(3,0xef))
                     
                  -

                  This rule states that any file with an extension of .jpeg -, .jpg, or .jpe is a JPEG file. In addition, any -file starting with the hexadecimal string <FFD8FF> (JPEG -Start-Of-Image) followed by a character between and including 0xe0 - and 0xef (JPEG APPn markers) is also a JPEG file.

                  +

                  This rule states that any file with an extension of .jpeg, + .jpg, or .jpe is a JPEG file. In addition, any file + starting with the hexadecimal string <FFD8FF> (JPEG + Start-Of-Image) followed by a character between and including +0xe0 and 0xef (JPEG APPn markers) is also a JPEG + file.

                  mime.convs

                  -

                  The mime.convs file defines all of the filter programs -that are known to the system. Each line consists of:

                  +

                  The mime.convs file defines all of the filter programs + that are known to the system. Each line consists of:

                     source destination cost program
                    @@ -2926,107 +3058,107 @@ image/* application/vnd.cups-postscript 50 imagetops
                     image/* application/vnd.cups-raster 50 imagetoraster
                     
                  -

                  The source field is a MIME type, optionally using a wildcard -for the super-type or sub-type (e.g. "text/plain", "image/*", -"*/postscript").

                  -

                  The destination field is a MIME type defined in the -mime.types file.

                  -

                  The cost field defines a relative cost for the filtering -operation from 1 to 100. The cost is used to choose between two -different sets of filters when converting a file. For example, to -convert from image/jpeg to +

                  The source field is a MIME type, optionally using a wildcard + for the super-type or sub-type (e.g. "text/plain", "image/*", + "*/postscript").

                  +

                  The destination field is a MIME type defined in the + mime.types file.

                  +

                  The cost field defines a relative cost for the filtering + operation from 1 to 100. The cost is used to choose between two + different sets of filters when converting a file. For example, to + convert from image/jpeg to application/vnd.cups-raster, you could use the imagetops and pstoraster filters for a total cost of 100, or the -imagetoraster filter for a total cost of 50.

                  -

                  The program field defines the filter program to run; the -special program "-" can be used to make two file types equivalent. The -program must accept the standard filter arguments and environment -variables described in the CUPS Interface Design Description and CUPS -Software Programmers Manual:

                  +imagetoraster
                  filter for a total cost of 50.

                  +

                  The program field defines the filter program to run; the + special program "-" can be used to make two file types equivalent. The + program must accept the standard filter arguments and environment + variables described in the CUPS Interface Design Description and CUPS + Software Programmers Manual:

                     program job user title options [filename]
                     
                  -

                  If specified, the filename argument defines a file to read -when filtering, otherwise the filter must read from the standard input. -All filtered output must go to the standard output. +

                  If specified, the filename argument defines a file to read + when filtering, otherwise the filter must read from the standard input. + All filtered output must go to the standard output.

                  Adding Filetypes and Filters

                  -

                  Adding a new file type or filter is fairly straight-forward. Rather -than adding the new type and filter to the mime.types and -mime.convs files which are overwritten when you upgrade to a new -version of CUPS, you simple need to create new files with .types - and .convs extensions in the /etc/cups - directory. We recommend that you use the product or format name, e.g.:

                  +

                  Adding a new file type or filter is fairly straight-forward. Rather + than adding the new type and filter to the mime.types and + mime.convs files which are overwritten when you upgrade to a new + version of CUPS, you simple need to create new files with .types + and .convs extensions in the /etc/cups directory. + We recommend that you use the product or format name, e.g.:

                     myproduct.types
                     myproduct.convs
                     
                  -

                  If you are providing a filter for a common file format or printer, -add the company or author name:

                  +

                  If you are providing a filter for a common file format or printer, + add the company or author name:

                     acme-msword.types
                     acme.msword.convs
                     
                  -

                  This will help to prevent name collisions if you install many -different file types and filters.

                  -

                  Once you choose the names for these files, create them using your -favorite text editor as described earlier in this chapter. Once you -have created the files, restart the cupsd process as -described earlier in "Restarting the CUPS Server" -.

                  +

                  This will help to prevent name collisions if you install many + different file types and filters.

                  +

                  Once you choose the names for these files, create them using your + favorite text editor as described earlier in this chapter. Once you + have created the files, restart the cupsd process as + described earlier in "Restarting the CUPS Server" +.

                  Printer Drivers and PPD Files

                  -

                  Most CUPS printer drivers utilize one or more printer-specific -filters and a PPD file for each printer model. Printer driver filters -are registered via the PPD file using cupsFilter - attributes:

                  +

                  Most CUPS printer drivers utilize one or more printer-specific + filters and a PPD file for each printer model. Printer driver filters + are registered via the PPD file using cupsFilter + attributes:

                     *cupsFilter: "application/vnd.cups-raster 0 rastertohp"
                     
                  -

                  The filter is specified using the source file type only; the -destination file type is assumed to be printer/name - -suitable for sending to the printer.

                  +

                  The filter is specified using the source file type only; the + destination file type is assumed to be printer/name - + suitable for sending to the printer.

                  Writing Your Own Filter or Printer Driver

                  -

                  CUPS supports an unlimited number of file formats and filters, and -can handle any printer. If you'd like to write a filter or printer -driver for your favorite file format or printer, consult the CUPS -Software Programmers Manual for step-by-step instructions.

                  -

                  7 - Printing with Other -Systems

                  -

                  This chapter describes how to print from client systems that use the -LPD, Mac OS, or Windows printing protocols.

                  +

                  CUPS supports an unlimited number of file formats and filters, and + can handle any printer. If you'd like to write a filter or printer + driver for your favorite file format or printer, consult the CUPS + Software Programmers Manual for step-by-step instructions.

                  +

                  7 - Printing with Other + Systems

                  +

                  This chapter describes how to print from client systems that use the + LPD, Mac OS, or Windows printing protocols.

                  The Basics

                  -

                  CUPS is based on the IPP protocol, so any system that supports IPP -can send jobs to and receive jobs from CUPS automatically. However, not -all systems support IPP yet. This chapter will show you how to connect -these systems to your CUPS server, either to accept jobs from your -server for printing, or to send jobs to your server.

                  +

                  CUPS is based on the IPP protocol, so any system that supports IPP + can send jobs to and receive jobs from CUPS automatically. However, not + all systems support IPP yet. This chapter will show you how to connect + these systems to your CUPS server, either to accept jobs from your + server for printing, or to send jobs to your server.

                  Printing from LPD Clients

                  -

                  CUPS supports limited functionality for LPD-based clients. With LPD -you can print files to specific printers, list the queue status, and so -forth. However, the automatic client configuration and printer options -are not supported by the LPD protocol, so you must manually configure -each client for the printers it needs to access.

                  -

                  The cups-lpd(8) program provides support for LPD -clients. To enable LPD support on your server, edit the -/etc/inetd.conf file and add a line reading:

                  +

                  CUPS supports limited functionality for LPD-based clients. With LPD + you can print files to specific printers, list the queue status, and so + forth. However, the automatic client configuration and printer options + are not supported by the LPD protocol, so you must manually configure + each client for the printers it needs to access.

                  +

                  The cups-lpd(8) program provides support for LPD + clients. To enable LPD support on your server, edit the + /etc/inetd.conf file and add a line reading:

                     printer stream tcp nowait lp /usr/lib/cups/daemon/cups-lpd cups-lpd
                     
                  -

                  The path to the cups-lpd may vary depending on your -installation.

                  -

                  Once you have added this line, send the inetd(8) - process a HUP signal or reboot the system:

                  +

                  The path to the cups-lpd may vary depending on your + installation.

                  +

                  Once you have added this line, send the inetd(8) process + a HUP signal or reboot the system:

                     killall -HUP inetd ENTER [IRIX and some versions of Linux]
                    @@ -3035,39 +3167,39 @@ installation. 

                  Printing to LPD Servers

                  -

                  CUPS provides the lpd backend for printing to LPD-based -servers and printers. Use a device URI of lpd://server/name - to print to a printer on an LPD server, where server is -the hostname or IP address of the server and name is the -queue name.

                  -

                  Microsoft Windows NT provides an LPD service under the name "TCP/IP -Printing Services". To enable LPD printing on NT, open the "Services" -control panel, select the "TCP/IP Printing Services" service, and click -on the "Start" button. Any shared printer will then be available via -the LPD protocol.

                  +

                  CUPS provides the lpd backend for printing to LPD-based + servers and printers. Use a device URI of lpd://server/name + to print to a printer on an LPD server, where server is + the hostname or IP address of the server and name is the + queue name.

                  +

                  Microsoft Windows NT provides an LPD service under the name "TCP/IP + Printing Services". To enable LPD printing on NT, open the "Services" + control panel, select the "TCP/IP Printing Services" service, and click + on the "Start" button. Any shared printer will then be available via + the LPD protocol.

                  Printing from Mac OS Clients

                  -

                  CUPS does not provide Mac OS support directly. However, there are -several free and commercial software packages that do.

                  +

                  CUPS does not provide Mac OS support directly. However, there are + several free and commercial software packages that do.

                  Columbia Appletalk Package (CAP)

                  -

                  Because the CAP LaserWriter server (lwsrv(8)) does not -support specification of PPD files, we do not recommend that you use -CAP with CUPS. However, you can run the lpsrv program for -limited printing with the command:

                  +

                  Because the CAP LaserWriter server (lwsrv(8)) does not + support specification of PPD files, we do not recommend that you use + CAP with CUPS. However, you can run the lpsrv program for + limited printing with the command:

                     lwsrv -n "Name" -p printer -a /usr/lib/adicts -f /usr/lib/LW+Fonts
                     
                  -

                  where Name is the name you want to use when sharing the -printer, and printer is the name of the CUPS print queue. +

                  where Name is the name you want to use when sharing the + printer, and printer is the name of the CUPS print queue.

                  XINET KA/Spool

                  -

                  To use your system as a print server for Mac OS clients, configure -each printer using a papserver(8) in the -/usr/adm/appletalk/services file, specifying the corresponding -PPD file in the /etc/cups/ppd directory for each printer. - For a printer named MyPrinter the entry would look like:

                  +

                  To use your system as a print server for Mac OS clients, configure + each printer using a papserver(8) in the + /usr/adm/appletalk/services file, specifying the corresponding + PPD file in the /etc/cups/ppd directory for each printer. + For a printer named MyPrinter the entry would look like:

                     /usr/etc/appletalk/papserver -I -L -P /etc/cups/ppd/MyPrinter.ppd \
                    @@ -3077,17 +3209,17 @@ PPD file in the /etc/cups/ppd directory for each printer.
                     
                    NOTE: -

                    Enter the text above on a single line without the backslash (\) - character.

                    +

                    Enter the text above on a single line without the backslash (\) + character.

                    NetATalk

                    -

                    To use your system as a print server for Mac OS clients, configure -each printer in the papd.conf file, specifying the -corresponding PPD file in the /etc/cups/ppd directory for -each printer. For a printer named MyPrinter the entry -would look like:

                    +

                    To use your system as a print server for Mac OS clients, configure + each printer in the papd.conf file, specifying the + corresponding PPD file in the /etc/cups/ppd directory for + each printer. For a printer named MyPrinter the entry + would look like:

                       Printer Description:MyPrinter@MyServer:\
                      @@ -3099,14 +3231,14 @@ Printer Description:MyPrinter@MyServer:\
                       
                       
                       

                      Printing to Mac OS Servers

                      -

                      CUPS currently does not provide a backend to communicate with a Mac -OS server. However, you can write and install a short shell script in -the /usr/lib/cups/backend directory that sends a print file -using the appropriate command. The following is a short script that -will run the papif command provided with CAP.

                      -

                      After copying this script to /usr/lib/cups/backend/cap, -specify a device URI of cap://server/printer to use this -backend with a print queue. +

                      CUPS currently does not provide a backend to communicate with a Mac + OS server. However, you can write and install a short shell script in + the /usr/lib/cups/backend directory that sends a print file + using the appropriate command. The following is a short script that + will run the papif command provided with CAP.

                      +

                      After copying this script to /usr/lib/cups/backend/cap, + specify a device URI of cap://server/printer to use this + backend with a print queue.

                        @@ -3169,46 +3301,46 @@ exit 0

                        Printing from Windows Clients

                        -

                        While CUPS does not provide Windows support directly, the free SAMBA -software package does. SAMBA version 2.0.6 is the first release of -SAMBA that supports CUPS. You can download SAMBA from:

                        +

                        While CUPS does not provide Windows support directly, the free SAMBA + software package does. SAMBA version 2.0.6 is the first release of + SAMBA that supports CUPS. You can download SAMBA from:

                        -

                        To configure SAMBA for CUPS, edit the smb.conf file and -replace the existing printing commands and options with the line:

                        +

                        To configure SAMBA for CUPS, edit the smb.conf file and + replace the existing printing commands and options with the line:

                           printing = cups
                           
                        -

                        That's all there is to it! Remote users will now be able to browse -and print to printers on your system.

                        +

                        That's all there is to it! Remote users will now be able to browse + and print to printers on your system.

                        Printing to Windows Servers

                        -

                        CUPS can print to Windows servers in one of two ways. The first way -uses the LPD protocol on the CUPS system and the "TCP/IP Printing -Services" on the Windows system. You can find out more about this -configuration in the LPD section earlier in this -chapter.

                        -

                        The second way is through the Microsoft Server Message Block ("SMB") -protocol. Support for this protocol is provided with the free SAMBA -software package. You can download SAMBA from:

                        +

                        CUPS can print to Windows servers in one of two ways. The first way + uses the LPD protocol on the CUPS system and the "TCP/IP Printing + Services" on the Windows system. You can find out more about this + configuration in the LPD section earlier in this + chapter.

                        +

                        The second way is through the Microsoft Server Message Block ("SMB") + protocol. Support for this protocol is provided with the free SAMBA + software package. You can download SAMBA from:

                        -

                        To configure CUPS for SAMBA, run the following command:

                        +

                        To configure CUPS for SAMBA, run the following command:

                           ln -s `which smbspool` /usr/lib/cups/backend/smb ENTER
                           
                        -

                        The smbspool(1) program is provided with SAMBA starting -with SAMBA 2.0.6. Once you have made the link you can configure your -printers with one of the following device URIs:

                        +

                        The smbspool(1) program is provided with SAMBA starting + with SAMBA 2.0.6. Once you have made the link you can configure your + printers with one of the following device URIs:

                           smb://workgroup/server/sharename
                          @@ -3217,87 +3349,86 @@ smb://user:pass@workgroup/server/sharename
                           smb://user:pass@server/sharename
                           
                        -

                        The workgroup name need only be specified if your -system is using a different workgroup. The user:pass - strings are required when printing to Windows NT servers or to shares -with passwords enabled under Windows 95 and 98.

                        +

                        The workgroup name need only be specified if your system + is using a different workgroup. The user:pass strings are + required when printing to Windows NT servers or to shares with + passwords enabled under Windows 95 and 98.

                        A - Software License Agreement

                        -

                        Common UNIX Printing System License -Agreement

                        +

                        Common UNIX Printing System License + Agreement

                        Copyright 1997-2001 by Easy Software Products
                        44141 AIRPORT VIEW DR STE 204
                        HOLLYWOOD, MARYLAND 20636-3111 USA

                        Voice: +1.301.373.9600 -
                        Email: cups-info@cups.org -
                        WWW: http://www.cups.org

                        +
                        Email: cups-info@cups.org +
                        WWW: http://www.cups.org

                        Introduction

                        -

                        The Common UNIX Printing SystemTM, ("CUPSTM"), -is provided under the GNU General Public License ("GPL") and GNU -Library General Public License ("LGPL"), Version 2. A copy of these -licenses follow this introduction.

                        -

                        The GNU LGPL applies to the CUPS API library, located in the "cups" -subdirectory of the CUPS source distribution and in the -"/usr/include/cups" directory and "libcups.a", "libcups.sl", or -"libcups.so" files in the binary distributions.

                        -

                        The GNU GPL applies to the remainder of the CUPS distribution, -including the "pstoraster" filter which is based upon GNU Ghostscript -5.50 and the "pdftops" filter which is based upon Xpdf 0.90.

                        -

                        For those not familiar with the GNU GPL, the license basically -allows you to:

                        -
                          -
                        • Use the CUPS software at no charge.
                        • -
                        • Distribute verbatim copies of the software in source or binary -form.
                        • -
                        • Sell verbatim copies of the software for a media fee, or sell -support for the software.
                        • -
                        • Distribute or sell printer drivers and filters that use CUPS so -long as source code is made available under the GPL.
                        • -
                        -

                        What this license does not allow you to do is make changes or -add features to CUPS and then sell a binary distribution without source -code. You must provide source for any new drivers, changes, or -additions to the software, and all code must be provided under the GPL -or LGPL as appropriate.

                        -

                        The GNU LGPL relaxes the "link-to" restriction, allowing you to -develop applications that use the CUPS API library under other licenses -and/or conditions as appropriate for your application.

                        +

                        The Common UNIX Printing SystemTM, ("CUPSTM"), + is provided under the GNU General Public License ("GPL") and GNU + Library General Public License ("LGPL"), Version 2. A copy of these + licenses follow this introduction.

                        +

                        The GNU LGPL applies to the CUPS API library, located in the "cups" + subdirectory of the CUPS source distribution and in the + "/usr/include/cups" directory and "libcups.a", "libcups_s.a", + "libcups.sl", or "libcups.so" files in the binary distributions.

                        +

                        The GNU GPL applies to the remainder of the CUPS distribution, + including the "pstoraster" filter which is based upon GNU Ghostscript + 5.50 and the "pdftops" filter which is based upon Xpdf 0.93a.

                        +

                        For those not familiar with the GNU GPL, the license basically allows + you to:

                        +
                          +
                        • Use the CUPS software at no charge.
                        • +
                        • Distribute verbatim copies of the software in source or binary form.
                        • +
                        • Sell verbatim copies of the software for a media fee, or sell + support for the software.
                        • +
                        • Distribute or sell printer drivers and filters that use CUPS so long + as source code is made available under the GPL.
                        • +
                        +

                        What this license does not allow you to do is make changes or + add features to CUPS and then sell a binary distribution without source + code. You must provide source for any new drivers, changes, or + additions to the software, and all code must be provided under the GPL + or LGPL as appropriate.

                        +

                        The GNU LGPL relaxes the "link-to" restriction, allowing you to + develop applications that use the CUPS API library under other licenses + and/or conditions as appropriate for your application.

                        Trademarks

                        -

                        Easy Software Products has trademarked the Common UNIX Printing -System, CUPS, and CUPS logo. These names and logos may be used freely -in any direct port or binary distribution of CUPS. To use them in -derivative products, please contract Easy Software Products for written -permission. Our intention is to protect the value of these trademarks -and ensure that any derivative product meets the same high-quality -standards as the original.

                        +

                        Easy Software Products has trademarked the Common UNIX Printing + System, CUPS, and CUPS logo. These names and logos may be used freely + in any direct port or binary distribution of CUPS. To use them in + derivative products, please contract Easy Software Products for written + permission. Our intention is to protect the value of these trademarks + and ensure that any derivative product meets the same high-quality + standards as the original.

                        Binary Distribution Rights

                        -

                        Easy Software Products also sells rights to the CUPS source code -under a binary distribution license for vendors that are unable to -release source code for their drivers, additions, and modifications to -CUPS under the GNU GPL and LGPL. For information please contact us at -the address shown above.

                        -

                        The Common UNIX Printing System provides a "pstoraster" filter that -utilizes the GNU GhostScript 5.50 core to convert PostScript files into -a stream of raster images. For binary distribution licensing of this -software, please contact:

                        Miles Jones +

                        Easy Software Products also sells rights to the CUPS source code + under a binary distribution license for vendors that are unable to + release source code for their drivers, additions, and modifications to + CUPS under the GNU GPL and LGPL. For information please contact us at + the address shown above.

                        +

                        The Common UNIX Printing System provides a "pstoraster" filter that + utilizes the GNU GhostScript 5.50 core to convert PostScript files into + a stream of raster images. For binary distribution licensing of this + software, please contact:

                        Miles Jones
                        Director of Marketing
                        Artifex Software Inc.
                        454 Las Gallinas Ave., Suite 108
                        San Rafael, CA 94903 USA
                        Voice: +1.415.492.9861
                        Fax: +1.415.492.9862 -
                        EMail: info@arsoft.com
                        +
                        EMail: info@arsoft.com

                        -

                        The "pdftops" filter is based on the Xpdf 0.90 software. For binary -distribution licensing of this software, please contact:

                        +

                        The "pdftops" filter is based on the Xpdf 0.93a software. For binary + distribution licensing of this software, please contact:

                        Derek B. Noonburg -
                        Email: derekn@foolabs.com -
                        WWW: -http://www.foolabs.com/xpdf/

                        +
                        Email: derekn@foolabs.com +
                        WWW: + http://www.foolabs.com/xpdf/

                        Support

                        -

                        Easy Software Products sells software support for CUPS as well as a -commercial printing product based on CUPS called ESP Print Pro. You can -find out more at our web site:

                        +

                        Easy Software Products sells software support for CUPS as well as a + commercial printing product based on CUPS called ESP Print Pro. You can + find out more at our web site:

                           http://www.easysw.com
                          @@ -3306,7 +3437,7 @@ find out more at our web site: 

                          GNU GENERAL PUBLIC LICENSE

                          -

                          Version 2, June 1991

                          +

                          Version 2, June 1991

                           Copyright 1989, 1991 Free Software Foundation, Inc.
                           59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
                          @@ -3318,252 +3449,250 @@ copies of this license document, but changing it is not allowed.
                           
                           

                          Preamble

                          -

                          The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too.

                          -

                          When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it in -new free programs; and that you know you can do these things.

                          -

                          To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it.

                          -

                          For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights.

                          -

                          We protect your rights with two steps: (1) copyright the software, -and (2) offer you this license which gives you legal permission to -copy, distribute and/or modify the software.

                          -

                          Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, -we want its recipients to know that what they have is not the original, -so that any problems introduced by others will not reflect on the -original authors' reputations.

                          -

                          Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all.

                          -

                          The precise terms and conditions for copying, distribution and -modification follow.

                          +

                          The licenses for most software are designed to take away your freedom + to share and change it. By contrast, the GNU General Public License is + intended to guarantee your freedom to share and change free + software--to make sure the software is free for all its users. This + General Public License applies to most of the Free Software + Foundation's software and to any other program whose authors commit to + using it. (Some other Free Software Foundation software is covered by + the GNU Library General Public License instead.) You can apply it to + your programs, too.

                          +

                          When we speak of free software, we are referring to freedom, not + price. Our General Public Licenses are designed to make sure that you + have the freedom to distribute copies of free software (and charge for + this service if you wish), that you receive source code or can get it + if you want it, that you can change the software or use pieces of it in + new free programs; and that you know you can do these things.

                          +

                          To protect your rights, we need to make restrictions that forbid + anyone to deny you these rights or to ask you to surrender the rights. + These restrictions translate to certain responsibilities for you if you + distribute copies of the software, or if you modify it.

                          +

                          For example, if you distribute copies of such a program, whether + gratis or for a fee, you must give the recipients all the rights that + you have. You must make sure that they, too, receive or can get the + source code. And you must show them these terms so they know their + rights.

                          +

                          We protect your rights with two steps: (1) copyright the software, + and (2) offer you this license which gives you legal permission to + copy, distribute and/or modify the software.

                          +

                          Also, for each author's protection and ours, we want to make certain + that everyone understands that there is no warranty for this free + software. If the software is modified by someone else and passed on, we + want its recipients to know that what they have is not the original, so + that any problems introduced by others will not reflect on the original + authors' reputations.

                          +

                          Finally, any free program is threatened constantly by software + patents. We wish to avoid the danger that redistributors of a free + program will individually obtain patent licenses, in effect making the + program proprietary. To prevent this, we have made it clear that any + patent must be licensed for everyone's free use or not licensed at all.

                          +

                          The precise terms and conditions for copying, distribution and + modification follow.

                          GNU GENERAL PUBLIC LICENSE
                          TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

                            -
                          1. This License applies to any program or other work which contains a -notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you".
                          2. -

                            Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the Program -(independent of having been made by running the Program). Whether that -is true depends on what the Program does.

                            -
                          3. You may copy and distribute verbatim copies of the Program's source -code as you receive it, in any medium, provided that you conspicuously -and appropriately publish on each copy an appropriate copyright notice -and disclaimer of warranty; keep intact all the notices that refer to -this License and to the absence of any warranty; and give any other -recipients of the Program a copy of this License along with the -Program.
                          4. -

                            You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee.

                            -
                          5. You may modify your copy or copies of the Program or any portion of -it, thus forming a work based on the Program, and copy and distribute -such modifications or work under the terms of Section 1 above, provided -that you also meet all of these conditions: +
                          6. This License applies to any program or other work which contains a + notice placed by the copyright holder saying it may be distributed + under the terms of this General Public License. The "Program", below, + refers to any such program or work, and a "work based on the Program" + means either the Program or any derivative work under copyright law: + that is to say, a work containing the Program or a portion of it, + either verbatim or with modifications and/or translated into another + language. (Hereinafter, translation is included without limitation in + the term "modification".) Each licensee is addressed as "you".
                          7. +

                            Activities other than copying, distribution and modification are not + covered by this License; they are outside its scope. The act of running + the Program is not restricted, and the output from the Program is + covered only if its contents constitute a work based on the Program + (independent of having been made by running the Program). Whether that + is true depends on what the Program does.

                            +
                          8. You may copy and distribute verbatim copies of the Program's source + code as you receive it, in any medium, provided that you conspicuously + and appropriately publish on each copy an appropriate copyright notice + and disclaimer of warranty; keep intact all the notices that refer to + this License and to the absence of any warranty; and give any other + recipients of the Program a copy of this License along with the + Program.
                          9. +

                            You may charge a fee for the physical act of transferring a copy, and + you may at your option offer warranty protection in exchange for a fee.

                            +
                          10. You may modify your copy or copies of the Program or any portion of + it, thus forming a work based on the Program, and copy and distribute + such modifications or work under the terms of Section 1 above, provided + that you also meet all of these conditions:
                              -
                            1. You must cause the modified files to carry prominent notices -stating that you changed the files and the date of any change.
                            2. -
                            3. You must cause any work that you distribute or publish, that in -whole or in part contains or is derived from the Program or any part -thereof, to be licensed as a whole at no charge to all third parties -under the terms of this License.
                            4. -
                            5. if the modified program normally reads commands interactively when -run, you must cause it, when started running for such interactive use -in the most ordinary way, to print or display an announcement including -an appropriate copyright notice and a notice that there is no warranty -(or else, saying that you provide a warranty) and that users may -redistribute the program under these conditions, and telling the user -how to view a copy of this License. (Exception: if the Program itself -is interactive but does not normally print such an announcement, your -work based on the Program is not required to print an announcement.)
                            6. +
                            7. You must cause the modified files to carry prominent notices stating + that you changed the files and the date of any change.
                            8. +
                            9. You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any part + thereof, to be licensed as a whole at no charge to all third parties + under the terms of this License.
                            10. +
                            11. if the modified program normally reads commands interactively when + run, you must cause it, when started running for such interactive use + in the most ordinary way, to print or display an announcement including + an appropriate copyright notice and a notice that there is no warranty + (or else, saying that you provide a warranty) and that users may + redistribute the program under these conditions, and telling the user + how to view a copy of this License. (Exception: if the Program itself + is interactive but does not normally print such an announcement, your + work based on the Program is not required to print an announcement.)
                          11. -

                            These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it.

                            -

                            Thus, it is not the intent of this section to claim rights or -contest your rights to work written entirely by you; rather, the intent -is to exercise the right to control the distribution of derivative or -collective works based on the Program.

                            -

                            In addition, mere aggregation of another work not based on the -Program with the Program (or with a work based on the Program) on a -volume of a storage or distribution medium does not bring the other -work under the scope of this License.

                            -
                          12. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: +

                            These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the Program, + and can be reasonably considered independent and separate works in + themselves, then this License, and its terms, do not apply to those + sections when you distribute them as separate works. But when you + distribute the same sections as part of a whole which is a work based + on the Program, the distribution of the whole must be on the terms of + this License, whose permissions for other licensees extend to the + entire whole, and thus to each and every part regardless of who wrote + it.

                            +

                            Thus, it is not the intent of this section to claim rights or contest + your rights to work written entirely by you; rather, the intent is to + exercise the right to control the distribution of derivative or + collective works based on the Program.

                            +

                            In addition, mere aggregation of another work not based on the + Program with the Program (or with a work based on the Program) on a + volume of a storage or distribution medium does not bring the other + work under the scope of this License.

                            +
                          13. You may copy and distribute the Program (or a work based on it, + under Section 2) in object code or executable form under the terms of + Sections 1 and 2 above provided that you also do one of the following:
                              -
                            1. Accompany it with the complete corresponding machine-readable -source code, which must be distributed under the terms of Sections 1 -and 2 above on a medium customarily used for software interchange; or,
                            2. -
                            3. Accompany it with a written offer, valid for at least three years, -to give any third party, for a charge no more than your cost of -physically performing source distribution, a complete machine-readable -copy of the corresponding source code, to be distributed under the -terms of Sections 1 and 2 above on a medium customarily used for -software interchange; or,
                            4. -
                            5. Accompany it with the information you received as to the offer to -distribute corresponding source code. (This alternative is allowed -only for noncommercial distribution and only if you received the -program in object code or executable form with such an offer, in accord -with Subsection b above.)
                            6. +
                            7. Accompany it with the complete corresponding machine-readable source + code, which must be distributed under the terms of Sections 1 and 2 + above on a medium customarily used for software interchange; or,
                            8. +
                            9. Accompany it with a written offer, valid for at least three years, + to give any third party, for a charge no more than your cost of + physically performing source distribution, a complete machine-readable + copy of the corresponding source code, to be distributed under the + terms of Sections 1 and 2 above on a medium customarily used for + software interchange; or,
                            10. +
                            11. Accompany it with the information you received as to the offer to + distribute corresponding source code. (This alternative is allowed only + for noncommercial distribution and only if you received the program in + object code or executable form with such an offer, in accord with + Subsection b above.)
                          14. -

                            The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to control -compilation and installation of the executable. However, as a special -exception, the source code distributed need not include anything that -is normally distributed (in either source or binary form) with the -major components (compiler, kernel, and so on) of the operating system -on which the executable runs, unless that component itself accompanies -the executable.

                            -

                            If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent access -to copy the source code from the same place counts as distribution of -the source code, even though third parties are not compelled to copy -the source along with the object code.

                            -
                          15. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt otherwise -to copy, modify, sublicense or distribute the Program is void, and will -automatically terminate your rights under this License. However, -parties who have received copies, or rights, from you under this -License will not have their licenses terminated so long as such parties -remain in full compliance.
                          16. -
                          17. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying the -Program or works based on it.
                          18. -
                          19. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License.
                          20. -
                          21. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program.
                          22. -

                            If any portion of this section is held invalid or unenforceable -under any particular circumstance, the balance of the section is -intended to apply and the section as a whole is intended to apply in -other circumstances.

                            -

                            It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice.

                            -

                            This section is intended to make thoroughly clear what is believed -to be a consequence of the rest of this License.

                            -
                          23. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License may -add an explicit geographical distribution limitation excluding those -countries, so that distribution is permitted only in or among countries -not thus excluded. In such case, this License incorporates the -limitation as if written in the body of this License.
                          24. -
                          25. The Free Software Foundation may publish revised and/or new -versions of the General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns.
                          26. -

                            Each version is given a distinguishing version number. If the -Program specifies a version number of this License which applies to it -and "any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Program does not specify a -version number of this License, you may choose any version ever -published by the Free Software Foundation.

                            -
                          27. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the -author to ask for permission. For software which is copyrighted by the -Free Software Foundation, write to the Free Software Foundation; we -sometimes make exceptions for this. Our decision will be guided by the -two goals of preserving the free status of all derivatives of our free -software and of promoting the sharing and reuse of software generally.
                          28. +

                            The source code for a work means the preferred form of the work for + making modifications to it. For an executable work, complete source + code means all the source code for all modules it contains, plus any + associated interface definition files, plus the scripts used to control + compilation and installation of the executable. However, as a special + exception, the source code distributed need not include anything that + is normally distributed (in either source or binary form) with the + major components (compiler, kernel, and so on) of the operating system + on which the executable runs, unless that component itself accompanies + the executable.

                            +

                            If distribution of executable or object code is made by offering + access to copy from a designated place, then offering equivalent access + to copy the source code from the same place counts as distribution of + the source code, even though third parties are not compelled to copy + the source along with the object code.

                            +
                          29. You may not copy, modify, sublicense, or distribute the Program + except as expressly provided under this License. Any attempt otherwise + to copy, modify, sublicense or distribute the Program is void, and will + automatically terminate your rights under this License. However, + parties who have received copies, or rights, from you under this + License will not have their licenses terminated so long as such parties + remain in full compliance.
                          30. +
                          31. You are not required to accept this License, since you have not + signed it. However, nothing else grants you permission to modify or + distribute the Program or its derivative works. These actions are + prohibited by law if you do not accept this License. Therefore, by + modifying or distributing the Program (or any work based on the + Program), you indicate your acceptance of this License to do so, and + all its terms and conditions for copying, distributing or modifying the + Program or works based on it.
                          32. +
                          33. Each time you redistribute the Program (or any work based on the + Program), the recipient automatically receives a license from the + original licensor to copy, distribute or modify the Program subject to + these terms and conditions. You may not impose any further restrictions + on the recipients' exercise of the rights granted herein. You are not + responsible for enforcing compliance by third parties to this License.
                          34. +
                          35. If, as a consequence of a court judgment or allegation of patent + infringement or for any other reason (not limited to patent issues), + conditions are imposed on you (whether by court order, agreement or + otherwise) that contradict the conditions of this License, they do not + excuse you from the conditions of this License. If you cannot + distribute so as to satisfy simultaneously your obligations under this + License and any other pertinent obligations, then as a consequence you + may not distribute the Program at all. For example, if a patent license + would not permit royalty-free redistribution of the Program by all + those who receive copies directly or indirectly through you, then the + only way you could satisfy both it and this License would be to refrain + entirely from distribution of the Program.
                          36. +

                            If any portion of this section is held invalid or unenforceable under + any particular circumstance, the balance of the section is intended to + apply and the section as a whole is intended to apply in other + circumstances.

                            +

                            It is not the purpose of this section to induce you to infringe any + patents or other property right claims or to contest validity of any + such claims; this section has the sole purpose of protecting the + integrity of the free software distribution system, which is + implemented by public license practices. Many people have made generous + contributions to the wide range of software distributed through that + system in reliance on consistent application of that system; it is up + to the author/donor to decide if he or she is willing to distribute + software through any other system and a licensee cannot impose that + choice.

                            +

                            This section is intended to make thoroughly clear what is believed to + be a consequence of the rest of this License.

                            +
                          37. If the distribution and/or use of the Program is restricted in + certain countries either by patents or by copyrighted interfaces, the + original copyright holder who places the Program under this License may + add an explicit geographical distribution limitation excluding those + countries, so that distribution is permitted only in or among countries + not thus excluded. In such case, this License incorporates the + limitation as if written in the body of this License.
                          38. +
                          39. The Free Software Foundation may publish revised and/or new versions + of the General Public License from time to time. Such new versions will + be similar in spirit to the present version, but may differ in detail + to address new problems or concerns.
                          40. +

                            Each version is given a distinguishing version number. If the Program + specifies a version number of this License which applies to it and "any + later version", you have the option of following the terms and + conditions either of that version or of any later version published by + the Free Software Foundation. If the Program does not specify a version + number of this License, you may choose any version ever published by + the Free Software Foundation.

                            +
                          41. If you wish to incorporate parts of the Program into other free + programs whose distribution conditions are different, write to the + author to ask for permission. For software which is copyrighted by the + Free Software Foundation, write to the Free Software Foundation; we + sometimes make exceptions for this. Our decision will be guided by the + two goals of preserving the free status of all derivatives of our free + software and of promoting the sharing and reuse of software generally.

                          NO WARRANTY

                            -
                          1. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. - EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, -EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS -WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
                          2. -
                          3. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES.
                          4. +
                          5. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY + FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN + OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES + PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH + YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL + NECESSARY SERVICING, REPAIR OR CORRECTION.
                          6. +
                          7. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN + WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY + AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU + FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR + CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE + PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING + RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A + FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF + SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + DAMAGES.

                          END OF TERMS AND CONDITIONS

                          GNU LIBRARY GENERAL PUBLIC LICENSE

                          -

                          Version 2, June 1991

                          +

                          Version 2, June 1991

                           Copyright (C) 1991 Free Software Foundation, Inc.
                           59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
                          @@ -3574,400 +3703,396 @@ of this license document, but changing it is not allowed.
                            numbered 2 because it goes with version 2 of the ordinary GPL.]
                           

                          Preamble

                          -

                          The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users.

                          -

                          This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too.

                          -

                          When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it in -new free programs; and that you know you can do these things.

                          -

                          To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the library, or if you modify it.

                          -

                          For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights.

                          -

                          Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library.

                          -

                          Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations.

                          -

                          Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all.

                          -

                          Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License, which was designed for utility -programs. This license, the GNU Library General Public License, -applies to certain designated libraries. This license is quite -different from the ordinary one; be sure to read it in full, and don't -assume that anything in it is the same as in the ordinary license.

                          -

                          The reason we have a separate public license for some libraries is -that they blur the distinction we usually make between modifying or -adding to a program and simply using it. Linking a program with a -library, without changing the library, is in some sense simply using -the library, and is analogous to running a utility program or -application program. However, in a textual and legal sense, the linked -executable is a combined work, a derivative of the original library, -and the ordinary General Public License treats it as such.

                          -

                          Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better.

                          -

                          However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended -to permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to -achieve this as regards changes in header files, but we have achieved -it as regards changes in the actual functions of the Library.) The -hope is that this will lead to faster development of free libraries.

                          -

                          The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library.

                          -

                          Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one.

                          +

                          The licenses for most software are designed to take away your freedom + to share and change it. By contrast, the GNU General Public Licenses + are intended to guarantee your freedom to share and change free + software--to make sure the software is free for all its users.

                          +

                          This license, the Library General Public License, applies to some + specially designated Free Software Foundation software, and to any + other libraries whose authors decide to use it. You can use it for your + libraries, too.

                          +

                          When we speak of free software, we are referring to freedom, not + price. Our General Public Licenses are designed to make sure that you + have the freedom to distribute copies of free software (and charge for + this service if you wish), that you receive source code or can get it + if you want it, that you can change the software or use pieces of it in + new free programs; and that you know you can do these things.

                          +

                          To protect your rights, we need to make restrictions that forbid + anyone to deny you these rights or to ask you to surrender the rights. + These restrictions translate to certain responsibilities for you if you + distribute copies of the library, or if you modify it.

                          +

                          For example, if you distribute copies of the library, whether gratis + or for a fee, you must give the recipients all the rights that we gave + you. You must make sure that they, too, receive or can get the source + code. If you link a program with the library, you must provide complete + object files to the recipients so that they can relink them with the + library, after making changes to the library and recompiling it. And + you must show them these terms so they know their rights.

                          +

                          Our method of protecting your rights has two steps: (1) copyright the + library, and (2) offer you this license which gives you legal + permission to copy, distribute and/or modify the library.

                          +

                          Also, for each distributor's protection, we want to make certain that + everyone understands that there is no warranty for this free library. + If the library is modified by someone else and passed on, we want its + recipients to know that what they have is not the original version, so + that any problems introduced by others will not reflect on the original + authors' reputations.

                          +

                          Finally, any free program is threatened constantly by software + patents. We wish to avoid the danger that companies distributing free + software will individually obtain patent licenses, thus in effect + transforming the program into proprietary software. To prevent this, we + have made it clear that any patent must be licensed for everyone's free + use or not licensed at all.

                          +

                          Most GNU software, including some libraries, is covered by the + ordinary GNU General Public License, which was designed for utility + programs. This license, the GNU Library General Public License, applies + to certain designated libraries. This license is quite different from + the ordinary one; be sure to read it in full, and don't assume that + anything in it is the same as in the ordinary license.

                          +

                          The reason we have a separate public license for some libraries is + that they blur the distinction we usually make between modifying or + adding to a program and simply using it. Linking a program with a + library, without changing the library, is in some sense simply using + the library, and is analogous to running a utility program or + application program. However, in a textual and legal sense, the linked + executable is a combined work, a derivative of the original library, + and the ordinary General Public License treats it as such.

                          +

                          Because of this blurred distinction, using the ordinary General + Public License for libraries did not effectively promote software + sharing, because most developers did not use the libraries. We + concluded that weaker conditions might promote sharing better.

                          +

                          However, unrestricted linking of non-free programs would deprive the + users of those programs of all benefit from the free status of the + libraries themselves. This Library General Public License is intended + to permit developers of non-free programs to use free libraries, while + preserving your freedom as a user of such programs to change the free + libraries that are incorporated in them. (We have not seen how to + achieve this as regards changes in header files, but we have achieved + it as regards changes in the actual functions of the Library.) The hope + is that this will lead to faster development of free libraries.

                          +

                          The precise terms and conditions for copying, distribution and + modification follow. Pay close attention to the difference between a + "work based on the library" and a "work that uses the library". The + former contains code derived from the library, while the latter only + works together with the library.

                          +

                          Note that it is possible for a library to be covered by the ordinary + General Public License rather than by this special one.

                          TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

                          -

                          0. This License Agreement applies to any software -library which contains a notice placed by the copyright holder or other -authorized party saying it may be distributed under the terms of this -Library General Public License (also called "this License"). Each -licensee is addressed as "you".

                          -

                          A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables.

                          -

                          The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".)

                          -

                          "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control -compilation and installation of the library.

                          -

                          Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does and -what the program that uses the Library does.

                          -

                          1. You may copy and distribute verbatim copies of -the Library's complete source code as you receive it, in any medium, -provided that you conspicuously and appropriately publish on each copy -an appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the Library.

                          -

                          You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee.

                          -

                          2. You may modify your copy or copies of the -Library or any portion of it, thus forming a work based on the Library, -and copy and distribute such modifications or work under the terms of -Section 1 above, provided that you also meet all of these conditions:

                          +

                          0. This License Agreement applies to any software + library which contains a notice placed by the copyright holder or other + authorized party saying it may be distributed under the terms of this + Library General Public License (also called "this License"). Each + licensee is addressed as "you".

                          +

                          A "library" means a collection of software functions and/or data + prepared so as to be conveniently linked with application programs + (which use some of those functions and data) to form executables.

                          +

                          The "Library", below, refers to any such software library or work + which has been distributed under these terms. A "work based on the + Library" means either the Library or any derivative work under + copyright law: that is to say, a work containing the Library or a + portion of it, either verbatim or with modifications and/or translated + straightforwardly into another language. (Hereinafter, translation is + included without limitation in the term "modification".)

                          +

                          "Source code" for a work means the preferred form of the work for + making modifications to it. For a library, complete source code means + all the source code for all modules it contains, plus any associated + interface definition files, plus the scripts used to control + compilation and installation of the library.

                          +

                          Activities other than copying, distribution and modification are not + covered by this License; they are outside its scope. The act of running + a program using the Library is not restricted, and output from such a + program is covered only if its contents constitute a work based on the + Library (independent of the use of the Library in a tool for writing + it). Whether that is true depends on what the Library does and what the + program that uses the Library does.

                          +

                          1. You may copy and distribute verbatim copies of + the Library's complete source code as you receive it, in any medium, + provided that you conspicuously and appropriately publish on each copy + an appropriate copyright notice and disclaimer of warranty; keep intact + all the notices that refer to this License and to the absence of any + warranty; and distribute a copy of this License along with the Library.

                          +

                          You may charge a fee for the physical act of transferring a copy, and + you may at your option offer warranty protection in exchange for a fee.

                          +

                          2. You may modify your copy or copies of the Library + or any portion of it, thus forming a work based on the Library, and + copy and distribute such modifications or work under the terms of + Section 1 above, provided that you also meet all of these conditions:

                            -
                          1. The modified work must itself be a software library.
                          2. +
                          3. The modified work must itself be a software library.
                          4. -
                          5. You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change.
                          6. +
                          7. You must cause the files modified to carry prominent notices stating + that you changed the files and the date of any change.
                          8. -
                          9. You must cause the whole of the work to be licensed at no charge -to all third parties under the terms of this License.
                          10. +
                          11. You must cause the whole of the work to be licensed at no charge to + all third parties under the terms of this License.
                          12. -
                          13. If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses the -facility, other than as an argument passed when the facility is -invoked, then you must make a good faith effort to ensure that, in the -event an application does not supply such function or table, the -facility still operates, and performs whatever part of its purpose -remains meaningful.
                          14. -

                            (For example, a function in a library to compute square roots has a -purpose that is entirely well-defined independent of the application. - Therefore, Subsection 2d requires that any application-supplied -function or table used by this function must be optional: if the -application does not supply it, the square root function must still -compute square roots.)

                            +
                          15. If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses the + facility, other than as an argument passed when the facility is + invoked, then you must make a good faith effort to ensure that, in the + event an application does not supply such function or table, the + facility still operates, and performs whatever part of its purpose + remains meaningful.
                          16. +

                            (For example, a function in a library to compute square roots has a + purpose that is entirely well-defined independent of the application. + Therefore, Subsection 2d requires that any application-supplied + function or table used by this function must be optional: if the + application does not supply it, the square root function must still + compute square roots.)

                          -

                          These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it.

                          -

                          Thus, it is not the intent of this section to claim rights or -contest your rights to work written entirely by you; rather, the intent -is to exercise the right to control the distribution of derivative or -collective works based on the Library.

                          -

                          In addition, mere aggregation of another work not based on the -Library with the Library (or with a work based on the Library) on a -volume of a storage or distribution medium does not bring the other -work under the scope of this License.

                          -

                          3. You may opt to apply the terms of the ordinary -GNU General Public License instead of this License to a given copy of -the Library. To do this, you must alter all the notices that refer to -this License, so that they refer to the ordinary GNU General Public -License, version 2, instead of to this License. (If a newer version -than version 2 of the ordinary GNU General Public License has appeared, -then you can specify that version instead if you wish.) Do not make -any other change in these notices.

                          -

                          Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy.

                          -

                          This option is useful when you wish to copy part of the code of the -Library into a program that is not a library.

                          -

                          4. You may copy and distribute the Library (or a -portion or derivative of it, under Section 2) in object code or -executable form under the terms of Sections 1 and 2 above provided that -you accompany it with the complete corresponding machine-readable -source code, which must be distributed under the terms of Sections 1 -and 2 above on a medium customarily used for software interchange.

                          -

                          If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to distribute -the source code, even though third parties are not compelled to copy -the source along with the object code.

                          -

                          5. A program that contains no derivative of any -portion of the Library, but is designed to work with the Library by -being compiled or linked with it, is called a "work that uses the -Library". Such a work, in isolation, is not a derivative work of the -Library, and therefore falls outside the scope of this License.

                          -

                          However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. Section -6 states terms for distribution of such executables.

                          -

                          When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law.

                          -

                          If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.)

                          -

                          Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, whether -or not they are linked directly with the Library itself.

                          -

                          6. As an exception to the Sections above, you may -also compile or link a "work that uses the Library" with the Library to -produce a work containing portions of the Library, and distribute that -work under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications.

                          -

                          You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things:

                          +

                          These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the Library, + and can be reasonably considered independent and separate works in + themselves, then this License, and its terms, do not apply to those + sections when you distribute them as separate works. But when you + distribute the same sections as part of a whole which is a work based + on the Library, the distribution of the whole must be on the terms of + this License, whose permissions for other licensees extend to the + entire whole, and thus to each and every part regardless of who wrote + it.

                          +

                          Thus, it is not the intent of this section to claim rights or contest + your rights to work written entirely by you; rather, the intent is to + exercise the right to control the distribution of derivative or + collective works based on the Library.

                          +

                          In addition, mere aggregation of another work not based on the + Library with the Library (or with a work based on the Library) on a + volume of a storage or distribution medium does not bring the other + work under the scope of this License.

                          +

                          3. You may opt to apply the terms of the ordinary + GNU General Public License instead of this License to a given copy of + the Library. To do this, you must alter all the notices that refer to + this License, so that they refer to the ordinary GNU General Public + License, version 2, instead of to this License. (If a newer version + than version 2 of the ordinary GNU General Public License has appeared, + then you can specify that version instead if you wish.) Do not make any + other change in these notices.

                          +

                          Once this change is made in a given copy, it is irreversible for that + copy, so the ordinary GNU General Public License applies to all + subsequent copies and derivative works made from that copy.

                          +

                          This option is useful when you wish to copy part of the code of the + Library into a program that is not a library.

                          +

                          4. You may copy and distribute the Library (or a + portion or derivative of it, under Section 2) in object code or + executable form under the terms of Sections 1 and 2 above provided that + you accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections 1 + and 2 above on a medium customarily used for software interchange.

                          +

                          If distribution of object code is made by offering access to copy + from a designated place, then offering equivalent access to copy the + source code from the same place satisfies the requirement to distribute + the source code, even though third parties are not compelled to copy + the source along with the object code.

                          +

                          5. A program that contains no derivative of any + portion of the Library, but is designed to work with the Library by + being compiled or linked with it, is called a "work that uses the + Library". Such a work, in isolation, is not a derivative work of the + Library, and therefore falls outside the scope of this License.

                          +

                          However, linking a "work that uses the Library" with the Library + creates an executable that is a derivative of the Library (because it + contains portions of the Library), rather than a "work that uses the + library". The executable is therefore covered by this License. Section + 6 states terms for distribution of such executables.

                          +

                          When a "work that uses the Library" uses material from a header file + that is part of the Library, the object code for the work may be a + derivative work of the Library even though the source code is not. + Whether this is true is especially significant if the work can be + linked without the Library, or if the work is itself a library. The + threshold for this to be true is not precisely defined by law.

                          +

                          If such an object file uses only numerical parameters, data structure + layouts and accessors, and small macros and small inline functions (ten + lines or less in length), then the use of the object file is + unrestricted, regardless of whether it is legally a derivative work. + (Executables containing this object code plus portions of the Library + will still fall under Section 6.)

                          +

                          Otherwise, if the work is a derivative of the Library, you may + distribute the object code for the work under the terms of Section 6. + Any executables containing that work also fall under Section 6, whether + or not they are linked directly with the Library itself.

                          +

                          6. As an exception to the Sections above, you may + also compile or link a "work that uses the Library" with the Library to + produce a work containing portions of the Library, and distribute that + work under terms of your choice, provided that the terms permit + modification of the work for the customer's own use and reverse + engineering for debugging such modifications.

                          +

                          You must give prominent notice with each copy of the work that the + Library is used in it and that the Library and its use are covered by + this License. You must supply a copy of this License. If the work + during execution displays copyright notices, you must include the + copyright notice for the Library among them, as well as a reference + directing the user to the copy of this License. Also, you must do one + of these things:

                            -
                          1. Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that uses -the Library", as object code and/or source code, so that the user can -modify the Library and then relink to produce a modified executable -containing the modified Library. (It is understood that the user who -changes the contents of definitions files in the Library will not -necessarily be able to recompile the application to use the modified -definitions.)
                          2. +
                          3. Accompany the work with the complete corresponding machine-readable + source code for the Library including whatever changes were used in the + work (which must be distributed under Sections 1 and 2 above); and, if + the work is an executable linked with the Library, with the complete + machine-readable "work that uses the Library", as object code and/or + source code, so that the user can modify the Library and then relink to + produce a modified executable containing the modified Library. (It is + understood that the user who changes the contents of definitions files + in the Library will not necessarily be able to recompile the + application to use the modified definitions.)
                          4. -
                          5. Accompany the work with a written offer, valid for at least three -years, to give the same user the materials specified in Subsection 6a, -above, for a charge no more than the cost of performing this -distribution.
                          6. +
                          7. Accompany the work with a written offer, valid for at least three + years, to give the same user the materials specified in Subsection 6a, + above, for a charge no more than the cost of performing this + distribution.
                          8. -
                          9. If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place.
                          10. +
                          11. If distribution of the work is made by offering access to copy from + a designated place, offer equivalent access to copy the above specified + materials from the same place.
                          12. -
                          13. Verify that the user has already received a copy of these - materials or that you have already sent this user a copy.
                          14. +
                          15. Verify that the user has already received a copy of these materials + or that you have already sent this user a copy.
                          -

                          For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major components -(compiler, kernel, and so on) of the operating system on which the -executable runs, unless that component itself accompanies the -executable.

                          -

                          It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute.

                          -

                          7. You may place library facilities that are a work -based on the Library side-by-side in a single library together with -other library facilities not covered by this License, and distribute -such a combined library, provided that the separate distribution of the -work based on the Library and of the other library facilities is -otherwise permitted, and provided that you do these two things:

                          +

                          For an executable, the required form of the "work that uses the + Library" must include any data and utility programs needed for + reproducing the executable from it. However, as a special exception, + the source code distributed need not include anything that is normally + distributed (in either source or binary form) with the major components + (compiler, kernel, and so on) of the operating system on which the + executable runs, unless that component itself accompanies the + executable.

                          +

                          It may happen that this requirement contradicts the license + restrictions of other proprietary libraries that do not normally + accompany the operating system. Such a contradiction means you cannot + use both them and the Library together in an executable that you + distribute.

                          +

                          7. You may place library facilities that are a work + based on the Library side-by-side in a single library together with + other library facilities not covered by this License, and distribute + such a combined library, provided that the separate distribution of the + work based on the Library and of the other library facilities is + otherwise permitted, and provided that you do these two things:

                            -
                          1. Accompany the combined library with a copy of the same work based -on the Library, uncombined with any other library facilities. This -must be distributed under the terms of the Sections above.
                          2. +
                          3. Accompany the combined library with a copy of the same work based on + the Library, uncombined with any other library facilities. This must be + distributed under the terms of the Sections above.
                          4. -
                          5. Give prominent notice with the combined library of the fact that -part of it is a work based on the Library, and explaining where to -find the accompanying uncombined form of the same work.
                          6. +
                          7. Give prominent notice with the combined library of the fact that + part of it is a work based on the Library, and explaining where to find + the accompanying uncombined form of the same work.
                          -

                          8. You may not copy, modify, sublicense, link with, -or distribute the Library except as expressly provided under this -License. Any attempt otherwise to copy, modify, sublicense, link with, -or distribute the Library is void, and will automatically terminate -your rights under this License. However, parties who have received -copies, or rights, from you under this License will not have their -licenses terminated so long as such parties remain in full compliance.

                          -

                          9. You are not required to accept this License, -since you have not signed it. However, nothing else grants you -permission to modify or distribute the Library or its derivative works. - These actions are prohibited by law if you do not accept this License. - Therefore, by modifying or distributing the Library (or any work based -on the Library), you indicate your acceptance of this License to do so, -and all its terms and conditions for copying, distributing or modifying -the Library or works based on it.

                          -

                          10. Each time you redistribute the Library (or any -work based on the Library), the recipient automatically receives a -license from the original licensor to copy, distribute, link with or -modify the Library subject to these terms and conditions. You may not -impose any further restrictions on the recipients' exercise of the -rights granted herein. You are not responsible for enforcing compliance -by third parties to this License.

                          -

                          11. If, as a consequence of a court judgment or -allegation of patent infringement or for any other reason (not limited -to patent issues), conditions are imposed on you (whether by court -order, agreement or otherwise) that contradict the conditions of this -License, they do not excuse you from the conditions of this License. - If you cannot distribute so as to satisfy simultaneously your -obligations under this License and any other pertinent obligations, -then as a consequence you may not distribute the Library at all. For -example, if a patent license would not permit royalty-free -redistribution of the Library by all those who receive copies directly -or indirectly through you, then the only way you could satisfy both it -and this License would be to refrain entirely from distribution of the -Library.

                          -

                          If any portion of this section is held invalid or unenforceable -under any particular circumstance, the balance of the section is -intended to apply, and the section as a whole is intended to apply in -other circumstances.

                          -

                          It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is implemented -by public license practices. Many people have made generous -contributions to the wide range of software distributed through that -system in reliance on consistent application of that system; it is up -to the author/donor to decide if he or she is willing to distribute -software through any other system and a licensee cannot impose that -choice.

                          -

                          This section is intended to make thoroughly clear what is believed -to be a consequence of the rest of this License.

                          -

                          12. If the distribution and/or use of the Library -is restricted in certain countries either by patents or by copyrighted -interfaces, the original copyright holder who places the Library under -this License may add an explicit geographical distribution limitation -excluding those countries, so that distribution is permitted only in or -among countries not thus excluded. In such case, this License -incorporates the limitation as if written in the body of this License.

                          -

                          13. The Free Software Foundation may publish -revised and/or new versions of the Library General Public License from -time to time. Such new versions will be similar in spirit to the -present version, but may differ in detail to address new problems or -concerns.

                          -

                          Each version is given a distinguishing version number. If the -Library specifies a version number of this License which applies to it -and "any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation.

                          -

                          14. If you wish to incorporate parts of the Library -into other free programs whose distribution conditions are incompatible -with these, write to the author to ask for permission. For software -which is copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally.

                          +

                          8. You may not copy, modify, sublicense, link with, + or distribute the Library except as expressly provided under this + License. Any attempt otherwise to copy, modify, sublicense, link with, + or distribute the Library is void, and will automatically terminate + your rights under this License. However, parties who have received + copies, or rights, from you under this License will not have their + licenses terminated so long as such parties remain in full compliance.

                          +

                          9. You are not required to accept this License, + since you have not signed it. However, nothing else grants you + permission to modify or distribute the Library or its derivative works. + These actions are prohibited by law if you do not accept this License. + Therefore, by modifying or distributing the Library (or any work based + on the Library), you indicate your acceptance of this License to do so, + and all its terms and conditions for copying, distributing or modifying + the Library or works based on it.

                          +

                          10. Each time you redistribute the Library (or any + work based on the Library), the recipient automatically receives a + license from the original licensor to copy, distribute, link with or + modify the Library subject to these terms and conditions. You may not + impose any further restrictions on the recipients' exercise of the + rights granted herein. You are not responsible for enforcing compliance + by third parties to this License.

                          +

                          11. If, as a consequence of a court judgment or + allegation of patent infringement or for any other reason (not limited + to patent issues), conditions are imposed on you (whether by court + order, agreement or otherwise) that contradict the conditions of this + License, they do not excuse you from the conditions of this License. If + you cannot distribute so as to satisfy simultaneously your obligations + under this License and any other pertinent obligations, then as a + consequence you may not distribute the Library at all. For example, if + a patent license would not permit royalty-free redistribution of the + Library by all those who receive copies directly or indirectly through + you, then the only way you could satisfy both it and this License would + be to refrain entirely from distribution of the Library.

                          +

                          If any portion of this section is held invalid or unenforceable under + any particular circumstance, the balance of the section is intended to + apply, and the section as a whole is intended to apply in other + circumstances.

                          +

                          It is not the purpose of this section to induce you to infringe any + patents or other property right claims or to contest validity of any + such claims; this section has the sole purpose of protecting the + integrity of the free software distribution system which is implemented + by public license practices. Many people have made generous + contributions to the wide range of software distributed through that + system in reliance on consistent application of that system; it is up + to the author/donor to decide if he or she is willing to distribute + software through any other system and a licensee cannot impose that + choice.

                          +

                          This section is intended to make thoroughly clear what is believed to + be a consequence of the rest of this License.

                          +

                          12. If the distribution and/or use of the Library is + restricted in certain countries either by patents or by copyrighted + interfaces, the original copyright holder who places the Library under + this License may add an explicit geographical distribution limitation + excluding those countries, so that distribution is permitted only in or + among countries not thus excluded. In such case, this License + incorporates the limitation as if written in the body of this License.

                          +

                          13. The Free Software Foundation may publish revised + and/or new versions of the Library General Public License from time to + time. Such new versions will be similar in spirit to the present + version, but may differ in detail to address new problems or concerns.

                          +

                          Each version is given a distinguishing version number. If the Library + specifies a version number of this License which applies to it and "any + later version", you have the option of following the terms and + conditions either of that version or of any later version published by + the Free Software Foundation. If the Library does not specify a license + version number, you may choose any version ever published by the Free + Software Foundation.

                          +

                          14. If you wish to incorporate parts of the Library + into other free programs whose distribution conditions are incompatible + with these, write to the author to ask for permission. For software + which is copyrighted by the Free Software Foundation, write to the Free + Software Foundation; we sometimes make exceptions for this. Our + decision will be guided by the two goals of preserving the free status + of all derivatives of our free software and of promoting the sharing + and reuse of software generally.

                          NO WARRANTY

                          -

                          15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, -THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT -WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE -OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU -ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

                          -

                          16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW -OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY -WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE -LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL -OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES.

                          +

                          15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, + THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY + APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT + HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT + WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE + OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU + ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

                          +

                          16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR + AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO + MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE + LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL + OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE + LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING + RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A + FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF + SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + DAMAGES.

                          END OF TERMS AND CONDITIONS

                          B - Common Network Settings

                          -

                          This appendix covers many of the popular TCP/IP network interfaces -and printer servers available on the market today.

                          +

                          This appendix covers many of the popular TCP/IP network interfaces + and printer servers available on the market today.

                          Configuring a Network Interface

                          -

                          When you first install a network printer or print server on your -LAN, you need to set the Internet Protocol ("IP") address. On most -higher-end "workgroup" printers, you can set the address through the -printer control panel. However, in most cases you will want to assign -the addresses remotely from your workstation. This makes administration -a bit easier and avoids assigning duplicate addresses accidentally.

                          -

                          To setup your printer or print server for remote address assignment, -you'll need the Ethernet Media Access Control ("MAC") address, also -sometimes called a node address, and the IP address you want to use for -the device. The Ethernet MAC address can often be found on the printer -test page or bottom of the print server. +

                          When you first install a network printer or print server on your LAN, + you need to set the Internet Protocol ("IP") address. On most + higher-end "workgroup" printers, you can set the address through the + printer control panel. However, in most cases you will want to assign + the addresses remotely from your workstation. This makes administration + a bit easier and avoids assigning duplicate addresses accidentally.

                          +

                          To setup your printer or print server for remote address assignment, + you'll need the Ethernet Media Access Control ("MAC") address, also + sometimes called a node address, and the IP address you want to use for + the device. The Ethernet MAC address can often be found on the printer + test page or bottom of the print server.

                          Configuring the IP Address Using ARP

                          -

                          The easiest way to set the IP address of a network device is to use -the arp(8) command. The arp sends an Address -Resolution Protocol ("ARP") packet to the specified Ethernet MAC -address, setting the network device's IP address:

                          +

                          The easiest way to set the IP address of a network device is to use + the arp(8) command. The arp sends an Address + Resolution Protocol ("ARP") packet to the specified Ethernet MAC + address, setting the network device's IP address:

                             arp -s ip-address ethernet-address ENTER
                            @@ -3976,50 +4101,50 @@ address, setting the network device's IP address: 

                          Configuring the IP Address Using RARP

                          -

                          The most flexible way to remotely assign IP addresses under UNIX is -through the Reverse Address Resolution Protocol ("RARP"). RARP allows a -network device to request an IP address using its Ethernet MAC address, -and one or more RARP servers on the network will respond with an ARP -packet with the IP address the device can use.

                          -

                          RARP should be used when you have to manage many printers or print -servers, or when you have a network device that does not remember its -IP address after a power cycle. If you just have a single printer or -print server, the arp command is the way to go.

                          +

                          The most flexible way to remotely assign IP addresses under UNIX is + through the Reverse Address Resolution Protocol ("RARP"). RARP allows a + network device to request an IP address using its Ethernet MAC address, + and one or more RARP servers on the network will respond with an ARP + packet with the IP address the device can use.

                          +

                          RARP should be used when you have to manage many printers or print + servers, or when you have a network device that does not remember its + IP address after a power cycle. If you just have a single printer or + print server, the arp command is the way to go.

                          Some UNIX operating systems use a program called rarpd(8) - to manage RARP. Others, like Linux, support this protocol in the -kernel. For systems that provide the rarpd program you -will need to start it before RARP lookups will work:

                          + to manage RARP. Others, like Linux, support this protocol in the + kernel. For systems that provide the rarpd program you + will need to start it before RARP lookups will work:

                             rarpd ENTER
                             
                          -

                          Under IRIX you can enable this functionality by default using:

                          +

                          Under IRIX you can enable this functionality by default using:

                             chkconfig rarpd on ENTER
                             
                          -

                          Both the rarpd program and kernel RARP support read a -list of Ethernet and IP addresses from the file /etc/ethers. -Each line contains the Ethernet address (colon delimited) followed by -an IP address or hostname like:

                          +

                          Both the rarpd program and kernel RARP support read a + list of Ethernet and IP addresses from the file /etc/ethers. + Each line contains the Ethernet address (colon delimited) followed by + an IP address or hostname like:

                             08:00:69:00:12:34 myprinter.mydomain.com
                             08:00:69:00:12:34 192.0.2.2
                             
                          -

                          Add a line to this file and cycle the power on the printer or print -server to set its address. +

                          Add a line to this file and cycle the power on the printer or print + server to set its address.

                          Configuring the IP Address Using BOOTP

                          -

                          The BOOTP protocol is used when you need to provide additional -information such as the location of a configuration file to the network -interface. Using the standard bootpd(8) program supplied -with UNIX you simply need to add a line to the /etc/bootptab - file; for IRIX:

                          +

                          The BOOTP protocol is used when you need to provide additional + information such as the location of a configuration file to the network + interface. Using the standard bootpd(8) program supplied + with UNIX you simply need to add a line to the /etc/bootptab + file; for IRIX:

                             myprinter 08:00:69:00:12:34 192.0.2.2 myprinter.boot
                            @@ -4027,36 +4152,36 @@ myprinter 08:00:69:00:12:34 192.0.2.2 myprinter.boot
                             
                          -

                          Newer versions of bootpd use a different format:

                          +

                          Newer versions of bootpd use a different format:

                             myprinter:ha=080069001234:ip=192.0.2.2:t144=myprinter.boot
                             
                          -

                          The myprinter.boot file resides in the -/usr/local/boot directory by default. If you do not need to -provide a boot file you may leave the last part of the line blank. +

                          The myprinter.boot file resides in the + /usr/local/boot directory by default. If you do not need to + provide a boot file you may leave the last part of the line blank.

                          NOTE: -

                          Some versions of UNIX do not enable the BOOTP service by default. -The /etc/inetd.conf usually contains a line for the BOOTP -service that can be uncommented if needed.

                          +

                          Some versions of UNIX do not enable the BOOTP service by default. The + /etc/inetd.conf usually contains a line for the BOOTP service + that can be uncommented if needed.

                          Verifying the Printer Connection

                          -

                          To test that the IP address has been successfully assigned and that -the printer is properly connected to your LAN, type:

                          +

                          To test that the IP address has been successfully assigned and that + the printer is properly connected to your LAN, type:

                             ping ip-address ENTER
                             
                          -

                          If the connection is working properly you will see something like:

                          +

                          If the connection is working properly you will see something like:

                             ping myprinter ENTER
                            @@ -4067,21 +4192,21 @@ PING myprinter (192.0.2.2): 56 data bytes
                             64 bytes from 192.0.2.2: icmp_seq=3 ttl=15 time=3 ms
                             
                          -

                          If not, verify that the printer or print server is connected to the -LAN, it is powered on, the LAN cabling is good, and the IP address is -set correctly. You can usually see the current IP address and network -status by printing a configuration or test page on the device. +

                          If not, verify that the printer or print server is connected to the + LAN, it is powered on, the LAN cabling is good, and the IP address is + set correctly. You can usually see the current IP address and network + status by printing a configuration or test page on the device.

                          Common Network Interface Settings

                          -

                          Once you have set the IP address you can access the printer or print -server using the ipp, lpd, or socket - backends. The following is a list of common network interfaces and -printer servers and the settings you should use with CUPS: +

                          Once you have set the IP address you can access the printer or print + server using the ipp, lpd, or socket + backends. The following is a list of common network interfaces and + printer servers and the settings you should use with CUPS:

                          - + @@ -4111,8 +4236,8 @@ lpd://address/pr1
                          lpd://address/pr3 - +

                          Configuring Axis Print Servers

                          -

                          The Axis print servers can be configured using ARP, RARP, or BOOTP. -However, on models that do not provide IPP support an additional step -must be performed to configure the TCP/IP portion of the print server -for use with CUPS. +

                          The Axis print servers can be configured using ARP, RARP, or BOOTP. + However, on models that do not provide IPP support an additional step + must be performed to configure the TCP/IP portion of the print server + for use with CUPS.

                          -

                          Each print server contains a configuration file named config - that contains a list of network parameters used by the server. To -modify this file you must first download it from the print server using -the ftp(1) program:

                          +

                          Each print server contains a configuration file named config + that contains a list of network parameters used by the server. To + modify this file you must first download it from the print server using + the ftp(1) program:

                             ftp ip-address ENTER
                            @@ -4195,8 +4320,8 @@ ftp> quit ENTER
                             
                          -

                          Next, edit the file with your favorite text editor and locate the -lines beginning with:

                          +

                          Next, edit the file with your favorite text editor and locate the + lines beginning with:

                             RTN_OPT.     : YES
                            @@ -4212,7 +4337,7 @@ RTEL_PR8.    : 0
                             
                          - Change the RTN_OPT line to read: + Change the RTN_OPT line to read:
                             RTN_OPT.     : NO
                            @@ -4220,9 +4345,9 @@ RTN_OPT.     : NO
                             
                          -

                          This disables the Reverse TELNET protocol and enables the standard -TELNET protocol on the print server. Next, assign a port number for -each parallel and serial port on the server as follows:

                          +

                          This disables the Reverse TELNET protocol and enables the standard + TELNET protocol on the print server. Next, assign a port number for + each parallel and serial port on the server as follows:

                             RTEL_PR1.    : 9100
                            @@ -4237,9 +4362,9 @@ RTEL_PR8.    : 9107
                             
                          -

                          This essentially makes the Axis print server look like a Hewlett -Packard JetDirect EX print server. Save the file and then upload the -new config file using the ftp command:

                          +

                          This essentially makes the Axis print server look like a Hewlett + Packard JetDirect EX print server. Save the file and then upload the + new config file using the ftp command:

                             ftp ip-address ENTER
                            @@ -4263,18 +4388,18 @@ ftp> quit ENTER
                             221 Goodbye.
                             
                          -

                          Your Axis print server is now ready for use!

                          +

                          Your Axis print server is now ready for use!

                          Configuring Linksys Print Servers

                          -

                          The Linksys print servers can be configured using ARP, RARP, or -BOOTP. Like older Axis print servers, an additional step must be -performed to configure the TCP/IP portion of the print server for use -with CUPS. +

                          The Linksys print servers can be configured using ARP, RARP, or + BOOTP. Like older Axis print servers, an additional step must be + performed to configure the TCP/IP portion of the print server for use + with CUPS.

                          -

                          Each print server contains a configuration file named CONFIG - that contains a list of network parameters used by the server. To -modify this file you must first download it from the print server using -the ftp(1) program:

                          +

                          Each print server contains a configuration file named CONFIG + that contains a list of network parameters used by the server. To + modify this file you must first download it from the print server using + the ftp(1) program:

                             ftp -n ip-address ENTER
                            @@ -4295,8 +4420,8 @@ ftp> quit ENTER
                             
                          -

                          Next, edit the file with your favorite text editor and locate the -lines beginning with:

                          +

                          Next, edit the file with your favorite text editor and locate the + lines beginning with:

                             0100 L1_PROUT:P1
                            @@ -4304,8 +4429,8 @@ lines beginning with: 

                            0140 L3_PROUT:P1
                          -

                          Change the port number for each parallel and serial port on the -server as follows:

                          +

                          Change the port number for each parallel and serial port on the + server as follows:

                             0100 L1_PROUT:P1
                            @@ -4315,9 +4440,9 @@ server as follows: 

                          -

                          This maps each virtual printer with a physical port. Save the file -and then upload the new CONFIG file using the ftp - command:

                          +

                          This maps each virtual printer with a physical port. Save the file + and then upload the new CONFIG file using the ftp + command:

                             ftp -n ip-address ENTER
                            @@ -4334,96 +4459,95 @@ ftp> quit ENTER
                             221 Goodbye.
                             
                          -

                          Your Linksys print server is now ready for use!

                          +

                          Your Linksys print server is now ready for use!

                          C - Printer Drivers

                          -

                          This appendix lists the printer drivers that are provided with CUPS.

                          +

                          This appendix lists the printer drivers that are provided with CUPS.

                          Printer Drivers

                          -

                          CUPS includes the following printer drivers:

                          +

                          CUPS includes the following printer drivers:

                          EPSON 9-pin Dot Matrix

                          -

                          The EPSON 9-pin Dot Matrix driver (epson9.ppd) supports -9-pin dot matrix printers that implement the ESC/P command set. It -provides 60x72, 120x72, and 240x72 DPI output in black only.

                          +

                          The EPSON 9-pin Dot Matrix driver (epson9.ppd) supports + 9-pin dot matrix printers that implement the ESC/P command set. It + provides 60x72, 120x72, and 240x72 DPI output in black only.

                          EPSON 24-pin Dot Matrix

                          -

                          The EPSON 24-pin Dot Matrix driver (epson9.ppd) supports -24-pin dot matrix printers that implement the ESC/P command set. It -provides 120x180, 180x180, 360x180, and 360x360 DPI output in black -only.

                          +

                          The EPSON 24-pin Dot Matrix driver (epson9.ppd) supports + 24-pin dot matrix printers that implement the ESC/P command set. It + provides 120x180, 180x180, 360x180, and 360x360 DPI output in black + only.

                          EPSON Stylus Color

                          -

                          The EPSON Stylus Color driver (stcolor.ppd) supports -EPSON Stylus Color printers that implement the ESC/P2 command set. It -provides 180, 360, and 720 DPI output in black and color (CMYK).

                          +

                          The EPSON Stylus Color driver (stcolor.ppd) supports EPSON + Stylus Color printers that implement the ESC/P2 command set. It + provides 180, 360, and 720 DPI output in black and color (CMYK).

                          EPSON Stylus Photo

                          -

                          The EPSON Stylus Photo driver (stphoto.ppd) supports -EPSON Stylus Photo printers that implement the ESC/P2 command set. It -provides 180, 360, and 720 DPI output in black and color (CMYKcm).

                          +

                          The EPSON Stylus Photo driver (stphoto.ppd) supports EPSON + Stylus Photo printers that implement the ESC/P2 command set. It + provides 180, 360, and 720 DPI output in black and color (CMYKcm).

                          HP DeskJet

                          -

                          The HP DeskJet driver (deskjet.ppd) supports HP DeskJet -printers that implement the PCL command set. It provides 150, 300, and -600 DPI output in black and color (CMYK).

                          -

                          The DeskJet printers that implement the HP-PPA command set (720C, -722C, 820C, and 1100C) are not supported due to a complete lack -of documentation and support from Hewlett Packard.

                          -

                          The duplexer provided with the HP DeskJet 900 series printers is -also not supported for similar reasons.

                          +

                          The HP DeskJet driver (deskjet.ppd) supports HP DeskJet + printers that implement the PCL command set. It provides 150, 300, and + 600 DPI output in black and color (CMYK).

                          +

                          The DeskJet printers that implement the HP-PPA command set (720C, + 722C, 820C, and 1100C) are not supported due to a complete lack + of documentation and support from Hewlett Packard.

                          +

                          The duplexer provided with the HP DeskJet 900 series printers is also + not supported for similar reasons.

                          HP LaserJet

                          -

                          The HP LaserJet driver (laserjet.ppd) supports HP -LaserJet printers that implement the PCL command set. It provides 150, -300, and 600 DPI output in black only and supports the duplexer if -installed.

                          -

                          LaserJet printers that do not implement PCL (3100, 3150) are not -supported due to a complete lack of documentation and support from -Hewlett Packard.

                          +

                          The HP LaserJet driver (laserjet.ppd) supports HP LaserJet + printers that implement the PCL command set. It provides 150, 300, and + 600 DPI output in black only and supports the duplexer if installed.

                          +

                          LaserJet printers that do not implement PCL (3100, 3150) are not + supported due to a complete lack of documentation and support from + Hewlett Packard.

                          D - List of Files

                          -

                          This appendix lists the files and directories that are installed for -the Common UNIX Printing System. +

                          This appendix lists the files and directories that are installed for + the Common UNIX Printing System.

                          Model/ManufacturerDevice -URI(s)
                          Model/ManufacturerDevice + URI(s)
                          Apple LaserWriterlpd:// address/PASSTHRU
                          EFI® Fiery® RIPlpd:// address/print
                          EPSON® Multiprotocol Ethernet -Interface Boardsocket://address
                          EPSON® Multiprotocol Ethernet + Interface Boardsocket://address
                          Extended System ExtendNET @@ -4163,16 +4288,16 @@ address:5503
                          - - - - - - - - - - - + + + + + + + + + + + - - + + - - + + - - - - - - - + + + + + + + - - - + + + - + - - - - - - - - - - + + + + + + + + + +
                          PathnameDescription
                          /etc/cups/certs/The location of -authentication certificate files for local HTTP clients.
                          /etc/cups/classes.confThe printer classes -configuration file for the scheduler.
                          /etc/cups/cupsd.confThe scheduler -configuration file.
                          /etc/cups/interfaces/The location of -System V interface scripts for printers.
                          /etc/cups/mime.convsThe list of standard -file filters included with ESP Print Pro.
                          /etc/cups/mime.typesThe list of -recognized file types for ESP Print Pro.
                          /etc/cups/ppd/The location of PostScript -Printer Description ("PPD") files for printers.
                          /etc/cups/printers.confThe printer -configuration file for the scheduler.
                          /usr/bin/cancelThe System V cancel job(s) -command.
                          /usr/bin/disableThe System V disable -printer command.
                          /usr/bin/enableThe System V enable -printer command.
                          /etc/cups/certs/The location of + authentication certificate files for local HTTP clients.
                          /etc/cups/classes.confThe printer classes + configuration file for the scheduler.
                          /etc/cups/cupsd.confThe scheduler + configuration file.
                          /etc/cups/interfaces/The location of + System V interface scripts for printers.
                          /etc/cups/mime.convsThe list of standard + file filters included with ESP Print Pro.
                          /etc/cups/mime.typesThe list of recognized + file types for ESP Print Pro.
                          /etc/cups/ppd/The location of PostScript + Printer Description ("PPD") files for printers.
                          /etc/cups/printers.confThe printer + configuration file for the scheduler.
                          /usr/bin/cancelThe System V cancel job(s) + command.
                          /usr/bin/disableThe System V disable + printer command.
                          /usr/bin/enableThe System V enable printer + command.
                          /usr/bin/lpThe System V print command.
                          /usr/bin/lpoptionsSets user-defined -printing options and defaults.
                          /usr/bin/lppasswdAdds, changes, or -removes Digest password accounts.
                          /usr/bin/lpoptionsSets user-defined + printing options and defaults.
                          /usr/bin/lppasswdAdds, changes, or removes + Digest password accounts.
                          /usr/bin/lpqThe Berkeley status command.
                          /usr/bin/lprThe Berkeley print command.
                          /usr/bin/lprmThe Berkeley cancel job(s) -command.
                          /usr/bin/lpstatThe System V status -command.
                          /usr/bin/lprmThe Berkeley cancel job(s) + command.
                          /usr/bin/lpstatThe System V status + command.
                          /usr/include/cups/CUPS API header files.
                          /usr/lib32/libcups.a @@ -4438,118 +4562,118 @@ command.
                          /usr/lib/libcups.so.2
                          /usr/lib/libcupsimage.so.2
                          Shared libraries (all others)
                          /usr/lib/cups/backend/Backends for -various types of printer connections.
                          /usr/lib/cups/cgi-bin/CGI programs for -the scheduler.
                          /usr/lib/cups/daemon/Daemons for polling -and LPD support.
                          /usr/lib/cups/filter/Filters for various -types of files.
                          /usr/lib/locale/The location of -language-specific message files. (System V)
                          /usr/lib/nls/msg/The location of -language-specific message files. (Compaq Tru64 UNIX)
                          /usr/share/locale/The location of -language-specific message files. (Linux, *BSD)
                          /usr/lib/cups/backend/Backends for various + types of printer connections.
                          /usr/lib/cups/cgi-bin/CGI programs for the + scheduler.
                          /usr/lib/cups/daemon/Daemons for polling + and LPD support.
                          /usr/lib/cups/filter/Filters for various + types of files.
                          /usr/lib/locale/The location of + language-specific message files. (System V)
                          /usr/lib/nls/msg/The location of + language-specific message files. (Compaq Tru64 UNIX)
                          /usr/share/locale/The location of + language-specific message files. (Linux, *BSD)
                          /usr/sbin/acceptThe accept-jobs command.
                          /usr/sbin/cupsdThe CUPS print scheduler.
                          /usr/sbin/lpadminThe System V printer -administration tool.
                          /usr/sbin/lpcThe Berkeley printer -administration tool.
                          /usr/sbin/lpinfoThe get-devices and -get-ppds command.
                          /usr/sbin/lpadminThe System V printer + administration tool.
                          /usr/sbin/lpcThe Berkeley printer + administration tool.
                          /usr/sbin/lpinfoThe get-devices and + get-ppds command.
                          /usr/sbin/lpmoveThe move-jobs command.
                          /usr/sbin/rejectThe reject-jobs command.
                          /usr/share/catman/a_man/
                          /usr/share/catman/u_man/
                          Man pages (IRIX)
                          /usr/share/man/Man pages (Compaq Tru64 -UNIX, HP-UX, Solaris)
                          /usr/share/man/Man pages (Compaq Tru64 + UNIX, HP-UX, Solaris)
                          /usr/man/Man pages (all others)
                          /usr/share/cups/data/The location of -filter data files.
                          /usr/share/cups/data/testprint.psThe -PostScript test page file.
                          /usr/share/cups/fonts/The location of -PostScript fonts for the PostScript RIP.
                          /usr/share/cups/model/The location of -PostScript Printer Description ("PPD") files and interface scripts -that may be used to setup a printer queue.
                          /usr/share/cups/pstoraster/Other -PostScript RIP initialization files.
                          /usr/share/cups/pstoraster/FontmapThe -font mapping file (converts filenames to fontnames)
                          /usr/share/cups/templates/The location of -HTML template files for the web interfaces.
                          /usr/share/doc/cups/Documentation and web -page data for the scheduler.
                          /var/log/cups/The location of scheduler -log files.
                          /var/spool/cups/The location of print -files waiting to be printed.
                          /usr/share/cups/data/The location of + filter data files.
                          /usr/share/cups/data/testprint.psThe + PostScript test page file.
                          /usr/share/cups/fonts/The location of + PostScript fonts for the PostScript RIP.
                          /usr/share/cups/model/The location of + PostScript Printer Description ("PPD") files and interface scripts that + may be used to setup a printer queue.
                          /usr/share/cups/pstoraster/Other + PostScript RIP initialization files.
                          /usr/share/cups/pstoraster/FontmapThe font + mapping file (converts filenames to fontnames)
                          /usr/share/cups/templates/The location of + HTML template files for the web interfaces.
                          /usr/share/doc/cups/Documentation and web + page data for the scheduler.
                          /var/log/cups/The location of scheduler + log files.
                          /var/spool/cups/The location of print + files waiting to be printed.

                          E - Troubleshooting Common Problems

                          -

                          This appendix covers some of the common problems first-time users -encounter when installing and configuring CUPS.

                          -

                          Commercial support for CUPS is available from Easy Software -Products. For more information please contact us at:

                          +

                          This appendix covers some of the common problems first-time users + encounter when installing and configuring CUPS.

                          +

                          Commercial support for CUPS is available from Easy Software Products. + For more information please contact us at:

                          My Applications Don't See the Available Printers

                          -

                          Many applications read the /etc/printcap file to get a -list of available printers.

                          -

                          The default CUPS configuration does not create the /etc/printcap - file automatically. To enable automatic creation and updating of this -file, use the Printcap directive -described in Chapter 6, "Printing System -Management".

                          +

                          Many applications read the /etc/printcap file to get a + list of available printers.

                          +

                          The default CUPS configuration does not create the /etc/printcap + file automatically. To enable automatic creation and updating of this + file, use the Printcap directive + described in Chapter 6, "Printing System + Management".

                          CUPS Doesn't Recognize My Username or Password!

                          -

                          CUPS will ask you for a UNIX username and password when you perform -printer administration tasks remotely or via a web browser. The default -configuration requires that you use the root username and -the corresponding password to authenticate the request.

                          -

                          CUPS does not allow you to authenticate an administration request -with an account that has no password for security reasons. If you do -not have a password on your root account then you won't be -able to add printers remotely or via the web interface! +

                          CUPS will ask you for a UNIX username and password when you perform + printer administration tasks remotely or via a web browser. The default + configuration requires that you use the root username and + the corresponding password to authenticate the request.

                          +

                          CUPS does not allow you to authenticate an administration request + with an account that has no password for security reasons. If you do + not have a password on your root account then you won't be + able to add printers remotely or via the web interface!

                          -

                          To disable password authentication you need to edit the -/etc/cups/cupsd.conf file and comment out the lines reading:

                          +

                          To disable password authentication you need to edit the + /etc/cups/cupsd.conf file and comment out the lines reading:

                             AuthType Basic
                             AuthClass System
                             
                          - for the /admin location. Then restart the CUPS server as -described in Chapter 8, "Printing System -Management". + for the /admin location. Then restart the CUPS server as + described in Chapter 8, "Printing System + Management".
                          NOTE: -

                          Disabling password checks will allow any local user to change your -printer and class configuration, but remote administration from -another machine will still not be allowed.

                          +

                          Disabling password checks will allow any local user to change your + printer and class configuration, but remote administration from another + machine will still not be allowed.

                          I Can't Do Administration Tasks from Another Machine!

                          -

                          The default CUPS configuration limits administration to the local -machine. To open up access, edit the /etc/cups/cupsd.conf - and comment out the lines reading:

                          +

                          The default CUPS configuration limits administration to the local + machine. To open up access, edit the /etc/cups/cupsd.conf + and comment out the lines reading:

                             Order deny,allow
                            @@ -4557,16 +4681,16 @@ Deny from all
                             Allow from 127.0.0.1
                             
                          - for the /admin location. Then restart the CUPS server as -described in Chapter 8, "Printing System -Management". + for the /admin location. Then restart the CUPS server as + described in Chapter 8, "Printing System + Management".
                          NOTE: -

                          Allowing administration access from all hosts is a potential - security risk. Please read Chapter 6, -"Printing System Management" for a description of these risks and -ways to minimize them.

                          +

                          Allowing administration access from all hosts is a potential security + risk. Please read Chapter 6, "Printing + System Management" for a description of these risks and ways to + minimize them.

                          @@ -4574,48 +4698,48 @@ ways to minimize them.

                          I Can't Do Administration Tasks from My Web Browser!

                          -

                          This problem is usually caused by:

                          +

                          This problem is usually caused by:

                            -
                          1. not specifying the correct password for the root account.
                          2. -
                          3. accessing the CUPS server using the hostname or IP address of the -server without enabling remote access for administration functions. -This can be corrected by following the instructions in the -"I Can't Do Administration Tasks from Another Machine!" section -earlier in this appendix.
                          4. -
                          5. not setting a password on the root account. CUPS will not - authenticate a user account that does not have a password for - security reasons.
                          6. -
                          7. authenticating using an account other than root, but the account -you are using is not a member of the system group.
                          8. -
                          9. configuring CUPS to use Digest authentication, but your web -browser does not support Digest authentication.
                          10. +
                          11. not specifying the correct password for the root account.
                          12. +
                          13. accessing the CUPS server using the hostname or IP address of the + server without enabling remote access for administration functions. + This can be corrected by following the instructions in the + "I Can't Do Administration Tasks from Another Machine!" section + earlier in this appendix.
                          14. +
                          15. not setting a password on the root account. CUPS will not + authenticate a user account that does not have a password for security + reasons.
                          16. +
                          17. authenticating using an account other than root, but the account you + are using is not a member of the system group.
                          18. +
                          19. configuring CUPS to use Digest authentication, but your web browser + does not support Digest authentication.

                          Connection Refused Messages

                          -

                          Under normal circumstances, "connection refused" messages for a -networked printer should be expected from time to time. Most network -interfaces only allow a single connection to be made at any given time -(one job at a time) and will refuse access to all other systems while -the first connection is active. CUPS automatically retries the -connection once every 30 seconds.

                          -

                          If the problem persists and you are unable to print any jobs to the -printer, verify that another machine is not maintaining a connection -with the printer, and that you have selected the proper port or printer -name for the printer.

                          -

                          Also, most external print servers will refuse connections if the -connected printer is turned off or is off-line. Verify that the -affected printer is turned on and is online.

                          +

                          Under normal circumstances, "connection refused" messages for a + networked printer should be expected from time to time. Most network + interfaces only allow a single connection to be made at any given time + (one job at a time) and will refuse access to all other systems while + the first connection is active. CUPS automatically retries the + connection once every 30 seconds.

                          +

                          If the problem persists and you are unable to print any jobs to the + printer, verify that another machine is not maintaining a connection + with the printer, and that you have selected the proper port or printer + name for the printer.

                          +

                          Also, most external print servers will refuse connections if the + connected printer is turned off or is off-line. Verify that the + affected printer is turned on and is online.

                          Write Error Messages

                          -

                          If you get "write error" messages on a printer queue the printer -interface (usually a Hewlett Packard JetDirect interface) has timed out -and reset the network connection from your workstation.

                          -

                          The error is caused by that startup delay between the initial setup -of the printer or plotter and the first page of print data that is -sent. +

                          If you get "write error" messages on a printer queue the printer + interface (usually a Hewlett Packard JetDirect interface) has timed out + and reset the network connection from your workstation.

                          +

                          The error is caused by that startup delay between the initial setup + of the printer or plotter and the first page of print data that is + sent.

                          -

                          To correct the problem, change the idle timeout on the interface to -at least 180 seconds or 3 minutes. To change the timeout on a Hewlett -Packard JetDirect interface, type:

                          +

                          To correct the problem, change the idle timeout on the interface to + at least 180 seconds or 3 minutes. To change the timeout on a Hewlett + Packard JetDirect interface, type:

                             telnet ip-address ENTER
                            diff --git a/doc/sam.pdf b/doc/sam.pdf
                            index fc3fa1a4ee..f97f6d5275 100644
                            Binary files a/doc/sam.pdf and b/doc/sam.pdf differ
                            diff --git a/doc/sam.shtml b/doc/sam.shtml
                            index ca928643e8..18cf426fd2 100644
                            --- a/doc/sam.shtml
                            +++ b/doc/sam.shtml
                            @@ -1,7 +1,7 @@
                             
                             
                             	
                            -	
                            +	
                             	
                             	CUPS Software Administrators Manual
                             
                            @@ -11,7 +11,7 @@
                             
                             

                            This software administrators manual provides printer administration information for the Common UNIX Printing SystemTM -("CUPSTM"), version 1.1.7. +("CUPSTM"), version 1.2.0. @@ -177,6 +177,11 @@ make changes you can get the HTMLDOC software from: http://www.easysw.com/htmldoc

                          +

                          Finally, you'll need a make program that +understands the include directive - FreeBSD, +NetBSD, and OpenBSD developers should use the gmake +program. +

                          Compiling CUPS

                          CUPS uses GNU autoconf to configure the makefiles and source code @@ -234,6 +239,16 @@ prior to running configure: http://www.openssl.org

                        +

                        If the OpenSSL headers and libraries are not installed in the +standard directories, use the --with-openssl-includes +and --with-openssl-libs options:

                        + +
                          +./configure --enable-ssl \
                          +    --with-openssl-includes=/foo/bar/include \
                          +    --with-openssl-libs=/foo/bar/lib
                          +
                        +

                        Once you have configured things, just type:

                          @@ -434,6 +449,18 @@ the PPD files for the HP DeskJet and HP LaserJet drivers included with CUPS.
                           You'll find a complete list of PPD files and the printers they will work with
                           in Appendix C, "Printer Drivers".
                           
                          +
                          +

                          For a dot matrix printer connected to the serial port this would might look like: + +

                            +/usr/sbin/lpadmin -p DotMatrix -E -v serial:/dev/ttyS0?baud=9600+size=8+parity=none+flow=soft deskjet.ppd ENTER
                            +
                          + +

                          Here you specify the serial port (e.g. S0,S1, d0, d1), baud rate +(e.g. 9600, 19200, 38400, 115200, etc.), number of bits, parity, and flow control. +If you do not need flow control, delete the "+flow=soft" portion. + +

                          Adding Your First Printer from the Web

                          The CUPS web server provides a user-friendly "wizard" interface for @@ -829,7 +856,6 @@ can use your favorite text editor to make changes to it. determine how the server operates:

                            -
                            @@ -847,11 +873,13 @@ determine how the server operates:
                          • BrowseOrder
                          • BrowsePoll
                          • BrowsePort +
                          • BrowseProtocols
                          • BrowseRelay
                          • BrowseShortNames
                          • BrowseTimeout
                          • Browsing
                          • Classification +
                          • ClassifyOverride
                          • DataDir
                          • DefaultCharset
                          • DefaultLanguage @@ -869,8 +897,11 @@ determine how the server operates:
                          • FilterLimit
                          • FontPath
                          • Group +
                          • HideImplicitMembers
                          • HostNameLookups
                          • ImplicitClasses +
                          • ImplicitAnyClasses +
                          • Include
                          • KeepAliveTimeout
                          • KeepAlive
                          • Limit @@ -886,7 +917,6 @@ determine how the server operates:
                          • MaxLogSize
                          • MaxRequestSize
                          • Order -
                          • PageLog
                          • @@ -894,6 +924,7 @@ determine how the server operates: +
                          • PageLog
                          • Port
                          • PreserveJobFiles
                          • PreserveJobHistory @@ -1083,6 +1114,7 @@ AuthGroupName lp AuthType None AuthType Basic AuthType Digest +AuthType BasicDigest

                            Description

                            @@ -1101,10 +1133,14 @@ perform:
                          • Digest - Digest authentication should be performed using the /etc/cups/passwd.md5 file. +
                          • BasicDigest - Basic authentication should be + performed using the /etc/cups/passwd.md5 file. + -

                            When using Basic or Digest authentication, -clients connecting through the localhost interface can also +

                            When using Basic, Digest, or +BasicDigest authentication, clients connecting +through the localhost interface can also authenticate using certificates.

                            The AuthType directive must appear inside a @@ -1315,6 +1351,39 @@ used for browse packets. The default port number is 631.

                          • + +

                            BrowseProtocols

                            +
                            + +

                            Examples

                            + +
                              +BrowseProtocols CUPS
                              +BrowseProtocols SLP
                              +BrowseProtocols CUPS SLP
                              +BrowseProtocols all
                              +
                            + +

                            Description

                            + +

                            The BrowseProtocols directive specifies the protocols to +use when collecting and distributing shared printers on the local network. +The default protocol is CUPS, which is a broadcast-based +protocol. + +

                            + + + +
                            + NOTE: + +

                            When using the SLP protocol, you must have at least + one Directory Agent (DA) server on your network. Otherwise the + CUPS scheduler (cupsd) will not respond to client + requests for several seconds while polling the network. +

                            +

                            BrowseRelay


                            @@ -1441,6 +1510,29 @@ on the server. When this option is set, at least one of the banner pages is forced to the classification level, and the classification is placed on each page of output. The default is no classification level. + +

                            ClassifyOverride

                            +
                            + +

                            Examples

                            + +
                              +ClassifyOverride Yes
                              +ClassifyOverride No
                              +
                            + +

                            Description

                            + +

                            The ClassifyOverride directive specifies whether users +can override the default classification level on the server. When the +server classification is set, users can change the classification using +the job-sheets option and can choose to only print one +security banner before or after the job. If the job-sheets +option is set to none then the server default classification +is used. + +

                            The default is to not allow classification overrides. +

                            DataDir


                            @@ -1693,6 +1785,26 @@ filter and CGI programs run as. The default group is sys, system, or root depending on the operating system. + +

                            HideImplicitMembers

                            +
                            + +

                            Examples

                            + +
                              +HideImplicitMembers Yes
                              +HideImplicitMembers No
                              +
                            + +

                            Description

                            + +

                            The HideImplicitMembers directive controls +whether the individual printers in an implicit class are shown +to the user. The default is No.

                            + +

                            ImplicitClasses +must be enabled for this directive to have any effect.

                            +

                            HostNameLookups


                            @@ -1739,6 +1851,45 @@ The default setting is On but is automatically turned Off if Browsing is turned Off. + +

                            ImplicitAnyClasses

                            +
                            + +

                            Examples

                            + +
                              +ImplicitAnyClasses On
                              +ImplicitAnyClasses Off
                              +
                            + +

                            Description

                            + +

                            The ImplicitAnyClasses directive controls +whether implicit classes for local and remote printers are +created with the name AnyPrinter. The default +setting is Off.

                            + +

                            ImplicitClasses +must be enabled for this directive to have any effect.

                            + + +

                            Include

                            +
                            + +

                            Examples

                            + +
                              +Include filename
                              +Include /foo/bar/filename
                              +
                            + +

                            Description

                            + +

                            The Include directive includes the named file in +the cupsd.conf file. If no leading path is +provided, the file is assumed to be relative to the +ServerRoot directory.

                            +

                            KeepAlive


                            diff --git a/doc/sdd.html b/doc/sdd.html index 2c9f95bf40..5a665fb6be 100644 --- a/doc/sdd.html +++ b/doc/sdd.html @@ -1,27 +1,27 @@ - CUPS Software Design Description +CUPS Software Design Description -

                            -

                            CUPS Software Design Description


                            +

                            +

                            CUPS Software Design Description


                            CUPS-SDD-1.1
                            Easy Software Products
                            Copyright 1997-2001, All Rights Reserved
                            @@ -138,459 +138,454 @@ Copyright 1997-2001, All Rights Reserved

                            1 Scope

                            1.1 Identification

                            - This software design description document provides general information - on the architecture and coding of the Common UNIX Printing System - ("CUPS") Version 1.1. + This software design description document provides general information + on the architecture and coding of the Common UNIX Printing System + ("CUPS") Version 1.1.

                            1.2 System Overview

                            -

                            CUPS provides a portable printing layer for UNIX®-based operating -systems. It has been developed by Easy -Software Products to promote a standard printing solution for all -UNIX vendors and users. CUPS provides the System V and Berkeley -command-line interfaces.

                            -

                            CUPS uses the Internet Printing Protocol ("IPP") as the basis for -managing print jobs and queues. The Line Printer Daemon ("LPD") Server -Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are -also supported with reduced functionality. CUPS adds network printer -browsing and PostScript Printer Description ("PPD") based printing -options to support real-world printing under UNIX.

                            -

                            CUPS also includes a customized version of GNU Ghostscript -(currently based off GNU Ghostscript 5.50) and an image file RIP that -are used to support non-PostScript printers. Sample drivers for HP and -EPSON printers are included that use these filters.

                            +

                            CUPS provides a portable printing layer for UNIX®-based operating + systems. It has been developed by Easy + Software Products to promote a standard printing solution for all + UNIX vendors and users. CUPS provides the System V and Berkeley + command-line interfaces.

                            +

                            CUPS uses the Internet Printing Protocol ("IPP") as the basis for + managing print jobs and queues. The Line Printer Daemon ("LPD") Server + Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are + also supported with reduced functionality. CUPS adds network printer + browsing and PostScript Printer Description ("PPD") based printing + options to support real-world printing under UNIX.

                            +

                            CUPS also includes a customized version of GNU Ghostscript (currently + based off GNU Ghostscript 5.50) and an image file RIP that are used to + support non-PostScript printers. Sample drivers for HP and EPSON + printers are included that use these filters.

                            1.3 Document Overview

                            - This software design description document is organized into the - following sections: + This software design description document is organized into the + following sections:
                              -
                            • 1 - Scope
                            • -
                            • 2 - References
                            • -
                            • 3 - Design Overview
                            • -
                            • A - Glossary
                            • +
                            • 1 - Scope
                            • +
                            • 2 - References
                            • +
                            • 3 - Design Overview
                            • +
                            • A - Glossary

                            2 References

                            2.1 CUPS Documentation

                            -

                            The following CUPS documentation is referenced by this document:

                            +

                            The following CUPS documentation is referenced by this document:

                              -
                            • CUPS-CMP-1.1: CUPS Configuration Management Plan
                            • -
                            • CUPS-IDD-1.1: CUPS System Interface Design Description
                            • -
                            • CUPS-IPP-1.1: CUPS Implementation of IPP
                            • -
                            • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
                            • -
                            • CUPS-SDD-1.1: CUPS Software Design Description
                            • -
                            • CUPS-SPM-1.1.x: CUPS Software Programming Manual
                            • -
                            • CUPS-SSR-1.1: CUPS Software Security Report
                            • -
                            • CUPS-STP-1.1: CUPS Software Test Plan
                            • -
                            • CUPS-SUM-1.1.x: CUPS Software Users Manual
                            • -
                            • CUPS-SVD-1.1: CUPS Software Version Description
                            • +
                            • CUPS-CMP-1.1: CUPS Configuration Management Plan
                            • +
                            • CUPS-IDD-1.1: CUPS System Interface Design Description
                            • +
                            • CUPS-IPP-1.1: CUPS Implementation of IPP
                            • +
                            • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
                            • +
                            • CUPS-SDD-1.1: CUPS Software Design Description
                            • +
                            • CUPS-SPM-1.1.x: CUPS Software Programming Manual
                            • +
                            • CUPS-SSR-1.1: CUPS Software Security Report
                            • +
                            • CUPS-STP-1.1: CUPS Software Test Plan
                            • +
                            • CUPS-SUM-1.1.x: CUPS Software Users Manual
                            • +
                            • CUPS-SVD-1.1: CUPS Software Version Description

                            2.2 Other Documents

                            -

                            The following non-CUPS documents are referenced by this document:

                            +

                            The following non-CUPS documents are referenced by this document:

                            3 Design Overview

                            - CUPS is composed of 9 software sub-systems that operate together to - perform common printing tasks: + CUPS is composed of 9 software sub-systems that operate together to + perform common printing tasks:
                              -
                            • Backends
                            • -
                            • Berkeley Commands
                            • -
                            • CGI
                            • -
                            • CUPS Application Programmers Interface
                            • -
                            • CUPS Imaging Library
                            • -
                            • Daemons
                            • -
                            • Filters
                            • -
                            • Scheduler
                            • -
                            • System V Commands
                            • +
                            • Backends
                            • +
                            • Berkeley Commands
                            • +
                            • CGI
                            • +
                            • CUPS Application Programmers Interface
                            • +
                            • CUPS Imaging Library
                            • +
                            • Daemons
                            • +
                            • Filters
                            • +
                            • Scheduler
                            • +
                            • System V Commands

                            3.1 Backends

                            - The backends implement communications over a number of different -interfaces. All backends are called with a common set of arguments: + The backends implement communications over a number of different + interfaces. All backends are called with a common set of arguments:
                              -
                            • Device URI - the Uniform Resource Identifier for the output device - (e.g. parallel:/dev/plp, ipp://hostname/resource -).
                            • -
                            • Job Identifier - the job identifier for this job (integer).
                            • -
                            • User Name - the user associated with this job (name string).
                            • -
                            • Title - the title/job-name associated with this job (name string).
                            • -
                            • Copies - the number of copies required (integer).
                            • -
                            • Options - the options associated with this job (space separated - option strings).
                            • -
                            • Filename (optional) - the file to print; if this option is not - specified, the backend must read the print file from the standard - input.
                            • +
                            • Device URI - the Uniform Resource Identifier for the output device + (e.g. parallel:/dev/plp, ipp://hostname/resource +).
                            • +
                            • Job Identifier - the job identifier for this job (integer).
                            • +
                            • User Name - the user associated with this job (name string).
                            • +
                            • Title - the title/job-name associated with this job (name string).
                            • +
                            • Copies - the number of copies required (integer).
                            • +
                            • Options - the options associated with this job (space separated + option strings).
                            • +
                            • Filename (optional) - the file to print; if this option is not + specified, the backend must read the print file from the standard + input.
                            -

                            Backends are named using the scheme of the URI, so a URI of -"ipp://hostname/resource" would be processed by the "ipp" backend.

                            +

                            Backends are named using the scheme of the URI, so a URI of + "ipp://hostname/resource" would be processed by the "ipp" backend.

                            3.1.1 ipp

                            -

                            The ipp backend sends the specified job to a network printer or host -using the Internet Printing Protocol. The URI is as specified by the -printer-uri-supported attribute from the printer or host.

                            +

                            The ipp backend sends the specified job to a network printer or host + using the Internet Printing Protocol. The URI is as specified by the +printer-uri-supported attribute from the printer or host.

                            3.1.2 lpd

                            -

                            The lpd backend sends the specified job to a network printer or host -using the Line Printer Daemon protocol. The URI is of the form:

                            +

                            The lpd backend sends the specified job to a network printer or host + using the Line Printer Daemon protocol. The URI is of the form:

                              lpd://hostname/queue
                               

                            3.1.3 parallel

                            -

                            The parallel backend sends the specified job to a local printer -connected via the specified parallel port device. The URI is of the -form:

                            +

                            The parallel backend sends the specified job to a local printer + connected via the specified parallel port device. The URI is of the + form:

                              parallel:/dev/file
                               

                            3.1.4 serial

                            -

                            The serial backend sends the specified job to a local printer -connected via the specified serial port device. The URI is of the -form:

                            +

                            The serial backend sends the specified job to a local printer + connected via the specified serial port device. The URI is of the form:

                              serial:/dev/file?option[+option+...]
                               
                            - The options can be any combination of the following: + The options can be any combination of the following:
                              -
                            • baud=rate - Sets the baud rate for the device.
                            • -
                            • bits=7 or 8 - Sets the number of data bits.
                            • -
                            • parity=even - Sets even parity checking.
                            • -
                            • parity=odd - Sets odd parity checking.
                            • -
                            • parity=none - Turns parity checking off.
                            • -
                            • flow=dtrdsr - Turns DTR/DSR (hardware) flow - control on.
                            • -
                            • flow=hard - Turns RTS/CTS (hardware) flow -control on.
                            • -
                            • flow=none - Turns flow control off.
                            • -
                            • flow=rtscts - Turns RTS/CTS (hardware) flow -control on.
                            • -
                            • flow=xonxoff - Turns XON/XOFF (software) flow -control on.
                            • +
                            • baud=rate - Sets the baud rate for the device.
                            • +
                            • bits=7 or 8 - Sets the number of data bits.
                            • +
                            • parity=even - Sets even parity checking.
                            • +
                            • parity=odd - Sets odd parity checking.
                            • +
                            • parity=none - Turns parity checking off.
                            • +
                            • flow=dtrdsr - Turns DTR/DSR (hardware) flow + control on.
                            • +
                            • flow=hard - Turns RTS/CTS (hardware) flow + control on.
                            • +
                            • flow=none - Turns flow control off.
                            • +
                            • flow=rtscts - Turns RTS/CTS (hardware) flow + control on.
                            • +
                            • flow=xonxoff - Turns XON/XOFF (software) flow + control on.

                            3.1.5 socket

                            -

                            The socket backend sends the specified job to a network host using -the AppSocket protocol commonly used by Hewlett-Packard and Tektronix -printers. The URI is of the form:

                            +

                            The socket backend sends the specified job to a network host using + the AppSocket protocol commonly used by Hewlett-Packard and Tektronix + printers. The URI is of the form:

                              socket://hostname[:port]
                               
                            - The default port number is 9100. + The default port number is 9100.

                            3.1.6 usb

                            -

                            The usb backend sends the specified job to a local printer connected -via the specified usb port device. The URI is of the form:

                            +

                            The usb backend sends the specified job to a local printer connected + via the specified usb port device. The URI is of the form:

                              usb:/dev/file
                               

                            3.2 Berkeley Commands

                            -

                            The Berkeley commands provide a simple command-line interface to -CUPS to submit and control print jobs. It is provided for compatibility -with existing software that is hardcoded to use the Berkeley commands.

                            +

                            The Berkeley commands provide a simple command-line interface to CUPS + to submit and control print jobs. It is provided for compatibility with + existing software that is hardcoded to use the Berkeley commands.

                            3.2.1 lpc

                            - The lpc command allows users and administrators to check the status -and control print queues. The version provided with CUPS supports the -following commands: + The lpc command allows users and administrators to check the status and + control print queues. The version provided with CUPS supports the + following commands:
                              -
                            • quit - Quits the lpc command.
                            • -
                            • status - Shows the status of printers and jobs in the queue.
                            • +
                            • quit - Quits the lpc command.
                            • +
                            • status - Shows the status of printers and jobs in the queue.

                            3.2.2 lpq

                            -

                            The lpq command shows the current queue status.

                            +

                            The lpq command shows the current queue status.

                            3.2.3 lpr

                            -

                            The lpr command submits a job for printing. The CUPS version of lpr -silently ignores the "i", "t", "m", "h", and "s" options.

                            +

                            The lpr command submits a job for printing. The CUPS version of lpr + silently ignores the "i", "t", "m", "h", and "s" options.

                            3.2.4 lprm

                            -

                            The lprm removes one or more print jobs.

                            +

                            The lprm removes one or more print jobs.

                            3.3 CGI

                            -

                            The Common Gateway Interface (CGI) programs provide a web-based -status interface to monitor the status of printers, classes, and jobs. -Each of the CGIs utilize HTML template files that can be customized to -provide alternate appearances.

                            +

                            The Common Gateway Interface (CGI) programs provide a web-based + status interface to monitor the status of printers, classes, and jobs. + Each of the CGIs utilize HTML template files that can be customized to + provide alternate appearances.

                            3.3.1 admin.cgi

                            -

                            The admin CGI provides administration interfaces for printers and -classes. The user can add, modify, delete, start, stop, and configure -printers and classes using "wizard" interfaces.

                            +

                            The admin CGI provides administration interfaces for printers and + classes. The user can add, modify, delete, start, stop, and configure + printers and classes using "wizard" interfaces.

                            3.3.2 classes.cgi

                            -

                            The classes CGI lists the available printer classes and any pending -jobs for the class. The user can click on individual classes to limit -the display and click on jobs to see the job status.

                            +

                            The classes CGI lists the available printer classes and any pending + jobs for the class. The user can click on individual classes to limit + the display and click on jobs to see the job status.

                            3.3.3 jobs.cgi

                            -

                            The jobs CGI lists the queued print jobs in order of priority. The -list can be limited by printer or job.

                            +

                            The jobs CGI lists the queued print jobs in order of priority. The + list can be limited by printer or job.

                            3.3.4 printers.cgi

                            -

                            The printers CGI lists the available printer queues and any pending -jobs for the printer. The user can click on individual printers to -limit the display and click on jobs to see the job status.

                            +

                            The printers CGI lists the available printer queues and any pending + jobs for the printer. The user can click on individual printers to + limit the display and click on jobs to see the job status.

                            3.4 CUPS Application Programmers Interface

                            -

                            The CUPS Application Programmers Interface ("API") provides common -convenience, HTTP, IPP, language, and PPD functions used by the CUPS -software.

                            +

                            The CUPS Application Programmers Interface ("API") provides common + convenience, HTTP, IPP, language, and PPD functions used by the CUPS + software.

                            3.4.1 Convenience Functions

                            -

                            Convenience functions are provided to submit an IPP request, send a -print file, cancel a job, get a list of available printers, get a list -of available classes, get the default printer or class, get the default -server name, get the local username, and get a password string.

                            +

                            Convenience functions are provided to submit an IPP request, send a + print file, cancel a job, get a list of available printers, get a list + of available classes, get the default printer or class, get the default + server name, get the local username, and get a password string.

                            3.4.2 HTTP Functions

                            -

                            The HTTP functions provide functions to connect to HTTP servers, -issue requests, read data from a server, and write data to a server.

                            +

                            The HTTP functions provide functions to connect to HTTP servers, + issue requests, read data from a server, and write data to a server.

                            3.4.3 IPP Functions

                            -

                            The IPP function provide functions to manage IPP request data and -attributes, read IPP responses from a server, and write IPP requests to -a server.

                            +

                            The IPP function provide functions to manage IPP request data and + attributes, read IPP responses from a server, and write IPP requests to + a server.

                            3.4.4 Language Functions

                            -

                            The language functions provide a standard interface for retrieving -common textual messages for a particular locale and determining the -correct encoding (e.g. US ASCII, UTF-8, ISO-8859-1, etc.)

                            +

                            The language functions provide a standard interface for retrieving + common textual messages for a particular locale and determining the + correct encoding (e.g. US ASCII, UTF-8, ISO-8859-1, etc.)

                            3.4.5 PPD Functions

                            -

                            The PostScript Printer Description functions manage PPD files, -select options, check for option conflicts, and emit selected options -in the correct order.

                            +

                            The PostScript Printer Description functions manage PPD files, select + options, check for option conflicts, and emit selected options in the + correct order.

                            3.5 CUPS Imaging Library

                            -

                            The CUPS imaging library provides colorspace conversion, color -management, image management, scaling, image file, and raster functions -used by the CUPS raster filters.

                            +

                            The CUPS imaging library provides colorspace conversion, color + management, image management, scaling, image file, and raster functions + used by the CUPS raster filters.

                            3.5.1 Colorspace Conversion Functions

                            -

                            The colorspace conversion functions handle conversion of grayscale -and RGB colors to grayscale, RGB, K, CMY, CMYK, and CMYKcm colorspaces.

                            +

                            The colorspace conversion functions handle conversion of grayscale + and RGB colors to grayscale, RGB, K, CMY, CMYK, and CMYKcm colorspaces.

                            3.5.2 Color Management Functions

                            -

                            The color management functions handle gamut mapping and density -correction. These are integrated with the colorspace conversion -functions so that colorspace conversion and color management are -processed in a single step.

                            +

                            The color management functions handle gamut mapping and density + correction. These are integrated with the colorspace conversion + functions so that colorspace conversion and color management are + processed in a single step.

                            3.5.3 Image Management Functions

                            -

                            The image management functions manage a tiled image database that is -swapped to/from disk as needed.

                            +

                            The image management functions manage a tiled image database that is + swapped to/from disk as needed.

                            3.5.4 Scaling Functions

                            -

                            The scaling functions provide image scaling services using -nearest-neighbor sampling and bilinear interpolation as appropriate.

                            +

                            The scaling functions provide image scaling services using + nearest-neighbor sampling and bilinear interpolation as appropriate.

                            3.5.5 Image File Functions

                            -

                            The image file functions handle loading of all image file formats.

                            +

                            The image file functions handle loading of all image file formats.

                            3.5.6 Raster Functions

                            -

                            The raster functions manage streams of CUPS raster data (described -in the Interface Design Document) used by non-PostScript printer -drivers and raster filters.

                            +

                            The raster functions manage streams of CUPS raster data (described in + the Interface Design Document) used by non-PostScript printer drivers + and raster filters.

                            3.6 Daemons

                            -

                            The daemons provide additional network functions for the scheduler. -Currently only two daemons are provided with CUPS.

                            +

                            The daemons provide additional network functions for the scheduler. + Currently only two daemons are provided with CUPS.

                            3.6.1 Line Printer Daemon

                            -

                            The line printer daemon provides remote LPD client support and is -run by the inetd(8) daemon as needed.

                            +

                            The line printer daemon provides remote LPD client support and is run + by the inetd(8) daemon as needed.

                            3.6.2 Polling Daemon

                            -

                            The polling daemon is used to poll a remote server for a list of -available printers and provide it to the scheduler for addition. A -separate polling daemon is run by the scheduler for every remote system -listed for polling in the scheduler configuration file.

                            +

                            The polling daemon is used to poll a remote server for a list of + available printers and provide it to the scheduler for addition. A + separate polling daemon is run by the scheduler for every remote system + listed for polling in the scheduler configuration file.

                            3.7 Filters

                            -

                            The filters implement file conversion services for CUPS. All filters -are called with a common set of arguments:

                            +

                            The filters implement file conversion services for CUPS. All filters + are called with a common set of arguments:

                              -
                            • Printer name - the name of the destination printer (name string).
                            • -
                            • Job Identifier - the job identifier for this job (integer).
                            • -
                            • User Name - the user associated with this job (name string).
                            • -
                            • Title - the title/job-name associated with this job (name string).
                            • -
                            • Copies - the number of copies required (integer).
                            • -
                            • Options - the options associated with this job (space separated - option strings).
                            • -
                            • Filename (optional) - the file to print; if this option is not - specified, the filter must read the input file from the standard - input.
                            • +
                            • Printer name - the name of the destination printer (name string).
                            • +
                            • Job Identifier - the job identifier for this job (integer).
                            • +
                            • User Name - the user associated with this job (name string).
                            • +
                            • Title - the title/job-name associated with this job (name string).
                            • +
                            • Copies - the number of copies required (integer).
                            • +
                            • Options - the options associated with this job (space separated + option strings).
                            • +
                            • Filename (optional) - the file to print; if this option is not + specified, the filter must read the input file from the standard input.
                            -

                            Filters are added to the MIME conversion data file and implement all -necessary conversions from one file type to another.

                            +

                            Filters are added to the MIME conversion data file and implement all + necessary conversions from one file type to another.

                            3.7.1 hpgltops

                            -

                            The hpgltops filter converts HP-GL/2 files into PostScript.

                            +

                            The hpgltops filter converts HP-GL/2 files into PostScript.

                            3.7.2 imagetops

                            -

                            The imagetops filter converts image files into PostScript.

                            +

                            The imagetops filter converts image files into PostScript.

                            3.7.3 imagetoraster

                            -

                            The imagetoraster filter converts image files into CUPS raster data.

                            +

                            The imagetoraster filter converts image files into CUPS raster data.

                            3.7.4 pdftops

                            -

                            The pdftops filter converts PDF files into PostScript.

                            +

                            The pdftops filter converts PDF files into PostScript.

                            3.7.5 pstops

                            -

                            The pstops filter inserts printer-specific commands from PPD files -and performs page filtering as requested by the user.

                            +

                            The pstops filter inserts printer-specific commands from PPD files + and performs page filtering as requested by the user.

                            3.7.6 pstoraster

                            -

                            The pstoraster filter converts PostScript program data into CUPS -raster data.

                            +

                            The pstoraster filter converts PostScript program data into CUPS + raster data.

                            3.7.7 rastertoepson

                            -

                            The rastertoepson filter handles converting CUPS raster data to -ESC/P and supports both color and black-and-white printers.

                            +

                            The rastertoepson filter handles converting CUPS raster data to ESC/P + and supports both color and black-and-white printers.

                            3.7.8 rastertohp

                            -

                            The rastertohp filter handles converting CUPS raster data to HP-PCL -and supports both color and black-and-white printers.

                            +

                            The rastertohp filter handles converting CUPS raster data to HP-PCL + and supports both color and black-and-white printers.

                            3.7.9 texttops

                            -

                            The texttops filter converts text files into PostScript.

                            +

                            The texttops filter converts text files into PostScript.

                            3.8 Scheduler

                            -

                            The scheduler is a fully-functional HTTP/1.1 and IPP/1.1 server that -manages the printers, classes, and jobs in the system. It also handles -a simple broadcast-based directory service so that remote print queues -and classes can be accessed transparently from the local system.

                            +

                            The scheduler is a fully-functional HTTP/1.1 and IPP/1.1 server that + manages the printers, classes, and jobs in the system. It also handles + a simple broadcast-based directory service so that remote print queues + and classes can be accessed transparently from the local system.

                            3.8.1 Authorization

                            -

                            The authorization module is responsible for performing access -control and authentication for all HTTP and IPP requests entering the -system.

                            +

                            The authorization module is responsible for performing access control + and authentication for all HTTP and IPP requests entering the system.

                            3.8.2 Classes

                            -

                            The classes module is responsible for managing printer classes in -the system. Each class is a collection of local and/or remote printers. - The classes module also reads and writes the classes configuration -file.

                            +

                            The classes module is responsible for managing printer classes in the + system. Each class is a collection of local and/or remote printers. The + classes module also reads and writes the classes configuration file.

                            3.8.3 Client

                            -

                            The client module is responsible for all HTTP client communications. - It handles listening on selected interfaces, accepting connections -from prospective clients, processing incoming HTTP requests, and -sending HTTP responses to those requests. The client module also is -responsible for executing the external CGI programs as needed to -support web-based printer, class, and job status monitoring and -administration.

                            -

                            Once authorized, all IPP requests are sent to the IPP module.

                            +

                            The client module is responsible for all HTTP client communications. + It handles listening on selected interfaces, accepting connections from + prospective clients, processing incoming HTTP requests, and sending + HTTP responses to those requests. The client module also is responsible + for executing the external CGI programs as needed to support web-based + printer, class, and job status monitoring and administration.

                            +

                            Once authorized, all IPP requests are sent to the IPP module.

                            3.8.4 Configuration

                            -

                            The configuration module is responsible for reading the CUPS -configuration file and initializing the appropriate data structures and -values. The configuration module also stops CUPS services before -reading the configuration file and restarts them after the -configuration file has been read.

                            +

                            The configuration module is responsible for reading the CUPS + configuration file and initializing the appropriate data structures and + values. The configuration module also stops CUPS services before + reading the configuration file and restarts them after the + configuration file has been read.

                            3.8.5 Devices

                            -

                            The devices module is responsible for managing the list of available -devices for the CUPS-Get-Devices operation.

                            +

                            The devices module is responsible for managing the list of available + devices for the CUPS-Get-Devices operation.

                            3.8.6 Directory Services

                            -

                            The directory services module sends and recieves printer state -information over a broadcast socket. Remote printers and classes are -automatically added to or removed from the local printer and class -lists as needed.

                            -

                            The directory services module can only recieve printer state -information over a single UDP port, however it can broadcast to -multiple addresses and ports as needed.

                            +

                            The directory services module sends and recieves printer state + information over a broadcast socket. Remote printers and classes are + automatically added to or removed from the local printer and class + lists as needed.

                            +

                            The directory services module can only recieve printer state + information over a single UDP port, however it can broadcast to + multiple addresses and ports as needed.

                            3.8.7 IPP

                            -

                            The IPP module handles IPP requests and acts accordingly. URI -validation is also performed here, as a client can post IPP data to any -URI on the server which might sidestep the access control or -authentication of the HTTP server.

                            +

                            The IPP module handles IPP requests and acts accordingly. URI + validation is also performed here, as a client can post IPP data to any + URI on the server which might sidestep the access control or + authentication of the HTTP server.

                            3.8.8 Jobs

                            -

                            The jobs module manages print jobs, starts filter and backend -processes for jobs to be printed, and monitors status messages from -those filters and backends.

                            +

                            The jobs module manages print jobs, starts filter and backend + processes for jobs to be printed, and monitors status messages from + those filters and backends.

                            3.8.9 Logging

                            -

                            The logging module manages the access, error, and page log files -that are generated by the scheduler.

                            +

                            The logging module manages the access, error, and page log files that + are generated by the scheduler.

                            3.8.10 Main

                            -

                            The main module is responsible for timing out and dispatching input -and output for client connections. It also watches for incoming -SIGHUP and SIGCHLD signals, reloads the server -configuration files as needed, and handles child process errors and -exits.

                            +

                            The main module is responsible for timing out and dispatching input + and output for client connections. It also watches for incoming +SIGHUP and SIGCHLD signals, reloads the server + configuration files as needed, and handles child process errors and + exits.

                            3.8.11 MIME

                            -

                            The Multimedia Internet Mail Exchange module manages a MIME type and -conversion database that supports file typing by extension and content -and least-cost file filtering from a source to a destination file type.

                            +

                            The Multimedia Internet Mail Exchange module manages a MIME type and + conversion database that supports file typing by extension and content + and least-cost file filtering from a source to a destination file type.

                            3.8.12 PPDs

                            -

                            The PPDs module is responsible for managing the list of available -PPD files for the CUPS-Get-PPDs operation.

                            +

                            The PPDs module is responsible for managing the list of available PPD + files for the CUPS-Get-PPDs operation.

                            3.8.13 Printers

                            -

                            The printers module is responsible for managing printers and PPD -files in the system. The printers module also reads and writes the -printers configuration file.

                            +

                            The printers module is responsible for managing printers and PPD + files in the system. The printers module also reads and writes the + printers configuration file.

                            3.9 System V Commands

                            -

                            The System V commands provide a robust command-line interface to -CUPS to submit and control printers and jobs.

                            +

                            The System V commands provide a robust command-line interface to CUPS + to submit and control printers and jobs.

                            3.9.1 accept

                            -

                            The accept command tells the scheduler to accept new jobs for -specific printers.

                            +

                            The accept command tells the scheduler to accept new jobs for + specific printers.

                            3.9.2 cancel

                            -

                            The cancel command tells the scheduler to cancel one or more jobs -that are queued for printing.

                            +

                            The cancel command tells the scheduler to cancel one or more jobs + that are queued for printing.

                            3.9.3 disable

                            -

                            The disable command tells the scheduler to stop printing jobs on the -specified printers.

                            +

                            The disable command tells the scheduler to stop printing jobs on the + specified printers.

                            3.9.4 enable

                            -

                            The enable command tells the scheduler to start printing jobs on the -specified printers.

                            +

                            The enable command tells the scheduler to start printing jobs on the + specified printers.

                            3.9.5 lp

                            -

                            The lp command submits submits files for printing. Unlike the -standard System V lp command, a single CUPS lp command will generate a -separate job ID for each file that is printed. Also, the Solaris "f", -"H", "P", "S", and "y" options are silently ignored.

                            +

                            The lp command submits submits files for printing. Unlike the + standard System V lp command, a single CUPS lp command will generate a + separate job ID for each file that is printed. Also, the Solaris "f", + "H", "P", "S", and "y" options are silently ignored.

                            3.9.6 lpadmin

                            -

                            The lpadmin command manages printer queues and classes. The Solaris -"A", "F", "I", "M", "P", "Q", "S", "T", "U", "W", "f", "l", "m", "o", -"s", "t", and "u" options are not supported, and new options "P" (PPD -file) and "E" (enable and accept) are provided to configure -CUPS-specific features.

                            +

                            The lpadmin command manages printer queues and classes. The Solaris + "A", "F", "I", "M", "P", "Q", "S", "T", "U", "W", "f", "l", "m", "o", + "s", "t", and "u" options are not supported, and new options "P" (PPD + file) and "E" (enable and accept) are provided to configure + CUPS-specific features.

                            3.9.7 lpinfo

                            -

                            The lpinfo command lists the available PPD files or devices as -selected by the user.

                            +

                            The lpinfo command lists the available PPD files or devices as + selected by the user.

                            3.9.8 lpmove

                            -

                            The lpmove command moves a print job to a new destination.

                            +

                            The lpmove command moves a print job to a new destination.

                            3.9.9 lpoptions

                            -

                            The lpoptions command manages user-defined printers and options.

                            +

                            The lpoptions command manages user-defined printers and options.

                            3.9.10 lpstat

                            -

                            The lpstat command lists printers, classes, and jobs as requested by -the user.

                            +

                            The lpstat command lists printers, classes, and jobs as requested by + the user.

                            3.9.11 reject

                            -

                            The reject command tells the scheduler not to accept new jobs for -specific printers.

                            +

                            The reject command tells the scheduler not to accept new jobs for + specific printers.

                            A Glossary

                            A.1 Terms

                            -
                            C
                            -
                            A computer language.
                            -
                            parallel
                            -
                            Sending or receiving data more than 1 bit at a time.
                            -
                            pipe
                            -
                            A one-way communications channel between two programs.
                            -
                            serial
                            -
                            Sending or receiving data 1 bit at a time.
                            -
                            socket
                            -
                            A two-way network communications channel.
                            +
                            C
                            +
                            A computer language.
                            +
                            parallel
                            +
                            Sending or receiving data more than 1 bit at a time.
                            +
                            pipe
                            +
                            A one-way communications channel between two programs.
                            +
                            serial
                            +
                            Sending or receiving data 1 bit at a time.
                            +
                            socket
                            +
                            A two-way network communications channel.

                            A.2 Acronyms

                            -
                            ASCII
                            -
                            American Standard Code for Information Interchange
                            -
                            CUPS
                            -
                            Common UNIX Printing System
                            -
                            ESC/P
                            -
                            EPSON Standard Code for Printers
                            -
                            FTP
                            -
                            File Transfer Protocol
                            -
                            HP-GL
                            -
                            Hewlett-Packard Graphics Language
                            -
                            HP-PCL
                            -
                            Hewlett-Packard Page Control Language
                            -
                            HP-PJL
                            -
                            Hewlett-Packard Printer Job Language
                            -
                            IETF
                            -
                            Internet Engineering Task Force
                            -
                            IPP
                            -
                            Internet Printing Protocol
                            -
                            ISO
                            -
                            International Standards Organization
                            -
                            LPD
                            -
                            Line Printer Daemon
                            -
                            MIME
                            -
                            Multimedia Internet Mail Exchange
                            -
                            PPD
                            -
                            PostScript Printer Description
                            -
                            SMB
                            -
                            Server Message Block
                            -
                            TFTP
                            -
                            Trivial File Transfer Protocol
                            +
                            ASCII
                            +
                            American Standard Code for Information Interchange
                            +
                            CUPS
                            +
                            Common UNIX Printing System
                            +
                            ESC/P
                            +
                            EPSON Standard Code for Printers
                            +
                            FTP
                            +
                            File Transfer Protocol
                            +
                            HP-GL
                            +
                            Hewlett-Packard Graphics Language
                            +
                            HP-PCL
                            +
                            Hewlett-Packard Page Control Language
                            +
                            HP-PJL
                            +
                            Hewlett-Packard Printer Job Language
                            +
                            IETF
                            +
                            Internet Engineering Task Force
                            +
                            IPP
                            +
                            Internet Printing Protocol
                            +
                            ISO
                            +
                            International Standards Organization
                            +
                            LPD
                            +
                            Line Printer Daemon
                            +
                            MIME
                            +
                            Multimedia Internet Mail Exchange
                            +
                            PPD
                            +
                            PostScript Printer Description
                            +
                            SMB
                            +
                            Server Message Block
                            +
                            TFTP
                            +
                            Trivial File Transfer Protocol
                            diff --git a/doc/sdd.pdf b/doc/sdd.pdf index b801309fdb..49fe27d6d0 100644 Binary files a/doc/sdd.pdf and b/doc/sdd.pdf differ diff --git a/doc/spm.html b/doc/spm.html index 724a715b57..fa926bd57c 100644 --- a/doc/spm.html +++ b/doc/spm.html @@ -1,27 +1,27 @@ - CUPS Software Programmers Manual +CUPS Software Programmers Manual - -

                            -

                            CUPS Software Programmers Manual


                            +

                            +

                            CUPS Software Programmers Manual


                            CUPS-SPM-1.1.7
                            Easy Software Products
                            Copyright 1997-2001, All Rights Reserved
                            @@ -1072,30 +1072,30 @@ Copyright 1997-2001, All Rights Reserved

                          Preface

                          -

                          This software programmers manual provides software programming -information for the Common UNIX Printing System ("CUPS") Version 1.1.7.

                          +

                          This software programmers manual provides software programming + information for the Common UNIX Printing System <<<<<<< spm.shtml + ("CUPS") Version 1.1.7. ======= ("CUPS") Version 1.1.13. >>>>>>> 1.21

                          System Overview

                          -

                          CUPS provides a portable printing layer for UNIX®-based operating -systems. It has been developed by Easy -Software Products to promote a standard printing solution for all -UNIX vendors and users. CUPS provides the System V and Berkeley -command-line interfaces.

                          -

                          CUPS uses the Internet Printing Protocol ("IPP") as the basis for -managing print jobs and queues. The Line Printer Daemon ("LPD") Server -Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are -also supported with reduced functionality. CUPS adds network printer -browsing and PostScript Printer Description ("PPD") based printing -options to support real-world printing under UNIX.

                          -

                          CUPS also includes a customized version of GNU Ghostscript -(currently based off GNU Ghostscript 5.50) and an image file RIP that -are used to support non-PostScript printers. Sample drivers for HP and -EPSON printers are included that use these filters.

                          +

                          CUPS provides a portable printing layer for UNIX®-based operating + systems. It has been developed by Easy + Software Products to promote a standard printing solution for all + UNIX vendors and users. CUPS provides the System V and Berkeley + command-line interfaces.

                          +

                          CUPS uses the Internet Printing Protocol ("IPP") as the basis for + managing print jobs and queues. The Line Printer Daemon ("LPD") Server + Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are + also supported with reduced functionality. CUPS adds network printer + browsing and PostScript Printer Description ("PPD") based printing + options to support real-world printing under UNIX.

                          +

                          CUPS also includes a customized version of GNU Ghostscript (currently + based off GNU Ghostscript 5.50) and an image file RIP that are used to + support non-PostScript printers. Sample drivers for HP and EPSON + printers are included that use these filters.

                          -

                          Document Overview

                          -

                          This software programmers manual is organized into the following -sections:

                          +

                          This software programmers manual is organized into the following + sections:

                          Notation Conventions

                          -

                          Various font and syntax conventions are used in this guide. Examples -and their meanings and uses are explained below: +

                          Various font and syntax conventions are used in this guide. Examples + and their meanings and uses are explained below:

                          +
                          lpstat(1)     - +
                          Example   Description
                           
                          lpstat -
                          lpstat(1)
                             The names of -commands; the first mention of a command or function in a chapter is -followed by a manual page section number.
                             The names of commands; + the first mention of a command or function in a chapter is followed by + a manual page section number.
                           
                          /var
                          /usr/share/cups/data/testprint.ps
                              @@ -1127,153 +1127,153 @@ File and directory names.
                          Screen output.
                           
                          lp -d printer filename ENTER -   Literal user input; special keys like ENTER are +   Literal user input; special keys like ENTER are in ALL CAPS.
                           
                          12.3   Numbers in the text are -written using the period (.) to indicate the decimal point.
                          12.3   Numbers in the text are + written using the period (.) to indicate the decimal point.

                          Abbreviations

                          - The following abbreviations are used throughout this manual: + The following abbreviations are used throughout this manual:
                            -
                            kb
                            +
                            kb
                            Kilobytes, or 1024 bytes -
                             
                            -
                            Mb
                            +
                              +
                            Mb
                            Megabytes, or 1048576 bytes -
                             
                            -
                            Gb
                            +
                              +
                            Gb
                            Gigabytes, or 1073741824 bytes -
                             
                            +
                             

                          Other References

                            -
                            CUPS Software Administrators Manual
                            +
                            CUPS Software Administrators Manual
                            An administration guide for the CUPS software. -
                             
                            -
                            CUPS Software Users Manual
                            +
                              +
                            CUPS Software Users Manual
                            An end-user guide for using the CUPS software. -
                             
                            +
                             

                          1 - Printing System Overview

                          -

                          This chapter provides an overview of how the Common UNIX Printing -System works.

                          +

                          This chapter provides an overview of how the Common UNIX Printing + System works.

                          The Printing Problem

                          -

                          For years the printing problem has plagued UNIX. Unlike -Microsoft® Windows® or Mac OS, UNIX has no standard interface or system -in place for supporting printers. Among the solutions currently -available, the Berkeley and System V printing systems are the most -prevalent.

                          -

                          These printing systems support line printers (text only) or -PostScript printers (text and graphics), and with some coaxing they can -be made to support a full range of printers and file formats. However, -because each varient of the UNIX operating system uses a different -printing system than the next developing printer drivers for a wide -range of printers and operating systems is extremely difficult. That -combined with the limited volume of customers for each UNIX varient has -forced most printer vendors to give up supporting UNIX entirely.

                          -

                          CUPS is designed to eliminate the printing problem. One -common printing system can be used by all UNIX varients to support the -printing needs of users. Printer vendors can use its modular filter -interface to develop a single driver program that supports a wide range -of file formats with little or no effort. Since CUPS provides both the -System V and Berkeley printing commands, users (and applications) can -reap the benefits of this new technology with no changes.

                          +

                          For years the printing problem has plagued UNIX. Unlike + Microsoft® Windows® or Mac OS, UNIX has no standard interface or system + in place for supporting printers. Among the solutions currently + available, the Berkeley and System V printing systems are the most + prevalent.

                          +

                          These printing systems support line printers (text only) or + PostScript printers (text and graphics), and with some coaxing they can + be made to support a full range of printers and file formats. However, + because each varient of the UNIX operating system uses a different + printing system than the next developing printer drivers for a wide + range of printers and operating systems is extremely difficult. That + combined with the limited volume of customers for each UNIX varient has + forced most printer vendors to give up supporting UNIX entirely.

                          +

                          CUPS is designed to eliminate the printing problem. One common + printing system can be used by all UNIX varients to support the + printing needs of users. Printer vendors can use its modular filter + interface to develop a single driver program that supports a wide range + of file formats with little or no effort. Since CUPS provides both the + System V and Berkeley printing commands, users (and applications) can + reap the benefits of this new technology with no changes.

                          The Technology

                          -

                          CUPS is based upon an emerging Internet standard called the Internet -Printing Protocol. IPP has been embraced by dozens of printer and -printer server manufacturers and is supported by Microsoft Windows -2000.

                          -

                          IPP defines a standard protocol for printing as well as managing -print jobs and printer options like media size, resolution, and so -forth. Like all IP-based protocols, IPP can be used locally or over the -Internet to printers hundreds or thousands of miles away. Unlike other -protocols, however, IPP also supports access control, authentication, -and encryption, making it a much more capable and secure printing -solution than older ones.

                          -

                          IPP is layered on top of the Hyper-Text Transport Protocol ("HTTP") -which is the basis of web servers on the Internet. This allows users to -view documentation, check status information on a printer or server, -and manage their printers, classes, and jobs using their web browser.

                          -

                          CUPS provides a complete IPP/1.1 based printing system that provides -Basic, Digest, and local certificate authentication and user, domain, -or IP-based access control. TLS encryption will be available in future -versions of CUPS.

                          +

                          CUPS is based upon an emerging Internet standard called the Internet + Printing Protocol. IPP has been embraced by dozens of printer and + printer server manufacturers and is supported by Microsoft Windows + 2000.

                          +

                          IPP defines a standard protocol for printing as well as managing + print jobs and printer options like media size, resolution, and so + forth. Like all IP-based protocols, IPP can be used locally or over the + Internet to printers hundreds or thousands of miles away. Unlike other + protocols, however, IPP also supports access control, authentication, + and encryption, making it a much more capable and secure printing + solution than older ones.

                          +

                          IPP is layered on top of the Hyper-Text Transport Protocol ("HTTP") + which is the basis of web servers on the Internet. This allows users to + view documentation, check status information on a printer or server, + and manage their printers, classes, and jobs using their web browser.

                          +

                          CUPS provides a complete IPP/1.1 based printing system that provides + Basic, Digest, and local certificate authentication and user, domain, + or IP-based access control. TLS encryption will be available in future + versions of CUPS.

                          Jobs

                          -

                          Each file or set of files that is submitted for printing is called a -job. Jobs are identified by a unique number starting at 1 and are -assigned to a particular destination, usually a printer. Jobs can also -have options associated with them such as media size, number of copies, -and priority.

                          +

                          Each file or set of files that is submitted for printing is called a + job. Jobs are identified by a unique number starting at 1 and are + assigned to a particular destination, usually a printer. Jobs can also + have options associated with them such as media size, number of copies, + and priority.

                          Classes

                          -

                          CUPS supports collections of printers known as classes. Jobs -sent to a class are forwarded to the first available printer in the -class.

                          +

                          CUPS supports collections of printers known as classes. Jobs + sent to a class are forwarded to the first available printer in the + class.

                          Filters

                          -

                          Filters allow a user or application to print many types of files -without extra effort. Print jobs sent to a CUPS server are filtered -before sending them to a printer. Some filters convert job files to -different formats that the printer can understand. Others perform page -selection and ordering tasks.

                          -

                          CUPS provides filters for printing many types of image files, -HP-GL/2 files, PDF files, and text files. CUPS also supplies PostScript -and image file Raster Image Processor ("RIP") filters that convert -PostScript or image files into bitmaps that can be sent to a raster -printer.

                          +

                          Filters allow a user or application to print many types of files + without extra effort. Print jobs sent to a CUPS server are filtered + before sending them to a printer. Some filters convert job files to + different formats that the printer can understand. Others perform page + selection and ordering tasks.

                          +

                          CUPS provides filters for printing many types of image files, HP-GL/2 + files, PDF files, and text files. CUPS also supplies PostScript and + image file Raster Image Processor ("RIP") filters that convert + PostScript or image files into bitmaps that can be sent to a raster + printer.

                          Backends

                          -

                          Backends perform the most important task of all - they send the -filtered print data to the printer.

                          -

                          CUPS provides backends for printing over parallel, serial, and USB -ports, and over the network via the IPP, JetDirect (AppSocket), and -Line Printer Daemon ("LPD") protocols. Additional backends are -available in network service packages such as the SMB backend included -with the popular SAMBA software.

                          -

                          Backends are also used to determine the available devices. On -startup each backend is asked for a list of devices it supports, and -any information that is available. This allows the parallel backend to -tell CUPS that an EPSON Stylus Color 600 printer is attached to -parallel port 1, for example.

                          +

                          Backends perform the most important task of all - they send the + filtered print data to the printer.

                          +

                          CUPS provides backends for printing over parallel, serial, and USB + ports, and over the network via the IPP, JetDirect (AppSocket), and + Line Printer Daemon ("LPD") protocols. Additional backends are + available in network service packages such as the SMB backend included + with the popular SAMBA software.

                          +

                          Backends are also used to determine the available devices. On startup + each backend is asked for a list of devices it supports, and any + information that is available. This allows the parallel backend to tell + CUPS that an EPSON Stylus Color 600 printer is attached to parallel + port 1, for example.

                          Printer Drivers

                          -

                          Printer drivers in CUPS consist of one of more filters specific to a -printer. CUPS includes sample printer drivers for Hewlett-Packard -LaserJet and DeskJet printers and EPSON 9-pin, 24-pin, Stylus Color, -and Stylus Photo printers. While these drivers do not generate optimal -output for the different printer models, they do provide basic printing -and demonstrate how you can write your own printer drivers and -incorporate them into CUPS.

                          +

                          Printer drivers in CUPS consist of one of more filters specific to a + printer. CUPS includes sample printer drivers for Hewlett-Packard + LaserJet and DeskJet printers and EPSON 9-pin, 24-pin, Stylus Color, + and Stylus Photo printers. While these drivers do not generate optimal + output for the different printer models, they do provide basic printing + and demonstrate how you can write your own printer drivers and + incorporate them into CUPS.

                          Networking

                          -

                          Printers and classes on the local system are automatically shared -with other systems on the network. This allows you to setup one system -to print to a printer and use this system as a printer server or spool -host for all of the others. Users may then select a local printer by -name or a remote printer using "name@server".

                          -

                          CUPS also provides implicit classes, which are collections of -printers and/or classes with the same name. This allows you to setup -multiple servers pointing to the same physical network printer, for -example, so that you aren't relying on a single system for printing. -Because this also works with printer classes, you can setup multiple -servers and printers and never worry about a single point of failure -unless all of the printers and servers go down!

                          +

                          Printers and classes on the local system are automatically shared + with other systems on the network. This allows you to setup one system + to print to a printer and use this system as a printer server or spool + host for all of the others. Users may then select a local printer by + name or a remote printer using "name@server".

                          +

                          CUPS also provides implicit classes, which are collections of + printers and/or classes with the same name. This allows you to setup + multiple servers pointing to the same physical network printer, for + example, so that you aren't relying on a single system for printing. + Because this also works with printer classes, you can setup multiple + servers and printers and never worry about a single point of failure + unless all of the printers and servers go down!

                          2 - The CUPS API

                          -

                          This chapter describes the CUPS Application Programmers Interface -("API").

                          +

                          This chapter describes the CUPS Application Programmers Interface + ("API").

                          The CUPS API Library

                          -

                          The CUPS library provides a whole collection of interfaces needed to -support the internal needs of the CUPS software as well as the needs of -applications, filters, printer drivers, and backends.

                          -

                          Unlike the rest of CUPS, the CUPS API library is provided under the -GNU Library General Public License. This means that you can use the -CUPS API library in both proprietary and open-source programs.

                          +

                          The CUPS library provides a whole collection of interfaces needed to + support the internal needs of the CUPS software as well as the needs of + applications, filters, printer drivers, and backends.

                          +

                          Unlike the rest of CUPS, the CUPS API library is provided under the + GNU Library General Public License. This means that you can use the + CUPS API library in both proprietary and open-source programs.

                          Programs that use the CUPS API library typically will include the -<cups/cups.h> header file:

                          +<cups/cups.h> header file:

                             #include <cups/cups.h>
                            @@ -1284,19 +1284,19 @@ jobid = cupsPrintFile("myprinter", "filename.ps", "titl
                                                   num_options, options);
                             
                          -

                          Use the -lcups compiler option when linking to the CUPS -API library:

                          +

                          Use the -lcups compiler option when linking to the CUPS + API library:

                             cc -o program program.c -lcups ENTER
                             
                          -

                          Additional options and libraries may be required depending on the -operating system and the location of the CUPS API library.

                          +

                          Additional options and libraries may be required depending on the + operating system and the location of the CUPS API library.

                          Detecting the CUPS API Library in GNU Autoconf

                          -

                          GNU autoconf is a popular configuration tool used by many programs. -Add the following lines to your configure.in file to check for the -CUPS API library in your configuration script:

                          +

                          GNU autoconf is a popular configuration tool used by many programs. + Add the following lines to your configure.in file to check for the + CUPS API library in your configuration script:

                             AC_CHECK_LIB(socket,socket,
                            @@ -1316,11 +1316,11 @@ AC_CHECK_LIB(cups,httpConnect)
                             

                          Printing Services

                          -

                          The CUPS API library provides some basic printing services for -applications that need to print files.

                          +

                          The CUPS API library provides some basic printing services for + applications that need to print files.

                          Include Files

                          The include file used by all of these functions is -<cups/cups.h>:

                          +<cups/cups.h>:

                             #include <cups/cups.h>
                            @@ -1328,7 +1328,7 @@ applications that need to print files. 

                          Printing a File

                          The CUPS API provides two functions for printing files. The first is -cupsPrintFile which prints a single named file:

                          +cupsPrintFile which prints a single named file:

                             #include <cups/cups.h>
                            @@ -1342,14 +1342,14 @@ int jobid;
                             jobid = cupsPrintFile("name", "filename", "title", 0, NULL);
                             
                          -

                          The name string is the name of the printer or class to -print to. The filename string is the name of the file to -print. The title string is the name of the print job, e.g. -"Acme Word Document".

                          -

                          The return value is a unique ID number for the print job or 0 if -there was an error.

                          +

                          The name string is the name of the printer or class to + print to. The filename string is the name of the file to + print. The title string is the name of the print job, e.g. + "Acme Word Document".

                          +

                          The return value is a unique ID number for the print job or 0 if + there was an error.

                          Printing Multiple Files

                          -

                          The second printing function is cupsPrintFiles:

                          +

                          The second printing function is cupsPrintFiles:

                             #include <cups/cups.h>
                            @@ -1365,13 +1365,12 @@ jobid = cupsPrintFiles("name", num_files, files, "t
                             

                          Instead of passing a filename string as with cupsPrintFile() -, you pass a file count (num_files) and filename pointer -array (files) for each file that you want to print.

                          -

                          As with cupsPrintFile(), the return value is a unique -ID for the print job.

                          +, you pass a file count (num_files) and filename pointer + array (files) for each file that you want to print.

                          +

                          As with cupsPrintFile(), the return value is a unique ID + for the print job.

                          Cancelling Jobs

                          -

                          The cupsCancelJob() function cancels a queued print -job:

                          +

                          The cupsCancelJob() function cancels a queued print job:

                             #include <cups/cups.h>
                            @@ -1385,16 +1384,15 @@ int status;
                             status = cupsCancelJob("name", jobid);
                             
                          -

                          The name string specifies the destination and is used -to determine the server to send the request to. The jobid +

                          The name string specifies the destination and is used to + determine the server to send the request to. The jobid value is the integer returned from a previous cupsPrintFile() - or cupsPrintFiles() call.

                          -

                          cupsCancelJob() returns 1 if the job was -successfully cancelled and 0 if there was an error.

                          + or cupsPrintFiles() call.

                          +

                          cupsCancelJob() returns 1 if the job was + successfully cancelled and 0 if there was an error.

                          Getting the Available Printers and Classes

                          -

                          The cupsGetDests() function can be used to get a list -of the available printers, classes, and instances that a user has -defined:

                          +

                          The cupsGetDests() function can be used to get a list of + the available printers, classes, and instances that a user has defined:

                             #include <cups/cups.h>
                            @@ -1409,10 +1407,10 @@ cups_dest_t *dests;
                             num_dests = cupsGetDests(&dests);
                             
                          -

                          Each destination is stored in a cups_dest_t structure -which defines the printer or class name, the instance name (if any), if -it is the default destination, and the default options the user has -defined for the destination:

                          +

                          Each destination is stored in a cups_dest_t structure + which defines the printer or class name, the instance name (if any), if + it is the default destination, and the default options the user has + defined for the destination:

                             typedef struct               /**** Destination ****/
                            @@ -1425,10 +1423,10 @@ typedef struct               /**** Destination ****/
                             } cups_dest_t;
                             
                          -

                          The destinations are sorted by name and instance for your -convenience. Once you have the list of available destinations, you can -lookup a specific destination using the cupsGetDest() - function:

                          +

                          The destinations are sorted by name and instance for your + convenience. Once you have the list of available destinations, you can + lookup a specific destination using the cupsGetDest() + function:

                             #include <cups/cups.h>
                            @@ -1444,16 +1442,16 @@ cups_dest_t *mydest;
                             mydest = cupsGetDest("name", "instance", num_dests, dests);
                             
                          -

                          The name string is the printer or class name. You can -pass a value of NULL to get the default destination.

                          -

                          The instance string is the user-defined instance name. -Pass NULL to select the default instance, e.g. "name" -instead of "name/instance".

                          +

                          The name string is the printer or class name. You can + pass a value of NULL to get the default destination.

                          +

                          The instance string is the user-defined instance name. + Pass NULL to select the default instance, e.g. "name" + instead of "name/instance".

                          Printing with Options

                          All of the previous printing examples have passed 0 and NULL for the last two arguments to the cupsPrintFile() - and cupsPrintFiles() functions. These last two arguments -are the number of options and a pointer to the option array:

                          + and cupsPrintFiles() functions. These last two arguments + are the number of options and a pointer to the option array:

                             int cupsPrintFile(const char *name, const char *filename, const char *title,
                            @@ -1463,12 +1461,12 @@ int cupsPrintFiles(const char *name, int num_files, const char **files,
                             		   cups_option_t *options);
                             
                          -

                          The cups_option_t structure holds each option and its -value. These are converted as needed and passed to the CUPS server when -printing a file.

                          +

                          The cups_option_t structure holds each option and its + value. These are converted as needed and passed to the CUPS server when + printing a file.

                          The simplest way of handling options is to use the num_options and options members of the cups_dest_t - structure described earlier:

                          + structure described earlier:

                             #include <cups/cups.h>
                            @@ -1488,11 +1486,11 @@ jobid  = cupsPrintFile(mydest->name, "filename", "title",
                                                    mydest->num_options, mydest->options);
                             
                          -

                          This effectively uses the options a user has previous selected -without a lot of code.

                          +

                          This effectively uses the options a user has previous selected + without a lot of code.

                          Setting Printer Options

                          Options can also be set by your program using the -cupsAddOption() function:

                          +cupsAddOption() function:

                             #include <cups/cups.h>
                            @@ -1516,13 +1514,13 @@ num_options = cupsAddOption("name", "value", n
                             

                          The name string is the name of the option, and the -value string is the value for that option.

                          -

                          Each call to cupsAddOption() returns the new number of -options. Since adding two options with the same name overwrites the -first value with the second, do not assume that calling -cupsAddOptions() 20 times will result in 20 options.

                          -

                          Call cupsFreeOptions once you are done using the -options:

                          +value string is the value for that option.

                          +

                          Each call to cupsAddOption() returns the new number of + options. Since adding two options with the same name overwrites the + first value with the second, do not assume that calling +cupsAddOptions() 20 times will result in 20 options.

                          +

                          Call cupsFreeOptions once you are done using the + options:

                             #include <cups/cups.h>
                            @@ -1538,12 +1536,12 @@ cupsFreeOptions(num_options, options);
                             

                          Getting Errors

                          -

                          If any of the CUPS API printing functions returns an error, the -reason for that error can be found by calling cupsLastError() +

                          If any of the CUPS API printing functions returns an error, the + reason for that error can be found by calling cupsLastError() and cupsErrorString(). cupsLastError() returns the last IPP error code that was encountered. -cupsErrorString() converts the error code to a localized message -string suitable for presentation to the user:

                          +cupsErrorString() converts the error code to a localized message + string suitable for presentation to the user:

                             #include <cups/cups.h>
                            @@ -1559,22 +1557,22 @@ if (jobid == 0)
                             

                          Passwords and Authentication

                          -

                          CUPS supports authentication of any request, including submission of -print jobs. The default mechanism for getting the username and password -is to use the login user and a password from the console.

                          -

                          To support other types of applications, in particular Graphical User -Interfaces ("GUIs"), the CUPS API provides functions to set the default -username and to register a callback function that returns a password -string.

                          -

                          The cupsSetPasswordCB() - function is used to set a password callback in your program. Only one -function can be used at any time.

                          -

                          The cupsSetUser() function -sets the current username for authentication. This function can be -called by your password callback function to change the current -username as needed.

                          -

                          The following example shows a simple password callback that gets a -username and password from the user:

                          +

                          CUPS supports authentication of any request, including submission of + print jobs. The default mechanism for getting the username and password + is to use the login user and a password from the console.

                          +

                          To support other types of applications, in particular Graphical User + Interfaces ("GUIs"), the CUPS API provides functions to set the default + username and to register a callback function that returns a password + string.

                          +

                          The cupsSetPasswordCB() + function is used to set a password callback in your program. Only one + function can be used at any time.

                          +

                          The cupsSetUser() function + sets the current username for authentication. This function can be + called by your password callback function to change the current + username as needed.

                          +

                          The following example shows a simple password callback that gets a + username and password from the user:

                             #include <cups/cups.h>
                            @@ -1606,30 +1604,30 @@ my_password_cb(const char *prompt)
                             cupsSetPasswordCB(my_password_cb);
                             
                          -

                          Similarly, a GUI interface could display the prompt string in a -window with input fields for the username and password. The username -should probably default to the value of -cupsUser() to make things easier on the user.

                          +

                          Similarly, a GUI interface could display the prompt string in a + window with input fields for the username and password. The username + should probably default to the value of +cupsUser() to make things easier on the user.

                          PPD Services

                          -

                          CUPS includes functions to access and manipulate PostScript Printer -Description ("PPD") files that are used with the printer drivers in -CUPS.

                          -

                          Each PPD file enumerates the available features provided by a -printer, including conflict information for specific options (e.g. -can't duplex output on envelopes.)

                          +

                          CUPS includes functions to access and manipulate PostScript Printer + Description ("PPD") files that are used with the printer drivers in + CUPS.

                          +

                          Each PPD file enumerates the available features provided by a + printer, including conflict information for specific options (e.g. + can't duplex output on envelopes.)

                          Include Files

                          -

                          Include the <cups/ppd.h> header file to use the PPD -functions:

                          +

                          Include the <cups/ppd.h> header file to use the PPD + functions:

                             #include <cups/ppd.h>
                             

                          This header file is also included by the <cups/cups.h> - header file.

                          + header file.

                          Getting a PPD File for a Printer

                          -

                          The cupsGetPPD() function retrieves the PPD file for -the named printer or class:

                          +

                          The cupsGetPPD() function retrieves the PPD file for the + named printer or class:

                             #include <cups/cups.h>
                            @@ -1641,16 +1639,16 @@ const char *filename;
                             filename = cupsGetPPD("name");
                             
                          -

                          The name string is the name of the printer or class, -including the remote server name as appropriate (e.g. -"printer@server".)

                          -

                          The return value is a pointer to a filename in static storage; this -value is overwritten with each call to cupsGetPPD(). If -the printer or class does not exist, a NULL pointer will -be returned.

                          +

                          The name string is the name of the printer or class, + including the remote server name as appropriate (e.g. + "printer@server".)

                          +

                          The return value is a pointer to a filename in static storage; this + value is overwritten with each call to cupsGetPPD(). If + the printer or class does not exist, a NULL pointer will + be returned.

                          Loading a PPD File

                          -

                          The ppdOpenFile() function "opens" a PPD file and loads -it into memory:

                          +

                          The ppdOpenFile() function "opens" a PPD file and loads + it into memory:

                             #include <cups/ppd.h>
                            @@ -1662,13 +1660,13 @@ ppd_file_t *ppd;
                             ppd = ppdOpenFile("filename");
                             
                          -

                          The filename string is the name of the file to load, -such as the value returned by the cupsGetPPD() function.

                          -

                          The return value is a pointer to a structure describing the contents -of the PPD file or NULL if the PPD file could not be read.

                          +

                          The filename string is the name of the file to load, + such as the value returned by the cupsGetPPD() function.

                          +

                          The return value is a pointer to a structure describing the contents + of the PPD file or NULL if the PPD file could not be read.

                          Freeing PPD File Information

                          Once you are done using a PPD file, call the ppdClose() - function to free all memory that has been used:

                          + function to free all memory that has been used:

                             #include <cups/ppd.h>
                            @@ -1683,41 +1681,40 @@ ppdClose(ppd);
                             

                          The PPD File Structure

                          -

                          Each PPD file contains a number of capability attributes, printer -options, and conflict definitions. The page size options also include -the physical margins for the printer and the minimum and maximum sizes -for the printer. All of this information is stored in the -ppd_file_t structure.

                          +

                          Each PPD file contains a number of capability attributes, printer + options, and conflict definitions. The page size options also include + the physical margins for the printer and the minimum and maximum sizes + for the printer. All of this information is stored in the +ppd_file_t structure.

                          Capabilities

                          -

                          Each PPD file contains a number of informational attributes that -describe the capabilities of the printer. These are provided in the -ppd_file_t structure in the following members: +

                          Each PPD file contains a number of informational attributes that + describe the capabilities of the printer. These are provided in the +ppd_file_t structure in the following members:

                          - - + + - +Default colorspace: PPD_CS_CMYK, PPD_CS_CMY, PPD_CS_GRAY, PPD_CS_RGB, + PPD_CS_RGBK, PPD_CS_N + - +
                          ppd_emul_t * + + - +
                          char ** +
                          jcl_end The language used for the options strings (English, French, etc.) - + - + - - - + + + - + - +
                          MemberTypeDescription
                          accurate_screensint -1 = supports accurate screens
                          color_deviceint1 = -color device
                          accurate_screensint1 + = supports accurate screens
                          color_deviceint1 = + color device
                          colorspaceppd_cs_t -Default colorspace: PPD_CS_CMYK, PPD_CS_CMY, PPD_CS_GRAY, PPD_CS_RGB, -PPD_CS_RGBK, PPD_CS_N
                          contone_onlyint1 = -printer is continuous tone only
                          contone_onlyint1 = + printer is continuous tone only
                          num_emulations
                          emulations
                          int -
                          ppd_emul_t *
                          Emulations supported by the -printer
                          flip_duplexint1 = -need to flip odd pages when duplexing
                          Emulations supported by the printer
                          flip_duplexint1 = + need to flip odd pages when duplexing
                          num_fonts
                          fonts
                          int -
                          char **
                          The fonts available on the printer.
                          The fonts available on the printer.
                          jcl_begin
                          jcl_ps -
                          jcl_end
                          char *Job -Control Language commands for PostScript output
                          char *Job Control + Language commands for PostScript output
                          landscapeint Landscape orientation, -90 or 90 degrees
                          lang_encodingchar * @@ -1726,52 +1723,53 @@ The character used for the option strings
                          language_levelint PostScript language level, 1 to 3
                          manual_copiesint1 = -Copies are done manually
                          manual_copiesint1 = + Copies are done manually
                          model_numberint Driver-specific model number.
                          patcheschar *Patch -commands to send to the printer
                          patcheschar *Patch + commands to send to the printer
                          manufacturerchar * The Manufacturer attribute from the PPD file, if any
                          modelnamechar *The -ModelName attribute from the PPD file
                          nicknamechar *The -NickName attribute from the PPD file, if any
                          productchar *The -Product attribute from the PPD file, if any
                          modelnamechar *The + ModelName attribute from the PPD file
                          nicknamechar *The + NickName attribute from the PPD file, if any
                          productchar *The + Product attribute from the PPD file, if any
                          shortnicknamechar * The ShortNickName attribute from the PPD file, if any
                          throughputintNumber -of pages per minute
                          throughputintNumber + of pages per minute
                          ttrasterizerchar * The TruType font rasterizer (Type42)
                          variable_sizesint1 -= supports variable sizes
                          variable_sizesint1 = + supports variable sizes

                          Options and Groups

                          PPD files support multiple options, which are stored in -ppd_option_t and ppd_choice_t structures by the PPD -functions.

                          +ppd_option_t and ppd_choice_t structures by the PPD + functions.

                          Each option in turn is associated with a group stored in the -ppd_group_t structure. Groups can be specified in the PPD file; -if an option is not associated with a group then it is put in a -"General" or "Extra" group depending on the option.

                          -

                          Groups can also have sub-groups; CUPS currently limits the depth of -sub-groups to 1 level to reduce programming complexity.

                          +ppd_group_t structure. Groups can be specified in the PPD file; + if an option is not associated with a group then it is put in a + "General" or "Extra" group depending on the option.

                          +

                          Groups can also have sub-groups; CUPS currently limits the depth of + sub-groups to 1 level to reduce programming complexity.

                          Conflicts

                          -

                          PPD files support specification of conflict conditions between -different options. Conflicts are stored in ppd_conflict_t - structures which specify the options that conflict with each other.

                          +

                          PPD files support specification of conflict conditions between + different options. Conflicts are stored in ppd_conflict_t + structures which specify the options that conflict with each other.

                          Page Sizes

                          -

                          PPD files specify all of the available pages sizes and the physical -margins associated with them. These sizes are stored in ppd_size_t - structures and are available in the num_sizes and -sizes members of the ppd_file_t structure. You can -lookup a particular page size with the ppdPageWidth(), -ppdPageLength(), and ppdPageSize() functions:

                          +

                          PPD files specify all of the available pages sizes and the physical + margins associated with them. These sizes are stored in +ppd_size_t structures and are available in the num_sizes + and sizes members of the ppd_file_t + structure. You can lookup a particular page size with the +ppdPageWidth(), ppdPageLength(), and +ppdPageSize() functions:

                             #include <cups/ppd.h>
                            @@ -1790,10 +1788,10 @@ width  = ppdPageWidth(ppd, "size");
                             length = ppdPageLength(ppd, "size");
                             
                          -

                          The size string is the named page size option. The -width and length are in points; there are 72 points per inch. The -ppd_size_t structure contains the width, length, and margin -information:

                          +

                          The size string is the named page size option. The width + and length are in points; there are 72 points per inch. The +ppd_size_t structure contains the width, length, and margin + information:

                             typedef struct    /**** Page Sizes ****/
                            @@ -1810,14 +1808,14 @@ typedef struct    /**** Page Sizes ****/
                             

                          Custom Page Sizes

                          -

                          Besides the standard page sizes listed in a PPD file, some printers -support variable or custom page sizes. If variables_sizes +

                          Besides the standard page sizes listed in a PPD file, some printers + support variable or custom page sizes. If variables_sizes is non-zero, the custom_min, custom_max, and -custom_margins members of the ppd_file_t structure -define the limits of the variable sizes.

                          +custom_margins members of the ppd_file_t structure + define the limits of the variable sizes.

                          To get the resulting media size, use a page size string of Custom.widthxlength, where width and -length are integer values in points:

                          +length are integer values in points:

                             Custom.612x792   [8.5 inches wide, 11 inches long]
                            @@ -1826,8 +1824,8 @@ Custom.1224x792  [17 inches wide, 11 inches long]
                             

                          Marking Options

                          Before marking any user-defined options, call the -ppdMarkDefaults() function to mark the default options from the -PPD file:

                          +ppdMarkDefaults() function to mark the default options from the + PPD file:

                             #include <cups/ppd.h>
                            @@ -1841,8 +1839,8 @@ ppd_file_t *ppd;
                             ppdMarkDefaults(ppd);
                             
                          -

                          Then call the ppdMarkOption() function to mark -individual options:

                          +

                          Then call the ppdMarkOption() function to mark + individual options:

                             #include <cups/ppd.h>
                            @@ -1857,11 +1855,11 @@ int        conflicts;
                             conflicts = ppdMarkOption(ppd, "name", "value");
                             
                          -

                          The name and value strings choose a -particular option and choice, respectively. The return value is 0 if -there are not conflicts created by the selection.

                          -

                          CUPS also provides a convenience function for marking all options in -the cups_option_t structure:

                          +

                          The name and value strings choose a + particular option and choice, respectively. The return value is 0 if + there are not conflicts created by the selection.

                          +

                          CUPS also provides a convenience function for marking all options in + the cups_option_t structure:

                             #include <cups/cups.h>
                            @@ -1878,15 +1876,15 @@ int           conflicts;
                             conflicts = cupsMarkOptions(ppd, num_options, options);
                             
                          -

                          The cupsMarkOptions() function also handles mapping the -IPP job template attributes to PPD options. The return value is the -number of conflicts present.

                          +

                          The cupsMarkOptions() function also handles mapping the + IPP job template attributes to PPD options. The return value is the + number of conflicts present.

                          Checking for Conflicts

                          The ppdMarkOption() and cupsMarkOptions() - functions return the number of conflicts with the currently marked -options.

                          -

                          Call the ppdConflicts() function to get the number of -conflicts after you have marked all of the options:

                          + functions return the number of conflicts with the currently marked + options.

                          +

                          Call the ppdConflicts() function to get the number of + conflicts after you have marked all of the options:

                             #include <cups/cups.h>
                            @@ -1901,124 +1899,124 @@ int        conflicts;
                             conflicts = ppdConflicts(ppd);
                             
                          -

                          The return value is the number of conflicting options, or 0 if there -are no conflicts.

                          +

                          The return value is the number of conflicting options, or 0 if there + are no conflicts.

                          3 - Writing Filters

                          -

                          This chapter describes how to write a file filter for CUPS.

                          +

                          This chapter describes how to write a file filter for CUPS.

                          Overview

                          -

                          File filters are programs that convert from one or more MIME types -to another type. Filters use a common command-line and environment -interface that allows them to be joined as needed to print files to any -type of printer.

                          +

                          File filters are programs that convert from one or more MIME types to + another type. Filters use a common command-line and environment + interface that allows them to be joined as needed to print files to any + type of printer.

                          Security Considerations

                          -

                          Filters are normally run as a non-priviledged user, so the major -security consideration is resource utilization - filters should not -depend on unlimited amounts of memory and disk space.

                          +

                          Filters are normally run as a non-priviledged user, so the major + security consideration is resource utilization - filters should not + depend on unlimited amounts of memory and disk space.

                          Users and Groups

                          -

                          The default CUPS configuration runs filters as user "lp" and group -"other".

                          +

                          The default CUPS configuration runs filters as user "lp" and group + "other".

                          Temporary Files

                          -

                          Temporary files should be created in the directory specified by the -"TMPDIR" environment variable. The -cupsTempFile() function can be used to safely choose -temporary files in this directory.

                          +

                          Temporary files should be created in the directory specified by the + "TMPDIR" environment variable. The +cupsTempFile() function can be used to safely choose + temporary files in this directory.

                          Sending Messages to the User

                          -

                          The CUPS scheduler collects messages sent to the standard error file -by the filter. These messages are relayed to the user based upon the -scheduler LogLevel directive.

                          -

                          The type of message is determined by an initial prefix sent on each -line:

                          -
                            -
                          • DEBUG: - a debug message
                          • -
                          • INFO: - an informational message
                          • -
                          • WARNING: - a warning message
                          • -
                          • ERROR: - an error message
                          • -
                          • PAGE: - a page accounting message
                          • -
                          -

                          If the line of text does not begin with any of the above prefixes, -it is treated as a debug message. Text following the prefix is copied -to the printer-state-message attribute for the printer, -and also added to the error_log unless it is an -informational or page accounting message.

                          +

                          The CUPS scheduler collects messages sent to the standard error file + by the filter. These messages are relayed to the user based upon the + scheduler LogLevel directive.

                          +

                          The type of message is determined by an initial prefix sent on each + line:

                          +
                            +
                          • DEBUG: - a debug message
                          • +
                          • INFO: - an informational message
                          • +
                          • WARNING: - a warning message
                          • +
                          • ERROR: - an error message
                          • +
                          • PAGE: - a page accounting message
                          • +
                          +

                          If the line of text does not begin with any of the above prefixes, it + is treated as a debug message. Text following the prefix is copied to + the printer-state-message attribute for the printer, and + also added to the error_log unless it is an informational or + page accounting message.

                          Page Accounting

                          -

                          Page accounting messages are used to inform the server when one or -more pages are printed. Each line has the form:

                          +

                          Page accounting messages are used to inform the server when one or + more pages are printed. Each line has the form:

                             PAGE: page-number copy-count
                             
                          -

                          The page-number field is the current page number, starting at -1. The copy-count field specifies the number of copies of that -page that was produced.

                          -

                          Page account messages are added to the page_log file and -cause the job-sheets-completed attribute to be updated for -the job.

                          +

                          The page-number field is the current page number, starting at + 1. The copy-count field specifies the number of copies of that + page that was produced.

                          +

                          Page account messages are added to the page_log file and + cause the job-sheets-completed attribute to be updated for + the job.

                          Command-Line Arguments

                          -

                          Every filter accepts exactly 6 or 7 command-line arguments:

                          +

                          Every filter accepts exactly 6 or 7 command-line arguments:

                             printer job user title copies options [filename]
                             
                            -
                          • printer - The name of the printer queue (normally - this is the name of the program being run)
                          • -
                          • job - The numeric job ID for the job being printed
                          • -
                          • user - The string from the originating-user-name - attribute
                          • -
                          • title - The string from the job-name - attribute
                          • -
                          • copies - The numeric value from the - number-copies attribute
                          • -
                          • options - String representations of the job template -attributes, separated by spaces. Boolean attributes are provided as -"name" for true values and "noname" for false values. All other -attributes are provided as "name=value" for single-valued attributes -and "name=value1,value2,...,valueN" for set attributes
                          • -
                          • filename - The request file
                          • -
                          -

                          The filename argument is only provided to the first filter in -the chain; all filters must be prepared to read the print file -from the standard input if the filename argument is omitted.

                          +
                        • printer - The name of the printer queue (normally this + is the name of the program being run)
                        • +
                        • job - The numeric job ID for the job being printed
                        • +
                        • user - The string from the originating-user-name + attribute
                        • +
                        • title - The string from the job-name + attribute
                        • +
                        • copies - The numeric value from the number-copies + attribute
                        • +
                        • options - String representations of the job template + attributes, separated by spaces. Boolean attributes are provided as + "name" for true values and "noname" for false values. All other + attributes are provided as "name=value" for single-valued attributes + and "name=value1,value2,...,valueN" for set attributes
                        • +
                        • filename - The request file
                        • +
                        +

                        The filename argument is only provided to the first filter in + the chain; all filters must be prepared to read the print file + from the standard input if the filename argument is omitted.

                        Copy Generation

                        -

                        The copies argument specifies the number of copies to produce -of the input file. In general, you should only generate copies if the -filename argument is supplied. The only exception to this are -filters that produce device-independent PostScript output (without any -printer commands from the printer's PPD file), since the PostScript -filter pstops is responsible for copy generation.

                        +

                        The copies argument specifies the number of copies to produce + of the input file. In general, you should only generate copies if the + filename argument is supplied. The only exception to this are + filters that produce device-independent PostScript output (without any + printer commands from the printer's PPD file), since the PostScript + filter pstops is responsible for copy generation.

                        Environment Variables

                        -

                        Every filter receives a fixed set of environment variables that can -be used by the filter:

                        -
                          -
                        • CHARSET - The character set used by the client for - this print file
                        • -
                        • CONTENT_TYPE - The original document type, such as - "application/postscript"
                        • -
                        • CUPS_DATADIR - The location of CUPS data files
                        • -
                        • CUPS_SERVERROOT - The location of CUPS configuration - files
                        • -
                        • DEVICE_URI - The output device URI
                        • -
                        • LANG - The language used by the client for this print -file
                        • -
                        • PATH - The execution path exported to the filter
                        • -
                        • PPD - The full filename of the printer's PPD file
                        • -
                        • PRINTER - The name of the printer queue
                        • -
                        • RIP_CACHE - The maximum amount of memory each filter - should use
                        • -
                        • SOFTWARE - The name of the CUPS software, typically - "CUPS/1.1"
                        • -
                        • TZ - The local timezone
                        • -
                        • USER - The name of the current user
                        • +

                          Every filter receives a fixed set of environment variables that can + be used by the filter:

                          +
                            +
                          • CHARSET - The character set used by the client for this + print file
                          • +
                          • CONTENT_TYPE - The original document type, such as + "application/postscript"
                          • +
                          • CUPS_DATADIR - The location of CUPS data files
                          • +
                          • CUPS_SERVERROOT - The location of CUPS configuration + files
                          • +
                          • DEVICE_URI - The output device URI
                          • +
                          • LANG - The language used by the client for this print + file
                          • +
                          • PATH - The execution path exported to the filter
                          • +
                          • PPD - The full filename of the printer's PPD file
                          • +
                          • PRINTER - The name of the printer queue
                          • +
                          • RIP_CACHE - The maximum amount of memory each filter + should use
                          • +
                          • SOFTWARE - The name of the CUPS software, typically + "CUPS/1.1"
                          • +
                          • TZ - The local timezone
                          • +
                          • USER - The name of the current user

                          Dissecting the HP-GL/2 Filter

                          -

                          The HP-GL/2 filter (hpgltops) provided with CUPS is a -complex program that converts HP-GL/2 files into device-independent -PostScript output. Since it produces device-independent PostScript -output, it does not need to handle copy generation or writing printer -options from the printer's PPD file.

                          +

                          The HP-GL/2 filter (hpgltops) provided with CUPS is a + complex program that converts HP-GL/2 files into device-independent + PostScript output. Since it produces device-independent PostScript + output, it does not need to handle copy generation or writing printer + options from the printer's PPD file.

                          Initializing the Filter

                          -

                          The first task of any filter is to ensure that the correct number of -command-line arguments are present:

                          +

                          The first task of any filter is to ensure that the correct number of + command-line arguments are present:

                             if (argc < 6 || argc > 7)
                            @@ -2028,8 +2026,8 @@ if (argc < 6 || argc > 7)
                             }
                             
                          -

                          After this you open the print file or read from the standard input -as needed:

                          +

                          After this you open the print file or read from the standard input as + needed:

                             FILE *fp;
                            @@ -2055,9 +2053,9 @@ else
                             }
                             
                          -

                          Once the print file has been opened, options can be processed using -the cupsParseOptions() and cupsGetOption() functions:

                          +

                          Once the print file has been opened, options can be processed using + the cupsParseOptions() and cupsGetOption() functions:

                             int           num_options;
                            @@ -2081,13 +2079,13 @@ if ((val = cupsGetOption("penwidth", num_options, options)) != NULL)
                               PenWidth = (float)atoi(val) * 0.001f;
                             
                          -

                          After the options have been processed, the filter writes PostScript -code to the standard output based on the print file, closes the print -file (as needed), and returns 0 to the scheduler.

                          +

                          After the options have been processed, the filter writes PostScript + code to the standard output based on the print file, closes the print + file (as needed), and returns 0 to the scheduler.

                          PostScript Output

                          -

                          Filters that produce PostScript output must generate output -conforming to the Adobe Document Structuring Conventions, 3.0. In -general this means the beginning of each file must begin with:

                          +

                          Filters that produce PostScript output must generate output + conforming to the Adobe Document Structuring Conventions, 3.0. In + general this means the beginning of each file must begin with:

                             %!PS-Adobe-3.0
                            @@ -2096,9 +2094,9 @@ general this means the beginning of each file must begin with: 

                            %%EndComments
                          -

                          The left, bottom, right, and top values -are integers in points from the lower-lefthand corner of the page.

                          -

                          Pages must be surrounded by:

                          +

                          The left, bottom, right, and top values + are integers in points from the lower-lefthand corner of the page.

                          +

                          Pages must be surrounded by:

                             %%Page: number number
                            @@ -2108,7 +2106,7 @@ grestore
                             showpage
                             
                          -

                          And the end of each file must contain:

                          +

                          And the end of each file must contain:

                             %%Trailer
                            @@ -2116,126 +2114,125 @@ showpage
                             %%EOF
                             
                          -

                          These comments allow the PostScript filter to correctly perform page -accounting, copy generation, N-up printing, and so forth.

                          +

                          These comments allow the PostScript filter to correctly perform page + accounting, copy generation, N-up printing, and so forth.

                          4 - Writing Printer Drivers

                          -

                          This chapter discusses how to write a printer driver, which is a -special filter program that converts CUPS raster data into the -appropriate commands and data required for a printer.

                          +

                          This chapter discusses how to write a printer driver, which is a + special filter program that converts CUPS raster data into the + appropriate commands and data required for a printer.

                          Overview

                          -

                          Raster printers utilitize PPD files that specify one or more -device-specific filters that handle converting print files for the -printer. The simplest raster printer drivers provide a single filter -that converts CUPS raster data to the printer's native format.

                          +

                          Raster printers utilitize PPD files that specify one or more + device-specific filters that handle converting print files for the + printer. The simplest raster printer drivers provide a single filter + that converts CUPS raster data to the printer's native format.

                          CUPS Raster Data

                          -

                          CUPS raster data (application/vnd.cups-raster) consists -of a stream of raster page descriptions produced by one of the RIP -filters, such as pstoraster or imagetoraster.

                          -

                          Each page of data begins with a page dictionary structure called -cups_raster_header_t. This structure contains the -colorspace, bits per color, media size, media type, hardware -resolution, and so forth.

                          -

                          After the page dictionary comes the page data which is a -full-resolution, uncompressed bitmap representing the page in the -printer's output colorspace.

                          +

                          CUPS raster data (application/vnd.cups-raster) consists + of a stream of raster page descriptions produced by one of the RIP + filters, such as pstoraster or imagetoraster.

                          +

                          Each page of data begins with a page dictionary structure called + cups_raster_header_t. This structure contains the + colorspace, bits per color, media size, media type, hardware + resolution, and so forth.

                          +

                          After the page dictionary comes the page data which is a + full-resolution, uncompressed bitmap representing the page in the + printer's output colorspace.

                          Page Accounting

                          -

                          Printer drivers must handle all page accounting. This means they -must send "PAGE:" messages to the standard error file for each page -(and in many cases, copy) sent to the printer.

                          +

                          Printer drivers must handle all page accounting. This means they must + send "PAGE:" messages to the standard error file for each page (and in + many cases, copy) sent to the printer.

                          Color Management

                          Printer drivers can implement their color management via the -cupsColorProfile attributes in the PPD file or internally in the -driver from a device-independent colorspace. In general, color -management performed by the RIP filters is more efficient than that -performed inside printer drivers.

                          -

                          For example, the pstoraster filter often only has to -perform a color conversion once each time the color is used for -multiple output pixels, while the raster filter must convert every -pixel on the page.

                          +cupsColorProfile attributes in the PPD file or internally in the + driver from a device-independent colorspace. In general, color + management performed by the RIP filters is more efficient than that + performed inside printer drivers.

                          +

                          For example, the pstoraster filter often only has to + perform a color conversion once each time the color is used for + multiple output pixels, while the raster filter must convert every + pixel on the page.

                          Device and Bitmap Variables

                          -

                          Besides the standard PostScript page device dictionary variables -defined in the Adobe PostScript Level 3 reference manual, the CUPS -filters support additional variables that are passed in the page device -dictionary header for the page and in some cases control the type of -raster data that is generated: +

                          Besides the standard PostScript page device dictionary variables + defined in the Adobe PostScript Level 3 reference manual, the CUPS + filters support additional variables that are passed in the page device + dictionary header for the page and in some cases control the type of + raster data that is generated:

                          - - - - - - - + + + + + + - - - - + + +
                          VariableTypeDescription
                          cupsWidthread-only integerWidth of bitmap in -pixels
                          cupsHeightread-only integer Height of bitmap -in pixels
                          cupsMediaTyperead-write integer -Device-specific media type code
                          cupsBitsPerColorread-write integerNumber of -bits per color; 1, 2, 4, and 8 are currently supported
                          cupsBitsPerPixelread-only integer Number of -bits per pixel; 1 to 32
                          cupsBytesPerLineread-only integerNumber of -bytes per line of raster graphics
                          cupsColorOrderread-write enumThe order of -color values in the bitmap: -
                            -
                          • CUPS_ORDER_CHUNKED - CMYK CMYK CMYK
                          • -
                          • CUPS_ORDER_BANDED - CCC MMM YYY KKK
                          • -
                          • CUPS_ORDER_PLANAR - CCC ... MMM ... YYY ... KKK ...
                          • +
                          cupsWidthread-only integerWidth of bitmap in + pixels
                          cupsHeightread-only integerHeight of bitmap in + pixels
                          cupsMediaTyperead-write integerDevice-specific + media type code
                          cupsBitsPerColorread-write integerNumber of + bits per color; 1, 2, 4, and 8 are currently supported
                          cupsBitsPerPixelread-only integerNumber of + bits per pixel; 1 to 32
                          cupsBytesPerLineread-only integerNumber of + bytes per line of raster graphics
                          cupsColorOrderread-write enumThe order of + color values in the bitmap: +
                            +
                          • CUPS_ORDER_CHUNKED - CMYK CMYK CMYK
                          • +
                          • CUPS_ORDER_BANDED - CCC MMM YYY KKK
                          • +
                          • CUPS_ORDER_PLANAR - CCC ... MMM ... YYY ... KKK ...
                          cupsColorSpaceread-write enumThe colorspace -of the bitmap: -
                            -
                          • CUPS_CSPACE_W - White (luminance)
                          • -
                          • CUPS_CSPACE_RGB - Red, green, blue
                          • -
                          • CUPS_CSPACE_RGBA - Red, green, blue, alpha
                          • -
                          • CUPS_CSPACE_K - Black
                          • -
                          • CUPS_CSPACE_CMY - Cyan, magenta, yellow
                          • -
                          • CUPS_CSPACE_YMC - Yellow, magenta, cyan
                          • -
                          • CUPS_CSPACE_CMYK - Cyan, magenta, yellow, black
                          • -
                          • CUPS_CSPACE_YMCK - Yellow, magenta, cyan, black
                          • -
                          • CUPS_CSPACE_KCMY - Black, cyan, magenta, yellow
                          • -
                          • CUPS_CSPACE_KCMYcm - Black, cyan, magenta, yellow, - light cyan, light magenta
                          • -
                          • CUPS_CSPACE_GMCK - Metallic yellow (gold), metallic -magenta, metallic cyan, black
                          • -
                          • CUPS_CSPACE_GMCS - Metallic yellow (gold), metallic -magenta, metallic cyan, metallic grey (silver)
                          • -
                          • CUPS_CSPACE_WHITE - White pigment (black as white -pigment)
                          • -
                          • CUPS_CSPACE_GOLD - Gold foil (black as gold foil)
                          • -
                          • CUPS_CSPACE_SILVER - Silver foil (black as silver -foil)
                          • +
                          cupsColorSpaceread-write enumThe colorspace of + the bitmap: +
                            +
                          • CUPS_CSPACE_W - White (luminance)
                          • +
                          • CUPS_CSPACE_RGB - Red, green, blue
                          • +
                          • CUPS_CSPACE_RGBA - Red, green, blue, alpha
                          • +
                          • CUPS_CSPACE_K - Black
                          • +
                          • CUPS_CSPACE_CMY - Cyan, magenta, yellow
                          • +
                          • CUPS_CSPACE_YMC - Yellow, magenta, cyan
                          • +
                          • CUPS_CSPACE_CMYK - Cyan, magenta, yellow, black
                          • +
                          • CUPS_CSPACE_YMCK - Yellow, magenta, cyan, black
                          • +
                          • CUPS_CSPACE_KCMY - Black, cyan, magenta, yellow
                          • +
                          • CUPS_CSPACE_KCMYcm - Black, cyan, magenta, yellow, + light cyan, light magenta
                          • +
                          • CUPS_CSPACE_GMCK - Metallic yellow (gold), metallic + magenta, metallic cyan, black
                          • +
                          • CUPS_CSPACE_GMCS - Metallic yellow (gold), metallic + magenta, metallic cyan, metallic grey (silver)
                          • +
                          • CUPS_CSPACE_WHITE - White pigment (black as white + pigment)
                          • +
                          • CUPS_CSPACE_GOLD - Gold foil (black as gold foil)
                          • +
                          • CUPS_CSPACE_SILVER - Silver foil (black as silver foil)
                          cupsCompressionread-write integer Device-specific compression type code
                          cupsRowCountread-write integerDevice-specific -row count value
                          cupsRowFeedread-write integerDevice-specific -row feed value
                          cupsRowStepread-write integerDevice-specific -row step value
                          cupsRowCountread-write integerDevice-specific + row count value
                          cupsRowFeedread-write integerDevice-specific + row feed value
                          cupsRowStepread-write integerDevice-specific + row step value

                          -

                          Bitmaps with a colorspace of CUPS_CSPACE_KCMYcm and more than 1 bit -per color are transmitted to the raster driver in KCMY colorspace; the -driver is responsible for producing the correct separation of normal -and light cyan and magenta inks.

                          +

                          Bitmaps with a colorspace of CUPS_CSPACE_KCMYcm and more than 1 bit + per color are transmitted to the raster driver in KCMY colorspace; the + driver is responsible for producing the correct separation of normal + and light cyan and magenta inks.

                          Dissecting the HP-PCL Driver

                          -

                          The HP-PCL driver provided with CUPS (rastertohp) -converts bitmap data from the raster filters into HP-PCL commands for -most PCL-compatible printers. The actual format of the raster data is -controlled by the PPD file being used - deskjet.ppd or -laserjet.ppd.

                          +

                          The HP-PCL driver provided with CUPS (rastertohp) + converts bitmap data from the raster filters into HP-PCL commands for + most PCL-compatible printers. The actual format of the raster data is + controlled by the PPD file being used - deskjet.ppd or + laserjet.ppd.

                          PPD Files

                          -

                          PPD files play an important part of all raster printer drivers. -Options defined in the PPD file contain PostScript commands that -control the raster data that is sent to the printer driver.

                          +

                          PPD files play an important part of all raster printer drivers. + Options defined in the PPD file contain PostScript commands that + control the raster data that is sent to the printer driver.

                          A typical CUPS printer driver will include ColorModel, InputSlot, PageSize, PageRegion, and -Resolution options. Each option is shown using the standard PPD -format:

                          +Resolution options. Each option is shown using the standard PPD + format:

                             *OpenUI *PageSize/Media Size: PickOne
                            @@ -2259,22 +2256,22 @@ format: 

                            *CloseUI: *PageSize
                          -

                          The OpenUI keyword specifies the new option. The first -name is the option with an asterisk (*) in front of it. The first name -is usually followed by a slash (/) and a human-readable version of the -option name.

                          -

                          Every option must have a default value, specified using the -DefaultOption keyword.

                          -

                          Each option begins with the option name followed by the computer and -human-readable values. The PostScript commands follow these inside -double quotes. PostScript commands can be provided on a single line:

                          +

                          The OpenUI keyword specifies the new option. The first + name is the option with an asterisk (*) in front of it. The first name + is usually followed by a slash (/) and a human-readable version of the + option name.

                          +

                          Every option must have a default value, specified using the +DefaultOption keyword.

                          +

                          Each option begins with the option name followed by the computer and + human-readable values. The PostScript commands follow these inside + double quotes. PostScript commands can be provided on a single line:

                             *PageSize A4/A4: "<</PageSize[595 842]/ImagingBBox null>> setpagedevice"
                             
                          -

                          or broken down on separate lines using the End keyword -to terminate them:

                          +

                          or broken down on separate lines using the End keyword + to terminate them:

                             *PageSize A4/A4: "<<
                            @@ -2284,15 +2281,14 @@ to terminate them: 

                            *End
                          -

                          The choice of the two formats is usually esthetic. However, each -line in a PPD file must not exceed 255 characters, so if your -PostScript commands are long you may need to break them up on separate -lines.

                          +

                          The choice of the two formats is usually esthetic. However, each line + in a PPD file must not exceed 255 characters, so if your PostScript + commands are long you may need to break them up on separate lines.

                          Reading Raster Data

                          -

                          As with any filter, your printer driver should handle raster data -from a filename specified on the command-line or from the standard -input. The cupsRasterOpen() - function opens a raster stream for printing:

                          +

                          As with any filter, your printer driver should handle raster data + from a filename specified on the command-line or from the standard + input. The cupsRasterOpen() + function opens a raster stream for printing:

                             int           fd;   /* File descriptor */
                            @@ -2333,8 +2329,8 @@ else
                             ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
                             
                          -

                          Once you have opened the raster stream you just need to read each -page and print it:

                          +

                          Once you have opened the raster stream you just need to read each + page and print it:

                             cups_raster_header_t header;
                            @@ -2352,8 +2348,8 @@ while (cupsRasterReadHeader(ras, &header))
                             }
                             
                          -

                          After you have processed all pages, close the raster stream and -return:

                          +

                          After you have processed all pages, close the raster stream and + return:

                             cupsRasterClose(ras);
                            @@ -2362,91 +2358,91 @@ return (0);
                             

                          5 - Writing Backends

                          -

                          This chapter describes how to write a backend for CUPS. Backends -communicate directly with printers and allow printer drivers and -filters to send data using any type of connection transparently.

                          +

                          This chapter describes how to write a backend for CUPS. Backends + communicate directly with printers and allow printer drivers and + filters to send data using any type of connection transparently.

                          Overview

                          -

                          Backends are special filters that communicate with printers -directly. They are treated slightly differently than filters, however, -and have some unique requirements.

                          +

                          Backends are special filters that communicate with printers directly. + They are treated slightly differently than filters, however, and have + some unique requirements.

                          Security Considerations

                          -

                          Backends are run as the root user, so special care must be taken to -avoid potential security violations. In particular, remember that a -backend will be able to manipulate disk files, devices, and other -resources that potentially could damage a system or printer.

                          +

                          Backends are run as the root user, so special care must be taken to + avoid potential security violations. In particular, remember that a + backend will be able to manipulate disk files, devices, and other + resources that potentially could damage a system or printer.

                          Command-Line Arguments

                          -

                          Besides the standard filter arguments, backends are also run with no -arguments to get a list of available devices. This discovery process is -described later in this chapter.

                          +

                          Besides the standard filter arguments, backends are also run with no + arguments to get a list of available devices. This discovery process is + described later in this chapter.

                          Copy Generation

                          -

                          Like filters, backends should send multiple copies of the print file -only if a filename is supplied on the command-line. Otherwise the -backend should assume that the upstream filter has already added the -necessary commands or data to produce the multiple copies.

                          +

                          Like filters, backends should send multiple copies of the print file + only if a filename is supplied on the command-line. Otherwise the + backend should assume that the upstream filter has already added the + necessary commands or data to produce the multiple copies.

                          Page Accounting

                          -

                          Backend filters generally do not do page accounting, however they -should at a minimum produce a single page message for each copy that is -produced when a filename is present on the command-line. This is -because the user selected "raw" printing and no other accounting -information is possible.

                          +

                          Backend filters generally do not do page accounting, however they + should at a minimum produce a single page message for each copy that is + produced when a filename is present on the command-line. This is + because the user selected "raw" printing and no other accounting + information is possible.

                          Exclusive Access

                          -

                          Backends that talk to local character or block devices should open -the device file in exclusive mode (O_EXCL) to cooperate -with other printers defined for the same device.

                          +

                          Backends that talk to local character or block devices should open + the device file in exclusive mode (O_EXCL) to cooperate + with other printers defined for the same device.

                          Retries

                          -

                          All backends must retry connections to the device. This -includes backends that talk to local character or block devices, as the -user may define more than one printer queue pointing at the same -physical device.

                          -

                          To prevent excess CPU utilitization, the backend should go to sleep -for an amount of time between retries; the CUPS-supplied backends retry -once every 30 seconds.

                          +

                          All backends must retry connections to the device. This + includes backends that talk to local character or block devices, as the + user may define more than one printer queue pointing at the same + physical device.

                          +

                          To prevent excess CPU utilitization, the backend should go to sleep + for an amount of time between retries; the CUPS-supplied backends retry + once every 30 seconds.

                          Dissecting the Serial Port Backend

                          -

                          The serial port backend provides support for serial printers. Since -it does everything a good backend needs to do, it provides an excellent -example of what to do.

                          +

                          The serial port backend provides support for serial printers. Since + it does everything a good backend needs to do, it provides an excellent + example of what to do.

                          Supporting Device Discovery

                          -

                          As previously noted, backends are special filter programs that talk -to printer devices. Another task a backend must perform is to list the -available devices it supports. The backend lists the available devices -when no additioanl arguments are supplied on the command-line (i.e. -just the command name...)

                          -

                          The serial backend lists devices by looking at serial port files in -the /dev directory, by consulting a hardware inventory -(IRIX), and in some cases by trying to open the ports to see if they -actually exist.

                          -

                          Once it finds a serial port it writes a single line for each port to -the standard error file. Each line looks like this:

                          +

                          As previously noted, backends are special filter programs that talk + to printer devices. Another task a backend must perform is to list the + available devices it supports. The backend lists the available devices + when no additioanl arguments are supplied on the command-line (i.e. + just the command name...)

                          +

                          The serial backend lists devices by looking at serial port files in + the /dev directory, by consulting a hardware inventory + (IRIX), and in some cases by trying to open the ports to see if they + actually exist.

                          +

                          Once it finds a serial port it writes a single line for each port to + the standard error file. Each line looks like this:

                             serial serial:/dev/ttyS0?baud=115200 "Unknown" "Serial Port 1"
                             
                          -

                          The first word "serial" is the device class; this identifies -the class of device which can be used to categorize it in user -interfaces. CUPS currently recognizes the following classes:

                          -
                            -
                          • "file" - a disk file.
                          • -
                          • "direct" - a parallel or fixed-rate serial data port, currently -used for Centronics, IEEE-1284, and USB printer ports.
                          • -
                          • "serial" - a variable-rate serial port.
                          • -
                          • "network" - a network connection, typically via AppSocket, HTTP, -IPP, LPD, or SMB/CIFS protocols.
                          • -
                          -

                          After the device class is the device URI, in this case -"serial:/dev/ttyS0?baud=115200". This is the URI that should be used by -the user to select this port. For serial ports, the "baud=115200" -specifies the maximum baud rate supported by the port - the actual -value will vary based on the speed the user selects for the printer.

                          -

                          The last two strings are the model and description for the port. The -"Unknown" string means that the printer model is unknown - some devices -are able to provide a make and model such as "HP DeskJet" that allows -users and software to choose an appropriate printer driver more easily. -Both the model and description must be enclosed inside double quotes.

                          +

                          The first word "serial" is the device class; this identifies + the class of device which can be used to categorize it in user + interfaces. CUPS currently recognizes the following classes:

                          +
                            +
                          • "file" - a disk file.
                          • +
                          • "direct" - a parallel or fixed-rate serial data port, currently used + for Centronics, IEEE-1284, and USB printer ports.
                          • +
                          • "serial" - a variable-rate serial port.
                          • +
                          • "network" - a network connection, typically via AppSocket, HTTP, + IPP, LPD, or SMB/CIFS protocols.
                          • +
                          +

                          After the device class is the device URI, in this case + "serial:/dev/ttyS0?baud=115200". This is the URI that should be used by + the user to select this port. For serial ports, the "baud=115200" + specifies the maximum baud rate supported by the port - the actual + value will vary based on the speed the user selects for the printer.

                          +

                          The last two strings are the model and description for the port. The + "Unknown" string means that the printer model is unknown - some devices + are able to provide a make and model such as "HP DeskJet" that allows + users and software to choose an appropriate printer driver more easily. + Both the model and description must be enclosed inside double quotes.

                          Opening the Serial Port

                          -

                          As noted previously, all backends should open device files in -exclusive mode, and retry as needed until the port is available. The -serial port does this using a do-while loop:

                          +

                          As noted previously, all backends should open device files in + exclusive mode, and retry as needed until the port is available. The + serial port does this using a do-while loop:

                             do
                            @@ -2468,15 +2464,15 @@ do
                             while (fd < 0);
                             
                          -

                          If the port is busy or in use by another process, the backend will -go to sleep for 30 seconds and try again. If another error is detected -a message is sent to the user and the backend aborts the print job -until the problem can be corrected.

                          +

                          If the port is busy or in use by another process, the backend will go + to sleep for 30 seconds and try again. If another error is detected a + message is sent to the user and the backend aborts the print job until + the problem can be corrected.

                          Writing Data to the Port

                          -

                          Network and character devices pose an interesting problem when -writing data to the port - they may not be able to write all of the -bytes in your buffer before returning. To work around this problem you -must loop until all bytes have been written:

                          +

                          Network and character devices pose an interesting problem when + writing data to the port - they may not be able to write all of the + bytes in your buffer before returning. To work around this problem you + must loop until all bytes have been written:

                             while (nbytes > 0)
                            @@ -2496,90 +2492,89 @@ while (nbytes > 0)
                             }
                             
                          -

                          The check for the ENOTTY error is needed on some -platforms to clear an error from a previous ioctl() call.

                          +

                          The check for the ENOTTY error is needed on some + platforms to clear an error from a previous ioctl() call.

                          Finishing Up

                          -

                          Once you have sent the print file, return 0 if the file printed -successfully or 1 if it did not. This will allow the scheduler to stop -the print job if there is a device error, preserving the print job for -later printing once the problem has been corrected.

                          +

                          Once you have sent the print file, return 0 if the file printed + successfully or 1 if it did not. This will allow the scheduler to stop + the print job if there is a device error, preserving the print job for + later printing once the problem has been corrected.

                          A - Software License Agreement

                          -

                          Common UNIX Printing System License -Agreement

                          +

                          Common UNIX Printing System License + Agreement

                          Copyright 1997-2001 by Easy Software Products
                          44141 AIRPORT VIEW DR STE 204
                          HOLLYWOOD, MARYLAND 20636-3111 USA

                          Voice: +1.301.373.9600 -
                          Email: cups-info@cups.org -
                          WWW: http://www.cups.org

                          +
                          Email: cups-info@cups.org +
                          WWW: http://www.cups.org

                          Introduction

                          -

                          The Common UNIX Printing SystemTM, ("CUPSTM"), -is provided under the GNU General Public License ("GPL") and GNU -Library General Public License ("LGPL"), Version 2. A copy of these -licenses follow this introduction.

                          -

                          The GNU LGPL applies to the CUPS API library, located in the "cups" -subdirectory of the CUPS source distribution and in the -"/usr/include/cups" directory and "libcups.a", "libcups.sl", or -"libcups.so" files in the binary distributions.

                          -

                          The GNU GPL applies to the remainder of the CUPS distribution, -including the "pstoraster" filter which is based upon GNU Ghostscript -5.50 and the "pdftops" filter which is based upon Xpdf 0.90.

                          -

                          For those not familiar with the GNU GPL, the license basically -allows you to:

                          -
                            -
                          • Use the CUPS software at no charge.
                          • -
                          • Distribute verbatim copies of the software in source or binary -form.
                          • -
                          • Sell verbatim copies of the software for a media fee, or sell -support for the software.
                          • -
                          • Distribute or sell printer drivers and filters that use CUPS so -long as source code is made available under the GPL.
                          • -
                          -

                          What this license does not allow you to do is make changes or -add features to CUPS and then sell a binary distribution without source -code. You must provide source for any new drivers, changes, or -additions to the software, and all code must be provided under the GPL -or LGPL as appropriate.

                          -

                          The GNU LGPL relaxes the "link-to" restriction, allowing you to -develop applications that use the CUPS API library under other licenses -and/or conditions as appropriate for your application.

                          +

                          The Common UNIX Printing SystemTM, ("CUPSTM"), + is provided under the GNU General Public License ("GPL") and GNU + Library General Public License ("LGPL"), Version 2. A copy of these + licenses follow this introduction.

                          +

                          The GNU LGPL applies to the CUPS API library, located in the "cups" + subdirectory of the CUPS source distribution and in the + "/usr/include/cups" directory and "libcups.a", "libcups_s.a", + "libcups.sl", or "libcups.so" files in the binary distributions.

                          +

                          The GNU GPL applies to the remainder of the CUPS distribution, + including the "pstoraster" filter which is based upon GNU Ghostscript + 5.50 and the "pdftops" filter which is based upon Xpdf 0.93a.

                          +

                          For those not familiar with the GNU GPL, the license basically allows + you to:

                          +
                            +
                          • Use the CUPS software at no charge.
                          • +
                          • Distribute verbatim copies of the software in source or binary form.
                          • +
                          • Sell verbatim copies of the software for a media fee, or sell + support for the software.
                          • +
                          • Distribute or sell printer drivers and filters that use CUPS so long + as source code is made available under the GPL.
                          • +
                          +

                          What this license does not allow you to do is make changes or + add features to CUPS and then sell a binary distribution without source + code. You must provide source for any new drivers, changes, or + additions to the software, and all code must be provided under the GPL + or LGPL as appropriate.

                          +

                          The GNU LGPL relaxes the "link-to" restriction, allowing you to + develop applications that use the CUPS API library under other licenses + and/or conditions as appropriate for your application.

                          Trademarks

                          -

                          Easy Software Products has trademarked the Common UNIX Printing -System, CUPS, and CUPS logo. These names and logos may be used freely -in any direct port or binary distribution of CUPS. To use them in -derivative products, please contract Easy Software Products for written -permission. Our intention is to protect the value of these trademarks -and ensure that any derivative product meets the same high-quality -standards as the original.

                          +

                          Easy Software Products has trademarked the Common UNIX Printing + System, CUPS, and CUPS logo. These names and logos may be used freely + in any direct port or binary distribution of CUPS. To use them in + derivative products, please contract Easy Software Products for written + permission. Our intention is to protect the value of these trademarks + and ensure that any derivative product meets the same high-quality + standards as the original.

                          Binary Distribution Rights

                          -

                          Easy Software Products also sells rights to the CUPS source code -under a binary distribution license for vendors that are unable to -release source code for their drivers, additions, and modifications to -CUPS under the GNU GPL and LGPL. For information please contact us at -the address shown above.

                          -

                          The Common UNIX Printing System provides a "pstoraster" filter that -utilizes the GNU GhostScript 5.50 core to convert PostScript files into -a stream of raster images. For binary distribution licensing of this -software, please contact:

                          Miles Jones +

                          Easy Software Products also sells rights to the CUPS source code + under a binary distribution license for vendors that are unable to + release source code for their drivers, additions, and modifications to + CUPS under the GNU GPL and LGPL. For information please contact us at + the address shown above.

                          +

                          The Common UNIX Printing System provides a "pstoraster" filter that + utilizes the GNU GhostScript 5.50 core to convert PostScript files into + a stream of raster images. For binary distribution licensing of this + software, please contact:

                          Miles Jones
                          Director of Marketing
                          Artifex Software Inc.
                          454 Las Gallinas Ave., Suite 108
                          San Rafael, CA 94903 USA
                          Voice: +1.415.492.9861
                          Fax: +1.415.492.9862 -
                          EMail: info@arsoft.com
                          +
                          EMail: info@arsoft.com

                          -

                          The "pdftops" filter is based on the Xpdf 0.90 software. For binary -distribution licensing of this software, please contact:

                          +

                          The "pdftops" filter is based on the Xpdf 0.93a software. For binary + distribution licensing of this software, please contact:

                          Derek B. Noonburg -
                          Email: derekn@foolabs.com -
                          WWW: -http://www.foolabs.com/xpdf/

                          +
                          Email: derekn@foolabs.com +
                          WWW: + http://www.foolabs.com/xpdf/

                          Support

                          -

                          Easy Software Products sells software support for CUPS as well as a -commercial printing product based on CUPS called ESP Print Pro. You can -find out more at our web site:

                          +

                          Easy Software Products sells software support for CUPS as well as a + commercial printing product based on CUPS called ESP Print Pro. You can + find out more at our web site:

                          -

                          GNU GENERAL PUBLIC LICENSE

                          -

                          Version 2, June 1991

                          +

                          Version 2, June 1991

                           Copyright 1989, 1991 Free Software Foundation, Inc.
                           59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
                          @@ -2601,254 +2595,250 @@ copies of this license document, but changing it is not allowed.
                           
                           

                          Preamble

                          -

                          The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too.

                          -

                          When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it in -new free programs; and that you know you can do these things.

                          -

                          To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it.

                          -

                          For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights.

                          -

                          We protect your rights with two steps: (1) copyright the software, -and (2) offer you this license which gives you legal permission to -copy, distribute and/or modify the software.

                          -

                          Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, -we want its recipients to know that what they have is not the original, -so that any problems introduced by others will not reflect on the -original authors' reputations.

                          -

                          Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all.

                          -

                          The precise terms and conditions for copying, distribution and -modification follow.

                          +

                          The licenses for most software are designed to take away your freedom + to share and change it. By contrast, the GNU General Public License is + intended to guarantee your freedom to share and change free + software--to make sure the software is free for all its users. This + General Public License applies to most of the Free Software + Foundation's software and to any other program whose authors commit to + using it. (Some other Free Software Foundation software is covered by + the GNU Library General Public License instead.) You can apply it to + your programs, too.

                          +

                          When we speak of free software, we are referring to freedom, not + price. Our General Public Licenses are designed to make sure that you + have the freedom to distribute copies of free software (and charge for + this service if you wish), that you receive source code or can get it + if you want it, that you can change the software or use pieces of it in + new free programs; and that you know you can do these things.

                          +

                          To protect your rights, we need to make restrictions that forbid + anyone to deny you these rights or to ask you to surrender the rights. + These restrictions translate to certain responsibilities for you if you + distribute copies of the software, or if you modify it.

                          +

                          For example, if you distribute copies of such a program, whether + gratis or for a fee, you must give the recipients all the rights that + you have. You must make sure that they, too, receive or can get the + source code. And you must show them these terms so they know their + rights.

                          +

                          We protect your rights with two steps: (1) copyright the software, + and (2) offer you this license which gives you legal permission to + copy, distribute and/or modify the software.

                          +

                          Also, for each author's protection and ours, we want to make certain + that everyone understands that there is no warranty for this free + software. If the software is modified by someone else and passed on, we + want its recipients to know that what they have is not the original, so + that any problems introduced by others will not reflect on the original + authors' reputations.

                          +

                          Finally, any free program is threatened constantly by software + patents. We wish to avoid the danger that redistributors of a free + program will individually obtain patent licenses, in effect making the + program proprietary. To prevent this, we have made it clear that any + patent must be licensed for everyone's free use or not licensed at all.

                          +

                          The precise terms and conditions for copying, distribution and + modification follow.

                          GNU GENERAL PUBLIC LICENSE -
                          TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND -MODIFICATION

                          +
                          TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
                            -
                          1. This License applies to any program or other work which contains a -notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you".
                          2. -

                            Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the Program -(independent of having been made by running the Program). Whether that -is true depends on what the Program does.

                            -
                          3. You may copy and distribute verbatim copies of the Program's source -code as you receive it, in any medium, provided that you conspicuously -and appropriately publish on each copy an appropriate copyright notice -and disclaimer of warranty; keep intact all the notices that refer to -this License and to the absence of any warranty; and give any other -recipients of the Program a copy of this License along with the -Program.
                          4. -

                            You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee.

                            -
                          5. You may modify your copy or copies of the Program or any portion of -it, thus forming a work based on the Program, and copy and distribute -such modifications or work under the terms of Section 1 above, provided -that you also meet all of these conditions: +
                          6. This License applies to any program or other work which contains a + notice placed by the copyright holder saying it may be distributed + under the terms of this General Public License. The "Program", below, + refers to any such program or work, and a "work based on the Program" + means either the Program or any derivative work under copyright law: + that is to say, a work containing the Program or a portion of it, + either verbatim or with modifications and/or translated into another + language. (Hereinafter, translation is included without limitation in + the term "modification".) Each licensee is addressed as "you".
                          7. +

                            Activities other than copying, distribution and modification are not + covered by this License; they are outside its scope. The act of running + the Program is not restricted, and the output from the Program is + covered only if its contents constitute a work based on the Program + (independent of having been made by running the Program). Whether that + is true depends on what the Program does.

                            +
                          8. You may copy and distribute verbatim copies of the Program's source + code as you receive it, in any medium, provided that you conspicuously + and appropriately publish on each copy an appropriate copyright notice + and disclaimer of warranty; keep intact all the notices that refer to + this License and to the absence of any warranty; and give any other + recipients of the Program a copy of this License along with the + Program.
                          9. +

                            You may charge a fee for the physical act of transferring a copy, and + you may at your option offer warranty protection in exchange for a fee.

                            +
                          10. You may modify your copy or copies of the Program or any portion of + it, thus forming a work based on the Program, and copy and distribute + such modifications or work under the terms of Section 1 above, provided + that you also meet all of these conditions:
                              -
                            1. You must cause the modified files to carry prominent notices -stating that you changed the files and the date of any change.
                            2. -
                            3. You must cause any work that you distribute or publish, that in -whole or in part contains or is derived from the Program or any part -thereof, to be licensed as a whole at no charge to all third parties -under the terms of this License.
                            4. -
                            5. if the modified program normally reads commands interactively when -run, you must cause it, when started running for such interactive use -in the most ordinary way, to print or display an announcement including -an appropriate copyright notice and a notice that there is no warranty -(or else, saying that you provide a warranty) and that users may -redistribute the program under these conditions, and telling the user -how to view a copy of this License. (Exception: if the Program itself -is interactive but does not normally print such an announcement, your -work based on the Program is not required to print an announcement.)
                            6. +
                            7. You must cause the modified files to carry prominent notices stating + that you changed the files and the date of any change.
                            8. +
                            9. You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any part + thereof, to be licensed as a whole at no charge to all third parties + under the terms of this License.
                            10. +
                            11. if the modified program normally reads commands interactively when + run, you must cause it, when started running for such interactive use + in the most ordinary way, to print or display an announcement including + an appropriate copyright notice and a notice that there is no warranty + (or else, saying that you provide a warranty) and that users may + redistribute the program under these conditions, and telling the user + how to view a copy of this License. (Exception: if the Program itself + is interactive but does not normally print such an announcement, your + work based on the Program is not required to print an announcement.)
                          11. -

                            These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it.

                            -

                            Thus, it is not the intent of this section to claim rights or -contest your rights to work written entirely by you; rather, the intent -is to exercise the right to control the distribution of derivative or -collective works based on the Program.

                            -

                            In addition, mere aggregation of another work not based on the -Program with the Program (or with a work based on the Program) on a -volume of a storage or distribution medium does not bring the other -work under the scope of this License.

                            -
                          12. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: +

                            These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the Program, + and can be reasonably considered independent and separate works in + themselves, then this License, and its terms, do not apply to those + sections when you distribute them as separate works. But when you + distribute the same sections as part of a whole which is a work based + on the Program, the distribution of the whole must be on the terms of + this License, whose permissions for other licensees extend to the + entire whole, and thus to each and every part regardless of who wrote + it.

                            +

                            Thus, it is not the intent of this section to claim rights or contest + your rights to work written entirely by you; rather, the intent is to + exercise the right to control the distribution of derivative or + collective works based on the Program.

                            +

                            In addition, mere aggregation of another work not based on the + Program with the Program (or with a work based on the Program) on a + volume of a storage or distribution medium does not bring the other + work under the scope of this License.

                            +
                          13. You may copy and distribute the Program (or a work based on it, + under Section 2) in object code or executable form under the terms of + Sections 1 and 2 above provided that you also do one of the following:
                              -
                            1. Accompany it with the complete corresponding machine-readable -source code, which must be distributed under the terms of Sections 1 -and 2 above on a medium customarily used for software interchange; or,
                            2. -
                            3. Accompany it with a written offer, valid for at least three years, -to give any third party, for a charge no more than your cost of -physically performing source distribution, a complete machine-readable -copy of the corresponding source code, to be distributed under the -terms of Sections 1 and 2 above on a medium customarily used for -software interchange; or,
                            4. -
                            5. Accompany it with the information you received as to the offer to -distribute corresponding source code. (This alternative is allowed -only for noncommercial distribution and only if you received the -program in object code or executable form with such an offer, in accord -with Subsection b above.)
                            6. +
                            7. Accompany it with the complete corresponding machine-readable source + code, which must be distributed under the terms of Sections 1 and 2 + above on a medium customarily used for software interchange; or,
                            8. +
                            9. Accompany it with a written offer, valid for at least three years, + to give any third party, for a charge no more than your cost of + physically performing source distribution, a complete machine-readable + copy of the corresponding source code, to be distributed under the + terms of Sections 1 and 2 above on a medium customarily used for + software interchange; or,
                            10. +
                            11. Accompany it with the information you received as to the offer to + distribute corresponding source code. (This alternative is allowed only + for noncommercial distribution and only if you received the program in + object code or executable form with such an offer, in accord with + Subsection b above.)
                          14. -

                            The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to control -compilation and installation of the executable. However, as a special -exception, the source code distributed need not include anything that -is normally distributed (in either source or binary form) with the -major components (compiler, kernel, and so on) of the operating system -on which the executable runs, unless that component itself accompanies -the executable.

                            -

                            If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent access -to copy the source code from the same place counts as distribution of -the source code, even though third parties are not compelled to copy -the source along with the object code.

                            -
                          15. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt otherwise -to copy, modify, sublicense or distribute the Program is void, and will -automatically terminate your rights under this License. However, -parties who have received copies, or rights, from you under this -License will not have their licenses terminated so long as such parties -remain in full compliance.
                          16. -
                          17. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying the -Program or works based on it.
                          18. -
                          19. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License.
                          20. -
                          21. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program.
                          22. -

                            If any portion of this section is held invalid or unenforceable -under any particular circumstance, the balance of the section is -intended to apply and the section as a whole is intended to apply in -other circumstances.

                            -

                            It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice.

                            -

                            This section is intended to make thoroughly clear what is believed -to be a consequence of the rest of this License.

                            -
                          23. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License may -add an explicit geographical distribution limitation excluding those -countries, so that distribution is permitted only in or among countries -not thus excluded. In such case, this License incorporates the -limitation as if written in the body of this License.
                          24. -
                          25. The Free Software Foundation may publish revised and/or new -versions of the General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns.
                          26. -

                            Each version is given a distinguishing version number. If the -Program specifies a version number of this License which applies to it -and "any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Program does not specify a -version number of this License, you may choose any version ever -published by the Free Software Foundation.

                            -
                          27. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the -author to ask for permission. For software which is copyrighted by the -Free Software Foundation, write to the Free Software Foundation; we -sometimes make exceptions for this. Our decision will be guided by the -two goals of preserving the free status of all derivatives of our free -software and of promoting the sharing and reuse of software generally.
                          28. +

                            The source code for a work means the preferred form of the work for + making modifications to it. For an executable work, complete source + code means all the source code for all modules it contains, plus any + associated interface definition files, plus the scripts used to control + compilation and installation of the executable. However, as a special + exception, the source code distributed need not include anything that + is normally distributed (in either source or binary form) with the + major components (compiler, kernel, and so on) of the operating system + on which the executable runs, unless that component itself accompanies + the executable.

                            +

                            If distribution of executable or object code is made by offering + access to copy from a designated place, then offering equivalent access + to copy the source code from the same place counts as distribution of + the source code, even though third parties are not compelled to copy + the source along with the object code.

                            +
                          29. You may not copy, modify, sublicense, or distribute the Program + except as expressly provided under this License. Any attempt otherwise + to copy, modify, sublicense or distribute the Program is void, and will + automatically terminate your rights under this License. However, + parties who have received copies, or rights, from you under this + License will not have their licenses terminated so long as such parties + remain in full compliance.
                          30. +
                          31. You are not required to accept this License, since you have not + signed it. However, nothing else grants you permission to modify or + distribute the Program or its derivative works. These actions are + prohibited by law if you do not accept this License. Therefore, by + modifying or distributing the Program (or any work based on the + Program), you indicate your acceptance of this License to do so, and + all its terms and conditions for copying, distributing or modifying the + Program or works based on it.
                          32. +
                          33. Each time you redistribute the Program (or any work based on the + Program), the recipient automatically receives a license from the + original licensor to copy, distribute or modify the Program subject to + these terms and conditions. You may not impose any further restrictions + on the recipients' exercise of the rights granted herein. You are not + responsible for enforcing compliance by third parties to this License.
                          34. +
                          35. If, as a consequence of a court judgment or allegation of patent + infringement or for any other reason (not limited to patent issues), + conditions are imposed on you (whether by court order, agreement or + otherwise) that contradict the conditions of this License, they do not + excuse you from the conditions of this License. If you cannot + distribute so as to satisfy simultaneously your obligations under this + License and any other pertinent obligations, then as a consequence you + may not distribute the Program at all. For example, if a patent license + would not permit royalty-free redistribution of the Program by all + those who receive copies directly or indirectly through you, then the + only way you could satisfy both it and this License would be to refrain + entirely from distribution of the Program.
                          36. +

                            If any portion of this section is held invalid or unenforceable under + any particular circumstance, the balance of the section is intended to + apply and the section as a whole is intended to apply in other + circumstances.

                            +

                            It is not the purpose of this section to induce you to infringe any + patents or other property right claims or to contest validity of any + such claims; this section has the sole purpose of protecting the + integrity of the free software distribution system, which is + implemented by public license practices. Many people have made generous + contributions to the wide range of software distributed through that + system in reliance on consistent application of that system; it is up + to the author/donor to decide if he or she is willing to distribute + software through any other system and a licensee cannot impose that + choice.

                            +

                            This section is intended to make thoroughly clear what is believed to + be a consequence of the rest of this License.

                            +
                          37. If the distribution and/or use of the Program is restricted in + certain countries either by patents or by copyrighted interfaces, the + original copyright holder who places the Program under this License may + add an explicit geographical distribution limitation excluding those + countries, so that distribution is permitted only in or among countries + not thus excluded. In such case, this License incorporates the + limitation as if written in the body of this License.
                          38. +
                          39. The Free Software Foundation may publish revised and/or new versions + of the General Public License from time to time. Such new versions will + be similar in spirit to the present version, but may differ in detail + to address new problems or concerns.
                          40. +

                            Each version is given a distinguishing version number. If the Program + specifies a version number of this License which applies to it and "any + later version", you have the option of following the terms and + conditions either of that version or of any later version published by + the Free Software Foundation. If the Program does not specify a version + number of this License, you may choose any version ever published by + the Free Software Foundation.

                            +
                          41. If you wish to incorporate parts of the Program into other free + programs whose distribution conditions are different, write to the + author to ask for permission. For software which is copyrighted by the + Free Software Foundation, write to the Free Software Foundation; we + sometimes make exceptions for this. Our decision will be guided by the + two goals of preserving the free status of all derivatives of our free + software and of promoting the sharing and reuse of software generally.

                          NO WARRANTY

                            -
                          1. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. - EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, -EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS -WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
                          2. -
                          3. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES.
                          4. +
                          5. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY + FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN + OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES + PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH + YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL + NECESSARY SERVICING, REPAIR OR CORRECTION.
                          6. +
                          7. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN + WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY + AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU + FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR + CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE + PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING + RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A + FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF + SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + DAMAGES.

                          END OF TERMS AND CONDITIONS

                          -

                          GNU LIBRARY GENERAL PUBLIC LICENSE

                          -

                          Version 2, June 1991

                          +

                          Version 2, June 1991

                           Copyright (C) 1991 Free Software Foundation, Inc.
                           59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
                          @@ -2859,870 +2849,861 @@ of this license document, but changing it is not allowed.
                            numbered 2 because it goes with version 2 of the ordinary GPL.]
                           

                          Preamble

                          -

                          The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users.

                          -

                          This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too.

                          -

                          When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it in -new free programs; and that you know you can do these things.

                          -

                          To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the library, or if you modify it.

                          -

                          For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights.

                          -

                          Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library.

                          -

                          Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations.

                          -

                          Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all.

                          -

                          Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License, which was designed for utility -programs. This license, the GNU Library General Public License, -applies to certain designated libraries. This license is quite -different from the ordinary one; be sure to read it in full, and don't -assume that anything in it is the same as in the ordinary license.

                          -

                          The reason we have a separate public license for some libraries is -that they blur the distinction we usually make between modifying or -adding to a program and simply using it. Linking a program with a -library, without changing the library, is in some sense simply using -the library, and is analogous to running a utility program or -application program. However, in a textual and legal sense, the linked -executable is a combined work, a derivative of the original library, -and the ordinary General Public License treats it as such.

                          -

                          Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better.

                          -

                          However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended -to permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to -achieve this as regards changes in header files, but we have achieved -it as regards changes in the actual functions of the Library.) The -hope is that this will lead to faster development of free libraries.

                          -

                          The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library.

                          -

                          Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one.

                          +

                          The licenses for most software are designed to take away your freedom + to share and change it. By contrast, the GNU General Public Licenses + are intended to guarantee your freedom to share and change free + software--to make sure the software is free for all its users.

                          +

                          This license, the Library General Public License, applies to some + specially designated Free Software Foundation software, and to any + other libraries whose authors decide to use it. You can use it for your + libraries, too.

                          +

                          When we speak of free software, we are referring to freedom, not + price. Our General Public Licenses are designed to make sure that you + have the freedom to distribute copies of free software (and charge for + this service if you wish), that you receive source code or can get it + if you want it, that you can change the software or use pieces of it in + new free programs; and that you know you can do these things.

                          +

                          To protect your rights, we need to make restrictions that forbid + anyone to deny you these rights or to ask you to surrender the rights. + These restrictions translate to certain responsibilities for you if you + distribute copies of the library, or if you modify it.

                          +

                          For example, if you distribute copies of the library, whether gratis + or for a fee, you must give the recipients all the rights that we gave + you. You must make sure that they, too, receive or can get the source + code. If you link a program with the library, you must provide complete + object files to the recipients so that they can relink them with the + library, after making changes to the library and recompiling it. And + you must show them these terms so they know their rights.

                          +

                          Our method of protecting your rights has two steps: (1) copyright the + library, and (2) offer you this license which gives you legal + permission to copy, distribute and/or modify the library.

                          +

                          Also, for each distributor's protection, we want to make certain that + everyone understands that there is no warranty for this free library. + If the library is modified by someone else and passed on, we want its + recipients to know that what they have is not the original version, so + that any problems introduced by others will not reflect on the original + authors' reputations.

                          +

                          Finally, any free program is threatened constantly by software + patents. We wish to avoid the danger that companies distributing free + software will individually obtain patent licenses, thus in effect + transforming the program into proprietary software. To prevent this, we + have made it clear that any patent must be licensed for everyone's free + use or not licensed at all.

                          +

                          Most GNU software, including some libraries, is covered by the + ordinary GNU General Public License, which was designed for utility + programs. This license, the GNU Library General Public License, applies + to certain designated libraries. This license is quite different from + the ordinary one; be sure to read it in full, and don't assume that + anything in it is the same as in the ordinary license.

                          +

                          The reason we have a separate public license for some libraries is + that they blur the distinction we usually make between modifying or + adding to a program and simply using it. Linking a program with a + library, without changing the library, is in some sense simply using + the library, and is analogous to running a utility program or + application program. However, in a textual and legal sense, the linked + executable is a combined work, a derivative of the original library, + and the ordinary General Public License treats it as such.

                          +

                          Because of this blurred distinction, using the ordinary General + Public License for libraries did not effectively promote software + sharing, because most developers did not use the libraries. We + concluded that weaker conditions might promote sharing better.

                          +

                          However, unrestricted linking of non-free programs would deprive the + users of those programs of all benefit from the free status of the + libraries themselves. This Library General Public License is intended + to permit developers of non-free programs to use free libraries, while + preserving your freedom as a user of such programs to change the free + libraries that are incorporated in them. (We have not seen how to + achieve this as regards changes in header files, but we have achieved + it as regards changes in the actual functions of the Library.) The hope + is that this will lead to faster development of free libraries.

                          +

                          The precise terms and conditions for copying, distribution and + modification follow. Pay close attention to the difference between a + "work based on the library" and a "work that uses the library". The + former contains code derived from the library, while the latter only + works together with the library.

                          +

                          Note that it is possible for a library to be covered by the ordinary + General Public License rather than by this special one.

                          TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

                          -

                          0. This License Agreement applies to any software -library which contains a notice placed by the copyright holder or other -authorized party saying it may be distributed under the terms of this -Library General Public License (also called "this License"). Each -licensee is addressed as "you".

                          -

                          A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables.

                          -

                          The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".)

                          -

                          "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control -compilation and installation of the library.

                          -

                          Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does and -what the program that uses the Library does.

                          -

                          1. You may copy and distribute verbatim copies of -the Library's complete source code as you receive it, in any medium, -provided that you conspicuously and appropriately publish on each copy -an appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the Library.

                          -

                          You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee.

                          -

                          2. You may modify your copy or copies of the -Library or any portion of it, thus forming a work based on the Library, -and copy and distribute such modifications or work under the terms of -Section 1 above, provided that you also meet all of these conditions:

                          +

                          0. This License Agreement applies to any software + library which contains a notice placed by the copyright holder or other + authorized party saying it may be distributed under the terms of this + Library General Public License (also called "this License"). Each + licensee is addressed as "you".

                          +

                          A "library" means a collection of software functions and/or data + prepared so as to be conveniently linked with application programs + (which use some of those functions and data) to form executables.

                          +

                          The "Library", below, refers to any such software library or work + which has been distributed under these terms. A "work based on the + Library" means either the Library or any derivative work under + copyright law: that is to say, a work containing the Library or a + portion of it, either verbatim or with modifications and/or translated + straightforwardly into another language. (Hereinafter, translation is + included without limitation in the term "modification".)

                          +

                          "Source code" for a work means the preferred form of the work for + making modifications to it. For a library, complete source code means + all the source code for all modules it contains, plus any associated + interface definition files, plus the scripts used to control + compilation and installation of the library.

                          +

                          Activities other than copying, distribution and modification are not + covered by this License; they are outside its scope. The act of running + a program using the Library is not restricted, and output from such a + program is covered only if its contents constitute a work based on the + Library (independent of the use of the Library in a tool for writing + it). Whether that is true depends on what the Library does and what the + program that uses the Library does.

                          +

                          1. You may copy and distribute verbatim copies of + the Library's complete source code as you receive it, in any medium, + provided that you conspicuously and appropriately publish on each copy + an appropriate copyright notice and disclaimer of warranty; keep intact + all the notices that refer to this License and to the absence of any + warranty; and distribute a copy of this License along with the Library.

                          +

                          You may charge a fee for the physical act of transferring a copy, and + you may at your option offer warranty protection in exchange for a fee.

                          +

                          2. You may modify your copy or copies of the Library + or any portion of it, thus forming a work based on the Library, and + copy and distribute such modifications or work under the terms of + Section 1 above, provided that you also meet all of these conditions:

                            -
                          1. The modified work must itself be a software library.
                          2. +
                          3. The modified work must itself be a software library.
                          4. -
                          5. You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change.
                          6. +
                          7. You must cause the files modified to carry prominent notices stating + that you changed the files and the date of any change.
                          8. -
                          9. You must cause the whole of the work to be licensed at no charge -to all third parties under the terms of this License.
                          10. +
                          11. You must cause the whole of the work to be licensed at no charge to + all third parties under the terms of this License.
                          12. -
                          13. If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses the -facility, other than as an argument passed when the facility is -invoked, then you must make a good faith effort to ensure that, in the -event an application does not supply such function or table, the -facility still operates, and performs whatever part of its purpose -remains meaningful.
                          14. -

                            (For example, a function in a library to compute square roots has a -purpose that is entirely well-defined independent of the application. - Therefore, Subsection 2d requires that any application-supplied -function or table used by this function must be optional: if the -application does not supply it, the square root function must still -compute square roots.)

                            +
                          15. If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses the + facility, other than as an argument passed when the facility is + invoked, then you must make a good faith effort to ensure that, in the + event an application does not supply such function or table, the + facility still operates, and performs whatever part of its purpose + remains meaningful.
                          16. +

                            (For example, a function in a library to compute square roots has a + purpose that is entirely well-defined independent of the application. + Therefore, Subsection 2d requires that any application-supplied + function or table used by this function must be optional: if the + application does not supply it, the square root function must still + compute square roots.)

                          -

                          These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it.

                          -

                          Thus, it is not the intent of this section to claim rights or -contest your rights to work written entirely by you; rather, the intent -is to exercise the right to control the distribution of derivative or -collective works based on the Library.

                          -

                          In addition, mere aggregation of another work not based on the -Library with the Library (or with a work based on the Library) on a -volume of a storage or distribution medium does not bring the other -work under the scope of this License.

                          -

                          3. You may opt to apply the terms of the ordinary -GNU General Public License instead of this License to a given copy of -the Library. To do this, you must alter all the notices that refer to -this License, so that they refer to the ordinary GNU General Public -License, version 2, instead of to this License. (If a newer version -than version 2 of the ordinary GNU General Public License has appeared, -then you can specify that version instead if you wish.) Do not make -any other change in these notices.

                          -

                          Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy.

                          -

                          This option is useful when you wish to copy part of the code of the -Library into a program that is not a library.

                          -

                          4. You may copy and distribute the Library (or a -portion or derivative of it, under Section 2) in object code or -executable form under the terms of Sections 1 and 2 above provided that -you accompany it with the complete corresponding machine-readable -source code, which must be distributed under the terms of Sections 1 -and 2 above on a medium customarily used for software interchange.

                          -

                          If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to distribute -the source code, even though third parties are not compelled to copy -the source along with the object code.

                          -

                          5. A program that contains no derivative of any -portion of the Library, but is designed to work with the Library by -being compiled or linked with it, is called a "work that uses the -Library". Such a work, in isolation, is not a derivative work of the -Library, and therefore falls outside the scope of this License.

                          -

                          However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. Section -6 states terms for distribution of such executables.

                          -

                          When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law.

                          -

                          If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.)

                          -

                          Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, whether -or not they are linked directly with the Library itself.

                          -

                          6. As an exception to the Sections above, you may -also compile or link a "work that uses the Library" with the Library to -produce a work containing portions of the Library, and distribute that -work under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications.

                          -

                          You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things:

                          +

                          These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the Library, + and can be reasonably considered independent and separate works in + themselves, then this License, and its terms, do not apply to those + sections when you distribute them as separate works. But when you + distribute the same sections as part of a whole which is a work based + on the Library, the distribution of the whole must be on the terms of + this License, whose permissions for other licensees extend to the + entire whole, and thus to each and every part regardless of who wrote + it.

                          +

                          Thus, it is not the intent of this section to claim rights or contest + your rights to work written entirely by you; rather, the intent is to + exercise the right to control the distribution of derivative or + collective works based on the Library.

                          +

                          In addition, mere aggregation of another work not based on the + Library with the Library (or with a work based on the Library) on a + volume of a storage or distribution medium does not bring the other + work under the scope of this License.

                          +

                          3. You may opt to apply the terms of the ordinary + GNU General Public License instead of this License to a given copy of + the Library. To do this, you must alter all the notices that refer to + this License, so that they refer to the ordinary GNU General Public + License, version 2, instead of to this License. (If a newer version + than version 2 of the ordinary GNU General Public License has appeared, + then you can specify that version instead if you wish.) Do not make any + other change in these notices.

                          +

                          Once this change is made in a given copy, it is irreversible for that + copy, so the ordinary GNU General Public License applies to all + subsequent copies and derivative works made from that copy.

                          +

                          This option is useful when you wish to copy part of the code of the + Library into a program that is not a library.

                          +

                          4. You may copy and distribute the Library (or a + portion or derivative of it, under Section 2) in object code or + executable form under the terms of Sections 1 and 2 above provided that + you accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections 1 + and 2 above on a medium customarily used for software interchange.

                          +

                          If distribution of object code is made by offering access to copy + from a designated place, then offering equivalent access to copy the + source code from the same place satisfies the requirement to distribute + the source code, even though third parties are not compelled to copy + the source along with the object code.

                          +

                          5. A program that contains no derivative of any + portion of the Library, but is designed to work with the Library by + being compiled or linked with it, is called a "work that uses the + Library". Such a work, in isolation, is not a derivative work of the + Library, and therefore falls outside the scope of this License.

                          +

                          However, linking a "work that uses the Library" with the Library + creates an executable that is a derivative of the Library (because it + contains portions of the Library), rather than a "work that uses the + library". The executable is therefore covered by this License. Section + 6 states terms for distribution of such executables.

                          +

                          When a "work that uses the Library" uses material from a header file + that is part of the Library, the object code for the work may be a + derivative work of the Library even though the source code is not. + Whether this is true is especially significant if the work can be + linked without the Library, or if the work is itself a library. The + threshold for this to be true is not precisely defined by law.

                          +

                          If such an object file uses only numerical parameters, data structure + layouts and accessors, and small macros and small inline functions (ten + lines or less in length), then the use of the object file is + unrestricted, regardless of whether it is legally a derivative work. + (Executables containing this object code plus portions of the Library + will still fall under Section 6.)

                          +

                          Otherwise, if the work is a derivative of the Library, you may + distribute the object code for the work under the terms of Section 6. + Any executables containing that work also fall under Section 6, whether + or not they are linked directly with the Library itself.

                          +

                          6. As an exception to the Sections above, you may + also compile or link a "work that uses the Library" with the Library to + produce a work containing portions of the Library, and distribute that + work under terms of your choice, provided that the terms permit + modification of the work for the customer's own use and reverse + engineering for debugging such modifications.

                          +

                          You must give prominent notice with each copy of the work that the + Library is used in it and that the Library and its use are covered by + this License. You must supply a copy of this License. If the work + during execution displays copyright notices, you must include the + copyright notice for the Library among them, as well as a reference + directing the user to the copy of this License. Also, you must do one + of these things:

                            -
                          1. Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that uses -the Library", as object code and/or source code, so that the user can -modify the Library and then relink to produce a modified executable -containing the modified Library. (It is understood that the user who -changes the contents of definitions files in the Library will not -necessarily be able to recompile the application to use the modified -definitions.)
                          2. +
                          3. Accompany the work with the complete corresponding machine-readable + source code for the Library including whatever changes were used in the + work (which must be distributed under Sections 1 and 2 above); and, if + the work is an executable linked with the Library, with the complete + machine-readable "work that uses the Library", as object code and/or + source code, so that the user can modify the Library and then relink to + produce a modified executable containing the modified Library. (It is + understood that the user who changes the contents of definitions files + in the Library will not necessarily be able to recompile the + application to use the modified definitions.)
                          4. -
                          5. Accompany the work with a written offer, valid for at least three -years, to give the same user the materials specified in Subsection 6a, -above, for a charge no more than the cost of performing this -distribution.
                          6. +
                          7. Accompany the work with a written offer, valid for at least three + years, to give the same user the materials specified in Subsection 6a, + above, for a charge no more than the cost of performing this + distribution.
                          8. -
                          9. If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place.
                          10. +
                          11. If distribution of the work is made by offering access to copy from + a designated place, offer equivalent access to copy the above specified + materials from the same place.
                          12. -
                          13. Verify that the user has already received a copy of these - materials or that you have already sent this user a copy.
                          14. +
                          15. Verify that the user has already received a copy of these materials + or that you have already sent this user a copy.
                          -

                          For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major components -(compiler, kernel, and so on) of the operating system on which the -executable runs, unless that component itself accompanies the -executable.

                          -

                          It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute.

                          -

                          7. You may place library facilities that are a work -based on the Library side-by-side in a single library together with -other library facilities not covered by this License, and distribute -such a combined library, provided that the separate distribution of the -work based on the Library and of the other library facilities is -otherwise permitted, and provided that you do these two things:

                          +

                          For an executable, the required form of the "work that uses the + Library" must include any data and utility programs needed for + reproducing the executable from it. However, as a special exception, + the source code distributed need not include anything that is normally + distributed (in either source or binary form) with the major components + (compiler, kernel, and so on) of the operating system on which the + executable runs, unless that component itself accompanies the + executable.

                          +

                          It may happen that this requirement contradicts the license + restrictions of other proprietary libraries that do not normally + accompany the operating system. Such a contradiction means you cannot + use both them and the Library together in an executable that you + distribute.

                          +

                          7. You may place library facilities that are a work + based on the Library side-by-side in a single library together with + other library facilities not covered by this License, and distribute + such a combined library, provided that the separate distribution of the + work based on the Library and of the other library facilities is + otherwise permitted, and provided that you do these two things:

                            -
                          1. Accompany the combined library with a copy of the same work based -on the Library, uncombined with any other library facilities. This -must be distributed under the terms of the Sections above.
                          2. +
                          3. Accompany the combined library with a copy of the same work based on + the Library, uncombined with any other library facilities. This must be + distributed under the terms of the Sections above.
                          4. -
                          5. Give prominent notice with the combined library of the fact that -part of it is a work based on the Library, and explaining where to -find the accompanying uncombined form of the same work.
                          6. +
                          7. Give prominent notice with the combined library of the fact that + part of it is a work based on the Library, and explaining where to find + the accompanying uncombined form of the same work.
                          -

                          8. You may not copy, modify, sublicense, link with, -or distribute the Library except as expressly provided under this -License. Any attempt otherwise to copy, modify, sublicense, link with, -or distribute the Library is void, and will automatically terminate -your rights under this License. However, parties who have received -copies, or rights, from you under this License will not have their -licenses terminated so long as such parties remain in full compliance.

                          -

                          9. You are not required to accept this License, -since you have not signed it. However, nothing else grants you -permission to modify or distribute the Library or its derivative works. - These actions are prohibited by law if you do not accept this License. - Therefore, by modifying or distributing the Library (or any work based -on the Library), you indicate your acceptance of this License to do so, -and all its terms and conditions for copying, distributing or modifying -the Library or works based on it.

                          -

                          10. Each time you redistribute the Library (or any -work based on the Library), the recipient automatically receives a -license from the original licensor to copy, distribute, link with or -modify the Library subject to these terms and conditions. You may not -impose any further restrictions on the recipients' exercise of the -rights granted herein. You are not responsible for enforcing compliance -by third parties to this License.

                          -

                          11. If, as a consequence of a court judgment or -allegation of patent infringement or for any other reason (not limited -to patent issues), conditions are imposed on you (whether by court -order, agreement or otherwise) that contradict the conditions of this -License, they do not excuse you from the conditions of this License. - If you cannot distribute so as to satisfy simultaneously your -obligations under this License and any other pertinent obligations, -then as a consequence you may not distribute the Library at all. For -example, if a patent license would not permit royalty-free -redistribution of the Library by all those who receive copies directly -or indirectly through you, then the only way you could satisfy both it -and this License would be to refrain entirely from distribution of the -Library.

                          -

                          If any portion of this section is held invalid or unenforceable -under any particular circumstance, the balance of the section is -intended to apply, and the section as a whole is intended to apply in -other circumstances.

                          -

                          It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is implemented -by public license practices. Many people have made generous -contributions to the wide range of software distributed through that -system in reliance on consistent application of that system; it is up -to the author/donor to decide if he or she is willing to distribute -software through any other system and a licensee cannot impose that -choice.

                          -

                          This section is intended to make thoroughly clear what is believed -to be a consequence of the rest of this License.

                          -

                          12. If the distribution and/or use of the Library -is restricted in certain countries either by patents or by copyrighted -interfaces, the original copyright holder who places the Library under -this License may add an explicit geographical distribution limitation -excluding those countries, so that distribution is permitted only in or -among countries not thus excluded. In such case, this License -incorporates the limitation as if written in the body of this License.

                          -

                          13. The Free Software Foundation may publish -revised and/or new versions of the Library General Public License from -time to time. Such new versions will be similar in spirit to the -present version, but may differ in detail to address new problems or -concerns.

                          -

                          Each version is given a distinguishing version number. If the -Library specifies a version number of this License which applies to it -and "any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation.

                          -

                          14. If you wish to incorporate parts of the Library -into other free programs whose distribution conditions are incompatible -with these, write to the author to ask for permission. For software -which is copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally.

                          +

                          8. You may not copy, modify, sublicense, link with, + or distribute the Library except as expressly provided under this + License. Any attempt otherwise to copy, modify, sublicense, link with, + or distribute the Library is void, and will automatically terminate + your rights under this License. However, parties who have received + copies, or rights, from you under this License will not have their + licenses terminated so long as such parties remain in full compliance.

                          +

                          9. You are not required to accept this License, + since you have not signed it. However, nothing else grants you + permission to modify or distribute the Library or its derivative works. + These actions are prohibited by law if you do not accept this License. + Therefore, by modifying or distributing the Library (or any work based + on the Library), you indicate your acceptance of this License to do so, + and all its terms and conditions for copying, distributing or modifying + the Library or works based on it.

                          +

                          10. Each time you redistribute the Library (or any + work based on the Library), the recipient automatically receives a + license from the original licensor to copy, distribute, link with or + modify the Library subject to these terms and conditions. You may not + impose any further restrictions on the recipients' exercise of the + rights granted herein. You are not responsible for enforcing compliance + by third parties to this License.

                          +

                          11. If, as a consequence of a court judgment or + allegation of patent infringement or for any other reason (not limited + to patent issues), conditions are imposed on you (whether by court + order, agreement or otherwise) that contradict the conditions of this + License, they do not excuse you from the conditions of this License. If + you cannot distribute so as to satisfy simultaneously your obligations + under this License and any other pertinent obligations, then as a + consequence you may not distribute the Library at all. For example, if + a patent license would not permit royalty-free redistribution of the + Library by all those who receive copies directly or indirectly through + you, then the only way you could satisfy both it and this License would + be to refrain entirely from distribution of the Library.

                          +

                          If any portion of this section is held invalid or unenforceable under + any particular circumstance, the balance of the section is intended to + apply, and the section as a whole is intended to apply in other + circumstances.

                          +

                          It is not the purpose of this section to induce you to infringe any + patents or other property right claims or to contest validity of any + such claims; this section has the sole purpose of protecting the + integrity of the free software distribution system which is implemented + by public license practices. Many people have made generous + contributions to the wide range of software distributed through that + system in reliance on consistent application of that system; it is up + to the author/donor to decide if he or she is willing to distribute + software through any other system and a licensee cannot impose that + choice.

                          +

                          This section is intended to make thoroughly clear what is believed to + be a consequence of the rest of this License.

                          +

                          12. If the distribution and/or use of the Library is + restricted in certain countries either by patents or by copyrighted + interfaces, the original copyright holder who places the Library under + this License may add an explicit geographical distribution limitation + excluding those countries, so that distribution is permitted only in or + among countries not thus excluded. In such case, this License + incorporates the limitation as if written in the body of this License.

                          +

                          13. The Free Software Foundation may publish revised + and/or new versions of the Library General Public License from time to + time. Such new versions will be similar in spirit to the present + version, but may differ in detail to address new problems or concerns.

                          +

                          Each version is given a distinguishing version number. If the Library + specifies a version number of this License which applies to it and "any + later version", you have the option of following the terms and + conditions either of that version or of any later version published by + the Free Software Foundation. If the Library does not specify a license + version number, you may choose any version ever published by the Free + Software Foundation.

                          +

                          14. If you wish to incorporate parts of the Library + into other free programs whose distribution conditions are incompatible + with these, write to the author to ask for permission. For software + which is copyrighted by the Free Software Foundation, write to the Free + Software Foundation; we sometimes make exceptions for this. Our + decision will be guided by the two goals of preserving the free status + of all derivatives of our free software and of promoting the sharing + and reuse of software generally.

                          NO WARRANTY

                          -

                          15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, -THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT -WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE -OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU -ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

                          -

                          16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW -OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY -WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE -LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL -OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES.

                          +

                          15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, + THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY + APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT + HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT + WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE + OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU + ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

                          +

                          16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR + AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO + MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE + LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL + OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE + LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING + RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A + FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF + SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + DAMAGES.

                          END OF TERMS AND CONDITIONS

                          B - Constants

                          -

                          This appendix lists all of the constants that are defined by the -CUPS API.

                          +

                          This appendix lists all of the constants that are defined by the CUPS + API.

                          CUPS Constants

                          Version Number

                          -

                          The CUPS_VERSION constant is a floating-point number -representing the API version number. The current version number is -1.0100 which represents CUPS version 1.1.0.

                          +

                          The CUPS_VERSION constant is a floating-point number + representing the API version number. The current version number is + 1.0100 which represents CUPS version 1.1.0.

                          Printer Capabilities

                          -

                          The CUPS_PRINTER constants represent capability bits -for printers and classes:

                          -
                            -
                          • CUPS_PRINTER_LOCAL - Is a local printer or class.
                          • -
                          • CUPS_PRINTER_REMOTE - Is a remote printer or class.
                          • -
                          • CUPS_PRINTER_CLASS - Is a class.
                          • -
                          • CUPS_PRINTER_BW - Printer prints in black and white.
                          • -
                          • CUPS_PRINTER_COLOR - Printer prints in color.
                          • -
                          • CUPS_PRINTER_DUPLEX - Printer can print double-sided.
                          • -
                          • CUPS_PRINTER_STAPLE - Printer can staple output.
                          • -
                          • CUPS_PRINTER_COPIES - Printer can produce multiple - copies on its own.
                          • -
                          • CUPS_PRINTER_COLLATE - Printer can collate copies.
                          • -
                          • CUPS_PRINTER_PUNCH - Printer can punch holes in -output.
                          • -
                          • CUPS_PRINTER_COVER - Printer can put covers on output.
                          • -
                          • CUPS_PRINTER_BIND - Printer can bind output.
                          • -
                          • CUPS_PRINTER_SORT - Printer can sort output.
                          • -
                          • CUPS_PRINTER_SMALL - Printer can print on media up to -9x14 inches.
                          • -
                          • CUPS_PRINTER_MEDIUM - Printer can print on media from -9x14 to 18x24 inches.
                          • -
                          • CUPS_PRINTER_LARGE - Printer can print on media - larger than 18x24 inches.
                          • -
                          • CUPS_PRINTER_VARIABLE - Printer can print on variable -or custom media sizes.
                          • -
                          • CUPS_PRINTER_IMPLICIT - Is an implicit class.
                          • -
                          • CUPS_PRINTER_OPTIONS - All of the printer capability - and option bits.
                          • +

                            The CUPS_PRINTER constants represent capability bits for + printers and classes:

                            +
                              +
                            • CUPS_PRINTER_LOCAL - Is a local printer or class.
                            • +
                            • CUPS_PRINTER_REMOTE - Is a remote printer or class.
                            • +
                            • CUPS_PRINTER_CLASS - Is a class.
                            • +
                            • CUPS_PRINTER_BW - Printer prints in black and white.
                            • +
                            • CUPS_PRINTER_COLOR - Printer prints in color.
                            • +
                            • CUPS_PRINTER_DUPLEX - Printer can print double-sided.
                            • +
                            • CUPS_PRINTER_STAPLE - Printer can staple output.
                            • +
                            • CUPS_PRINTER_COPIES - Printer can produce multiple + copies on its own.
                            • +
                            • CUPS_PRINTER_COLLATE - Printer can collate copies.
                            • +
                            • CUPS_PRINTER_PUNCH - Printer can punch holes in output.
                            • +
                            • CUPS_PRINTER_COVER - Printer can put covers on output.
                            • +
                            • CUPS_PRINTER_BIND - Printer can bind output.
                            • +
                            • CUPS_PRINTER_SORT - Printer can sort output.
                            • +
                            • CUPS_PRINTER_SMALL - Printer can print on media up to + 9x14 inches.
                            • +
                            • CUPS_PRINTER_MEDIUM - Printer can print on media from + 9x14 to 18x24 inches.
                            • +
                            • CUPS_PRINTER_LARGE - Printer can print on media larger + than 18x24 inches.
                            • +
                            • CUPS_PRINTER_VARIABLE - Printer can print on variable + or custom media sizes.
                            • +
                            • CUPS_PRINTER_IMPLICIT - Is an implicit class.
                            • +
                            • CUPS_PRINTER_OPTIONS - All of the printer capability + and option bits.

                            Encodings

                            -

                            CUPS defines the following character set encoding constants:

                            -
                              -
                            • CUPS_US_ASCII - US ASCII character set.
                            • -
                            • CUPS_UTF_8 - UTF-8 encoding of Unicode.
                            • -
                            • CUPS_ISO8859_1 - ISO-8859-1 character set.
                            • -
                            • CUPS_ISO8859_2 - ISO-8859-2 character set.
                            • -
                            • CUPS_ISO8859_3 - ISO-8859-3 character set.
                            • -
                            • CUPS_ISO8859_4 - ISO-8859-4 character set.
                            • -
                            • CUPS_ISO8859_5 - ISO-8859-5 character set.
                            • -
                            • CUPS_ISO8859_6 - ISO-8859-6 character set.
                            • -
                            • CUPS_ISO8859_7 - ISO-8859-7 character set.
                            • -
                            • CUPS_ISO8859_8 - ISO-8859-8 character set.
                            • -
                            • CUPS_ISO8859_9 - ISO-8859-9 character set.
                            • -
                            • CUPS_ISO8859_10 - ISO-8859-10 character set.
                            • -
                            • CUPS_ISO8859_13 - ISO-8859-13 character set.
                            • -
                            • CUPS_ISO8859_14 - ISO-8859-14 character set.
                            • -
                            • CUPS_ISO8859_15 - ISO-8859-15 character set.
                            • -
                            • CUPS_WINDOWS_874 - Windows code page 874.
                            • -
                            • CUPS_WINDOWS_1250 - Windows code page 1250.
                            • -
                            • CUPS_WINDOWS_1251 - Windows code page 1251.
                            • -
                            • CUPS_WINDOWS_1252 - Windows code page 1252.
                            • -
                            • CUPS_WINDOWS_1253 - Windows code page 1253.
                            • -
                            • CUPS_WINDOWS_1254 - Windows code page 1254.
                            • -
                            • CUPS_WINDOWS_1255 - Windows code page 1255.
                            • -
                            • CUPS_WINDOWS_1256 - Windows code page 1256.
                            • -
                            • CUPS_WINDOWS_1257 - Windows code page 1257.
                            • -
                            • CUPS_WINDOWS_1258 - Windows code page 1258.
                            • +

                              CUPS defines the following character set encoding constants:

                              +
                                +
                              • CUPS_US_ASCII - US ASCII character set.
                              • +
                              • CUPS_UTF_8 - UTF-8 encoding of Unicode.
                              • +
                              • CUPS_ISO8859_1 - ISO-8859-1 character set.
                              • +
                              • CUPS_ISO8859_2 - ISO-8859-2 character set.
                              • +
                              • CUPS_ISO8859_3 - ISO-8859-3 character set.
                              • +
                              • CUPS_ISO8859_4 - ISO-8859-4 character set.
                              • +
                              • CUPS_ISO8859_5 - ISO-8859-5 character set.
                              • +
                              • CUPS_ISO8859_6 - ISO-8859-6 character set.
                              • +
                              • CUPS_ISO8859_7 - ISO-8859-7 character set.
                              • +
                              • CUPS_ISO8859_8 - ISO-8859-8 character set.
                              • +
                              • CUPS_ISO8859_9 - ISO-8859-9 character set.
                              • +
                              • CUPS_ISO8859_10 - ISO-8859-10 character set.
                              • +
                              • CUPS_ISO8859_13 - ISO-8859-13 character set.
                              • +
                              • CUPS_ISO8859_14 - ISO-8859-14 character set.
                              • +
                              • CUPS_ISO8859_15 - ISO-8859-15 character set.
                              • +
                              • CUPS_WINDOWS_874 - Windows code page 874.
                              • +
                              • CUPS_WINDOWS_1250 - Windows code page 1250.
                              • +
                              • CUPS_WINDOWS_1251 - Windows code page 1251.
                              • +
                              • CUPS_WINDOWS_1252 - Windows code page 1252.
                              • +
                              • CUPS_WINDOWS_1253 - Windows code page 1253.
                              • +
                              • CUPS_WINDOWS_1254 - Windows code page 1254.
                              • +
                              • CUPS_WINDOWS_1255 - Windows code page 1255.
                              • +
                              • CUPS_WINDOWS_1256 - Windows code page 1256.
                              • +
                              • CUPS_WINDOWS_1257 - Windows code page 1257.
                              • +
                              • CUPS_WINDOWS_1258 - Windows code page 1258.

                              HTTP Constants

                              Limits

                              -

                              The following constants define the limits for strings:

                              +

                              The following constants define the limits for strings:

                                -
                              • HTTP_MAX_BUFFER - Size of socket buffer.
                              • -
                              • HTTP_MAX_HOST - Maximum length of hostname.
                              • -
                              • HTTP_MAX_URI - Maximum length of URI.
                              • -
                              • HTTP_MAX_VALUE - Maximum length of field values.
                              • +
                              • HTTP_MAX_BUFFER - Size of socket buffer.
                              • +
                              • HTTP_MAX_HOST - Maximum length of hostname.
                              • +
                              • HTTP_MAX_URI - Maximum length of URI.
                              • +
                              • HTTP_MAX_VALUE - Maximum length of field values.

                              Status Codes

                              The following status codes can be returned by httpUpdate() -:

                              -
                                -
                              • HTTP_ERROR - A network error occurred
                              • -
                              • HTTP_CONTINUE - Continue response from HTTP proxy
                              • -
                              • HTTP_OK - OPTIONS/GET/HEAD/POST/TRACE command was -successful
                              • -
                              • HTTP_CREATED - PUT command was successful
                              • -
                              • HTTP_ACCEPTED - DELETE command was successful
                              • -
                              • HTTP_NOT_AUTHORITATIVE - Information isn't -authoritative
                              • -
                              • HTTP_NO_CONTENT - Successful command
                              • -
                              • HTTP_RESET_CONTENT - Content was reset/recreated
                              • -
                              • HTTP_PARTIAL_CONTENT - Only a partial file was -recieved/sent
                              • -
                              • HTTP_MULTIPLE_CHOICES - Multiple files match request
                              • -
                              • HTTP_MOVED_PERMANENTLY - Document has moved -permanently
                              • -
                              • HTTP_MOVED_TEMPORARILY - Document has moved -temporarily
                              • -
                              • HTTP_SEE_OTHER - See this other link...
                              • -
                              • HTTP_NOT_MODIFIED - File not modified
                              • -
                              • HTTP_USE_PROXY - Must use a proxy to access this URI
                              • -
                              • HTTP_BAD_REQUEST - Bad request
                              • -
                              • HTTP_UNAUTHORIZED - Unauthorized to access host
                              • -
                              • HTTP_PAYMENT_REQUIRED - Payment required
                              • -
                              • HTTP_FORBIDDEN - Forbidden to access this URI
                              • -
                              • HTTP_NOT_FOUND - URI was not found
                              • -
                              • HTTP_METHOD_NOT_ALLOWED - Method is not allowed
                              • -
                              • HTTP_NOT_ACCEPTABLE - Not Acceptable
                              • -
                              • HTTP_PROXY_AUTHENTICATION - Proxy Authentication is -Required
                              • -
                              • HTTP_REQUEST_TIMEOUT - Request timed out
                              • -
                              • HTTP_CONFLICT - Request is self-conflicting
                              • -
                              • HTTP_GONE - Server has gone away
                              • -
                              • HTTP_LENGTH_REQUIRED - A content length or encoding is -required
                              • -
                              • HTTP_PRECONDITION - Precondition failed
                              • -
                              • HTTP_REQUEST_TOO_LARGE - Request entity too large
                              • -
                              • HTTP_URI_TOO_LONG - URI too long
                              • -
                              • HTTP_UNSUPPORTED_MEDIATYPE - The requested media type -is unsupported
                              • -
                              • HTTP_SERVER_ERROR - Internal server error
                              • -
                              • HTTP_NOT_IMPLEMENTED - Feature not implemented
                              • -
                              • HTTP_BAD_GATEWAY - Bad gateway
                              • -
                              • HTTP_SERVICE_UNAVAILABLE - Service is unavailable
                              • -
                              • HTTP_GATEWAY_TIMEOUT - Gateway connection timed out
                              • -
                              • HTTP_NOT_SUPPORTED - HTTP version not supported
                              • +:

                                +
                                  +
                                • HTTP_ERROR - A network error occurred
                                • +
                                • HTTP_CONTINUE - Continue response from HTTP proxy
                                • +
                                • HTTP_OK - OPTIONS/GET/HEAD/POST/TRACE command was + successful
                                • +
                                • HTTP_CREATED - PUT command was successful
                                • +
                                • HTTP_ACCEPTED - DELETE command was successful
                                • +
                                • HTTP_NOT_AUTHORITATIVE - Information isn't + authoritative
                                • +
                                • HTTP_NO_CONTENT - Successful command
                                • +
                                • HTTP_RESET_CONTENT - Content was reset/recreated
                                • +
                                • HTTP_PARTIAL_CONTENT - Only a partial file was + recieved/sent
                                • +
                                • HTTP_MULTIPLE_CHOICES - Multiple files match request
                                • +
                                • HTTP_MOVED_PERMANENTLY - Document has moved permanently
                                • +
                                • HTTP_MOVED_TEMPORARILY - Document has moved temporarily
                                • +
                                • HTTP_SEE_OTHER - See this other link...
                                • +
                                • HTTP_NOT_MODIFIED - File not modified
                                • +
                                • HTTP_USE_PROXY - Must use a proxy to access this URI
                                • +
                                • HTTP_BAD_REQUEST - Bad request
                                • +
                                • HTTP_UNAUTHORIZED - Unauthorized to access host
                                • +
                                • HTTP_PAYMENT_REQUIRED - Payment required
                                • +
                                • HTTP_FORBIDDEN - Forbidden to access this URI
                                • +
                                • HTTP_NOT_FOUND - URI was not found
                                • +
                                • HTTP_METHOD_NOT_ALLOWED - Method is not allowed
                                • +
                                • HTTP_NOT_ACCEPTABLE - Not Acceptable
                                • +
                                • HTTP_PROXY_AUTHENTICATION - Proxy Authentication is + Required
                                • +
                                • HTTP_REQUEST_TIMEOUT - Request timed out
                                • +
                                • HTTP_CONFLICT - Request is self-conflicting
                                • +
                                • HTTP_GONE - Server has gone away
                                • +
                                • HTTP_LENGTH_REQUIRED - A content length or encoding is + required
                                • +
                                • HTTP_PRECONDITION - Precondition failed
                                • +
                                • HTTP_REQUEST_TOO_LARGE - Request entity too large
                                • +
                                • HTTP_URI_TOO_LONG - URI too long
                                • +
                                • HTTP_UNSUPPORTED_MEDIATYPE - The requested media type + is unsupported
                                • +
                                • HTTP_SERVER_ERROR - Internal server error
                                • +
                                • HTTP_NOT_IMPLEMENTED - Feature not implemented
                                • +
                                • HTTP_BAD_GATEWAY - Bad gateway
                                • +
                                • HTTP_SERVICE_UNAVAILABLE - Service is unavailable
                                • +
                                • HTTP_GATEWAY_TIMEOUT - Gateway connection timed out
                                • +
                                • HTTP_NOT_SUPPORTED - HTTP version not supported

                                Fields

                                -

                                The following fields are indices for each of the standard HTTP -fields in HTTP 1/1:

                                -
                                  -
                                • HTTP_FIELD_ACCEPT_LANGUAGE - Accept-Language
                                • -
                                • HTTP_FIELD_ACCEPT_RANGES - Accept-Ranges
                                • -
                                • HTTP_FIELD_AUTHORIZATION - Authorization
                                • -
                                • HTTP_FIELD_CONNECTION - Connection
                                • -
                                • HTTP_FIELD_CONTENT_ENCODING - Content-Encoding
                                • -
                                • HTTP_FIELD_CONTENT_LANGUAGE - Content-Language
                                • -
                                • HTTP_FIELD_CONTENT_LENGTH - Content-Length
                                • -
                                • HTTP_FIELD_CONTENT_LOCATION - Content-Location
                                • -
                                • HTTP_FIELD_CONTENT_MD5 - Content-MD5
                                • -
                                • HTTP_FIELD_CONTENT_RANGE - Content-Range
                                • -
                                • HTTP_FIELD_CONTENT_TYPE - Content-Type
                                • -
                                • HTTP_FIELD_CONTENT_VERSION - Content-Version
                                • -
                                • HTTP_FIELD_DATE - Date
                                • -
                                • HTTP_FIELD_HOST - Host
                                • -
                                • HTTP_FIELD_IF_MODIFIED_SINCE - If-Modified-Since
                                • -
                                • HTTP_FIELD_IF_UNMODIFIED_SINCE - If-Unmodified-Since
                                • -
                                • HTTP_FIELD_KEEP_ALIVE - Keep-Alive
                                • -
                                • HTTP_FIELD_LAST_MODIFIED - Last-Modified
                                • -
                                • HTTP_FIELD_LINK - Link
                                • -
                                • HTTP_FIELD_LOCATION - Location
                                • -
                                • HTTP_FIELD_RANGE - Range
                                • -
                                • HTTP_FIELD_REFERER - Referer
                                • -
                                • HTTP_FIELD_RETRY_AFTER - Retry-After
                                • -
                                • HTTP_FIELD_TRANSFER_ENCODING - Transfer-Encoding
                                • -
                                • HTTP_FIELD_UPGRADE - Upgrade
                                • -
                                • HTTP_FIELD_USER_AGENT - User-Agent
                                • -
                                • HTTP_FIELD_WWW_AUTHENTICATE - WWW-Authenticate
                                • +

                                  The following fields are indices for each of the standard HTTP fields + in HTTP 1/1:

                                  +
                                    +
                                  • HTTP_FIELD_ACCEPT_LANGUAGE - Accept-Language
                                  • +
                                  • HTTP_FIELD_ACCEPT_RANGES - Accept-Ranges
                                  • +
                                  • HTTP_FIELD_AUTHORIZATION - Authorization
                                  • +
                                  • HTTP_FIELD_CONNECTION - Connection
                                  • +
                                  • HTTP_FIELD_CONTENT_ENCODING - Content-Encoding
                                  • +
                                  • HTTP_FIELD_CONTENT_LANGUAGE - Content-Language
                                  • +
                                  • HTTP_FIELD_CONTENT_LENGTH - Content-Length
                                  • +
                                  • HTTP_FIELD_CONTENT_LOCATION - Content-Location
                                  • +
                                  • HTTP_FIELD_CONTENT_MD5 - Content-MD5
                                  • +
                                  • HTTP_FIELD_CONTENT_RANGE - Content-Range
                                  • +
                                  • HTTP_FIELD_CONTENT_TYPE - Content-Type
                                  • +
                                  • HTTP_FIELD_CONTENT_VERSION - Content-Version
                                  • +
                                  • HTTP_FIELD_DATE - Date
                                  • +
                                  • HTTP_FIELD_HOST - Host
                                  • +
                                  • HTTP_FIELD_IF_MODIFIED_SINCE - If-Modified-Since
                                  • +
                                  • HTTP_FIELD_IF_UNMODIFIED_SINCE - If-Unmodified-Since
                                  • +
                                  • HTTP_FIELD_KEEP_ALIVE - Keep-Alive
                                  • +
                                  • HTTP_FIELD_LAST_MODIFIED - Last-Modified
                                  • +
                                  • HTTP_FIELD_LINK - Link
                                  • +
                                  • HTTP_FIELD_LOCATION - Location
                                  • +
                                  • HTTP_FIELD_RANGE - Range
                                  • +
                                  • HTTP_FIELD_REFERER - Referer
                                  • +
                                  • HTTP_FIELD_RETRY_AFTER - Retry-After
                                  • +
                                  • HTTP_FIELD_TRANSFER_ENCODING - Transfer-Encoding
                                  • +
                                  • HTTP_FIELD_UPGRADE - Upgrade
                                  • +
                                  • HTTP_FIELD_USER_AGENT - User-Agent
                                  • +
                                  • HTTP_FIELD_WWW_AUTHENTICATE - WWW-Authenticate

                                  IPP Constants

                                  Limits

                                  -

                                  The following constants define array limits for IPP data:

                                  +

                                  The following constants define array limits for IPP data:

                                    -
                                  • IPP_MAX_NAME - Maximum length of an attribute name
                                  • -
                                  • IPP_MAX_VALUES - Maximum number of set-of values that -can be read in a request.
                                  • +
                                  • IPP_MAX_NAME - Maximum length of an attribute name
                                  • +
                                  • IPP_MAX_VALUES - Maximum number of set-of values that + can be read in a request.

                                  Tags

                                    -
                                  • IPP_TAG_ZERO - Wildcard tag value for searches; also - used to separate groups of attributes
                                  • -
                                  • IPP_TAG_OPERATION - Tag for values of type operation
                                  • -
                                  • IPP_TAG_JOB - Tag for values of type job
                                  • -
                                  • IPP_TAG_END - Tag for values of type end
                                  • -
                                  • IPP_TAG_PRINTER - Tag for values of type printer
                                  • -
                                  • IPP_TAG_UNSUPPORTED_GROUP - Tag for values of type -unsupported_group
                                  • -
                                  • IPP_TAG_UNSUPPORTED_VALUE - Tag for values of type -unsupported_value
                                  • -
                                  • IPP_TAG_DEFAULT - Tag for values of type default
                                  • -
                                  • IPP_TAG_UNKNOWN - Tag for values of type unknown
                                  • -
                                  • IPP_TAG_NOVALUE - Tag for values of type novalue
                                  • -
                                  • IPP_TAG_NOTSETTABLE - Tag for values of type -notsettable
                                  • -
                                  • IPP_TAG_DELETEATTR - Tag for values of type deleteattr
                                  • -
                                  • IPP_TAG_ANYVALUE - Tag for values of type anyvalue
                                  • -
                                  • IPP_TAG_INTEGER - Tag for values of type integer
                                  • -
                                  • IPP_TAG_BOOLEAN - Tag for values of type boolean
                                  • -
                                  • IPP_TAG_ENUM - Tag for values of type enum
                                  • -
                                  • IPP_TAG_STRING - Tag for values of type string
                                  • -
                                  • IPP_TAG_DATE - Tag for values of type date
                                  • -
                                  • IPP_TAG_RESOLUTION - Tag for values of type resolution
                                  • -
                                  • IPP_TAG_RANGE - Tag for values of type range
                                  • -
                                  • IPP_TAG_COLLECTION - Tag for values of type collection
                                  • -
                                  • IPP_TAG_TEXTLANG - Tag for values of type textlang
                                  • -
                                  • IPP_TAG_NAMELANG - Tag for values of type namelang
                                  • -
                                  • IPP_TAG_TEXT - Tag for values of type text
                                  • -
                                  • IPP_TAG_NAME - Tag for values of type name
                                  • -
                                  • IPP_TAG_KEYWORD - Tag for values of type keyword
                                  • -
                                  • IPP_TAG_URI - Tag for values of type uri
                                  • -
                                  • IPP_TAG_URISCHEME - Tag for values of type urischeme
                                  • -
                                  • IPP_TAG_CHARSET - Tag for values of type charset
                                  • -
                                  • IPP_TAG_LANGUAGE - Tag for values of type language
                                  • -
                                  • IPP_TAG_MIMETYPE - Tag for values of type mimetype
                                  • +
                                  • IPP_TAG_ZERO - Wildcard tag value for searches; also + used to separate groups of attributes
                                  • +
                                  • IPP_TAG_OPERATION - Tag for values of type operation
                                  • +
                                  • IPP_TAG_JOB - Tag for values of type job
                                  • +
                                  • IPP_TAG_END - Tag for values of type end
                                  • +
                                  • IPP_TAG_PRINTER - Tag for values of type printer
                                  • +
                                  • IPP_TAG_UNSUPPORTED_GROUP - Tag for values of type + unsupported_group
                                  • +
                                  • IPP_TAG_UNSUPPORTED_VALUE - Tag for values of type + unsupported_value
                                  • +
                                  • IPP_TAG_DEFAULT - Tag for values of type default
                                  • +
                                  • IPP_TAG_UNKNOWN - Tag for values of type unknown
                                  • +
                                  • IPP_TAG_NOVALUE - Tag for values of type novalue
                                  • +
                                  • IPP_TAG_NOTSETTABLE - Tag for values of type + notsettable
                                  • +
                                  • IPP_TAG_DELETEATTR - Tag for values of type deleteattr
                                  • +
                                  • IPP_TAG_ANYVALUE - Tag for values of type anyvalue
                                  • +
                                  • IPP_TAG_INTEGER - Tag for values of type integer
                                  • +
                                  • IPP_TAG_BOOLEAN - Tag for values of type boolean
                                  • +
                                  • IPP_TAG_ENUM - Tag for values of type enum
                                  • +
                                  • IPP_TAG_STRING - Tag for values of type string
                                  • +
                                  • IPP_TAG_DATE - Tag for values of type date
                                  • +
                                  • IPP_TAG_RESOLUTION - Tag for values of type resolution
                                  • +
                                  • IPP_TAG_RANGE - Tag for values of type range
                                  • +
                                  • IPP_TAG_COLLECTION - Tag for values of type collection
                                  • +
                                  • IPP_TAG_TEXTLANG - Tag for values of type textlang
                                  • +
                                  • IPP_TAG_NAMELANG - Tag for values of type namelang
                                  • +
                                  • IPP_TAG_TEXT - Tag for values of type text
                                  • +
                                  • IPP_TAG_NAME - Tag for values of type name
                                  • +
                                  • IPP_TAG_KEYWORD - Tag for values of type keyword
                                  • +
                                  • IPP_TAG_URI - Tag for values of type uri
                                  • +
                                  • IPP_TAG_URISCHEME - Tag for values of type urischeme
                                  • +
                                  • IPP_TAG_CHARSET - Tag for values of type charset
                                  • +
                                  • IPP_TAG_LANGUAGE - Tag for values of type language
                                  • +
                                  • IPP_TAG_MIMETYPE - Tag for values of type mimetype

                                  Resolution Units

                                  The IPP_RES_PER_INCH and IPP_RES_PER_CM - constants specify dots per inch and dots per centimeter, respectively.

                                  + constants specify dots per inch and dots per centimeter, respectively.

                                  Finishings

                                  -

                                  The finishing values specify special finishing operations to be -performed on the job.

                                  +

                                  The finishing values specify special finishing operations to be + performed on the job.

                                    -
                                  • IPP_FINISH_NONE - Do no finishing
                                  • -
                                  • IPP_FINISH_STAPLE - Staple the job
                                  • -
                                  • IPP_FINISH_PUNCH - Punch the job
                                  • -
                                  • IPP_FINISH_COVER - Cover the job
                                  • -
                                  • IPP_FINISH_BIND - Bind the job
                                  • +
                                  • IPP_FINISH_NONE - Do no finishing
                                  • +
                                  • IPP_FINISH_STAPLE - Staple the job
                                  • +
                                  • IPP_FINISH_PUNCH - Punch the job
                                  • +
                                  • IPP_FINISH_COVER - Cover the job
                                  • +
                                  • IPP_FINISH_BIND - Bind the job

                                  Orientations

                                  -

                                  The orientation values specify the orientation of the job.

                                  +

                                  The orientation values specify the orientation of the job.

                                    -
                                  • IPP_PORTRAIT - No rotation
                                  • -
                                  • IPP_LANDSCAPE - 90 degrees counter-clockwise
                                  • -
                                  • IPP_REVERSE_LANDSCAPE - 90 degrees clockwise
                                  • -
                                  • IPP_REVERSE_PORTRAIT - 180 degrees
                                  • +
                                  • IPP_PORTRAIT - No rotation
                                  • +
                                  • IPP_LANDSCAPE - 90 degrees counter-clockwise
                                  • +
                                  • IPP_REVERSE_LANDSCAPE - 90 degrees clockwise
                                  • +
                                  • IPP_REVERSE_PORTRAIT - 180 degrees

                                  Qualities

                                  -

                                  The quality values specify the desired quality of the print.

                                  +

                                  The quality values specify the desired quality of the print.

                                    -
                                  • IPP_QUALITY_DRAFT - Draft quality
                                  • -
                                  • IPP_QUALITY_NORMAL - Normal quality
                                  • -
                                  • IPP_QUALITY_HIGH - High quality
                                  • +
                                  • IPP_QUALITY_DRAFT - Draft quality
                                  • +
                                  • IPP_QUALITY_NORMAL - Normal quality
                                  • +
                                  • IPP_QUALITY_HIGH - High quality

                                  Job States

                                  -

                                  The job state values are used to represent the current job state.

                                  +

                                  The job state values are used to represent the current job state.

                                    -
                                  • IPP_JOB_PENDING - Job is pending
                                  • -
                                  • IPP_JOB_HELD - Job is held
                                  • -
                                  • IPP_JOB_PROCESSING - Job is processing
                                  • -
                                  • IPP_JOB_STOPPED - Job is stopped
                                  • -
                                  • IPP_JOB_CANCELLED - Job is cancelled
                                  • -
                                  • IPP_JOB_ABORTED - Job is aborted
                                  • -
                                  • IPP_JOB_COMPLETED - Job is completed
                                  • +
                                  • IPP_JOB_PENDING - Job is pending
                                  • +
                                  • IPP_JOB_HELD - Job is held
                                  • +
                                  • IPP_JOB_PROCESSING - Job is processing
                                  • +
                                  • IPP_JOB_STOPPED - Job is stopped
                                  • +
                                  • IPP_JOB_CANCELLED - Job is cancelled
                                  • +
                                  • IPP_JOB_ABORTED - Job is aborted
                                  • +
                                  • IPP_JOB_COMPLETED - Job is completed

                                  Printer States

                                  -

                                  The printer state values are used to represent the current printer -state.

                                  +

                                  The printer state values are used to represent the current printer + state.

                                    -
                                  • IPP_PRINTER_IDLE - Printer is idle
                                  • -
                                  • IPP_PRINTER_PROCESSING - Printer is processing
                                  • -
                                  • IPP_PRINTER_STOPPED - Printer is stopped
                                  • +
                                  • IPP_PRINTER_IDLE - Printer is idle
                                  • +
                                  • IPP_PRINTER_PROCESSING - Printer is processing
                                  • +
                                  • IPP_PRINTER_STOPPED - Printer is stopped

                                  Operations

                                  -

                                  The operation values represent the available IPP operations.

                                  -
                                    -
                                  • IPP_PRINT_JOB - Print a file
                                  • -
                                  • IPP_PRINT_URI - Print a URI
                                  • -
                                  • IPP_VALIDATE_JOB - Validate job attributes
                                  • -
                                  • IPP_CREATE_JOB - Create a new job
                                  • -
                                  • IPP_SEND_DOCUMENT - Send a document to a job
                                  • -
                                  • IPP_SEND_URI - Send a URI to a job
                                  • -
                                  • IPP_CANCEL_JOB - Cancel a job
                                  • -
                                  • IPP_GET_JOB_ATTRIBUTES - Get job attributes
                                  • -
                                  • IPP_GET_JOBS - Get a list of all jobs
                                  • -
                                  • IPP_GET_PRINTER_ATTRIBUTES - Get printer attributes
                                  • -
                                  • IPP_HOLD_JOB - Hold a pending job
                                  • -
                                  • IPP_RELEASE_JOB - Release a held job
                                  • -
                                  • IPP_RESTART_JOB - Restart a completed job
                                  • -
                                  • IPP_PAUSE_PRINTER - Pause a printer
                                  • -
                                  • IPP_RESUME_PRINTER - Restart a paused printer
                                  • -
                                  • IPP_PURGE_JOBS - Purge jobs from the queue
                                  • -
                                  • IPP_SET_PRINTER_ATTRIBUTES - Set printer attributes
                                  • -
                                  • IPP_SET_JOB_ATTRIBUTES - Set job attributes
                                  • -
                                  • IPP_GET_PRINTER_SUPPORTED_VALUES - Get printer -supported values
                                  • -
                                  • CUPS_GET_DEFAULT - Get the default destination
                                  • -
                                  • CUPS_GET_PRINTERS - Get a list of all printers
                                  • -
                                  • CUPS_ADD_PRINTER - Add or modify a printer
                                  • -
                                  • CUPS_DELETE_PRINTER - Delete a printer
                                  • -
                                  • CUPS_GET_CLASSES - Get a list of all classes
                                  • -
                                  • CUPS_ADD_CLASS - Add or modify a class
                                  • -
                                  • CUPS_DELETE_CLASS - Delete a class
                                  • -
                                  • CUPS_ACCEPT_JOBS - Accept jobs on a printer or class
                                  • -
                                  • CUPS_REJECT_JOBS - Reject jobs on a printer or class
                                  • -
                                  • CUPS_SET_DEFAULT - Set the default destination
                                  • -
                                  • CUPS_GET_DEVICES - Get a list of all devices
                                  • -
                                  • CUPS_GET_PPDS - Get a list of all PPDs
                                  • -
                                  • CUPS_MOVE_JOB - Move a job to a new destination
                                  • +

                                    The operation values represent the available IPP operations.

                                    +
                                      +
                                    • IPP_PRINT_JOB - Print a file
                                    • +
                                    • IPP_PRINT_URI - Print a URI
                                    • +
                                    • IPP_VALIDATE_JOB - Validate job attributes
                                    • +
                                    • IPP_CREATE_JOB - Create a new job
                                    • +
                                    • IPP_SEND_DOCUMENT - Send a document to a job
                                    • +
                                    • IPP_SEND_URI - Send a URI to a job
                                    • +
                                    • IPP_CANCEL_JOB - Cancel a job
                                    • +
                                    • IPP_GET_JOB_ATTRIBUTES - Get job attributes
                                    • +
                                    • IPP_GET_JOBS - Get a list of all jobs
                                    • +
                                    • IPP_GET_PRINTER_ATTRIBUTES - Get printer attributes
                                    • +
                                    • IPP_HOLD_JOB - Hold a pending job
                                    • +
                                    • IPP_RELEASE_JOB - Release a held job
                                    • +
                                    • IPP_RESTART_JOB - Restart a completed job
                                    • +
                                    • IPP_PAUSE_PRINTER - Pause a printer
                                    • +
                                    • IPP_RESUME_PRINTER - Restart a paused printer
                                    • +
                                    • IPP_PURGE_JOBS - Purge jobs from the queue
                                    • +
                                    • IPP_SET_PRINTER_ATTRIBUTES - Set printer attributes
                                    • +
                                    • IPP_SET_JOB_ATTRIBUTES - Set job attributes
                                    • +
                                    • IPP_GET_PRINTER_SUPPORTED_VALUES - Get printer + supported values
                                    • +
                                    • CUPS_GET_DEFAULT - Get the default destination
                                    • +
                                    • CUPS_GET_PRINTERS - Get a list of all printers
                                    • +
                                    • CUPS_ADD_PRINTER - Add or modify a printer
                                    • +
                                    • CUPS_DELETE_PRINTER - Delete a printer
                                    • +
                                    • CUPS_GET_CLASSES - Get a list of all classes
                                    • +
                                    • CUPS_ADD_CLASS - Add or modify a class
                                    • +
                                    • CUPS_DELETE_CLASS - Delete a class
                                    • +
                                    • CUPS_ACCEPT_JOBS - Accept jobs on a printer or class
                                    • +
                                    • CUPS_REJECT_JOBS - Reject jobs on a printer or class
                                    • +
                                    • CUPS_SET_DEFAULT - Set the default destination
                                    • +
                                    • CUPS_GET_DEVICES - Get a list of all devices
                                    • +
                                    • CUPS_GET_PPDS - Get a list of all PPDs
                                    • +
                                    • CUPS_MOVE_JOB - Move a job to a new destination

                                    Status Codes

                                    -

                                    Status codes are returned by all IPP requests.

                                    -
                                      -
                                    • IPP_OK - Request completed with no errors
                                    • -
                                    • IPP_OK_SUBST - Request completed but some attribute - values were substituted
                                    • -
                                    • IPP_OK_CONFLICT - Request completed but some -attributes conflicted
                                    • -
                                    • IPP_BAD_REQUEST - The request was bad
                                    • -
                                    • IPP_FORBIDDEN - You don't have access to the resource
                                    • -
                                    • IPP_NOT_AUTHENTICATED - You are not authenticated for - the resource
                                    • -
                                    • IPP_NOT_AUTHORIZED - You not authorized to access the -resource
                                    • -
                                    • IPP_NOT_POSSIBLE - The requested operation cannot be - completed
                                    • -
                                    • IPP_TIMEOUT - A timeout occurred
                                    • -
                                    • IPP_NOT_FOUND - The resource was not found
                                    • -
                                    • IPP_GONE - The resource has gone away
                                    • -
                                    • IPP_REQUEST_ENTITY - The request was too large
                                    • -
                                    • IPP_REQUEST_VALUE - The request contained a value - that was unknown to the server
                                    • -
                                    • IPP_DOCUMENT_FORMAT - The document format is not - supported by the server
                                    • -
                                    • IPP_ATTRIBUTES - Required attributes are missing
                                    • -
                                    • IPP_URI_SCHEME - The URI scheme is not supported
                                    • -
                                    • IPP_CHARSET - The charset is not supported
                                    • -
                                    • IPP_CONFLICT - One or more attributes conflict
                                    • -
                                    • IPP_COMPRESSION_NOT_SUPPORTED - The specified - compression is not supported
                                    • -
                                    • IPP_COMPRESSION_ERROR - The compressed data contained -an error
                                    • -
                                    • IPP_DOCUMENT_FORMAT_ERROR - The document data - contained an error in it
                                    • -
                                    • IPP_DOCUMENT_ACCESS_ERROR - The remote document could -not be accessed
                                    • -
                                    • IPP_INTERNAL_ERROR - The server encountered an - internal error
                                    • -
                                    • IPP_OPERATION_NOT_SUPPORTED - The requested operation - is not supported
                                    • -
                                    • IPP_SERVICE_UNAVAILABLE - The requested service is -unavailable
                                    • -
                                    • IPP_VERSION_NOT_SUPPORTED - The IPP request version -is not supported
                                    • -
                                    • IPP_DEVICE_ERROR - The output device encountered an -error
                                    • -
                                    • IPP_TEMPORARY_ERROR - A temporary error occurred
                                    • -
                                    • IPP_NOT_ACCEPTING - The destination is not accepting - jobs
                                    • -
                                    • IPP_PRINTER_BUSY - The destination is busy
                                    • -
                                    • IPP_ERROR_JOB_CANCELLED - The requested job has been - cancelled
                                    • -
                                    • IPP_MULTIPLE_JOBS_NOT_SUPPORTED - The server does not -support multiple jobs
                                    • +

                                      Status codes are returned by all IPP requests.

                                      +
                                        +
                                      • IPP_OK - Request completed with no errors
                                      • +
                                      • IPP_OK_SUBST - Request completed but some attribute + values were substituted
                                      • +
                                      • IPP_OK_CONFLICT - Request completed but some attributes + conflicted
                                      • +
                                      • IPP_BAD_REQUEST - The request was bad
                                      • +
                                      • IPP_FORBIDDEN - You don't have access to the resource
                                      • +
                                      • IPP_NOT_AUTHENTICATED - You are not authenticated for + the resource
                                      • +
                                      • IPP_NOT_AUTHORIZED - You not authorized to access the + resource
                                      • +
                                      • IPP_NOT_POSSIBLE - The requested operation cannot be + completed
                                      • +
                                      • IPP_TIMEOUT - A timeout occurred
                                      • +
                                      • IPP_NOT_FOUND - The resource was not found
                                      • +
                                      • IPP_GONE - The resource has gone away
                                      • +
                                      • IPP_REQUEST_ENTITY - The request was too large
                                      • +
                                      • IPP_REQUEST_VALUE - The request contained a value that + was unknown to the server
                                      • +
                                      • IPP_DOCUMENT_FORMAT - The document format is not + supported by the server
                                      • +
                                      • IPP_ATTRIBUTES - Required attributes are missing
                                      • +
                                      • IPP_URI_SCHEME - The URI scheme is not supported
                                      • +
                                      • IPP_CHARSET - The charset is not supported
                                      • +
                                      • IPP_CONFLICT - One or more attributes conflict
                                      • +
                                      • IPP_COMPRESSION_NOT_SUPPORTED - The specified + compression is not supported
                                      • +
                                      • IPP_COMPRESSION_ERROR - The compressed data contained + an error
                                      • +
                                      • IPP_DOCUMENT_FORMAT_ERROR - The document data contained + an error in it
                                      • +
                                      • IPP_DOCUMENT_ACCESS_ERROR - The remote document could + not be accessed
                                      • +
                                      • IPP_INTERNAL_ERROR - The server encountered an internal + error
                                      • +
                                      • IPP_OPERATION_NOT_SUPPORTED - The requested operation + is not supported
                                      • +
                                      • IPP_SERVICE_UNAVAILABLE - The requested service is + unavailable
                                      • +
                                      • IPP_VERSION_NOT_SUPPORTED - The IPP request version is + not supported
                                      • +
                                      • IPP_DEVICE_ERROR - The output device encountered an + error
                                      • +
                                      • IPP_TEMPORARY_ERROR - A temporary error occurred
                                      • +
                                      • IPP_NOT_ACCEPTING - The destination is not accepting + jobs
                                      • +
                                      • IPP_PRINTER_BUSY - The destination is busy
                                      • +
                                      • IPP_ERROR_JOB_CANCELLED - The requested job has been + cancelled
                                      • +
                                      • IPP_MULTIPLE_JOBS_NOT_SUPPORTED - The server does not + support multiple jobs

                                      PPD Constants

                                      PPD Format Version

                                      -

                                      The PPD_VERSION constant defines a floating point -number representing the newest format version that is supported by -CUPS, currently 4.3.

                                      +

                                      The PPD_VERSION constant defines a floating point number + representing the newest format version that is supported by CUPS, + currently 4.3.

                                      PPD User-Interface Types

                                      -

                                      Each printer option has a type associated with it:

                                      +

                                      Each printer option has a type associated with it:

                                        -
                                      • PPD_UI_BOOLEAN - The user can turn this option on or -off
                                      • -
                                      • PPD_UI_PICKONE - The user can choose one option value - to use.
                                      • -
                                      • PPD_UI_PICKMANY - The user can choose zero or more - option values.
                                      • +
                                      • PPD_UI_BOOLEAN - The user can turn this option on or + off
                                      • +
                                      • PPD_UI_PICKONE - The user can choose one option value + to use.
                                      • +
                                      • PPD_UI_PICKMANY - The user can choose zero or more + option values.

                                      PPD Sections

                                      -

                                      Some options must be output before others, or in different sections -of the output document. The ppd_section_t enumeration -defines which section the option must be output in:

                                      -
                                        -
                                      • PPD_ORDER_ANY - The option can be output in any of - the document, page, or prolog sections of the document
                                      • -
                                      • PPD_ORDER_DOCUMENT - The option must be output in the -DocumentSetup section of the document
                                      • -
                                      • PPD_ORDER_EXIT - The option must be output before the -document
                                      • -
                                      • PPD_ORDER_JCL - The option must be output in the job -control section of the document
                                      • -
                                      • PPD_ORDER_PAGE - The option must be output in the - PageSetup section of the document
                                      • -
                                      • PPD_ORDER_PROLOG - The option must be output in the - Prolog section of the document
                                      • +

                                        Some options must be output before others, or in different sections + of the output document. The ppd_section_t enumeration + defines which section the option must be output in:

                                        +
                                          +
                                        • PPD_ORDER_ANY - The option can be output in any of the + document, page, or prolog sections of the document
                                        • +
                                        • PPD_ORDER_DOCUMENT - The option must be output in the + DocumentSetup section of the document
                                        • +
                                        • PPD_ORDER_EXIT - The option must be output before the + document
                                        • +
                                        • PPD_ORDER_JCL - The option must be output in the job + control section of the document
                                        • +
                                        • PPD_ORDER_PAGE - The option must be output in the + PageSetup section of the document
                                        • +
                                        • PPD_ORDER_PROLOG - The option must be output in the + Prolog section of the document

                                        PPD Colorspaces

                                        -

                                        Each printer has a default colorspace:

                                        +

                                        Each printer has a default colorspace:

                                          -
                                        • PPD_CS_CMYK - The printer uses CMYK colors by default
                                        • -
                                        • PPD_CS_CMY - The printer uses CMY colors by default
                                        • -
                                        • PPD_CS_GRAY - The printer uses grayscale by default
                                        • -
                                        • PPD_CS_RGB - The printer uses RGB colors by default
                                        • -
                                        • PPD_CS_RGBK - The printer uses RGBK colors by default
                                        • -
                                        • PPD_CS_N - The printer uses a DeviceN colorspace by -default
                                        • +
                                        • PPD_CS_CMYK - The printer uses CMYK colors by default
                                        • +
                                        • PPD_CS_CMY - The printer uses CMY colors by default
                                        • +
                                        • PPD_CS_GRAY - The printer uses grayscale by default
                                        • +
                                        • PPD_CS_RGB - The printer uses RGB colors by default
                                        • +
                                        • PPD_CS_RGBK - The printer uses RGBK colors by default
                                        • +
                                        • PPD_CS_N - The printer uses a DeviceN colorspace by + default

                                        Raster Constants

                                        Raster Sync Words

                                        The CUPS_RASTER_SYNC and CUPS_RASTER_REVSYNC - constants define the standard sync words at the beginning of each CUPS -raster file.

                                        + constants define the standard sync words at the beginning of each CUPS + raster file.

                                        Raster Stream Modes

                                        The CUPS_RASTER_READ and CUPS_RASTER_WRITE - constants are used with the -cupsRasterOpen() function to specify a stream for reading or -writing.

                                        + constants are used with the +cupsRasterOpen() function to specify a stream for reading or + writing.

                                        Raster Boolean Constants

                                        -

                                        The CUPS_FALSE and CUPS_TRUE constants -represent boolean values in the page header.

                                        +

                                        The CUPS_FALSE and CUPS_TRUE constants + represent boolean values in the page header.

                                        Raster Jog Values

                                        -

                                        The cups_jog_t enumeration defines constants for the -Jog page device dictionary variable:

                                        +

                                        The cups_jog_t enumeration defines constants for the Jog + page device dictionary variable:

                                          -
                                        • CUPS_JOG_NONE - Do no jogging
                                        • -
                                        • CUPS_JOG_FILE - Jog pages after each file
                                        • -
                                        • CUPS_JOG_JOB - Jog pages after each job
                                        • -
                                        • CUPS_JOG_SET - Jog pages after each set of jobs
                                        • +
                                        • CUPS_JOG_NONE - Do no jogging
                                        • +
                                        • CUPS_JOG_FILE - Jog pages after each file
                                        • +
                                        • CUPS_JOG_JOB - Jog pages after each job
                                        • +
                                        • CUPS_JOG_SET - Jog pages after each set of jobs

                                        Raster Orientation Values

                                        -

                                        The cups_orient_t enumeration defines constants for the -Orientation page device dictionary variable:

                                        +

                                        The cups_orient_t enumeration defines constants for the + Orientation page device dictionary variable:

                                          -
                                        • CUPS_ORIENT_0 - Portrait orientation
                                        • -
                                        • CUPS_ORIENT_90 - Landscape orientation
                                        • -
                                        • CUPS_ORIENT_180 - Reverse-portrait orientation
                                        • -
                                        • CUPS_ORIENT_270 - Reverse-landscape orientation
                                        • +
                                        • CUPS_ORIENT_0 - Portrait orientation
                                        • +
                                        • CUPS_ORIENT_90 - Landscape orientation
                                        • +
                                        • CUPS_ORIENT_180 - Reverse-portrait orientation
                                        • +
                                        • CUPS_ORIENT_270 - Reverse-landscape orientation

                                        Raster CutMedia Values

                                        -

                                        The cups_cut_t enumeration defines constants for the -CutMedia page device dictionary variable:

                                        +

                                        The cups_cut_t enumeration defines constants for the + CutMedia page device dictionary variable:

                                          -
                                        • CUPS_CUT_NONE - Do no jogging
                                        • -
                                        • CUPS_CUT_FILE - Cut pages after each file
                                        • -
                                        • CUPS_CUT_JOB - Cut pages after each job
                                        • -
                                        • CUPS_CUT_SET - Cut pages after each set of jobs
                                        • -
                                        • CUPS_CUT_PAGE - Cut each page
                                        • +
                                        • CUPS_CUT_NONE - Do no jogging
                                        • +
                                        • CUPS_CUT_FILE - Cut pages after each file
                                        • +
                                        • CUPS_CUT_JOB - Cut pages after each job
                                        • +
                                        • CUPS_CUT_SET - Cut pages after each set of jobs
                                        • +
                                        • CUPS_CUT_PAGE - Cut each page

                                        Raster AdvanceMedia Values

                                        -

                                        The cups_advance_t enumeration defines constants for -the AdvanceMedia page device dictionary variable:

                                        +

                                        The cups_advance_t enumeration defines constants for the + AdvanceMedia page device dictionary variable:

                                          -
                                        • CUPS_ADVANCE_NONE - Do no jogging
                                        • -
                                        • CUPS_ADVANCE_FILE - Advance media after each file
                                        • -
                                        • CUPS_ADVANCE_JOB - Advance media after each job
                                        • -
                                        • CUPS_ADVANCE_SET - Advance media after each set of -jobs
                                        • -
                                        • CUPS_ADVANCE_PAGE - Advance media for each page
                                        • +
                                        • CUPS_ADVANCE_NONE - Do no jogging
                                        • +
                                        • CUPS_ADVANCE_FILE - Advance media after each file
                                        • +
                                        • CUPS_ADVANCE_JOB - Advance media after each job
                                        • +
                                        • CUPS_ADVANCE_SET - Advance media after each set of jobs
                                        • +
                                        • CUPS_ADVANCE_PAGE - Advance media for each page

                                        Raster LeadingEdge Values

                                        -

                                        The cups_edge_t enumeration defines constants for the -LeadingEdge page device dictionary variable:

                                        -
                                          -
                                        • CUPS_EDGE_TOP - The top of the media is the leading - edge
                                        • -
                                        • CUPS_EDGE_RIGHT - The right of the media is the -leading edge
                                        • -
                                        • CUPS_EDGE_BOTTOM - The bottom of the media is the - leading edge
                                        • -
                                        • CUPS_EDGE_LEFT - The left of the media is the leading - edge
                                        • +

                                          The cups_edge_t enumeration defines constants for the + LeadingEdge page device dictionary variable:

                                          +
                                            +
                                          • CUPS_EDGE_TOP - The top of the media is the leading + edge
                                          • +
                                          • CUPS_EDGE_RIGHT - The right of the media is the leading + edge
                                          • +
                                          • CUPS_EDGE_BOTTOM - The bottom of the media is the + leading edge
                                          • +
                                          • CUPS_EDGE_LEFT - The left of the media is the leading + edge

                                          Raster Color Order Values

                                          -

                                          The cups_order_t enumeration defines the possible color -value orderings:

                                          +

                                          The cups_order_t enumeration defines the possible color + value orderings:

                                            -
                                          • CUPS_ORDER_CHUNKED - CMYK CMYK CMYK
                                          • -
                                          • CUPS_ORDER_BANDED - CCC MMM YYY KKK
                                          • -
                                          • CUPS_ORDER_PLANAR - CCC ... MMM ... YYY ... KKK ...
                                          • +
                                          • CUPS_ORDER_CHUNKED - CMYK CMYK CMYK
                                          • +
                                          • CUPS_ORDER_BANDED - CCC MMM YYY KKK
                                          • +
                                          • CUPS_ORDER_PLANAR - CCC ... MMM ... YYY ... KKK ...

                                          Raster Colorspace Values

                                          -

                                          The cups_cspace_t enumeration defines the possible -colorspaces:

                                          -
                                            -
                                          • CUPS_CSPACE_W - White (luminance)
                                          • -
                                          • CUPS_CSPACE_RGB - Red, green, blue
                                          • -
                                          • CUPS_CSPACE_RGBA - Red, green, blue, alpha
                                          • -
                                          • CUPS_CSPACE_K - Black
                                          • -
                                          • CUPS_CSPACE_CMY - Cyan, magenta, yellow
                                          • -
                                          • CUPS_CSPACE_YMC - Yellow, magenta, cyan
                                          • -
                                          • CUPS_CSPACE_CMYK - Cyan, magenta, yellow, black
                                          • -
                                          • CUPS_CSPACE_YMCK - Yellow, magenta, cyan, black
                                          • -
                                          • CUPS_CSPACE_KCMY - Black, cyan, magenta, yellow
                                          • -
                                          • CUPS_CSPACE_KCMYcm - Black, cyan, magenta, yellow, - light cyan, light magenta
                                          • -
                                          • CUPS_CSPACE_GMCK - Metallic yellow (gold), metallic -magenta, metallic cyan, black
                                          • -
                                          • CUPS_CSPACE_GMCS - Metallic yellow (gold), metallic -magenta, metallic cyan, metallic grey (silver)
                                          • -
                                          • CUPS_CSPACE_WHITE - White pigment (black as white -pigment)
                                          • -
                                          • CUPS_CSPACE_GOLD - Gold foil (black as gold foil)
                                          • -
                                          • CUPS_CSPACE_SILVER - Silver foil (black as silver -foil)
                                          • +

                                            The cups_cspace_t enumeration defines the possible + colorspaces:

                                            +
                                              +
                                            • CUPS_CSPACE_W - White (luminance)
                                            • +
                                            • CUPS_CSPACE_RGB - Red, green, blue
                                            • +
                                            • CUPS_CSPACE_RGBA - Red, green, blue, alpha
                                            • +
                                            • CUPS_CSPACE_K - Black
                                            • +
                                            • CUPS_CSPACE_CMY - Cyan, magenta, yellow
                                            • +
                                            • CUPS_CSPACE_YMC - Yellow, magenta, cyan
                                            • +
                                            • CUPS_CSPACE_CMYK - Cyan, magenta, yellow, black
                                            • +
                                            • CUPS_CSPACE_YMCK - Yellow, magenta, cyan, black
                                            • +
                                            • CUPS_CSPACE_KCMY - Black, cyan, magenta, yellow
                                            • +
                                            • CUPS_CSPACE_KCMYcm - Black, cyan, magenta, yellow, + light cyan, light magenta
                                            • +
                                            • CUPS_CSPACE_GMCK - Metallic yellow (gold), metallic + magenta, metallic cyan, black
                                            • +
                                            • CUPS_CSPACE_GMCS - Metallic yellow (gold), metallic + magenta, metallic cyan, metallic grey (silver)
                                            • +
                                            • CUPS_CSPACE_WHITE - White pigment (black as white + pigment)
                                            • +
                                            • CUPS_CSPACE_GOLD - Gold foil (black as gold foil)
                                            • +
                                            • CUPS_CSPACE_SILVER - Silver foil (black as silver foil)

                                            C - Structures

                                            -

                                            This appendix describes all of the structures that are defined by -the CUPS API.

                                            +

                                            This appendix describes all of the structures that are defined by the + CUPS API.

                                            Raster Structures

                                            Raster Page Header

                                            -

                                            The raster page header consists of the PostScript page device -dictionary for the page: +

                                            The raster page header consists of the PostScript page device + dictionary for the page:

                                            @@ -3730,85 +3711,84 @@ dictionary for the page: - - - + + + - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + +
                                            MemberTypeDescription
                                            MediaColorchar[64]The media color name
                                            MediaTypechar[64]The media type name
                                            OutputTypechar[64]The output type name
                                            AdvanceDistanceunsignedThe distance to -advance the media in points
                                            AdvanceMediacups_adv_tWhen to advance the -media
                                            Collatecups_bool_tWhether or not to produce -collated copies
                                            AdvanceDistanceunsignedThe distance to advance + the media in points
                                            AdvanceMediacups_adv_tWhen to advance the + media
                                            Collatecups_bool_tWhether or not to produce + collated copies
                                            CutMediacups_cut_tWhen to cut the media
                                            Duplexcups_bool_tWhether or not to print on -both sides of the paper
                                            HWResolutionunsigned[2]The resolution of the -page image in pixels per inch; the HWResolution[0] represents the -horizontal resolution and HWResolution[1] represents the vertical -resolution
                                            ImagingBoundingBoxunsigned[4]The bounding box -for the page in points; the elements represent the left, bottom, -right, and top coordinates of the imaged area (if 0 then the whole -page is imaged)
                                            InsertSheetcups_bool_tWhether or not to -insert a sheet before this page
                                            Duplexcups_bool_tWhether or not to print on + both sides of the paper
                                            HWResolutionunsigned[2]The resolution of the + page image in pixels per inch; the HWResolution[0] represents the + horizontal resolution and HWResolution[1] represents the vertical + resolution
                                            ImagingBoundingBoxunsigned[4]The bounding box + for the page in points; the elements represent the left, bottom, right, + and top coordinates of the imaged area (if 0 then the whole page is + imaged)
                                            InsertSheetcups_bool_tWhether or not to insert + a sheet before this page
                                            Jogcups_jog_tWhen to jog copies of the page
                                            LeadingEdgecups_edge_tThe leading edge of the -page
                                            Marginsunsigned[2]The lower-lefthand margin -of the page in points
                                            ManualFeedcups_bool_tWhether or not to -manually feed the page
                                            MediaPositionunsignedThe input slot number to -use
                                            MediaWeightunsignedThe weight of the output -media in grams/m2
                                            MirrorPrintcups_bool_tWhether or not to -mirror the print
                                            NegativePrintcups_bool_tWhether or not to -invert the print
                                            NumCopiesunsignedThe number of copies to -produce
                                            Orientationcups_orient_tThe orientation of -the page image
                                            OutputFaceUpcups_bool_tWhether or not to -output the page face up
                                            PageSizeunsigned[2]The width and height of -the page in points
                                            Separationscups_bool_tWhether or not to -output separations
                                            TraySwitchcups_bool_tWhether or not to -automatically switch trays for the requested media size/type
                                            Tumblecups_bool_tWhether or not to rotate the -back side of the page
                                            cupsWidthunsignedThe width of the page image -in pixels
                                            cupsHeightunsignedThe height of the page -image in pixels
                                            cupsMediaTypeunsignedThe device-specific -media type code
                                            cupsBitsPerColorunsignedThe number of bits -per color
                                            cupsBitsPerPixelunsignedThe number of bits -per pixel
                                            cupsBytesPerLineunsignedThe number of bytes -per line of image data
                                            cupsColorOrdercups_order_tThe order of color -values
                                            cupsColorSpacecups_cspace_tThe type of color -values
                                            cupsCompressionunsignedThe device-specific -compression code
                                            cupsRowCountunsignedThe device-specific row -count
                                            cupsRowFeedunsignedThe device-specific row -feed
                                            cupsRowStepunsignedThe device-specific row -step
                                            LeadingEdgecups_edge_tThe leading edge of the + page
                                            Marginsunsigned[2]The lower-lefthand margin of + the page in points
                                            ManualFeedcups_bool_tWhether or not to + manually feed the page
                                            MediaPositionunsignedThe input slot number to + use
                                            MediaWeightunsignedThe weight of the output + media in grams/m2
                                            MirrorPrintcups_bool_tWhether or not to mirror + the print
                                            NegativePrintcups_bool_tWhether or not to + invert the print
                                            NumCopiesunsignedThe number of copies to + produce
                                            Orientationcups_orient_tThe orientation of the + page image
                                            OutputFaceUpcups_bool_tWhether or not to + output the page face up
                                            PageSizeunsigned[2]The width and height of the + page in points
                                            Separationscups_bool_tWhether or not to output + separations
                                            TraySwitchcups_bool_tWhether or not to + automatically switch trays for the requested media size/type
                                            Tumblecups_bool_tWhether or not to rotate the + back side of the page
                                            cupsWidthunsignedThe width of the page image + in pixels
                                            cupsHeightunsignedThe height of the page image + in pixels
                                            cupsMediaTypeunsignedThe device-specific media + type code
                                            cupsBitsPerColorunsignedThe number of bits per + color
                                            cupsBitsPerPixelunsignedThe number of bits per + pixel
                                            cupsBytesPerLineunsignedThe number of bytes + per line of image data
                                            cupsColorOrdercups_order_tThe order of color + values
                                            cupsColorSpacecups_cspace_tThe type of color + values
                                            cupsCompressionunsignedThe device-specific + compression code
                                            cupsRowCountunsignedThe device-specific row + count
                                            cupsRowFeedunsignedThe device-specific row + feed
                                            cupsRowStepunsignedThe device-specific row + step

                                            -

                                            D - Functions

                                            -

                                            This appendix provides a reference for all of the CUPS API -functions. +

                                            D - Functions

                                            +

                                            This appendix provides a reference for all of the CUPS API functions.

                                            cupsAddOption()

                                            @@ -3832,9 +3812,9 @@ cupsAddOption(const char *name,

    Returns

    -

    The new number of options.

    +

    The new number of options.

    Description

    -

    cupsAddOption() adds an option to the specified array.

    +

    cupsAddOption() adds an option to the specified array.

    Example

     #include <cups.h>
    @@ -3854,8 +3834,8 @@ num_options = cupsAddOption("media", "letter", num_options,
     num_options = cupsAddOption("resolution", "300dpi", num_options, &options);
     

    See Also

    - cupsFreeOptions(), -cupsGetOption(), + cupsFreeOptions(), + cupsGetOption(), cupsParseOptions() @@ -3875,10 +3855,10 @@ cupsCancelJob(const char *dest,

    Returns

    -

    1 on success, 0 on failure. On failure the error can be found by -calling cupsLastError().

    +

    1 on success, 0 on failure. On failure the error can be found by + calling cupsLastError().

    Description

    -

    cupsCancelJob() cancels the specifies job.

    +

    cupsCancelJob() cancels the specifies job.

    Example

     #include <cups.h>
    @@ -3886,8 +3866,8 @@ calling cupsLastError(). 

    cupsCancelJob("LaserJet", 1);

    See Also

    -

    cupsLastError(), -cupsPrintFile() +

    cupsLastError(), + cupsPrintFile()

    cupsDoFileRequest()

    @@ -3911,14 +3891,14 @@ cupsDoFileRequest(http_t *http,

    Returns

    -

    IPP response data or NULL if the request fails. On -failure the error can be found by calling -cupsLastError().

    +

    IPP response data or NULL if the request fails. On + failure the error can be found by calling +cupsLastError().

    Description

    -

    cupsDoFileRequest() does a HTTP POST request and -provides the IPP request and optionally the contents of a file to the -IPP server. It also handles resubmitting the request and performing -password authentication as needed.

    +

    cupsDoFileRequest() does a HTTP POST request and + provides the IPP request and optionally the contents of a file to the + IPP server. It also handles resubmitting the request and performing + password authentication as needed.

    Example

     #include <cups.h>
    @@ -3957,11 +3937,11 @@ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-nam
     response = cupsDoFileRequest(http, request, "/resource", "filename.txt");
     

    See Also

    -

    cupsLangDefault(), -cupsLangEncoding(), -cupsUser(), httpConnect() -, ippAddString(), -ippNew() +

    cupsLangDefault(), + cupsLangEncoding(), +cupsUser(), httpConnect() +, ippAddString(), + ippNew()

    cupsDoRequest()

    @@ -3982,13 +3962,13 @@ cupsDoRequest(http_t *http,

    Returns

    -

    IPP response data or NULL if the request fails. On -failure the error can be found by calling -cupsLastError().

    +

    IPP response data or NULL if the request fails. On + failure the error can be found by calling +cupsLastError().

    Description

    -

    cupsDoRequest() does a HTTP POST request and provides -the IPP request to the IPP server. It also handles resubmitting the -request and performing password authentication as needed.

    +

    cupsDoRequest() does a HTTP POST request and provides + the IPP request to the IPP server. It also handles resubmitting the + request and performing password authentication as needed.

    Example

     #include <cups.h>
    @@ -4024,11 +4004,11 @@ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
     response = cupsDoRequest(http, request, "/resource");
     

    See Also

    -

    cupsLangDefault(), -cupsLangEncoding(), -cupsUser(), httpConnect() -, ippAddString(), -ippNew() +

    cupsLangDefault(), + cupsLangEncoding(), +cupsUser(), httpConnect() +, ippAddString(), + ippNew()

    cupsFreeOptions()

    @@ -4048,8 +4028,8 @@ cupsFreeOptions(int num_options,

    Description

    -

    cupsFreeOptions() frees all memory associated with the -option array specified.

    +

    cupsFreeOptions() frees all memory associated with the + option array specified.

    Example

     #include <cups/cups.h>
    @@ -4062,9 +4042,9 @@ cups_option_t *options;
     cupsFreeOptions(num_options, options);
     

    See Also

    -

    cupsAddOption(), -cupsGetOption(), cupsMarkOptions(), cupsParseOptions() +

    cupsAddOption(), + cupsGetOption(), cupsMarkOptions(), cupsParseOptions()

    cupsGetClasses()

    @@ -4081,11 +4061,11 @@ cupsGetClasses(char ***classes);

    Returns

    -

    The number of printer classes available.

    +

    The number of printer classes available.

    Description

    -

    cupsGetClasses() gets a list of the available printer -classes. The returned array should be freed using the free() - when it is no longer needed.

    +

    cupsGetClasses() gets a list of the available printer + classes. The returned array should be freed using the free() + when it is no longer needed.

    Example

     #include <cups/cups.h>
    @@ -4102,15 +4082,15 @@ num_classes = cupsGetClasses(
     
     if (num_classes > 0)
     {
    -  for (i = 0; i num_classes; i ++)
    +  for (i = 0; i <num_classes; i ++)
         free(classes[i]);
     
       free(classes);
     }
     

    See Also

    -

    cupsGetDefault(), -cupsGetPrinters() +

    cupsGetDefault(), + cupsGetPrinters()

    cupsGetDefault()

    @@ -4120,11 +4100,11 @@ const char * cupsGetDefault(void);

    Returns

    -

    A pointer to the default destination.

    +

    A pointer to the default destination.

    Description

    -

    cupsGetDefault() gets the default destination printer -or class. The default destination is stored in a static string and will -be overwritten (usually with the same value) after each call.

    +

    cupsGetDefault() gets the default destination printer or + class. The default destination is stored in a static string and will be + overwritten (usually with the same value) after each call.

    Example

     #include <cups/cups.h>
    @@ -4132,8 +4112,8 @@ be overwritten (usually with the same value) after each call. 

    printf("The default destination is %s\n", cupsGetDefault());

    See Also

    -

    cupsGetClasses(), -cupsGetPrinters() +

    cupsGetClasses(), + cupsGetPrinters()

    cupsGetOption()

    @@ -4154,12 +4134,12 @@ cupsGetOption(const char *name,

    Returns

    -

    A pointer to the option values or NULL if the option is -not defined.

    +

    A pointer to the option values or NULL if the option is + not defined.

    Description

    -

    cupsGetOption() returns the first occurrence of the -named option. If the option is not included in the options array then a -NULL pointer is returned.

    +

    cupsGetOption() returns the first occurrence of the + named option. If the option is not included in the options array then a + NULL pointer is returned.

     #include <cups/cups.h>
     
    @@ -4172,9 +4152,9 @@ const char    *media;
     media = cupsGetOption("media", num_options, options);
     

    See Also

    -

    cupsAddOption(), -cupsFreeOptions(), cupsMarkOptions() -, cupsParseOptions() +

    cupsAddOption(), + cupsFreeOptions(), cupsMarkOptions() +, cupsParseOptions()

    cupsGetPassword()

    @@ -4191,11 +4171,11 @@ cupsGetPassword(const char *prompt);

    Returns

    -

    A pointer to the password that was entered or NULL if -no password was entered.

    +

    A pointer to the password that was entered or NULL if no + password was entered.

    Description

    -

    cupsGetPassword() displays the prompt string and asks -the user for a password. The password text is not echoed to the user.

    +

    cupsGetPassword() displays the prompt string and asks + the user for a password. The password text is not echoed to the user.

    Example

     #include <cups/cups.h>
    @@ -4207,9 +4187,9 @@ char *password;
     password = cupsGetPassword("Please enter a password:");
     

    See Also

    -

    cupsServer(), -cupsSetPasswordCB(), cupsSetServer(), cupsSetUser(), cupsUser() +

    cupsServer(), + cupsSetPasswordCB(), cupsSetServer(), cupsSetUser(), cupsUser()

    @@ -4228,14 +4208,14 @@ cupsGetPPD(const char *printer);

    Returns

    The name of a temporary file containing the PPD file or NULL - if the printer cannot be located or does not have a PPD file.

    + if the printer cannot be located or does not have a PPD file.

    Description

    -

    cupsGetPPD() gets a copy of the PPD file for the named -printer. The printer name can be of the form "printer" or -"printer@hostname".

    -

    You should remove (unlink) the PPD file after you are done using it. -The filename is stored in a static buffer and will be overwritten with -each call to cupsGetPPD().

    +

    cupsGetPPD() gets a copy of the PPD file for the named + printer. The printer name can be of the form "printer" or + "printer@hostname".

    +

    You should remove (unlink) the PPD file after you are done using it. + The filename is stored in a static buffer and will be overwritten with + each call to cupsGetPPD().

    Example

     #include <cups/cups.h>
    @@ -4252,7 +4232,6 @@ unlink(ppd);
     
    -

    cupsGetPrinters()

    Usage

    @@ -4267,11 +4246,11 @@ cupsGetPrinters(char ***printers);
     
     
     

    Returns

    -

    The number of printer printers available.

    +

    The number of printer printers available.

    Description

    -

    cupsGetPrinters() gets a list of the available -printers. The returned array should be freed using the free() - when it is no longer needed.

    +

    cupsGetPrinters() gets a list of the available printers. + The returned array should be freed using the free() when + it is no longer needed.

    Example

     #include <cups/cups.h>
    @@ -4288,15 +4267,15 @@ num_printers = cupsGetPrinters(
     
     if (num_printers > 0)
     {
    -  for (i = 0; i num_printers; i ++)
    +  for (i = 0; i <num_printers; i ++)
         free(printers[i]);
     
       free(printers);
     }
     

    See Also

    -

    cupsGetClasses(), -cupsGetDefault() +

    cupsGetClasses(), + cupsGetDefault()

    cupsLangDefault()

    @@ -4306,14 +4285,14 @@ const char * cupsLangDefault(void);

    Returns

    -

    A pointer to the default language structure.

    +

    A pointer to the default language structure.

    Description

    -

    cupsLangDefault() returns a language structure for the -default language. The default language is defined by the LANG - environment variable. If the specified language cannot be located then -the POSIX (English) locale is used.

    -

    Call cupsLangFree() to free any memory associated with -the language structure when you are done.

    +

    cupsLangDefault() returns a language structure for the + default language. The default language is defined by the LANG + environment variable. If the specified language cannot be located then + the POSIX (English) locale is used.

    +

    Call cupsLangFree() to free any memory associated with + the language structure when you are done.

    Example

     #include <cups/language.h>
    @@ -4328,9 +4307,9 @@ language = cupsLangDefault();
     cupsLangFree(language);
     

    See Also

    -

    cupsLangEncoding(), -cupsLangFlush(), cupsLangFree(), -cupsLangGet(), cupsLangString() +

    cupsLangEncoding(), + cupsLangFlush(), cupsLangFree(), + cupsLangGet(), cupsLangString()

    cupsLangEncoding()

    @@ -4347,10 +4326,10 @@ cupsLangEncoding(cups_lang_t *language);

    Returns

    -

    A pointer to the encoding string.

    +

    A pointer to the encoding string.

    Description

    -

    cupsLangEncoding() returns the language encoding used -for the specified language, e.g. "iso-8859-1", "utf-8", etc.

    +

    cupsLangEncoding() returns the language encoding used + for the specified language, e.g. "iso-8859-1", "utf-8", etc.

    Example

     #include <cups/language.h>
    @@ -4366,9 +4345,9 @@ encoding = cupsLangEncoding(language);
     cupsLangFree(language);
     

    See Also

    -

    cupsLangDefault(), -cupsLangFlush(), cupsLangFree(), -cupsLangGet(), cupsLangString() +

    cupsLangDefault(), + cupsLangFlush(), cupsLangFree(), + cupsLangGet(), cupsLangString()

    cupsLangFlush()

    @@ -4378,8 +4357,8 @@ void cupsLangFlush(void);

    Description

    -

    cupsLangFlush() frees all language structures that have -been allocated.

    +

    cupsLangFlush() frees all language structures that have + been allocated.

    Example

     #include <cups/language.h>
    @@ -4389,9 +4368,9 @@ been allocated. 

    cupsLangFlush();

    See Also

    -

    cupsLangDefault(), -cupsLangEncoding(), cupsLangFree(), -cupsLangGet(), cupsLangString() +

    cupsLangDefault(), + cupsLangEncoding(), cupsLangFree(), + cupsLangGet(), cupsLangString()

    cupsLangFree()

    @@ -4408,7 +4387,7 @@ cupsLangFree(cups_lang_t *language);

    Description

    -

    cupsLangFree() frees the specified language structure.

    +

    cupsLangFree() frees the specified language structure.

    Example

     #include <cups/language.h>
    @@ -4419,9 +4398,9 @@ cups_lang_t *language;
     cupsLangFree(language);
     

    See Also

    -

    cupsLangDefault(), -cupsLangEncoding(), cupsLangFlush(), -cupsLangGet(), cupsLangString() +

    cupsLangDefault(), + cupsLangEncoding(), cupsLangFlush(), + cupsLangGet(), cupsLangString()

    cupsLangGet()

    @@ -4438,11 +4417,11 @@ cupsLangGet(const char *name);

    Returns

    -

    A pointer to a language structure.

    +

    A pointer to a language structure.

    Description

    -

    cupsLangGet() returns a language structure for the -specified locale. If the locale is not defined then the POSIX (English) -locale is substituted.

    +

    cupsLangGet() returns a language structure for the + specified locale. If the locale is not defined then the POSIX (English) + locale is substituted.

    Example

     #include <cups/language.h>
    @@ -4458,9 +4437,9 @@ language = cupsLangGet("fr");
     cupsLangFree(language);
     

    See Also

    -

    cupsLangDefault(), -cupsLangEncoding(), cupsLangFlush(), -cupsLangFree(), cupsLangString() +

    cupsLangDefault(), + cupsLangEncoding(), cupsLangFlush(), + cupsLangFree(), cupsLangString()

    cupsLangString()

    @@ -4479,11 +4458,11 @@ cupsLangString(cups_lang_t *language,

    Returns

    -

    A pointer to the message string or NULL if the message -is not defined.

    +

    A pointer to the message string or NULL if the message + is not defined.

    Description

    -

    cupsLangString() returns a pointer to the specified -message string in the specified language.

    +

    cupsLangString() returns a pointer to the specified + message string in the specified language.

    Example

     #include <cups/language.h>
    @@ -4501,9 +4480,9 @@ s = cupsLangString(language, CUPS_MSG_YES);
     cupsLangFree(language);
     

    See Also

    -

    cupsLangDefault(), -cupsLangEncoding(), cupsLangFlush(), -cupsLangFree(), cupsLangGet() +

    cupsLangDefault(), + cupsLangEncoding(), cupsLangFlush(), + cupsLangFree(), cupsLangGet()

    cupsLastError()

    @@ -4513,11 +4492,11 @@ ipp_status_t cupsLastError(void);

    Returns

    -

    An enumeration containing the last IPP error.

    +

    An enumeration containing the last IPP error.

    Description

    -

    cupsLastError() returns the last IPP error that -occurred. If no error occurred then it will return IPP_OK - or IPP_OK_CONFLICT.

    +

    cupsLastError() returns the last IPP error that + occurred. If no error occurred then it will return IPP_OK + or IPP_OK_CONFLICT.

    Example

     #include <cups/cups.h>
    @@ -4529,8 +4508,8 @@ ipp_status_t status;
     status = cupsLastError();
     

    See Also

    -

    cupsCancelJob(), -cupsPrintFile() +

    cupsCancelJob(), + cupsPrintFile()

    cupsMarkOptions()

    @@ -4552,11 +4531,10 @@ cupsMarkOptions(ppd_file_t *ppd,

    Returns

    -

    The number of conflicts found.

    +

    The number of conflicts found.

    Description

    -

    cupsMarkOptions() marks options in the PPD file. It -also handles mapping of IPP option names and values to PPD option -names.

    +

    cupsMarkOptions() marks options in the PPD file. It also + handles mapping of IPP option names and values to PPD option names.

    Example

     #include <cups/cups.h>
    @@ -4570,9 +4548,9 @@ ppd_file_t    *ppd;
     cupsMarkOptions(ppd, num_options, options);
     

    See Also

    -

    cupsAddOption(), -cupsFreeOptions(), cupsGetOption(), -cupsParseOptions() +

    cupsAddOption(), + cupsFreeOptions(), cupsGetOption(), + cupsParseOptions()

    cupsParseOptions()

    @@ -4594,11 +4572,11 @@ cupsParseOptions(const char *arg,

    Returns

    -

    The new number of options in the array.

    +

    The new number of options in the array.

    Description

    -

    cupsParseOptions() parses the specifies string for one -or more options of the form "name=value", "name", or "noname". It can -be called multiple times to combine the options from several strings.

    +

    cupsParseOptions() parses the specifies string for one + or more options of the form "name=value", "name", or "noname". It can + be called multiple times to combine the options from several strings.

    Example

     #include <cups/cups.h>
    @@ -4613,9 +4591,9 @@ options     = (cups_option_t *)0;
     num_options = cupsParseOptions(argv[5], num_options, &options);
     

    See Also

    -

    cupsAddOption(), -cupsFreeOptions(), cupsGetOption(), -cupsMarkOptions() +

    cupsAddOption(), + cupsFreeOptions(), cupsGetOption(), + cupsMarkOptions()

    cupsPrintFile()

    @@ -4641,11 +4619,11 @@ cupsPrintFile(const char *printer,

    Returns

    -

    The new job ID number or 0 on error.

    +

    The new job ID number or 0 on error.

    Description

    -

    cupsPrintFile() sends a file to the specified printer -or class for printing. If the job cannot be printed the error code can -be found by calling cupsLastError().

    +

    cupsPrintFile() sends a file to the specified printer or + class for printing. If the job cannot be printed the error code can be + found by calling cupsLastError().

    Example

     #include <cups/cups.h>
    @@ -4660,10 +4638,9 @@ jobid = cupsPrintFile("printer@hostname", "filename.ps", &qu
                           num_options, options);
     

    See Also

    -

    cupsCancelJob(), -cupsLastError(), cupsPrintFiles() +

    cupsCancelJob(), + cupsLastError(), cupsPrintFiles() -

    cupsPrintFiles()

    Usage

    @@ -4690,11 +4667,11 @@ cupsPrintFiles(const char *printer,

    Returns

    -

    The new job ID number or 0 on error.

    +

    The new job ID number or 0 on error.

    Description

    -

    cupsPrintFiles() sends multiple files to the specified -printer or class for printing. If the job cannot be printed the error -code can be found by calling cupsLastError().

    +

    cupsPrintFiles() sends multiple files to the specified + printer or class for printing. If the job cannot be printed the error + code can be found by calling cupsLastError().

    Example

     #include <cups/cups.h>
    @@ -4711,8 +4688,8 @@ jobid = cupsPrintFiles("printer@hostname", num_files, files,
                            "Job Title", num_options, options);
     

    See Also

    -

    cupsCancelJob(), -cupsLastError(), cupsPrintFile() +

    cupsCancelJob(), + cupsLastError(), cupsPrintFile()

    cupsRasterClose()

    @@ -4729,7 +4706,7 @@ cupsRasterClose(cups_raster_t *ras);

    Description

    -

    cupsRasterClose() closes the specified raster stream.

    +

    cupsRasterClose() closes the specified raster stream.

    Example

     #include <cups/raster.h>
    @@ -4741,11 +4718,11 @@ cups_raster_t *ras;
     cupsRasterClose(ras);
     

    See Also

    -

    cupsRasterOpen(), -cupsRasterReadHeader(), -cupsRasterReadPixels(), -cupsRasterWriteHeader(), -cupsRasterWritePixels() +

    cupsRasterOpen(), + cupsRasterReadHeader(), + cupsRasterReadPixels(), + cupsRasterWriteHeader(), + cupsRasterWritePixels()

    cupsRasterOpen()

    @@ -4761,15 +4738,15 @@ cupsRasterOpen(int fd, ArgumentDescription fdThe file descriptor to use. modeThe mode to use; CUPS_RASTER_READ or - CUPS_RASTER_WRITE. +CUPS_RASTER_WRITE.

    Returns

    -

    A pointer to a raster stream or NULL if there was an -error.

    +

    A pointer to a raster stream or NULL if there was an + error.

    Description

    -

    cupsRasterOpen() opens a raster stream for reading or -writing.

    +

    cupsRasterOpen() opens a raster stream for reading or + writing.

    Example

     #include <cups/raster.h>
    @@ -4781,11 +4758,11 @@ cups_raster_t *ras;
     ras = cupsRasterOpen(0, CUPS_RASTER_READ);
     

    See Also

    -

    cupsRasterClose(), -cupsRasterReadHeader(), -cupsRasterReadPixels(), -cupsRasterWriteHeader(), -cupsRasterWritePixels() +

    cupsRasterClose(), + cupsRasterReadHeader(), + cupsRasterReadPixels(), + cupsRasterWriteHeader(), + cupsRasterWritePixels()

    cupsRasterReadHeader()

    @@ -4800,15 +4777,15 @@ cupsRasterReadHeader(cups_raster_t *ras, - +
    ArgumentDescription
    rasThe raster stream to read from.
    headerA pointer to a page header structure to read -into.
    headerA pointer to a page header structure to read + into.

    Returns

    -

    1 on success, 0 on EOF or error.

    +

    1 on success, 0 on EOF or error.

    Description

    -

    cupsRasterReadHeader() reads a page header from the -specified raster stream.

    +

    cupsRasterReadHeader() reads a page header from the + specified raster stream.

    Example

     #include <cups/raster.h>
    @@ -4832,11 +4809,11 @@ while (cupsRasterReadHeader(ras, &header))
     }
     

    See Also

    -

    cupsRasterClose(), -cupsRasterOpen(), -cupsRasterReadPixels(), -cupsRasterWriteHeader(), -cupsRasterWritePixels() +

    cupsRasterClose(), + cupsRasterOpen(), + cupsRasterReadPixels(), + cupsRasterWriteHeader(), + cupsRasterWritePixels()

    cupsRasterReadPixels()

    @@ -4857,10 +4834,10 @@ cupsRasterReadPixels(cups_raster_t *ras,

    Returns

    -

    The number of bytes read or 0 on EOF or error.

    +

    The number of bytes read or 0 on EOF or error.

    Description

    -

    cupsRasterReadPixels() reads pixel data from the -specified raster stream.

    +

    cupsRasterReadPixels() reads pixel data from the + specified raster stream.

    Example

     #include <cups/raster.h>
    @@ -4884,11 +4861,11 @@ while (cupsRasterReadHeader(ras, &header))
     }
     

    See Also

    -

    cupsRasterClose(), -cupsRasterOpen(), -cupsRasterReadHeader(), -cupsRasterWriteHeader(), -cupsRasterWritePixels() +

    cupsRasterClose(), + cupsRasterOpen(), + cupsRasterReadHeader(), + cupsRasterWriteHeader(), + cupsRasterWritePixels()

    cupsRasterWriteHeader()

    @@ -4907,10 +4884,10 @@ cupsRasterWriteHeader(cups_raster_t *ras,

    Returns

    -

    1 on success, 0 on error.

    +

    1 on success, 0 on error.

    Description

    -

    cupsRasterWriteHeader() writes the specified page -header to a raster stream.

    +

    cupsRasterWriteHeader() writes the specified page header + to a raster stream.

    Example

     #include <cups/raster.h>
    @@ -4931,11 +4908,11 @@ for (line = 0; line < header.cupsHeight; line ++)
     }
     

    See Also

    -

    cupsRasterClose(), -cupsRasterOpen(), -cupsRasterReadHeader(), -cupsRasterReadPixels(), -cupsRasterWritePixels() +

    cupsRasterClose(), + cupsRasterOpen(), + cupsRasterReadHeader(), + cupsRasterReadPixels(), + cupsRasterWritePixels()

    cupsRasterWritePixels()

    @@ -4956,10 +4933,10 @@ cupsRasterWritePixels(cups_raster_t *ras,

    Returns

    -

    The number of bytes written.

    +

    The number of bytes written.

    Description

    -

    cupsRasterWritePixels() writes the specified pixel data -to a raster stream.

    +

    cupsRasterWritePixels() writes the specified pixel data + to a raster stream.

    Example

     #include <cups/raster.h>
    @@ -4980,11 +4957,11 @@ for (line = 0; line < header.cupsHeight; line ++)
     }
     

    See Also

    -

    cupsRasterClose(), -cupsRasterOpen(), -cupsRasterReadHeader(), -cupsRasterReadPixels(), -cupsRasterWriteHeader() +

    cupsRasterClose(), + cupsRasterOpen(), + cupsRasterReadHeader(), + cupsRasterReadPixels(), + cupsRasterWriteHeader()

    cupsServer()

    @@ -4994,17 +4971,17 @@ const char * cupsServer(void);

    Returns

    -

    A pointer to the default server name.

    +

    A pointer to the default server name.

    Description

    -

    cupsServer() returns a pointer to the default server -name. The server name is stored in a static location and will be -overwritten with every call to cupsServer()

    -

    The default server is determined from the following locations:

    +

    cupsServer() returns a pointer to the default server + name. The server name is stored in a static location and will be + overwritten with every call to cupsServer()

    +

    The default server is determined from the following locations:

      -
    1. The CUPS_SERVER environment variable,
    2. -
    3. The ServerName directive in the client.conf - file,
    4. -
    5. The default host, "localhost".
    6. +
    7. The CUPS_SERVER environment variable,
    8. +
    9. The ServerName directive in the client.conf + file,
    10. +
    11. The default host, "localhost".

    Example

    @@ -5015,9 +4992,9 @@ const char *server;
     server = cupsServer();
     

    See Also

    -

    cupsGetPassword(), -cupsSetPasswordCB(), cupsSetServer(), cupsSetUser(), cupsUser() +

    cupsGetPassword(), + cupsSetPasswordCB(), cupsSetServer(), cupsSetUser(), cupsUser()

    @@ -5035,11 +5012,11 @@ cupsSetPasswordCB(const char *(*cb)(const char *prompt));

    Description

    -

    cupsSetPasswordCB() sets the callback function to use -when asking the user for a password. The callback function must accept -a single character string pointer (the prompt string) and return -NULL if the user did not enter a password string or a pointer to -the password string otherwise.

    +

    cupsSetPasswordCB() sets the callback function to use + when asking the user for a password. The callback function must accept + a single character string pointer (the prompt string) and return +NULL if the user did not enter a password string or a pointer to + the password string otherwise.

    Example

     #include <cups/cups.h>
    @@ -5060,9 +5037,9 @@ cupsSetPasswordCB(my_password_cb);
     password = cupsGetPassword("Please enter a password:");
     

    See Also

    -

    cupsServer(), -cupsSetServer(), cupsSetUser(), -cupsUser() +

    cupsServer(), + cupsSetServer(), cupsSetUser(), + cupsUser()

    cupsSetServer()

    @@ -5079,9 +5056,9 @@ cupsSetServer(const char *server);

    Description

    -

    cupsSetServer() sets the default server to use for the -CUPS API. If the server argument is NULL, the -default server is used.

    +

    cupsSetServer() sets the default server to use for the + CUPS API. If the server argument is NULL, the + default server is used.

    Example

     #include <cups/cups.h>
    @@ -5089,9 +5066,9 @@ default server is used. 

    cupsSetServer("foo.bar.com");

    See Also

    -

    cupsServer(), -cupsSetPasswordCB(), cupsSetUser(), -cupsUser() +

    cupsServer(), + cupsSetPasswordCB(), cupsSetUser(), + cupsUser()

    cupsSetUser()

    @@ -5108,9 +5085,9 @@ cupsSetUser(const char *user);

    Description

    -

    cupsSetUser() sets the default user name for -authentication. If the user argument is NULL - then the current login user is used.

    +

    cupsSetUser() sets the default user name for + authentication. If the user argument is NULL + then the current login user is used.

    Example

     #include <cups/cups.h>
    @@ -5120,9 +5097,9 @@ authentication. If the user argument is NULL
     cupsSetUser("root");
     

    See Also

    -

    cupsServer(), -cupsSetPasswordCB(), cupsSetServer(), cupsUser() +

    cupsServer(), + cupsSetPasswordCB(), cupsSetServer(), cupsUser()

    cupsTempFile()

    @@ -5136,17 +5113,17 @@ cupsTempFile(char *filename,
    - +
    ArgumentDescription
    filenameThe character string to hold the temporary -filename.
    filenameThe character string to hold the temporary + filename.
    lengthThe size of the filename string in bytes.

    Returns

    -

    A pointer to filename.

    +

    A pointer to filename.

    Description

    -

    cupsTempFile() generates a temporary filename for the -/var/tmp directory or the directory specified by the TMPDIR - environment variable.

    +

    cupsTempFile() generates a temporary filename for the + /var/tmp directory or the directory specified by the TMPDIR + environment variable.

    Example

     #include <cups/cups.h>
    @@ -5157,7 +5134,6 @@ cupsTempFile(filename, sizeof(filename));
     
    -

    cupsUser()

    Usage

    @@ -5165,11 +5141,11 @@ const char *
     cupsUser(void);
     

    Returns

    -

    A pointer to the current username or NULL if the user -ID is undefined.

    +

    A pointer to the current username or NULL if the user ID + is undefined.

    Description

    -

    cupsUser() returns the name associated with the current -user ID as reported by the getuid() system call.

    +

    cupsUser() returns the name associated with the current + user ID as reported by the getuid() system call.

    Example

     #include <cups/cups.h>
    @@ -5179,8 +5155,8 @@ const char *user;
     user = cupsUser();
     

    See Also

    -

    cupsGetPassword(), -cupsServer() +

    cupsGetPassword(), + cupsServer()

    httpBlocking()

    @@ -5193,14 +5169,14 @@ void httpBlocking(http_t *http, int blocking) - +
    ArgumentDescription
    httpThe HTTP connection
    blocking0 if the connection should be non-blocking, 1 -if it should be blocking
    blocking0 if the connection should be non-blocking, 1 + if it should be blocking

    Description

    -

    The httpBlocking() function sets the blocking mode for -the HTTP connection. By default HTTP connections will block (stop) the -client program until data is available or can be sent to the server.

    +

    The httpBlocking() function sets the blocking mode for + the HTTP connection. By default HTTP connections will block (stop) the + client program until data is available or can be sent to the server.

    Example

     #include <cups/http.h>
    @@ -5211,8 +5187,8 @@ http = httpConnect("server", port);
     httpBlocking(http, 0);
     

    See Also

    - httpCheck(), -httpConnect() + httpCheck(), + httpConnect()

    httpCheck()

    @@ -5228,10 +5204,10 @@ int httpCheck(http_t *http);

    Returns

    -

    0 if there is no data pending, 1 otherwise.

    +

    0 if there is no data pending, 1 otherwise.

    Description

    -

    The httpCheck() function checks to see if there is any -data pending on an HTTP connection.

    +

    The httpCheck() function checks to see if there is any + data pending on an HTTP connection.

    Example

     #include <cups/http.h>
    @@ -5244,9 +5220,9 @@ if (httpCheck(http))
     }
     

    See Also

    - httpBlocking(), -httpConnect(), httpGets() -, httpRead() + httpBlocking(), + httpConnect(), httpGets() +, httpRead()

    httpClearFields()

    @@ -5262,8 +5238,8 @@ void httpClearFields(http_t *http)

    Description

    -

    The httpClearFields() function clears all HTTP request -fields for the HTTP connection.

    +

    The httpClearFields() function clears all HTTP request + fields for the HTTP connection.

    Example

     #include <cups/http.h>
    @@ -5273,8 +5249,8 @@ http_t *http;
     httpClearFields(http);
     

    See Also

    - httpConnect(), -httpGetField(), + httpConnect(), + httpGetField(), httpSetField() @@ -5291,8 +5267,8 @@ void httpClose(http_t *http);

    Description

    -

    The httpClose() function closes an active HTTP -connection.

    +

    The httpClose() function closes an active HTTP + connection.

    Example

     #include <cups/http.h>
    @@ -5302,7 +5278,7 @@ http_t *http;
     httpClose(http);
     

    See Also

    - httpConnect() + httpConnect()

    httpConnect()

    @@ -5314,17 +5290,17 @@ http_t *httpConnect(const char *hostname, int port);
    - +
    ArgumentDescription
    hostnameThe name or IP address of the server to -connect to
    hostnameThe name or IP address of the server to connect + to
    portThe port number to use

    Returns

    -

    A pointer to a HTTP connection structure or NULL if the connection -could not be made.

    +

    A pointer to a HTTP connection structure or NULL if the connection + could not be made.

    Description

    -

    The httpConnect() function opens a HTTP connection to -the specified server and port.

    +

    The httpConnect() function opens a HTTP connection to + the specified server and port.

    Example

     #include <cups/http.h>
    @@ -5334,10 +5310,10 @@ http_t *http;
     http = httpConnect(cupsServer(), ippPort());
     

    See Also

    - httpClose(), -httpGet(), httpGets(), httpPost(), -httpRead(), httpWrite() + httpClose(), +httpGet(), httpGets(), + httpPost(), httpRead() +, httpWrite()

    httpDecode64()

    @@ -5354,10 +5330,10 @@ char *httpDecode64(char *out, const char *in);

    Returns

    -

    A pointer to the decoded string.

    +

    A pointer to the decoded string.

    Description

    -

    The httpDecode64() function decodes a base-64 encoded -string to the original string.

    +

    The httpDecode64() function decodes a base-64 encoded + string to the original string.

    Example

     #include <cups/http.h>
    @@ -5368,7 +5344,7 @@ char original_string[255];
     httpDecode64(original_string, encoded_string);
     

    See Also

    - httpEncode64() + httpEncode64()

    httpDelete()

    @@ -5385,10 +5361,10 @@ int httpDelete(http_t *http, const char *uri);

    Returns

    -

    0 on success, non-zero on failure.

    +

    0 on success, non-zero on failure.

    Description

    -

    The httpDelete() function sends a HTTP DELETE request -to the server.

    +

    The httpDelete() function sends a HTTP DELETE request to + the server.

    Example

     #include <cups/http.h>
    @@ -5398,8 +5374,8 @@ http_t *http;
     httpDelete(http, "/some/uri");
     

    See Also

    - httpConnect(), -httpSetField(), + httpConnect(), + httpSetField(), httpUpdate() @@ -5417,10 +5393,10 @@ char *httpEncode64(char *out, const char *in);

    Returns

    -

    A pointer to the encoded string.

    +

    A pointer to the encoded string.

    Description

    -

    The httpEncode64() function decodes a base-64 encoded -string to the original string.

    +

    The httpEncode64() function decodes a base-64 encoded + string to the original string.

    Example

     #include <cups/http.h>
    @@ -5431,7 +5407,7 @@ char original_string[255];
     httpEncode64(encoded_string, original_string);
     

    See Also

    - httpDecode64() + httpDecode64()

    httpError()

    @@ -5447,10 +5423,10 @@ int httpError(http_t *http);

    Returns

    -

    The last error that occurred or 0 if no error has occurred.

    +

    The last error that occurred or 0 if no error has occurred.

    Description

    -

    The httpError() function returns the last error that -occurred on the HTTP connection.

    +

    The httpError() function returns the last error that + occurred on the HTTP connection.

    Example

     #include <cups/http.h>
    @@ -5463,7 +5439,7 @@ if (httpError(http))
     }
     

    See Also

    - httpConnect() + httpConnect()

    httpFlush()

    @@ -5479,8 +5455,8 @@ void httpFlush(http_t *http);

    Description

    -

    The httpFlush() function flushes any remaining data -left from a GET or POST operation.

    +

    The httpFlush() function flushes any remaining data left + from a GET or POST operation.

    Example

     #include <cups/http.h>
    @@ -5490,7 +5466,7 @@ http_t *http;
     httpFlush(http);
     

    See Also

    - httpConnect(), + httpConnect(),

    httpGet()

    @@ -5507,10 +5483,10 @@ int httpGet(http_t *http, const char *uri);

    Returns

    -

    0 on success, non-zero on failure.

    +

    0 on success, non-zero on failure.

    Description

    -

    The httpGet() function sends a HTTP GET request to the -server.

    +

    The httpGet() function sends a HTTP GET request to the + server.

    Example

     #include <cups/http.h>
    @@ -5520,8 +5496,8 @@ http_t *http;
     httpGet(http, "/some/uri");
     

    See Also

    - httpConnect(), -httpSetField(), + httpConnect(), + httpSetField(), httpUpdate() @@ -5534,17 +5510,17 @@ char *httpGets(char *line, int length, http_t *http)
    - +
    ArgumentDescription
    lineThe string to fill with a line from the HTTP -connection
    lineThe string to fill with a line from the HTTP + connection
    lengthThe maximum length of the string
    httpThe HTTP connection

    Returns

    -

    A pointer to the string or NULL if no line could be retrieved.

    +

    A pointer to the string or NULL if no line could be retrieved.

    Description

    -

    The httpGets() function is used to read a request line -from the HTTP connection. It is not normally used by a client program.

    +

    The httpGets() function is used to read a request line + from the HTTP connection. It is not normally used by a client program.

    Example

     #include <cups/http.h>
    @@ -5558,8 +5534,8 @@ if (httpGets(line, sizeof(line), http))
     }
     

    See Also

    - httpConnect(), -httpUpdate() + httpConnect(), + httpUpdate()

    httpGetDateString()

    @@ -5575,11 +5551,11 @@ const char *httpGetDateString(time_t time)

    Returns

    -

    A pointer to a static string containing the HTTP date/time string -for the specified UNIX time value.

    +

    A pointer to a static string containing the HTTP date/time string for + the specified UNIX time value.

    Description

    -

    The httpGetDateString() function generates a date/time -string suitable for HTTP requests from a UNIX time value.

    +

    The httpGetDateString() function generates a date/time + string suitable for HTTP requests from a UNIX time value.

    Example

     #include <cups/http.h>
    @@ -5587,7 +5563,7 @@ string suitable for HTTP requests from a UNIX time value. 

    puts(httpGetDateString(time(NULL)));

    See Also

    - httpGetDateTime() + httpGetDateTime()

    httpGetDateTime()

    @@ -5603,10 +5579,10 @@ time_t httpGetDateTime(const char *date)

    Returns

    -

    A UNIX time value.

    +

    A UNIX time value.

    Description

    -

    The httpGetDateTime() function converts a HTTP -date/time string to a UNIX time value.

    +

    The httpGetDateTime() function converts a HTTP date/time + string to a UNIX time value.

    Example

     #include <cups/http.h>
    @@ -5614,7 +5590,7 @@ date/time string to a UNIX time value. 

    printf("%d\n", httpGetDateTime("Fri, 30 June 2000 12:34:56 GMT"));

    See Also

    - httpGetDateString() + httpGetDateString()

    httpGetField()

    @@ -5631,10 +5607,10 @@ const char *httpGetField(http_t *http, http_field_t field);

    Returns

    -

    A pointer to the field value string.

    +

    A pointer to the field value string.

    Description

    -

    The httpGetField() function returns the current value -for the specified HTTP field.

    +

    The httpGetField() function returns the current value + for the specified HTTP field.

    Example

     #include <cups/http.h>
    @@ -5647,8 +5623,8 @@ while (httpUpdate(http) == HTTP_CONTINUE);
     puts(httpGetField(http, HTTP_FIELD_CONTENT_TYPE));
     

    See Also

    - httpConnect(), -httpSetField() + httpConnect(), + httpSetField()

    httpHead()

    @@ -5665,10 +5641,10 @@ int httpHead(http_t *http, const char *uri);

    Returns

    -

    0 on success, non-zero on failure.

    +

    0 on success, non-zero on failure.

    Description

    -

    The httpHead() function sends a HTTP HEAD request to -the server.

    +

    The httpHead() function sends a HTTP HEAD request to the + server.

    Example

     #include <cups/http.h>
    @@ -5678,8 +5654,8 @@ http_t *http;
     httpHead(http, "/some/uri");
     

    See Also

    - httpConnect(), -httpSetField(), + httpConnect(), + httpSetField(), httpUpdate() @@ -5689,9 +5665,9 @@ httpUpdate() void httpInitialize(void);

    Description

    -

    The httpInitialize() function initializes the -networking code as needed by the underlying platform. It is called -automatically by the httpConnect() function.

    +

    The httpInitialize() function initializes the networking + code as needed by the underlying platform. It is called automatically + by the httpConnect() function.

    Example

     #include <cups/http.h>
    @@ -5699,7 +5675,7 @@ automatically by the httpConnect() function. 

    httpInitialize();

    See Also

    - httpConnect() + httpConnect()

    httpOptions()

    @@ -5716,10 +5692,10 @@ int httpOptions(http_t *http, const char *uri);

    Returns

    -

    0 on success, non-zero on failure.

    +

    0 on success, non-zero on failure.

    Description

    -

    The httpOptions() function sends a HTTP OPTIONS request -to the server.

    +

    The httpOptions() function sends a HTTP OPTIONS request + to the server.

    Example

     #include <cups/http.h>
    @@ -5729,8 +5705,8 @@ http_t *http;
     httpOptions(http, "/some/uri");
     

    See Also

    - httpConnect(), -httpSetField(), + httpConnect(), + httpSetField(), httpUpdate() @@ -5748,10 +5724,10 @@ int httpPost(http_t *http, const char *uri);

    Returns

    -

    0 on success, non-zero on failure.

    +

    0 on success, non-zero on failure.

    Description

    -

    The httpPost() function sends a HTTP POST request to -the server.

    +

    The httpPost() function sends a HTTP POST request to the + server.

    Example

     #include <cups/http.h>
    @@ -5761,8 +5737,8 @@ http_t *http;
     httpPost(http, "/some/uri");
     

    See Also

    - httpConnect(), -httpSetField(), + httpConnect(), + httpSetField(), httpUpdate() @@ -5780,11 +5756,11 @@ int httpPrintf(http_t *http, const char *format, ...);

    Returns

    -

    The number of bytes written.

    +

    The number of bytes written.

    Description

    -

    The httpPrintf() function sends a formatted string to -the HTTP connection. It is normally only used by the CUPS API and -scheduler.

    +

    The httpPrintf() function sends a formatted string to + the HTTP connection. It is normally only used by the CUPS API and + scheduler.

    Example

     #include <cups/http.h>
    @@ -5794,7 +5770,7 @@ http_t *http;
     httpPrintf(http, "GET / HTTP/1.1 \r\n");
     

    See Also

    - httpConnect() + httpConnect()

    httpPut()

    @@ -5811,10 +5787,10 @@ int httpPut(http_t *http, const char *uri);

    Returns

    -

    0 on success, non-zero on failure.

    +

    0 on success, non-zero on failure.

    Description

    -

    The httpPut() function sends a HTTP PUT request to the -server.

    +

    The httpPut() function sends a HTTP PUT request to the + server.

    Example

     #include <cups/http.h>
    @@ -5824,8 +5800,8 @@ http_t *http;
     httpDelete(http, "/some/uri");
     

    See Also

    - httpConnect(), -httpSetField(), + httpConnect(), + httpSetField(), httpUpdate() @@ -5844,10 +5820,10 @@ int httpRead(http_t *http, char *buffer, int length);

    Returns

    -

    The number of bytes read or -1 on error.

    +

    The number of bytes read or -1 on error.

    Description

    -

    The httpRead() function reads data from the HTTP -connection, possibly the result of a GET or POST request.

    +

    The httpRead() function reads data from the HTTP + connection, possibly the result of a GET or POST request.

    Example

     #include <cups/http.h>
    @@ -5865,8 +5841,8 @@ while ((bytes = httpRead(http, buffer, sizeof(buffer) - 1)) > 0)
     }
     

    See Also

    - httpConnect(), -httpWrite() + httpConnect(), + httpWrite()

    httpReconnect()

    @@ -5882,11 +5858,11 @@ int httpReconnect(http_t *http);

    Returns

    -

    0 on success, non-zero on failure.

    +

    0 on success, non-zero on failure.

    Description

    -

    The httpReconnect() function reconnects to the HTTP -server. This is usually done automatically if the HTTP functions detect -that the server connection has terminated.

    +

    The httpReconnect() function reconnects to the HTTP + server. This is usually done automatically if the HTTP functions detect + that the server connection has terminated.

    Example

     #include <cups/http.h>
    @@ -5896,7 +5872,7 @@ http_t *http;
     httpReconnect(http);
     

    See Also

    - httpConnect() + httpConnect()

    httpSeparate()

    @@ -5912,20 +5888,20 @@ void httpSeparate(const char *uri, char *method, ArgumentDescription uriThe URI to separate methodThe method (scheme) of the URI -usernameThe username (and password) portion of the -URI, if any +usernameThe username (and password) portion of the URI, + if any hostThe hostname portion of the URI, if any -portThe port number for the URI, either as specified -or as default for the method/scheme -resourceThe resource string, usually a filename on the -server +portThe port number for the URI, either as specified or + as default for the method/scheme +resourceThe resource string, usually a filename on the + server

    Description

    -

    The httpSeparate() function separates the specified URI -into its component parts. The method, username, hostname, and resource -strings should be at least HTTP_MAX_URI characters long to -avoid potential buffer overflow problems.

    +

    The httpSeparate() function separates the specified URI + into its component parts. The method, username, hostname, and resource + strings should be at least HTTP_MAX_URI characters long to + avoid potential buffer overflow problems.

    Example

     char uri[HTTP_MAX_URI];
    @@ -5938,7 +5914,7 @@ int port;
     httpSeparate(uri, method, username, host, &port, resource);
     

    See Also

    - httpConnect() + httpConnect()

    httpSetField()

    @@ -5956,8 +5932,8 @@ void httpSetField(http_t *http, http_field_t field, const char *value);

    Description

    -

    The httpSetField() function sets the current value for -the specified HTTP field.

    +

    The httpSetField() function sets the current value for + the specified HTTP field.

    Example

     #include <cups/http.h>
    @@ -5969,8 +5945,8 @@ httpGet(http, "/some/uri");
     while (httpUpdate(http) == HTTP_CONTINUE);
     

    See Also

    - httpConnect(), -httpGetField() + httpConnect(), + httpGetField()

    httpTrace()

    @@ -5987,10 +5963,10 @@ int httpTrace(http_t *http, const char *uri);

    Returns

    -

    0 on success, non-zero on failure.

    +

    0 on success, non-zero on failure.

    Description

    -

    The httpTrace() function sends a HTTP TRACE request to -the server.

    +

    The httpTrace() function sends a HTTP TRACE request to + the server.

    Example

     #include <cups/http.h>
    @@ -6000,8 +5976,8 @@ http_t *http;
     httpTrace(http, "/some/uri");
     

    See Also

    - httpConnect(), -httpSetField(), + httpConnect(), + httpSetField(), httpUpdate() @@ -6018,16 +5994,16 @@ http_status_t httpUpdate(http_t *http);

    Returns

    -

    The HTTP status of the current request.

    +

    The HTTP status of the current request.

    Description

    -

    The httpUpdate() function updates the current request -status. It is used after any DELETE, GET, HEAD, OPTIONS, POST, PUT, or -TRACE request to finalize the HTTP request and retrieve the request -status.

    -

    Since proxies and the current blocking mode can cause the request to -take longer, programs should continue calling httpUpdate() +

    The httpUpdate() function updates the current request + status. It is used after any DELETE, GET, HEAD, OPTIONS, POST, PUT, or + TRACE request to finalize the HTTP request and retrieve the request + status.

    +

    Since proxies and the current blocking mode can cause the request to + take longer, programs should continue calling httpUpdate() until the return status is not the constant value HTTP_CONTINUE -.

    +.

    Example

     #include <cups/http.h>
    @@ -6040,12 +6016,12 @@ while ((status = httpUpdate(http)) == HTTP_CONTINUE);
     printf("Request status is %d\n", status);
     

    See Also

    - httpConnect(), -httpDelete(), httpGet() -, httpHead(), -httpOptions(), httpPost() -, httpPut(), -httpTrace() + httpConnect(), + httpDelete(), httpGet() +, httpHead(), + httpOptions(), httpPost() +, httpPut(), + httpTrace()

    httpWrite()

    @@ -6063,10 +6039,10 @@ int httpWrite(http_t *http, char *buffer, int length);

    Returns

    -

    The number of bytes read or -1 on error.

    +

    The number of bytes read or -1 on error.

    Description

    -

    The httpWrite() function reads data from the HTTP -connection, possibly the result of a GET or POST request.

    +

    The httpWrite() function reads data from the HTTP + connection, possibly the result of a GET or POST request.

    Example

     #include <cups/http.h>
    @@ -6090,8 +6066,8 @@ while ((bytes = httpRead(http, buffer, sizeof(buffer) - 1)) > 0)
     }
     

    See Also

    - httpConnect(), -httpRead() + httpConnect(), + httpRead()

    ippAddBoolean()

    @@ -6111,11 +6087,11 @@ ipp_attribute_t *ippAddBoolean(ipp_t *ipp, ipp_tag_t group,

    Returns

    -

    A pointer to the new attribute or NULL if the attribute could not be -created.

    +

    A pointer to the new attribute or NULL if the attribute could not be + created.

    Description

    -

    The ippAddBoolean() function adds a single boolean -attribute value to the specified IPP request.

    +

    The ippAddBoolean() function adds a single boolean + attribute value to the specified IPP request.

    Example

     #include <cups/ipp.h>
    @@ -6125,15 +6101,15 @@ ipp_t *ipp;
     ippAddBoolean(ipp, IPP_TAG_OPERATION, "my-jobs", 1);
     

    See Also

    - ippAddBooleans(), -ippAddDate(), -ippAddInteger(), -ippAddIntegers(), ippAddRange() -, ippAddRanges(), -ippAddResolution(), -ippAddResolutions(), -ippAddSeparator(), -ippAddString(), + ippAddBooleans(), + ippAddDate(), +ippAddInteger(), +ippAddIntegers(), ippAddRange() +, ippAddRanges(), + ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), ippAddStrings() @@ -6156,13 +6132,13 @@ ipp_attribute_t *ippAddBooleans(ipp_t *ipp, ipp_tag_t group,

    Returns

    -

    A pointer to the new attribute or NULL if the attribute could not be -created.

    +

    A pointer to the new attribute or NULL if the attribute could not be + created.

    Description

    -

    The ippAddBooleans() function adds one or more boolean -attribute values to the specified IPP request. If the values +

    The ippAddBooleans() function adds one or more boolean + attribute values to the specified IPP request. If the values pointer is NULL then an array of num_values - false values is created.

    + false values is created.

    Example

     #include <cups/ipp.h>
    @@ -6173,15 +6149,15 @@ char values[10];
     ippAddBooleans(ipp, IPP_TAG_OPERATION, "some-attribute", 10, values);
     

    See Also

    - ippAddBoolean(), -ippAddDate(), -ippAddInteger(), -ippAddIntegers(), ippAddRange() -, ippAddRanges(), -ippAddResolution(), -ippAddResolutions(), -ippAddSeparator(), -ippAddString(), + ippAddBoolean(), + ippAddDate(), +ippAddInteger(), +ippAddIntegers(), ippAddRange() +, ippAddRanges(), + ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), ippAddStrings() @@ -6202,11 +6178,11 @@ ipp_attribute_t *ippAddDate(ipp_t *ipp, ipp_tag_t group,

    Returns

    -

    A pointer to the new attribute or NULL if the attribute could not be -created.

    +

    A pointer to the new attribute or NULL if the attribute could not be + created.

    Description

    -

    The ippAddDate() function adds a single date-time -attribute value to the specified IPP request.

    +

    The ippAddDate() function adds a single date-time + attribute value to the specified IPP request.

    Example

     #include <cups/ipp.h>
    @@ -6217,16 +6193,16 @@ ippAddDate(ipp, IPP_TAG_OPERATION, "some-attribute",
                ippTimeToDate(time(NULL));
     

    See Also

    - ippAddBoolean(), -ippAddBooleans(), -ippAddInteger(), -ippAddIntegers(), ippAddRange() -, ippAddRanges(), -ippAddResolution(), -ippAddResolutions(), -ippAddSeparator(), -ippAddString(), -ippAddStrings(), + ippAddBoolean(), + ippAddBooleans(), +ippAddInteger(), +ippAddIntegers(), ippAddRange() +, ippAddRanges(), + ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), +ippAddStrings(), ippTimeToDate() @@ -6243,18 +6219,18 @@ ipp_attribute_t *ippAddInteger(ipp_t *ipp, ipp_tag_t group, ArgumentDescription ippThe IPP request groupThe IPP group -tagThe type of integer value (IPP_TAG_INTEGER or -IPP_TAG_ENUM) +tagThe type of integer value (IPP_TAG_INTEGER or + IPP_TAG_ENUM) nameThe name of attribute valueThe integer value

    Returns

    -

    A pointer to the new attribute or NULL if the attribute could not be -created.

    +

    A pointer to the new attribute or NULL if the attribute could not be + created.

    Description

    -

    The ippAddInteger() function adds a single integer -attribute value to the specified IPP request.

    +

    The ippAddInteger() function adds a single integer + attribute value to the specified IPP request.

    Example

     #include <cups/ipp.h>
    @@ -6264,15 +6240,15 @@ ipp_t *ipp;
     ippAddInteger(ipp, IPP_TAG_OPERATION, "limit", 100);
     

    See Also

    - ippAddBoolean(), -ippAddBooleans(), -ippAddDate(), -ippAddIntegers(), ippAddRange() -, ippAddRanges(), -ippAddResolution(), -ippAddResolutions(), -ippAddSeparator(), -ippAddString(), + ippAddBoolean(), + ippAddBooleans(), +ippAddDate(), +ippAddIntegers(), ippAddRange() +, ippAddRanges(), + ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), ippAddStrings() @@ -6289,21 +6265,21 @@ ipp_attribute_t *ippAddIntegers(ipp_t *ipp, ipp_tag_t group, ArgumentDescription ippThe IPP request groupThe IPP group -tagThe type of integer value (IPP_TAG_INTEGER or -IPP_TAG_ENUM) +tagThe type of integer value (IPP_TAG_INTEGER or + IPP_TAG_ENUM) nameThe name of attribute num_valuesThe number of values valuesThe integer values

    Returns

    -

    A pointer to the new attribute or NULL if the attribute could not be -created.

    +

    A pointer to the new attribute or NULL if the attribute could not be + created.

    Description

    -

    The ippAddIntegers() function adds one or more integer -attribute values to the specified IPP request. If the values - pointer is NULL then an array of num_values - 0 values is created.

    +

    The ippAddIntegers() function adds one or more integer + attribute values to the specified IPP request. If the values + pointer is NULL then an array of num_values 0 + values is created.

    Example

     #include <cups/ipp.h>
    @@ -6314,15 +6290,15 @@ int values[100];
     ippAddIntegers(ipp, IPP_TAG_OPERATION, "some-attribute", 100, values);
     

    See Also

    - ippAddBoolean(), -ippAddBooleans(), -ippAddDate(), ippAddInteger() -, ippAddRange(), -ippAddRanges(), -ippAddResolution(), -ippAddResolutions(), -ippAddSeparator(), -ippAddString(), + ippAddBoolean(), + ippAddBooleans(), +ippAddDate(), ippAddInteger() +, ippAddRange(), + ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), ippAddStrings() @@ -6345,11 +6321,11 @@ ipp_attribute_t *ippAddRange(ipp_t *ipp, ipp_tag_t group,

    Returns

    -

    A pointer to the new attribute or NULL if the attribute could not be -created.

    +

    A pointer to the new attribute or NULL if the attribute could not be + created.

    Description

    -

    The ippAddRange() function adds a single range -attribute value to the specified IPP request.

    +

    The ippAddRange() function adds a single range attribute + value to the specified IPP request.

    Example

     #include <cups/ipp.h>
    @@ -6359,15 +6335,15 @@ ipp_t *ipp;
     ippAddRange(ipp, IPP_TAG_OPERATION, "page-ranges", 1, 10);
     

    See Also

    - ippAddBoolean(), -ippAddBooleans(), -ippAddDate(), ippAddInteger() -, ippAddIntegers(), -ippAddRanges(), -ippAddResolution(), -ippAddResolutions(), -ippAddSeparator(), -ippAddString(), + ippAddBoolean(), + ippAddBooleans(), +ippAddDate(), ippAddInteger() +, ippAddIntegers(), + ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), ippAddStrings() @@ -6391,13 +6367,13 @@ ipp_attribute_t *ippAddRanges(ipp_t *ipp, ipp_tag_t group,

    Returns

    -

    A pointer to the new attribute or NULL if the attribute could not be -created.

    +

    A pointer to the new attribute or NULL if the attribute could not be + created.

    Description

    -

    The ippAddRanges() function adds one or more range -attribute values to the specified IPP request. If the values +

    The ippAddRanges() function adds one or more range + attribute values to the specified IPP request. If the values pointer is NULL then an array of num_values - 0,0 ranges is created.

    + 0,0 ranges is created.

    Example

     #include <cups/ipp.h>
    @@ -6409,15 +6385,15 @@ int highs[2];
     ippAddRanges(ipp, IPP_TAG_OPERATION, "page-ranges", 2, lows, highs);
     

    See Also

    - ippAddBoolean(), -ippAddBooleans(), -ippAddDate(), ippAddInteger() -, ippAddIntegers(), -ippAddRange(), -ippAddResolution(), -ippAddResolutions(), -ippAddSeparator(), -ippAddString(), + ippAddBoolean(), + ippAddBooleans(), +ippAddDate(), ippAddInteger() +, ippAddIntegers(), + ippAddRange(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), ippAddStrings() @@ -6441,11 +6417,11 @@ ipp_attribute_t *ippAddResolution(ipp_t *ipp, ipp_tag_t group,

    Returns

    -

    A pointer to the new attribute or NULL if the attribute could not be -created.

    +

    A pointer to the new attribute or NULL if the attribute could not be + created.

    Description

    -

    The ippAddResolution() function adds a single -resolution attribute value to the specified IPP request.

    +

    The ippAddResolution() function adds a single resolution + attribute value to the specified IPP request.

    Example

     #include <cups/ipp.h>
    @@ -6456,15 +6432,15 @@ ippAddBoolean(ipp, IPP_TAG_OPERATION, "printer-resolution",
                   720, 720, IPP_RES_PER_INCH);
     

    See Also

    - ippAddBoolean(), -ippAddBooleans(), -ippAddDate(), ippAddInteger() -, ippAddIntegers(), -ippAddRange(), -ippAddRanges(), -ippAddResolutions(), -ippAddSeparator(), -ippAddString(), + ippAddBoolean(), + ippAddBooleans(), +ippAddDate(), ippAddInteger() +, ippAddIntegers(), + ippAddRange(), +ippAddRanges(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), ippAddStrings() @@ -6490,13 +6466,13 @@ ipp_attribute_t *ippAddResolutions(ipp_t *ipp, ipp_tag_t group,

    Returns

    -

    A pointer to the new attribute or NULL if the attribute could not be -created.

    +

    A pointer to the new attribute or NULL if the attribute could not be + created.

    Description

    -

    The ippAddResolutions() function adds one or more -resolution attribute values to the specified IPP request. If the +

    The ippAddResolutions() function adds one or more + resolution attribute values to the specified IPP request. If the values pointer is NULL then an array of -num_values 0,0 resolutions is created.

    +num_values 0,0 resolutions is created.

    Example

     #include <cups/ipp.h>
    @@ -6510,15 +6486,15 @@ ippAddBoolean(ipp, IPP_TAG_OPERATION, "printer-resolutions-supported",
                   5, xres, yres, units);
     

    See Also

    - ippAddBoolean(), -ippAddBooleans(), -ippAddDate(), ippAddInteger() -, ippAddIntegers(), -ippAddRange(), -ippAddRanges(), -ippAddResolution(), -ippAddSeparator(), -ippAddString(), + ippAddBoolean(), + ippAddBooleans(), +ippAddDate(), ippAddInteger() +, ippAddIntegers(), + ippAddRange(), +ippAddRanges(), +ippAddResolution(), +ippAddSeparator(), +ippAddString(), ippAddStrings() @@ -6535,11 +6511,11 @@ ipp_attribute_t *ippAddSeparator(ipp_t *ipp);

    Returns

    -

    A pointer to the new separator or NULL if the separator could not be -created.

    +

    A pointer to the new separator or NULL if the separator could not be + created.

    Description

    -

    The ippAddSeparator() function adds a group separator -to the specified IPP request.

    +

    The ippAddSeparator() function adds a group separator to + the specified IPP request.

    Example

     #include <cups/ipp.h>
    @@ -6549,15 +6525,15 @@ ipp_t *ipp;
     ippAddSeparator(ipp);
     

    See Also

    - ippAddBoolean(), -ippAddBooleans(), -ippAddDate(), ippAddInteger() -, ippAddIntegers(), -ippAddRange(), -ippAddRanges(), -ippAddResolution(), -ippAddResolutions(), -ippAddString(), + ippAddBoolean(), + ippAddBooleans(), +ippAddDate(), ippAddInteger() +, ippAddIntegers(), + ippAddRange(), +ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddString(), ippAddStrings() @@ -6581,14 +6557,14 @@ ipp_attribute_t *ippAddString(ipp_t *ipp, ipp_tag_t group,

    Returns

    -

    A pointer to the new attribute or NULL if the attribute could not be -created.

    +

    A pointer to the new attribute or NULL if the attribute could not be + created.

    Description

    -

    The ippAddString() function adds a single string -attribute value to the specified IPP request. For IPP_TAG_NAMELANG - and IPP_TAG_TEXTLANG strings, the charset value is -provided with the string to identify the string encoding used. -Otherwise the charset value is ignored.

    +

    The ippAddString() function adds a single string + attribute value to the specified IPP request. For +IPP_TAG_NAMELANG and IPP_TAG_TEXTLANG strings, the + charset value is provided with the string to identify the string + encoding used. Otherwise the charset value is ignored.

    Example

     #include <cups/ipp.h>
    @@ -6599,15 +6575,15 @@ ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
                  NULL, "abc123");
     

    See Also

    - ippAddBoolean(), -ippAddBooleans(), -ippAddDate(), ippAddInteger() -, ippAddIntegers(), -ippAddRange(), -ippAddRanges(), -ippAddResolution(), -ippAddResolutions(), -ippAddSeparator(), + ippAddBoolean(), + ippAddBooleans(), +ippAddDate(), ippAddInteger() +, ippAddIntegers(), + ippAddRange(), +ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), ippAddStrings() @@ -6633,16 +6609,16 @@ ipp_attribute_t *ippAddStrings(ipp_t *ipp, ipp_tag_t group,

    Returns

    -

    A pointer to the new attribute or NULL if the attribute could not be -created.

    +

    A pointer to the new attribute or NULL if the attribute could not be + created.

    Description

    -

    The ippAddStrings() function adds one or more string -attribute values to the specified IPP request. For -IPP_TAG_NAMELANG and IPP_TAG_TEXTLANG strings, the -charset value is provided with the strings to identify the string -encoding used. Otherwise the charset value is ignored. If the +

    The ippAddStrings() function adds one or more string + attribute values to the specified IPP request. For +IPP_TAG_NAMELANG and IPP_TAG_TEXTLANG strings, the + charset value is provided with the strings to identify the string + encoding used. Otherwise the charset value is ignored. If the values pointer is NULL then an array of -num_values NULL strings is created.

    +num_values NULL strings is created.

    Example

     #include <cups/ipp.h>
    @@ -6654,15 +6630,15 @@ ippAddStrings(ipp, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "attr-name",
                   2, NULL, values);
     

    See Also

    - ippAddBoolean(), -ippAddBooleans(), -ippAddDate(), ippAddInteger() -, ippAddIntegers(), -ippAddRange(), -ippAddRanges(), -ippAddResolution(), -ippAddResolutions(), -ippAddSeparator(), + ippAddBoolean(), + ippAddBooleans(), +ippAddDate(), ippAddInteger() +, ippAddIntegers(), + ippAddRange(), +ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), ippAddString() @@ -6679,10 +6655,10 @@ time_t ippDateToTime(const ipp_uchar_t date[11]);

    Returns

    -

    A UNIX time value.

    +

    A UNIX time value.

    Description

    -

    The ippDateToTime() function converts an IPP date-time -value to a UNIX time value.

    +

    The ippDateToTime() function converts an IPP date-time + value to a UNIX time value.

    Example

     #include <cups/ipp.h>
    @@ -6692,7 +6668,7 @@ ipp_uchar_t date[11];
     printf("UNIX time is %d\n", ippDateToTime(date));
     

    See Also

    - ippTimeToDate() + ippTimeToDate()

    ippDelete()

    @@ -6708,8 +6684,8 @@ void ippDelete(ipp_t *ipp);

    Description

    -

    The ippDelete() function deletes all memory used by an -IPP request or response.

    +

    The ippDelete() function deletes all memory used by an + IPP request or response.

    Example

     #include <cups/ipp.h>
    @@ -6719,7 +6695,7 @@ ipp_t *ipp;
     ippDelete(ipp);
     

    See Also

    - ippNew() + ippNew()

    ippFindAttribute()

    @@ -6734,19 +6710,19 @@ ipp_attribute_t *ippFindAttribute(ipp_t *ipp, const char *name, ipp_tag_t tag); ippThe IPP request or response nameThe name of the attribute tagThe required value tag for the attribute or - IPP_TAG_ZERO for any type of value. +IPP_TAG_ZERO
    for any type of value.

    Returns

    A pointer to the first occurrence of the requested attribute, or -NULL if it was not found.

    +NULL
    if it was not found.

    Description

    -

    ippFindAttribute() finds the first occurrence of the -named attribute. The tag parameter restricts the search to -a specific value type - use IPP_TAG_ZERO to find any value -with the name.

    +

    ippFindAttribute() finds the first occurrence of the + named attribute. The tag parameter restricts the search to + a specific value type - use IPP_TAG_ZERO to find any value + with the name.

    The value tags IPP_TAG_NAME and IPP_TAG_TEXT - match the name/text values with or without the language code.

    + match the name/text values with or without the language code.

    Example

     ipp_attribute_t *attr;
    @@ -6754,9 +6730,9 @@ ipp_attribute_t *attr;
     attr = ippFindAttribute(response, "printer-state-message", IPP_TAG_TEXT);
     

    See Also

    - cupsDoFileRequest(), -cupsDoRequest(), ippDelete() -, ippNew() + cupsDoFileRequest(), + cupsDoRequest(), +ippDelete(), ippNew()

    ippLength()

    @@ -6772,16 +6748,16 @@ int ippLength(ipp_t *ipp);

    Returns

    -

    The total encoded length of the IPP request or response in bytes.

    +

    The total encoded length of the IPP request or response in bytes.

    Description

    -

    ippLength() returns the length of the IPP request or -response in bytes.

    +

    ippLength() returns the length of the IPP request or + response in bytes.

    Example

     printf("The length of the response is %d bytes.\n", ippLength(response));
     

    See Also

    - ippDelete(), + ippDelete(), ippNew() @@ -6791,10 +6767,10 @@ ippNew() ipp_t *ippNew(void);

    Returns

    -

    A pointer to a new IPP request or response.

    +

    A pointer to a new IPP request or response.

    Description

    -

    The ippNew() function creates a new IPP request or -response.

    +

    The ippNew() function creates a new IPP request or + response.

    Example

     #include <cups/ipp.h>
    @@ -6804,7 +6780,7 @@ ipp_t *ipp;
     ipp = ippNew();
     

    See Also

    - ippDelete() + ippDelete()

    ippPort()

    @@ -6813,10 +6789,10 @@ ipp = ippNew(); int ippPort(void);

    Returns

    -

    The default TCP/IP port number for IPP requests.

    +

    The default TCP/IP port number for IPP requests.

    Description

    -

    The ippPort() function returns the default IPP port -number for requests.

    +

    The ippPort() function returns the default IPP port + number for requests.

    Example

     #include <cups/http.h>
    @@ -6827,8 +6803,8 @@ http_t *http;
     http = httpConnect(cupsServer(), ippPort());
     

    See Also

    - cupsServer(), -ippSetPort() + cupsServer(), + ippSetPort()

    ippRead()

    @@ -6845,12 +6821,12 @@ ipp_state_t ippRead(http_t *http, ipp_t *ipp);

    Returns

    -

    The current read state.

    +

    The current read state.

    Description

    -

    The ippRead() function reads IPP attributes from the -specified HTTP connection. Programs should continue calling +

    The ippRead() function reads IPP attributes from the + specified HTTP connection. Programs should continue calling ippRead() until IPP_ERROR or IPP_DATA - is returned.

    + is returned.

    Example

     #include <cups/http.h>
    @@ -6872,7 +6848,7 @@ if (status == IPP_DATA)
     }
     

    See Also

    - ippWrite() + ippWrite()

    ippSetPort()

    @@ -6889,8 +6865,8 @@ ippSetPort(int port);

    Description

    -

    The ippSetPort() function sets the default IPP port -number for requests.

    +

    The ippSetPort() function sets the default IPP port + number for requests.

    Example

     #include <cups/http.h>
    @@ -6901,7 +6877,7 @@ number for requests. 

    ippSetPort(8631);

    See Also

    - ippPort() + ippPort()

    ippTimeToDate()

    @@ -6917,10 +6893,10 @@ ipp_uchar_t *ippTimeToDate(time_t time);

    Returns

    -

    A static pointer to an IPP date-time value.

    +

    A static pointer to an IPP date-time value.

    Description

    -

    The ippTimeToDate() function converts a UNIX time to an -IPP date-time value.

    +

    The ippTimeToDate() function converts a UNIX time to an + IPP date-time value.

    Example

     #include <cups/ipp.h>
    @@ -6930,7 +6906,7 @@ ipp_uchar_t *date;
     date = ippTimeToDate(time(NULL));
     

    See Also

    - ippDateToTime() + ippDateToTime()

    ippWrite()

    @@ -6947,12 +6923,12 @@ ipp_state_t ippWrite(http_t *http, ipp_t *ipp);

    Returns

    -

    The current write state.

    +

    The current write state.

    Description

    -

    The ippWrite() function writes IPP attributes to the -specified HTTP connection. Programs should continue calling +

    The ippWrite() function writes IPP attributes to the + specified HTTP connection. Programs should continue calling ippWrite() until IPP_ERROR or IPP_DATA - is returned.

    + is returned.

    Example

     #include <cups/http.h>
    @@ -6975,7 +6951,7 @@ if (status == IPP_DATA)
     }
     

    See Also

    - ippRead() + ippRead()

    ppdClose()

    @@ -6991,8 +6967,8 @@ void ppdClose(ppd_file_t *ppd);

    Description

    -

    The ppdClose() function frees all memory associated -with the PPD file.

    +

    The ppdClose() function frees all memory associated with + the PPD file.

    Example

     #include <cups/ppd.h>
    @@ -7002,8 +6978,8 @@ ppd_file_t *ppd;
     ppdClose(ppd);
     

    See Also

    - ppdOpen(), -ppdOpenFd(), ppdOpenFile() + ppdOpen(), +ppdOpenFd(), ppdOpenFile() @@ -7020,10 +6996,10 @@ int ppdConflicts(ppd_file_t *ppd);

    Returns

    -

    The number of option conflicts in the file.

    +

    The number of option conflicts in the file.

    Description

    -

    The ppdConflicts() function returns the number of -conflicts with the currently selected options.

    +

    The ppdConflicts() function returns the number of + conflicts with the currently selected options.

    Example

     #include <cups/ppd.h>
    @@ -7033,9 +7009,9 @@ ppd_file_t *ppd;
     printf("%d conflicts\n", ppdConflicts(ppd));
     

    See Also

    - cupsMarkOptions(), -ppdIsMarked(), -ppdMarkDefaults(), + cupsMarkOptions(), + ppdIsMarked(), +ppdMarkDefaults(), ppdMarkOption() @@ -7054,10 +7030,10 @@ int ppdEmit(ppd_file_t *ppd, FILE *file, ppd_section_t section);

    Returns

    -

    0 on success, -1 on error.

    +

    0 on success, -1 on error.

    Description

    -

    The ppdEmit() function sends printer-specific option -commands to the specified file.

    +

    The ppdEmit() function sends printer-specific option + commands to the specified file.

    Example

     #include <cups/ppd.h>
    @@ -7067,7 +7043,7 @@ ppd_file_t *ppd;
     ppdEmit(ppd, stdout, PPD_ORDER_PAGE);
     

    See Also

    - ppdEmitFd() + ppdEmitFd()

    ppdEmitFd()

    @@ -7085,10 +7061,10 @@ int ppdEmitFd(ppd_file_t *ppd, int fd, ppd_section_t section);

    Returns

    -

    0 on success, -1 on error.

    +

    0 on success, -1 on error.

    Description

    -

    The ppdEmitFd() function sends printer-specific option -commands to the specified file descriptor.

    +

    The ppdEmitFd() function sends printer-specific option + commands to the specified file descriptor.

    Example

     #include <cups/ppd.h>
    @@ -7098,7 +7074,7 @@ ppd_file_t *ppd;
     ppdEmitFd(ppd, 1, PPD_ORDER_PAGE);
     

    See Also

    - ppdEmit() + ppdEmit()

    ppdFindChoice()

    @@ -7115,10 +7091,10 @@ ppd_choice_t *ppdFindChoice(ppd_option_t *option, const char *choice);

    Returns

    -

    A pointer to the choice data or NULL if the choice does not exist.

    +

    A pointer to the choice data or NULL if the choice does not exist.

    Description

    -

    The ppdFindChoice() function returns a pointer to the -choice data for the specified option.

    +

    The ppdFindChoice() function returns a pointer to the + choice data for the specified option.

    Example

     #include <cups/ppd.h>
    @@ -7131,8 +7107,8 @@ option = ppdFindOption(ppd, "PageSize");
     choice = ppdFindChoice(option, "Letter");
     

    See Also

    - ppdFindMarkedChoice(), ppdFindOption() + ppdFindMarkedChoice(), ppdFindOption()

    ppdFindMarkedChoice()

    @@ -7149,11 +7125,11 @@ ppd_choice_t *ppdFindMarkedChoice(ppd_file_t *ppd, const char *keyword);

    Returns

    -

    A pointer to the choice data or NULL if the choice does not exist or -is not marked.

    +

    A pointer to the choice data or NULL if the choice does not exist or + is not marked.

    Description

    -

    The ppdFindMarkedChoice() function returns a pointer to -the marked choice data for the specified option.

    +

    The ppdFindMarkedChoice() function returns a pointer to + the marked choice data for the specified option.

    Example

     #include <cups/ppd.h>
    @@ -7164,8 +7140,8 @@ ppd_choice_t *choice;
     choice = ppdFindMarkedChoice(ppd, "PageSize");
     

    See Also

    - ppdFindChoice(), -ppdFindOption() + ppdFindChoice(), + ppdFindOption()

    ppdFindOption()

    @@ -7182,10 +7158,10 @@ ppd_option_t *ppdFindOption(ppd_file_t *ppd, const char *keyword);

    Returns

    -

    A pointer to the option data or NULL if the option does not exist.

    +

    A pointer to the option data or NULL if the option does not exist.

    Description

    -

    The ppdFindOption() function returns a pointer to the -option data for the specified option.

    +

    The ppdFindOption() function returns a pointer to the + option data for the specified option.

    Example

     #include <cups/ppd.h>
    @@ -7196,8 +7172,8 @@ ppd_option_t *option;
     option = ppdFindOption(ppd, "PageSize");
     

    See Also

    - ppdFindChoice(), -ppdFindMarkedChoice() + ppdFindChoice(), + ppdFindMarkedChoice()

    ppdIsMarked()

    @@ -7215,10 +7191,10 @@ int ppdIsMarked(ppd_file_t *ppd, const char *keyword, char char *choice);

    Returns

    -

    1 if the choice is marked, 0 otherwise.

    +

    1 if the choice is marked, 0 otherwise.

    Description

    -

    The ppdIsMarked() function returns whether or not the -specified option choice is marked.

    +

    The ppdIsMarked() function returns whether or not the + specified option choice is marked.

    Example

     #include <cups/ppd.h>
    @@ -7229,10 +7205,10 @@ printf("Letter size %s selected.\n",
            ppdIsMarked(ppd, "PageSize", "Letter") ? "is" : "is not");
     

    See Also

    - cupsMarkOptions(), -ppdConflicts(), -ppdIsMarked(), -ppdMarkDefaults(), + cupsMarkOptions(), + ppdConflicts(), +ppdIsMarked(), +ppdMarkDefaults(), ppdMarkOption() @@ -7249,8 +7225,8 @@ void ppdMarkDefaults(ppd_file_t *ppd);

    Description

    -

    The ppdMarkDefaults() function marks all of the default -choices in the PPD file.

    +

    The ppdMarkDefaults() function marks all of the default + choices in the PPD file.

    Example

     #include <cups/ppd.h>
    @@ -7260,10 +7236,10 @@ ppd_file_t *ppd;
     ppdMarkDefaults(ppd);
     

    See Also

    - cupsMarkOptions(), -ppdConflicts(), -ppdIsMarked(), -ppdMarkDefaults(), + cupsMarkOptions(), + ppdConflicts(), +ppdIsMarked(), +ppdMarkDefaults(), ppdMarkOption() @@ -7282,10 +7258,10 @@ int ppdMarkOption(ppd_file_t *ppd, const char *keyword, const char *choice);

    Returns

    -

    The number of conflicts in the PPD file.

    +

    The number of conflicts in the PPD file.

    Description

    -

    The ppdMarkOption() function marks the specified option -choice.

    +

    The ppdMarkOption() function marks the specified option + choice.

    Example

     #include <cups/ppd.h>
    @@ -7295,10 +7271,10 @@ ppd_file_t *ppd;
     ppdMarkOption(ppd, "PageSize", "Letter");
     

    See Also

    - cupsMarkOptions(), -ppdConflicts(), -ppdIsMarked(), -ppdMarkDefaults(), + cupsMarkOptions(), + ppdConflicts(), +ppdIsMarked(), +ppdMarkDefaults(), ppdMarkOption() @@ -7315,11 +7291,11 @@ ppd_file_t *ppdOpen(FILE *file);

    Returns

    -

    A pointer to a PPD file structure or NULL if the PPD file could not -be read.

    +

    A pointer to a PPD file structure or NULL if the PPD file could not + be read.

    Description

    -

    The ppdOpen() function reads a PPD file from the -specified file into memory.

    +

    The ppdOpen() function reads a PPD file from the + specified file into memory.

    Example

     #include <cups/ppd.h>
    @@ -7332,8 +7308,8 @@ ppd = ppdOpen(file);
     fclose(file);
     

    See Also

    - ppdClose(), -ppdOpenFd(), ppdOpenFile() + ppdClose(), +ppdOpenFd(), ppdOpenFile() @@ -7350,11 +7326,11 @@ ppd_file_t *ppdOpenFd(int fd);

    Returns

    -

    A pointer to a PPD file structure or NULL if the PPD file could not -be read.

    +

    A pointer to a PPD file structure or NULL if the PPD file could not + be read.

    Description

    -

    The ppdOpenFd() function reads a PPD file from the -specified file descriptor into memory.

    +

    The ppdOpenFd() function reads a PPD file from the + specified file descriptor into memory.

    Example

     #include <cups/ppd.h>
    @@ -7367,11 +7343,10 @@ ppd = ppdOpenFd(fd);
     close(fd);
     

    See Also

    - ppdClose(), -ppdOpen(), ppdOpenFile() + ppdClose(), +ppdOpen(), ppdOpenFile() -

    ppdOpenFile()

    Usage

    @@ -7385,11 +7360,11 @@ ppd_file_t *ppdOpenFile(const char *filename);
     
     
     

    Returns

    -

    A pointer to a PPD file structure or NULL if the PPD file could not -be read.

    +

    A pointer to a PPD file structure or NULL if the PPD file could not + be read.

    Description

    -

    The ppdOpenFile() function reads a PPD file from the -named file into memory.

    +

    The ppdOpenFile() function reads a PPD file from the + named file into memory.

    Example

     #include <cups/ppd.h>
    @@ -7399,8 +7374,8 @@ ppd_file_t *ppd;
     ppd = ppdOpenFile("filename.ppd");
     

    See Also

    - ppdClose(), -ppdOpen(), ppdOpenFd() + ppdClose(), +ppdOpen(), ppdOpenFd()

    ppdPageLength()

    @@ -7417,11 +7392,11 @@ float ppdPageLength(ppd_file_t *ppd, const char *name);

    Returns

    -

    The length of the specified page size in points or 0 if the page -size does not exist.

    +

    The length of the specified page size in points or 0 if the page size + does not exist.

    Description

    -

    The ppdPageLength() function returns the page length of -the specified page size.

    +

    The ppdPageLength() function returns the page length of + the specified page size.

    Example

     #include <cups/ppd.h>
    @@ -7431,8 +7406,8 @@ ppd_file_t *ppd;
     printf("Length = %.0f\n", ppdPageLength(ppd, "Letter"));
     

    See Also

    - ppdPageLength(), -ppdPageSize(), + ppdPageLength(), + ppdPageSize(), ppdPageWidth() @@ -7450,11 +7425,11 @@ ppd_size_t *ppdPageSize(ppd_file_t *ppd, const char *name);

    Returns

    -

    A pointer to the page size record of the specified page size in -points or NULL if the page size does not exist.

    +

    A pointer to the page size record of the specified page size in + points or NULL if the page size does not exist.

    Description

    -

    The ppdPageSize() function returns the page size record -for the specified page size.

    +

    The ppdPageSize() function returns the page size record + for the specified page size.

    Example

     #include <cups/ppd.h>
    @@ -7474,8 +7449,8 @@ if (size != NULL)
     }
     

    See Also

    - ppdPageLength(), -ppdPageWidth() + ppdPageLength(), + ppdPageWidth()

    ppdPageWidth()

    @@ -7492,11 +7467,11 @@ float ppdPageWidth(ppd_file_t *ppd, const char *name);

    Returns

    -

    The width of the specified page size in points or 0 if the page size -does not exist.

    +

    The width of the specified page size in points or 0 if the page size + does not exist.

    Description

    -

    The ppdPageWidth() function returns the page width of -the specified page size.

    +

    The ppdPageWidth() function returns the page width of + the specified page size.

    Example

     #include <cups/ppd.h>
    @@ -7506,6 +7481,6 @@ ppd_file_t *ppd;
     printf("Width = %.0f\n", ppdPageWidth(ppd, "Letter"));
     

    See Also

    - ppdPageLength(), -ppdPageSize() + ppdPageLength(), + ppdPageSize() diff --git a/doc/spm.pdf b/doc/spm.pdf index 672132355a..50d39b1efb 100644 Binary files a/doc/spm.pdf and b/doc/spm.pdf differ diff --git a/doc/spm.shtml b/doc/spm.shtml index 55bf517bb3..94dbb01262 100644 --- a/doc/spm.shtml +++ b/doc/spm.shtml @@ -1,7 +1,7 @@ - + CUPS Software Programmers Manual @@ -11,7 +11,7 @@

    This software programmers manual provides software programming information for the Common UNIX Printing System -("CUPS") Version 1.1.7. +("CUPS") Version 1.2.0. diff --git a/doc/sps.html b/doc/sps.html index 3a320e8fe7..5845b01a5f 100644 --- a/doc/sps.html +++ b/doc/sps.html @@ -1,27 +1,27 @@ - CUPS Software Performance Specification +CUPS Software Performance Specification -


    -

    CUPS Software Performance Specification


    +

    +

    CUPS Software Performance Specification


    CUPS-SPS-1.1
    Easy Software Products
    Copyright 1997-2001, All Rights Reserved
    @@ -52,30 +52,30 @@ Copyright 1997-2001, All Rights Reserved

    1 Scope

    1.1 Identification

    -

    This software performance specification provides an analysis of the -memory, disk, and processor utilitization of each program in the Common -UNIX Printing System ("CUPS") Version 1.1.

    -

    For the purposes of comparison, all figures are for the Linux Intel -platform. Memory utilization on other platforms should be similar.

    +

    This software performance specification provides an analysis of the + memory, disk, and processor utilitization of each program in the Common + UNIX Printing System ("CUPS") Version 1.1.

    +

    For the purposes of comparison, all figures are for the Linux Intel + platform. Memory utilization on other platforms should be similar.

    1.2 System Overview

    -

    CUPS provides a portable printing layer for UNIX®-based operating -systems. It has been developed by Easy -Software Products to promote a standard printing solution for all -UNIX vendors and users. CUPS provides the System V and Berkeley -command-line interfaces.

    -

    CUPS uses the Internet Printing Protocol ("IPP") as the basis for -managing print jobs and queues. The Line Printer Daemon ("LPD") Server -Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are -also supported with reduced functionality. CUPS adds network printer -browsing and PostScript Printer Description ("PPD") based printing -options to support real-world printing under UNIX.

    -

    CUPS also includes a customized version of GNU Ghostscript -(currently based off GNU Ghostscript 5.50) and an image file RIP that -are used to support non-PostScript printers. Sample drivers for HP and -EPSON printers are included that use these filters.

    +

    CUPS provides a portable printing layer for UNIX®-based operating + systems. It has been developed by Easy + Software Products to promote a standard printing solution for all + UNIX vendors and users. CUPS provides the System V and Berkeley + command-line interfaces.

    +

    CUPS uses the Internet Printing Protocol ("IPP") as the basis for + managing print jobs and queues. The Line Printer Daemon ("LPD") Server + Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are + also supported with reduced functionality. CUPS adds network printer + browsing and PostScript Printer Description ("PPD") based printing + options to support real-world printing under UNIX.

    +

    CUPS also includes a customized version of GNU Ghostscript (currently + based off GNU Ghostscript 5.50) and an image file RIP that are used to + support non-PostScript printers. Sample drivers for HP and EPSON + printers are included that use these filters.

    1.3 Document Overview

    -

    This software performance specification is organized into the -following sections:

    +

    This software performance specification is organized into the + following sections:

    • 1 - Scope
    • 2 - References
    • @@ -85,72 +85,72 @@ following sections:

    2 References

    2.1 CUPS Documentation

    -

    The following CUPS documentation is referenced by this document:

    +

    The following CUPS documentation is referenced by this document:

      -
    • CUPS-CMP-1.1: CUPS Configuration Management Plan
    • -
    • CUPS-IDD-1.1: CUPS System Interface Design Description
    • -
    • CUPS-IPP-1.1: CUPS Implementation of IPP
    • -
    • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
    • -
    • CUPS-SDD-1.1: CUPS Software Design Description
    • -
    • CUPS-SPM-1.1.x: CUPS Software Programming Manual
    • -
    • CUPS-SSR-1.1: CUPS Software Security Report
    • -
    • CUPS-STP-1.1: CUPS Software Test Plan
    • -
    • CUPS-SUM-1.1.x: CUPS Software Users Manual
    • -
    • CUPS-SVD-1.1: CUPS Software Version Description
    • +
    • CUPS-CMP-1.1: CUPS Configuration Management Plan
    • +
    • CUPS-IDD-1.1: CUPS System Interface Design Description
    • +
    • CUPS-IPP-1.1: CUPS Implementation of IPP
    • +
    • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
    • +
    • CUPS-SDD-1.1: CUPS Software Design Description
    • +
    • CUPS-SPM-1.1.x: CUPS Software Programming Manual
    • +
    • CUPS-SSR-1.1: CUPS Software Security Report
    • +
    • CUPS-STP-1.1: CUPS Software Test Plan
    • +
    • CUPS-SUM-1.1.x: CUPS Software Users Manual
    • +
    • CUPS-SVD-1.1: CUPS Software Version Description

    2.2 Other Documents

    -

    The following non-CUPS documents are referenced by this document:

    +

    The following non-CUPS documents are referenced by this document:

    3 Programs

    -

    The following table describes the average memory, disk, and CPU -usage of each program in CUPS.

    -

    The base memory column shows the initial memory requirements for -each program, including any shared libraries that are provided by CUPS.

    -

    The max memory column shows the maximum amount of memory that will -be used by the program based upon the default configuration settings -supplied with CUPS.

    -

    The temp files column indicates whether any temporary files are -created.

    -

    The CPU usage column specifies a relative CPU usage by the program -under normal conditions, either low, medium, or high. Low usage -indicates that the program will never use more than 33% of the -available CPU time. Medium usage indicates the program will use as much -as 66% of the available CPU time. High usage indicates the program uses -66% or more of the available CPU time. +

    The following table describes the average memory, disk, and CPU usage + of each program in CUPS.

    +

    The base memory column shows the initial memory requirements for each + program, including any shared libraries that are provided by CUPS.

    +

    The max memory column shows the maximum amount of memory that will be + used by the program based upon the default configuration settings + supplied with CUPS.

    +

    The temp files column indicates whether any temporary files are + created.

    +

    The CPU usage column specifies a relative CPU usage by the program + under normal conditions, either low, medium, or high. Low usage + indicates that the program will never use more than 33% of the + available CPU time. Medium usage indicates the program will use as much + as 66% of the available CPU time. High usage indicates the program uses + 66% or more of the available CPU time.

    - + - + - - + + - + @@ -188,31 +188,31 @@ None Medium - + - - + + - + - - - - + + + + @@ -222,11 +222,11 @@ Low

    4 Scheduler Objects

    -

    The cupsd program is the CUPS scheduler process. It -manages many interdependent server objects that are used to manage and -print files to printers.

    -

    The following table provides the memory and disk cost associated -with each server object. +

    The cupsd program is the CUPS scheduler process. It + manages many interdependent server objects that are used to manage and + print files to printers.

    +

    The following table provides the memory and disk cost associated with + each server object.

    Backends
    ProgramBase MemoryMax MemoryTemp -FilesCPU Usage
    ProgramBase MemoryMax MemoryTemp + FilesCPU Usage
    ipp91k256kUp to size of print file Low
    lpd89k89kUp to size of print file Low
    parallel85k85kUp to size of print -fileLow
    parallel85k85kUp to size of print + fileLow
    serial85k85kUp to size of print file Low
    socket85k85kUp to size of print file @@ -158,10 +158,10 @@ Low
    usb85k85kUp to size of print file Low
    CGIs
    ProgramBase MemoryMax MemoryTemp -FilesCPU Usage
    admin.cgi107k256kUp to size of PPD -fileMedium
    ProgramBase MemoryMax MemoryTemp + FilesCPU Usage
    admin.cgi107k256kUp to size of PPD + fileMedium
    classes.cgi95kSize of class objects NoneMedium
    jobs.cgi93kSize of job objectsNone @@ -169,8 +169,8 @@ Medium
    printers.cgi95kSize of printer objects NoneMedium
    Command-Line Programs
    ProgramBase MemoryMax MemoryTemp -FilesCPU Usage
    ProgramBase MemoryMax MemoryTemp + FilesCPU Usage
    accept88k128kNoneLow
    cancel88k128kNoneLow
    disable88k128kNoneLow
    Medium
    lpr87k256kNoneLow
    lprm84k128kNoneLow
    lpstat119kSize of job, printer, and class -objectsNoneMedium
    lpstat119kSize of job, printer, and class + objectsNoneMedium
    reject88k128kNoneLow
    Daemons
    ProgramBase MemoryMax MemoryTemp -FilesCPU Usage
    cups-lpd92k256kOne file per control -or data file from clientLow
    ProgramBase MemoryMax MemoryTemp + FilesCPU Usage
    cups-lpd92k256kOne file per control + or data file from clientLow
    cupsd308kSee Scheduler Requirements See Scheduler RequirementsMedium
    cups-polld84kSize of printer and class objects NoneLow
    Filters
    ProgramBase MemoryMax MemoryTemp -FilesCPU Usage
    ProgramBase MemoryMax MemoryTemp + FilesCPU Usage
    hpgltops263k320kNoneMedium
    imagetops628k10MSwap file for -uncompressed image dataMedium
    imagetoraster652k10MSwap file for -uncompressed image dataHigh
    pstops775k840kUp to size of print -fileMedium
    pstoraster4M14MSwap file for command -listsHigh
    imagetops628k10MSwap file for + uncompressed image dataMedium
    imagetoraster652k10MSwap file for + uncompressed image dataHigh
    pstops775k840kUp to size of print + fileMedium
    pstoraster4M14MSwap file for command + listsHigh
    rastertoepson693k1MNoneLow
    rastertohp690k1MNoneLow
    @@ -249,49 +249,49 @@ with each server object.

    A Glossary

    A.1 Terms

    -
    C
    -
    A computer language.
    -
    parallel
    -
    Sending or receiving data more than 1 bit at a time.
    -
    pipe
    -
    A one-way communications channel between two programs.
    -
    serial
    -
    Sending or receiving data 1 bit at a time.
    -
    socket
    -
    A two-way network communications channel.
    +
    C
    +
    A computer language.
    +
    parallel
    +
    Sending or receiving data more than 1 bit at a time.
    +
    pipe
    +
    A one-way communications channel between two programs.
    +
    serial
    +
    Sending or receiving data 1 bit at a time.
    +
    socket
    +
    A two-way network communications channel.

    A.2 Acronyms

    -
    ASCII
    -
    American Standard Code for Information Interchange
    -
    CUPS
    -
    Common UNIX Printing System
    -
    ESC/P
    -
    EPSON Standard Code for Printers
    -
    FTP
    -
    File Transfer Protocol
    -
    HP-GL
    -
    Hewlett-Packard Graphics Language
    -
    HP-PCL
    -
    Hewlett-Packard Page Control Language
    -
    HP-PJL
    -
    Hewlett-Packard Printer Job Language
    -
    IETF
    -
    Internet Engineering Task Force
    -
    IPP
    -
    Internet Printing Protocol
    -
    ISO
    -
    International Standards Organization
    -
    LPD
    -
    Line Printer Daemon
    -
    MIME
    -
    Multimedia Internet Mail Exchange
    -
    PPD
    -
    PostScript Printer Description
    -
    SMB
    -
    Server Message Block
    -
    TFTP
    -
    Trivial File Transfer Protocol
    +
    ASCII
    +
    American Standard Code for Information Interchange
    +
    CUPS
    +
    Common UNIX Printing System
    +
    ESC/P
    +
    EPSON Standard Code for Printers
    +
    FTP
    +
    File Transfer Protocol
    +
    HP-GL
    +
    Hewlett-Packard Graphics Language
    +
    HP-PCL
    +
    Hewlett-Packard Page Control Language
    +
    HP-PJL
    +
    Hewlett-Packard Printer Job Language
    +
    IETF
    +
    Internet Engineering Task Force
    +
    IPP
    +
    Internet Printing Protocol
    +
    ISO
    +
    International Standards Organization
    +
    LPD
    +
    Line Printer Daemon
    +
    MIME
    +
    Multimedia Internet Mail Exchange
    +
    PPD
    +
    PostScript Printer Description
    +
    SMB
    +
    Server Message Block
    +
    TFTP
    +
    Trivial File Transfer Protocol
    diff --git a/doc/sps.pdf b/doc/sps.pdf index 79527d3fb5..888366894c 100644 Binary files a/doc/sps.pdf and b/doc/sps.pdf differ diff --git a/doc/ssr.html b/doc/ssr.html index f06bfd2216..8171ad8821 100644 --- a/doc/ssr.html +++ b/doc/ssr.html @@ -1,27 +1,27 @@ - CUPS Software Security Report +CUPS Software Security Report -

    -

    CUPS Software Security Report


    +

    +

    CUPS Software Security Report


    CUPS-SSR-1.1
    Easy Software Products
    Copyright 1997-2001, All Rights Reserved
    @@ -57,28 +57,28 @@ Copyright 1997-2001, All Rights Reserved

    1 Scope

    1.1 Identification

    -

    This software security report provides an analysis of possible -security concerns for the Common UNIX Printing System ("CUPS") Version -1.1.

    +

    This software security report provides an analysis of possible + security concerns for the Common UNIX Printing System ("CUPS") Version + 1.1.

    1.2 System Overview

    -

    CUPS provides a portable printing layer for UNIX®-based operating -systems. It has been developed by Easy -Software Products to promote a standard printing solution for all -UNIX vendors and users. CUPS provides the System V and Berkeley -command-line interfaces.

    -

    CUPS uses the Internet Printing Protocol ("IPP") as the basis for -managing print jobs and queues. The Line Printer Daemon ("LPD") Server -Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are -also supported with reduced functionality. CUPS adds network printer -browsing and PostScript Printer Description ("PPD") based printing -options to support real-world printing under UNIX.

    -

    CUPS also includes a customized version of GNU Ghostscript -(currently based off GNU Ghostscript 5.50) and an image file RIP that -are used to support non-PostScript printers. Sample drivers for HP and -EPSON printers are included that use these filters.

    +

    CUPS provides a portable printing layer for UNIX®-based operating + systems. It has been developed by Easy + Software Products to promote a standard printing solution for all + UNIX vendors and users. CUPS provides the System V and Berkeley + command-line interfaces.

    +

    CUPS uses the Internet Printing Protocol ("IPP") as the basis for + managing print jobs and queues. The Line Printer Daemon ("LPD") Server + Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are + also supported with reduced functionality. CUPS adds network printer + browsing and PostScript Printer Description ("PPD") based printing + options to support real-world printing under UNIX.

    +

    CUPS also includes a customized version of GNU Ghostscript (currently + based off GNU Ghostscript 5.50) and an image file RIP that are used to + support non-PostScript printers. Sample drivers for HP and EPSON + printers are included that use these filters.

    1.3 Document Overview

    -

    This software security report is organized into the following -sections:

    +

    This software security report is organized into the following + sections:

    • 1 - Scope
    • 2 - References
    • @@ -88,183 +88,182 @@ sections:

    2 References

    2.1 CUPS Documentation

    -

    The following CUPS documentation is referenced by this document:

    +

    The following CUPS documentation is referenced by this document:

      -
    • CUPS-CMP-1.1: CUPS Configuration Management Plan
    • -
    • CUPS-IDD-1.1: CUPS System Interface Design Description
    • -
    • CUPS-IPP-1.1: CUPS Implementation of IPP
    • -
    • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
    • -
    • CUPS-SDD-1.1: CUPS Software Design Description
    • -
    • CUPS-SPM-1.1.x: CUPS Software Programming Manual
    • -
    • CUPS-SSR-1.1: CUPS Software Security Report
    • -
    • CUPS-STP-1.1: CUPS Software Test Plan
    • -
    • CUPS-SUM-1.1.x: CUPS Software Users Manual
    • -
    • CUPS-SVD-1.1: CUPS Software Version Description
    • +
    • CUPS-CMP-1.1: CUPS Configuration Management Plan
    • +
    • CUPS-IDD-1.1: CUPS System Interface Design Description
    • +
    • CUPS-IPP-1.1: CUPS Implementation of IPP
    • +
    • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
    • +
    • CUPS-SDD-1.1: CUPS Software Design Description
    • +
    • CUPS-SPM-1.1.x: CUPS Software Programming Manual
    • +
    • CUPS-SSR-1.1: CUPS Software Security Report
    • +
    • CUPS-STP-1.1: CUPS Software Test Plan
    • +
    • CUPS-SUM-1.1.x: CUPS Software Users Manual
    • +
    • CUPS-SVD-1.1: CUPS Software Version Description

    2.2 Other Documents

    -

    The following non-CUPS documents are referenced by this document:

    +

    The following non-CUPS documents are referenced by this document:

    3 Local Access Risks

    -

    Local access risks are those that can be exploited only with a local -user account. This section does not address issues related to -dissemination of the root password or other security issues associated -with the UNIX operating system.

    +

    Local access risks are those that can be exploited only with a local + user account. This section does not address issues related to + dissemination of the root password or other security issues associated + with the UNIX operating system.

    3.1 Security Breaches

    -

    There is one known security vulnerability with local access:

    +

    There is one known security vulnerability with local access:

      -
    1. Device URIs are passed to backend filters in argv[0] and in an -environment variable. Since device URIs can contain usernames and -passwords it may be possible for a local user to gain access to a -remote resource.
    2. -

      We recommend that any password-protected accounts used for remote -printing have limited access priviledges so that the possible damages -can be minimized.

      -

      The device URI is "sanitized" (the username and password are - removed) when sent to an IPP client so that a remote user cannot -exploit this vulnerability.

      +
    3. Device URIs are passed to backend filters in argv[0] and in an + environment variable. Since device URIs can contain usernames and + passwords it may be possible for a local user to gain access to a + remote resource.
    4. +

      We recommend that any password-protected accounts used for remote + printing have limited access priviledges so that the possible damages + can be minimized.

      +

      The device URI is "sanitized" (the username and password are removed) + when sent to an IPP client so that a remote user cannot exploit this + vulnerability.

    4 Remote Access Risks

    -

    Remote access risks are those that can be exploited without a local -user account and/or from a remote system. This section does not address -issues related to network or firewall security.

    +

    Remote access risks are those that can be exploited without a local + user account and/or from a remote system. This section does not address + issues related to network or firewall security.

    4.1 Denial of Service Attacks

    -

    Like all Internet services, the CUPS server is vulnerable to denial -of service attacks, including:

    +

    Like all Internet services, the CUPS server is vulnerable to denial + of service attacks, including:

      -
    1. Establishing multiple connections to the server until the server - will accept no more.
    2. -

      This cannot be protected against by the current software. It is -possible that future versions of the CUPS software could be configured -to limit the number of connections allowed from a single host, however -that still would not prevent a distributed attack.

      -
    3. Repeatedly opening and closing connections to the server as fast - as possible.
    4. -

      There is no easy way of protecting against this in the CUPS - software. If the attack is coming from outside the local network it -might be possible to filter such an attack, however once the -connection request has been received by the server it must at least -accept the connection to find out who is connecting.

      -
    5. Flooding the network with broadcast packets on port 631.
    6. -

      It might be possible to disable browsing if this condition is -detected by the CUPS software, however if there are large numbers of -printers available on the network such an algorithm might think that -an attack was occurring when instead a valid update was being -received.

      -
    7. Sending partial IPP requests; specifically, sending part of an - attribute value and then stopping transmission.
    8. -

      The current code is structured to read and write the IPP request -data on-the-fly, so there is no easy way to protect against this for -large attribute values.

      -
    9. Sending large/long print jobs to printers, preventing other users - from printing.
    10. -

      There are limited facilities for protecting against large print - jobs (the MaxRequestSize attribute), however this will - not protect printers from malicious users and print files that - generate hundreds or thousands of pages. In general, we recommend - restricting printer access to known hosts or networks, and adding - user-level access control as needed for expensive printers.

      +
    11. Establishing multiple connections to the server until the server + will accept no more.
    12. +

      This cannot be protected against by the current software. It is + possible that future versions of the CUPS software could be configured + to limit the number of connections allowed from a single host, however + that still would not prevent a distributed attack.

      +
    13. Repeatedly opening and closing connections to the server as fast as + possible.
    14. +

      There is no easy way of protecting against this in the CUPS software. + If the attack is coming from outside the local network it might be + possible to filter such an attack, however once the connection request + has been received by the server it must at least accept the connection + to find out who is connecting.

      +
    15. Flooding the network with broadcast packets on port 631.
    16. +

      It might be possible to disable browsing if this condition is + detected by the CUPS software, however if there are large numbers of + printers available on the network such an algorithm might think that an + attack was occurring when instead a valid update was being received.

      +
    17. Sending partial IPP requests; specifically, sending part of an + attribute value and then stopping transmission.
    18. +

      The current code is structured to read and write the IPP request data + on-the-fly, so there is no easy way to protect against this for large + attribute values.

      +
    19. Sending large/long print jobs to printers, preventing other users + from printing.
    20. +

      There are limited facilities for protecting against large print jobs + (the MaxRequestSize attribute), however this will not + protect printers from malicious users and print files that generate + hundreds or thousands of pages. In general, we recommend restricting + printer access to known hosts or networks, and adding user-level access + control as needed for expensive printers.

    4.2 Security Breaches

    -

    The current CUPS server supports Basic, Digest, and local -certificate authentication:

    +

    The current CUPS server supports Basic, Digest, and local certificate + authentication:

      -
    1. Basic authentication essentially places the clear text of the -username and password on the network. Since CUPS uses the UNIX -username and password account information, the authentication -information could be used to gain access to accounts (possibly -priviledged accounts) on the server.
    2. -
    3. Digest authentication uses an MD5 checksum of the username, - password, and domain ("CUPS"), so the original username and password -is not sent over the network. However, the current implementation does -not authenticate the entire message and uses the client's IP address -for the nonce value, making it possible to launch "man in the middle" -and replay attacks from the same client. The next minor release of -CUPS will support Digest authentication of the entire message body, -effectively stopping these methods of attack.
    4. -
    5. Local certificate authentication passes 128-bit "certificates" -that identify an authenticated user. Certificates are created -on-the-fly from random data and stored in files under -/etc/cups/certs. They have restricted read permissions: root + -system for the root certificate, and lp + system for CGI certificates. -Because certificates are only available on the local system, the CUPS - server does not accept local authentication unless the client is -connected to the localhost address (127.0.0.1.)
    6. +
    7. Basic authentication essentially places the clear text of the + username and password on the network. Since CUPS uses the UNIX username + and password account information, the authentication information could + be used to gain access to accounts (possibly priviledged accounts) on + the server.
    8. +
    9. Digest authentication uses an MD5 checksum of the username, + password, and domain ("CUPS"), so the original username and password is + not sent over the network. However, the current implementation does not + authenticate the entire message and uses the client's IP address for + the nonce value, making it possible to launch "man in the middle" and + replay attacks from the same client. The next minor release of CUPS + will support Digest authentication of the entire message body, + effectively stopping these methods of attack.
    10. +
    11. Local certificate authentication passes 128-bit "certificates" that + identify an authenticated user. Certificates are created on-the-fly + from random data and stored in files under /etc/cups/certs +. They have restricted read permissions: root + system for the root + certificate, and lp + system for CGI certificates. Because certificates + are only available on the local system, the CUPS server does not accept + local authentication unless the client is connected to the localhost + address (127.0.0.1.)
    -

    The default CUPS configuration disables remote administration. We do -not recommend that remote administration be enabled for all hosts. -However, if you have a trusted network or subnet, access can be -restricted accordingly. Also, we highly recommend using Digest -authentication when possible. Unfortunately, most web browsers do not -support Digest authentication at this time.

    +

    The default CUPS configuration disables remote administration. We do + not recommend that remote administration be enabled for all hosts. + However, if you have a trusted network or subnet, access can be + restricted accordingly. Also, we highly recommend using Digest + authentication when possible. Unfortunately, most web browsers do not + support Digest authentication at this time.

    A Glossary

    A.1 Terms

    -
    C
    -
    A computer language.
    -
    parallel
    -
    Sending or receiving data more than 1 bit at a time.
    -
    pipe
    -
    A one-way communications channel between two programs.
    -
    serial
    -
    Sending or receiving data 1 bit at a time.
    -
    socket
    -
    A two-way network communications channel.
    +
    C
    +
    A computer language.
    +
    parallel
    +
    Sending or receiving data more than 1 bit at a time.
    +
    pipe
    +
    A one-way communications channel between two programs.
    +
    serial
    +
    Sending or receiving data 1 bit at a time.
    +
    socket
    +
    A two-way network communications channel.

    A.2 Acronyms

    -
    ASCII
    -
    American Standard Code for Information Interchange
    -
    CUPS
    -
    Common UNIX Printing System
    -
    ESC/P
    -
    EPSON Standard Code for Printers
    -
    FTP
    -
    File Transfer Protocol
    -
    HP-GL
    -
    Hewlett-Packard Graphics Language
    -
    HP-PCL
    -
    Hewlett-Packard Page Control Language
    -
    HP-PJL
    -
    Hewlett-Packard Printer Job Language
    -
    IETF
    -
    Internet Engineering Task Force
    -
    IPP
    -
    Internet Printing Protocol
    -
    ISO
    -
    International Standards Organization
    -
    LPD
    -
    Line Printer Daemon
    -
    MIME
    -
    Multimedia Internet Mail Exchange
    -
    PPD
    -
    PostScript Printer Description
    -
    SMB
    -
    Server Message Block
    -
    TFTP
    -
    Trivial File Transfer Protocol
    +
    ASCII
    +
    American Standard Code for Information Interchange
    +
    CUPS
    +
    Common UNIX Printing System
    +
    ESC/P
    +
    EPSON Standard Code for Printers
    +
    FTP
    +
    File Transfer Protocol
    +
    HP-GL
    +
    Hewlett-Packard Graphics Language
    +
    HP-PCL
    +
    Hewlett-Packard Page Control Language
    +
    HP-PJL
    +
    Hewlett-Packard Printer Job Language
    +
    IETF
    +
    Internet Engineering Task Force
    +
    IPP
    +
    Internet Printing Protocol
    +
    ISO
    +
    International Standards Organization
    +
    LPD
    +
    Line Printer Daemon
    +
    MIME
    +
    Multimedia Internet Mail Exchange
    +
    PPD
    +
    PostScript Printer Description
    +
    SMB
    +
    Server Message Block
    +
    TFTP
    +
    Trivial File Transfer Protocol
    diff --git a/doc/ssr.pdf b/doc/ssr.pdf index f24244cd93..6dccf74de4 100644 Binary files a/doc/ssr.pdf and b/doc/ssr.pdf differ diff --git a/doc/stp.html b/doc/stp.html index 2ed71e25a0..bd95c89807 100644 --- a/doc/stp.html +++ b/doc/stp.html @@ -1,27 +1,27 @@ - CUPS Software Test Plan +CUPS Software Test Plan -

    -

    CUPS Software Test Plan


    +

    +

    CUPS Software Test Plan


    CUPS-STP-1.1
    Easy Software Products
    Copyright 1997-2001, All Rights Reserved
    @@ -68,27 +68,27 @@ Copyright 1997-2001, All Rights Reserved

    1 Scope

    1.1 Identification

    -

    This software test plan provides detailed tests that are used to -evaluate the stability and compliance of the Common UNIX Printing -System ("CUPS") Version 1.1.

    +

    This software test plan provides detailed tests that are used to + evaluate the stability and compliance of the Common UNIX Printing + System ("CUPS") Version 1.1.

    1.2 System Overview

    -

    CUPS provides a portable printing layer for UNIX®-based operating -systems. It has been developed by Easy -Software Products to promote a standard printing solution for all -UNIX vendors and users. CUPS provides the System V and Berkeley -command-line interfaces.

    -

    CUPS uses the Internet Printing Protocol ("IPP") as the basis for -managing print jobs and queues. The Line Printer Daemon ("LPD") Server -Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are -also supported with reduced functionality. CUPS adds network printer -browsing and PostScript Printer Description ("PPD") based printing -options to support real-world printing under UNIX.

    -

    CUPS also includes a customized version of GNU Ghostscript -(currently based off GNU Ghostscript 5.50) and an image file RIP that -are used to support non-PostScript printers. Sample drivers for HP and -EPSON printers are included that use these filters.

    +

    CUPS provides a portable printing layer for UNIX®-based operating + systems. It has been developed by Easy + Software Products to promote a standard printing solution for all + UNIX vendors and users. CUPS provides the System V and Berkeley + command-line interfaces.

    +

    CUPS uses the Internet Printing Protocol ("IPP") as the basis for + managing print jobs and queues. The Line Printer Daemon ("LPD") Server + Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are + also supported with reduced functionality. CUPS adds network printer + browsing and PostScript Printer Description ("PPD") based printing + options to support real-world printing under UNIX.

    +

    CUPS also includes a customized version of GNU Ghostscript (currently + based off GNU Ghostscript 5.50) and an image file RIP that are used to + support non-PostScript printers. Sample drivers for HP and EPSON + printers are included that use these filters.

    1.3 Document Overview

    -

    This software test plan is organized into the following sections:

    +

    This software test plan is organized into the following sections:

    • 1 - Scope
    • 2 - References
    • @@ -99,164 +99,164 @@ EPSON printers are included that use these filters.

    2 References

    2.1 CUPS Documentation

    -

    The following CUPS documentation is referenced by this document:

    +

    The following CUPS documentation is referenced by this document:

      -
    • CUPS-CMP-1.1: CUPS Configuration Management Plan
    • -
    • CUPS-IDD-1.1: CUPS System Interface Design Description
    • -
    • CUPS-IPP-1.1: CUPS Implementation of IPP
    • -
    • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
    • -
    • CUPS-SDD-1.1: CUPS Software Design Description
    • -
    • CUPS-SPM-1.1.x: CUPS Software Programming Manual
    • -
    • CUPS-SSR-1.1: CUPS Software Security Report
    • -
    • CUPS-STP-1.1: CUPS Software Test Plan
    • -
    • CUPS-SUM-1.1.x: CUPS Software Users Manual
    • -
    • CUPS-SVD-1.1: CUPS Software Version Description
    • +
    • CUPS-CMP-1.1: CUPS Configuration Management Plan
    • +
    • CUPS-IDD-1.1: CUPS System Interface Design Description
    • +
    • CUPS-IPP-1.1: CUPS Implementation of IPP
    • +
    • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
    • +
    • CUPS-SDD-1.1: CUPS Software Design Description
    • +
    • CUPS-SPM-1.1.x: CUPS Software Programming Manual
    • +
    • CUPS-SSR-1.1: CUPS Software Security Report
    • +
    • CUPS-STP-1.1: CUPS Software Test Plan
    • +
    • CUPS-SUM-1.1.x: CUPS Software Users Manual
    • +
    • CUPS-SVD-1.1: CUPS Software Version Description

    2.2 Other Documents

    -

    The following non-CUPS documents are referenced by this document:

    +

    The following non-CUPS documents are referenced by this document:

    3 Test Procedure

    -

    The test software and data files are located in the test - subdirectory of the source distribution. A script is provided to -compile the ipptest program and run all of the tests that -follow, producing a success/fail report.

    -

    The test target of the top-level makefile can be used -to run this script:

    +

    The test software and data files are located in the test + subdirectory of the source distribution. A script is provided to + compile the ipptest program and run all of the tests that + follow, producing a success/fail report.

    +

    The test target of the top-level makefile can be used to + run this script:

       make test
       
    -

    or you can run the test script directly:

    +

    or you can run the test script directly:

       cd test
       ./run-stp-tests
       
    -

    A Software Test Report is stored in HTML and PDF files that are -generated using the HTMLDOC - software.

    +

    A Software Test Report is stored in HTML and PDF files that are + generated using the HTMLDOC + software.

    4 IPP Compliance Tests

    -

    This section describes the tests used to validate the IPP standards -compliance of the CUPS server.

    +

    This section describes the tests used to validate the IPP standards + compliance of the CUPS server.

    4.1 Request Tests

    -

    These tests verify that the CUPS scheduler only accepts valid IPP -requests that start with the attributes-charset and +

    These tests verify that the CUPS scheduler only accepts valid IPP + requests that start with the attributes-charset and attributes-natural-language attributes and also contain a -printer-uri or job-uri attribute.

    +printer-uri or job-uri attribute.

    It also verifies that the CUPS scheduler always responds with attributes-charset and attributes-natural-language - attributes, using default values if they are not provided by the -client.

    + attributes, using default values if they are not provided by the + client.

    4.2 CUPS Printer Operation Tests

    -

    These tests verify that the CUPS printer operations are supported -and function properly. Two printers called Test1 and -Test2 are created, one as a PostScript printer and one as a -raster printer.

    +

    These tests verify that the CUPS printer operations are supported and + function properly. Two printers called Test1 and +Test2 are created, one as a PostScript printer and one as a + raster printer.

    4.3 Job Operation Tests

    -

    These test verify that the CUPS scheduler accepts print jobs for all -supported file formats and that the cancel-job, -hold-job, and resume-job operations work.

    +

    These test verify that the CUPS scheduler accepts print jobs for all + supported file formats and that the cancel-job, +hold-job, and resume-job operations work.

    5 Command Tests

    -

    This section describes the tests used to validate the Berkeley and -System V commands included with CUPS.

    +

    This section describes the tests used to validate the Berkeley and + System V commands included with CUPS.

    5.1 lpadmin

    -

    This test verifies that printers can be added, modified, and -defaulted using the lpadmin command.

    +

    This test verifies that printers can be added, modified, and + defaulted using the lpadmin command.

    5.2 lpc

    -

    This test verifies that the lpc command can show the -current status of all print queues.

    +

    This test verifies that the lpc command can show the + current status of all print queues.

    5.3 lpq

    -

    This test verifies that the lpq command lists any jobs -in the queue.

    +

    This test verifies that the lpq command lists any jobs + in the queue.

    5.4 lpstat

    -

    This test verifies that the lpstat command works with -all reports using the "-t" option.

    +

    This test verifies that the lpstat command works with + all reports using the "-t" option.

    5.5 lp

    -

    This test verifies that the lp command works with both -the default destination and a specific destination.

    +

    This test verifies that the lp command works with both + the default destination and a specific destination.

    5.6 lpr

    -

    This test verifies that the lpr command works with both -the default destination and a specific destination.

    +

    This test verifies that the lpr command works with both + the default destination and a specific destination.

    5.7 lprm

    -

    This test verifies that the lprm command can properly -cancel a job.

    +

    This test verifies that the lprm command can properly + cancel a job.

    5.8 cancel

    -

    This test verifies that the cancel command can properly -cancel a job or all jobs.

    +

    This test verifies that the cancel command can properly + cancel a job or all jobs.

    5.9 lpinfo

    -

    This test verifies that the lpinfo command returns a -list of available printer drivers and devices.

    +

    This test verifies that the lpinfo command returns a + list of available printer drivers and devices.

    A Glossary

    A.1 Terms

    -
    C
    -
    A computer language.
    -
    parallel
    -
    Sending or receiving data more than 1 bit at a time.
    -
    pipe
    -
    A one-way communications channel between two programs.
    -
    serial
    -
    Sending or receiving data 1 bit at a time.
    -
    socket
    -
    A two-way network communications channel.
    +
    C
    +
    A computer language.
    +
    parallel
    +
    Sending or receiving data more than 1 bit at a time.
    +
    pipe
    +
    A one-way communications channel between two programs.
    +
    serial
    +
    Sending or receiving data 1 bit at a time.
    +
    socket
    +
    A two-way network communications channel.

    A.2 Acronyms

    -
    ASCII
    -
    American Standard Code for Information Interchange
    -
    CUPS
    -
    Common UNIX Printing System
    -
    ESC/P
    -
    EPSON Standard Code for Printers
    -
    FTP
    -
    File Transfer Protocol
    -
    HP-GL
    -
    Hewlett-Packard Graphics Language
    -
    HP-PCL
    -
    Hewlett-Packard Page Control Language
    -
    HP-PJL
    -
    Hewlett-Packard Printer Job Language
    -
    IETF
    -
    Internet Engineering Task Force
    -
    IPP
    -
    Internet Printing Protocol
    -
    ISO
    -
    International Standards Organization
    -
    LPD
    -
    Line Printer Daemon
    -
    MIME
    -
    Multimedia Internet Mail Exchange
    -
    PPD
    -
    PostScript Printer Description
    -
    SMB
    -
    Server Message Block
    -
    TFTP
    -
    Trivial File Transfer Protocol
    +
    ASCII
    +
    American Standard Code for Information Interchange
    +
    CUPS
    +
    Common UNIX Printing System
    +
    ESC/P
    +
    EPSON Standard Code for Printers
    +
    FTP
    +
    File Transfer Protocol
    +
    HP-GL
    +
    Hewlett-Packard Graphics Language
    +
    HP-PCL
    +
    Hewlett-Packard Page Control Language
    +
    HP-PJL
    +
    Hewlett-Packard Printer Job Language
    +
    IETF
    +
    Internet Engineering Task Force
    +
    IPP
    +
    Internet Printing Protocol
    +
    ISO
    +
    International Standards Organization
    +
    LPD
    +
    Line Printer Daemon
    +
    MIME
    +
    Multimedia Internet Mail Exchange
    +
    PPD
    +
    PostScript Printer Description
    +
    SMB
    +
    Server Message Block
    +
    TFTP
    +
    Trivial File Transfer Protocol
    diff --git a/doc/stp.pdf b/doc/stp.pdf index 0063718909..2251be5b78 100644 Binary files a/doc/stp.pdf and b/doc/stp.pdf differ diff --git a/doc/sum.html b/doc/sum.html index 576c6c8b05..8f84e624e4 100644 --- a/doc/sum.html +++ b/doc/sum.html @@ -124,24 +124,26 @@ Copyright 1997-2001, All Rights Reserved

    Preface

    -

    This software users manual describes how to use the Common UNIX -Printing SystemTM ("CUPSTM") Version 1.1.7.

    +

    This software users manual describes how to use the Common UNIX + Printing <<<<<<< sum.shtml SystemTM ("CUPSTM") + Version 1.1.7. ======= SystemTM ("CUPSTM") + Version 1.1.13. >>>>>>> 1.29

    System Overview

    -

    CUPS provides a portable printing layer for UNIX®-based operating -systems. It has been developed by Easy -Software Products to promote a standard printing solution for all -UNIX vendors and users. CUPS provides the System V and Berkeley -command-line interfaces.

    -

    CUPS uses the Internet Printing Protocol ("IPP") as the basis for -managing print jobs and queues. The Line Printer Daemon ("LPD") Server -Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are -also supported with reduced functionality. CUPS adds network printer -browsing and PostScript Printer Description ("PPD") based printing -options to support real-world printing under UNIX.

    -

    CUPS also includes a customized version of GNU Ghostscript -(currently based off GNU Ghostscript 5.50) and an image file RIP that -are used to support non-PostScript printers. Sample drivers for HP and -EPSON printers are included that use these filters.

    +

    CUPS provides a portable printing layer for UNIX®-based operating + systems. It has been developed by Easy + Software Products to promote a standard printing solution for all + UNIX vendors and users. CUPS provides the System V and Berkeley + command-line interfaces.

    +

    CUPS uses the Internet Printing Protocol ("IPP") as the basis for + managing print jobs and queues. The Line Printer Daemon ("LPD") Server + Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are + also supported with reduced functionality. CUPS adds network printer + browsing and PostScript Printer Description ("PPD") based printing + options to support real-world printing under UNIX.

    +

    CUPS also includes a customized version of GNU Ghostscript (currently + based off GNU Ghostscript 5.50) and an image file RIP that are used to + support non-PostScript printers. Sample drivers for HP and EPSON + printers are included that use these filters.

    Document Overview

    @@ -155,16 +157,16 @@ EPSON printers are included that use these filters.

  • A - Software License Agreement
  • Notation Conventions

    -

    Various font and syntax conventions are used in this guide. Examples -and their meanings and uses are explained below: +

    Various font and syntax conventions are used in this guide. Examples + and their meanings and uses are explained below:

    ObjectMemory PerDisk Per
    +
    lpstat(1)     - +
    Example   Description
     
    lpstat -
    lpstat(1)
       The names of commands; -the first mention of a command or function in a chapter is followed by -a manual page section number.
       The names of commands; + the first mention of a command or function in a chapter is followed by + a manual page section number.
     
    /var
    /usr/share/cups/data/testprint.ps
        @@ -174,217 +176,217 @@ File and directory names.
    Screen output.
     
    lp -d printer filename ENTER -   Literal user input; special keys like ENTER are +   Literal user input; special keys like ENTER are in ALL CAPS.
     
    12.3   Numbers in the text are -written using the period (.) to indicate the decimal point.
    12.3   Numbers in the text are + written using the period (.) to indicate the decimal point.

    Abbreviations

    - The following abbreviations are used throughout this manual: + The following abbreviations are used throughout this manual:
      -
      kb
      +
      kb
      Kilobytes, or 1024 bytes -
       
      -
      Mb
      +
        +
      Mb
      Megabytes, or 1048576 bytes -
       
      -
      Gb
      +
        +
      Gb
      Gigabytes, or 1073741824 bytes -
       
      +
       

    Other References

      -
      CUPS Software Administrators Manual
      +
      CUPS Software Administrators Manual
      An administration guide for the CUPS software. -
       
      -
      CUPS Software Programmers Manual
      -
      A programmer guide for interfacing with and/or extending the CUPS +
       
      +
      CUPS Software Programmers Manual
      +
      A programmer guide for interfacing with and/or extending the CUPS software. -
       
      +
       

    1 - Printing System Overview

    -

    This chapter provides an overview of how the Common UNIX Printing -System works.

    +

    This chapter provides an overview of how the Common UNIX Printing + System works.

    The Printing Problem

    -

    For years the printing problem has plagued UNIX. Unlike -Microsoft® Windows® or Mac OS, UNIX has no standard interface or system -in place for supporting printers. Among the solutions currently -available, the Berkeley and System V printing systems are the most -prevalent.

    -

    These printing systems support line printers (text only) or -PostScript printers (text and graphics), and with some coaxing they can -be made to support a full range of printers and file formats. However, -because each varient of the UNIX operating system uses a different -printing system than the next developing printer drivers for a wide -range of printers and operating systems is extremely difficult. That -combined with the limited volume of customers for each UNIX varient has -forced most printer vendors to give up supporting UNIX entirely.

    -

    CUPS is designed to eliminate the printing problem. One -common printing system can be used by all UNIX varients to support the -printing needs of users. Printer vendors can use its modular filter -interface to develop a single driver program that supports a wide range -of file formats with little or no effort. Since CUPS provides both the -System V and Berkeley printing commands, users (and applications) can -reap the benefits of this new technology with no changes.

    +

    For years the printing problem has plagued UNIX. Unlike + Microsoft® Windows® or Mac OS, UNIX has no standard interface or system + in place for supporting printers. Among the solutions currently + available, the Berkeley and System V printing systems are the most + prevalent.

    +

    These printing systems support line printers (text only) or + PostScript printers (text and graphics), and with some coaxing they can + be made to support a full range of printers and file formats. However, + because each varient of the UNIX operating system uses a different + printing system than the next developing printer drivers for a wide + range of printers and operating systems is extremely difficult. That + combined with the limited volume of customers for each UNIX varient has + forced most printer vendors to give up supporting UNIX entirely.

    +

    CUPS is designed to eliminate the printing problem. One common + printing system can be used by all UNIX varients to support the + printing needs of users. Printer vendors can use its modular filter + interface to develop a single driver program that supports a wide range + of file formats with little or no effort. Since CUPS provides both the + System V and Berkeley printing commands, users (and applications) can + reap the benefits of this new technology with no changes.

    The Technology

    -

    CUPS is based upon an emerging Internet standard called the Internet -Printing Protocol. IPP has been embraced by dozens of printer and -printer server manufacturers and is supported by Microsoft Windows -2000.

    -

    IPP defines a standard protocol for printing as well as managing -print jobs and printer options like media size, resolution, and so -forth. Like all IP-based protocols, IPP can be used locally or over the -Internet to printers hundreds or thousands of miles away. Unlike other -protocols, however, IPP also supports access control, authentication, -and encryption, making it a much more capable and secure printing -solution than older ones.

    -

    IPP is layered on top of the Hyper-Text Transport Protocol ("HTTP") -which is the basis of web servers on the Internet. This allows users to -view documentation, check status information on a printer or server, -and manage their printers, classes, and jobs using their web browser.

    -

    CUPS provides a complete IPP/1.1 based printing system that provides -Basic, Digest, and local certificate authentication and user, domain, -or IP-based access control. TLS encryption will be available in future -versions of CUPS.

    +

    CUPS is based upon an emerging Internet standard called the Internet + Printing Protocol. IPP has been embraced by dozens of printer and + printer server manufacturers and is supported by Microsoft Windows + 2000.

    +

    IPP defines a standard protocol for printing as well as managing + print jobs and printer options like media size, resolution, and so + forth. Like all IP-based protocols, IPP can be used locally or over the + Internet to printers hundreds or thousands of miles away. Unlike other + protocols, however, IPP also supports access control, authentication, + and encryption, making it a much more capable and secure printing + solution than older ones.

    +

    IPP is layered on top of the Hyper-Text Transport Protocol ("HTTP") + which is the basis of web servers on the Internet. This allows users to + view documentation, check status information on a printer or server, + and manage their printers, classes, and jobs using their web browser.

    +

    CUPS provides a complete IPP/1.1 based printing system that provides + Basic, Digest, and local certificate authentication and user, domain, + or IP-based access control. TLS encryption will be available in future + versions of CUPS.

    Jobs

    -

    Each file or set of files that is submitted for printing is called a -job. Jobs are identified by a unique number starting at 1 and are -assigned to a particular destination, usually a printer. Jobs can also -have options associated with them such as media size, number of copies, -and priority.

    +

    Each file or set of files that is submitted for printing is called a + job. Jobs are identified by a unique number starting at 1 and are + assigned to a particular destination, usually a printer. Jobs can also + have options associated with them such as media size, number of copies, + and priority.

    Classes

    -

    CUPS supports collections of printers known as classes. Jobs -sent to a class are forwarded to the first available printer in the -class.

    +

    CUPS supports collections of printers known as classes. Jobs + sent to a class are forwarded to the first available printer in the + class.

    Filters

    -

    Filters allow a user or application to print many types of files -without extra effort. Print jobs sent to a CUPS server are filtered -before sending them to a printer. Some filters convert job files to -different formats that the printer can understand. Others perform page -selection and ordering tasks.

    -

    CUPS provides filters for printing many types of image files, -HP-GL/2 files, PDF files, and text files. CUPS also supplies PostScript -and image file Raster Image Processor ("RIP") filters that convert -PostScript or image files into bitmaps that can be sent to a raster -printer.

    +

    Filters allow a user or application to print many types of files + without extra effort. Print jobs sent to a CUPS server are filtered + before sending them to a printer. Some filters convert job files to + different formats that the printer can understand. Others perform page + selection and ordering tasks.

    +

    CUPS provides filters for printing many types of image files, HP-GL/2 + files, PDF files, and text files. CUPS also supplies PostScript and + image file Raster Image Processor ("RIP") filters that convert + PostScript or image files into bitmaps that can be sent to a raster + printer.

    Backends

    -

    Backends perform the most important task of all - they send the -filtered print data to the printer.

    -

    CUPS provides backends for printing over parallel, serial, and USB -ports, and over the network via the IPP, JetDirect (AppSocket), and -Line Printer Daemon ("LPD") protocols. Additional backends are -available in network service packages such as the SMB backend included -with the popular SAMBA software.

    -

    Backends are also used to determine the available devices. On -startup each backend is asked for a list of devices it supports, and -any information that is available. This allows the parallel backend to -tell CUPS that an EPSON Stylus Color 600 printer is attached to -parallel port 1, for example.

    +

    Backends perform the most important task of all - they send the + filtered print data to the printer.

    +

    CUPS provides backends for printing over parallel, serial, and USB + ports, and over the network via the IPP, JetDirect (AppSocket), and + Line Printer Daemon ("LPD") protocols. Additional backends are + available in network service packages such as the SMB backend included + with the popular SAMBA software.

    +

    Backends are also used to determine the available devices. On startup + each backend is asked for a list of devices it supports, and any + information that is available. This allows the parallel backend to tell + CUPS that an EPSON Stylus Color 600 printer is attached to parallel + port 1, for example.

    Printer Drivers

    -

    Printer drivers in CUPS consist of one of more filters specific to a -printer. CUPS includes sample printer drivers for Hewlett-Packard -LaserJet and DeskJet printers and EPSON 9-pin, 24-pin, Stylus Color, -and Stylus Photo printers. While these drivers do not generate optimal -output for the different printer models, they do provide basic printing -and demonstrate how you can write your own printer drivers and -incorporate them into CUPS.

    +

    Printer drivers in CUPS consist of one of more filters specific to a + printer. CUPS includes sample printer drivers for Hewlett-Packard + LaserJet and DeskJet printers and EPSON 9-pin, 24-pin, Stylus Color, + and Stylus Photo printers. While these drivers do not generate optimal + output for the different printer models, they do provide basic printing + and demonstrate how you can write your own printer drivers and + incorporate them into CUPS.

    Networking

    -

    Printers and classes on the local system are automatically shared -with other systems on the network. This allows you to setup one system -to print to a printer and use this system as a printer server or spool -host for all of the others. Users may then select a local printer by -name or a remote printer using "name@server".

    -

    CUPS also provides implicit classes, which are collections of -printers and/or classes with the same name. This allows you to setup -multiple servers pointing to the same physical network printer, for -example, so that you aren't relying on a single system for printing. -Because this also works with printer classes, you can setup multiple -servers and printers and never worry about a single point of failure -unless all of the printers and servers go down!

    +

    Printers and classes on the local system are automatically shared + with other systems on the network. This allows you to setup one system + to print to a printer and use this system as a printer server or spool + host for all of the others. Users may then select a local printer by + name or a remote printer using "name@server".

    +

    CUPS also provides implicit classes, which are collections of + printers and/or classes with the same name. This allows you to setup + multiple servers pointing to the same physical network printer, for + example, so that you aren't relying on a single system for printing. + Because this also works with printer classes, you can setup multiple + servers and printers and never worry about a single point of failure + unless all of the printers and servers go down!

    2 - Using the Printing System

    -

    This chapter shows you how to submit, query, and cancel print jobs -to different printers.

    +

    This chapter shows you how to submit, query, and cancel print jobs to + different printers.

    Submitting Files for Printing

    CUPS provides both the System V (lp(1)) and Berkeley ( -lpr(1)) printing commands. Type the following command to print a -file to the default (or only) printer on the system:

    +lpr(1)
    ) printing commands. Type the following command to print a + file to the default (or only) printer on the system:

       lp filename ENTER
       
    -

    or:

    +

    or:

       lpr filename ENTER
       
    -

    CUPS understands many different types of files directly, including -PostScript and image files. This allows you to print from inside your -applications or at the command-line, whichever is most convenient!

    +

    CUPS understands many different types of files directly, including + PostScript and image files. This allows you to print from inside your + applications or at the command-line, whichever is most convenient!

    Choosing a Printer

    -

    Many systems will have more than one printer available to the user. -These printers can be attached to the local system via a parallel, -serial, or USB port, or available over the network.

    -

    Use the lpstat(1) command to see a list of available -printers:

    +

    Many systems will have more than one printer available to the user. + These printers can be attached to the local system via a parallel, + serial, or USB port, or available over the network.

    +

    Use the lpstat(1) command to see a list of available + printers:

       lpstat -p -d ENTER
       
    -

    The -p option specifies that you want to see a list of -printers, and the -d option reports the current system -default printer or class.

    -

    Use the -d option with the lp command to -print to a specific printer:

    +

    The -p option specifies that you want to see a list of + printers, and the -d option reports the current system + default printer or class.

    +

    Use the -d option with the lp command to + print to a specific printer:

       lp -d printer filename ENTER
       
    -

    or the -P option with the lpr command:

    +

    or the -P option with the lpr command:

       lpr -P printer filename ENTER
       

    Setting Printer Options

    -

    For many types of files, the default printer options may be -sufficient for your needs. However, there may be times when you need to -change the options for a particular file you are printing.

    -

    The lp and lpr commands allow you to pass -printer options using the -o option:

    +

    For many types of files, the default printer options may be + sufficient for your needs. However, there may be times when you need to + change the options for a particular file you are printing.

    +

    The lp and lpr commands allow you to pass + printer options using the -o option:

       lp -o landscape -o scaling=75 -o media=A4 filename.jpg
       lpr -o landscape -o scaling=75 -o media=A4 filename.jpg
       
    -

    The available printer options vary depending on the printer. The -standard options are described in Chapter -3, "Standard Printing Options".

    +

    The available printer options vary depending on the printer. The + standard options are described in Chapter + 3, "Standard Printing Options".

    Printing Multiple Copies

    -

    Both the lp and lpr commands have options -for printing more than one copy of a file:

    +

    Both the lp and lpr commands have options + for printing more than one copy of a file:

       lp -n num-copies filename ENTER
       lpr -#num-copies filename ENTER
       
    -

    Copies are normally not collated for you. Use the -o -Collate=True option to get collated copies :

    +

    Copies are normally not collated for you. Use the -o + Collate=True option to get collated copies :

       lp -n num-copies -o Collate=True filename ENTER
      @@ -394,8 +396,8 @@ Collate=True option to get collated copies : 

      Checking the Printer Status from the Command-Line

      -

      The lpstat command can be used to check for jobs that -you have submitted for printing:

      +

      The lpstat command can be used to check for jobs that + you have submitted for printing:

         lpstat ENTER
        @@ -405,7 +407,7 @@ Printer-3 johndoe 372842
         

      The jobs are listed in the order they will be printed. Use the --p option to see which files and printers are active:

      +-p option to see which files and printers are active:

         lpstat -p ENTER
        @@ -414,8 +416,8 @@ printer DeskJet now printing DeskJet-1.
         
      -

      Use the -o and -p options together to show -the jobs and the printers:

      +

      Use the -o and -p options together to show + the jobs and the printers:

         lpstat -o -p ENTER
        @@ -426,37 +428,37 @@ printer DeskJet now printing DeskJet-1.
         

      Checking the Printer Status from the Web

      -

      Since CUPS uses the Internet Printing Protocol, it is also a -fully-functional web server. To use your web browser to monitor the -printers on your system, open the URL:

      +

      Since CUPS uses the Internet Printing Protocol, it is also a + fully-functional web server. To use your web browser to monitor the + printers on your system, open the URL:

      -

      From there you can view the status of classes, jobs, and printers -with the click of a button!

      +

      From there you can view the status of classes, jobs, and printers + with the click of a button!

      Canceling a Print Job

      -

      The cancel(1) and lprm(1) commands cancel -a print job:

      +

      The cancel(1) and lprm(1) commands cancel a + print job:

         cancel job-id ENTER
         lprm job-id ENTER
         
      -

      The job-id is the number that was reported to you by -the lp or lpstat commands.

      -

      3 - Standard Printer -Options

      -

      This chapter describes the standard printer options that are -available when printing with the lp and lpr - commands.

      +

      The job-id is the number that was reported to you by the + lp or lpstat commands.

      +

      3 - Standard Printer + Options

      +

      This chapter describes the standard printer options that are + available when printing with the lp and lpr + commands.

      General Options

      -

      The following options apply when printing all types of files.

      +

      The following options apply when printing all types of files.

      Setting the Orientation

      -

      The -o landscape option will rotate the page 90 degrees -to print in landscape orientation:

      +

      The -o landscape option will rotate the page 90 degrees + to print in landscape orientation:

         lp -o landscape filename ENTER
        @@ -466,8 +468,8 @@ to print in landscape orientation: 

        Selecting the Media Size, Type, and Source

        -

        The -o media=xyz option sets the media size, type, -and/or source:

        +

        The -o media=xyz option sets the media size, type, + and/or source:

           lp -o media=Letter filename ENTER
          @@ -478,31 +480,31 @@ and/or source: 

        -

        The available media sizes, types, and sources depend on the printer, -but most support the following options (case is not significant):

        -
          -
        • Letter - US Letter (8.5x11 inches, or 216x279mm)
        • -
        • Legal - US Legal (8.5x14 inches, or 216x356mm)
        • -
        • A4 - ISO A4 (8.27x11.69 inches, or 210x297mm)
        • -
        • COM10 - US #10 Envelope (9.5x4.125 inches, or - 241x105mm)
        • -
        • DL - ISO DL Envelope (8.66x4.33 inches, or 220x110mm)
        • -
        • Transparency - Transparency media type or source
        • -
        • Upper - Upper paper tray
        • -
        • Lower - Lower paper tray
        • -
        • MultiPurpose - Multi-purpose paper tray
        • -
        • LargeCapacity - Large capacity paper tray
        • -
        -

        The actual options supported are defined in the printer's PPD file -in the PageSize, InputSlot, and -MediaType options.

        +

        The available media sizes, types, and sources depend on the printer, + but most support the following options (case is not significant):

        +
          +
        • Letter - US Letter (8.5x11 inches, or 216x279mm)
        • +
        • Legal - US Legal (8.5x14 inches, or 216x356mm)
        • +
        • A4 - ISO A4 (8.27x11.69 inches, or 210x297mm)
        • +
        • COM10 - US #10 Envelope (9.5x4.125 inches, or + 241x105mm)
        • +
        • DL - ISO DL Envelope (8.66x4.33 inches, or 220x110mm)
        • +
        • Transparency - Transparency media type or source
        • +
        • Upper - Upper paper tray
        • +
        • Lower - Lower paper tray
        • +
        • MultiPurpose - Multi-purpose paper tray
        • +
        • LargeCapacity - Large capacity paper tray
        • +
        +

        The actual options supported are defined in the printer's PPD file in + the PageSize, InputSlot, and MediaType + options.

        Printing On Both Sides of the Paper

        -

        The -o sides=two-sided-short-edge and -o -sides=two-sided-long-edge options will enable duplexing on the -printer, if the printer supports it. The -o -sides=two-sided-short-edge option is suitable for landscape -pages, while the -o sides=two-sided-long-edge option is -suitable for portrait pages:

        +

        The -o sides=two-sided-short-edge and -o + sides=two-sided-long-edge options will enable duplexing on the + printer, if the printer supports it. The -o + sides=two-sided-short-edge option is suitable for landscape + pages, while the -o sides=two-sided-long-edge option is + suitable for portrait pages:

           lp -o sides=two-sided-short-edge filename ENTER
          @@ -510,7 +512,7 @@ suitable for portrait pages: 

          lpr -o sides=two-sided-long-edge filename ENTER
        -

        The default is to print single-sided:

        +

        The default is to print single-sided:

           lp -o sides=one-sided filename ENTER
          @@ -518,10 +520,10 @@ suitable for portrait pages: 

        Banner Options

        -

        The following options apply when printing all types of files.

        +

        The following options apply when printing all types of files.

        Selecting the Banner Page(s)

        -

        The -o jobsheets=start,end option sets the banner -page(s) to use for a job:

        +

        The -o jobsheets=start,end option sets the banner + page(s) to use for a job:

           lp -o job-sheets=none filename ENTER
          @@ -529,31 +531,31 @@ page(s) to use for a job: 

          lpr -o job-sheets=classified,classified filename ENTER
        -

        If only one banner file is specified, it will be printed before the -files in the job. If a second banner file is specified, it is printed -after the files in the job.

        -

        The available banner pages depend on the local system configuration; -CUPS includes the following banner files:

        -
          -
        • none - Do not produce a banner page.
        • -
        • classified - A banner page with a "classified" label -at the top and bottom.
        • -
        • confidential - A banner page with a "confidential" -label at the top and bottom.
        • -
        • secret - A banner page with a "secret" label at the -top and bottom.
        • -
        • standard - A banner page with no label at the top and -bottom.
        • -
        • topsecret - A banner page with a "top secret" label -at the top and bottom.
        • -
        • unclassified - A banner page with an "unclassified" -label at the top and bottom.
        • +

          If only one banner file is specified, it will be printed before the + files in the job. If a second banner file is specified, it is printed + after the files in the job.

          +

          The available banner pages depend on the local system configuration; + CUPS includes the following banner files:

          +
            +
          • none - Do not produce a banner page.
          • +
          • classified - A banner page with a "classified" label at + the top and bottom.
          • +
          • confidential - A banner page with a "confidential" + label at the top and bottom.
          • +
          • secret - A banner page with a "secret" label at the top + and bottom.
          • +
          • standard - A banner page with no label at the top and + bottom.
          • +
          • topsecret - A banner page with a "top secret" label at + the top and bottom.
          • +
          • unclassified - A banner page with an "unclassified" + label at the top and bottom.

          Document Options

          -

          The following options apply when printing all types of files.

          +

          The following options apply when printing all types of files.

          Selecting a Range of Pages

          -

          The -o page-ranges=pages option selects a range of -pages for printing:

          +

          The -o page-ranges=pages option selects a range of pages + for printing:

             lp -o page-ranges=1 filename ENTER
            @@ -562,14 +564,14 @@ pages for printing: 

            lpr -o page-ranges=1-4,7,9-12 filename ENTER
          -

          As shown above, the pages value can be a single page, a -range of pages, or a collection of page numbers and ranges separated by -commas. The pages will always be printed in ascending order, regardless -of the order of the pages in the page-ranges option.

          -

          The default is to print all pages.

          +

          As shown above, the pages value can be a single page, a + range of pages, or a collection of page numbers and ranges separated by + commas. The pages will always be printed in ascending order, regardless + of the order of the pages in the page-ranges option.

          +

          The default is to print all pages.

          Selecting Even or Odd Pages

          -

          Use the -o page-set=set option to select the even or -odd pages:

          +

          Use the -o page-set=set option to select the even or odd + pages:

             lp -o page-set=odd filename ENTER
            @@ -577,11 +579,11 @@ odd pages: 

            lpr -o page-set=even filename ENTER
          -

          The default is to print all pages.

          +

          The default is to print all pages.

          N-Up Printing

          -

          The -o number-up=value option selects N-Up printing. - N-Up printing places multiple document pages on a single printed page. - CUPS supports 1-Up, 2-Up, and 4-Up formats:

          +

          The -o number-up=value option selects N-Up printing. + N-Up printing places multiple document pages on a single printed page. + CUPS supports 1-Up, 2-Up, and 4-Up formats:

             lp -o number-up=1 filename ENTER
            @@ -590,34 +592,34 @@ odd pages: 

            lpr -o number-up=4 filename ENTER
          -

          The default format is 1-Up.

          +

          The default format is 1-Up.

          Setting the Brightness

          -

          You can control the overall brightness of the printed output using -the -o brightness=percent option:

          +

          You can control the overall brightness of the printed output using + the -o brightness=percent option:

             lp -o brightness=120 filename ENTER
             lpr -o brightness=120 filename ENTER
             
          -

          Values greater than 100 will lighten the print, while values less -than 100 will darken it.

          +

          Values greater than 100 will lighten the print, while values less + than 100 will darken it.

          Setting the Gamma Correction

          -

          You can control the overall gamma correction of the printed output -using the -o gamma=value option:

          +

          You can control the overall gamma correction of the printed output + using the -o gamma=value option:

             lp -o gamma=1700 filename ENTER
             lpr -o gamma=1700 filename ENTER
             
          -

          Values greater than 1000 will lighten the print, while values less -than 1000 will darken it. The default gamma is 1000.

          +

          Values greater than 1000 will lighten the print, while values less + than 1000 will darken it. The default gamma is 1000.

          Text Options

          -

          The following options apply when printing text files.

          +

          The following options apply when printing text files.

          Setting the Number of Characters Per Inch

          -

          The -o cpi=value option sets the number of characters -per inch:

          +

          The -o cpi=value option sets the number of characters + per inch:

             lp -o cpi=10 filename ENTER
            @@ -625,32 +627,32 @@ per inch: 

            lpr -o cpi=17 filename ENTER
          -

          The default characters per inch is 10.

          +

          The default characters per inch is 10.

          Setting the Number of Lines Per Inch

          -

          The -o lpi=value option sets the number of lines per -inch:

          +

          The -o lpi=value option sets the number of lines per + inch:

             lp -o lpi=6 filename ENTER
             lpr -o lpi=8 filename ENTER
             
          -

          The default lines per inch is 6.

          +

          The default lines per inch is 6.

          Setting the Number of Columns

          -

          The -o columns=value option sets the number of text -columns:

          +

          The -o columns=value option sets the number of text + columns:

             lp -o columns=2 filename ENTER
             lpr -o columns=3 filename ENTER
             
          -

          The default number of columns is 1.

          +

          The default number of columns is 1.

          Setting the Page Margins

          -

          Normally the page margins are set to the hard limits of the printer. -Use the -o page-left=value, -o page-right=value +

          Normally the page margins are set to the hard limits of the printer. + Use the -o page-left=value, -o page-right=value , -o page-top=value, and -o page-bottom=value - options to adjust the page margins:

          + options to adjust the page margins:

             lp -o page-left=value filename ENTER
            @@ -660,13 +662,13 @@ Use the -o page-left=value, -o page-right=value
             lpr -o page-bottom=value filename ENTER
             
          -

          The value argument is the margin in points; each point -is 1/72 inch or 0.35mm.

          +

          The value argument is the margin in points; each point + is 1/72 inch or 0.35mm.

          Pretty Printing

          -

          The -o prettyprint option puts a header at the top of -each page with the page number, job title (usually the filename), and -the date. Also, C and C++ keywords are highlighted, and comment lines -are italicized:

          +

          The -o prettyprint option puts a header at the top of + each page with the page number, job title (usually the filename), and + the date. Also, C and C++ keywords are highlighted, and comment lines + are italicized:

             lp -o prettyprint filename ENTER
            @@ -674,49 +676,57 @@ are italicized: 

          Image Options

          -

          The following options apply when printing image files.

          +

          The following options apply when printing image files.

          Positioning the Image

          -

          The -o position=name option specifies the position of -the image on the page:

          -
            -
          • center - Center the image on the page (default)
          • -
          • top - Print the image centered at the top of the page
          • -
          • left - Print the image centered on the left of page
          • -
          • right - Print the image centered on the right of the -page
          • -
          • top-left - Print the image at the top left corner of - the page
          • -
          • top-right - Print the image at the top right corner of - the page
          • -
          • bottom - Print the image centered at the bottom of - the page
          • -
          • bottom-left - Print the image at the bottom left - corner of the page
          • -
          • bottom-right - Print the image at the bottom right - corner of the page
          • +

            The -o position=name option specifies the position of + the image on the page:

            +
              +
            • center - Center the image on the page (default)
            • +
            • top - Print the image centered at the top of the page
            • +
            • left - Print the image centered on the left of page
            • +
            • right - Print the image centered on the right of the + page
            • +
            • top-left - Print the image at the top left corner of + the page
            • +
            • top-right - Print the image at the top right corner of + the page
            • +
            • bottom - Print the image centered at the bottom of the + page
            • +
            • bottom-left - Print the image at the bottom left corner + of the page
            • +
            • bottom-right - Print the image at the bottom right + corner of the page

            Scaling the Image

            -

            The -o scaling=percent and -o ppi=value - options change the size of a printed image:

            +

            The -o scaling=percent, -o ppi=value, and +-o natural-scaling=percent options change the size of a printed + image:

               lp -o scaling=percent filename ENTER
               lp -o ppi=value filename ENTER
              -lpr -o ppi=value filename ENTER
              +lpr -o natural-scaling=percent filename ENTER
               
            -

            The percent value is a number from 1 to 800 specifying -the size in relation to the page (not the image.) A scaling of -100 percent will fill the page as completely as the image aspect ratio -allows. A scaling of 200 percent will print on up to 4 pages.

            -

            The ppi value is a number from 1 to 1200 specifying the -resolution of the image in pixels per inch. An image that is 3000x2400 -pixels will print 10x8 inches at 300 pixels per inch, for example. If -the specified resolution makes the image larger than the page, multiple -pages will be printed to satisfy the request.

            +

            The scaling=percent value is a number from 1 to 800 + specifying the size in relation to the page (not the image.) A + scaling of 100 percent will fill the page as completely as the image + aspect ratio allows. A scaling of 200 percent will print on up to 4 + pages.

            +

            The ppi=value value is a number from 1 to 1200 + specifying the resolution of the image in pixels per inch. An image + that is 3000x2400 pixels will print 10x8 inches at 300 pixels per inch, + for example. If the specified resolution makes the image larger than + the page, multiple pages will be printed to satisfy the request.

            +

            The natural-scaling=percent value is a number from 1 to + 800 specifying the size in relation to the natural image size. A + scaling of 100 percent will print the image at its natural size, while + a scaling of 50 percent will print the image at half its natural size. + If the specified scaling makes the image larger than the page, multiple + pages will be printed to satisfy the request.

            Adjusting the Hue (Tint) of an Image

            -

            The -o hue=value option will adjust the hue of the -printed image, much like the tint control on your television:

            +

            The -o hue=value option will adjust the hue of the + printed image, much like the tint control on your television:

               lp -o hue=value filename ENTER
              @@ -725,9 +735,9 @@ printed image, much like the tint control on your television: 

            -

            The value argument is a number from -360 to 360 and -represents the color hue rotation. The following table summarizes the -change you'll see with different colors: +

            The value argument is a number from -360 to 360 and + represents the color hue rotation. The following table summarizes the + change you'll see with different colors:

            @@ -740,84 +750,83 @@ change you'll see with different colors:
            Originalhue=-45hue=45

            -

            The default hue adjustment is 0.

            +

            The default hue adjustment is 0.

            Adjusting the Saturation (Color) of an Image

            -

            The -o saturation=percent option adjusts the saturation -of the colors in an image, much like the color knob on your television:

            +

            The -o saturation=percent option adjusts the saturation + of the colors in an image, much like the color knob on your television:

               lp -o saturation=percent filename ENTER
               lpr -o saturation=percent filename ENTER
               
            -

            The percent argument specifies the color saturation -from 0 to 200. A color saturation of 0 produces a black-and-white -print, while a value of 200 will make the colors extremely intense.

            -

            The default saturation is 100. +

            The percent argument specifies the color saturation from + 0 to 200. A color saturation of 0 produces a black-and-white print, + while a value of 200 will make the colors extremely intense.

            +

            The default saturation is 100.

            HP-GL/2 Options

            -

            The following options apply to HP-GL/2 files.

            +

            The following options apply to HP-GL/2 files.

            Printing in Black

            -

            The -o blackplot option specifies that all pens should -plot in black:

            +

            The -o blackplot option specifies that all pens should + plot in black:

               lp -o blackplot filename ENTER
               lpr -o blackplot filename ENTER
               
            -

            The default is to use the colors defined in the plot file or the -standard pen colors defined in the HP-GL/2 reference manual from -Hewlett Packard.

            +

            The default is to use the colors defined in the plot file or the + standard pen colors defined in the HP-GL/2 reference manual from + Hewlett Packard.

            Fitting the Plot on the Page

            -

            The -o fitplot option specifies that the plot should be -scaled to fit on the page:

            +

            The -o fitplot option specifies that the plot should be + scaled to fit on the page:

               lp -o fitplot filename ENTER
               lpr -o fitplot filename ENTER
               
            -

            The default is to use the absolute distances specified in the plot -file. +

            The default is to use the absolute distances specified in the plot + file.

            NOTE: -

            This feature depends upon an accurate plot size (PS) - command in the HP-GL/2 file. If no plot size is given in the file - than the HP-GL/2 filter assumes the plot is ANSI E size.

            +

            This feature depends upon an accurate plot size (PS) + command in the HP-GL/2 file. If no plot size is given in the file than + the HP-GL/2 filter assumes the plot is ANSI E size.

            Setting the Default Pen Width

            -

            The -o penwidth=value option specifies the default pen -width for HP-GL/2 files:

            +

            The -o penwidth=value option specifies the default pen + width for HP-GL/2 files:

               lp -o penwidth=value filename ENTER
               lpr -o penwidth=value filename ENTER
               
            -

            The pen width value specifies the pen width in -micrometers. The default value of 1000 produces lines that are 1 -millimeter in width. Specifying a pen width of 0 produces lines that -are exactly 1 pixel wide. +

            The pen width value specifies the pen width in + micrometers. The default value of 1000 produces lines that are 1 + millimeter in width. Specifying a pen width of 0 produces lines that + are exactly 1 pixel wide.

            NOTE: -

            This option is ignored when the pen widths are set in the plot -file.

            +

            This option is ignored when the pen widths are set in the plot file.

            Raw or Unfiltered Output

            -

            The -o raw option allows you to send files directly to -a printer without filtering. This is sometimes required when printing -from applications that provide their own "printer drivers" for your -printer:

            +

            The -o raw option allows you to send files directly to a + printer without filtering. This is sometimes required when printing + from applications that provide their own "printer drivers" for your + printer:

               lp -o raw filename ENTER
              @@ -825,37 +834,37 @@ printer: 

            The -l option can also be used with the lpr - command to send files directly to a printer:

            + command to send files directly to a printer:

               lpr -l filename ENTER
               
            -

            4 - Saving Printer Options -and Defaults

            -

            This chapter describes how to save printer options for your printer -and set your own default printer.

            +

            4 - Saving Printer Options + and Defaults

            +

            This chapter describes how to save printer options for your printer + and set your own default printer.

            Printer Options

            -

            Each printer supports a large number of options, which you learned -about in Chapter 3, "Standard Printer -Options". Rather than specifying these options each time you print -a file, CUPS allows you to save them as "default" options for the -printer.

            -

            The lpoptions(1) command saves the options for your -printers. Like the lp and lpr commands, it -accepts printer options using the -o argument:

            +

            Each printer supports a large number of options, which you learned + about in Chapter 3, "Standard Printer + Options". Rather than specifying these options each time you print + a file, CUPS allows you to save them as "default" options for the + printer.

            +

            The lpoptions(1) command saves the options for your + printers. Like the lp and lpr commands, it + accepts printer options using the -o argument:

               lpoptions -o media=A4 -o sides=two-sided-long-edge ENTER
               lpoptions -o media=Legal -o scaling=100 ENTER
               
            -

            Once saved, any lp or lpr command will use -them when you print.

            +

            Once saved, any lp or lpr command will use + them when you print.

            Setting Options for a Specific Printer

            -

            The previous example shows how to set the options for the default -printer. The -p printer option specifies the options are -for another printer:

            +

            The previous example shows how to set the options for the default + printer. The -p printer option specifies the options are + for another printer:

               lpoptions -p laserjet -o media=A4 -o sides=two-sided-long-edge ENTER
              @@ -863,8 +872,8 @@ for another printer: 

            Viewing the Current Defaults

            -

            The lpoptions command can also be used to show the -current options by not specifying any new options on the command-line:

            +

            The lpoptions command can also be used to show the + current options by not specifying any new options on the command-line:

               lpoptions ENTER
              @@ -874,28 +883,28 @@ media=Legal scaling=100
               

            Setting the Default Printer

            -

            The administrator normally will set a system-wide default printer -that is normally used as the default printer by everyone. Use the --d printer option to set your own default printer:

            +

            The administrator normally will set a system-wide default printer + that is normally used as the default printer by everyone. Use the +-d printer option to set your own default printer:

               lpoptions -d deskjet ENTER
               

            The printer can be local (deskjet) or remote ( -deskjet@server).

            +deskjet@server).

            Printer Instances

            -

            Besides setting options for each print queue, CUPS supports -printer instances which allow you to define several different sets -of options for each printer. You specify a printer instance using the -slash (/) character:

            +

            Besides setting options for each print queue, CUPS supports + printer instances which allow you to define several different sets + of options for each printer. You specify a printer instance using the + slash (/) character:

               lpoptions -p laserjet/duplex -o sides=two-sided-long-edge ENTER
               lpoptions -p laserjet/legal -o media=Legal ENTER
               
            -

            The lp and lpr commands also understand this notation:

            +

            The lp and lpr commands also understand this notation:

               lp -d laserjet/duplex filename ENTER
              @@ -903,8 +912,8 @@ slash (/) character: 

            Removing Instances

            -

            Use the -x printer/instance option to remove a printer -instance that you no longer need:

            +

            Use the -x printer/instance option to remove a printer + instance that you no longer need:

               lpoptions -x laserjet ENTER
              @@ -912,86 +921,85 @@ instance that you no longer need: 

              lpoptions -x laserjet/legal ENTER
            -

            The -x option only removes the default options for that -printer and instance; the original print queue will remain until -deleted with the lpadmin(8) command by the administrator.

            +

            The -x option only removes the default options for that + printer and instance; the original print queue will remain until + deleted with the lpadmin(8) command by the administrator.

            A - Software License Agreement

            -

            Common UNIX Printing System License -Agreement

            +

            Common UNIX Printing System License + Agreement

            Copyright 1997-2001 by Easy Software Products
            44141 AIRPORT VIEW DR STE 204
            HOLLYWOOD, MARYLAND 20636-3111 USA

            Voice: +1.301.373.9600 -
            Email: cups-info@cups.org -
            WWW: http://www.cups.org

            +
            Email: cups-info@cups.org +
            WWW: http://www.cups.org

            Introduction

            -

            The Common UNIX Printing SystemTM, ("CUPSTM"), -is provided under the GNU General Public License ("GPL") and GNU -Library General Public License ("LGPL"), Version 2. A copy of these -licenses follow this introduction.

            -

            The GNU LGPL applies to the CUPS API library, located in the "cups" -subdirectory of the CUPS source distribution and in the -"/usr/include/cups" directory and "libcups.a", "libcups.sl", or -"libcups.so" files in the binary distributions.

            -

            The GNU GPL applies to the remainder of the CUPS distribution, -including the "pstoraster" filter which is based upon GNU Ghostscript -5.50 and the "pdftops" filter which is based upon Xpdf 0.90.

            -

            For those not familiar with the GNU GPL, the license basically -allows you to:

            -
              -
            • Use the CUPS software at no charge.
            • -
            • Distribute verbatim copies of the software in source or binary -form.
            • -
            • Sell verbatim copies of the software for a media fee, or sell -support for the software.
            • -
            • Distribute or sell printer drivers and filters that use CUPS so -long as source code is made available under the GPL.
            • -
            -

            What this license does not allow you to do is make changes or -add features to CUPS and then sell a binary distribution without source -code. You must provide source for any new drivers, changes, or -additions to the software, and all code must be provided under the GPL -or LGPL as appropriate.

            -

            The GNU LGPL relaxes the "link-to" restriction, allowing you to -develop applications that use the CUPS API library under other licenses -and/or conditions as appropriate for your application.

            +

            The Common UNIX Printing SystemTM, ("CUPSTM"), + is provided under the GNU General Public License ("GPL") and GNU + Library General Public License ("LGPL"), Version 2. A copy of these + licenses follow this introduction.

            +

            The GNU LGPL applies to the CUPS API library, located in the "cups" + subdirectory of the CUPS source distribution and in the + "/usr/include/cups" directory and "libcups.a", "libcups_s.a", + "libcups.sl", or "libcups.so" files in the binary distributions.

            +

            The GNU GPL applies to the remainder of the CUPS distribution, + including the "pstoraster" filter which is based upon GNU Ghostscript + 5.50 and the "pdftops" filter which is based upon Xpdf 0.93a.

            +

            For those not familiar with the GNU GPL, the license basically allows + you to:

            +
              +
            • Use the CUPS software at no charge.
            • +
            • Distribute verbatim copies of the software in source or binary form.
            • +
            • Sell verbatim copies of the software for a media fee, or sell + support for the software.
            • +
            • Distribute or sell printer drivers and filters that use CUPS so long + as source code is made available under the GPL.
            • +
            +

            What this license does not allow you to do is make changes or + add features to CUPS and then sell a binary distribution without source + code. You must provide source for any new drivers, changes, or + additions to the software, and all code must be provided under the GPL + or LGPL as appropriate.

            +

            The GNU LGPL relaxes the "link-to" restriction, allowing you to + develop applications that use the CUPS API library under other licenses + and/or conditions as appropriate for your application.

            Trademarks

            -

            Easy Software Products has trademarked the Common UNIX Printing -System, CUPS, and CUPS logo. These names and logos may be used freely -in any direct port or binary distribution of CUPS. To use them in -derivative products, please contract Easy Software Products for written -permission. Our intention is to protect the value of these trademarks -and ensure that any derivative product meets the same high-quality -standards as the original.

            +

            Easy Software Products has trademarked the Common UNIX Printing + System, CUPS, and CUPS logo. These names and logos may be used freely + in any direct port or binary distribution of CUPS. To use them in + derivative products, please contract Easy Software Products for written + permission. Our intention is to protect the value of these trademarks + and ensure that any derivative product meets the same high-quality + standards as the original.

            Binary Distribution Rights

            -

            Easy Software Products also sells rights to the CUPS source code -under a binary distribution license for vendors that are unable to -release source code for their drivers, additions, and modifications to -CUPS under the GNU GPL and LGPL. For information please contact us at -the address shown above.

            -

            The Common UNIX Printing System provides a "pstoraster" filter that -utilizes the GNU GhostScript 5.50 core to convert PostScript files into -a stream of raster images. For binary distribution licensing of this -software, please contact:

            Miles Jones +

            Easy Software Products also sells rights to the CUPS source code + under a binary distribution license for vendors that are unable to + release source code for their drivers, additions, and modifications to + CUPS under the GNU GPL and LGPL. For information please contact us at + the address shown above.

            +

            The Common UNIX Printing System provides a "pstoraster" filter that + utilizes the GNU GhostScript 5.50 core to convert PostScript files into + a stream of raster images. For binary distribution licensing of this + software, please contact:

            Miles Jones
            Director of Marketing
            Artifex Software Inc.
            454 Las Gallinas Ave., Suite 108
            San Rafael, CA 94903 USA
            Voice: +1.415.492.9861
            Fax: +1.415.492.9862 -
            EMail: info@arsoft.com
            +
            EMail: info@arsoft.com

            -

            The "pdftops" filter is based on the Xpdf 0.90 software. For binary -distribution licensing of this software, please contact:

            +

            The "pdftops" filter is based on the Xpdf 0.93a software. For binary + distribution licensing of this software, please contact:

            Derek B. Noonburg -
            Email: derekn@foolabs.com -
            WWW: -http://www.foolabs.com/xpdf/

            +
            Email: derekn@foolabs.com +
            WWW: + http://www.foolabs.com/xpdf/

            Support

            -

            Easy Software Products sells software support for CUPS as well as a -commercial printing product based on CUPS called ESP Print Pro. You can -find out more at our web site:

            +

            Easy Software Products sells software support for CUPS as well as a + commercial printing product based on CUPS called ESP Print Pro. You can + find out more at our web site:

               http://www.easysw.com
              @@ -1000,7 +1008,7 @@ find out more at our web site: 

              GNU GENERAL PUBLIC LICENSE

              -

              Version 2, June 1991

              +

              Version 2, June 1991

               Copyright 1989, 1991 Free Software Foundation, Inc.
               59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
              @@ -1012,252 +1020,250 @@ copies of this license document, but changing it is not allowed.
               
               

              Preamble

              -

              The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too.

              -

              When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it in -new free programs; and that you know you can do these things.

              -

              To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it.

              -

              For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights.

              -

              We protect your rights with two steps: (1) copyright the software, -and (2) offer you this license which gives you legal permission to -copy, distribute and/or modify the software.

              -

              Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, -we want its recipients to know that what they have is not the original, -so that any problems introduced by others will not reflect on the -original authors' reputations.

              -

              Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all.

              -

              The precise terms and conditions for copying, distribution and -modification follow.

              +

              The licenses for most software are designed to take away your freedom + to share and change it. By contrast, the GNU General Public License is + intended to guarantee your freedom to share and change free + software--to make sure the software is free for all its users. This + General Public License applies to most of the Free Software + Foundation's software and to any other program whose authors commit to + using it. (Some other Free Software Foundation software is covered by + the GNU Library General Public License instead.) You can apply it to + your programs, too.

              +

              When we speak of free software, we are referring to freedom, not + price. Our General Public Licenses are designed to make sure that you + have the freedom to distribute copies of free software (and charge for + this service if you wish), that you receive source code or can get it + if you want it, that you can change the software or use pieces of it in + new free programs; and that you know you can do these things.

              +

              To protect your rights, we need to make restrictions that forbid + anyone to deny you these rights or to ask you to surrender the rights. + These restrictions translate to certain responsibilities for you if you + distribute copies of the software, or if you modify it.

              +

              For example, if you distribute copies of such a program, whether + gratis or for a fee, you must give the recipients all the rights that + you have. You must make sure that they, too, receive or can get the + source code. And you must show them these terms so they know their + rights.

              +

              We protect your rights with two steps: (1) copyright the software, + and (2) offer you this license which gives you legal permission to + copy, distribute and/or modify the software.

              +

              Also, for each author's protection and ours, we want to make certain + that everyone understands that there is no warranty for this free + software. If the software is modified by someone else and passed on, we + want its recipients to know that what they have is not the original, so + that any problems introduced by others will not reflect on the original + authors' reputations.

              +

              Finally, any free program is threatened constantly by software + patents. We wish to avoid the danger that redistributors of a free + program will individually obtain patent licenses, in effect making the + program proprietary. To prevent this, we have made it clear that any + patent must be licensed for everyone's free use or not licensed at all.

              +

              The precise terms and conditions for copying, distribution and + modification follow.

              GNU GENERAL PUBLIC LICENSE
              TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

                -
              1. This License applies to any program or other work which contains a -notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you".
              2. -

                Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the Program -(independent of having been made by running the Program). Whether that -is true depends on what the Program does.

                -
              3. You may copy and distribute verbatim copies of the Program's source -code as you receive it, in any medium, provided that you conspicuously -and appropriately publish on each copy an appropriate copyright notice -and disclaimer of warranty; keep intact all the notices that refer to -this License and to the absence of any warranty; and give any other -recipients of the Program a copy of this License along with the -Program.
              4. -

                You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee.

                -
              5. You may modify your copy or copies of the Program or any portion of -it, thus forming a work based on the Program, and copy and distribute -such modifications or work under the terms of Section 1 above, provided -that you also meet all of these conditions: +
              6. This License applies to any program or other work which contains a + notice placed by the copyright holder saying it may be distributed + under the terms of this General Public License. The "Program", below, + refers to any such program or work, and a "work based on the Program" + means either the Program or any derivative work under copyright law: + that is to say, a work containing the Program or a portion of it, + either verbatim or with modifications and/or translated into another + language. (Hereinafter, translation is included without limitation in + the term "modification".) Each licensee is addressed as "you".
              7. +

                Activities other than copying, distribution and modification are not + covered by this License; they are outside its scope. The act of running + the Program is not restricted, and the output from the Program is + covered only if its contents constitute a work based on the Program + (independent of having been made by running the Program). Whether that + is true depends on what the Program does.

                +
              8. You may copy and distribute verbatim copies of the Program's source + code as you receive it, in any medium, provided that you conspicuously + and appropriately publish on each copy an appropriate copyright notice + and disclaimer of warranty; keep intact all the notices that refer to + this License and to the absence of any warranty; and give any other + recipients of the Program a copy of this License along with the + Program.
              9. +

                You may charge a fee for the physical act of transferring a copy, and + you may at your option offer warranty protection in exchange for a fee.

                +
              10. You may modify your copy or copies of the Program or any portion of + it, thus forming a work based on the Program, and copy and distribute + such modifications or work under the terms of Section 1 above, provided + that you also meet all of these conditions:
                  -
                1. You must cause the modified files to carry prominent notices -stating that you changed the files and the date of any change.
                2. -
                3. You must cause any work that you distribute or publish, that in -whole or in part contains or is derived from the Program or any part -thereof, to be licensed as a whole at no charge to all third parties -under the terms of this License.
                4. -
                5. if the modified program normally reads commands interactively when -run, you must cause it, when started running for such interactive use -in the most ordinary way, to print or display an announcement including -an appropriate copyright notice and a notice that there is no warranty -(or else, saying that you provide a warranty) and that users may -redistribute the program under these conditions, and telling the user -how to view a copy of this License. (Exception: if the Program itself -is interactive but does not normally print such an announcement, your -work based on the Program is not required to print an announcement.)
                6. +
                7. You must cause the modified files to carry prominent notices stating + that you changed the files and the date of any change.
                8. +
                9. You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any part + thereof, to be licensed as a whole at no charge to all third parties + under the terms of this License.
                10. +
                11. if the modified program normally reads commands interactively when + run, you must cause it, when started running for such interactive use + in the most ordinary way, to print or display an announcement including + an appropriate copyright notice and a notice that there is no warranty + (or else, saying that you provide a warranty) and that users may + redistribute the program under these conditions, and telling the user + how to view a copy of this License. (Exception: if the Program itself + is interactive but does not normally print such an announcement, your + work based on the Program is not required to print an announcement.)
              11. -

                These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it.

                -

                Thus, it is not the intent of this section to claim rights or -contest your rights to work written entirely by you; rather, the intent -is to exercise the right to control the distribution of derivative or -collective works based on the Program.

                -

                In addition, mere aggregation of another work not based on the -Program with the Program (or with a work based on the Program) on a -volume of a storage or distribution medium does not bring the other -work under the scope of this License.

                -
              12. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: +

                These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the Program, + and can be reasonably considered independent and separate works in + themselves, then this License, and its terms, do not apply to those + sections when you distribute them as separate works. But when you + distribute the same sections as part of a whole which is a work based + on the Program, the distribution of the whole must be on the terms of + this License, whose permissions for other licensees extend to the + entire whole, and thus to each and every part regardless of who wrote + it.

                +

                Thus, it is not the intent of this section to claim rights or contest + your rights to work written entirely by you; rather, the intent is to + exercise the right to control the distribution of derivative or + collective works based on the Program.

                +

                In addition, mere aggregation of another work not based on the + Program with the Program (or with a work based on the Program) on a + volume of a storage or distribution medium does not bring the other + work under the scope of this License.

                +
              13. You may copy and distribute the Program (or a work based on it, + under Section 2) in object code or executable form under the terms of + Sections 1 and 2 above provided that you also do one of the following:
                  -
                1. Accompany it with the complete corresponding machine-readable -source code, which must be distributed under the terms of Sections 1 -and 2 above on a medium customarily used for software interchange; or,
                2. -
                3. Accompany it with a written offer, valid for at least three years, -to give any third party, for a charge no more than your cost of -physically performing source distribution, a complete machine-readable -copy of the corresponding source code, to be distributed under the -terms of Sections 1 and 2 above on a medium customarily used for -software interchange; or,
                4. -
                5. Accompany it with the information you received as to the offer to -distribute corresponding source code. (This alternative is allowed -only for noncommercial distribution and only if you received the -program in object code or executable form with such an offer, in accord -with Subsection b above.)
                6. +
                7. Accompany it with the complete corresponding machine-readable source + code, which must be distributed under the terms of Sections 1 and 2 + above on a medium customarily used for software interchange; or,
                8. +
                9. Accompany it with a written offer, valid for at least three years, + to give any third party, for a charge no more than your cost of + physically performing source distribution, a complete machine-readable + copy of the corresponding source code, to be distributed under the + terms of Sections 1 and 2 above on a medium customarily used for + software interchange; or,
                10. +
                11. Accompany it with the information you received as to the offer to + distribute corresponding source code. (This alternative is allowed only + for noncommercial distribution and only if you received the program in + object code or executable form with such an offer, in accord with + Subsection b above.)
              14. -

                The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to control -compilation and installation of the executable. However, as a special -exception, the source code distributed need not include anything that -is normally distributed (in either source or binary form) with the -major components (compiler, kernel, and so on) of the operating system -on which the executable runs, unless that component itself accompanies -the executable.

                -

                If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent access -to copy the source code from the same place counts as distribution of -the source code, even though third parties are not compelled to copy -the source along with the object code.

                -
              15. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt otherwise -to copy, modify, sublicense or distribute the Program is void, and will -automatically terminate your rights under this License. However, -parties who have received copies, or rights, from you under this -License will not have their licenses terminated so long as such parties -remain in full compliance.
              16. -
              17. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying the -Program or works based on it.
              18. -
              19. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License.
              20. -
              21. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program.
              22. -

                If any portion of this section is held invalid or unenforceable -under any particular circumstance, the balance of the section is -intended to apply and the section as a whole is intended to apply in -other circumstances.

                -

                It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice.

                -

                This section is intended to make thoroughly clear what is believed -to be a consequence of the rest of this License.

                -
              23. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License may -add an explicit geographical distribution limitation excluding those -countries, so that distribution is permitted only in or among countries -not thus excluded. In such case, this License incorporates the -limitation as if written in the body of this License.
              24. -
              25. The Free Software Foundation may publish revised and/or new -versions of the General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns.
              26. -

                Each version is given a distinguishing version number. If the -Program specifies a version number of this License which applies to it -and "any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Program does not specify a -version number of this License, you may choose any version ever -published by the Free Software Foundation.

                -
              27. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the -author to ask for permission. For software which is copyrighted by the -Free Software Foundation, write to the Free Software Foundation; we -sometimes make exceptions for this. Our decision will be guided by the -two goals of preserving the free status of all derivatives of our free -software and of promoting the sharing and reuse of software generally.
              28. +

                The source code for a work means the preferred form of the work for + making modifications to it. For an executable work, complete source + code means all the source code for all modules it contains, plus any + associated interface definition files, plus the scripts used to control + compilation and installation of the executable. However, as a special + exception, the source code distributed need not include anything that + is normally distributed (in either source or binary form) with the + major components (compiler, kernel, and so on) of the operating system + on which the executable runs, unless that component itself accompanies + the executable.

                +

                If distribution of executable or object code is made by offering + access to copy from a designated place, then offering equivalent access + to copy the source code from the same place counts as distribution of + the source code, even though third parties are not compelled to copy + the source along with the object code.

                +
              29. You may not copy, modify, sublicense, or distribute the Program + except as expressly provided under this License. Any attempt otherwise + to copy, modify, sublicense or distribute the Program is void, and will + automatically terminate your rights under this License. However, + parties who have received copies, or rights, from you under this + License will not have their licenses terminated so long as such parties + remain in full compliance.
              30. +
              31. You are not required to accept this License, since you have not + signed it. However, nothing else grants you permission to modify or + distribute the Program or its derivative works. These actions are + prohibited by law if you do not accept this License. Therefore, by + modifying or distributing the Program (or any work based on the + Program), you indicate your acceptance of this License to do so, and + all its terms and conditions for copying, distributing or modifying the + Program or works based on it.
              32. +
              33. Each time you redistribute the Program (or any work based on the + Program), the recipient automatically receives a license from the + original licensor to copy, distribute or modify the Program subject to + these terms and conditions. You may not impose any further restrictions + on the recipients' exercise of the rights granted herein. You are not + responsible for enforcing compliance by third parties to this License.
              34. +
              35. If, as a consequence of a court judgment or allegation of patent + infringement or for any other reason (not limited to patent issues), + conditions are imposed on you (whether by court order, agreement or + otherwise) that contradict the conditions of this License, they do not + excuse you from the conditions of this License. If you cannot + distribute so as to satisfy simultaneously your obligations under this + License and any other pertinent obligations, then as a consequence you + may not distribute the Program at all. For example, if a patent license + would not permit royalty-free redistribution of the Program by all + those who receive copies directly or indirectly through you, then the + only way you could satisfy both it and this License would be to refrain + entirely from distribution of the Program.
              36. +

                If any portion of this section is held invalid or unenforceable under + any particular circumstance, the balance of the section is intended to + apply and the section as a whole is intended to apply in other + circumstances.

                +

                It is not the purpose of this section to induce you to infringe any + patents or other property right claims or to contest validity of any + such claims; this section has the sole purpose of protecting the + integrity of the free software distribution system, which is + implemented by public license practices. Many people have made generous + contributions to the wide range of software distributed through that + system in reliance on consistent application of that system; it is up + to the author/donor to decide if he or she is willing to distribute + software through any other system and a licensee cannot impose that + choice.

                +

                This section is intended to make thoroughly clear what is believed to + be a consequence of the rest of this License.

                +
              37. If the distribution and/or use of the Program is restricted in + certain countries either by patents or by copyrighted interfaces, the + original copyright holder who places the Program under this License may + add an explicit geographical distribution limitation excluding those + countries, so that distribution is permitted only in or among countries + not thus excluded. In such case, this License incorporates the + limitation as if written in the body of this License.
              38. +
              39. The Free Software Foundation may publish revised and/or new versions + of the General Public License from time to time. Such new versions will + be similar in spirit to the present version, but may differ in detail + to address new problems or concerns.
              40. +

                Each version is given a distinguishing version number. If the Program + specifies a version number of this License which applies to it and "any + later version", you have the option of following the terms and + conditions either of that version or of any later version published by + the Free Software Foundation. If the Program does not specify a version + number of this License, you may choose any version ever published by + the Free Software Foundation.

                +
              41. If you wish to incorporate parts of the Program into other free + programs whose distribution conditions are different, write to the + author to ask for permission. For software which is copyrighted by the + Free Software Foundation, write to the Free Software Foundation; we + sometimes make exceptions for this. Our decision will be guided by the + two goals of preserving the free status of all derivatives of our free + software and of promoting the sharing and reuse of software generally.

              NO WARRANTY

                -
              1. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. - EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, -EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS -WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
              2. -
              3. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES.
              4. +
              5. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY + FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN + OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES + PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH + YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL + NECESSARY SERVICING, REPAIR OR CORRECTION.
              6. +
              7. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN + WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY + AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU + FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR + CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE + PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING + RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A + FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF + SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + DAMAGES.

              END OF TERMS AND CONDITIONS

              GNU LIBRARY GENERAL PUBLIC LICENSE

              -

              Version 2, June 1991

              +

              Version 2, June 1991

               Copyright (C) 1991 Free Software Foundation, Inc.
               59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
              @@ -1268,376 +1274,372 @@ of this license document, but changing it is not allowed.
                numbered 2 because it goes with version 2 of the ordinary GPL.]
               

              Preamble

              -

              The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users.

              -

              This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too.

              -

              When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it in -new free programs; and that you know you can do these things.

              -

              To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the library, or if you modify it.

              -

              For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights.

              -

              Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library.

              -

              Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations.

              -

              Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all.

              -

              Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License, which was designed for utility -programs. This license, the GNU Library General Public License, -applies to certain designated libraries. This license is quite -different from the ordinary one; be sure to read it in full, and don't -assume that anything in it is the same as in the ordinary license.

              -

              The reason we have a separate public license for some libraries is -that they blur the distinction we usually make between modifying or -adding to a program and simply using it. Linking a program with a -library, without changing the library, is in some sense simply using -the library, and is analogous to running a utility program or -application program. However, in a textual and legal sense, the linked -executable is a combined work, a derivative of the original library, -and the ordinary General Public License treats it as such.

              -

              Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better.

              -

              However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended -to permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to -achieve this as regards changes in header files, but we have achieved -it as regards changes in the actual functions of the Library.) The -hope is that this will lead to faster development of free libraries.

              -

              The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library.

              -

              Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one.

              +

              The licenses for most software are designed to take away your freedom + to share and change it. By contrast, the GNU General Public Licenses + are intended to guarantee your freedom to share and change free + software--to make sure the software is free for all its users.

              +

              This license, the Library General Public License, applies to some + specially designated Free Software Foundation software, and to any + other libraries whose authors decide to use it. You can use it for your + libraries, too.

              +

              When we speak of free software, we are referring to freedom, not + price. Our General Public Licenses are designed to make sure that you + have the freedom to distribute copies of free software (and charge for + this service if you wish), that you receive source code or can get it + if you want it, that you can change the software or use pieces of it in + new free programs; and that you know you can do these things.

              +

              To protect your rights, we need to make restrictions that forbid + anyone to deny you these rights or to ask you to surrender the rights. + These restrictions translate to certain responsibilities for you if you + distribute copies of the library, or if you modify it.

              +

              For example, if you distribute copies of the library, whether gratis + or for a fee, you must give the recipients all the rights that we gave + you. You must make sure that they, too, receive or can get the source + code. If you link a program with the library, you must provide complete + object files to the recipients so that they can relink them with the + library, after making changes to the library and recompiling it. And + you must show them these terms so they know their rights.

              +

              Our method of protecting your rights has two steps: (1) copyright the + library, and (2) offer you this license which gives you legal + permission to copy, distribute and/or modify the library.

              +

              Also, for each distributor's protection, we want to make certain that + everyone understands that there is no warranty for this free library. + If the library is modified by someone else and passed on, we want its + recipients to know that what they have is not the original version, so + that any problems introduced by others will not reflect on the original + authors' reputations.

              +

              Finally, any free program is threatened constantly by software + patents. We wish to avoid the danger that companies distributing free + software will individually obtain patent licenses, thus in effect + transforming the program into proprietary software. To prevent this, we + have made it clear that any patent must be licensed for everyone's free + use or not licensed at all.

              +

              Most GNU software, including some libraries, is covered by the + ordinary GNU General Public License, which was designed for utility + programs. This license, the GNU Library General Public License, applies + to certain designated libraries. This license is quite different from + the ordinary one; be sure to read it in full, and don't assume that + anything in it is the same as in the ordinary license.

              +

              The reason we have a separate public license for some libraries is + that they blur the distinction we usually make between modifying or + adding to a program and simply using it. Linking a program with a + library, without changing the library, is in some sense simply using + the library, and is analogous to running a utility program or + application program. However, in a textual and legal sense, the linked + executable is a combined work, a derivative of the original library, + and the ordinary General Public License treats it as such.

              +

              Because of this blurred distinction, using the ordinary General + Public License for libraries did not effectively promote software + sharing, because most developers did not use the libraries. We + concluded that weaker conditions might promote sharing better.

              +

              However, unrestricted linking of non-free programs would deprive the + users of those programs of all benefit from the free status of the + libraries themselves. This Library General Public License is intended + to permit developers of non-free programs to use free libraries, while + preserving your freedom as a user of such programs to change the free + libraries that are incorporated in them. (We have not seen how to + achieve this as regards changes in header files, but we have achieved + it as regards changes in the actual functions of the Library.) The hope + is that this will lead to faster development of free libraries.

              +

              The precise terms and conditions for copying, distribution and + modification follow. Pay close attention to the difference between a + "work based on the library" and a "work that uses the library". The + former contains code derived from the library, while the latter only + works together with the library.

              +

              Note that it is possible for a library to be covered by the ordinary + General Public License rather than by this special one.

              TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

              -

              0. This License Agreement applies to any software -library which contains a notice placed by the copyright holder or other -authorized party saying it may be distributed under the terms of this -Library General Public License (also called "this License"). Each -licensee is addressed as "you".

              -

              A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables.

              -

              The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".)

              -

              "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control -compilation and installation of the library.

              -

              Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does and -what the program that uses the Library does.

              -

              1. You may copy and distribute verbatim copies of -the Library's complete source code as you receive it, in any medium, -provided that you conspicuously and appropriately publish on each copy -an appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the Library.

              -

              You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee.

              -

              2. You may modify your copy or copies of the -Library or any portion of it, thus forming a work based on the Library, -and copy and distribute such modifications or work under the terms of -Section 1 above, provided that you also meet all of these conditions:

              +

              0. This License Agreement applies to any software + library which contains a notice placed by the copyright holder or other + authorized party saying it may be distributed under the terms of this + Library General Public License (also called "this License"). Each + licensee is addressed as "you".

              +

              A "library" means a collection of software functions and/or data + prepared so as to be conveniently linked with application programs + (which use some of those functions and data) to form executables.

              +

              The "Library", below, refers to any such software library or work + which has been distributed under these terms. A "work based on the + Library" means either the Library or any derivative work under + copyright law: that is to say, a work containing the Library or a + portion of it, either verbatim or with modifications and/or translated + straightforwardly into another language. (Hereinafter, translation is + included without limitation in the term "modification".)

              +

              "Source code" for a work means the preferred form of the work for + making modifications to it. For a library, complete source code means + all the source code for all modules it contains, plus any associated + interface definition files, plus the scripts used to control + compilation and installation of the library.

              +

              Activities other than copying, distribution and modification are not + covered by this License; they are outside its scope. The act of running + a program using the Library is not restricted, and output from such a + program is covered only if its contents constitute a work based on the + Library (independent of the use of the Library in a tool for writing + it). Whether that is true depends on what the Library does and what the + program that uses the Library does.

              +

              1. You may copy and distribute verbatim copies of + the Library's complete source code as you receive it, in any medium, + provided that you conspicuously and appropriately publish on each copy + an appropriate copyright notice and disclaimer of warranty; keep intact + all the notices that refer to this License and to the absence of any + warranty; and distribute a copy of this License along with the Library.

              +

              You may charge a fee for the physical act of transferring a copy, and + you may at your option offer warranty protection in exchange for a fee.

              +

              2. You may modify your copy or copies of the Library + or any portion of it, thus forming a work based on the Library, and + copy and distribute such modifications or work under the terms of + Section 1 above, provided that you also meet all of these conditions:

                -
              1. The modified work must itself be a software library.
              2. +
              3. The modified work must itself be a software library.
              4. -
              5. You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change.
              6. +
              7. You must cause the files modified to carry prominent notices stating + that you changed the files and the date of any change.
              8. -
              9. You must cause the whole of the work to be licensed at no charge -to all third parties under the terms of this License.
              10. +
              11. You must cause the whole of the work to be licensed at no charge to + all third parties under the terms of this License.
              12. -
              13. If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses the -facility, other than as an argument passed when the facility is -invoked, then you must make a good faith effort to ensure that, in the -event an application does not supply such function or table, the -facility still operates, and performs whatever part of its purpose -remains meaningful.
              14. -

                (For example, a function in a library to compute square roots has a -purpose that is entirely well-defined independent of the application. - Therefore, Subsection 2d requires that any application-supplied -function or table used by this function must be optional: if the -application does not supply it, the square root function must still -compute square roots.)

                +
              15. If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses the + facility, other than as an argument passed when the facility is + invoked, then you must make a good faith effort to ensure that, in the + event an application does not supply such function or table, the + facility still operates, and performs whatever part of its purpose + remains meaningful.
              16. +

                (For example, a function in a library to compute square roots has a + purpose that is entirely well-defined independent of the application. + Therefore, Subsection 2d requires that any application-supplied + function or table used by this function must be optional: if the + application does not supply it, the square root function must still + compute square roots.)

              -

              These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it.

              -

              Thus, it is not the intent of this section to claim rights or -contest your rights to work written entirely by you; rather, the intent -is to exercise the right to control the distribution of derivative or -collective works based on the Library.

              -

              In addition, mere aggregation of another work not based on the -Library with the Library (or with a work based on the Library) on a -volume of a storage or distribution medium does not bring the other -work under the scope of this License.

              -

              3. You may opt to apply the terms of the ordinary -GNU General Public License instead of this License to a given copy of -the Library. To do this, you must alter all the notices that refer to -this License, so that they refer to the ordinary GNU General Public -License, version 2, instead of to this License. (If a newer version -than version 2 of the ordinary GNU General Public License has appeared, -then you can specify that version instead if you wish.) Do not make -any other change in these notices.

              -

              Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy.

              -

              This option is useful when you wish to copy part of the code of the -Library into a program that is not a library.

              -

              4. You may copy and distribute the Library (or a -portion or derivative of it, under Section 2) in object code or -executable form under the terms of Sections 1 and 2 above provided that -you accompany it with the complete corresponding machine-readable -source code, which must be distributed under the terms of Sections 1 -and 2 above on a medium customarily used for software interchange.

              -

              If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to distribute -the source code, even though third parties are not compelled to copy -the source along with the object code.

              -

              5. A program that contains no derivative of any -portion of the Library, but is designed to work with the Library by -being compiled or linked with it, is called a "work that uses the -Library". Such a work, in isolation, is not a derivative work of the -Library, and therefore falls outside the scope of this License.

              -

              However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. Section -6 states terms for distribution of such executables.

              -

              When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law.

              -

              If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.)

              -

              Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, whether -or not they are linked directly with the Library itself.

              -

              6. As an exception to the Sections above, you may -also compile or link a "work that uses the Library" with the Library to -produce a work containing portions of the Library, and distribute that -work under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications.

              -

              You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things:

              +

              These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the Library, + and can be reasonably considered independent and separate works in + themselves, then this License, and its terms, do not apply to those + sections when you distribute them as separate works. But when you + distribute the same sections as part of a whole which is a work based + on the Library, the distribution of the whole must be on the terms of + this License, whose permissions for other licensees extend to the + entire whole, and thus to each and every part regardless of who wrote + it.

              +

              Thus, it is not the intent of this section to claim rights or contest + your rights to work written entirely by you; rather, the intent is to + exercise the right to control the distribution of derivative or + collective works based on the Library.

              +

              In addition, mere aggregation of another work not based on the + Library with the Library (or with a work based on the Library) on a + volume of a storage or distribution medium does not bring the other + work under the scope of this License.

              +

              3. You may opt to apply the terms of the ordinary + GNU General Public License instead of this License to a given copy of + the Library. To do this, you must alter all the notices that refer to + this License, so that they refer to the ordinary GNU General Public + License, version 2, instead of to this License. (If a newer version + than version 2 of the ordinary GNU General Public License has appeared, + then you can specify that version instead if you wish.) Do not make any + other change in these notices.

              +

              Once this change is made in a given copy, it is irreversible for that + copy, so the ordinary GNU General Public License applies to all + subsequent copies and derivative works made from that copy.

              +

              This option is useful when you wish to copy part of the code of the + Library into a program that is not a library.

              +

              4. You may copy and distribute the Library (or a + portion or derivative of it, under Section 2) in object code or + executable form under the terms of Sections 1 and 2 above provided that + you accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections 1 + and 2 above on a medium customarily used for software interchange.

              +

              If distribution of object code is made by offering access to copy + from a designated place, then offering equivalent access to copy the + source code from the same place satisfies the requirement to distribute + the source code, even though third parties are not compelled to copy + the source along with the object code.

              +

              5. A program that contains no derivative of any + portion of the Library, but is designed to work with the Library by + being compiled or linked with it, is called a "work that uses the + Library". Such a work, in isolation, is not a derivative work of the + Library, and therefore falls outside the scope of this License.

              +

              However, linking a "work that uses the Library" with the Library + creates an executable that is a derivative of the Library (because it + contains portions of the Library), rather than a "work that uses the + library". The executable is therefore covered by this License. Section + 6 states terms for distribution of such executables.

              +

              When a "work that uses the Library" uses material from a header file + that is part of the Library, the object code for the work may be a + derivative work of the Library even though the source code is not. + Whether this is true is especially significant if the work can be + linked without the Library, or if the work is itself a library. The + threshold for this to be true is not precisely defined by law.

              +

              If such an object file uses only numerical parameters, data structure + layouts and accessors, and small macros and small inline functions (ten + lines or less in length), then the use of the object file is + unrestricted, regardless of whether it is legally a derivative work. + (Executables containing this object code plus portions of the Library + will still fall under Section 6.)

              +

              Otherwise, if the work is a derivative of the Library, you may + distribute the object code for the work under the terms of Section 6. + Any executables containing that work also fall under Section 6, whether + or not they are linked directly with the Library itself.

              +

              6. As an exception to the Sections above, you may + also compile or link a "work that uses the Library" with the Library to + produce a work containing portions of the Library, and distribute that + work under terms of your choice, provided that the terms permit + modification of the work for the customer's own use and reverse + engineering for debugging such modifications.

              +

              You must give prominent notice with each copy of the work that the + Library is used in it and that the Library and its use are covered by + this License. You must supply a copy of this License. If the work + during execution displays copyright notices, you must include the + copyright notice for the Library among them, as well as a reference + directing the user to the copy of this License. Also, you must do one + of these things:

                -
              1. Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that uses -the Library", as object code and/or source code, so that the user can -modify the Library and then relink to produce a modified executable -containing the modified Library. (It is understood that the user who -changes the contents of definitions files in the Library will not -necessarily be able to recompile the application to use the modified -definitions.)
              2. +
              3. Accompany the work with the complete corresponding machine-readable + source code for the Library including whatever changes were used in the + work (which must be distributed under Sections 1 and 2 above); and, if + the work is an executable linked with the Library, with the complete + machine-readable "work that uses the Library", as object code and/or + source code, so that the user can modify the Library and then relink to + produce a modified executable containing the modified Library. (It is + understood that the user who changes the contents of definitions files + in the Library will not necessarily be able to recompile the + application to use the modified definitions.)
              4. -
              5. Accompany the work with a written offer, valid for at least three -years, to give the same user the materials specified in Subsection 6a, -above, for a charge no more than the cost of performing this -distribution.
              6. +
              7. Accompany the work with a written offer, valid for at least three + years, to give the same user the materials specified in Subsection 6a, + above, for a charge no more than the cost of performing this + distribution.
              8. -
              9. If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place.
              10. +
              11. If distribution of the work is made by offering access to copy from + a designated place, offer equivalent access to copy the above specified + materials from the same place.
              12. -
              13. Verify that the user has already received a copy of these - materials or that you have already sent this user a copy.
              14. +
              15. Verify that the user has already received a copy of these materials + or that you have already sent this user a copy.
              -

              For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major components -(compiler, kernel, and so on) of the operating system on which the -executable runs, unless that component itself accompanies the -executable.

              -

              It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute.

              -

              7. You may place library facilities that are a work -based on the Library side-by-side in a single library together with -other library facilities not covered by this License, and distribute -such a combined library, provided that the separate distribution of the -work based on the Library and of the other library facilities is -otherwise permitted, and provided that you do these two things:

              +

              For an executable, the required form of the "work that uses the + Library" must include any data and utility programs needed for + reproducing the executable from it. However, as a special exception, + the source code distributed need not include anything that is normally + distributed (in either source or binary form) with the major components + (compiler, kernel, and so on) of the operating system on which the + executable runs, unless that component itself accompanies the + executable.

              +

              It may happen that this requirement contradicts the license + restrictions of other proprietary libraries that do not normally + accompany the operating system. Such a contradiction means you cannot + use both them and the Library together in an executable that you + distribute.

              +

              7. You may place library facilities that are a work + based on the Library side-by-side in a single library together with + other library facilities not covered by this License, and distribute + such a combined library, provided that the separate distribution of the + work based on the Library and of the other library facilities is + otherwise permitted, and provided that you do these two things:

                -
              1. Accompany the combined library with a copy of the same work based -on the Library, uncombined with any other library facilities. This -must be distributed under the terms of the Sections above.
              2. +
              3. Accompany the combined library with a copy of the same work based on + the Library, uncombined with any other library facilities. This must be + distributed under the terms of the Sections above.
              4. -
              5. Give prominent notice with the combined library of the fact that -part of it is a work based on the Library, and explaining where to -find the accompanying uncombined form of the same work.
              6. +
              7. Give prominent notice with the combined library of the fact that + part of it is a work based on the Library, and explaining where to find + the accompanying uncombined form of the same work.
              -

              8. You may not copy, modify, sublicense, link with, -or distribute the Library except as expressly provided under this -License. Any attempt otherwise to copy, modify, sublicense, link with, -or distribute the Library is void, and will automatically terminate -your rights under this License. However, parties who have received -copies, or rights, from you under this License will not have their -licenses terminated so long as such parties remain in full compliance.

              -

              9. You are not required to accept this License, -since you have not signed it. However, nothing else grants you -permission to modify or distribute the Library or its derivative works. - These actions are prohibited by law if you do not accept this License. - Therefore, by modifying or distributing the Library (or any work based -on the Library), you indicate your acceptance of this License to do so, -and all its terms and conditions for copying, distributing or modifying -the Library or works based on it.

              -

              10. Each time you redistribute the Library (or any -work based on the Library), the recipient automatically receives a -license from the original licensor to copy, distribute, link with or -modify the Library subject to these terms and conditions. You may not -impose any further restrictions on the recipients' exercise of the -rights granted herein. You are not responsible for enforcing compliance -by third parties to this License.

              -

              11. If, as a consequence of a court judgment or -allegation of patent infringement or for any other reason (not limited -to patent issues), conditions are imposed on you (whether by court -order, agreement or otherwise) that contradict the conditions of this -License, they do not excuse you from the conditions of this License. - If you cannot distribute so as to satisfy simultaneously your -obligations under this License and any other pertinent obligations, -then as a consequence you may not distribute the Library at all. For -example, if a patent license would not permit royalty-free -redistribution of the Library by all those who receive copies directly -or indirectly through you, then the only way you could satisfy both it -and this License would be to refrain entirely from distribution of the -Library.

              -

              If any portion of this section is held invalid or unenforceable -under any particular circumstance, the balance of the section is -intended to apply, and the section as a whole is intended to apply in -other circumstances.

              -

              It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is implemented -by public license practices. Many people have made generous -contributions to the wide range of software distributed through that -system in reliance on consistent application of that system; it is up -to the author/donor to decide if he or she is willing to distribute -software through any other system and a licensee cannot impose that -choice.

              -

              This section is intended to make thoroughly clear what is believed -to be a consequence of the rest of this License.

              -

              12. If the distribution and/or use of the Library -is restricted in certain countries either by patents or by copyrighted -interfaces, the original copyright holder who places the Library under -this License may add an explicit geographical distribution limitation -excluding those countries, so that distribution is permitted only in or -among countries not thus excluded. In such case, this License -incorporates the limitation as if written in the body of this License.

              -

              13. The Free Software Foundation may publish -revised and/or new versions of the Library General Public License from -time to time. Such new versions will be similar in spirit to the -present version, but may differ in detail to address new problems or -concerns.

              -

              Each version is given a distinguishing version number. If the -Library specifies a version number of this License which applies to it -and "any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation.

              -

              14. If you wish to incorporate parts of the Library -into other free programs whose distribution conditions are incompatible -with these, write to the author to ask for permission. For software -which is copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally.

              +

              8. You may not copy, modify, sublicense, link with, + or distribute the Library except as expressly provided under this + License. Any attempt otherwise to copy, modify, sublicense, link with, + or distribute the Library is void, and will automatically terminate + your rights under this License. However, parties who have received + copies, or rights, from you under this License will not have their + licenses terminated so long as such parties remain in full compliance.

              +

              9. You are not required to accept this License, + since you have not signed it. However, nothing else grants you + permission to modify or distribute the Library or its derivative works. + These actions are prohibited by law if you do not accept this License. + Therefore, by modifying or distributing the Library (or any work based + on the Library), you indicate your acceptance of this License to do so, + and all its terms and conditions for copying, distributing or modifying + the Library or works based on it.

              +

              10. Each time you redistribute the Library (or any + work based on the Library), the recipient automatically receives a + license from the original licensor to copy, distribute, link with or + modify the Library subject to these terms and conditions. You may not + impose any further restrictions on the recipients' exercise of the + rights granted herein. You are not responsible for enforcing compliance + by third parties to this License.

              +

              11. If, as a consequence of a court judgment or + allegation of patent infringement or for any other reason (not limited + to patent issues), conditions are imposed on you (whether by court + order, agreement or otherwise) that contradict the conditions of this + License, they do not excuse you from the conditions of this License. If + you cannot distribute so as to satisfy simultaneously your obligations + under this License and any other pertinent obligations, then as a + consequence you may not distribute the Library at all. For example, if + a patent license would not permit royalty-free redistribution of the + Library by all those who receive copies directly or indirectly through + you, then the only way you could satisfy both it and this License would + be to refrain entirely from distribution of the Library.

              +

              If any portion of this section is held invalid or unenforceable under + any particular circumstance, the balance of the section is intended to + apply, and the section as a whole is intended to apply in other + circumstances.

              +

              It is not the purpose of this section to induce you to infringe any + patents or other property right claims or to contest validity of any + such claims; this section has the sole purpose of protecting the + integrity of the free software distribution system which is implemented + by public license practices. Many people have made generous + contributions to the wide range of software distributed through that + system in reliance on consistent application of that system; it is up + to the author/donor to decide if he or she is willing to distribute + software through any other system and a licensee cannot impose that + choice.

              +

              This section is intended to make thoroughly clear what is believed to + be a consequence of the rest of this License.

              +

              12. If the distribution and/or use of the Library is + restricted in certain countries either by patents or by copyrighted + interfaces, the original copyright holder who places the Library under + this License may add an explicit geographical distribution limitation + excluding those countries, so that distribution is permitted only in or + among countries not thus excluded. In such case, this License + incorporates the limitation as if written in the body of this License.

              +

              13. The Free Software Foundation may publish revised + and/or new versions of the Library General Public License from time to + time. Such new versions will be similar in spirit to the present + version, but may differ in detail to address new problems or concerns.

              +

              Each version is given a distinguishing version number. If the Library + specifies a version number of this License which applies to it and "any + later version", you have the option of following the terms and + conditions either of that version or of any later version published by + the Free Software Foundation. If the Library does not specify a license + version number, you may choose any version ever published by the Free + Software Foundation.

              +

              14. If you wish to incorporate parts of the Library + into other free programs whose distribution conditions are incompatible + with these, write to the author to ask for permission. For software + which is copyrighted by the Free Software Foundation, write to the Free + Software Foundation; we sometimes make exceptions for this. Our + decision will be guided by the two goals of preserving the free status + of all derivatives of our free software and of promoting the sharing + and reuse of software generally.

              NO WARRANTY

              -

              15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, -THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT -WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE -OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU -ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

              -

              16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW -OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY -WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE -LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL -OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES.

              +

              15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, + THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY + APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT + HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT + WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE + OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU + ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

              +

              16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR + AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO + MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE + LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL + OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE + LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING + RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A + FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF + SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + DAMAGES.

              END OF TERMS AND CONDITIONS

              diff --git a/doc/sum.pdf b/doc/sum.pdf index 34bdc62d90..4426de5a98 100644 Binary files a/doc/sum.pdf and b/doc/sum.pdf differ diff --git a/doc/sum.shtml b/doc/sum.shtml index 46e689c3a0..fd15b01233 100644 --- a/doc/sum.shtml +++ b/doc/sum.shtml @@ -2,7 +2,7 @@ - + CUPS Software Users Manual @@ -11,7 +11,7 @@

              Preface

              This software users manual describes how to use the Common UNIX Printing -SystemTM ("CUPSTM") Version 1.1.7. +SystemTM ("CUPSTM") Version 1.2.0. @@ -592,27 +592,36 @@ image on the page:

              Scaling the Image

              -

              The -o scaling=percent and -o ppi=value +

              The -o scaling=percent, -o +ppi=value, and -o natural-scaling=percent options change the size of a printed image:

                 lp -o scaling=percent filename ENTER
                 lp -o ppi=value filename ENTER
                -lpr -o ppi=value filename ENTER
                +lpr -o natural-scaling=percent filename ENTER
                 
              -

              The percent value is a number from 1 to 800 +

              The scaling=percent value is a number from 1 to 800 specifying the size in relation to the page (not the image.) A scaling of 100 percent will fill the page as completely as the image aspect ratio allows. A scaling of 200 percent will print on up to 4 pages. -

              The ppi value is a number from 1 to 1200 specifying the +

              The ppi=value value is a number from 1 to 1200 specifying the resolution of the image in pixels per inch. An image that is 3000x2400 pixels will print 10x8 inches at 300 pixels per inch, for example. If the specified resolution makes the image larger than the page, multiple pages will be printed to satisfy the request. +

              The natural-scaling=percent value is a number +from 1 to 800 specifying the size in relation to the natural +image size. A scaling of 100 percent will print the image at its +natural size, while a scaling of 50 percent will print the image +at half its natural size. If the specified scaling makes the +image larger than the page, multiple pages will be printed to +satisfy the request. +

              Adjusting the Hue (Tint) of an Image

              The -o hue=value option will adjust the hue of the diff --git a/doc/svd.html b/doc/svd.html index edeacc4cd0..9eb11cea59 100644 --- a/doc/svd.html +++ b/doc/svd.html @@ -1,27 +1,27 @@ - CUPS Software Version Description +CUPS Software Version Description -


              -

              CUPS Software Version Description


              +

              +

              CUPS Software Version Description


              CUPS-SVD-1.1
              Easy Software Products
              Copyright 1997-2001, All Rights Reserved
              @@ -76,27 +76,27 @@ Copyright 1997-2001, All Rights Reserved

              1 Scope

              1.1 Identification

              - This software version description document provides release -information for the Common UNIX Printing System ("CUPS") Version 1.1. + This software version description document provides release information + for the Common UNIX Printing System ("CUPS") Version 1.1.

              1.2 System Overview

              -

              CUPS provides a portable printing layer for UNIX®-based operating -systems. It has been developed by Easy -Software Products to promote a standard printing solution for all -UNIX vendors and users. CUPS provides the System V and Berkeley -command-line interfaces.

              -

              CUPS uses the Internet Printing Protocol ("IPP") as the basis for -managing print jobs and queues. The Line Printer Daemon ("LPD") Server -Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are -also supported with reduced functionality. CUPS adds network printer -browsing and PostScript Printer Description ("PPD") based printing -options to support real-world printing under UNIX.

              -

              CUPS also includes a customized version of GNU Ghostscript -(currently based off GNU Ghostscript 5.50) and an image file RIP that -are used to support non-PostScript printers. Sample drivers for HP and -EPSON printers are included that use these filters.

              +

              CUPS provides a portable printing layer for UNIX®-based operating + systems. It has been developed by Easy + Software Products to promote a standard printing solution for all + UNIX vendors and users. CUPS provides the System V and Berkeley + command-line interfaces.

              +

              CUPS uses the Internet Printing Protocol ("IPP") as the basis for + managing print jobs and queues. The Line Printer Daemon ("LPD") Server + Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are + also supported with reduced functionality. CUPS adds network printer + browsing and PostScript Printer Description ("PPD") based printing + options to support real-world printing under UNIX.

              +

              CUPS also includes a customized version of GNU Ghostscript (currently + based off GNU Ghostscript 5.50) and an image file RIP that are used to + support non-PostScript printers. Sample drivers for HP and EPSON + printers are included that use these filters.

              1.3 Document Overview

              -

              This software version description document is organized into the -following sections:

              +

              This software version description document is organized into the + following sections:

              2 References

              2.1 CUPS Documentation

              -

              The following CUPS documentation is referenced by this document:

              +

              The following CUPS documentation is referenced by this document:

                -
              • CUPS-CMP-1.1: CUPS Configuration Management Plan
              • -
              • CUPS-IDD-1.1: CUPS System Interface Design Description
              • -
              • CUPS-IPP-1.1: CUPS Implementation of IPP
              • -
              • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
              • -
              • CUPS-SDD-1.1: CUPS Software Design Description
              • -
              • CUPS-SPM-1.1.x: CUPS Software Programming Manual
              • -
              • CUPS-SSR-1.1: CUPS Software Security Report
              • -
              • CUPS-STP-1.1: CUPS Software Test Plan
              • -
              • CUPS-SUM-1.1.x: CUPS Software Users Manual
              • -
              • CUPS-SVD-1.1: CUPS Software Version Description
              • +
              • CUPS-CMP-1.1: CUPS Configuration Management Plan
              • +
              • CUPS-IDD-1.1: CUPS System Interface Design Description
              • +
              • CUPS-IPP-1.1: CUPS Implementation of IPP
              • +
              • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
              • +
              • CUPS-SDD-1.1: CUPS Software Design Description
              • +
              • CUPS-SPM-1.1.x: CUPS Software Programming Manual
              • +
              • CUPS-SSR-1.1: CUPS Software Security Report
              • +
              • CUPS-STP-1.1: CUPS Software Test Plan
              • +
              • CUPS-SUM-1.1.x: CUPS Software Users Manual
              • +
              • CUPS-SVD-1.1: CUPS Software Version Description

              2.2 Other Documents

              -

              The following non-CUPS documents are referenced by this document:

              +

              The following non-CUPS documents are referenced by this document:

              3 Additions

              -

              CUPS 1.1 includes many new features from the 1.0.x releases.

              +

              CUPS 1.1 includes many new features from the 1.0.x releases.

              3.1 Filters

              3.1.1 imagetoraster, imagetops

              -

              The image file filters have been upgraded to support conversion of -Microsoft Bitmap ("BMP") and Alias PIX files.

              +

              The image file filters have been upgraded to support conversion of + Microsoft Bitmap ("BMP") and Alias PIX files.

              3.1.2 pdftops

              -

              A new pdftops filter has been developed that is based on the -excellent Xpdf 0.90 software from Derek B. Noonburg. The new filter is -faster, smaller, and considerably more reliable than the -Ghostscript-based filter in CUPS 1.0.

              +

              A new pdftops filter has been developed that is based on the + excellent Xpdf 0.90 software from Derek B. Noonburg. The new filter is + faster, smaller, and considerably more reliable than the + Ghostscript-based filter in CUPS 1.0.

              3.1.3 pstoraster

              -

              The pstoraster filter has been integrated with GNU -GhostScript 5.50. The new RIP supports most Level 3 PostScript language -features.

              +

              The pstoraster filter has been integrated with GNU + GhostScript 5.50. The new RIP supports most Level 3 PostScript language + features.

              3.1.4 rastertoepson

              -

              The new rastertoepson filter supports EPSON printers -using the ESC/P or ESC/P2 command sets. PPDs are supplied for 9-pin, -24-pin, Stylus Color, and Stylus Photo printers.

              +

              The new rastertoepson filter supports EPSON printers + using the ESC/P or ESC/P2 command sets. PPDs are supplied for 9-pin, + 24-pin, Stylus Color, and Stylus Photo printers.

              3.2 User-Defined Printers and Options

              -

              The new lpoptions command allows users to configure -default document options and create additional "instances" of existing -printers, each with unique options.

              +

              The new lpoptions command allows users to configure + default document options and create additional "instances" of existing + printers, each with unique options.

              The lp, lpr, and lpstat - commands have been upgraded to use this option and printer instance -information automatically.

              + commands have been upgraded to use this option and printer instance + information automatically.

              3.3 Daemons

              -

              CUPS 1.1 includes two new daemons that provide enhanced network -printing support.

              +

              CUPS 1.1 includes two new daemons that provide enhanced network + printing support.

              3.3.1 cups-lpd

              -

              The cups-lpd daemon provides support for clients using -the Line Printer Daemon protocol.

              +

              The cups-lpd daemon provides support for clients using + the Line Printer Daemon protocol.

              3.3.2 cups-polld

              -

              The cups-polld daemon provides remote polling services -for the scheduler.

              +

              The cups-polld daemon provides remote polling services + for the scheduler.

              3.4 Commands

              -

              CUPS 1.1 includes several new printing commands.

              +

              CUPS 1.1 includes several new printing commands.

              3.4.1 lpoptions

              -

              The lpoptions command provides user-defined printers -and options.

              +

              The lpoptions command provides user-defined printers and + options.

              3.4.2 lpmove

              -

              The lpmove command moves a print job to a new -destination.

              +

              The lpmove command moves a print job to a new + destination.

              3.4.3 lpinfo

              -

              The lpinfo command lists the available PPD files or -devices.

              +

              The lpinfo command lists the available PPD files or + devices.

              3.5 IPP Implementation

              CUPS 1.1 adds support for the set-job-attributes - extension operation as well as two new CUPS-specific extension -operations to determine which devices and printer drivers are available -on the system.

              -

              Further information on the CUPS implementation of IPP can be found -in CUPS-IPP-1.1.

              + extension operation as well as two new CUPS-specific extension + operations to determine which devices and printer drivers are available + on the system.

              +

              Further information on the CUPS implementation of IPP can be found in + CUPS-IPP-1.1.

              4 Changes

              -

              CUPS 1.1 includes many changes from the 1.0.x releases.

              +

              CUPS 1.1 includes many changes from the 1.0.x releases.

              4.1 Directory Structure

              -

              The directory structure in CUPS 1.1 has been modified to conform to -the Filesystem Hierarchy Standard, 2.0. The following table describes -the new file locations. +

              The directory structure in CUPS 1.1 has been modified to conform to + the Filesystem Hierarchy Standard, 2.0. The following table describes + the new file locations.

              - +
              Table 1: Directory structure -changes from CUPS 1.0.x to 1.1.x.
              @@ -231,67 +231,66 @@ changes from CUPS 1.0.x to 1.1.x.

              4.2 IPP Implementation

              -

              CUPS 1.1 is based on version 1.1 of the Internet Printing Protocol.

              +

              CUPS 1.1 is based on version 1.1 of the Internet Printing Protocol.

              The new scheduler supports the create-job and send-document operations. In addition, the job-sheets , job-sheets-default, and job-sheets-supported - attributes are now supported for banner pages.

              + attributes are now supported for banner pages.

              The CUPS-get-printers and CUPS-get-classes - operations have been upgraded to support limited filtering based upon -the printer-type, printer-location, -printer-info, and printer-make-and-model - attributes.

              + operations have been upgraded to support limited filtering based upon + the printer-type, printer-location, +printer-info, and printer-make-and-model attributes.

              The CUPS-add-printer operation now supports the -ppd-name attribute to specify a locally-available PPD file -rather than sending the PPD file from the client with the request.

              -

              Further information on the CUPS implementation of IPP can be found -in CUPS-IPP-1.1.

              +ppd-name attribute to specify a locally-available PPD file rather + than sending the PPD file from the client with the request.

              +

              Further information on the CUPS implementation of IPP can be found in + CUPS-IPP-1.1.

              A Glossary

              A.1 Terms

              -
              C
              -
              A computer language.
              -
              parallel
              -
              Sending or receiving data more than 1 bit at a time.
              -
              pipe
              -
              A one-way communications channel between two programs.
              -
              serial
              -
              Sending or receiving data 1 bit at a time.
              -
              socket
              -
              A two-way network communications channel.
              +
              C
              +
              A computer language.
              +
              parallel
              +
              Sending or receiving data more than 1 bit at a time.
              +
              pipe
              +
              A one-way communications channel between two programs.
              +
              serial
              +
              Sending or receiving data 1 bit at a time.
              +
              socket
              +
              A two-way network communications channel.

              A.2 Acronyms

              -
              ASCII
              -
              American Standard Code for Information Interchange
              -
              CUPS
              -
              Common UNIX Printing System
              -
              ESC/P
              -
              EPSON Standard Code for Printers
              -
              FTP
              -
              File Transfer Protocol
              -
              HP-GL
              -
              Hewlett-Packard Graphics Language
              -
              HP-PCL
              -
              Hewlett-Packard Page Control Language
              -
              HP-PJL
              -
              Hewlett-Packard Printer Job Language
              -
              IETF
              -
              Internet Engineering Task Force
              -
              IPP
              -
              Internet Printing Protocol
              -
              ISO
              -
              International Standards Organization
              -
              LPD
              -
              Line Printer Daemon
              -
              MIME
              -
              Multimedia Internet Mail Exchange
              -
              PPD
              -
              PostScript Printer Description
              -
              SMB
              -
              Server Message Block
              -
              TFTP
              -
              Trivial File Transfer Protocol
              +
              ASCII
              +
              American Standard Code for Information Interchange
              +
              CUPS
              +
              Common UNIX Printing System
              +
              ESC/P
              +
              EPSON Standard Code for Printers
              +
              FTP
              +
              File Transfer Protocol
              +
              HP-GL
              +
              Hewlett-Packard Graphics Language
              +
              HP-PCL
              +
              Hewlett-Packard Page Control Language
              +
              HP-PJL
              +
              Hewlett-Packard Printer Job Language
              +
              IETF
              +
              Internet Engineering Task Force
              +
              IPP
              +
              Internet Printing Protocol
              +
              ISO
              +
              International Standards Organization
              +
              LPD
              +
              Line Printer Daemon
              +
              MIME
              +
              Multimedia Internet Mail Exchange
              +
              PPD
              +
              PostScript Printer Description
              +
              SMB
              +
              Server Message Block
              +
              TFTP
              +
              Trivial File Transfer Protocol
              diff --git a/doc/svd.pdf b/doc/svd.pdf index 05918d142a..b0d4a71a66 100644 Binary files a/doc/svd.pdf and b/doc/svd.pdf differ diff --git a/filter/Makefile b/filter/Makefile index fdc02bdd94..1a209fe141 100644 --- a/filter/Makefile +++ b/filter/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.41 2001/02/02 16:37:44 mike Exp $" +# "$Id: Makefile,v 1.41.2.1 2001/12/26 16:52:38 mike Exp $" # # Filter makefile for the Common UNIX Printing System (CUPS). # @@ -25,7 +25,7 @@ include ../Makedefs TARGETS = hpgltops texttops pstops imagetops imagetoraster \ - rastertoepson rastertohp + rastertodymo rastertoepson rastertohp HPGLOBJS = hpgl-attr.o hpgl-config.o hpgl-main.o hpgl-prolog.o \ hpgl-char.o hpgl-input.o hpgl-polygon.o hpgl-vector.o @@ -36,8 +36,8 @@ IMAGEOBJS = image-bmp.o image-colorspace.o image-gif.o image-jpeg.o \ FORMOBJS = form-attr.o form-main.o form-ps.o form-text.o form-tree.o OBJS = $(HPGLOBJS) $(IMAGEOBJS) $(FORMOBJS) \ imagetops.o imagetoraster.o common.o pstops.o raster.o \ - rastertoepson.o rastertohp.o texttops.o textcommon.o - + rastertodymo.o rastertoepson.o rastertohp.o texttops.o \ + textcommon.o # # Make all targets... @@ -59,20 +59,21 @@ clean: # install: - -$(MKDIR) $(LIBDIR) - $(CHMOD) ugo+rx $(LIBDIR) + $(INSTALL_DIR) $(SERVERBIN)/filter + for file in $(TARGETS); do \ + $(INSTALL_BIN) $$file $(SERVERBIN)/filter; \ + done + $(INSTALL_DIR) $(LIBDIR) $(INSTALL_LIB) $(LIBCUPSIMAGE) $(LIBDIR) - -if test $(LIBCUPSIMAGE) != "libcupsimage.a" -a $(LIBCUPSIMAGE) != "libcupsimage.la"; then \ + -if test $(LIBCUPSIMAGE) = "libcupsimage.so.2" -o $(LIBCUPSIMAGE) = "libcupsimage.sl.2"; then \ $(RM) $(LIBDIR)/`basename $(LIBCUPSIMAGE) .2`; \ $(LN) $(LIBCUPSIMAGE) $(LIBDIR)/`basename $(LIBCUPSIMAGE) .2`; \ fi - -$(MKDIR) $(SERVERBIN)/filter - $(CHMOD) ugo+rx $(SERVERBIN) - $(CHMOD) ugo+rx $(SERVERBIN)/filter - $(INSTALL_BIN) $(TARGETS) $(SERVERBIN)/filter - -$(MKDIR) $(INCLUDEDIR)/cups - $(CHMOD) ugo+rx $(INCLUDEDIR) - $(CHMOD) ugo+rx $(INCLUDEDIR)/cups + -if test $(LIBCUPSIMAGE) = "libcupsimage.2.dylib"; then \ + $(RM) $(LIBDIR)/libcupsimage.dylib; \ + $(LN) $(LIBCUPSIMAGE) $(LIBDIR)/libcupsimage.dylib; \ + fi + $(INSTALL_DIR) $(INCLUDEDIR)/cups $(INSTALL_DATA) raster.h $(INCLUDEDIR)/cups @@ -107,14 +108,37 @@ libcupsimage.so.2 libcupsimage.sl.2: $(IMAGEOBJS) ../Makedefs $(LN) $@ `basename $@ .2` +# +# libcupsimage.2.dylib +# + +libcupsimage.2.dylib: $(IMAGEOBJS) ../Makedefs + echo Linking $@... + $(DSO) $(DSOFLAGS) -o $@ $(IMAGEOBJS) $(DSOLIBS) $(LINKCUPS) -lm -lcc_dynamic + $(RM) libcupsimage.dylib + $(LN) $@ libcupsimage.dylib + + +# +# libcupsimage_s.a +# + +libcupsimage_s.a: $(IMAGEOBJS) ../Makedefs + echo Linking $@... + $(DSO) $(DSOFLAGS) -o libcupsimage_s.o $(IMAGEOBJS) $(DSOLIBS) \ + $(LINKCUPS) -lm + $(RM) $@ + $(AR) $(ARFLAGS) $@ libcupsimage_s.o + + # # libcupsimage.la # libcupsimage.la: $(IMAGEOBJS) ../Makedefs echo Linking $@... - $(CC) -o $@ $(IMAGEOBJS:.o=.lo) -rpath $(LIBDIR) \ - -version-info 2:0 + $(DSO) -o $(DSOFLAGS) $@ $(IMAGEOBJS:.o=.lo) $(DSOLIBS) \ + -rpath $(LIBDIR) -version-info 2:0 # @@ -165,6 +189,16 @@ pstops: pstops.o common.o ../Makedefs ../cups/$(LIBCUPS) pstops.o: common.h +# +# rastertodymo +# + +rastertodymo: rastertodymo.o ../Makedefs ../cups/$(LIBCUPS) libcupsimage.a + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ rastertodymo.o libcupsimage.a $(LIBS) +rastertodymo.o: raster.h + + # # rastertoepson # @@ -203,5 +237,5 @@ $(OBJS): ../Makedefs ../cups/cups.h ../cups/ppd.h ../cups/language.h # -# End of "$Id: Makefile,v 1.41 2001/02/02 16:37:44 mike Exp $". +# End of "$Id: Makefile,v 1.41.2.1 2001/12/26 16:52:38 mike Exp $". # diff --git a/filter/image-colorspace.c b/filter/image-colorspace.c index 3781f22fe0..b4601317d2 100644 --- a/filter/image-colorspace.c +++ b/filter/image-colorspace.c @@ -1,5 +1,5 @@ /* - * "$Id: image-colorspace.c,v 1.22 2001/03/29 14:58:52 mike Exp $" + * "$Id: image-colorspace.c,v 1.22.2.1 2001/12/26 16:52:38 mike Exp $" * * Colorspace conversions for the Common UNIX Printing System (CUPS). * @@ -23,6 +23,7 @@ * * Contents: * + * ImageSetProfile() - Set the device color profile. * ImageWhiteToWhite() - Convert luminance colors to device-dependent * ImageWhiteToRGB() - Convert luminance data to RGB. * ImageWhiteToBlack() - Convert luminance colors to black. @@ -56,12 +57,13 @@ /* - * Globals... + * Local globals... */ -extern int ImageHaveProfile; -extern int ImageDensity[256]; -extern int ImageMatrix[3][3][256]; +static int ImageHaveProfile = 0; /* Do we have a color profile? */ +static int ImageDensity[256]; /* Ink/marker density LUT */ +static int ImageMatrix[3][3][256]; /* Color transform matrix LUT */ + /* * Local functions... @@ -78,6 +80,31 @@ static void zrotate(float [3][3], float, float); static void zshear(float [3][3], float, float); +/* + * 'ImageSetProfile()' - Set the device color profile. + */ + +void +ImageSetProfile(float d, /* I - Ink/marker density */ + float g, /* I - Ink/marker gamma */ + float matrix[3][3]) /* I - Color transform matrix */ +{ + int i, j, k; /* Looping vars */ + float m; /* Current matrix value */ + int *im; /* Pointer into ImageMatrix */ + + ImageHaveProfile = 1; + + for (i = 0, im = ImageMatrix[0][0]; i < 3; i ++) + for (j = 0; j < 3; j ++) + for (k = 0, m = matrix[i][j]; k < 256; k ++) + *im++ = (int)(k * m + 0.5); + + for (k = 0, im = ImageDensity; k < 256; k ++) + *im++ = 255.0 * d * pow((float)k / 255.0, g) + 0.5; +} + + /* * 'ImageWhiteToWhite()' - Convert luminance colors to device-dependent * luminance. @@ -878,5 +905,5 @@ zshear(float mat[3][3], /* I - Matrix */ /* - * End of "$Id: image-colorspace.c,v 1.22 2001/03/29 14:58:52 mike Exp $". + * End of "$Id: image-colorspace.c,v 1.22.2.1 2001/12/26 16:52:38 mike Exp $". */ diff --git a/filter/image-jpeg.c b/filter/image-jpeg.c index 6bf640c7c5..f6a517115e 100644 --- a/filter/image-jpeg.c +++ b/filter/image-jpeg.c @@ -1,5 +1,5 @@ /* - * "$Id: image-jpeg.c,v 1.11 2001/01/22 15:03:38 mike Exp $" + * "$Id: image-jpeg.c,v 1.11.2.1 2001/12/26 16:52:38 mike Exp $" * * JPEG image routines for the Common UNIX Printing System (CUPS). * @@ -98,7 +98,7 @@ ImageReadJPEG(image_t *img, /* IO - Image */ } fprintf(stderr, "DEBUG: JPEG image %dx%dx%d, %dx%d PPI\n", - img->xsize, img->colorspace, cinfo.output_components, + img->xsize, img->ysize, cinfo.output_components, img->xppi, img->yppi); ImageSetMaxTiles(img, 0); @@ -190,5 +190,5 @@ ImageReadJPEG(image_t *img, /* IO - Image */ /* - * End of "$Id: image-jpeg.c,v 1.11 2001/01/22 15:03:38 mike Exp $". + * End of "$Id: image-jpeg.c,v 1.11.2.1 2001/12/26 16:52:38 mike Exp $". */ diff --git a/filter/image.c b/filter/image.c index db1d827fd8..ee14f77d5b 100644 --- a/filter/image.c +++ b/filter/image.c @@ -1,5 +1,5 @@ /* - * "$Id: image.c,v 1.28 2001/03/01 22:51:30 mike Exp $" + * "$Id: image.c,v 1.28.2.1 2001/12/26 16:52:38 mike Exp $" * * Base image support for the Common UNIX Printing System (CUPS). * @@ -26,7 +26,6 @@ * ImageOpen() - Open an image file and read it into memory. * ImageClose() - Close an image file. * ImageSetMaxTiles() - Set the maximum number of tiles to cache. - * ImageSetProfile() - Set the device color profile. * ImageGetCol() - Get a column of pixels from an image. * ImageGetRow() - Get a row of pixels from an image. * ImagePutCol() - Put a column of pixels to an image. @@ -46,15 +45,6 @@ #include -/* - * Globals... - */ - -int ImageHaveProfile = 0; /* Do we have a color profile? */ -int ImageDensity[256]; /* Ink/marker density LUT */ -int ImageMatrix[3][3][256]; /* Color transform matrix LUT */ - - /* * Local functions... */ @@ -311,31 +301,6 @@ ImageSetMaxTiles(image_t *img, /* I - Image to set */ } -/* - * 'ImageSetProfile()' - Set the device color profile. - */ - -void -ImageSetProfile(float d, /* I - Ink/marker density */ - float g, /* I - Ink/marker gamma */ - float matrix[3][3]) /* I - Color transform matrix */ -{ - int i, j, k; /* Looping vars */ - float m; /* Current matrix value */ - int *im; /* Pointer into ImageMatrix */ - - ImageHaveProfile = 1; - - for (i = 0, im = ImageMatrix[0][0]; i < 3; i ++) - for (j = 0; j < 3; j ++) - for (k = 0, m = matrix[i][j]; k < 256; k ++) - *im++ = (int)(k * m + 0.5); - - for (k = 0, im = ImageDensity; k < 256; k ++) - *im++ = 255.0 * d * pow((float)k / 255.0, g) + 0.5; -} - - /* * 'ImageGetCol()' - Get a column of pixels from an image. */ @@ -804,5 +769,5 @@ flush_tile(image_t *img) /* I - Image */ /* - * End of "$Id: image.c,v 1.28 2001/03/01 22:51:30 mike Exp $". + * End of "$Id: image.c,v 1.28.2.1 2001/12/26 16:52:38 mike Exp $". */ diff --git a/filter/imagetops.c b/filter/imagetops.c index ac1db10baf..f494cd4adf 100644 --- a/filter/imagetops.c +++ b/filter/imagetops.c @@ -1,5 +1,5 @@ /* - * "$Id: imagetops.c,v 1.36.2.1 2001/05/13 18:38:18 mike Exp $" + * "$Id: imagetops.c,v 1.36.2.2 2001/12/26 16:52:39 mike Exp $" * * Image file to PostScript filter for the Common UNIX Printing System (CUPS). * @@ -305,6 +305,12 @@ main(int argc, /* I - Number of command-line arguments */ xinches = (float)img->xsize / (float)xppi; yinches = (float)img->ysize / (float)yppi; + if ((val = cupsGetOption("natural-scaling", num_options, options)) != NULL) + { + xinches = xinches * atoi(val) / 100; + yinches = yinches * atoi(val) / 100; + } + if (cupsGetOption("orientation", num_options, options) == NULL && cupsGetOption("landscape", num_options, options) == NULL) { @@ -859,5 +865,5 @@ ps_ascii85(ib_t *data, /* I - Data to print */ /* - * End of "$Id: imagetops.c,v 1.36.2.1 2001/05/13 18:38:18 mike Exp $". + * End of "$Id: imagetops.c,v 1.36.2.2 2001/12/26 16:52:39 mike Exp $". */ diff --git a/filter/imagetoraster.c b/filter/imagetoraster.c index 22c457f439..229f7a0a87 100644 --- a/filter/imagetoraster.c +++ b/filter/imagetoraster.c @@ -1,5 +1,5 @@ /* - * "$Id: imagetoraster.c,v 1.56.2.1 2001/05/13 18:38:19 mike Exp $" + * "$Id: imagetoraster.c,v 1.56.2.2 2001/12/26 16:52:39 mike Exp $" * * Image file to raster filter for the Common UNIX Printing System (CUPS). * @@ -677,6 +677,12 @@ main(int argc, /* I - Number of command-line arguments */ xinches = (float)img->xsize / (float)xppi; yinches = (float)img->ysize / (float)yppi; + if ((val = cupsGetOption("natural-scaling", num_options, options)) != NULL) + { + xinches = xinches * atoi(val) / 100; + yinches = yinches * atoi(val) / 100; + } + if (cupsGetOption("orientation", num_options, options) == NULL && cupsGetOption("landscape", num_options, options) == NULL) { @@ -4442,5 +4448,5 @@ make_lut(ib_t *lut, /* I - Lookup table */ /* - * End of "$Id: imagetoraster.c,v 1.56.2.1 2001/05/13 18:38:19 mike Exp $". + * End of "$Id: imagetoraster.c,v 1.56.2.2 2001/12/26 16:52:39 mike Exp $". */ diff --git a/filter/pstops.c b/filter/pstops.c index bc4e585860..507004ab73 100644 --- a/filter/pstops.c +++ b/filter/pstops.c @@ -1,5 +1,5 @@ /* - * "$Id: pstops.c,v 1.54.2.1 2001/05/13 18:38:20 mike Exp $" + * "$Id: pstops.c,v 1.54.2.2 2001/12/26 16:52:39 mike Exp $" * * PostScript filter for the Common UNIX Printing System (CUPS). * @@ -100,6 +100,7 @@ main(int argc, /* I - Number of command-line arguments */ int nbytes, /* Number of bytes read */ tbytes; /* Total bytes to read for binary data */ int page; /* Current page sequence number */ + int real_page; /* "Real" page number in document */ int page_count; /* Page count for NUp */ int subpage; /* Sub-page number */ int copy; /* Current copy */ @@ -248,6 +249,12 @@ main(int argc, /* I - Number of command-line arguments */ return (1); } + /* + * See if this is an EPS file... + */ + + UseESPsp = strstr(line, "EPS") != NULL; + /* * Start sending the document with any commands needed... */ @@ -280,14 +287,15 @@ main(int argc, /* I - Number of command-line arguments */ */ UseESPsp = 1; + } - WriteLabelProlog(val); + WriteLabelProlog(val); + if (UseESPsp) puts("userdict begin\n" "/ESPshowpage /showpage load def\n" "/showpage { } def\n" "end"); - } if (Copies > 1 && (!Collate || !slowcollate)) { @@ -345,7 +353,7 @@ main(int argc, /* I - Number of command-line arguments */ * Then read all of the pages, filtering as needed... */ - for (page = 1;;) + for (page = 1, real_page = 1;;) { if (strncmp(line, "%%BeginDocument:", 16) == 0 || strncmp(line, "%%BeginDocument ", 16) == 0) /* Adobe Acrobat BUG */ @@ -362,7 +370,7 @@ main(int argc, /* I - Number of command-line arguments */ } else if (strncmp(line, "%%Page:", 7) == 0 && level == 0) { - if (!check_range(NumPages + 1)) + if (!check_range(real_page)) { while (psgets(line, sizeof(line), fp) != NULL) if (strncmp(line, "%%BeginDocument:", 16) == 0 || @@ -371,7 +379,10 @@ main(int argc, /* I - Number of command-line arguments */ else if (strcmp(line, "%%EndDocument") == 0 && level > 0) level --; else if (strncmp(line, "%%Page:", 7) == 0 && level == 0) + { + real_page ++; break; + } continue; } @@ -398,6 +409,7 @@ main(int argc, /* I - Number of command-line arguments */ } NumPages ++; + real_page ++; } else if (strncmp(line, "%%BeginBinary:", 14) == 0 || (strncmp(line, "%%BeginData:", 12) == 0 && @@ -963,5 +975,5 @@ start_nup(int number) /* I - Page number */ /* - * End of "$Id: pstops.c,v 1.54.2.1 2001/05/13 18:38:20 mike Exp $". + * End of "$Id: pstops.c,v 1.54.2.2 2001/12/26 16:52:39 mike Exp $". */ diff --git a/filter/rastertodymo.c b/filter/rastertodymo.c index 0518f76867..3ccebd45e6 100644 --- a/filter/rastertodymo.c +++ b/filter/rastertodymo.c @@ -1,5 +1,5 @@ /* - * "$Id: rastertodymo.c,v 1.4 2001/07/18 20:45:51 mike Exp $" + * "$Id: rastertodymo.c,v 1.4.2.1 2001/12/26 16:52:40 mike Exp $" * * DYMO label printer filter for the Common UNIX Printing System (CUPS). * @@ -357,5 +357,5 @@ main(int argc, /* I - Number of command-line arguments */ /* - * End of "$Id: rastertodymo.c,v 1.4 2001/07/18 20:45:51 mike Exp $". + * End of "$Id: rastertodymo.c,v 1.4.2.1 2001/12/26 16:52:40 mike Exp $". */ diff --git a/filter/textcommon.c b/filter/textcommon.c index 0700d211b6..a28dd5cf0c 100644 --- a/filter/textcommon.c +++ b/filter/textcommon.c @@ -1,5 +1,5 @@ /* - * "$Id: textcommon.c,v 1.16.2.1 2001/05/13 18:38:21 mike Exp $" + * "$Id: textcommon.c,v 1.16.2.2 2001/12/26 16:52:40 mike Exp $" * * Common text filter routines for the Common UNIX Printing System (CUPS). * @@ -970,10 +970,19 @@ TextMain(const char *name, /* I - Name of filter */ if (PrettyPrint) Page[line][i].attr = attr; + else if (ch == ' ' && Page[line][i].ch) + ch = Page[line][i].ch; else if (ch == Page[line][i].ch) Page[line][i].attr |= ATTR_BOLD; else if (Page[line][i].ch == '_') Page[line][i].attr |= ATTR_UNDERLINE; + else if (ch == '_') + { + Page[line][i].attr |= ATTR_UNDERLINE; + + if (Page[line][i].ch) + ch = Page[line][i].ch; + } else Page[line][i].attr = attr; @@ -1142,5 +1151,5 @@ getutf8(FILE *fp) /* I - File to read from */ /* - * End of "$Id: textcommon.c,v 1.16.2.1 2001/05/13 18:38:21 mike Exp $". + * End of "$Id: textcommon.c,v 1.16.2.2 2001/12/26 16:52:40 mike Exp $". */ diff --git a/fonts/Makefile b/fonts/Makefile index 06ebc57e25..81d3289efa 100644 --- a/fonts/Makefile +++ b/fonts/Makefile @@ -64,10 +64,10 @@ clean: # install: - -$(MKDIR) $(DATADIR)/fonts - $(CHMOD) ugo+rx $(DATADIR) - $(CHMOD) ugo+rx $(DATADIR)/fonts - $(INSTALL_DATA) $(FONTS) $(DATADIR)/fonts + $(INSTALL_DIR) $(DATADIR)/fonts + for file in $(FONTS); do \ + $(INSTALL_DATA) $$file $(DATADIR)/fonts; \ + done # diff --git a/locale/Makefile b/locale/Makefile index 3703403d56..e3edc2d642 100644 --- a/locale/Makefile +++ b/locale/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.8 2000/07/07 17:02:44 mike Exp $" +# "$Id: Makefile,v 1.8.2.1 2001/12/26 16:52:40 mike Exp $" # # Locale file makefile for the Common UNIX Printing System (CUPS). # @@ -28,7 +28,7 @@ include ../Makedefs # Locales... # -LOCALES = C de en es fr it +LOCALES = C cs de en es fr it # @@ -50,13 +50,9 @@ clean: # install: - -$(MKDIR) $(LOCALEDIR) - $(CHMOD) ugo+rx $(LOCALEDIR) + $(INSTALL_DIR) $(LOCALEDIR) for dir in $(LOCALES) ; do \ - if test ! -d $(LOCALEDIR)/$$dir ; then \ - $(MKDIR) $(LOCALEDIR)/$$dir ; \ - $(CHMOD) ugo+rx $(LOCALEDIR)/$$dir ; \ - fi ; \ + $(INSTALL_DIR) $(LOCALEDIR)/$$dir ; \ $(INSTALL_DATA) $$dir/cups_$$dir $(LOCALEDIR)/$$dir ; \ done @@ -76,5 +72,5 @@ translate.o: ../cups/http.h # -# End of "$Id: Makefile,v 1.8 2000/07/07 17:02:44 mike Exp $". +# End of "$Id: Makefile,v 1.8.2.1 2001/12/26 16:52:40 mike Exp $". # diff --git a/man/Makefile b/man/Makefile index 9396282f22..96af00b99b 100644 --- a/man/Makefile +++ b/man/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.12 2001/02/20 17:33:00 mike Exp $" +# "$Id: Makefile,v 1.12.2.1 2001/12/26 16:52:41 mike Exp $" # # Man page makefile for the Common UNIX Printing System (CUPS). # @@ -28,23 +28,26 @@ include ../Makedefs # Man pages... # -MAN1 = backend.man filter.man lp.man lpoptions.man lpq.man lprm.man \ - lpr.man lpstat.man +MAN1 = backend.man filter.man lp.man lpoptions.man lppasswd.man \ + lpq.man lprm.man lpr.man lpstat.man +MAN3 = cups-config.man MAN5 = classes.conf.man cupsd.conf.man mime.convs.man mime.types.man \ printers.conf.man -MAN8 = accept.man cups-lpd.man cups-polld.man cupsd.man enable.man \ - lpadmin.man lpinfo.man lpmove.man lpc.man +MAN8 = accept.man cupsaddsmb.man cups-lpd.man cups-polld.man \ + cupsd.man enable.man lpadmin.man lpinfo.man lpmove.man \ + lpc.man CAT1 = $(MAN1:.man=.$(CAT1EXT)) -CAT5 = $(MAN5:.man=.$(CAT1EXT)) -CAT8 = $(MAN8:.man=.$(CAT1EXT)) +CAT3 = $(MAN3:.man=.$(CAT3EXT)) +CAT5 = $(MAN5:.man=.$(CAT5EXT)) +CAT8 = $(MAN8:.man=.$(CAT8EXT)) # # Make everything... # -all: $(CAT1) $(CAT5) $(CAT8) +all: $(CAT1) $(CAT3) $(CAT5) $(CAT8) # @@ -52,7 +55,7 @@ all: $(CAT1) $(CAT5) $(CAT8) # clean: - $(RM) $(CAT1) $(CAT5) $(CAT8) + $(RM) $(CAT1) $(CAT3) $(CAT5) $(CAT8) # @@ -60,21 +63,21 @@ clean: # install: - -$(MKDIR) $(MANDIR)/man1 - -$(CHMOD) ugo+rx $(MANDIR) - -$(CHMOD) ugo+rx $(MANDIR)/man1 + $(INSTALL_DIR) $(MANDIR)/man1 for file in $(MAN1); do \ $(INSTALL_MAN) $$file $(MANDIR)/man1/`basename $$file man`1; \ done $(RM) $(MANDIR)/man1/cancel.1 $(LN) lp.1 $(MANDIR)/man1/cancel.1 - -$(MKDIR) $(MANDIR)/man5 - -$(CHMOD) ugo+rx $(MANDIR)/man5 + $(INSTALL_DIR) $(PMANDIR)/man3 + for file in $(MAN3); do \ + $(INSTALL_MAN) $$file $(PMANDIR)/man3/`basename $$file man`3; \ + done + $(INSTALL_DIR) $(MANDIR)/man5 for file in $(MAN5); do \ $(INSTALL_MAN) $$file $(MANDIR)/man5/`basename $$file man`5; \ done - -$(MKDIR) $(AMANDIR)/man$(MAN8EXT) - -$(CHMOD) ugo+rx $(AMANDIR)/man$(MAN8EXT) + $(INSTALL_DIR) $(AMANDIR)/man$(MAN8EXT) for file in $(MAN8); do \ $(INSTALL_MAN) $$file $(AMANDIR)/man$(MAN8EXT)/`basename $$file man`$(MAN8EXT); \ done @@ -82,23 +85,30 @@ install: $(LN) accept.$(MAN8EXT) $(AMANDIR)/man$(MAN8EXT)/reject.$(MAN8EXT) $(RM) $(AMANDIR)/man$(MAN8EXT)/disable.$(MAN8EXT) $(LN) enable.$(MAN8EXT) $(AMANDIR)/man$(MAN8EXT)/disable.$(MAN8EXT) - -$(MKDIR) $(MANDIR)/cat1 - -$(CHMOD) ugo+rx $(MANDIR)/cat1 - $(INSTALL_MAN) $(CAT1) $(MANDIR)/cat1 + $(INSTALL_DIR) $(MANDIR)/cat1 + for file in $(CAT1); do \ + $(INSTALL_MAN) $$file $(MANDIR)/cat1; \ + done $(RM) $(MANDIR)/cat1/cancel.$(CAT1EXT) $(LN) lp.$(CAT1EXT) $(MANDIR)/cat1/cancel.$(CAT1EXT) - -$(MKDIR) $(MANDIR)/cat5 - -$(CHMOD) ugo+rx $(MANDIR)/cat5 - $(INSTALL_MAN) $(CAT5) $(MANDIR)/cat5 - -$(MKDIR) $(AMANDIR)/cat$(MAN8EXT) - -$(CHMOD) ugo+rx $(AMANDIR)/cat$(MAN8EXT) - $(INSTALL_MAN) $(CAT8) $(AMANDIR)/cat$(MAN8EXT) + $(INSTALL_DIR) $(PMANDIR)/cat3 + for file in $(CAT3); do \ + $(INSTALL_MAN) $$file $(PMANDIR)/cat3; \ + done + $(INSTALL_DIR) $(MANDIR)/cat5 + for file in $(CAT5); do \ + $(INSTALL_MAN) $$file $(MANDIR)/cat5; \ + done + $(INSTALL_DIR) $(AMANDIR)/cat$(MAN8EXT) + for file in $(CAT8); do \ + $(INSTALL_MAN) $$file $(AMANDIR)/cat$(MAN8EXT); \ + done $(RM) $(AMANDIR)/cat$(MAN8EXT)/reject.$(CAT8EXT) - $(LN) accept.$(CAT1EXT) $(AMANDIR)/cat$(MAN8EXT)/reject.$(CAT8EXT) + $(LN) accept.$(CAT8EXT) $(AMANDIR)/cat$(MAN8EXT)/reject.$(CAT8EXT) $(RM) $(AMANDIR)/cat$(MAN8EXT)/disable.$(CAT8EXT) - $(LN) enable.$(CAT1EXT) $(AMANDIR)/cat$(MAN8EXT)/disable.$(CAT8EXT) + $(LN) enable.$(CAT8EXT) $(AMANDIR)/cat$(MAN8EXT)/disable.$(CAT8EXT) # -# End of "$Id: Makefile,v 1.12 2001/02/20 17:33:00 mike Exp $". +# End of "$Id: Makefile,v 1.12.2.1 2001/12/26 16:52:41 mike Exp $". # diff --git a/man/cups-config.man b/man/cups-config.man index e681adaae8..e4cad76cea 100644 --- a/man/cups-config.man +++ b/man/cups-config.man @@ -1,5 +1,5 @@ .\" -.\" "$Id: cups-config.man,v 1.1 2001/10/26 03:16:48 mike Exp $" +.\" "$Id: cups-config.man,v 1.1.2.1 2001/12/26 16:52:41 mike Exp $" .\" .\" cups-config man page for the Common UNIX Printing System (CUPS). .\" @@ -91,5 +91,5 @@ http://localhost:631/documentation.html .SH COPYRIGHT Copyright 1993-2001 by Easy Software Products, All Rights Reserved. .\" -.\" End of "$Id: cups-config.man,v 1.1 2001/10/26 03:16:48 mike Exp $". +.\" End of "$Id: cups-config.man,v 1.1.2.1 2001/12/26 16:52:41 mike Exp $". .\" diff --git a/man/cupsaddsmb.man b/man/cupsaddsmb.man index 4d7da8879b..a6fcab69f3 100644 --- a/man/cupsaddsmb.man +++ b/man/cupsaddsmb.man @@ -1,5 +1,5 @@ .\" -.\" "$Id: cupsaddsmb.man,v 1.2 2001/11/09 17:19:41 mike Exp $" +.\" "$Id: cupsaddsmb.man,v 1.2.2.1 2001/12/26 16:52:41 mike Exp $" .\" .\" cupsaddsmb man page for the Common UNIX Printing System (CUPS). .\" @@ -110,5 +110,5 @@ http://localhost:631/documentation.html .SH COPYRIGHT Copyright 1993-2001 by Easy Software Products, All Rights Reserved. .\" -.\" End of "$Id: cupsaddsmb.man,v 1.2 2001/11/09 17:19:41 mike Exp $". +.\" End of "$Id: cupsaddsmb.man,v 1.2.2.1 2001/12/26 16:52:41 mike Exp $". .\" diff --git a/man/lp.man b/man/lp.man index edfd8c6d90..a76adcc1c8 100644 --- a/man/lp.man +++ b/man/lp.man @@ -1,5 +1,5 @@ .\" -.\" "$Id: lp.man,v 1.6 2001/03/09 14:26:54 mike Exp $" +.\" "$Id: lp.man,v 1.6.2.1 2001/12/26 16:52:41 mike Exp $" .\" .\" lp/cancel man page for the Common UNIX Printing System (CUPS). .\" @@ -21,7 +21,7 @@ .\" EMail: cups-info@cups.org .\" WWW: http://www.cups.org .\" -.TH lp 1 "Common UNIX Printing System" "23 January 2001" "Easy Software Products" +.TH lp 1 "Common UNIX Printing System" "25 September 2001" "Easy Software Products" .SH NAME lp \- print files .br @@ -36,7 +36,7 @@ cancel \- cancel jobs .I num-copies [ \-o .I option -] [ \-p/q +] [ \-q .I priority ] [ \-s ] [ \-t .I title @@ -57,7 +57,7 @@ cancel \- cancel jobs .I num-copies [ \-o .I option -] [ \-p/q +] [ \-q .I priority ] [ \-t .I title @@ -114,10 +114,10 @@ Sets the number of copies to print from 1 to 100. .br Sets a job option. .TP 5 -\-p/q \fIpriority\fR +\-q \fIpriority\fR .br -Sets the job priority from 1 (lowest) to 100 (highest). The default priority -is 50. +Sets the job priority from 1 (lowest) to 100 (highest). The +default priority is 50. .TP 5 \-s .br @@ -145,6 +145,10 @@ any printable character except SPACE and TAB. Also, printer and class names are \fBnot\fR case-sensitive. .LP The "m" option is not functional in CUPS 1.1. +.LP +The "q" option accepts a different range of values than the +Solaris lp command, matching the IPP job priority values (1-100) +instead of the Solaris values (0-39). .SH SEE ALSO lpstat(1), CUPS Software Users Manual, @@ -152,5 +156,5 @@ http://localhost:631/documentation.html .SH COPYRIGHT Copyright 1993-2001 by Easy Software Products, All Rights Reserved. .\" -.\" End of "$Id: lp.man,v 1.6 2001/03/09 14:26:54 mike Exp $". +.\" End of "$Id: lp.man,v 1.6.2.1 2001/12/26 16:52:41 mike Exp $". .\" diff --git a/pdftops/Array.cxx b/pdftops/Array.cxx index 9681b6854c..141afc8cab 100644 --- a/pdftops/Array.cxx +++ b/pdftops/Array.cxx @@ -19,7 +19,8 @@ // Array //------------------------------------------------------------------------ -Array::Array() { +Array::Array(XRef *xrefA) { + xref = xrefA; elems = NULL; size = length = 0; ref = 1; @@ -43,7 +44,7 @@ void Array::add(Object *elem) { } Object *Array::get(int i, Object *obj) { - return elems[i].fetch(obj); + return elems[i].fetch(xref, obj); } Object *Array::getNF(int i, Object *obj) { diff --git a/pdftops/Array.h b/pdftops/Array.h index ecf2eea6fd..1616fc33f4 100644 --- a/pdftops/Array.h +++ b/pdftops/Array.h @@ -15,6 +15,8 @@ #include "Object.h" +class XRef; + //------------------------------------------------------------------------ // Array //------------------------------------------------------------------------ @@ -23,7 +25,7 @@ class Array { public: // Constructor. - Array(); + Array(XRef *xrefA); // Destructor. ~Array(); @@ -44,6 +46,7 @@ public: private: + XRef *xref; // the xref table for this PDF file Object *elems; // array of elements int size; // size of array int length; // number of elements in array diff --git a/pdftops/Catalog.cxx b/pdftops/Catalog.cxx index 815cca3ae0..fadb4763b6 100644 --- a/pdftops/Catalog.cxx +++ b/pdftops/Catalog.cxx @@ -13,6 +13,7 @@ #include #include "gmem.h" #include "Object.h" +#include "XRef.h" #include "Array.h" #include "Dict.h" #include "Page.h" @@ -24,24 +25,27 @@ // Catalog //------------------------------------------------------------------------ -Catalog::Catalog(Object *catDict) { - Object pagesDict; +Catalog::Catalog(XRef *xrefA, GBool printCommands) { + Object catDict, pagesDict; Object obj, obj2; int numPages0; int i; ok = gTrue; + xref = xrefA; pages = NULL; pageRefs = NULL; numPages = pagesSize = 0; + baseURI = NULL; - if (!catDict->isDict()) { - error(-1, "Catalog object is wrong type (%s)", catDict->getTypeName()); + xref->getCatalog(&catDict); + if (!catDict.isDict()) { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); goto err1; } // read page tree - catDict->dictLookup("Pages", &pagesDict); + catDict.dictLookup("Pages", &pagesDict); // This should really be isDict("Pages"), but I've seen at least one // PDF file where the /Type entry is missing. if (!pagesDict.isDict()) { @@ -64,25 +68,24 @@ Catalog::Catalog(Object *catDict) { pageRefs[i].num = -1; pageRefs[i].gen = -1; } - numPages = readPageTree(pagesDict.getDict(), NULL, 0); + numPages = readPageTree(pagesDict.getDict(), NULL, 0, printCommands); if (numPages != numPages0) { error(-1, "Page count in top-level pages object is incorrect"); } pagesDict.free(); // read named destination dictionary - catDict->dictLookup("Dests", &dests); + catDict.dictLookup("Dests", &dests); // read root of named destination tree - if (catDict->dictLookup("Names", &obj)->isDict()) + if (catDict.dictLookup("Names", &obj)->isDict()) obj.dictLookup("Dests", &nameTree); else nameTree.initNull(); obj.free(); // read base URI - baseURI = NULL; - if (catDict->dictLookup("URI", &obj)->isDict()) { + if (catDict.dictLookup("URI", &obj)->isDict()) { if (obj.dictLookup("Base", &obj2)->isString()) { baseURI = obj2.getString()->copy(); } @@ -90,6 +93,7 @@ Catalog::Catalog(Object *catDict) { } obj.free(); + catDict.free(); return; err3: @@ -97,6 +101,7 @@ Catalog::Catalog(Object *catDict) { err2: pagesDict.free(); err1: + catDict.free(); dests.initNull(); nameTree.initNull(); ok = gFalse; @@ -121,7 +126,8 @@ Catalog::~Catalog() { } } -int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start) { +int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start, + GBool printCommands) { Object kids; Object kid; Object kidRef; @@ -140,7 +146,7 @@ int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start) { kids.arrayGet(i, &kid); if (kid.isDict("Page")) { attrs2 = new PageAttrs(attrs1, kid.getDict()); - page = new Page(start+1, kid.getDict(), attrs2); + page = new Page(xref, start+1, kid.getDict(), attrs2, printCommands); if (!page->isOk()) { ++start; goto err3; @@ -166,7 +172,8 @@ int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start) { // This should really be isDict("Pages"), but I've seen at least one // PDF file where the /Type entry is missing. } else if (kid.isDict()) { - if ((start = readPageTree(kid.getDict(), attrs1, start)) < 0) + if ((start = readPageTree(kid.getDict(), attrs1, start, printCommands)) + < 0) goto err2; } else { error(-1, "Kid object (page %d) is wrong type (%s)", diff --git a/pdftops/Catalog.h b/pdftops/Catalog.h index b0f3143233..5bf0c74a79 100644 --- a/pdftops/Catalog.h +++ b/pdftops/Catalog.h @@ -13,6 +13,7 @@ #pragma interface #endif +class XRef; class Object; class Page; class PageAttrs; @@ -27,7 +28,7 @@ class Catalog { public: // Constructor. - Catalog(Object *catDict); + Catalog(XRef *xrefA, GBool printCommands = gFalse); // Destructor. ~Catalog(); @@ -57,6 +58,7 @@ public: private: + XRef *xref; // the xref table for this PDF file Page **pages; // array of pages Ref *pageRefs; // object ID for each page int numPages; // number of pages @@ -66,7 +68,8 @@ private: GString *baseURI; // base URI for URI-type links GBool ok; // true if catalog is valid - int readPageTree(Dict *pages, PageAttrs *attrs, int start); + int readPageTree(Dict *pages, PageAttrs *attrs, int start, + GBool printCommands); Object *findDestInTree(Object *tree, GString *name, Object *obj); }; diff --git a/pdftops/CompactFontInfo.h b/pdftops/CompactFontInfo.h index 159f4bf36b..c642660297 100644 --- a/pdftops/CompactFontInfo.h +++ b/pdftops/CompactFontInfo.h @@ -9,7 +9,7 @@ #ifndef COMPACTFONTINFO_H #define COMPACTFONTINFO_H -static const char *type1CStdStrings[391] = { +static char *type1CStdStrings[391] = { ".notdef", "space", "exclam", diff --git a/pdftops/Decrypt.cxx b/pdftops/Decrypt.cxx index ae9b73239d..623f59417f 100644 --- a/pdftops/Decrypt.cxx +++ b/pdftops/Decrypt.cxx @@ -28,42 +28,96 @@ static Guchar passwordPad[32] = { // Decrypt //------------------------------------------------------------------------ -Decrypt::Decrypt(Guchar *fileKey, int objNum, int objGen) { +Decrypt::Decrypt(Guchar *fileKey, int keyLength, int objNum, int objGen) { + int i; + // construct object key - objKey[0] = fileKey[0]; - objKey[1] = fileKey[1]; - objKey[2] = fileKey[2]; - objKey[3] = fileKey[3]; - objKey[4] = fileKey[4]; - objKey[5] = objNum & 0xff; - objKey[6] = (objNum >> 8) & 0xff; - objKey[7] = (objNum >> 16) & 0xff; - objKey[8] = objGen & 0xff; - objKey[9] = (objGen >> 8) & 0xff; - md5(objKey, 10, objKey); + for (i = 0; i < keyLength; ++i) { + objKey[i] = fileKey[i]; + } + objKey[keyLength] = objNum & 0xff; + objKey[keyLength + 1] = (objNum >> 8) & 0xff; + objKey[keyLength + 2] = (objNum >> 16) & 0xff; + objKey[keyLength + 3] = objGen & 0xff; + objKey[keyLength + 4] = (objGen >> 8) & 0xff; + md5(objKey, keyLength + 5, objKey); // set up for decryption x = y = 0; - rc4InitKey(objKey, 10, state); + if ((objKeyLength = keyLength + 5) > 16) { + objKeyLength = 16; + } + rc4InitKey(objKey, objKeyLength, state); } void Decrypt::reset() { x = y = 0; - rc4InitKey(objKey, 10, state); + rc4InitKey(objKey, objKeyLength, state); } Guchar Decrypt::decryptByte(Guchar c) { return rc4DecryptByte(state, &x, &y, c); } -GBool Decrypt::makeFileKey(GString *ownerKey, GString *userKey, +GBool Decrypt::makeFileKey(int encVersion, int encRevision, int keyLength, + GString *ownerKey, GString *userKey, int permissions, GString *fileID, - GString *userPassword, Guchar *fileKey) { - Guchar *buf; - Guchar userTest[32]; + GString *ownerPassword, GString *userPassword, + Guchar *fileKey, GBool *ownerPasswordOk) { + Guchar test[32]; + GString *userPassword2; Guchar fState[256]; Guchar fx, fy; int len, i; + + // try using the supplied owner password to generate the user password + if (ownerPassword) { + len = ownerPassword->getLength(); + if (len < 32) { + memcpy(test, ownerPassword->getCString(), len); + memcpy(test + len, passwordPad, 32 - len); + } else { + memcpy(test, ownerPassword->getCString(), 32); + } + } else { + memcpy(test, passwordPad, 32); + } + md5(test, 32, test); + if (encRevision == 3) { + for (i = 0; i < 50; ++i) { + md5(test, 16, test); + } + } + rc4InitKey(test, keyLength, fState); + fx = fy = 0; + for (i = 0; i < 32; ++i) { + test[i] = rc4DecryptByte(fState, &fx, &fy, ownerKey->getChar(i)); + } + userPassword2 = new GString((char *)test, 32); + if (makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey, + permissions, fileID, userPassword2, fileKey)) { + *ownerPasswordOk = gTrue; + delete userPassword2; + return gTrue; + } + *ownerPasswordOk = gFalse; + delete userPassword2; + + // try using the supplied user password + return makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey, + permissions, fileID, userPassword, fileKey); +} + +GBool Decrypt::makeFileKey2(int encVersion, int encRevision, int keyLength, + GString *ownerKey, GString *userKey, + int permissions, GString *fileID, + GString *userPassword, Guchar *fileKey) { + Guchar *buf; + Guchar test[32]; + Guchar fState[256]; + Guchar tmpKey[16]; + Guchar fx, fy; + int len, i, j; GBool ok; // generate file key @@ -86,16 +140,41 @@ GBool Decrypt::makeFileKey(GString *ownerKey, GString *userKey, buf[67] = (permissions >> 24) & 0xff; memcpy(buf + 68, fileID->getCString(), fileID->getLength()); md5(buf, 68 + fileID->getLength(), fileKey); + if (encRevision == 3) { + for (i = 0; i < 50; ++i) { + md5(fileKey, 16, fileKey); + } + } - // test user key - fx = fy = 0; - rc4InitKey(fileKey, 5, fState); - for (i = 0; i < 32; ++i) { - userTest[i] = rc4DecryptByte(fState, &fx, &fy, userKey->getChar(i)); + // test user password + if (encRevision == 2) { + rc4InitKey(fileKey, keyLength, fState); + fx = fy = 0; + for (i = 0; i < 32; ++i) { + test[i] = rc4DecryptByte(fState, &fx, &fy, userKey->getChar(i)); + } + ok = memcmp(test, passwordPad, 32) == 0; + } else if (encRevision == 3) { + memcpy(test, userKey->getCString(), 32); + for (i = 19; i >= 0; --i) { + for (j = 0; j < keyLength; ++j) { + tmpKey[j] = fileKey[j] ^ i; + } + rc4InitKey(tmpKey, keyLength, fState); + fx = fy = 0; + for (j = 0; j < 32; ++j) { + test[j] = rc4DecryptByte(fState, &fx, &fy, test[j]); + } + } + memcpy(buf, passwordPad, 32); + memcpy(buf + 32, fileID->getCString(), fileID->getLength()); + md5(buf, 32 + fileID->getLength(), buf); + ok = memcmp(test, buf, 16) == 0; + } else { + ok = gFalse; } - ok = memcmp(userTest, passwordPad, 32) == 0; - gfree(buf); + gfree(buf); return ok; } @@ -136,6 +215,7 @@ static Guchar rc4DecryptByte(Guchar *state, Guchar *x, Guchar *y, Guchar c) { // MD5 message digest //------------------------------------------------------------------------ +// this works around a bug in older Sun compilers static inline Gulong rotateLeft(Gulong x, int r) { x &= 0xffffffff; return ((x << r) | (x >> (32 - r))) & 0xffffffff; diff --git a/pdftops/Decrypt.h b/pdftops/Decrypt.h index 3ea43741dc..1bdb2b7ec2 100644 --- a/pdftops/Decrypt.h +++ b/pdftops/Decrypt.h @@ -24,7 +24,7 @@ class Decrypt { public: // Initialize the decryptor object. - Decrypt(Guchar *fileKey, int objNum, int objGen); + Decrypt(Guchar *fileKey, int keyLength, int objNum, int objGen); // Reset decryption. void reset(); @@ -32,16 +32,26 @@ public: // Decrypt one byte. Guchar decryptByte(Guchar c); - // Generate a file key. The buffer must have space for - // at least 16 bytes. Checks user key and returns gTrue if okay. - // may be NULL. - static GBool makeFileKey(GString *ownerKey, GString *userKey, + // Generate a file key. The buffer must have space for at + // least 16 bytes. Checks and then + // and returns true if either is correct. Sets if + // the owner password was correct. Either or both of the passwords + // may be NULL, which is treated as an empty string. + static GBool makeFileKey(int encVersion, int encRevision, int keyLength, + GString *ownerKey, GString *userKey, int permissions, GString *fileID, - GString *userPassword, Guchar *fileKey); + GString *ownerPassword, GString *userPassword, + Guchar *fileKey, GBool *ownerPasswordOk); private: - Guchar objKey[16]; + static GBool makeFileKey2(int encVersion, int encRevision, int keyLength, + GString *ownerKey, GString *userKey, + int permissions, GString *fileID, + GString *userPassword, Guchar *fileKey); + + int objKeyLength; + Guchar objKey[21]; Guchar state[256]; Guchar x, y; }; diff --git a/pdftops/Dict.cxx b/pdftops/Dict.cxx index 9ec4815bd9..1ebadfce0a 100644 --- a/pdftops/Dict.cxx +++ b/pdftops/Dict.cxx @@ -21,7 +21,8 @@ // Dict //------------------------------------------------------------------------ -Dict::Dict() { +Dict::Dict(XRef *xrefA) { + xref = xrefA; entries = NULL; size = length = 0; ref = 1; @@ -31,13 +32,13 @@ Dict::~Dict() { int i; for (i = 0; i < length; ++i) { - gfree((void *)entries[i].key); + gfree(entries[i].key); entries[i].val.free(); } gfree(entries); } -void Dict::add(const char *key, Object *val) { +void Dict::add(char *key, Object *val) { if (length + 1 > size) { size += 8; entries = (DictEntry *)grealloc(entries, size * sizeof(DictEntry)); @@ -47,7 +48,7 @@ void Dict::add(const char *key, Object *val) { ++length; } -inline DictEntry *Dict::find(const char *key) { +inline DictEntry *Dict::find(char *key) { int i; for (i = 0; i < length; ++i) { @@ -57,30 +58,30 @@ inline DictEntry *Dict::find(const char *key) { return NULL; } -GBool Dict::is(const char *type) { +GBool Dict::is(char *type) { DictEntry *e; return (e = find("Type")) && e->val.isName(type); } -Object *Dict::lookup(const char *key, Object *obj) { +Object *Dict::lookup(char *key, Object *obj) { DictEntry *e; - return (e = find(key)) ? e->val.fetch(obj) : obj->initNull(); + return (e = find(key)) ? e->val.fetch(xref, obj) : obj->initNull(); } -Object *Dict::lookupNF(const char *key, Object *obj) { +Object *Dict::lookupNF(char *key, Object *obj) { DictEntry *e; return (e = find(key)) ? e->val.copy(obj) : obj->initNull(); } -const char *Dict::getKey(int i) { +char *Dict::getKey(int i) { return entries[i].key; } Object *Dict::getVal(int i, Object *obj) { - return entries[i].val.fetch(obj); + return entries[i].val.fetch(xref, obj); } Object *Dict::getValNF(int i, Object *obj) { diff --git a/pdftops/Dict.h b/pdftops/Dict.h index 37f656587c..c4f1ea58d4 100644 --- a/pdftops/Dict.h +++ b/pdftops/Dict.h @@ -20,7 +20,7 @@ //------------------------------------------------------------------------ struct DictEntry { - const char *key; + char *key; Object val; }; @@ -28,7 +28,7 @@ class Dict { public: // Constructor. - Dict(); + Dict(XRef *xrefA); // Destructor. ~Dict(); @@ -41,29 +41,35 @@ public: int getLength() { return length; } // Add an entry. NB: does not copy key. - void add(const char *key, Object *val); + void add(char *key, Object *val); // Check if dictionary is of specified type. - GBool is(const char *type); + GBool is(char *type); // Look up an entry and return the value. Returns a null object // if is not in the dictionary. - Object *lookup(const char *key, Object *obj); - Object *lookupNF(const char *key, Object *obj); + Object *lookup(char *key, Object *obj); + Object *lookupNF(char *key, Object *obj); // Iterative accessors. - const char *getKey(int i); + char *getKey(int i); Object *getVal(int i, Object *obj); Object *getValNF(int i, Object *obj); + // Set the xref pointer. This is only used in one special case: the + // trailer dictionary, which is read before the xref table is + // parsed. + void setXRef(XRef *xrefA) { xref = xrefA; } + private: + XRef *xref; // the xref table for this PDF file DictEntry *entries; // array of entries int size; // size of array int length; // number of entries in dictionary int ref; // reference count - DictEntry *find(const char *key); + DictEntry *find(char *key); }; #endif diff --git a/pdftops/Error.cxx b/pdftops/Error.cxx index 96a96d2bf2..81010e0199 100644 --- a/pdftops/Error.cxx +++ b/pdftops/Error.cxx @@ -34,13 +34,10 @@ void CDECL error(int pos, const char *msg, ...) { if (errQuiet) { return; } - if (printCommands) { - fflush(stdout); - } if (pos >= 0) { - fprintf(errFile, "ERROR: (%d): ", pos); + fprintf(errFile, "Error (%d): ", pos); } else { - fprintf(errFile, "ERROR: "); + fprintf(errFile, "Error: "); } va_start(args, msg); vfprintf(errFile, msg, args); diff --git a/pdftops/FontEncoding.cxx b/pdftops/FontEncoding.cxx index f526445019..3d084cc9da 100644 --- a/pdftops/FontEncoding.cxx +++ b/pdftops/FontEncoding.cxx @@ -21,7 +21,7 @@ // FontEncoding //------------------------------------------------------------------------ -inline int FontEncoding::hash(const char *name) { +inline int FontEncoding::hash(char *name) { Guint h; h = (Guint)name[0] & 0xff; @@ -33,7 +33,7 @@ inline int FontEncoding::hash(const char *name) { FontEncoding::FontEncoding() { int i; - encoding = (const char **)gmalloc(256 * sizeof(const char *)); + encoding = (char **)gmalloc(256 * sizeof(char *)); size = 256; freeEnc = gTrue; for (i = 0; i < 256; ++i) @@ -42,24 +42,24 @@ FontEncoding::FontEncoding() { hashTab[i] = -1; } -FontEncoding::FontEncoding(const char **nencoding, int nsize) { +FontEncoding::FontEncoding(char **encodingA, int sizeA) { int i; - encoding = nencoding; - size = nsize; + encoding = encodingA; + size = sizeA; freeEnc = gFalse; for (i = 0; i < fontEncHashSize; ++i) hashTab[i] = -1; for (i = 0; i < size; ++i) { - if (nencoding[i]) - addChar1(i, nencoding[i]); + if (encoding[i]) + addChar1(i, encoding[i]); } } FontEncoding::FontEncoding(FontEncoding *fontEnc) { int i; - encoding = (const char **)gmalloc(fontEnc->size * sizeof(const char *)); + encoding = (char **)gmalloc(fontEnc->size * sizeof(char *)); size = fontEnc->size; freeEnc = gTrue; for (i = 0; i < size; ++i) { @@ -69,7 +69,7 @@ FontEncoding::FontEncoding(FontEncoding *fontEnc) { memcpy(hashTab, fontEnc->hashTab, fontEncHashSize * sizeof(short)); } -void FontEncoding::addChar(int code, const char *name) { +void FontEncoding::addChar(int code, char *name) { int h, i; // replace character associated with code @@ -83,7 +83,7 @@ void FontEncoding::addChar(int code, const char *name) { if (++h == fontEncHashSize) h = 0; } - gfree((void *)encoding[code]); + gfree(encoding[code]); } // associate name with code @@ -93,7 +93,7 @@ void FontEncoding::addChar(int code, const char *name) { addChar1(code, name); } -void FontEncoding::addChar1(int code, const char *name) { +void FontEncoding::addChar1(int code, char *name) { int h, i, code2; // insert name in hash table @@ -121,13 +121,13 @@ FontEncoding::~FontEncoding() { if (freeEnc) { for (i = 0; i < size; ++i) { if (encoding[i]) - gfree((void *)encoding[i]); + gfree(encoding[i]); } - gfree((void *)encoding); + gfree(encoding); } } -int FontEncoding::getCharCode(const char *name) { +int FontEncoding::getCharCode(char *name) { int h, i, code; h = hash(name); diff --git a/pdftops/FontEncoding.h b/pdftops/FontEncoding.h index 120858b9bd..9a5695dbe5 100644 --- a/pdftops/FontEncoding.h +++ b/pdftops/FontEncoding.h @@ -28,7 +28,7 @@ public: FontEncoding(); // Construct an encoding from an array of char names. - FontEncoding(const char **encoding, int size); + FontEncoding(char **encodingA, int sizeA); // Destructor. ~FontEncoding(); @@ -40,21 +40,21 @@ public: int getSize() { return size; } // Add a char to the encoding. - void addChar(int code, const char *name); + void addChar(int code, char *name); // Return the character name associated with . - const char *getCharName(int code) { return encoding[code]; } + char *getCharName(int code) { return encoding[code]; } // Return the code associated with . - int getCharCode(const char *name); + int getCharCode(char *name); private: FontEncoding(FontEncoding *fontEnc); - int hash(const char *name); - void addChar1(int code, const char *name); + int hash(char *name); + void addChar1(int code, char *name); - const char **encoding; // code --> name mapping + char **encoding; // code --> name mapping int size; // number of codes GBool freeEnc; // should we free the encoding array? short // name --> code hash table diff --git a/pdftops/FontFile.cxx b/pdftops/FontFile.cxx index 5ec923a0db..4054db7cd0 100644 --- a/pdftops/FontFile.cxx +++ b/pdftops/FontFile.cxx @@ -32,7 +32,7 @@ static char *getString(int sid, Guchar *stringIdxPtr, //------------------------------------------------------------------------ -static inline const char *nextLine(const char *line, const char *end) { +static inline char *nextLine(char *line, char *end) { while (line < end && *line != '\n' && *line != '\r') ++line; while (line < end && *line == '\n' || *line == '\r') @@ -56,9 +56,8 @@ FontFile::~FontFile() { // Type1FontFile //------------------------------------------------------------------------ -Type1FontFile::Type1FontFile(const char *file, int len) { - const char *line, *line1; - char *p, *p2; +Type1FontFile::Type1FontFile(char *file, int len) { + char *line, *line1, *p, *p2; char buf[256]; char c; int n, code, i; @@ -125,7 +124,7 @@ Type1FontFile::Type1FontFile(const char *file, int len) { Type1FontFile::~Type1FontFile() { if (name) - gfree((void *)name); + gfree(name); if (encoding && freeEnc) delete encoding; } @@ -140,11 +139,11 @@ FontEncoding *Type1FontFile::getEncoding(GBool taken) { // Type1CFontFile //------------------------------------------------------------------------ -Type1CFontFile::Type1CFontFile(const char *file, int len) { +Type1CFontFile::Type1CFontFile(char *file, int len) { char buf[256]; Guchar *topPtr, *idxStartPtr, *idxPtr0, *idxPtr1; Guchar *stringIdxPtr, *stringStartPtr; - int idxOffSize, stringOffSize; + int topOffSize, idxOffSize, stringOffSize; int nFonts, nStrings, nGlyphs; int nCodes, nRanges, nLeft, nSups; Gushort *glyphNames; @@ -157,14 +156,13 @@ Type1CFontFile::Type1CFontFile(const char *file, int len) { int key; int i, j, n; - (void)len; - name = NULL; encoding = NULL; freeEnc = gTrue; // read header topPtr = (Guchar *)file + (file[2] & 0xff); + topOffSize = file[3] & 0xff; // read name index (first font only) nFonts = getWord(topPtr, 2); @@ -175,7 +173,7 @@ Type1CFontFile::Type1CFontFile(const char *file, int len) { idxPtr1 = idxStartPtr + getWord(topPtr + idxOffSize, idxOffSize); if ((n = idxPtr1 - idxPtr0) > 255) n = 255; - strncpy(buf, (const char *)idxPtr0, n); + strncpy(buf, (char *)idxPtr0, n); buf[n] = '\0'; name = copyString(buf); topPtr = idxStartPtr + getWord(topPtr + nFonts * idxOffSize, idxOffSize); @@ -318,7 +316,7 @@ Type1CFontFile::Type1CFontFile(const char *file, int len) { Type1CFontFile::~Type1CFontFile() { if (name) - gfree((void *)name); + gfree(name); if (encoding && freeEnc) delete encoding; } @@ -415,7 +413,7 @@ static char *getString(int sid, Guchar *stringIdxPtr, stringOffSize); if ((len = idxPtr1 - idxPtr0) > 255) len = 255; - strncpy(buf, (const char *)idxPtr0, len); + strncpy(buf, (char *)idxPtr0, len); buf[len] = '\0'; } return buf; @@ -425,10 +423,10 @@ static char *getString(int sid, Guchar *stringIdxPtr, // Type1CFontConverter //------------------------------------------------------------------------ -Type1CFontConverter::Type1CFontConverter(const char *nfile, int nlen, FILE *nout) { - file = nfile; - len = nlen; - out = nout; +Type1CFontConverter::Type1CFontConverter(char *fileA, int lenA, FILE *outA) { + file = fileA; + len = lenA; + out = outA; r1 = 55665; line = 0; } @@ -437,7 +435,7 @@ Type1CFontConverter::~Type1CFontConverter() { } void Type1CFontConverter::convert() { - const char *fontName; + char *fontName; struct { int version; int notice; @@ -464,7 +462,7 @@ void Type1CFontConverter::convert() { char buf[256], eBuf[256]; Guchar *topPtr, *idxStartPtr, *idxPtr0, *idxPtr1; Guchar *stringIdxPtr, *stringStartPtr; - int idxOffSize, stringOffSize; + int topOffSize, idxOffSize, stringOffSize; int nFonts, nStrings, nGlyphs; int nCodes, nRanges, nLeft, nSups; Gushort *glyphNames; @@ -479,6 +477,7 @@ void Type1CFontConverter::convert() { // read header topPtr = (Guchar *)file + (file[2] & 0xff); + topOffSize = file[3] & 0xff; // read name (first font only) nFonts = getWord(topPtr, 2); @@ -489,7 +488,7 @@ void Type1CFontConverter::convert() { idxPtr1 = idxStartPtr + getWord(topPtr + idxOffSize, idxOffSize); if ((n = idxPtr1 - idxPtr0) > 255) n = 255; - strncpy(buf, (const char *)idxPtr0, n); + strncpy(buf, (char *)idxPtr0, n); buf[n] = '\0'; fontName = copyString(buf); topPtr = idxStartPtr + getWord(topPtr + nFonts * idxOffSize, idxOffSize); @@ -587,8 +586,15 @@ void Type1CFontConverter::convert() { topPtr = stringStartPtr + getWord(topPtr + nStrings * stringOffSize, stringOffSize); - // skip global subrs +#if 1 //~ + // get global subrs + int nGSubrs; + int gSubrOffSize; + + nGSubrs = getWord(topPtr, 2); + gSubrOffSize = topPtr[2]; topPtr += 3; +#endif // write header and font dictionary, up to encoding fprintf(out, "%%!FontType1-1.0: %s", fontName); @@ -845,7 +851,7 @@ void Type1CFontConverter::convert() { nominalWidthXFP = fp[0]; break; default: - error(-1, "Uknown Type 1C private dict entry %04x", key); + error(-1, "Unknown Type 1C private dict entry %04x", key); break; } i = 0; @@ -918,11 +924,11 @@ void Type1CFontConverter::convert() { // clean up if (dict.charset > 2) - gfree((void *)glyphNames); - gfree((void *)fontName); + gfree(glyphNames); + gfree(fontName); } -void Type1CFontConverter::eexecWrite(const char *s) { +void Type1CFontConverter::eexecWrite(char *s) { Guchar *p; Guchar x; @@ -939,7 +945,7 @@ void Type1CFontConverter::eexecWrite(const char *s) { } } -void Type1CFontConverter::cvtGlyph(const char *name, Guchar *s, int n) { +void Type1CFontConverter::cvtGlyph(char *name, Guchar *s, int n) { int nHints; int x; GBool first = gTrue; @@ -1509,12 +1515,12 @@ void Type1CFontConverter::cvtGlyphWidth(GBool useOp) { eexecDumpOp1(13); } -void Type1CFontConverter::eexecDumpNum(double x, GBool nfp) { +void Type1CFontConverter::eexecDumpNum(double x, GBool fpA) { Guchar buf[12]; int y, n; n = 0; - if (nfp) { + if (fpA) { if (x >= -32768 && x < 32768) { y = (int)(x * 256.0); buf[0] = 255; @@ -1557,16 +1563,16 @@ void Type1CFontConverter::eexecDumpNum(double x, GBool nfp) { n = 5; } } - charBuf->append((const char *)buf, n); + charBuf->append((char *)buf, n); } -void Type1CFontConverter::eexecDumpOp1(int nop) { - charBuf->append((char)nop); +void Type1CFontConverter::eexecDumpOp1(int opA) { + charBuf->append((char)opA); } -void Type1CFontConverter::eexecDumpOp2(int nop) { +void Type1CFontConverter::eexecDumpOp2(int opA) { charBuf->append((char)12); - charBuf->append((char)nop); + charBuf->append((char)opA); } void Type1CFontConverter::eexecWriteCharstring(Guchar *s, int n) { @@ -1595,7 +1601,7 @@ void Type1CFontConverter::eexecWriteCharstring(Guchar *s, int n) { } } -void Type1CFontConverter::getDeltaInt(char *buf, const char *name, double *nop, +void Type1CFontConverter::getDeltaInt(char *buf, char *name, double *opA, int n) { int x, i; @@ -1603,14 +1609,14 @@ void Type1CFontConverter::getDeltaInt(char *buf, const char *name, double *nop, buf += strlen(buf); x = 0; for (i = 0; i < n; ++i) { - x += (int)nop[i]; + x += (int)opA[i]; sprintf(buf, "%s%d", i > 0 ? " " : "", x); buf += strlen(buf); } sprintf(buf, "] def\n"); } -void Type1CFontConverter::getDeltaReal(char *buf, const char *name, double *nop, +void Type1CFontConverter::getDeltaReal(char *buf, char *name, double *opA, int n) { double x; int i; @@ -1619,9 +1625,906 @@ void Type1CFontConverter::getDeltaReal(char *buf, const char *name, double *nop, buf += strlen(buf); x = 0; for (i = 0; i < n; ++i) { - x += nop[i]; + x += opA[i]; sprintf(buf, "%s%g", i > 0 ? " " : "", x); buf += strlen(buf); } sprintf(buf, "] def\n"); } + +//------------------------------------------------------------------------ +// TrueTypeFontFile +//------------------------------------------------------------------------ + +// +// Terminology +// ----------- +// +// character code = number used as an element of a text string +// +// character name = glyph name = name for a particular glyph within a +// font +// +// glyph index = position (within some internal table in the font) +// where the instructions to draw a particular glyph are +// stored +// +// Type 1 fonts +// ------------ +// +// Type 1 fonts contain: +// +// Encoding: array of glyph names, maps char codes to glyph names +// +// Encoding[charCode] = charName +// +// CharStrings: dictionary of instructions, keyed by character names, +// maps character name to glyph data +// +// CharStrings[charName] = glyphData +// +// TrueType fonts +// -------------- +// +// TrueType fonts contain: +// +// 'cmap' table: mapping from character code to glyph index; there may +// be multiple cmaps in a TrueType font +// +// cmap[charCode] = glyphIdx +// +// 'post' table: mapping from glyph index to glyph name +// +// post[glyphIdx] = glyphName +// +// Type 42 fonts +// ------------- +// +// Type 42 fonts contain: +// +// Encoding: array of glyph names, maps char codes to glyph names +// +// Encoding[charCode] = charName +// +// CharStrings: dictionary of glyph indexes, keyed by character names, +// maps character name to glyph index +// +// CharStrings[charName] = glyphIdx +// + +struct TTFontTableHdr { + char tag[4]; + Guint checksum; + Guint offset; + Guint length; +}; + +// TrueType tables required by the Type 42 spec. +static char *t42ReqTables[9] = { + "head", + "hhea", + "loca", + "maxp", + "cvt ", + "prep", + "glyf", + "hmtx", + "fpgm" +}; + +// Glyph names in some arbitrary standard that Apple uses for their +// TrueType fonts. +static char *macGlyphNames[258] = { + ".notdef", + "null", + "CR", + "space", + "exclam", + "quotedbl", + "numbersign", + "dollar", + "percent", + "ampersand", + "quotesingle", + "parenleft", + "parenright", + "asterisk", + "plus", + "comma", + "hyphen", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less", + "equal", + "greater", + "question", + "at", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "bracketleft", + "backslash", + "bracketright", + "asciicircum", + "underscore", + "grave", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "braceleft", + "bar", + "braceright", + "asciitilde", + "Adieresis", + "Aring", + "Ccedilla", + "Eacute", + "Ntilde", + "Odieresis", + "Udieresis", + "aacute", + "agrave", + "acircumflex", + "adieresis", + "atilde", + "aring", + "ccedilla", + "eacute", + "egrave", + "ecircumflex", + "edieresis", + "iacute", + "igrave", + "icircumflex", + "idieresis", + "ntilde", + "oacute", + "ograve", + "ocircumflex", + "odieresis", + "otilde", + "uacute", + "ugrave", + "ucircumflex", + "udieresis", + "dagger", + "degree", + "cent", + "sterling", + "section", + "bullet", + "paragraph", + "germandbls", + "registered", + "copyright", + "trademark", + "acute", + "dieresis", + "notequal", + "AE", + "Oslash", + "infinity", + "plusminus", + "lessequal", + "greaterequal", + "yen", + "mu1", + "partialdiff", + "summation", + "product", + "pi", + "integral", + "ordfeminine", + "ordmasculine", + "Ohm", + "ae", + "oslash", + "questiondown", + "exclamdown", + "logicalnot", + "radical", + "florin", + "approxequal", + "increment", + "guillemotleft", + "guillemotright", + "ellipsis", + "nbspace", + "Agrave", + "Atilde", + "Otilde", + "OE", + "oe", + "endash", + "emdash", + "quotedblleft", + "quotedblright", + "quoteleft", + "quoteright", + "divide", + "lozenge", + "ydieresis", + "Ydieresis", + "fraction", + "currency", + "guilsinglleft", + "guilsinglright", + "fi", + "fl", + "daggerdbl", + "periodcentered", + "quotesinglbase", + "quotedblbase", + "perthousand", + "Acircumflex", + "Ecircumflex", + "Aacute", + "Edieresis", + "Egrave", + "Iacute", + "Icircumflex", + "Idieresis", + "Igrave", + "Oacute", + "Ocircumflex", + "applelogo", + "Ograve", + "Uacute", + "Ucircumflex", + "Ugrave", + "dotlessi", + "circumflex", + "tilde", + "overscore", + "breve", + "dotaccent", + "ring", + "cedilla", + "hungarumlaut", + "ogonek", + "caron", + "Lslash", + "lslash", + "Scaron", + "scaron", + "Zcaron", + "zcaron", + "brokenbar", + "Eth", + "eth", + "Yacute", + "yacute", + "Thorn", + "thorn", + "minus", + "multiply", + "onesuperior", + "twosuperior", + "threesuperior", + "onehalf", + "onequarter", + "threequarters", + "franc", + "Gbreve", + "gbreve", + "Idot", + "Scedilla", + "scedilla", + "Cacute", + "cacute", + "Ccaron", + "ccaron", + "dmacron" +}; + +TrueTypeFontFile::TrueTypeFontFile(char *fileA, int lenA) { + int pos, i; + + file = fileA; + len = lenA; + + encoding = NULL; + freeEnc = gTrue; + + // read table directory + nTables = getUShort(4); + tableHdrs = (TTFontTableHdr *)gmalloc(nTables * sizeof(TTFontTableHdr)); + pos = 12; + for (i = 0; i < nTables; ++i) { + tableHdrs[i].tag[0] = getByte(pos+0); + tableHdrs[i].tag[1] = getByte(pos+1); + tableHdrs[i].tag[2] = getByte(pos+2); + tableHdrs[i].tag[3] = getByte(pos+3); + tableHdrs[i].checksum = getULong(pos+4); + tableHdrs[i].offset = getULong(pos+8); + tableHdrs[i].length = getULong(pos+12); + pos += 16; + } + + // check for tables that are required by both the TrueType spec + // and the Type 42 spec + if (seekTable("head") < 0 || + seekTable("hhea") < 0 || + seekTable("loca") < 0 || + seekTable("maxp") < 0 || + seekTable("glyf") < 0 || + seekTable("hmtx") < 0) { + error(-1, "TrueType font file is missing a required table"); + return; + } + + // read the 'head' table + pos = seekTable("head"); + bbox[0] = getShort(pos + 36); + bbox[1] = getShort(pos + 38); + bbox[2] = getShort(pos + 40); + bbox[3] = getShort(pos + 42); + locaFmt = getShort(pos + 50); + + // read the 'maxp' table + pos = seekTable("maxp"); + nGlyphs = getUShort(pos + 4); +} + +TrueTypeFontFile::~TrueTypeFontFile() { + if (encoding && freeEnc) { + delete encoding; + } + gfree(tableHdrs); +} + +char *TrueTypeFontFile::getName() { + return NULL; +} + +FontEncoding *TrueTypeFontFile::getEncoding(GBool taken) { + int cmap[256]; + int nCmaps, cmapPlatform, cmapEncoding, cmapFmt, cmapLen, cmapOffset; + int segCnt, segStart, segEnd, segDelta, segOffset; + int pos, i, j, k; + Guint fmt; + GString *s; + int stringIdx, stringPos, n; + + //----- construct the (char code) -> (glyph idx) mapping + + // map everything to the missing glyph + for (i = 0; i < 256; ++i) { + cmap[i] = 0; + } + + // look for the 'cmap' table + if ((pos = seekTable("cmap")) >= 0) { + nCmaps = getUShort(pos+2); + + // if the font has a Windows-symbol cmap, use it; + // otherwise, use the first cmap in the table + for (i = 0; i < nCmaps; ++i) { + cmapPlatform = getUShort(pos + 4 + 8*i); + cmapEncoding = getUShort(pos + 4 + 8*i + 2); + if (cmapPlatform == 3 && cmapEncoding == 0) { + break; + } + } + if (i >= nCmaps) { + i = 0; + cmapPlatform = getUShort(pos + 4); + cmapEncoding = getUShort(pos + 4 + 2); + } + pos += getULong(pos + 4 + 8*i + 4); + + // read the cmap + cmapFmt = getUShort(pos); + switch (cmapFmt) { + case 0: // byte encoding table (Apple standard) + cmapLen = getUShort(pos + 2); + for (i = 0; i < cmapLen && i < 256; ++i) { + cmap[i] = getByte(pos + 6 + i); + } + break; + case 4: // segment mapping to delta values (Microsoft standard) + if (cmapPlatform == 3 && cmapEncoding == 0) { + // Windows-symbol uses char codes 0xf000 - 0xf0ff + cmapOffset = 0xf000; + } else { + cmapOffset = 0; + } + segCnt = getUShort(pos + 6) / 2; + for (i = 0; i < segCnt; ++i) { + segEnd = getUShort(pos + 14 + 2*i); + segStart = getUShort(pos + 16 + 2*segCnt + 2*i); + segDelta = getUShort(pos + 16 + 4*segCnt + 2*i); + segOffset = getUShort(pos + 16 + 6*segCnt + 2*i); + if (segStart - cmapOffset <= 0xff && + segEnd - cmapOffset >= 0) { + for (j = (segStart - cmapOffset >= 0) ? segStart : cmapOffset; + j <= segEnd && j - cmapOffset <= 0xff; + ++j) { + if (segOffset == 0) { + k = (j + segDelta) & 0xffff; + } else { + k = getUShort(pos + 16 + 6*segCnt + 2*i + + segOffset + 2 * (j - segStart)); + if (k != 0) { + k = (k + segDelta) & 0xffff; + } + } + cmap[j - cmapOffset] = k; + } + } + } + break; + default: + error(-1, "Unimplemented cmap type (%d) in TrueType font file", + cmapFmt); + break; + } + } + + //----- construct the (glyph idx) -> (glyph name) mapping + //----- and compute the (char code) -> (glyph name) mapping + + encoding = new FontEncoding(); + + if ((pos = seekTable("post")) >= 0) { + fmt = getULong(pos); + + // Apple font + if (fmt == 0x00010000) { + for (i = 0; i < 256; ++i) { + j = (cmap[i] < 258) ? cmap[i] : 0; + encoding->addChar(i, copyString(macGlyphNames[j])); + } + + // Microsoft font + } else if (fmt == 0x00020000) { + stringIdx = 0; + stringPos = pos + 34 + 2*nGlyphs; + for (i = 0; i < 256; ++i) { + if (cmap[i] < nGlyphs) { + j = getUShort(pos + 34 + 2 * cmap[i]); + if (j < 258) { + encoding->addChar(i, copyString(macGlyphNames[j])); + } else { + j -= 258; + if (j != stringIdx) { + for (stringIdx = 0, stringPos = pos + 34 + 2*nGlyphs; + stringIdx < j; + ++stringIdx, stringPos += 1 + getByte(stringPos)) ; + } + n = getByte(stringPos); + s = new GString(file + stringPos + 1, n); + encoding->addChar(i, copyString(s->getCString())); + delete s; + ++stringIdx; + stringPos += 1 + n; + } + } else { + encoding->addChar(i, copyString(macGlyphNames[0])); + } + } + + // Apple subset + } else if (fmt == 0x000280000) { + for (i = 0; i < 256; ++i) { + if (cmap[i] < nGlyphs) { + j = i + getChar(pos + 32 + cmap[i]); + } else { + j = 0; + } + encoding->addChar(i, copyString(macGlyphNames[j])); + } + + // Ugh, just assume the Apple glyph set + } else { + for (i = 0; i < 256; ++i) { + j = (cmap[i] < 258) ? cmap[i] : 0; + encoding->addChar(i, copyString(macGlyphNames[j])); + } + } + + // no "post" table: assume the Apple glyph set + } else { + for (i = 0; i < 256; ++i) { + j = (cmap[i] < 258) ? cmap[i] : 0; + encoding->addChar(i, copyString(macGlyphNames[j])); + } + } + + if (taken) { + freeEnc = gFalse; + } + return encoding; +} + +void TrueTypeFontFile::convertToType42(char *name, FontEncoding *encodingA, + FILE *out) { + // write the header + fprintf(out, "%%!PS-TrueTypeFont-%g\n", getFixed(0)); + + // begin the font dictionary + fprintf(out, "10 dict begin\n"); + fprintf(out, "/FontName /%s def\n", name); + fprintf(out, "/FontType 42 def\n"); + fprintf(out, "/FontMatrix [1 0 0 1 0 0] def\n"); + fprintf(out, "/FontBBox [%d %d %d %d] def\n", + bbox[0], bbox[1], bbox[2], bbox[3]); + fprintf(out, "/PaintType 0 def\n"); + + // write the guts of the dictionary + cvtEncoding(encodingA, out); + cvtCharStrings(encodingA, out); + cvtSfnts(out); + + // end the dictionary and define the font + fprintf(out, "FontName currentdict end definefont pop\n"); +} + +int TrueTypeFontFile::getByte(int pos) { + return file[pos] & 0xff; +} + +int TrueTypeFontFile::getChar(int pos) { + int x; + + x = file[pos] & 0xff; + if (x & 0x80) + x |= 0xffffff00; + return x; +} + +int TrueTypeFontFile::getUShort(int pos) { + int x; + + x = file[pos] & 0xff; + x = (x << 8) + (file[pos+1] & 0xff); + return x; +} + +int TrueTypeFontFile::getShort(int pos) { + int x; + + x = file[pos] & 0xff; + x = (x << 8) + (file[pos+1] & 0xff); + if (x & 0x8000) + x |= 0xffff0000; + return x; +} + +Guint TrueTypeFontFile::getULong(int pos) { + int x; + + x = file[pos] & 0xff; + x = (x << 8) + (file[pos+1] & 0xff); + x = (x << 8) + (file[pos+2] & 0xff); + x = (x << 8) + (file[pos+3] & 0xff); + return x; +} + +double TrueTypeFontFile::getFixed(int pos) { + int x, y; + + x = getShort(pos); + y = getUShort(pos+2); + return (double)x + (double)y / 65536; +} + +int TrueTypeFontFile::seekTable(char *tag) { + int i; + + for (i = 0; i < nTables; ++i) { + if (!strncmp(tableHdrs[i].tag, tag, 4)) + return tableHdrs[i].offset; + } + return -1; +} + +void TrueTypeFontFile::cvtEncoding(FontEncoding *encodingA, FILE *out) { + char *name; + int i; + + fprintf(out, "/Encoding 256 array\n"); + for (i = 0; i < 256; ++i) { + if (!(name = encodingA->getCharName(i))) { + name = ".notdef"; + } + fprintf(out, "dup %d /%s put\n", i, name); + } + fprintf(out, "readonly def\n"); +} + +void TrueTypeFontFile::cvtCharStrings(FontEncoding *encodingA, FILE *out) { + int cmap[256]; + int nCmaps, cmapPlatform, cmapEncoding, cmapFmt, cmapLen, cmapOffset; + int segCnt, segStart, segEnd, segDelta, segOffset; + char *name; + int pos, i, j, k; + + //----- read the cmap: construct the (char code) -> (glyph idx) mapping + + // map everything to the missing glyph + for (i = 0; i < 256; ++i) { + cmap[i] = 0; + } + + // look for the 'cmap' table + if ((pos = seekTable("cmap")) >= 0) { + nCmaps = getUShort(pos+2); + + // if the font has a Windows-symbol cmap, use it; + // otherwise, use the first cmap in the table + for (i = 0; i < nCmaps; ++i) { + cmapPlatform = getUShort(pos + 4 + 8*i); + cmapEncoding = getUShort(pos + 4 + 8*i + 2); + if (cmapPlatform == 3 && cmapEncoding == 0) { + break; + } + } + if (i >= nCmaps) { + i = 0; + cmapPlatform = getUShort(pos + 4); + cmapEncoding = getUShort(pos + 4 + 2); + } + pos += getULong(pos + 4 + 8*i + 4); + + // read the cmap + cmapFmt = getUShort(pos); + switch (cmapFmt) { + case 0: // byte encoding table (Apple standard) + cmapLen = getUShort(pos + 2); + for (i = 0; i < cmapLen && i < 256; ++i) { + cmap[i] = getByte(pos + 6 + i); + } + break; + case 4: // segment mapping to delta values (Microsoft standard) + if (cmapPlatform == 3 && cmapEncoding == 0) { + // Windows-symbol uses char codes 0xf000 - 0xf0ff + cmapOffset = 0xf000; + } else { + cmapOffset = 0; + } + segCnt = getUShort(pos + 6) / 2; + for (i = 0; i < segCnt; ++i) { + segEnd = getUShort(pos + 14 + 2*i); + segStart = getUShort(pos + 16 + 2*segCnt + 2*i); + segDelta = getUShort(pos + 16 + 4*segCnt + 2*i); + segOffset = getUShort(pos + 16 + 6*segCnt + 2*i); + if (segStart - cmapOffset <= 0xff && + segEnd - cmapOffset >= 0) { + for (j = (segStart - cmapOffset >= 0) ? segStart : cmapOffset; + j <= segEnd && j - cmapOffset <= 0xff; + ++j) { + if (segOffset == 0) { + k = (j + segDelta) & 0xffff; + } else { + k = getUShort(pos + 16 + 6*segCnt + 2*i + + segOffset + 2 * (j - segStart)); + if (k != 0) { + k = (k + segDelta) & 0xffff; + } + } + cmap[j - cmapOffset] = k; + } + } + } + break; + default: + error(-1, "Unimplemented cmap type (%d) in TrueType font file", + cmapFmt); + break; + } + } + + //----- map char code to glyph index + + // 1. use encoding to map name to char code + // 2. use cmap to map char code to glyph index + + fprintf(out, "/CharStrings 256 dict dup begin\n"); + fprintf(out, "/.notdef 0 def\n"); + + // kludge: this loop goes backward because the WinAnsi and MacRoman + // encodings define certain chars multiple times (space, hyphen, + // etc.), and we want the lowest-numbered definition to "stick" + // (because the higher-numbered defn(s) may not have valid cmap + // entries) + i = encodingA->getSize(); + if (i > 255) { + i = 255; + } + for (; i >= 0; --i) { + name = encodingA->getCharName(i); + if (name && strcmp(name, ".notdef")) { + fprintf(out, "/%s %d def\n", name, cmap[i]); + } + } + + fprintf(out, "end readonly def\n"); +} + +void TrueTypeFontFile::cvtSfnts(FILE *out) { + char tableDir[12 + 9*16]; + int *list; + int nTablesOut, pos, destPos, i, j, k1, k2; + + fprintf(out, "/sfnts [\n"); + + // count tables + nTablesOut = 0; + for (i = 0; i < 9; ++i) { + for (j = 0; j < nTables; ++j) { + if (!strncmp(t42ReqTables[i], tableHdrs[j].tag, 4)) { + ++nTablesOut; + break; + } + } + } + + // header + tableDir[0] = 0x00; // sfnt version + tableDir[1] = 0x01; + tableDir[2] = 0x00; + tableDir[3] = 0x00; + tableDir[4] = (nTablesOut >> 8) & 0xff; // numTables + tableDir[5] = nTablesOut & 0xff; + tableDir[6] = 0; // searchRange + tableDir[7] = (char)128; + tableDir[8] = 0; // entrySelector + tableDir[9] = 3; + tableDir[10] = 0; // rangeShift + tableDir[11] = 16; + + // table directory + pos = 12; + destPos = 12 + 16 * nTablesOut; + for (i = 0; i < 9; ++i) { + for (j = 0; j < nTables; ++j) { + if (!strncmp(t42ReqTables[i], tableHdrs[j].tag, 4)) { + break; + } + } + if (j < nTables) { + memcpy(&tableDir[pos], t42ReqTables[i], 4); + tableDir[pos+4] = (tableHdrs[j].checksum >> 24) & 0xff; + tableDir[pos+5] = (tableHdrs[j].checksum >> 16) & 0xff; + tableDir[pos+6] = (tableHdrs[j].checksum >> 8) & 0xff; + tableDir[pos+7] = tableHdrs[j].checksum & 0xff; + tableDir[pos+8] = (destPos >> 24) & 0xff; + tableDir[pos+9] = (destPos >> 16) & 0xff; + tableDir[pos+10] = (destPos >> 8) & 0xff; + tableDir[pos+11] = destPos & 0xff; + tableDir[pos+12] = (tableHdrs[j].length >> 24) & 0xff; + tableDir[pos+13] = (tableHdrs[j].length >> 16) & 0xff; + tableDir[pos+14] = (tableHdrs[j].length >> 8) & 0xff; + tableDir[pos+15] = tableHdrs[j].length & 0xff; + pos += 16; + destPos += tableHdrs[j].length; + if (tableHdrs[j].length & 3) { + destPos += 4 - (tableHdrs[j].length & 3); + } + } + } + + dumpString(tableDir, 12 + 16 * nTablesOut, out); + + for (i = 0; i < 9; ++i) { + for (j = 0; j < nTables; ++j) { + if (!strncmp(t42ReqTables[i], tableHdrs[j].tag, 4)) { + break; + } + } + if (j < nTables) { + if (!strcmp(t42ReqTables[i], "glyf") && tableHdrs[j].length > 65532) { + // the 'glyf' table won't fit in a single string, and we're only + // allowed to break at glyph boundaries + list = (int *)gmalloc((nGlyphs + 1) * sizeof(int)); + pos = seekTable("loca"); + for (k1 = 0; k1 <= nGlyphs; ++k1) { + if (locaFmt) { + list[k1] = getULong(pos + 4*k1); + } else { + list[k1] = 2 * getUShort(pos + 2*k1); + } + } + k1 = 0; + while (k1 < nGlyphs) { + for (k2 = k1 + 1; + k2 < nGlyphs && list[k2+1] - list[k1] <= 65532; + ++k2) ; + // ghostscript is unhappy if we break at anything other + // than a multiple of four bytes + while (((list[k2] - list[k1]) & 3) && k2 > k1 + 1) { + --k2; + } + dumpString(file + tableHdrs[j].offset + list[k1], + list[k2] - list[k1], out); + k1 = k2; + } + gfree(list); + } else { + dumpString(file + tableHdrs[j].offset, tableHdrs[j].length, out); + } + } + } + + fprintf(out, "] def\n"); +} + +void TrueTypeFontFile::dumpString(char *s, int n, FILE *out) { + int i, j; + + fprintf(out, "<"); + for (i = 0; i < n; i += 32) { + for (j = 0; j < 32 && i+j < n; ++j) { + fprintf(out, "%02X", s[i+j] & 0xff); + } + if (i+32 < n) { + fprintf(out, "\n"); + } + } + if (n & 3) { + for (i = 0; i < 4 - (n & 3); ++i) { + fprintf(out, "00"); + } + } + // append an extra mystery zero byte because the Type 42 spec says so + fprintf(out, "00>\n"); +} diff --git a/pdftops/FontFile.h b/pdftops/FontFile.h index 59382a962a..b64d827ebc 100644 --- a/pdftops/FontFile.h +++ b/pdftops/FontFile.h @@ -30,7 +30,7 @@ public: // Returns the font name, as specified internally by the font file. // Returns NULL if no name is available. - virtual const char *getName() = 0; + virtual char *getName() = 0; // Returns the custom font encoding, or NULL if the encoding is // not available. If is set, the caller of this function @@ -45,14 +45,14 @@ public: class Type1FontFile: public FontFile { public: - Type1FontFile(const char *file, int len); + Type1FontFile(char *file, int len); virtual ~Type1FontFile(); - virtual const char *getName() { return name; } + virtual char *getName() { return name; } virtual FontEncoding *getEncoding(GBool taken); private: - const char *name; + char *name; FontEncoding *encoding; GBool freeEnc; }; @@ -64,14 +64,14 @@ private: class Type1CFontFile: public FontFile { public: - Type1CFontFile(const char *file, int len); + Type1CFontFile(char *file, int len); virtual ~Type1CFontFile(); - virtual const char *getName() { return name; } + virtual char *getName() { return name; } virtual FontEncoding *getEncoding(GBool taken); private: - const char *name; + char *name; FontEncoding *encoding; GBool freeEnc; }; @@ -83,23 +83,23 @@ private: class Type1CFontConverter { public: - Type1CFontConverter(const char *file, int len, FILE *out); + Type1CFontConverter(char *fileA, int lenA, FILE *outA); ~Type1CFontConverter(); void convert(); private: - void eexecWrite(const char *s); - void cvtGlyph(const char *name, Guchar *s, int n); + void eexecWrite(char *s); + void cvtGlyph(char *name, Guchar *s, int n); void cvtGlyphWidth(GBool useOp); - void eexecDumpNum(double x, GBool fp); - void eexecDumpOp1(int op); - void eexecDumpOp2(int op); + void eexecDumpNum(double x, GBool fpA); + void eexecDumpOp1(int opA); + void eexecDumpOp2(int opA); void eexecWriteCharstring(Guchar *s, int n); - void getDeltaInt(char *buf, const char *name, double *op, int n); - void getDeltaReal(char *buf, const char *name, double *op, int n); + void getDeltaInt(char *buf, char *name, double *opA, int n); + void getDeltaReal(char *buf, char *name, double *opA, int n); - const char *file; + char *file; int len; FILE *out; double op[48]; // operands @@ -114,4 +114,57 @@ private: int line; // number of eexec chars on current line }; +//------------------------------------------------------------------------ +// TrueTypeFontFile +//------------------------------------------------------------------------ + +struct TTFontTableHdr; + +class TrueTypeFontFile: public FontFile { +public: + + TrueTypeFontFile(char *fileA, int lenA); + ~TrueTypeFontFile(); + + // This always returns NULL, since it's probably better to trust the + // font name in the PDF file rather than the one in the TrueType + // font file. + virtual char *getName(); + + virtual FontEncoding *getEncoding(GBool taken); + + // Convert to a Type 42 font, suitable for embedding in a PostScript + // file. The name will be used as the PostScript font name (so we + // don't need to depend on the 'name' table in the font). The + // encoding is needed because the PDF Font object can modify the + // encoding. + void convertToType42(char *name, FontEncoding *encodingA, FILE *out); + +private: + + char *file; + int len; + + FontEncoding *encoding; + GBool freeEnc; + + TTFontTableHdr *tableHdrs; + int nTables; + int bbox[4]; + int locaFmt; + int nGlyphs; + + int getByte(int pos); + int getChar(int pos); + int getUShort(int pos); + int getShort(int pos); + Guint getULong(int pos); + double getFixed(int pos); + int seekTable(char *tag); + void cvtEncoding(FontEncoding *encodingA, FILE *out); + void cvtCharStrings(FontEncoding *encodingA, FILE *out); + void cvtSfnts(FILE *out); + void dumpString(char *s, int n, FILE *out); +}; + #endif diff --git a/pdftops/FontInfo.h b/pdftops/FontInfo.h index 9b20f0faa3..a5b4cced33 100644 --- a/pdftops/FontInfo.h +++ b/pdftops/FontInfo.h @@ -16,7 +16,7 @@ //------------------------------------------------------------------------ #define standardEncodingSize 335 -static const char *standardEncodingNames[standardEncodingSize] = { +static char *standardEncodingNames[standardEncodingSize] = { NULL, NULL, NULL, @@ -357,7 +357,7 @@ static FontEncoding standardEncoding(standardEncodingNames, standardEncodingSize); #define symbolEncodingSize 257 -static const char *symbolEncodingNames[symbolEncodingSize] = { +static char *symbolEncodingNames[symbolEncodingSize] = { NULL, NULL, NULL, @@ -620,7 +620,7 @@ static FontEncoding symbolEncoding(symbolEncodingNames, symbolEncodingSize); #define zapfDingbatsEncodingSize 270 -static const char *zapfDingbatsEncodingNames[zapfDingbatsEncodingSize] = { +static char *zapfDingbatsEncodingNames[zapfDingbatsEncodingSize] = { NULL, NULL, NULL, @@ -896,7 +896,7 @@ static FontEncoding zapfDingbatsEncoding(zapfDingbatsEncodingNames, zapfDingbatsEncodingSize); #define macRomanEncodingSize 256 -static const char *macRomanEncodingNames[macRomanEncodingSize] = { +static char *macRomanEncodingNames[macRomanEncodingSize] = { NULL, NULL, NULL, @@ -1158,7 +1158,7 @@ static FontEncoding macRomanEncoding(macRomanEncodingNames, macRomanEncodingSize); #define winAnsiEncodingSize 256 -static const char *winAnsiEncodingNames[winAnsiEncodingSize] = { +static char *winAnsiEncodingNames[winAnsiEncodingSize] = { NULL, NULL, NULL, @@ -1287,7 +1287,7 @@ static const char *winAnsiEncodingNames[winAnsiEncodingSize] = { "braceright", "asciitilde", "bullet", - "bullet", + "Euro", "bullet", "quotesinglbase", "florin", @@ -2041,28 +2041,30 @@ static Gushort zapfDingbatsWidths[270] = { //------------------------------------------------------------------------ struct BuiltinFont { - const char *name; + char *name; Gushort *widths; FontEncoding *encoding; + short ascent; + short descent; }; #define numBuiltinFonts ((int)(sizeof(builtinFonts)/sizeof(BuiltinFont))) static BuiltinFont builtinFonts[] = { - {"Courier", courierWidths, &standardEncoding}, - {"Courier-Bold", courierBoldWidths, &standardEncoding}, - {"Courier-BoldOblique", courierBoldObliqueWidths, &standardEncoding}, - {"Courier-Oblique", courierObliqueWidths, &standardEncoding}, - {"Helvetica", helveticaWidths, &standardEncoding}, - {"Helvetica-Bold", helveticaBoldWidths, &standardEncoding}, - {"Helvetica-BoldOblique", helveticaBoldObliqueWidths, &standardEncoding}, - {"Helvetica-Oblique", helveticaObliqueWidths, &standardEncoding}, - {"Symbol", symbolWidths, &symbolEncoding}, - {"Times-Bold", timesBoldWidths, &standardEncoding}, - {"Times-BoldItalic", timesBoldItalicWidths, &standardEncoding}, - {"Times-Italic", timesItalicWidths, &standardEncoding}, - {"Times-Roman", timesRomanWidths, &standardEncoding}, - {"ZapfDingbats", zapfDingbatsWidths, &zapfDingbatsEncoding} + {"Courier", courierWidths, &standardEncoding, 624, -207}, + {"Courier-Bold", courierBoldWidths, &standardEncoding, 674, -257}, + {"Courier-BoldOblique", courierBoldObliqueWidths, &standardEncoding, 674, -257}, + {"Courier-Oblique", courierObliqueWidths, &standardEncoding, 624, -207}, + {"Helvetica", helveticaWidths, &standardEncoding, 729, -219}, + {"Helvetica-Bold", helveticaBoldWidths, &standardEncoding, 729, -219}, + {"Helvetica-BoldOblique", helveticaBoldObliqueWidths, &standardEncoding, 729, -219}, + {"Helvetica-Oblique", helveticaObliqueWidths, &standardEncoding, 729, -219}, + {"Symbol", symbolWidths, &symbolEncoding, 1010, -293}, + {"Times-Bold", timesBoldWidths, &standardEncoding, 670, -210}, + {"Times-BoldItalic", timesBoldItalicWidths, &standardEncoding, 682, -203}, + {"Times-Italic", timesItalicWidths, &standardEncoding, 684, -206}, + {"Times-Roman", timesRomanWidths, &standardEncoding, 682, -217}, + {"ZapfDingbats", zapfDingbatsWidths, &zapfDingbatsEncoding, 820, -143} }; #endif diff --git a/pdftops/FormWidget.cxx b/pdftops/FormWidget.cxx index 76428d05e6..a9f8c06937 100644 --- a/pdftops/FormWidget.cxx +++ b/pdftops/FormWidget.cxx @@ -19,11 +19,12 @@ // FormWidget //------------------------------------------------------------------------ -FormWidget::FormWidget(Dict *dict) { +FormWidget::FormWidget(XRef *xrefA, Dict *dict) { Object obj1, obj2; double t; ok = gFalse; + xref = xrefA; if (dict->lookup("AP", &obj1)->isDict()) { obj1.dictLookupNF("N", &obj2); @@ -74,7 +75,7 @@ FormWidget::~FormWidget() { void FormWidget::draw(Gfx *gfx) { Object obj; - if (appearance.fetch(&obj)->isStream()) { + if (appearance.fetch(xref, &obj)->isStream()) { gfx->doWidgetForm(&obj, xMin, yMin, xMax, yMax); } obj.free(); @@ -84,7 +85,7 @@ void FormWidget::draw(Gfx *gfx) { // FormWidgets //------------------------------------------------------------------------ -FormWidgets::FormWidgets(Object *annots) { +FormWidgets::FormWidgets(XRef *xref, Object *annots) { FormWidget *widget; Object obj1, obj2; int size; @@ -100,7 +101,7 @@ FormWidgets::FormWidgets(Object *annots) { obj1.dictLookup("Subtype", &obj2); if (obj2.isName("Widget") || obj2.isName("Stamp")) { - widget = new FormWidget(obj1.getDict()); + widget = new FormWidget(xref, obj1.getDict()); if (widget->isOk()) { if (nWidgets >= size) { size += 16; diff --git a/pdftops/FormWidget.h b/pdftops/FormWidget.h index d746083bf4..c14421e81f 100644 --- a/pdftops/FormWidget.h +++ b/pdftops/FormWidget.h @@ -13,6 +13,7 @@ #pragma interface #endif +class XRef; class Gfx; //------------------------------------------------------------------------ @@ -22,17 +23,18 @@ class Gfx; class FormWidget { public: - FormWidget(Dict *dict); + FormWidget(XRef *xrefA, Dict *dict); ~FormWidget(); GBool isOk() { return ok; } void draw(Gfx *gfx); // Get appearance object. - Object *getAppearance(Object *obj) { return appearance.fetch(obj); } + Object *getAppearance(Object *obj) { return appearance.fetch(xref, obj); } private: + XRef *xref; // the xref table for this PDF file Object appearance; // a reference to the Form XObject stream // for the normal appearance double xMin, yMin, // widget rectangle @@ -48,7 +50,7 @@ class FormWidgets { public: // Extract widgets from array of annotations. - FormWidgets(Object *annots); + FormWidgets(XRef *xref, Object *annots); ~FormWidgets(); diff --git a/pdftops/Gfx.cxx b/pdftops/Gfx.cxx index fb323930da..a55efde82d 100644 --- a/pdftops/Gfx.cxx +++ b/pdftops/Gfx.cxx @@ -25,9 +25,20 @@ #include "GfxState.h" #include "OutputDev.h" #include "Params.h" +#include "Page.h" #include "Error.h" #include "Gfx.h" +//------------------------------------------------------------------------ +// constants +//------------------------------------------------------------------------ + +// Max number of splits along the t axis for an axial shading fill. +#define axialMaxSplits 256 + +// Max delta allowed in any color component for an axial shading fill. +#define axialColorDelta (1 / 256.0) + //------------------------------------------------------------------------ // Operator table //------------------------------------------------------------------------ @@ -189,15 +200,11 @@ Operator Gfx::opTab[] = { #define numOps (sizeof(opTab) / sizeof(Operator)) -//------------------------------------------------------------------------ - -GBool printCommands = gFalse; - //------------------------------------------------------------------------ // GfxResources //------------------------------------------------------------------------ -GfxResources::GfxResources(Dict *resDict, GfxResources *next) { +GfxResources::GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA) { Object obj1; if (resDict) { @@ -206,7 +213,7 @@ GfxResources::GfxResources(Dict *resDict, GfxResources *next) { fonts = NULL; resDict->lookup("Font", &obj1); if (obj1.isDict()) { - fonts = new GfxFontDict(obj1.getDict()); + fonts = new GfxFontDict(xref, obj1.getDict()); } obj1.free(); @@ -219,6 +226,9 @@ GfxResources::GfxResources(Dict *resDict, GfxResources *next) { // get pattern dictionary resDict->lookup("Pattern", &patternDict); + // get shading dictionary + resDict->lookup("Shading", &shadingDict); + // get graphics state parameter dictionary resDict->lookup("ExtGState", &gStateDict); @@ -230,7 +240,7 @@ GfxResources::GfxResources(Dict *resDict, GfxResources *next) { gStateDict.initNull(); } - this->next = next; + next = nextA; } GfxResources::~GfxResources() { @@ -240,10 +250,11 @@ GfxResources::~GfxResources() { xObjDict.free(); colorSpaceDict.free(); patternDict.free(); + shadingDict.free(); gStateDict.free(); } -GfxFont *GfxResources::lookupFont(const char *name) { +GfxFont *GfxResources::lookupFont(char *name) { GfxFont *font; GfxResources *resPtr; @@ -257,7 +268,7 @@ GfxFont *GfxResources::lookupFont(const char *name) { return NULL; } -GBool GfxResources::lookupXObject(const char *name, Object *obj) { +GBool GfxResources::lookupXObject(char *name, Object *obj) { GfxResources *resPtr; for (resPtr = this; resPtr; resPtr = resPtr->next) { @@ -271,7 +282,7 @@ GBool GfxResources::lookupXObject(const char *name, Object *obj) { return gFalse; } -GBool GfxResources::lookupXObjectNF(const char *name, Object *obj) { +GBool GfxResources::lookupXObjectNF(char *name, Object *obj) { GfxResources *resPtr; for (resPtr = this; resPtr; resPtr = resPtr->next) { @@ -285,7 +296,7 @@ GBool GfxResources::lookupXObjectNF(const char *name, Object *obj) { return gFalse; } -void GfxResources::lookupColorSpace(const char *name, Object *obj) { +void GfxResources::lookupColorSpace(char *name, Object *obj) { GfxResources *resPtr; for (resPtr = this; resPtr; resPtr = resPtr->next) { @@ -299,7 +310,7 @@ void GfxResources::lookupColorSpace(const char *name, Object *obj) { obj->initNull(); } -GfxPattern *GfxResources::lookupPattern(const char *name) { +GfxPattern *GfxResources::lookupPattern(char *name) { GfxResources *resPtr; GfxPattern *pattern; Object obj; @@ -318,7 +329,26 @@ GfxPattern *GfxResources::lookupPattern(const char *name) { return NULL; } -GBool GfxResources::lookupGState(const char *name, Object *obj) { +GfxShading *GfxResources::lookupShading(char *name) { + GfxResources *resPtr; + GfxShading *shading; + Object obj; + + for (resPtr = this; resPtr; resPtr = resPtr->next) { + if (resPtr->shadingDict.isDict()) { + if (!resPtr->shadingDict.dictLookup(name, &obj)->isNull()) { + shading = GfxShading::parse(&obj); + obj.free(); + return shading; + } + obj.free(); + } + } + error(-1, "Unknown shading '%s'", name); + return NULL; +} + +GBool GfxResources::lookupGState(char *name, Object *obj) { GfxResources *resPtr; for (resPtr = this; resPtr; resPtr = resPtr->next) { @@ -337,18 +367,20 @@ GBool GfxResources::lookupGState(const char *name, Object *obj) { // Gfx //------------------------------------------------------------------------ -Gfx::Gfx(OutputDev *out1, int pageNum, Dict *resDict, - double dpi, double x1, double y1, double x2, double y2, GBool crop, - double cropX1, double cropY1, double cropX2, double cropY2, - int rotate) { +Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, double dpi, + PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate, + GBool printCommandsA) { int i; + xref = xrefA; + printCommands = printCommandsA; + // start the resource stack - res = new GfxResources(resDict, NULL); + res = new GfxResources(xref, resDict, NULL); // initialize - out = out1; - state = new GfxState(dpi, x1, y1, x2, y2, rotate, out->upsideDown()); + out = outA; + state = new GfxState(dpi, box, rotate, out->upsideDown()); fontChanged = gFalse; clip = clipNone; ignoreUndef = 0; @@ -361,11 +393,12 @@ Gfx::Gfx(OutputDev *out1, int pageNum, Dict *resDict, // set crop box if (crop) { - state->moveTo(cropX1, cropY1); - state->lineTo(cropX2, cropY1); - state->lineTo(cropX2, cropY2); - state->lineTo(cropX1, cropY2); + state->moveTo(cropBox->x1, cropBox->y1); + state->lineTo(cropBox->x2, cropBox->y1); + state->lineTo(cropBox->x2, cropBox->y2); + state->lineTo(cropBox->x1, cropBox->y2); state->closePath(); + state->clip(); out->clip(state); state->clearPath(); } @@ -406,7 +439,7 @@ void Gfx::display(Object *obj, GBool topLevel) { error(-1, "Weird page contents"); return; } - parser = new Parser(new Lexer(obj)); + parser = new Parser(xref, new Lexer(xref, obj)); go(topLevel); delete parser; parser = NULL; @@ -433,6 +466,7 @@ void Gfx::go(GBool topLevel) { args[i].print(stdout); } printf("\n"); + fflush(stdout); } execOp(&obj, args, numArgs); obj.free(); @@ -457,6 +491,7 @@ void Gfx::go(GBool topLevel) { printf("throwing away arg: "); obj.print(stdout); printf("\n"); + fflush(stdout); } obj.free(); } @@ -476,6 +511,7 @@ void Gfx::go(GBool topLevel) { args[i].print(stdout); } printf("\n"); + fflush(stdout); } for (i = 0; i < numArgs; ++i) args[i].free(); @@ -485,16 +521,11 @@ void Gfx::go(GBool topLevel) { if (topLevel && numCmds > 0) { out->dump(); } - - // clean up - if (printCommands) { - fflush(stdout); - } } void Gfx::execOp(Object *cmd, Object args[], int numArgs) { Operator *op; - const char *name; + char *name; int i; // find operator @@ -531,7 +562,7 @@ void Gfx::execOp(Object *cmd, Object args[], int numArgs) { (this->*op->func)(args, numArgs); } -Operator *Gfx::findOp(const char *name) { +Operator *Gfx::findOp(char *name) { int a, b, m, cmp; a = -1; @@ -576,17 +607,11 @@ int Gfx::getPos() { //------------------------------------------------------------------------ void Gfx::opSave(Object args[], int numArgs) { - (void)args; - (void)numArgs; - out->saveState(state); state = state->save(); } void Gfx::opRestore(Object args[], int numArgs) { - (void)args; - (void)numArgs; - state = state->restore(); out->restoreState(state); @@ -598,8 +623,6 @@ void Gfx::opRestore(Object args[], int numArgs) { } void Gfx::opConcat(Object args[], int numArgs) { - (void)numArgs; - state->concatCTM(args[0].getNum(), args[1].getNum(), args[2].getNum(), args[3].getNum(), args[4].getNum(), args[5].getNum()); @@ -616,8 +639,6 @@ void Gfx::opSetDash(Object args[], int numArgs) { double *dash; int i; - (void)numArgs; - a = args[0].getArray(); length = a->getLength(); if (length == 0) { @@ -778,7 +799,7 @@ void Gfx::opSetFillColorSpace(Object args[], int numArgs) { if (colorSpace) { state->setFillColorSpace(colorSpace); } else { - error(getPos(), "Bad color space"); + error(getPos(), "Bad color space (fill)"); } for (i = 0; i < gfxColorMaxComps; ++i) { color.c[i] = 0; @@ -804,7 +825,7 @@ void Gfx::opSetStrokeColorSpace(Object args[], int numArgs) { if (colorSpace) { state->setStrokeColorSpace(colorSpace); } else { - error(getPos(), "Bad color space"); + error(getPos(), "Bad color space (stroke)"); } for (i = 0; i < gfxColorMaxComps; ++i) { color.c[i] = 0; @@ -906,14 +927,10 @@ void Gfx::opSetStrokeColorN(Object args[], int numArgs) { //------------------------------------------------------------------------ void Gfx::opMoveTo(Object args[], int numArgs) { - (void)numArgs; - state->moveTo(args[0].getNum(), args[1].getNum()); } void Gfx::opLineTo(Object args[], int numArgs) { - (void)numArgs; - if (!state->isCurPt()) { error(getPos(), "No current point in lineto"); return; @@ -924,8 +941,6 @@ void Gfx::opLineTo(Object args[], int numArgs) { void Gfx::opCurveTo(Object args[], int numArgs) { double x1, y1, x2, y2, x3, y3; - (void)numArgs; - if (!state->isCurPt()) { error(getPos(), "No current point in curveto"); return; @@ -942,8 +957,6 @@ void Gfx::opCurveTo(Object args[], int numArgs) { void Gfx::opCurveTo1(Object args[], int numArgs) { double x1, y1, x2, y2, x3, y3; - (void)numArgs; - if (!state->isCurPt()) { error(getPos(), "No current point in curveto1"); return; @@ -960,8 +973,6 @@ void Gfx::opCurveTo1(Object args[], int numArgs) { void Gfx::opCurveTo2(Object args[], int numArgs) { double x1, y1, x2, y2, x3, y3; - (void)numArgs; - if (!state->isCurPt()) { error(getPos(), "No current point in curveto2"); return; @@ -978,8 +989,6 @@ void Gfx::opCurveTo2(Object args[], int numArgs) { void Gfx::opRectangle(Object args[], int numArgs) { double x, y, w, h; - (void)numArgs; - x = args[0].getNum(); y = args[1].getNum(); w = args[2].getNum(); @@ -992,9 +1001,6 @@ void Gfx::opRectangle(Object args[], int numArgs) { } void Gfx::opClosePath(Object args[], int numArgs) { - (void)args; - (void)numArgs; - if (!state->isPath()) { error(getPos(), "No current point in closepath"); return; @@ -1007,16 +1013,10 @@ void Gfx::opClosePath(Object args[], int numArgs) { //------------------------------------------------------------------------ void Gfx::opEndPath(Object args[], int numArgs) { - (void)args; - (void)numArgs; - doEndPath(); } void Gfx::opStroke(Object args[], int numArgs) { - (void)args; - (void)numArgs; - if (!state->isCurPt()) { //error(getPos(), "No path in stroke"); return; @@ -1027,9 +1027,6 @@ void Gfx::opStroke(Object args[], int numArgs) { } void Gfx::opCloseStroke(Object args[], int numArgs) { - (void)args; - (void)numArgs; - if (!state->isCurPt()) { //error(getPos(), "No path in closepath/stroke"); return; @@ -1042,9 +1039,6 @@ void Gfx::opCloseStroke(Object args[], int numArgs) { } void Gfx::opFill(Object args[], int numArgs) { - (void)args; - (void)numArgs; - if (!state->isCurPt()) { //error(getPos(), "No path in fill"); return; @@ -1060,9 +1054,6 @@ void Gfx::opFill(Object args[], int numArgs) { } void Gfx::opEOFill(Object args[], int numArgs) { - (void)args; - (void)numArgs; - if (!state->isCurPt()) { //error(getPos(), "No path in eofill"); return; @@ -1078,9 +1069,6 @@ void Gfx::opEOFill(Object args[], int numArgs) { } void Gfx::opFillStroke(Object args[], int numArgs) { - (void)args; - (void)numArgs; - if (!state->isCurPt()) { //error(getPos(), "No path in fill/stroke"); return; @@ -1097,9 +1085,6 @@ void Gfx::opFillStroke(Object args[], int numArgs) { } void Gfx::opCloseFillStroke(Object args[], int numArgs) { - (void)args; - (void)numArgs; - if (!state->isCurPt()) { //error(getPos(), "No path in closepath/fill/stroke"); return; @@ -1117,9 +1102,6 @@ void Gfx::opCloseFillStroke(Object args[], int numArgs) { } void Gfx::opEOFillStroke(Object args[], int numArgs) { - (void)args; - (void)numArgs; - if (!state->isCurPt()) { //error(getPos(), "No path in eofill/stroke"); return; @@ -1136,9 +1118,6 @@ void Gfx::opEOFillStroke(Object args[], int numArgs) { } void Gfx::opCloseEOFillStroke(Object args[], int numArgs) { - (void)args; - (void)numArgs; - if (!state->isCurPt()) { //error(getPos(), "No path in closepath/eofill/stroke"); return; @@ -1155,25 +1134,19 @@ void Gfx::opCloseEOFillStroke(Object args[], int numArgs) { doEndPath(); } -void Gfx::opShFill(Object args[], int numArgs) { - (void)args; - (void)numArgs; -} - void Gfx::doPatternFill(GBool eoFill) { GfxPatternColorSpace *patCS; GfxPattern *pattern; GfxTilingPattern *tPat; GfxColorSpace *cs; - GfxPath *path; - GfxSubpath *subpath; double xMin, yMin, xMax, yMax, x, y, x1, y1; + double cxMin, cyMin, cxMax, cyMax; int xi0, yi0, xi1, yi1, xi, yi; double *ctm, *btm, *ptm; - double m[6], ictm[6], m1[6], im[6]; + double m[6], ictm[6], m1[6], im[6], imb[6]; double det; double xstep, ystep; - int i, j; + int i; // get color space patCS = (GfxPatternColorSpace *)state->getFillColorSpace(); @@ -1223,33 +1196,14 @@ void Gfx::doPatternFill(GBool eoFill) { im[4] = (m[2] * m[5] - m[3] * m[4]) * det; im[5] = (m[1] * m[4] - m[0] * m[5]) * det; - // compute bounding box of current path, in pattern space - xMin = xMax = yMin = yMax = 0; // make gcc happy - path = state->getPath(); - for (i = 0; i < path->getNumSubpaths(); ++i) { - subpath = path->getSubpath(i); - for (j = 0; j < subpath->getNumPoints(); ++j) { - x = subpath->getX(j); - y = subpath->getY(j); - x1 = x * im[0] + y * im[2] + im[4]; - y1 = x * im[1] + y * im[3] + im[5]; - if (i == 0 && j == 0) { - xMin = xMax = x1; - yMin = yMax = y1; - } else { - if (x1 < xMin) { - xMin = x1; - } else if (x1 > xMax) { - xMax = x1; - } - if (y1 < yMin) { - yMin = y1; - } else if (y1 > yMax) { - yMax = y1; - } - } - } - } + // construct a (base space) -> (pattern space) transform matrix + det = 1 / (m1[0] * m1[3] - m1[1] * m1[2]); + imb[0] = m1[3] * det; + imb[1] = -m1[1] * det; + imb[2] = -m1[2] * det; + imb[3] = m1[0] * det; + imb[4] = (m1[2] * m1[5] - m1[3] * m1[4]) * det; + imb[5] = (m1[1] * m1[4] - m1[0] * m1[5]) * det; // save current graphics state out->saveState(state); @@ -1265,6 +1219,7 @@ void Gfx::doPatternFill(GBool eoFill) { out->updateFillColor(state); // clip to current path + state->clip(); if (eoFill) { out->eoClip(state); } else { @@ -1272,6 +1227,47 @@ void Gfx::doPatternFill(GBool eoFill) { } state->clearPath(); + // transform clip region bbox to pattern space + state->getClipBBox(&cxMin, &cyMin, &cxMax, &cyMax); + xMin = xMax = cxMin * imb[0] + cyMin * imb[2] + imb[4]; + yMin = yMax = cxMin * imb[1] + cyMin * imb[3] + imb[5]; + x1 = cxMin * imb[0] + cyMax * imb[2] + imb[4]; + y1 = cxMin * imb[1] + cyMax * imb[3] + imb[5]; + if (x1 < xMin) { + xMin = x1; + } else if (x1 > xMax) { + xMax = x1; + } + if (y1 < yMin) { + yMin = y1; + } else if (y1 > yMax) { + yMax = y1; + } + x1 = cxMax * imb[0] + cyMin * imb[2] + imb[4]; + y1 = cxMax * imb[1] + cyMin * imb[3] + imb[5]; + if (x1 < xMin) { + xMin = x1; + } else if (x1 > xMax) { + xMax = x1; + } + if (y1 < yMin) { + yMin = y1; + } else if (y1 > yMax) { + yMax = y1; + } + x1 = cxMax * imb[0] + cyMax * imb[2] + imb[4]; + y1 = cxMax * imb[1] + cyMax * imb[3] + imb[5]; + if (x1 < xMin) { + xMin = x1; + } else if (x1 > xMax) { + xMax = x1; + } + if (y1 < yMin) { + yMin = y1; + } else if (y1 > yMax) { + yMax = y1; + } + // draw the pattern //~ this should treat negative steps differently -- start at right/top //~ edge instead of left/bottom (?) @@ -1300,12 +1296,335 @@ void Gfx::doPatternFill(GBool eoFill) { out->restoreState(state); } +void Gfx::opShFill(Object args[], int numArgs) { + GfxShading *shading; + double xMin, yMin, xMax, yMax; + + if (!(shading = res->lookupShading(args[0].getName()))) { + return; + } + + // save current graphics state + out->saveState(state); + state = state->save(); + + // clip to bbox + if (shading->getHasBBox()) { + shading->getBBox(&xMin, &yMin, &xMax, &yMax); + state->moveTo(xMin, yMin); + state->lineTo(xMax, yMin); + state->lineTo(xMax, yMax); + state->lineTo(xMin, yMax); + state->closePath(); + state->clip(); + out->clip(state); + state->clearPath(); + } + + // set the color space + state->setFillColorSpace(shading->getColorSpace()->copy()); + + // do shading type-specific operations + switch (shading->getType()) { + case 2: + doAxialShFill((GfxAxialShading *)shading); + break; + } + + // restore graphics state + state = state->restore(); + out->restoreState(state); + + delete shading; +} + +void Gfx::doAxialShFill(GfxAxialShading *shading) { + double xMin, yMin, xMax, yMax; + double x0, y0, x1, y1; + double det; + double *ctm; + double ictm[6]; + double dx, dy, mul; + double tMin, tMax, t, tx, ty; + double s[4], sMin, sMax, tmp; + double ux0, uy0, ux1, uy1, vx0, vy0, vx1, vy1; + double t0, t1, tt; + double ta[axialMaxSplits + 1]; + int next[axialMaxSplits + 1]; + GfxColor color0, color1; + int nComps; + int i, j, k, kk; + + // get clip region bbox and transform to current user space + state->getClipBBox(&x0, &y0, &x1, &y1); + ctm = state->getCTM(); + det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]); + ictm[0] = ctm[3] * det; + ictm[1] = -ctm[1] * det; + ictm[2] = -ctm[2] * det; + ictm[3] = ctm[0] * det; + ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det; + ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det; + xMin = xMax = x0 * ictm[0] + y0 * ictm[2] + ictm[4]; + yMin = yMax = x0 * ictm[1] + y0 * ictm[3] + ictm[5]; + tx = x0 * ictm[0] + y1 * ictm[2] + ictm[4]; + ty = x0 * ictm[1] + y1 * ictm[3] + ictm[5]; + if (tx < xMin) { + xMin = tx; + } else if (tx > xMax) { + xMax = tx; + } + if (ty < yMin) { + yMin = ty; + } else if (ty > yMax) { + yMax = ty; + } + tx = x1 * ictm[0] + y0 * ictm[2] + ictm[4]; + ty = x1 * ictm[1] + y0 * ictm[3] + ictm[5]; + if (tx < xMin) { + xMin = tx; + } else if (tx > xMax) { + xMax = tx; + } + if (ty < yMin) { + yMin = ty; + } else if (ty > yMax) { + yMax = ty; + } + tx = x1 * ictm[0] + y1 * ictm[2] + ictm[4]; + ty = x1 * ictm[1] + y1 * ictm[3] + ictm[5]; + if (tx < xMin) { + xMin = tx; + } else if (tx > xMax) { + xMax = tx; + } + if (ty < yMin) { + yMin = ty; + } else if (ty > yMax) { + yMax = ty; + } + + // compute min and max t values, based on the four corners of the + // clip region bbox + shading->getCoords(&x0, &y0, &x1, &y1); + dx = x1 - x0; + dy = y1 - y0; + mul = 1 / (dx * dx + dy * dy); + tMin = tMax = ((xMin - x0) * dx + (yMin - y0) * dy) * mul; + t = ((xMin - x0) * dx + (yMax - y0) * dy) * mul; + if (t < tMin) { + tMin = t; + } else if (t > tMax) { + tMax = t; + } + t = ((xMax - x0) * dx + (yMin - y0) * dy) * mul; + if (t < tMin) { + tMin = t; + } else if (t > tMax) { + tMax = t; + } + t = ((xMax - x0) * dx + (yMax - y0) * dy) * mul; + if (t < tMin) { + tMin = t; + } else if (t > tMax) { + tMax = t; + } + if (tMin < 0 && !shading->getExtend0()) { + tMin = 0; + } + if (tMax > 1 && !shading->getExtend1()) { + tMax = 1; + } + + // get the function domain + t0 = shading->getDomain0(); + t1 = shading->getDomain1(); + + // Traverse the t axis and do the shading. + // + // For each point (tx, ty) on the t axis, consider a line through + // that point perpendicular to the t axis: + // + // x(s) = tx + s * -dy --> s = (x - tx) / -dy + // y(s) = ty + s * dx --> s = (y - ty) / dx + // + // Then look at the intersection of this line with the bounding box + // (xMin, yMin, xMax, yMax). In the general case, there are four + // intersection points: + // + // s0 = (xMin - tx) / -dy + // s1 = (xMax - tx) / -dy + // s2 = (yMin - ty) / dx + // s3 = (yMax - ty) / dx + // + // and we want the middle two s values. + // + // In the case where dx = 0, take s0 and s1; in the case where dy = + // 0, take s2 and s3. + // + // Each filled polygon is bounded by two of these line segments + // perpdendicular to the t axis. + // + // The t axis is bisected into smaller regions until the color + // difference across a region is small enough, and then the region + // is painted with a single color. + + // set up + nComps = shading->getColorSpace()->getNComps(); + ta[0] = tMin; + ta[axialMaxSplits] = tMax; + next[0] = axialMaxSplits; + + // compute the color at t = tMin + if (tMin < 0) { + tt = t0; + } else if (tMin > 1) { + tt = t1; + } else { + tt = t0 + (t1 - t0) * tMin; + } + shading->getColor(tt, &color0); + + // compute the coordinates of the point on the t axis at t = tMin; + // then compute the intersection of the perpendicular line with the + // bounding box + tx = x0 + tMin * dx; + ty = y0 + tMin * dy; + if (dx == 0 && dy == 0) { + sMin = sMax = 0; + } if (dx == 0) { + sMin = (xMin - tx) / -dy; + sMax = (xMax - tx) / -dy; + if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; } + } else if (dy == 0) { + sMin = (yMin - ty) / dx; + sMax = (yMax - ty) / dx; + if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; } + } else { + s[0] = (yMin - ty) / dx; + s[1] = (yMax - ty) / dx; + s[2] = (xMin - tx) / -dy; + s[3] = (xMax - tx) / -dy; + for (j = 0; j < 3; ++j) { + kk = j; + for (k = j + 1; k < 4; ++k) { + if (s[k] < s[kk]) { + kk = k; + } + } + tmp = s[j]; s[j] = s[kk]; s[kk] = tmp; + } + sMin = s[1]; + sMax = s[2]; + } + ux0 = tx - sMin * dy; + uy0 = ty + sMin * dx; + vx0 = tx - sMax * dy; + vy0 = ty + sMax * dx; + + i = 0; + while (i < axialMaxSplits) { + + // bisect until color difference is small enough or we hit the + // bisection limit + j = next[i]; + while (j > i + 1) { + if (ta[j] < 0) { + tt = t0; + } else if (ta[j] > 1) { + tt = t1; + } else { + tt = t0 + (t1 - t0) * ta[j]; + } + shading->getColor(tt, &color1); + for (k = 0; k < nComps; ++k) { + if (fabs(color1.c[k] - color0.c[k]) > axialColorDelta) { + break; + } + } + if (k == nComps) { + break; + } + k = (i + j) / 2; + ta[k] = 0.5 * (ta[i] + ta[j]); + next[i] = k; + next[k] = j; + j = k; + } + + // use the average of the colors of the two sides of the region + for (k = 0; k < nComps; ++k) { + color0.c[k] = 0.5 * (color0.c[k] + color1.c[k]); + } + + // compute the coordinates of the point on the t axis; then + // compute the intersection of the perpendicular line with the + // bounding box + tx = x0 + ta[j] * dx; + ty = y0 + ta[j] * dy; + if (dx == 0 && dy == 0) { + sMin = sMax = 0; + } if (dx == 0) { + sMin = (xMin - tx) / -dy; + sMax = (xMax - tx) / -dy; + if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; } + } else if (dy == 0) { + sMin = (yMin - ty) / dx; + sMax = (yMax - ty) / dx; + if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; } + } else { + s[0] = (yMin - ty) / dx; + s[1] = (yMax - ty) / dx; + s[2] = (xMin - tx) / -dy; + s[3] = (xMax - tx) / -dy; + for (j = 0; j < 3; ++j) { + kk = j; + for (k = j + 1; k < 4; ++k) { + if (s[k] < s[kk]) { + kk = k; + } + } + tmp = s[j]; s[j] = s[kk]; s[kk] = tmp; + } + sMin = s[1]; + sMax = s[2]; + } + ux1 = tx - sMin * dy; + uy1 = ty + sMin * dx; + vx1 = tx - sMax * dy; + vy1 = ty + sMax * dx; + + // set the color + state->setFillColor(&color0); + out->updateFillColor(state); + + // fill the region + state->moveTo(ux0, uy0); + state->lineTo(vx0, vy0); + state->lineTo(vx1, vy1); + state->lineTo(ux1, uy1); + state->closePath(); + out->fill(state); + state->clearPath(); + + // set up for next region + ux0 = ux1; + uy0 = uy1; + vx0 = vx1; + vy0 = vy1; + color0 = color1; + i = next[i]; + } +} + void Gfx::doEndPath() { - if (state->isPath()) { - if (clip == clipNormal) + if (state->isPath() && clip != clipNone) { + state->clip(); + if (clip == clipNormal) { out->clip(state); - else if (clip == clipEO) + } else { out->eoClip(state); + } } clip = clipNone; state->clearPath(); @@ -1316,16 +1635,10 @@ void Gfx::doEndPath() { //------------------------------------------------------------------------ void Gfx::opClip(Object args[], int numArgs) { - (void)args; - (void)numArgs; - clip = clipNormal; } void Gfx::opEOClip(Object args[], int numArgs) { - (void)args; - (void)numArgs; - clip = clipEO; } @@ -1334,9 +1647,6 @@ void Gfx::opEOClip(Object args[], int numArgs) { //------------------------------------------------------------------------ void Gfx::opBeginText(Object args[], int numArgs) { - (void)args; - (void)numArgs; - state->setTextMat(1, 0, 0, 1, 0, 0); state->textMoveTo(0, 0); out->updateTextMat(state); @@ -1345,8 +1655,6 @@ void Gfx::opBeginText(Object args[], int numArgs) { } void Gfx::opEndText(Object args[], int numArgs) { - (void)args; - (void)numArgs; } //------------------------------------------------------------------------ @@ -1354,9 +1662,6 @@ void Gfx::opEndText(Object args[], int numArgs) { //------------------------------------------------------------------------ void Gfx::opSetCharSpacing(Object args[], int numArgs) { - (void)args; - (void)numArgs; - state->setCharSpace(args[0].getNum()); out->updateCharSpace(state); } @@ -1371,43 +1676,35 @@ void Gfx::opSetFont(Object args[], int numArgs) { printf(" font: '%s' %g\n", font->getName() ? font->getName()->getCString() : "???", args[1].getNum()); + fflush(stdout); } state->setFont(font, args[1].getNum()); fontChanged = gTrue; } void Gfx::opSetTextLeading(Object args[], int numArgs) { - (void)numArgs; - state->setLeading(args[0].getNum()); } void Gfx::opSetTextRender(Object args[], int numArgs) { - (void)numArgs; - state->setRender(args[0].getInt()); out->updateRender(state); } void Gfx::opSetTextRise(Object args[], int numArgs) { - (void)numArgs; - state->setRise(args[0].getNum()); out->updateRise(state); } void Gfx::opSetWordSpacing(Object args[], int numArgs) { - (void)numArgs; - state->setWordSpace(args[0].getNum()); out->updateWordSpace(state); } void Gfx::opSetHorizScaling(Object args[], int numArgs) { - (void)numArgs; - state->setHorizScaling(args[0].getNum()); out->updateHorizScaling(state); + fontChanged = gTrue; } //------------------------------------------------------------------------ @@ -1417,8 +1714,6 @@ void Gfx::opSetHorizScaling(Object args[], int numArgs) { void Gfx::opTextMove(Object args[], int numArgs) { double tx, ty; - (void)numArgs; - tx = state->getLineX() + args[0].getNum(); ty = state->getLineY() + args[1].getNum(); state->textMoveTo(tx, ty); @@ -1428,8 +1723,6 @@ void Gfx::opTextMove(Object args[], int numArgs) { void Gfx::opTextMoveSet(Object args[], int numArgs) { double tx, ty; - (void)numArgs; - tx = state->getLineX() + args[0].getNum(); ty = args[1].getNum(); state->setLeading(-ty); @@ -1439,8 +1732,6 @@ void Gfx::opTextMoveSet(Object args[], int numArgs) { } void Gfx::opSetTextMatrix(Object args[], int numArgs) { - (void)numArgs; - state->setTextMat(args[0].getNum(), args[1].getNum(), args[2].getNum(), args[3].getNum(), args[4].getNum(), args[5].getNum()); @@ -1453,9 +1744,6 @@ void Gfx::opSetTextMatrix(Object args[], int numArgs) { void Gfx::opTextNextLine(Object args[], int numArgs) { double tx, ty; - (void)args; - (void)numArgs; - tx = state->getLineX(); ty = state->getLineY() - state->getLeading(); state->textMoveTo(tx, ty); @@ -1467,8 +1755,6 @@ void Gfx::opTextNextLine(Object args[], int numArgs) { //------------------------------------------------------------------------ void Gfx::opShowText(Object args[], int numArgs) { - (void)numArgs; - if (!state->getFont()) { error(getPos(), "No font in show"); return; @@ -1479,8 +1765,6 @@ void Gfx::opShowText(Object args[], int numArgs) { void Gfx::opMoveShowText(Object args[], int numArgs) { double tx, ty; - (void)numArgs; - if (!state->getFont()) { error(getPos(), "No font in move/show"); return; @@ -1495,8 +1779,6 @@ void Gfx::opMoveShowText(Object args[], int numArgs) { void Gfx::opMoveSetShowText(Object args[], int numArgs) { double tx, ty; - (void)numArgs; - if (!state->getFont()) { error(getPos(), "No font in move/set/show"); return; @@ -1517,8 +1799,6 @@ void Gfx::opShowSpaceText(Object args[], int numArgs) { Object obj; int i; - (void)numArgs; - if (!state->getFont()) { error(getPos(), "No font in show/space"); return; @@ -1547,7 +1827,7 @@ void Gfx::doShowText(GString *s) { GString *s16; char s16a[2]; int m, n; -#if 0 //~type3 +#if 1 //~type3 double dx, dy, width, height, w, h, x, y; double oldCTM[6], newCTM[6]; double *mat; @@ -1555,8 +1835,9 @@ void Gfx::doShowText(GString *s) { Parser *oldParser; int i; #else - double dx, dy, width, height, w, h, sWidth, sHeight; + double dx, dy, width, height, w, h; #endif + double sWidth, sHeight; if (fontChanged) { out->updateFont(state); @@ -1580,12 +1861,12 @@ void Gfx::doShowText(GString *s) { while (n > 0) { m = getNextChar16(enc, p, &c16); if (enc->wMode == 0) { - width = state->getFontSize() * state->getHorizScaling() * - font->getWidth16(c16) + + width = state->getFontSize() * font->getWidth16(c16) + state->getCharSpace(); - if (c16 == ' ') { + if (m == 1 && c16 == ' ') { width += state->getWordSpace(); } + width *= state->getHorizScaling(); height = 0; } else { width = 0; @@ -1616,7 +1897,7 @@ void Gfx::doShowText(GString *s) { //----- 8-bit font } else { -#if 0 //~type3 +#if 1 //~type3 //~ also check out->renderType3() if (font->getType() == fontType3) { out->beginString(state, s); @@ -1644,6 +1925,8 @@ void Gfx::doShowText(GString *s) { c8 = *p; font->getCharProc(c8, &charProc); state->transform(state->getCurX() + dx, state->getCurY() + dy, &x, &y); + out->saveState(state); + state = state->save(); state->setCTM(newCTM[0], newCTM[1], newCTM[2], newCTM[3], x, y); //~ out->updateCTM(???) if (charProc.isStream()) { @@ -1651,16 +1934,15 @@ void Gfx::doShowText(GString *s) { } else { error(getPos(), "Missing or bad Type3 CharProc entry"); } - state->setCTM(oldCTM[0], oldCTM[1], oldCTM[2], - oldCTM[3], oldCTM[4], oldCTM[5]); - //~ out->updateCTM(???) - use gsave/grestore instead? + state = state->restore(); + out->restoreState(state); charProc.free(); - width = state->getFontSize() * state->getHorizScaling() * - font->getWidth(c8) + + width = state->getFontSize() * font->getWidth(c8) + state->getCharSpace(); if (c8 == ' ') { width += state->getWordSpace(); } + width *= state->getHorizScaling(); state->textShift(width); } parser = oldParser; @@ -1672,11 +1954,12 @@ void Gfx::doShowText(GString *s) { state->textTransformDelta(0, state->getRise(), &dx, &dy); for (p = (Guchar *)s->getCString(), n = s->getLength(); n; ++p, --n) { c8 = *p; - width = state->getFontSize() * state->getHorizScaling() * - font->getWidth(c8) + + width = state->getFontSize() * font->getWidth(c8) + state->getCharSpace(); - if (c8 == ' ') + if (c8 == ' ') { width += state->getWordSpace(); + } + width *= state->getHorizScaling(); state->textTransformDelta(width, 0, &w, &h); out->drawChar(state, state->getCurX() + dx, state->getCurY() + dy, w, h, c8); @@ -1685,13 +1968,14 @@ void Gfx::doShowText(GString *s) { out->endString(state); } else { out->drawString(state, s); - width = state->getFontSize() * state->getHorizScaling() * - font->getWidth(s) + + width = state->getFontSize() * font->getWidth(s) + s->getLength() * state->getCharSpace(); for (p = (Guchar *)s->getCString(), n = s->getLength(); n; ++p, --n) { - if (*p == ' ') + if (*p == ' ') { width += state->getWordSpace(); + } } + width *= state->getHorizScaling(); state->textShift(width); } } @@ -1772,13 +2056,17 @@ void Gfx::opXObject(Object args[], int numArgs) { void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) { Dict *dict; - Object obj1, obj2; int width, height; int bits; GBool mask; + GBool invert; GfxColorSpace *colorSpace; GfxImageColorMap *colorMap; - GBool invert; + Object maskObj; + GBool haveMask; + int maskColors[2*gfxColorMaxComps]; + Object obj1, obj2; + int i; // get stream dict dict = str->getDict(); @@ -1886,10 +2174,25 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) { goto err1; } + // get the mask + haveMask = gFalse; + dict->lookup("Mask", &maskObj); + if (maskObj.isArray()) { + for (i = 0; i < maskObj.arrayGetLength(); ++i) { + maskObj.arrayGet(i, &obj1); + maskColors[i] = obj1.getInt(); + obj1.free(); + } + haveMask = gTrue; + } + // draw it - out->drawImage(state, ref, str, width, height, colorMap, inlineImg); + out->drawImage(state, ref, str, width, height, colorMap, + haveMask ? maskColors : (int *)NULL, inlineImg); delete colorMap; str->close(); + + maskObj.free(); } return; @@ -1951,7 +2254,7 @@ void Gfx::doForm(Object *str) { // get resources dict->lookup("Resources", &resObj); - resDict = resObj.isDict() ? resObj.getDict() : NULL; + resDict = resObj.isDict() ? resObj.getDict() : (Dict *)NULL; // draw it doForm1(str, resDict, m, bbox); @@ -2013,7 +2316,7 @@ void Gfx::doWidgetForm(Object *str, double xMin, double yMin, // get resources dict->lookup("Resources", &resObj); - resDict = resObj.isDict() ? resObj.getDict() : NULL; + resDict = resObj.isDict() ? resObj.getDict() : (Dict *)NULL; // draw it doForm1(str, resDict, m, bbox); @@ -2029,7 +2332,7 @@ void Gfx::doForm1(Object *str, Dict *resDict, double *matrix, double *bbox) { int i; // push new resources on stack - res = new GfxResources(resDict, res); + res = new GfxResources(xref, resDict, res); // save current graphics state out->saveState(state); @@ -2056,6 +2359,7 @@ void Gfx::doForm1(Object *str, Dict *resDict, double *matrix, double *bbox) { state->lineTo(bbox[2], bbox[3]); state->lineTo(bbox[0], bbox[3]); state->closePath(); + state->clip(); out->clip(state); state->clearPath(); @@ -2090,9 +2394,6 @@ void Gfx::opBeginImage(Object args[], int numArgs) { Stream *str; int c1, c2; - (void)args; - (void)numArgs; - // build dict/stream str = buildImageStream(); @@ -2114,11 +2415,11 @@ void Gfx::opBeginImage(Object args[], int numArgs) { Stream *Gfx::buildImageStream() { Object dict; Object obj; - const char *key; + char *key; Stream *str; // build dictionary - dict.initDict(); + dict.initDict(xref); parser->getObj(&obj); while (!obj.isCmd("ID") && !obj.isEOF()) { if (!obj.isName()) { @@ -2147,16 +2448,10 @@ Stream *Gfx::buildImageStream() { } void Gfx::opImageData(Object args[], int numArgs) { - (void)args; - (void)numArgs; - error(getPos(), "Internal: got 'ID' operator"); } void Gfx::opEndImage(Object args[], int numArgs) { - (void)args; - (void)numArgs; - error(getPos(), "Internal: got 'EI' operator"); } @@ -2165,17 +2460,11 @@ void Gfx::opEndImage(Object args[], int numArgs) { //------------------------------------------------------------------------ void Gfx::opSetCharWidth(Object args[], int numArgs) { - (void)args; - (void)numArgs; - - error(getPos(), "Encountered 'd0' operator in content stream"); +// error(getPos(), "Encountered 'd0' operator in content stream"); } void Gfx::opSetCacheDevice(Object args[], int numArgs) { - (void)args; - (void)numArgs; - - error(getPos(), "Encountered 'd1' operator in content stream"); +// error(getPos(), "Encountered 'd1' operator in content stream"); } //------------------------------------------------------------------------ @@ -2183,16 +2472,10 @@ void Gfx::opSetCacheDevice(Object args[], int numArgs) { //------------------------------------------------------------------------ void Gfx::opBeginIgnoreUndef(Object args[], int numArgs) { - (void)args; - (void)numArgs; - ++ignoreUndef; } void Gfx::opEndIgnoreUndef(Object args[], int numArgs) { - (void)args; - (void)numArgs; - if (ignoreUndef > 0) --ignoreUndef; } @@ -2202,28 +2485,24 @@ void Gfx::opEndIgnoreUndef(Object args[], int numArgs) { //------------------------------------------------------------------------ void Gfx::opBeginMarkedContent(Object args[], int numArgs) { - (void)numArgs; - if (printCommands) { printf(" marked content: %s ", args[0].getName()); if (numArgs == 2) args[2].print(stdout); printf("\n"); + fflush(stdout); } } void Gfx::opEndMarkedContent(Object args[], int numArgs) { - (void)args; - (void)numArgs; } void Gfx::opMarkPoint(Object args[], int numArgs) { - (void)numArgs; - if (printCommands) { printf(" mark point: %s ", args[0].getName()); if (numArgs == 2) args[2].print(stdout); printf("\n"); + fflush(stdout); } } diff --git a/pdftops/Gfx.h b/pdftops/Gfx.h index 011fbfcd14..24e124697a 100644 --- a/pdftops/Gfx.h +++ b/pdftops/Gfx.h @@ -16,6 +16,7 @@ #include "gtypes.h" class GString; +class XRef; class Array; class Stream; class Parser; @@ -25,8 +26,11 @@ class GfxFontDict; class GfxFont; struct GfxFontEncoding16; class GfxPattern; +class GfxShading; +class GfxAxialShading; class GfxState; class Gfx; +struct PDFRectangle; //------------------------------------------------------------------------ // Gfx @@ -62,15 +66,16 @@ struct Operator { class GfxResources { public: - GfxResources(Dict *resDict, GfxResources *next); + GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA); ~GfxResources(); - GfxFont *lookupFont(const char *name); - GBool lookupXObject(const char *name, Object *obj); - GBool lookupXObjectNF(const char *name, Object *obj); - void lookupColorSpace(const char *name, Object *obj); - GfxPattern *lookupPattern(const char *name); - GBool lookupGState(const char *name, Object *obj); + GfxFont *lookupFont(char *name); + GBool lookupXObject(char *name, Object *obj); + GBool lookupXObjectNF(char *name, Object *obj); + void lookupColorSpace(char *name, Object *obj); + GfxPattern *lookupPattern(char *name); + GfxShading *lookupShading(char *name); + GBool lookupGState(char *name, Object *obj); GfxResources *getNext() { return next; } @@ -80,6 +85,7 @@ private: Object xObjDict; Object colorSpaceDict; Object patternDict; + Object shadingDict; Object gStateDict; GfxResources *next; }; @@ -88,10 +94,9 @@ class Gfx { public: // Constructor for regular output. - Gfx(OutputDev *out1, int pageNum, Dict *resDict, - double dpi, double x1, double y1, double x2, double y2, GBool crop, - double cropX1, double cropY1, double cropX2, double cropY2, - int rotate); + Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, double dpi, + PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate, + GBool printCommandsA); // Destructor. ~Gfx(); @@ -104,7 +109,9 @@ public: private: + XRef *xref; // the xref table for this PDF file OutputDev *out; // output device + GBool printCommands; // print the drawing commands (for debugging) GfxResources *res; // resource stack GfxState *state; // current graphics state @@ -120,7 +127,7 @@ private: void go(GBool topLevel); void execOp(Object *cmd, Object args[], int numArgs); - Operator *findOp(const char *name); + Operator *findOp(char *name); GBool checkArg(Object *arg, TchkType type); int getPos(); @@ -170,8 +177,9 @@ private: void opCloseFillStroke(Object args[], int numArgs); void opEOFillStroke(Object args[], int numArgs); void opCloseEOFillStroke(Object args[], int numArgs); - void opShFill(Object args[], int numArgs); void doPatternFill(GBool eoFill); + void opShFill(Object args[], int numArgs); + void doAxialShFill(GfxAxialShading *shading); void doEndPath(); // path clipping operators diff --git a/pdftops/GfxFont.cxx b/pdftops/GfxFont.cxx index 413796f2d9..96b802e146 100644 --- a/pdftops/GfxFont.cxx +++ b/pdftops/GfxFont.cxx @@ -40,12 +40,10 @@ //------------------------------------------------------------------------ -#if defined(JAPANESE_SUPPORT) || defined(CHINESE_GB_SUPPORT) || defined(CHINESE_CNS_SUPPORT) extern "C" { -static int cmpWidthExcep(const void *w1, const void *w2); -static int cmpWidthExcepV(const void *w1, const void *w2); +static int CDECL cmpWidthExcep(const void *w1, const void *w2); +static int CDECL cmpWidthExcepV(const void *w1, const void *w2); } -#endif /* JAPANESE_SUPPORT || CHINESE_GB_SUPPORT || CHINESE_CNS_SUPPORT */ //------------------------------------------------------------------------ @@ -68,16 +66,16 @@ static Gushort *defCharWidths[12] = { // GfxFont //------------------------------------------------------------------------ -GfxFont::GfxFont(const char *tag1, Ref id1, Dict *fontDict) { +GfxFont::GfxFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict) { BuiltinFont *builtinFont; Object obj1, obj2, obj3, obj4; int missingWidth; - const char *name2, *p; + char *name2, *p; int i; // get font tag and ID - tag = new GString(tag1); - id = id1; + tag = new GString(tagA); + id = idA; // get font type type = fontUnknownType; @@ -106,7 +104,7 @@ GfxFont::GfxFont(const char *tag1, Ref id1, Dict *fontDict) { // without embedding them, so munge the names into the equivalent // PostScript names. This is a kludge -- it would be nice if Adobe // followed their own spec. - if (type == fontTrueType) { + if (type == fontTrueType && name) { p = name->getCString(); name2 = NULL; if (!strncmp(p, "Arial", 5)) { @@ -160,12 +158,39 @@ GfxFont::GfxFont(const char *tag1, Ref id1, Dict *fontDict) { // assume Times-Roman by default (for substitution purposes) flags = fontSerif; + // default ascent/descent values + if (builtinFont) { + ascent = 0.001 * builtinFont->ascent; + descent = 0.001 * builtinFont->descent; + } else { + ascent = 0.95; + descent = -0.35; + } + // get info from font descriptor embFontName = NULL; embFontID.num = -1; embFontID.gen = -1; missingWidth = 0; - fontDict->lookup("FontDescriptor", &obj1); + if (type == fontType0) { + fontDict->lookup("DescendantFonts", &obj2); + if (obj2.isArray()) { + obj2.arrayGet(0, &obj3); + if (obj3.isDict()) { + obj3.dictLookup("FontDescriptor", &obj1); + } else { + error(-1, "Bad descendant font in Type 0 font"); + obj1.initNull(); + } + obj3.free(); + } else { + error(-1, "Missing DescendantFonts entry in Type 0 font"); + obj1.initNull(); + } + obj2.free(); + } else { + fontDict->lookup("FontDescriptor", &obj1); + } if (obj1.isDict()) { // get flags @@ -197,7 +222,7 @@ GfxFont::GfxFont(const char *tag1, Ref id1, Dict *fontDict) { obj1.dictLookupNF("FontFile3", &obj2); if (obj2.isRef()) { embFontID = obj2.getRef(); - obj2.fetch(&obj3); + obj2.fetch(xref, &obj3); if (obj3.isStream()) { obj3.streamGetDict()->lookup("Subtype", &obj4); if (obj4.isName("Type1")) @@ -223,6 +248,30 @@ GfxFont::GfxFont(const char *tag1, Ref id1, Dict *fontDict) { missingWidth = obj2.getInt(); } obj2.free(); + + // get Ascent and Descent + obj1.dictLookup("Ascent", &obj2); + if (obj2.isNum()) { + ascent = 0.001 * obj2.getNum(); + } + obj2.free(); + obj1.dictLookup("Descent", &obj2); + if (obj2.isNum()) { + descent = 0.001 * obj2.getNum(); + } + obj2.free(); + + // font FontBBox + fontBBox[0] = fontBBox[1] = fontBBox[2] = fontBBox[3] = 0; + if (obj1.dictLookup("FontBBox", &obj2)->isArray()) { + for (i = 0; i < 4 && i < obj2.arrayGetLength(); ++i) { + if (obj2.arrayGet(i, &obj3)->isNum()) { + fontBBox[i] = obj3.getNum(); + } + obj3.free(); + } + } + obj2.free(); } obj1.free(); @@ -256,7 +305,7 @@ GfxFont::GfxFont(const char *tag1, Ref id1, Dict *fontDict) { if (type == fontType0) { getType0EncAndWidths(fontDict); } else { - getEncAndWidths(fontDict, builtinFont, missingWidth); + getEncAndWidths(xref, fontDict, builtinFont, missingWidth); } } @@ -390,10 +439,10 @@ Object *GfxFont::getCharProc(int code, Object *proc) { return proc; } -void GfxFont::getEncAndWidths(Dict *fontDict, BuiltinFont *builtinFont, - int missingWidth) { +void GfxFont::getEncAndWidths(XRef *xref, Dict *fontDict, + BuiltinFont *builtinFont, int missingWidth) { Object obj1, obj2, obj3; - const char *buf; + char *buf; int len; FontFile *fontFile; int code, i; @@ -433,26 +482,31 @@ void GfxFont::getEncAndWidths(Dict *fontDict, BuiltinFont *builtinFont, obj1.free(); // check embedded or external font file for base encoding - if ((type == fontType1 || type == fontType1C) && + if ((type == fontType1 || type == fontType1C || type == fontTrueType) && (extFontFile || embFontID.num >= 0)) { - if (extFontFile) + if (extFontFile) { buf = readExtFontFile(&len); - else - buf = readEmbFontFile(&len); + } else { + buf = readEmbFontFile(xref, &len); + } if (buf) { - if (type == fontType1) + if (type == fontType1) { fontFile = new Type1FontFile(buf, len); - else + } else if (type == fontType1C) { fontFile = new Type1CFontFile(buf, len); + } else { + fontFile = new TrueTypeFontFile(buf, len); + } if (fontFile->getName()) { if (embFontName) delete embFontName; embFontName = new GString(fontFile->getName()); } - if (!encoding) + if (!encoding) { encoding = fontFile->getEncoding(gTrue); + } delete fontFile; - gfree((void *)buf); + gfree(buf); } } @@ -500,7 +554,7 @@ void GfxFont::getEncAndWidths(Dict *fontDict, BuiltinFont *builtinFont, } void GfxFont::findExtFontFile() { - const char **path; + char **path; FILE *f; for (path = fontPath; *path; ++path) { @@ -524,7 +578,7 @@ void GfxFont::findExtFontFile() { } } -const char *GfxFont::readExtFontFile(int *len) { +char *GfxFont::readExtFontFile(int *len) { FILE *f; char *buf; @@ -542,7 +596,7 @@ const char *GfxFont::readExtFontFile(int *len) { return buf; } -const char *GfxFont::readEmbFontFile(int *len) { +char *GfxFont::readEmbFontFile(XRef *xref, int *len) { char *buf; Object obj1, obj2; Stream *str; @@ -550,7 +604,7 @@ const char *GfxFont::readEmbFontFile(int *len) { int size, i; obj1.initRef(embFontID.num, embFontID.gen); - obj1.fetch(&obj2); + obj1.fetch(xref, &obj2); if (!obj2.isStream()) { error(-1, "Embedded font file is not a stream"); obj2.free(); @@ -584,7 +638,7 @@ void GfxFont::makeWidths(Dict *fontDict, FontEncoding *builtinEncoding, Object obj1, obj2; int firstChar, lastChar; int code, code2; - const char *charName; + char *charName; Gushort *defWidths; int index; double mult; @@ -594,72 +648,73 @@ void GfxFont::makeWidths(Dict *fontDict, FontEncoding *builtinEncoding, widths[code] = missingWidth * 0.001; } + // use widths from font dict, if present + fontDict->lookup("FirstChar", &obj1); + firstChar = obj1.isInt() ? obj1.getInt() : 0; + obj1.free(); + fontDict->lookup("LastChar", &obj1); + lastChar = obj1.isInt() ? obj1.getInt() : 255; + obj1.free(); + if (type == fontType3) + mult = fontMat[0]; + else + mult = 0.001; + fontDict->lookup("Widths", &obj1); + if (obj1.isArray()) { + for (code = firstChar; code <= lastChar; ++code) { + obj1.arrayGet(code - firstChar, &obj2); + if (obj2.isNum()) + widths[code] = obj2.getNum() * mult; + obj2.free(); + } + // use widths from built-in font - if (builtinEncoding) { + } else if (builtinEncoding) { code2 = 0; // to make gcc happy for (code = 0; code < 256; ++code) { if ((charName = encoding->getCharName(code)) && - (code2 = builtinEncoding->getCharCode(charName)) >= 0) + (code2 = builtinEncoding->getCharCode(charName)) >= 0) { widths[code] = builtinWidths[code2] * 0.001; + } else if (code == 32) { + // this is a kludge for broken PDF files that encode char 32 + // as .notdef + widths[code] = builtinWidths[' '] * 0.001; + } } - // get widths from font dict + // couldn't find widths -- use defaults } else { - fontDict->lookup("FirstChar", &obj1); - firstChar = obj1.isInt() ? obj1.getInt() : 0; - obj1.free(); - fontDict->lookup("LastChar", &obj1); - lastChar = obj1.isInt() ? obj1.getInt() : 255; - obj1.free(); - if (type == fontType3) - mult = fontMat[0]; - else - mult = 0.001; - fontDict->lookup("Widths", &obj1); - if (obj1.isArray()) { - for (code = firstChar; code <= lastChar; ++code) { - obj1.arrayGet(code - firstChar, &obj2); - if (obj2.isNum()) - widths[code] = obj2.getNum() * mult; - obj2.free(); - } - } else { - - // couldn't find widths -- use defaults #if 0 //~ - //~ certain PDF generators apparently don't include widths - //~ for Arial and TimesNewRoman -- and this error message - //~ is a nuisance - error(-1, "No character widths resource for non-builtin font"); + //~ certain PDF generators apparently don't include widths + //~ for Arial and TimesNewRoman -- and this error message + //~ is a nuisance + error(-1, "No character widths resource for non-builtin font"); #endif - if (isFixedWidth()) - index = 0; - else if (isSerif()) - index = 8; - else - index = 4; - if (isBold()) - index += 2; - if (isItalic()) - index += 1; - defWidths = defCharWidths[index]; - code2 = 0; // to make gcc happy - for (code = 0; code < 256; ++code) { - if ((charName = encoding->getCharName(code)) && - (code2 = standardEncoding.getCharCode(charName)) >= 0) - widths[code] = defWidths[code2] * 0.001; - } + if (isFixedWidth()) + index = 0; + else if (isSerif()) + index = 8; + else + index = 4; + if (isBold()) + index += 2; + if (isItalic()) + index += 1; + defWidths = defCharWidths[index]; + code2 = 0; // to make gcc happy + for (code = 0; code < 256; ++code) { + if ((charName = encoding->getCharName(code)) && + (code2 = standardEncoding.getCharCode(charName)) >= 0) + widths[code] = defWidths[code2] * 0.001; } - obj1.free(); } + obj1.free(); } void GfxFont::getType0EncAndWidths(Dict *fontDict) { Object obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8; -#if defined(JAPANESE_SUPPORT) || defined(CHINESE_GB_SUPPORT) || defined(CHINESE_CNS_SUPPORT) int excepsSize; int i, j, k, n; -#endif /* JAPANESE_SUPPORT || CHINESE_GB_SUPPORT || CHINESE_CNS_SUPPORT */ widths16.exceps = NULL; widths16.excepsV = NULL; @@ -713,7 +768,7 @@ void GfxFont::getType0EncAndWidths(Dict *fontDict) { goto err4; #endif } else { - error(-1, "Uknown Type 0 character set: %s-%s", + error(-1, "Unknown Type 0 character set: %s-%s", obj4.getString()->getCString(), obj5.getString()->getCString()); goto err4; } @@ -721,8 +776,6 @@ void GfxFont::getType0EncAndWidths(Dict *fontDict) { error(-1, "Unknown Type 0 character set"); goto err4; } - -#if defined(JAPANESE_SUPPORT) || defined(CHINESE_GB_SUPPORT) || defined(CHINESE_CNS_SUPPORT) obj5.free(); obj4.free(); obj3.free(); @@ -914,7 +967,7 @@ void GfxFont::getType0EncAndWidths(Dict *fontDict) { error(-1, "Bad encoding for Type 0 font"); goto err1; } -# if JAPANESE_SUPPORT +#if JAPANESE_SUPPORT if (enc16.charSet == font16AdobeJapan12) { for (i = 0; gfxJapan12Tab[i].name; ++i) { if (!strcmp(obj1.getName(), gfxJapan12Tab[i].name)) @@ -927,8 +980,8 @@ void GfxFont::getType0EncAndWidths(Dict *fontDict) { } enc16.enc = gfxJapan12Tab[i].enc; } -# endif -# if CHINESE_GB_SUPPORT +#endif +#if CHINESE_GB_SUPPORT if (enc16.charSet == font16AdobeGB12) { for (i = 0; gfxGB12Tab[i].name; ++i) { if (!strcmp(obj1.getName(), gfxGB12Tab[i].name)) @@ -941,8 +994,8 @@ void GfxFont::getType0EncAndWidths(Dict *fontDict) { } enc16.enc = gfxGB12Tab[i].enc; } -# endif -# if CHINESE_CNS_SUPPORT +#endif +#if CHINESE_CNS_SUPPORT if (enc16.charSet == font16AdobeCNS13) { for (i = 0; gfxCNS13Tab[i].name; ++i) { if (!strcmp(obj1.getName(), gfxCNS13Tab[i].name)) @@ -955,11 +1008,10 @@ void GfxFont::getType0EncAndWidths(Dict *fontDict) { } enc16.enc = gfxCNS13Tab[i].enc; } -# endif +#endif obj1.free(); return; -#endif /* JAPANESE_SUPPORT || CHINESE_GB_SUPPORT || CHINESE_CNS_SUPPORT */ err4: obj5.free(); @@ -975,21 +1027,21 @@ void GfxFont::getType0EncAndWidths(Dict *fontDict) { makeWidths(fontDict, NULL, NULL, 0); } -#if defined(JAPANESE_SUPPORT) || defined(CHINESE_GB_SUPPORT) || defined(CHINESE_CNS_SUPPORT) -static int cmpWidthExcep(const void *w1, const void *w2) { +extern "C" { +static int CDECL cmpWidthExcep(const void *w1, const void *w2) { return ((GfxFontWidthExcep *)w1)->first - ((GfxFontWidthExcep *)w2)->first; } -static int cmpWidthExcepV(const void *w1, const void *w2) { +static int CDECL cmpWidthExcepV(const void *w1, const void *w2) { return ((GfxFontWidthExcepV *)w1)->first - ((GfxFontWidthExcepV *)w2)->first; } -#endif /* JAPANESE_SUPPORT || CHINESE_GB_SUPPORT || CHINESE_CNS_SUPPORT */ +} //------------------------------------------------------------------------ // GfxFontDict //------------------------------------------------------------------------ -GfxFontDict::GfxFontDict(Dict *fontDict) { +GfxFontDict::GfxFontDict(XRef *xref, Dict *fontDict) { int i; Object obj1, obj2; @@ -997,10 +1049,10 @@ GfxFontDict::GfxFontDict(Dict *fontDict) { fonts = (GfxFont **)gmalloc(numFonts * sizeof(GfxFont *)); for (i = 0; i < numFonts; ++i) { fontDict->getValNF(i, &obj1); - obj1.fetch(&obj2); + obj1.fetch(xref, &obj2); if (obj1.isRef() && obj2.isDict()) { - fonts[i] = new GfxFont(fontDict->getKey(i), obj1.getRef(), - obj2.getDict()); + fonts[i] = new GfxFont(xref, fontDict->getKey(i), + obj1.getRef(), obj2.getDict()); } else { error(-1, "font resource is not a dictionary"); fonts[i] = NULL; @@ -1018,7 +1070,7 @@ GfxFontDict::~GfxFontDict() { gfree(fonts); } -GfxFont *GfxFontDict::lookup(const char *tag) { +GfxFont *GfxFontDict::lookup(char *tag) { int i; for (i = 0; i < numFonts; ++i) { diff --git a/pdftops/GfxFont.h b/pdftops/GfxFont.h index 6853b1cc1a..e51635632a 100644 --- a/pdftops/GfxFont.h +++ b/pdftops/GfxFont.h @@ -98,7 +98,7 @@ class GfxFont { public: // Constructor. - GfxFont(const char *tag1, Ref id1, Dict *fontDict); + GfxFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict); // Destructor. ~GfxFont(); @@ -110,7 +110,7 @@ public: Ref getID() { return id; } // Does this font match the tag? - GBool matches(const char *tag1) { return !tag->cmp(tag1); } + GBool matches(char *tagA) { return !tag->cmp(tagA); } // Get base font name. GString *getName() { return name; } @@ -128,8 +128,8 @@ public: // Get the PostScript font name for the embedded font. Returns // NULL if there is no embedded font. - const char *getEmbeddedFontName() - { return embFontName ? embFontName->getCString() : (const char *)NULL; } + char *getEmbeddedFontName() + { return embFontName ? embFontName->getCString() : (char *)NULL; } // Get the name of the external font file. Returns NULL if there // is no external font file. @@ -156,10 +156,10 @@ public: FontEncoding *getEncoding() { return encoding; } // Return the character name associated with . - const char *getCharName(int code) { return encoding->getCharName(code); } + char *getCharName(int code) { return encoding->getCharName(code); } // Return the code associated with . - int getCharCode(const char *charName) { return encoding->getCharCode(charName); } + int getCharCode(char *charName) { return encoding->getCharCode(charName); } // Return the Type 3 CharProc for the character associated with . Object *getCharProc(int code, Object *proc); @@ -174,14 +174,21 @@ public: // Return the font matrix. double *getFontMatrix() { return fontMat; } + // Return the font bounding box. + double *getFontBBox() { return fontBBox; } + + // Return the ascent and descent values. + double getAscent() { return ascent; } + double getDescent() { return descent; } + // Read an external or embedded font file into a buffer. - const char *readExtFontFile(int *len); - const char *readEmbFontFile(int *len); + char *readExtFontFile(int *len); + char *readEmbFontFile(XRef *xref, int *len); private: - void getEncAndWidths(Dict *fontDict, BuiltinFont *builtinFont, - int missingWidth); + void getEncAndWidths(XRef *xref, Dict *fontDict, + BuiltinFont *builtinFont, int missingWidth); void findExtFontFile(); void makeWidths(Dict *fontDict, FontEncoding *builtinEncoding, Gushort *builtinWidths, int missingWidth); @@ -198,6 +205,9 @@ private: GString *extFontFile; // external font file name Object charProcs; // Type3 CharProcs dictionary double fontMat[6]; // font matrix + double fontBBox[4]; // font bounding box + double ascent; // max height above baseline + double descent; // max depth below baseline union { FontEncoding *encoding; // 8-bit font encoding struct { @@ -219,13 +229,13 @@ class GfxFontDict { public: // Build the font dictionary, given the PDF font dictionary. - GfxFontDict(Dict *fontDict); + GfxFontDict(XRef *xref, Dict *fontDict); // Destructor. ~GfxFontDict(); // Get the specified font. - GfxFont *lookup(const char *tag); + GfxFont *lookup(char *tag); // Iterative access. int getNumFonts() { return numFonts; } diff --git a/pdftops/GfxState.cxx b/pdftops/GfxState.cxx index 1abf9a56ec..1407415700 100644 --- a/pdftops/GfxState.cxx +++ b/pdftops/GfxState.cxx @@ -17,6 +17,7 @@ #include "Error.h" #include "Object.h" #include "Array.h" +#include "Page.h" #include "GfxState.h" //------------------------------------------------------------------------ @@ -261,9 +262,9 @@ GfxCalRGBColorSpace::GfxCalRGBColorSpace() { whiteX = whiteY = whiteZ = 1; blackX = blackY = blackZ = 0; gammaR = gammaG = gammaB = 1; - m[0] = 1; m[1] = 0; m[2] = 0; - m[3] = 0; m[4] = 1; m[5] = 0; - m[6] = 0; m[7] = 0; m[8] = 1; + mat[0] = 1; mat[1] = 0; mat[2] = 0; + mat[3] = 0; mat[4] = 1; mat[5] = 0; + mat[6] = 0; mat[7] = 0; mat[8] = 1; } GfxCalRGBColorSpace::~GfxCalRGBColorSpace() { @@ -284,7 +285,7 @@ GfxColorSpace *GfxCalRGBColorSpace::copy() { cs->gammaG = gammaG; cs->gammaB = gammaB; for (i = 0; i < 9; ++i) { - cs->m[i] = m[i]; + cs->mat[i] = mat[i]; } return cs; } @@ -344,7 +345,7 @@ GfxColorSpace *GfxCalRGBColorSpace::parse(Array *arr) { obj2.arrayGetLength() == 9) { for (i = 0; i < 9; ++i) { obj2.arrayGet(i, &obj3); - cs->m[i] = obj3.getNum(); + cs->mat[i] = obj3.getNum(); obj3.free(); } } @@ -609,11 +610,11 @@ void GfxLabColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange, // GfxICCBasedColorSpace //------------------------------------------------------------------------ -GfxICCBasedColorSpace::GfxICCBasedColorSpace(int nComps, GfxColorSpace *alt, - Ref *iccProfileStream) { - this->nComps = nComps; - this->alt = alt; - this->iccProfileStream = *iccProfileStream; +GfxICCBasedColorSpace::GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA, + Ref *iccProfileStreamA) { + nComps = nCompsA; + alt = altA; + iccProfileStream = *iccProfileStreamA; rangeMin[0] = rangeMin[1] = rangeMin[2] = rangeMin[3] = 0; rangeMax[0] = rangeMax[1] = rangeMax[2] = rangeMax[3] = 1; } @@ -636,19 +637,19 @@ GfxColorSpace *GfxICCBasedColorSpace::copy() { GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr) { GfxICCBasedColorSpace *cs; - Ref iccProfileStream; - int nComps; - GfxColorSpace *alt; + Ref iccProfileStreamA; + int nCompsA; + GfxColorSpace *altA; Dict *dict; Object obj1, obj2, obj3; int i; arr->getNF(1, &obj1); if (obj1.isRef()) { - iccProfileStream = obj1.getRef(); + iccProfileStreamA = obj1.getRef(); } else { - iccProfileStream.num = 0; - iccProfileStream.gen = 0; + iccProfileStreamA.num = 0; + iccProfileStreamA.gen = 0; } obj1.free(); arr->get(1, &obj1); @@ -664,19 +665,19 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr) { obj1.free(); return NULL; } - nComps = obj2.getInt(); + nCompsA = obj2.getInt(); obj2.free(); if (dict->lookup("Alternate", &obj2)->isNull() || - !(alt = GfxColorSpace::parse(&obj2))) { - switch (nComps) { + !(altA = GfxColorSpace::parse(&obj2))) { + switch (nCompsA) { case 1: - alt = new GfxDeviceGrayColorSpace(); + altA = new GfxDeviceGrayColorSpace(); break; case 3: - alt = new GfxDeviceRGBColorSpace(); + altA = new GfxDeviceRGBColorSpace(); break; case 4: - alt = new GfxDeviceCMYKColorSpace(); + altA = new GfxDeviceCMYKColorSpace(); break; default: error(-1, "Bad ICCBased color space - invalid N"); @@ -686,10 +687,10 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr) { } } obj2.free(); - cs = new GfxICCBasedColorSpace(nComps, alt, &iccProfileStream); + cs = new GfxICCBasedColorSpace(nCompsA, altA, &iccProfileStreamA); if (dict->lookup("Range", &obj2)->isArray() && - obj2.arrayGetLength() == 2 * nComps) { - for (i = 0; i < nComps; ++i) { + obj2.arrayGetLength() == 2 * nCompsA) { + for (i = 0; i < nCompsA; ++i) { obj2.arrayGet(2*i, &obj3); cs->rangeMin[i] = obj3.getNum(); obj3.free(); @@ -730,12 +731,12 @@ void GfxICCBasedColorSpace::getDefaultRanges(double *decodeLow, // GfxIndexedColorSpace //------------------------------------------------------------------------ -GfxIndexedColorSpace::GfxIndexedColorSpace(GfxColorSpace *base, - int indexHigh) { - this->base = base; - this->indexHigh = indexHigh; - this->lookup = (Guchar *)gmalloc((indexHigh + 1) * base->getNComps() * - sizeof(Guchar)); +GfxIndexedColorSpace::GfxIndexedColorSpace(GfxColorSpace *baseA, + int indexHighA) { + base = baseA; + indexHigh = indexHighA; + lookup = (Guchar *)gmalloc((indexHigh + 1) * base->getNComps() * + sizeof(Guchar)); } GfxIndexedColorSpace::~GfxIndexedColorSpace() { @@ -754,8 +755,8 @@ GfxColorSpace *GfxIndexedColorSpace::copy() { GfxColorSpace *GfxIndexedColorSpace::parse(Array *arr) { GfxIndexedColorSpace *cs; - GfxColorSpace *base; - int indexHigh; + GfxColorSpace *baseA; + int indexHighA; Object obj1; int x; char *s; @@ -766,7 +767,7 @@ GfxColorSpace *GfxIndexedColorSpace::parse(Array *arr) { goto err1; } arr->get(1, &obj1); - if (!(base = GfxColorSpace::parse(&obj1))) { + if (!(baseA = GfxColorSpace::parse(&obj1))) { error(-1, "Bad Indexed color space (base color space)"); goto err2; } @@ -775,14 +776,14 @@ GfxColorSpace *GfxIndexedColorSpace::parse(Array *arr) { error(-1, "Bad Indexed color space (hival)"); goto err2; } - indexHigh = obj1.getInt(); + indexHighA = obj1.getInt(); obj1.free(); - cs = new GfxIndexedColorSpace(base, indexHigh); + cs = new GfxIndexedColorSpace(baseA, indexHighA); arr->get(3, &obj1); - n = base->getNComps(); + n = baseA->getNComps(); if (obj1.isStream()) { obj1.streamReset(); - for (i = 0; i <= indexHigh; ++i) { + for (i = 0; i <= indexHighA; ++i) { for (j = 0; j < n; ++j) { if ((x = obj1.streamGetChar()) == EOF) { error(-1, "Bad Indexed color space (lookup table stream too short)"); @@ -793,12 +794,12 @@ GfxColorSpace *GfxIndexedColorSpace::parse(Array *arr) { } obj1.streamClose(); } else if (obj1.isString()) { - if (obj1.getString()->getLength() < (indexHigh + 1) * n) { + if (obj1.getString()->getLength() < (indexHighA + 1) * n) { error(-1, "Bad Indexed color space (lookup table string too short)"); goto err3; } s = obj1.getString()->getCString(); - for (i = 0; i <= indexHigh; ++i) { + for (i = 0; i <= indexHighA; ++i) { for (j = 0; j < n; ++j) { cs->lookup[i*n + j] = (Guchar)*s++; } @@ -868,12 +869,12 @@ void GfxIndexedColorSpace::getDefaultRanges(double *decodeLow, // GfxSeparationColorSpace //------------------------------------------------------------------------ -GfxSeparationColorSpace::GfxSeparationColorSpace(GString *name, - GfxColorSpace *alt, - Function *func) { - this->name = name; - this->alt = alt; - this->func = func; +GfxSeparationColorSpace::GfxSeparationColorSpace(GString *nameA, + GfxColorSpace *altA, + Function *funcA) { + name = nameA; + alt = altA; + func = funcA; } GfxSeparationColorSpace::~GfxSeparationColorSpace() { @@ -889,9 +890,9 @@ GfxColorSpace *GfxSeparationColorSpace::copy() { //~ handle the 'All' and 'None' colorants GfxColorSpace *GfxSeparationColorSpace::parse(Array *arr) { GfxSeparationColorSpace *cs; - GString *name; - GfxColorSpace *alt; - Function *func; + GString *nameA; + GfxColorSpace *altA; + Function *funcA; Object obj1; if (arr->getLength() != 4) { @@ -902,27 +903,31 @@ GfxColorSpace *GfxSeparationColorSpace::parse(Array *arr) { error(-1, "Bad Separation color space (name)"); goto err2; } - name = new GString(obj1.getName()); + nameA = new GString(obj1.getName()); obj1.free(); arr->get(2, &obj1); - if (!(alt = GfxColorSpace::parse(&obj1))) { + if (!(altA = GfxColorSpace::parse(&obj1))) { error(-1, "Bad Separation color space (alternate color space)"); goto err3; } obj1.free(); - func = Function::parse(arr->get(3, &obj1)); - obj1.free(); - if (!func->isOk()) { + arr->get(3, &obj1); + if (!(funcA = Function::parse(&obj1))) { goto err4; } - cs = new GfxSeparationColorSpace(name, alt, func); + if (!funcA->isOk()) { + goto err5; + } + obj1.free(); + cs = new GfxSeparationColorSpace(nameA, altA, funcA); return cs; + err5: + delete funcA; err4: - delete func; - delete alt; + delete altA; err3: - delete name; + delete nameA; err2: obj1.free(); err1: @@ -954,12 +959,12 @@ void GfxSeparationColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { // GfxDeviceNColorSpace //------------------------------------------------------------------------ -GfxDeviceNColorSpace::GfxDeviceNColorSpace(int nComps, - GfxColorSpace *alt, - Function *func) { - this->nComps = nComps; - this->alt = alt; - this->func = func; +GfxDeviceNColorSpace::GfxDeviceNColorSpace(int nCompsA, + GfxColorSpace *altA, + Function *funcA) { + nComps = nCompsA; + alt = altA; + func = funcA; } GfxDeviceNColorSpace::~GfxDeviceNColorSpace() { @@ -986,10 +991,10 @@ GfxColorSpace *GfxDeviceNColorSpace::copy() { //~ handle the 'None' colorant GfxColorSpace *GfxDeviceNColorSpace::parse(Array *arr) { GfxDeviceNColorSpace *cs; - int nComps; - GString *names[gfxColorMaxComps]; - GfxColorSpace *alt; - Function *func; + int nCompsA; + GString *namesA[gfxColorMaxComps]; + GfxColorSpace *altA; + Function *funcA; Object obj1, obj2; int i; @@ -1001,40 +1006,44 @@ GfxColorSpace *GfxDeviceNColorSpace::parse(Array *arr) { error(-1, "Bad DeviceN color space (names)"); goto err2; } - nComps = obj1.arrayGetLength(); - for (i = 0; i < nComps; ++i) { + nCompsA = obj1.arrayGetLength(); + for (i = 0; i < nCompsA; ++i) { if (!obj1.arrayGet(i, &obj2)->isName()) { error(-1, "Bad DeviceN color space (names)"); obj2.free(); goto err2; } - names[i] = new GString(obj2.getName()); + namesA[i] = new GString(obj2.getName()); obj2.free(); } obj1.free(); arr->get(2, &obj1); - if (!(alt = GfxColorSpace::parse(&obj1))) { + if (!(altA = GfxColorSpace::parse(&obj1))) { error(-1, "Bad DeviceN color space (alternate color space)"); goto err3; } obj1.free(); - func = Function::parse(arr->get(3, &obj1)); - obj1.free(); - if (!func->isOk()) { + arr->get(3, &obj1); + if (!(funcA = Function::parse(&obj1))) { goto err4; } - cs = new GfxDeviceNColorSpace(nComps, alt, func); - for (i = 0; i < nComps; ++i) { - cs->names[i] = names[i]; + if (!funcA->isOk()) { + goto err5; + } + obj1.free(); + cs = new GfxDeviceNColorSpace(nCompsA, altA, funcA); + for (i = 0; i < nCompsA; ++i) { + cs->names[i] = namesA[i]; } return cs; + err5: + delete funcA; err4: - delete func; - delete alt; + delete altA; err3: - for (i = 0; i < nComps; ++i) { - delete names[i]; + for (i = 0; i < nCompsA; ++i) { + delete namesA[i]; } err2: obj1.free(); @@ -1067,8 +1076,8 @@ void GfxDeviceNColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { // GfxPatternColorSpace //------------------------------------------------------------------------ -GfxPatternColorSpace::GfxPatternColorSpace(GfxColorSpace *under) { - this->under = under; +GfxPatternColorSpace::GfxPatternColorSpace(GfxColorSpace *underA) { + under = underA; } GfxPatternColorSpace::~GfxPatternColorSpace() { @@ -1084,24 +1093,24 @@ GfxColorSpace *GfxPatternColorSpace::copy() { GfxColorSpace *GfxPatternColorSpace::parse(Array *arr) { GfxPatternColorSpace *cs; - GfxColorSpace *under; + GfxColorSpace *underA; Object obj1; if (arr->getLength() != 1 && arr->getLength() != 2) { error(-1, "Bad Pattern color space"); return NULL; } - under = NULL; + underA = NULL; if (arr->getLength() == 2) { arr->get(1, &obj1); - if (!(under = GfxColorSpace::parse(&obj1))) { + if (!(underA = GfxColorSpace::parse(&obj1))) { error(-1, "Bad Pattern color space (underlying color space)"); obj1.free(); return NULL; } obj1.free(); } - cs = new GfxPatternColorSpace(under); + cs = new GfxPatternColorSpace(underA); return cs; } @@ -1122,8 +1131,8 @@ void GfxPatternColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { // Pattern //------------------------------------------------------------------------ -GfxPattern::GfxPattern(int type) { - this->type = type; +GfxPattern::GfxPattern(int typeA) { + type = typeA; } GfxPattern::~GfxPattern() { @@ -1237,480 +1246,254 @@ GfxTilingPattern::GfxTilingPattern(GfxTilingPattern *pat): } //------------------------------------------------------------------------ -// Function +// GfxShading //------------------------------------------------------------------------ -Function::Function() { -} - -Function::~Function() { +GfxShading::GfxShading() { } -Function *Function::parse(Object *funcObj) { - Function *func; - Dict *dict; - int funcType; - Object obj1; - - if (funcObj->isStream()) { - dict = funcObj->streamGetDict(); - } else if (funcObj->isDict()) { - dict = funcObj->getDict(); - } else { - error(-1, "Expected function dictionary or stream"); - return NULL; - } - - if (!dict->lookup("FunctionType", &obj1)->isInt()) { - error(-1, "Function type is missing or wrong type"); - obj1.free(); - return NULL; - } - funcType = obj1.getInt(); - obj1.free(); - - if (funcType == 0) { - func = new SampledFunction(funcObj, dict); - } else if (funcType == 2) { - func = new ExponentialFunction(funcObj, dict); - } else { - error(-1, "Unimplemented function type"); - return NULL; - } - if (!func->isOk()) { - delete func; - return NULL; - } - - return func; +GfxShading::~GfxShading() { + delete colorSpace; } -GBool Function::init(Dict *dict) { +GfxShading *GfxShading::parse(Object *obj) { + GfxShading *shading; + int typeA; + GfxColorSpace *colorSpaceA; + GfxColor backgroundA; + GBool hasBackgroundA; + double xMinA, yMinA, xMaxA, yMaxA; + GBool hasBBoxA; Object obj1, obj2; int i; - //----- Domain - if (!dict->lookup("Domain", &obj1)->isArray()) { - error(-1, "Function is missing domain"); - goto err2; - } - m = obj1.arrayGetLength() / 2; - if (m > funcMaxInputs) { - error(-1, "Functions with more than %d inputs are unsupported", - funcMaxInputs); - goto err2; - } - for (i = 0; i < m; ++i) { - obj1.arrayGet(2*i, &obj2); - if (!obj2.isNum()) { - error(-1, "Illegal value in function domain array"); + shading = NULL; + if (obj->isDict()) { + + if (!obj->dictLookup("ShadingType", &obj1)->isInt()) { + error(-1, "Invalid ShadingType in shading dictionary"); + obj1.free(); goto err1; } - domain[i][0] = obj2.getNum(); - obj2.free(); - obj1.arrayGet(2*i+1, &obj2); - if (!obj2.isNum()) { - error(-1, "Illegal value in function domain array"); + typeA = obj1.getInt(); + obj1.free(); + if (typeA != 2) { + error(-1, "Unimplemented shading type %d", typeA); goto err1; } - domain[i][1] = obj2.getNum(); - obj2.free(); - } - obj1.free(); - //----- Range - hasRange = gFalse; - n = 0; - if (dict->lookup("Range", &obj1)->isArray()) { - hasRange = gTrue; - n = obj1.arrayGetLength() / 2; - if (n > funcMaxOutputs) { - error(-1, "Functions with more than %d outputs are unsupported", - funcMaxOutputs); - goto err2; - } - for (i = 0; i < n; ++i) { - obj1.arrayGet(2*i, &obj2); - if (!obj2.isNum()) { - error(-1, "Illegal value in function range array"); - goto err1; - } - range[i][0] = obj2.getNum(); - obj2.free(); - obj1.arrayGet(2*i+1, &obj2); - if (!obj2.isNum()) { - error(-1, "Illegal value in function range array"); - goto err1; - } - range[i][1] = obj2.getNum(); - obj2.free(); + obj->dictLookup("ColorSpace", &obj1); + if (!(colorSpaceA = GfxColorSpace::parse(&obj1))) { + error(-1, "Bad color space in shading dictionary"); + obj1.free(); + goto err1; } obj1.free(); - } - - return gTrue; - err1: - obj2.free(); - err2: - obj1.free(); - return gFalse; -} - -//------------------------------------------------------------------------ -// SampledFunction -//------------------------------------------------------------------------ - -SampledFunction::SampledFunction(Object *funcObj, Dict *dict) { - Stream *str; - int nSamples, sampleBits; - double sampleMul; - Object obj1, obj2; - Guint buf, bitMask; - int bits; - int s; - int i; - - samples = NULL; - ok = gFalse; - - //----- initialize the generic stuff - if (!init(dict)) { - goto err1; - } - if (!hasRange) { - error(-1, "Type 0 function is missing range"); - goto err1; - } - - //----- get the stream - if (!funcObj->isStream()) { - error(-1, "Type 0 function isn't a stream"); - goto err1; - } - str = funcObj->getStream(); - - //----- Size - if (!dict->lookup("Size", &obj1)->isArray() || - obj1.arrayGetLength() != m) { - error(-1, "Function has missing or invalid size array"); - goto err2; - } - for (i = 0; i < m; ++i) { - obj1.arrayGet(i, &obj2); - if (!obj2.isInt()) { - error(-1, "Illegal value in function size array"); - goto err3; + for (i = 0; i < gfxColorMaxComps; ++i) { + backgroundA.c[i] = 0; } - sampleSize[i] = obj2.getInt(); - obj2.free(); - } - obj1.free(); - - //----- BitsPerSample - if (!dict->lookup("BitsPerSample", &obj1)->isInt()) { - error(-1, "Function has missing or invalid BitsPerSample"); - goto err2; - } - sampleBits = obj1.getInt(); - sampleMul = 1.0 / (double)((1 << sampleBits) - 1); - obj1.free(); - - //----- Encode - if (dict->lookup("Encode", &obj1)->isArray() && - obj1.arrayGetLength() == 2*m) { - for (i = 0; i < m; ++i) { - obj1.arrayGet(2*i, &obj2); - if (!obj2.isNum()) { - error(-1, "Illegal value in function encode array"); - goto err3; - } - encode[i][0] = obj2.getNum(); - obj2.free(); - obj1.arrayGet(2*i+1, &obj2); - if (!obj2.isNum()) { - error(-1, "Illegal value in function encode array"); - goto err3; + hasBackgroundA = gFalse; + if (obj->dictLookup("Background", &obj1)->isArray()) { + if (obj1.arrayGetLength() == colorSpaceA->getNComps()) { + hasBackgroundA = gTrue; + for (i = 0; i < colorSpaceA->getNComps(); ++i) { + backgroundA.c[i] = obj1.arrayGet(i, &obj2)->getNum(); + obj2.free(); + } + } else { + error(-1, "Bad Background in shading dictionary"); } - encode[i][1] = obj2.getNum(); - obj2.free(); - } - } else { - for (i = 0; i < m; ++i) { - encode[i][0] = 0; - encode[i][1] = sampleSize[i] - 1; } - } - obj1.free(); + obj1.free(); - //----- Decode - if (dict->lookup("Decode", &obj1)->isArray() && - obj1.arrayGetLength() == 2*n) { - for (i = 0; i < n; ++i) { - obj1.arrayGet(2*i, &obj2); - if (!obj2.isNum()) { - error(-1, "Illegal value in function decode array"); - goto err3; + xMinA = yMinA = xMaxA = yMaxA = 0; + hasBBoxA = gFalse; + if (obj->dictLookup("BBox", &obj1)->isArray()) { + if (obj1.arrayGetLength() == 4) { + hasBBoxA = gTrue; + xMinA = obj1.arrayGet(0, &obj2)->getNum(); + obj2.free(); + yMinA = obj1.arrayGet(1, &obj2)->getNum(); + obj2.free(); + xMaxA = obj1.arrayGet(2, &obj2)->getNum(); + obj2.free(); + yMaxA = obj1.arrayGet(3, &obj2)->getNum(); + obj2.free(); + } else { + error(-1, "Bad BBox in shading dictionary"); } - decode[i][0] = obj2.getNum(); - obj2.free(); - obj1.arrayGet(2*i+1, &obj2); - if (!obj2.isNum()) { - error(-1, "Illegal value in function decode array"); - goto err3; - } - decode[i][1] = obj2.getNum(); - obj2.free(); - } - } else { - for (i = 0; i < n; ++i) { - decode[i][0] = range[i][0]; - decode[i][1] = range[i][1]; } - } - obj1.free(); + obj1.free(); - //----- samples - nSamples = n; - for (i = 0; i < m; ++i) - nSamples *= sampleSize[i]; - samples = (double *)gmalloc(nSamples * sizeof(double)); - buf = 0; - bits = 0; - bitMask = (1 << sampleBits) - 1; - str->reset(); - for (i = 0; i < nSamples; ++i) { - if (sampleBits == 8) { - s = str->getChar(); - } else if (sampleBits == 16) { - s = str->getChar(); - s = (s << 8) + str->getChar(); - } else if (sampleBits == 32) { - s = str->getChar(); - s = (s << 8) + str->getChar(); - s = (s << 8) + str->getChar(); - s = (s << 8) + str->getChar(); - } else { - while (bits < sampleBits) { - buf = (buf << 8) | (str->getChar() & 0xff); - bits += 8; - } - s = (buf >> (bits - sampleBits)) & bitMask; - bits -= sampleBits; + shading = GfxAxialShading::parse(obj->getDict()); + + if (shading) { + shading->type = typeA; + shading->colorSpace = colorSpaceA; + shading->background = backgroundA; + shading->hasBackground = hasBackgroundA; + shading->xMin = xMinA; + shading->yMin = yMinA; + shading->xMax = xMaxA; + shading->yMax = yMaxA; + shading->hasBBox = hasBBoxA; } - samples[i] = (double)s * sampleMul; } - str->close(); - ok = gTrue; - return; + return shading; - err3: - obj2.free(); - err2: - obj1.free(); err1: - return; -} - -SampledFunction::~SampledFunction() { - if (samples) { - gfree(samples); - } + return NULL; } -SampledFunction::SampledFunction(SampledFunction *func) { - int nSamples, i; +//------------------------------------------------------------------------ +// GfxAxialShading +//------------------------------------------------------------------------ - memcpy(this, func, sizeof(SampledFunction)); +GfxAxialShading::GfxAxialShading(double x0A, double y0A, + double x1A, double y1A, + double t0A, double t1A, + Function **funcsA, int nFuncsA, + GBool extend0A, GBool extend1A) { + int i; - nSamples = n; - for (i = 0; i < m; ++i) { - nSamples *= sampleSize[i]; + x0 = x0A; + y0 = y0A; + x1 = x1A; + y1 = y1A; + t0 = t0A; + t1 = t1A; + nFuncs = nFuncsA; + for (i = 0; i < nFuncs; ++i) { + funcs[i] = funcsA[i]; } - samples = (double *)gmalloc(nSamples * sizeof(double)); - memcpy(samples, func->samples, nSamples * sizeof(double)); + extend0 = extend0A; + extend1 = extend1A; } -void SampledFunction::transform(double *in, double *out) { - double e[4]; - double s; - double x0, x1; - int e0, e1; - double efrac; +GfxAxialShading::~GfxAxialShading() { int i; - // map input values into sample array - for (i = 0; i < m; ++i) { - e[i] = ((in[i] - domain[i][0]) / (domain[i][1] - domain[i][0])) * - (encode[i][1] - encode[i][0]) + encode[i][0]; - if (e[i] < 0) { - e[i] = 0; - } else if (e[i] > sampleSize[i] - 1) { - e[i] = sampleSize[i] - 1; - } - } - - for (i = 0; i < n; ++i) { - - // m-linear interpolation - // (only m=1 is currently supported) - e0 = (int)floor(e[0]); - e1 = (int)ceil(e[0]); - efrac = e[0] - e0; - x0 = samples[e0 * n + i]; - x1 = samples[e1 * n + i]; - s = (1 - efrac) * x0 + efrac * x1; - - // map output values to range - out[i] = s * (decode[i][1] - decode[i][0]) + decode[i][0]; - if (out[i] < range[i][0]) { - out[i] = range[i][0]; - } else if (out[i] > range[i][1]) { - out[i] = range[i][1]; - } + for (i = 0; i < nFuncs; ++i) { + delete funcs[i]; } } -//------------------------------------------------------------------------ -// ExponentialFunction -//------------------------------------------------------------------------ - -ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) { +GfxAxialShading *GfxAxialShading::parse(Dict *dict) { + double x0A, y0A, x1A, y1A; + double t0A, t1A; + Function *funcsA[gfxColorMaxComps]; + int nFuncsA; + GBool extend0A, extend1A; Object obj1, obj2; - GBool hasN; int i; - ok = gFalse; - hasN = gFalse; - - //----- initialize the generic stuff - if (!init(dict)) { - goto err1; - } - if (m != 1) { - error(-1, "Exponential function with more than one input"); + x0A = y0A = x1A = y1A = 0; + if (dict->lookup("Coords", &obj1)->isArray() && + obj1.arrayGetLength() == 4) { + x0A = obj1.arrayGet(0, &obj2)->getNum(); + obj2.free(); + y0A = obj1.arrayGet(1, &obj2)->getNum(); + obj2.free(); + x1A = obj1.arrayGet(2, &obj2)->getNum(); + obj2.free(); + y1A = obj1.arrayGet(3, &obj2)->getNum(); + obj2.free(); + } else { + error(-1, "Missing or invalid Coords in shading dictionary"); goto err1; } + obj1.free(); - //----- default values - for (i = 0; i < funcMaxOutputs; ++i) { - c0[i] = 0; - c1[i] = 1; + t0A = 0; + t1A = 1; + if (dict->lookup("Domain", &obj1)->isArray() && + obj1.arrayGetLength() == 2) { + t0A = obj1.arrayGet(0, &obj2)->getNum(); + obj2.free(); + t1A = obj1.arrayGet(1, &obj2)->getNum(); + obj2.free(); } + obj1.free(); - //----- C0 - if (dict->lookup("C0", &obj1)->isArray()) { - if (!hasN) { - n = obj1.arrayGetLength(); - } else if (obj1.arrayGetLength() != n) { - error(-1, "Function's C0 array is wrong length"); - goto err2; - } - for (i = 0; i < n; ++i) { + dict->lookup("Function", &obj1); + if (obj1.isArray()) { + nFuncsA = obj1.arrayGetLength(); + for (i = 0; i < nFuncsA; ++i) { obj1.arrayGet(i, &obj2); - if (!obj2.isNum()) { - error(-1, "Illegal value in function C0 array"); - goto err3; + if (!(funcsA[i] = Function::parse(&obj2))) { + obj1.free(); + obj2.free(); + goto err1; } - c0[i] = obj2.getNum(); obj2.free(); } - obj1.free(); + } else { + nFuncsA = 1; + if (!(funcsA[0] = Function::parse(&obj1))) { + obj1.free(); + goto err1; + } } - - //----- C1 - if (dict->lookup("C1", &obj1)->isArray()) { - if (!hasN) { - n = obj1.arrayGetLength(); - } else if (obj1.arrayGetLength() != n) { - error(-1, "Function's C1 array is wrong length"); + obj1.free(); + for (i = 0; i < nFuncsA; ++i) { + if (!funcsA[i]->isOk()) { goto err2; } - for (i = 0; i < n; ++i) { - obj1.arrayGet(i, &obj2); - if (!obj2.isNum()) { - error(-1, "Illegal value in function C1 array"); - goto err3; - } - c1[i] = obj2.getNum(); - obj2.free(); - } - obj1.free(); } - //----- N (exponent) - if (!dict->lookup("N", &obj1)->isNum()) { - error(-1, "Function has missing or invalid N"); - goto err2; + extend0A = extend1A = gFalse; + if (dict->lookup("Extend", &obj1)->isArray() && + obj1.arrayGetLength() == 2) { + extend0A = obj1.arrayGet(0, &obj2)->getBool(); + obj2.free(); + extend1A = obj1.arrayGet(1, &obj2)->getBool(); + obj2.free(); } - e = obj1.getNum(); obj1.free(); - ok = gTrue; - return; + return new GfxAxialShading(x0A, y0A, x1A, y1A, t0A, t1A, + funcsA, nFuncsA, extend0A, extend1A); - err3: - obj2.free(); err2: - obj1.free(); + for (i = 0; i < nFuncsA; ++i) { + delete funcsA[i]; + } err1: - return; -} - -ExponentialFunction::~ExponentialFunction() { -} - -ExponentialFunction::ExponentialFunction(ExponentialFunction *func) { - memcpy(this, func, sizeof(ExponentialFunction)); + return NULL; } -void ExponentialFunction::transform(double *in, double *out) { - double x; +void GfxAxialShading::getColor(double t, GfxColor *color) { int i; - if (in[0] < domain[0][0]) { - x = domain[0][0]; - } else if (in[0] > domain[0][1]) { - x = domain[0][1]; - } else { - x = in[0]; - } - for (i = 0; i < n; ++i) { - out[i] = c0[i] + pow(x, e) * (c1[i] - c0[i]); - if (hasRange) { - if (out[i] < range[i][0]) { - out[i] = range[i][0]; - } else if (out[i] > range[i][1]) { - out[i] = range[i][1]; - } - } + for (i = 0; i < nFuncs; ++i) { + funcs[i]->transform(&t, &color->c[i]); } - return; } //------------------------------------------------------------------------ // GfxImageColorMap //------------------------------------------------------------------------ -GfxImageColorMap::GfxImageColorMap(int bits, Object *decode, - GfxColorSpace *colorSpace) { +GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode, + GfxColorSpace *colorSpaceA) { GfxIndexedColorSpace *indexedCS; GfxSeparationColorSpace *sepCS; int maxPixel, indexHigh; Guchar *lookup2; Function *sepFunc; Object obj; - double x; + double x[gfxColorMaxComps]; double y[gfxColorMaxComps]; int i, j, k; ok = gTrue; // bits per component and color space - this->bits = bits; + bits = bitsA; maxPixel = (1 << bits) - 1; - this->colorSpace = colorSpace; + colorSpace = colorSpaceA; // get decode map if (decode->isNull()) { @@ -1783,8 +1566,8 @@ GfxImageColorMap::GfxImageColorMap(int bits, Object *decode, lookup = (double *)gmalloc((maxPixel + 1) * nComps2 * sizeof(double)); sepFunc = sepCS->getFunc(); for (i = 0; i <= maxPixel; ++i) { - x = decodeLow[0] + (i * decodeRange[0]) / maxPixel; - sepFunc->transform(&x, y); + x[0] = decodeLow[0] + (i * decodeRange[0]) / maxPixel; + sepFunc->transform(x, y); for (k = 0; k < nComps2; ++k) { lookup[i*nComps2 + k] = y[k]; } @@ -2014,14 +1797,14 @@ void GfxPath::curveTo(double x1, double y1, double x2, double y2, // GfxState //------------------------------------------------------------------------ -GfxState::GfxState(double dpi, double px1a, double py1a, - double px2a, double py2a, int rotate, GBool upsideDown) { +GfxState::GfxState(double dpi, PDFRectangle *pageBox, int rotate, + GBool upsideDown) { double k; - px1 = px1a; - py1 = py1a; - px2 = px2a; - py2 = py2a; + px1 = pageBox->x1; + py1 = pageBox->y1; + px2 = pageBox->x2; + py2 = pageBox->y2; k = dpi / 72.0; if (rotate == 90) { ctm[0] = 0; @@ -2095,6 +1878,11 @@ GfxState::GfxState(double dpi, double px1a, double py1a, curX = curY = 0; lineX = lineY = 0; + clipXMin = 0; + clipYMin = 0; + clipXMax = pageWidth; + clipYMax = pageHeight; + saved = NULL; } @@ -2233,6 +2021,47 @@ void GfxState::clearPath() { path = new GfxPath(); } +void GfxState::clip() { + double xMin, yMin, xMax, yMax, x, y; + GfxSubpath *subpath; + int i, j; + + xMin = xMax = yMin = yMax = 0; // make gcc happy + for (i = 0; i < path->getNumSubpaths(); ++i) { + subpath = path->getSubpath(i); + for (j = 0; j < subpath->getNumPoints(); ++j) { + transform(subpath->getX(j), subpath->getY(j), &x, &y); + if (i == 0 && j == 0) { + xMin = xMax = x; + yMin = yMax = y; + } else { + if (x < xMin) { + xMin = x; + } else if (x > xMax) { + xMax = x; + } + if (y < yMin) { + yMin = y; + } else if (y > yMax) { + yMax = y; + } + } + } + } + if (xMin > clipXMin) { + clipXMin = xMin; + } + if (yMin > clipYMin) { + clipYMin = yMin; + } + if (xMax < clipXMax) { + clipXMax = xMax; + } + if (yMax < clipYMax) { + clipYMax = yMax; + } +} + void GfxState::textShift(double tx) { double dx, dy; diff --git a/pdftops/GfxState.h b/pdftops/GfxState.h index 2056c4d1fb..a628f6bf1f 100644 --- a/pdftops/GfxState.h +++ b/pdftops/GfxState.h @@ -15,16 +15,17 @@ #include "gtypes.h" #include "Object.h" +#include "Function.h" class Array; -class Function; class GfxFont; +struct PDFRectangle; //------------------------------------------------------------------------ // GfxColor //------------------------------------------------------------------------ -#define gfxColorMaxComps 8 +#define gfxColorMaxComps funcMaxOutputs struct GfxColor { double c[gfxColorMaxComps]; @@ -201,14 +202,14 @@ public: double getGammaR() { return gammaR; } double getGammaG() { return gammaG; } double getGammaB() { return gammaB; } - double *getMatrix() { return m; } + double *getMatrix() { return mat; } private: double whiteX, whiteY, whiteZ; // white point double blackX, blackY, blackZ; // black point double gammaR, gammaG, gammaB; // gamma values - double m[9]; // ABC -> XYZ transform matrix + double mat[9]; // ABC -> XYZ transform matrix }; //------------------------------------------------------------------------ @@ -283,8 +284,8 @@ private: class GfxICCBasedColorSpace: public GfxColorSpace { public: - GfxICCBasedColorSpace(int nComps, GfxColorSpace *alt, - Ref *iccProfileStream); + GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA, + Ref *iccProfileStreamA); virtual ~GfxICCBasedColorSpace(); virtual GfxColorSpace *copy(); virtual GfxColorSpaceMode getMode() { return csICCBased; } @@ -320,7 +321,7 @@ private: class GfxIndexedColorSpace: public GfxColorSpace { public: - GfxIndexedColorSpace(GfxColorSpace *base, int indexHigh); + GfxIndexedColorSpace(GfxColorSpace *baseA, int indexHighA); virtual ~GfxIndexedColorSpace(); virtual GfxColorSpace *copy(); virtual GfxColorSpaceMode getMode() { return csIndexed; } @@ -356,8 +357,8 @@ private: class GfxSeparationColorSpace: public GfxColorSpace { public: - GfxSeparationColorSpace(GString *name, GfxColorSpace *alt, - Function *func); + GfxSeparationColorSpace(GString *nameA, GfxColorSpace *altA, + Function *funcA); virtual ~GfxSeparationColorSpace(); virtual GfxColorSpace *copy(); virtual GfxColorSpaceMode getMode() { return csSeparation; } @@ -424,7 +425,7 @@ private: class GfxPatternColorSpace: public GfxColorSpace { public: - GfxPatternColorSpace(GfxColorSpace *under); + GfxPatternColorSpace(GfxColorSpace *underA); virtual ~GfxPatternColorSpace(); virtual GfxColorSpace *copy(); virtual GfxColorSpaceMode getMode() { return csPattern; } @@ -454,7 +455,7 @@ private: class GfxPattern { public: - GfxPattern(int type); + GfxPattern(int typeA); virtual ~GfxPattern(); static GfxPattern *parse(Object *obj); @@ -504,94 +505,66 @@ private: }; //------------------------------------------------------------------------ -// Function +// GfxShading //------------------------------------------------------------------------ -#define funcMaxInputs 1 -#define funcMaxOutputs 8 - -class Function { +class GfxShading { public: - Function(); - - virtual ~Function(); - - // Construct a function. Returns NULL if unsuccessful. - static Function *parse(Object *funcObj); - - // Initialize the entries common to all function types. - GBool init(Dict *dict); - - virtual Function *copy() = 0; - - // Return size of input and output tuples. - int getInputSize() { return m; } - int getOutputSize() { return n; } + GfxShading(); + virtual ~GfxShading(); - // Transform an input tuple into an output tuple. - virtual void transform(double *in, double *out) = 0; + static GfxShading *parse(Object *obj); - virtual GBool isOk() = 0; + int getType() { return type; } + GfxColorSpace *getColorSpace() { return colorSpace; } + GfxColor *getBackground() { return &background; } + GBool getHasBackground() { return hasBackground; } + void getBBox(double *xMinA, double *yMinA, double *xMaxA, double *yMaxA) + { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; } + GBool getHasBBox() { return hasBBox; } -protected: +private: - int m, n; // size of input and output tuples - double // min and max values for function domain - domain[funcMaxInputs][2]; - double // min and max values for function range - range[funcMaxOutputs][2]; - GBool hasRange; // set if range is defined + int type; + GfxColorSpace *colorSpace; + GfxColor background; + GBool hasBackground; + double xMin, yMin, xMax, yMax; + GBool hasBBox; }; //------------------------------------------------------------------------ -// SampledFunction +// GfxAxialShading //------------------------------------------------------------------------ -class SampledFunction: public Function { +class GfxAxialShading: public GfxShading { public: - SampledFunction(Object *funcObj, Dict *dict); - virtual ~SampledFunction(); - virtual Function *copy() { return new SampledFunction(this); } - virtual void transform(double *in, double *out); - virtual GBool isOk() { return ok; } - -private: - - SampledFunction(SampledFunction *func); - - int // number of samples for each domain element - sampleSize[funcMaxInputs]; - double // min and max values for domain encoder - encode[funcMaxInputs][2]; - double // min and max values for range decoder - decode[funcMaxOutputs][2]; - double *samples; // the samples - GBool ok; -}; - -//------------------------------------------------------------------------ -// ExponentialFunction -//------------------------------------------------------------------------ + GfxAxialShading(double x0A, double y0A, + double x1A, double y1A, + double t0A, double t1A, + Function **funcsA, int nFuncsA, + GBool extend0A, GBool extend1A); + virtual ~GfxAxialShading(); -class ExponentialFunction: public Function { -public: + static GfxAxialShading *parse(Dict *dict); - ExponentialFunction(Object *funcObj, Dict *dict); - virtual ~ExponentialFunction(); - virtual Function *copy() { return new ExponentialFunction(this); } - virtual void transform(double *in, double *out); - virtual GBool isOk() { return ok; } + void getCoords(double *x0A, double *y0A, double *x1A, double *y1A) + { *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; } + double getDomain0() { return t0; } + double getDomain1() { return t1; } + void getColor(double t, GfxColor *color); + GBool getExtend0() { return extend0; } + GBool getExtend1() { return extend1; } private: - ExponentialFunction(ExponentialFunction *func); - - double c0[funcMaxOutputs]; - double c1[funcMaxOutputs]; - double e; - GBool ok; + double x0, y0, x1, y1; + double t0, t1; + Function *funcs[gfxColorMaxComps]; + int nFuncs; + GBool extend0, extend1; }; //------------------------------------------------------------------------ @@ -602,7 +575,7 @@ class GfxImageColorMap { public: // Constructor. - GfxImageColorMap(int bits, Object *decode, GfxColorSpace *colorSpace); + GfxImageColorMap(int bitsA, Object *decode, GfxColorSpace *colorSpaceA); // Destructor. ~GfxImageColorMap(); @@ -750,10 +723,10 @@ class GfxState { public: // Construct a default GfxState, for a device with resolution , - // page box (,)-(,), page rotation , and - // coordinate system specified by . - GfxState(double dpi, double px1a, double py1a, - double px2a, double py2a, int rotate, GBool upsideDown); + // page box , page rotation , and coordinate system + // specified by . + GfxState(double dpi, PDFRectangle *pageBox, int rotate, + GBool upsideDown); // Destructor. ~GfxState(); @@ -771,6 +744,10 @@ public: double getPageHeight() { return pageHeight; } GfxColor *getFillColor() { return &fillColor; } GfxColor *getStrokeColor() { return &strokeColor; } + void getFillGray(double *gray) + { fillColorSpace->getGray(&fillColor, gray); } + void getStrokeGray(double *gray) + { strokeColorSpace->getGray(&fillColor, gray); } void getFillRGB(GfxRGB *rgb) { fillColorSpace->getRGB(&fillColor, rgb); } void getStrokeRGB(GfxRGB *rgb) @@ -804,6 +781,8 @@ public: GfxPath *getPath() { return path; } double getCurX() { return curX; } double getCurY() { return curY; } + void getClipBBox(double *xMin, double *yMin, double *xMax, double *yMax) + { *xMin = clipXMin; *yMin = clipYMin; *xMax = clipXMax; *yMax = clipYMax; } double getLineX() { return lineX; } double getLineY() { return lineY; } @@ -848,9 +827,9 @@ public: void setFlatness(int flatness1) { flatness = flatness1; } void setLineJoin(int lineJoin1) { lineJoin = lineJoin1; } void setLineCap(int lineCap1) { lineCap = lineCap1; } - void setMiterLimit(double miterLimit1) { miterLimit = miterLimit1; } - void setFont(GfxFont *font1, double fontSize1) - { font = font1; fontSize = fontSize1; } + void setMiterLimit(double limit) { miterLimit = limit; } + void setFont(GfxFont *fontA, double fontSizeA) + { font = fontA; fontSize = fontSizeA; } void setTextMat(double a, double b, double c, double d, double e, double f) { textMat[0] = a; textMat[1] = b; textMat[2] = c; @@ -861,12 +840,12 @@ public: { wordSpace = space; } void setHorizScaling(double scale) { horizScaling = 0.01 * scale; } - void setLeading(double leading1) - { leading = leading1; } - void setRise(double rise1) - { rise = rise1; } - void setRender(int render1) - { render = render1; } + void setLeading(double leadingA) + { leading = leadingA; } + void setRise(double riseA) + { rise = riseA; } + void setRender(int renderA) + { render = renderA; } // Add to path. void moveTo(double x, double y) @@ -880,6 +859,9 @@ public: { path->close(); curX = path->getLastX(); curY = path->getLastY(); } void clearPath(); + // Update clip region. + void clip(); + // Text position. void textMoveTo(double tx, double ty) { lineX = tx; lineY = ty; textTransform(tx, ty, &curX, &curY); } @@ -929,6 +911,9 @@ private: double curX, curY; // current point (user coords) double lineX, lineY; // start of current text line (text coords) + double clipXMin, clipYMin, // bounding box for clip region + clipXMax, clipYMax; + GfxState *saved; // next GfxState on stack GfxState(GfxState *state); diff --git a/pdftops/Lexer.cxx b/pdftops/Lexer.cxx index 4ca8cfe9f5..442566b721 100644 --- a/pdftops/Lexer.cxx +++ b/pdftops/Lexer.cxx @@ -44,22 +44,22 @@ static char specialChars[256] = { // Lexer //------------------------------------------------------------------------ -Lexer::Lexer(Stream *str) { +Lexer::Lexer(XRef *xref, Stream *str) { Object obj; curStr.initStream(str); - streams = new Array(); + streams = new Array(xref); streams->add(curStr.copy(&obj)); strPtr = 0; freeArray = gTrue; curStr.streamReset(); } -Lexer::Lexer(Object *obj) { +Lexer::Lexer(XRef *xref, Object *obj) { Object obj2; if (obj->isStream()) { - streams = new Array(); + streams = new Array(xref); freeArray = gTrue; streams->add(obj->copy(&obj2)); } else { @@ -204,11 +204,15 @@ Object *Lexer::getObj(Object *obj) { case '(': ++numParen; + c2 = c; break; case ')': - if (--numParen == 0) + if (--numParen == 0) { done = gTrue; + } else { + c2 = c; + } break; case '\\': diff --git a/pdftops/Lexer.h b/pdftops/Lexer.h index 70144b86bc..5edbeda6b1 100644 --- a/pdftops/Lexer.h +++ b/pdftops/Lexer.h @@ -16,6 +16,8 @@ #include "Object.h" #include "Stream.h" +class XRef; + #define tokBufSize 128 // size of token buffer //------------------------------------------------------------------------ @@ -27,11 +29,11 @@ public: // Construct a lexer for a single stream. Deletes the stream when // lexer is deleted. - Lexer(Stream *str); + Lexer(XRef *xref, Stream *str); // Construct a lexer for a stream or array of streams (assumes obj // is either a stream or array of streams). - Lexer(Object *obj); + Lexer(XRef *xref, Object *obj); // Destructor. ~Lexer(); diff --git a/pdftops/Link.cxx b/pdftops/Link.cxx index a53e0990b8..999c1f202f 100644 --- a/pdftops/Link.cxx +++ b/pdftops/Link.cxx @@ -28,11 +28,11 @@ static GString *getFileSpecName(Object *fileSpecObj); // LinkDest //------------------------------------------------------------------------ -LinkDest::LinkDest(Array *a, GBool pageIsRef1) { +LinkDest::LinkDest(Array *a, GBool pageIsRefA) { Object obj1, obj2; // initialize fields - pageIsRef = pageIsRef1; + pageIsRef = pageIsRefA; left = bottom = right = top = zoom = 0; ok = gFalse; @@ -384,8 +384,8 @@ LinkNamed::~LinkNamed() { // LinkUnknown //------------------------------------------------------------------------ -LinkUnknown::LinkUnknown(const char *action1) { - action = new GString(action1); +LinkUnknown::LinkUnknown(char *actionA) { + action = new GString(actionA); } LinkUnknown::~LinkUnknown() { @@ -447,11 +447,14 @@ Link::Link(Dict *dict, GString *baseURI) { // get border borderW = 0; if (!dict->lookup("Border", &obj1)->isNull()) { - if (obj1.isArray() && obj1.arrayGet(2, &obj2)->isNum()) - borderW = obj2.getNum(); - else - error(-1, "Bad annotation border"); - obj2.free(); + if (obj1.isArray() && obj1.arrayGetLength() >= 3) { + if (obj1.arrayGet(2, &obj2)->isNum()) { + borderW = obj2.getNum(); + } else { + error(-1, "Bad annotation border"); + } + obj2.free(); + } } obj1.free(); diff --git a/pdftops/Link.h b/pdftops/Link.h index a502763525..4d16724788 100644 --- a/pdftops/Link.h +++ b/pdftops/Link.h @@ -249,7 +249,7 @@ class LinkUnknown: public LinkAction { public: // Build a LinkUnknown with the specified action type. - LinkUnknown(const char *action1); + LinkUnknown(char *actionA); // Destructor. virtual ~LinkUnknown(); diff --git a/pdftops/Makefile b/pdftops/Makefile index 95c601ae41..abc87af72d 100644 --- a/pdftops/Makefile +++ b/pdftops/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.6 2001/03/02 22:34:16 andy Exp $" +# "$Id: Makefile,v 1.6.2.1 2001/12/26 16:52:45 mike Exp $" # # pdftops filter Makefile for the Common UNIX Printing System (CUPS). # @@ -16,7 +16,7 @@ include ../Makedefs LIBOBJS = Decrypt.o GString.o gfile.o gmempp.o gmem.o parseargs.o \ Array.o Catalog.o Dict.o Error.o FontEncoding.o \ - FontFile.o FormWidget.o Gfx.o GfxFont.o GfxState.o \ + FontFile.o FormWidget.o Function.o Gfx.o GfxFont.o GfxState.o \ Lexer.o Link.o Object.o OutputDev.o Page.o Params.o \ Parser.o PDFDoc.o PSOutputDev.o Stream.o XRef.o OBJS = pdftops.o $(LIBOBJS) @@ -43,10 +43,7 @@ clean: # install: - $(MKDIR) $(SERVERBIN)/filter - $(CHMOD) ugo+rx $(SERVERBIN) - $(CHMOD) ugo+rx $(SERVERBIN)/filter - $(RM) $(SERVERBIN)/filter/pdftops + $(INSTALL_DIR) $(SERVERBIN)/filter $(INSTALL_BIN) pdftops $(SERVERBIN)/filter @@ -89,6 +86,7 @@ FontEncoding.o: gmem.h FontEncoding.h gtypes.h FontFile.o: gmem.h Error.h config.h FontFile.h gtypes.h GString.h \ FontEncoding.h StdFontInfo.h CompactFontInfo.h FormWidget.o: FormWidget.h gmem.h Object.h Gfx.h +Function.o: gmem.h Object.h Dict.h Stream.h Error.h Function.h Gfx.o: gmem.h Object.h gtypes.h GString.h Array.h Dict.h Stream.h \ Lexer.h Parser.h GfxFont.h FontEncoding.h GfxState.h \ OutputDev.h Params.h Error.h config.h Gfx.h @@ -130,5 +128,5 @@ XRef.o: gmem.h Object.h gtypes.h GString.h Array.h Dict.h Stream.h \ $(OBJS): ../config.h ../Makedefs # -# End of "$Id: Makefile,v 1.6 2001/03/02 22:34:16 andy Exp $". +# End of "$Id: Makefile,v 1.6.2.1 2001/12/26 16:52:45 mike Exp $". # diff --git a/pdftops/Object.cxx b/pdftops/Object.cxx index b3ebe40f0e..ca671ea2cf 100644 --- a/pdftops/Object.cxx +++ b/pdftops/Object.cxx @@ -22,7 +22,7 @@ // Object //------------------------------------------------------------------------ -const char *objTypeNames[numObjTypes] = { +char *objTypeNames[numObjTypes] = { "boolean", "integer", "real", @@ -44,21 +44,21 @@ int Object::numAlloc[numObjTypes] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; #endif -Object *Object::initArray() { +Object *Object::initArray(XRef *xref) { initObj(objArray); - array = new Array(); + array = new Array(xref); return this; } -Object *Object::initDict() { +Object *Object::initDict(XRef *xref) { initObj(objDict); - dict = new Dict(); + dict = new Dict(xref); return this; } -Object *Object::initStream(Stream *stream1) { +Object *Object::initStream(Stream *streamA) { initObj(objStream); - stream = stream1; + stream = streamA; return this; } @@ -92,7 +92,7 @@ Object *Object::copy(Object *obj) { return obj; } -Object *Object::fetch(Object *obj) { +Object *Object::fetch(XRef *xref, Object *obj) { return (type == objRef && xref) ? xref->fetch(ref.num, ref.gen, obj) : copy(obj); } @@ -103,7 +103,7 @@ void Object::free() { delete string; break; case objName: - gfree((void *)name); + gfree(name); break; case objArray: if (!array->decRef()) { @@ -121,7 +121,7 @@ void Object::free() { } break; case objCmd: - gfree((void *)cmd); + gfree(cmd); break; default: break; @@ -132,7 +132,7 @@ void Object::free() { type = objNone; } -const char *Object::getTypeName() { +char *Object::getTypeName() { return objTypeNames[type]; } @@ -216,7 +216,5 @@ void Object::memCheck(FILE *f) { fprintf(f, " %-20s: %6d\n", objTypeNames[i], numAlloc[i]); } } -#else - (void)f; #endif } diff --git a/pdftops/Object.h b/pdftops/Object.h index d5132efa5a..49af586139 100644 --- a/pdftops/Object.h +++ b/pdftops/Object.h @@ -19,6 +19,7 @@ #include "gmem.h" #include "GString.h" +class XRef; class Array; class Dict; class Stream; @@ -78,27 +79,25 @@ public: type(objNone) {} // Initialize an object. - Object *initBool(GBool booln1) - { initObj(objBool); booln = booln1; return this; } - Object *initInt(int intg1) - { initObj(objInt); intg = intg1; return this; } - Object *initReal(double real1) - { initObj(objReal); real = real1; return this; } - Object *initString(GString *string1) - { initObj(objString); string = string1; return this; } - Object *initName(const char *name1) - { initObj(objName); name = copyString(name1); return this; } + Object *initBool(GBool boolnA) + { initObj(objBool); booln = boolnA; return this; } + Object *initInt(int intgA) + { initObj(objInt); intg = intgA; return this; } + Object *initReal(double realA) + { initObj(objReal); real = realA; return this; } + Object *initString(GString *stringA) + { initObj(objString); string = stringA; return this; } + Object *initName(char *nameA) + { initObj(objName); name = copyString(nameA); return this; } Object *initNull() { initObj(objNull); return this; } - Object *initArray(); - Object *initDict(); - Object *initDict(Dict *dict1) - { initObj(objDict); dict = dict1; return this; } - Object *initStream(Stream *stream1); - Object *initRef(int num1, int gen1) - { initObj(objRef); ref.num = num1; ref.gen = gen1; return this; } - Object *initCmd(const char *cmd1) - { initObj(objCmd); cmd = copyString(cmd1); return this; } + Object *initArray(XRef *xref); + Object *initDict(XRef *xref); + Object *initStream(Stream *streamA); + Object *initRef(int numA, int genA) + { initObj(objRef); ref.num = numA; ref.gen = genA; return this; } + Object *initCmd(char *cmdA) + { initObj(objCmd); cmd = copyString(cmdA); return this; } Object *initError() { initObj(objError); return this; } Object *initEOF() @@ -109,7 +108,7 @@ public: // If object is a Ref, fetch and return the referenced object. // Otherwise, return a copy of the object. - Object *fetch(Object *obj); + Object *fetch(XRef *xref, Object *obj); // Free object contents. void free(); @@ -133,12 +132,12 @@ public: GBool isNone() { return type == objNone; } // Special type checking. - GBool isName(const char *name1) - { return type == objName && !strcmp(name, name1); } - GBool isDict(const char *dictType); - GBool isStream(const char *dictType); - GBool isCmd(const char *cmd1) - { return type == objCmd && !strcmp(cmd, cmd1); } + GBool isName(char *nameA) + { return type == objName && !strcmp(name, nameA); } + GBool isDict(char *dictType); + GBool isStream(char *dictType); + GBool isCmd(char *cmdA) + { return type == objCmd && !strcmp(cmd, cmdA); } // Accessors. NB: these assume object is of correct type. GBool getBool() { return booln; } @@ -146,7 +145,7 @@ public: double getReal() { return real; } double getNum() { return type == objInt ? (double)intg : real; } GString *getString() { return string; } - const char *getName() { return name; } + char *getName() { return name; } Array *getArray() { return array; } Dict *getDict() { return dict; } Stream *getStream() { return stream; } @@ -162,16 +161,16 @@ public: // Dict accessors. int dictGetLength(); - void dictAdd(const char *key, Object *val); - GBool dictIs(const char *dictType); - Object *dictLookup(const char *key, Object *obj); - Object *dictLookupNF(const char *key, Object *obj); - const char *dictGetKey(int i); + void dictAdd(char *key, Object *val); + GBool dictIs(char *dictType); + Object *dictLookup(char *key, Object *obj); + Object *dictLookupNF(char *key, Object *obj); + char *dictGetKey(int i); Object *dictGetVal(int i, Object *obj); Object *dictGetValNF(int i, Object *obj); // Stream accessors. - GBool streamIs(const char *dictType); + GBool streamIs(char *dictType); void streamReset(); void streamClose(); int streamGetChar(); @@ -182,7 +181,7 @@ public: Dict *streamGetDict(); // Output. - const char *getTypeName(); + char *getTypeName(); void print(FILE *f = stdout); // Memory testing. @@ -196,12 +195,12 @@ private: int intg; // integer double real; // real GString *string; // string - const char *name; // name + char *name; // name Array *array; // array Dict *dict; // dictionary Stream *stream; // stream Ref ref; // indirect reference - const char *cmd; // command + char *cmd; // command }; #ifdef DEBUG_MEM @@ -237,22 +236,22 @@ inline Object *Object::arrayGetNF(int i, Object *obj) inline int Object::dictGetLength() { return dict->getLength(); } -inline void Object::dictAdd(const char *key, Object *val) +inline void Object::dictAdd(char *key, Object *val) { dict->add(key, val); } -inline GBool Object::dictIs(const char *dictType) +inline GBool Object::dictIs(char *dictType) { return dict->is(dictType); } -inline GBool Object::isDict(const char *dictType) +inline GBool Object::isDict(char *dictType) { return type == objDict && dictIs(dictType); } -inline Object *Object::dictLookup(const char *key, Object *obj) +inline Object *Object::dictLookup(char *key, Object *obj) { return dict->lookup(key, obj); } -inline Object *Object::dictLookupNF(const char *key, Object *obj) +inline Object *Object::dictLookupNF(char *key, Object *obj) { return dict->lookupNF(key, obj); } -inline const char *Object::dictGetKey(int i) +inline char *Object::dictGetKey(int i) { return dict->getKey(i); } inline Object *Object::dictGetVal(int i, Object *obj) @@ -267,10 +266,10 @@ inline Object *Object::dictGetValNF(int i, Object *obj) #include "Stream.h" -inline GBool Object::streamIs(const char *dictType) +inline GBool Object::streamIs(char *dictType) { return stream->getDict()->is(dictType); } -inline GBool Object::isStream(const char *dictType) +inline GBool Object::isStream(char *dictType) { return type == objStream && streamIs(dictType); } inline void Object::streamReset() diff --git a/pdftops/OutputDev.cxx b/pdftops/OutputDev.cxx index b90636116b..014b2aef65 100644 --- a/pdftops/OutputDev.cxx +++ b/pdftops/OutputDev.cxx @@ -20,29 +20,30 @@ // OutputDev //------------------------------------------------------------------------ -void OutputDev::setDefaultCTM(double *ctm1) { +void OutputDev::setDefaultCTM(double *ctm) { int i; double det; - for (i = 0; i < 6; ++i) - ctm[i] = ctm1[i]; - det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]); - ictm[0] = ctm[3] * det; - ictm[1] = -ctm[1] * det; - ictm[2] = -ctm[2] * det; - ictm[3] = ctm[0] * det; - ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det; - ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det; + for (i = 0; i < 6; ++i) { + defCTM[i] = ctm[i]; + } + det = 1 / (defCTM[0] * defCTM[3] - defCTM[1] * defCTM[2]); + defICTM[0] = defCTM[3] * det; + defICTM[1] = -defCTM[1] * det; + defICTM[2] = -defCTM[2] * det; + defICTM[3] = defCTM[0] * det; + defICTM[4] = (defCTM[2] * defCTM[5] - defCTM[3] * defCTM[4]) * det; + defICTM[5] = (defCTM[1] * defCTM[4] - defCTM[0] * defCTM[5]) * det; } void OutputDev::cvtDevToUser(int dx, int dy, double *ux, double *uy) { - *ux = ictm[0] * dx + ictm[2] * dy + ictm[4]; - *uy = ictm[1] * dx + ictm[3] * dy + ictm[5]; + *ux = defICTM[0] * dx + defICTM[2] * dy + defICTM[4]; + *uy = defICTM[1] * dx + defICTM[3] * dy + defICTM[5]; } void OutputDev::cvtUserToDev(double ux, double uy, int *dx, int *dy) { - *dx = (int)(ctm[0] * ux + ctm[2] * uy + ctm[4] + 0.5); - *dy = (int)(ctm[1] * ux + ctm[3] * uy + ctm[5] + 0.5); + *dx = (int)(defCTM[0] * ux + defCTM[2] * uy + defCTM[4] + 0.5); + *dy = (int)(defCTM[1] * ux + defCTM[3] * uy + defCTM[5] + 0.5); } void OutputDev::updateAll(GfxState *state) { @@ -62,9 +63,6 @@ void OutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, GBool inlineImg) { int i, j; - (void)state; - (void)invert; - if (inlineImg) { str->reset(); j = height * ((width + 7) / 8); @@ -75,11 +73,9 @@ void OutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, void OutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, - GBool inlineImg) { + int *maskColors, GBool inlineImg) { int i, j; - (void)state; - if (inlineImg) { str->reset(); j = height * ((width * colorMap->getNumPixelComps() * diff --git a/pdftops/OutputDev.h b/pdftops/OutputDev.h index 7128183fae..c332fa933f 100644 --- a/pdftops/OutputDev.h +++ b/pdftops/OutputDev.h @@ -48,10 +48,10 @@ public: //----- initialization and control // Set default transform matrix. - virtual void setDefaultCTM(double *ctm1); + virtual void setDefaultCTM(double *ctm); // Start a page. - virtual void startPage(int, GfxState *) {} + virtual void startPage(int pageNum, GfxState *state) {} // End a page. virtual void endPage() {} @@ -66,56 +66,56 @@ public: virtual void cvtUserToDev(double ux, double uy, int *dx, int *dy); //----- link borders - virtual void drawLink(Link *, Catalog *) {} + virtual void drawLink(Link *link, Catalog *catalog) {} //----- save/restore graphics state - virtual void saveState(GfxState *) {} - virtual void restoreState(GfxState *) {} + virtual void saveState(GfxState *state) {} + virtual void restoreState(GfxState *state) {} //----- update graphics state virtual void updateAll(GfxState *state); - virtual void updateCTM(GfxState *, double, double, - double, double, double, double) {} - virtual void updateLineDash(GfxState *) {} - virtual void updateFlatness(GfxState *) {} - virtual void updateLineJoin(GfxState *) {} - virtual void updateLineCap(GfxState *) {} - virtual void updateMiterLimit(GfxState *) {} - virtual void updateLineWidth(GfxState *) {} - virtual void updateFillColor(GfxState *) {} - virtual void updateStrokeColor(GfxState *) {} - virtual void updateFillOpacity(GfxState *) {} - virtual void updateStrokeOpacity(GfxState *) {} - - //----- update text - virtual void updateFont(GfxState *) {} - virtual void updateTextMat(GfxState *) {} - virtual void updateCharSpace(GfxState *) {} - virtual void updateRender(GfxState *) {} - virtual void updateRise(GfxState *) {} - virtual void updateWordSpace(GfxState *) {} - virtual void updateHorizScaling(GfxState *) {} - virtual void updateTextPos(GfxState *) {} - virtual void updateTextShift(GfxState *, double) {} + virtual void updateCTM(GfxState *state, double m11, double m12, + double m21, double m22, double m31, double m32) {} + virtual void updateLineDash(GfxState *state) {} + virtual void updateFlatness(GfxState *state) {} + virtual void updateLineJoin(GfxState *state) {} + virtual void updateLineCap(GfxState *state) {} + virtual void updateMiterLimit(GfxState *state) {} + virtual void updateLineWidth(GfxState *state) {} + virtual void updateFillColor(GfxState *state) {} + virtual void updateStrokeColor(GfxState *state) {} + virtual void updateFillOpacity(GfxState *state) {} + virtual void updateStrokeOpacity(GfxState *state) {} + + //----- update text state + virtual void updateFont(GfxState *state) {} + virtual void updateTextMat(GfxState *state) {} + virtual void updateCharSpace(GfxState *state) {} + virtual void updateRender(GfxState *state) {} + virtual void updateRise(GfxState *state) {} + virtual void updateWordSpace(GfxState *state) {} + virtual void updateHorizScaling(GfxState *state) {} + virtual void updateTextPos(GfxState *state) {} + virtual void updateTextShift(GfxState *state, double shift) {} //----- path painting - virtual void stroke(GfxState *) {} - virtual void fill(GfxState *) {} - virtual void eoFill(GfxState *) {} + virtual void stroke(GfxState *state) {} + virtual void fill(GfxState *state) {} + virtual void eoFill(GfxState *state) {} //----- path clipping - virtual void clip(GfxState *) {} - virtual void eoClip(GfxState *) {} + virtual void clip(GfxState *state) {} + virtual void eoClip(GfxState *state) {} //----- text drawing - virtual void beginString(GfxState *, GString *) {} - virtual void endString(GfxState *) {} - virtual void drawChar(GfxState *, double, double, - double, double, Guchar) {} - virtual void drawChar16(GfxState *, double, double, - double, double, int) {} - virtual void drawString(GfxState *, GString *) {} - virtual void drawString16(GfxState *, GString *) {} + virtual void beginString(GfxState *state, GString *s) {} + virtual void endString(GfxState *state) {} + virtual void drawChar(GfxState *state, double x, double y, + double dx, double dy, Guchar c) {} + virtual void drawChar16(GfxState *state, double x, double y, + double dx, double dy, int c) {} + virtual void drawString(GfxState *state, GString *s) {} + virtual void drawString16(GfxState *state, GString *s) {} //----- image drawing virtual void drawImageMask(GfxState *state, Object *ref, Stream *str, @@ -123,7 +123,7 @@ public: GBool inlineImg); virtual void drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, - GBool inlineImg); + int *maskColors, GBool inlineImg); #if OPI_SUPPORT //----- OPI functions @@ -133,8 +133,8 @@ public: private: - double ctm[6]; // coordinate transform matrix - double ictm[6]; // inverse CTM + double defCTM[6]; // default coordinate transform matrix + double defICTM[6]; // inverse of default CTM }; #endif diff --git a/pdftops/PDFDoc.cxx b/pdftops/PDFDoc.cxx index b10410e540..ae04280543 100644 --- a/pdftops/PDFDoc.cxx +++ b/pdftops/PDFDoc.cxx @@ -37,7 +37,8 @@ // PDFDoc //------------------------------------------------------------------------ -PDFDoc::PDFDoc(GString *fileName1, GString *userPassword) { +PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword, + GString *userPassword, GBool printCommandsA) { Object obj; GString *fileName2; @@ -48,9 +49,10 @@ PDFDoc::PDFDoc(GString *fileName1, GString *userPassword) { xref = NULL; catalog = NULL; links = NULL; + printCommands = printCommandsA; // try to open file - fileName = fileName1; + fileName = fileNameA; fileName2 = NULL; #ifdef VMS if (!(file = fopen(fileName->getCString(), "rb", "ctx=stm"))) { @@ -77,36 +79,35 @@ PDFDoc::PDFDoc(GString *fileName1, GString *userPassword) { obj.initNull(); str = new FileStream(file, 0, -1, &obj); - ok = setup(userPassword); + ok = setup(ownerPassword, userPassword); } -PDFDoc::PDFDoc(BaseStream *nstr, GString *userPassword) { +PDFDoc::PDFDoc(BaseStream *strA, GString *ownerPassword, + GString *userPassword, GBool printCommandsA) { ok = gFalse; fileName = NULL; file = NULL; - str = nstr; + str = strA; xref = NULL; catalog = NULL; links = NULL; - ok = setup(userPassword); + printCommands = printCommandsA; + ok = setup(ownerPassword, userPassword); } -GBool PDFDoc::setup(GString *userPassword) { - Object catObj; - +GBool PDFDoc::setup(GString *ownerPassword, GString *userPassword) { // check header checkHeader(); // read xref table - xref = new XRef(str, userPassword); + xref = new XRef(str, ownerPassword, userPassword); if (!xref->isOk()) { error(-1, "Couldn't read xref table"); return gFalse; } // read catalog - catalog = new Catalog(xref->getCatalog(&catObj)); - catObj.free(); + catalog = new Catalog(xref, printCommands); if (!catalog->isOk()) { error(-1, "Couldn't read page catalog"); return gFalse; @@ -203,8 +204,8 @@ GBool PDFDoc::isLinearized() { lin = gFalse; obj1.initNull(); - parser = new Parser(new Lexer(str->makeSubStream(str->getStart(), - -1, &obj1))); + parser = new Parser(xref, new Lexer(xref, str->makeSubStream(str->getStart(), + -1, &obj1))); parser->getObj(&obj1); parser->getObj(&obj2); parser->getObj(&obj3); @@ -248,4 +249,3 @@ void PDFDoc::getLinks(Page *page) { links = new Links(page->getAnnots(&obj), catalog->getBaseURI()); obj.free(); } - diff --git a/pdftops/PDFDoc.h b/pdftops/PDFDoc.h index e679db9795..c693e991a1 100644 --- a/pdftops/PDFDoc.h +++ b/pdftops/PDFDoc.h @@ -14,13 +14,13 @@ #endif #include +#include "XRef.h" #include "Link.h" #include "Catalog.h" #include "Page.h" class GString; class BaseStream; -class XRef; class OutputDev; class Links; class LinkAction; @@ -33,8 +33,10 @@ class LinkDest; class PDFDoc { public: - PDFDoc(GString *fileName1, GString *userPassword = NULL); - PDFDoc(BaseStream *str, GString *userPassword = NULL); + PDFDoc(GString *fileNameA, GString *ownerPassword = NULL, + GString *userPassword = NULL, GBool printCommandsA = gFalse); + PDFDoc(BaseStream *strA, GString *ownerPassword = NULL, + GString *userPassword = NULL, GBool printCommandsA = gFalse); ~PDFDoc(); // Was PDF document successfully opened? @@ -43,6 +45,9 @@ public: // Get file name. GString *getFileName() { return fileName; } + // Get the xref table. + XRef *getXRef() { return xref; } + // Get catalog. Catalog *getCatalog() { return catalog; } @@ -88,10 +93,14 @@ public: GBool isEncrypted() { return xref->isEncrypted(); } // Check various permissions. - GBool okToPrint() { return xref->okToPrint(); } - GBool okToChange() { return xref->okToChange(); } - GBool okToCopy() { return xref->okToCopy(); } - GBool okToAddNotes() { return xref->okToAddNotes(); } + GBool okToPrint(GBool ignoreOwnerPW = gFalse) + { return xref->okToPrint(ignoreOwnerPW); } + GBool okToChange(GBool ignoreOwnerPW = gFalse) + { return xref->okToChange(ignoreOwnerPW); } + GBool okToCopy(GBool ignoreOwnerPW = gFalse) + { return xref->okToCopy(ignoreOwnerPW); } + GBool okToAddNotes(GBool ignoreOwnerPW = gFalse) + { return xref->okToAddNotes(ignoreOwnerPW); } // Is this document linearized? GBool isLinearized(); @@ -107,7 +116,7 @@ public: private: - GBool setup(GString *userPassword); + GBool setup(GString *ownerPassword, GString *userPassword); void checkHeader(); void getLinks(Page *page); @@ -118,6 +127,7 @@ private: XRef *xref; Catalog *catalog; Links *links; + GBool printCommands; GBool ok; }; diff --git a/pdftops/PSOutputDev.cxx b/pdftops/PSOutputDev.cxx index 84e8ca7c72..b62a23d24b 100644 --- a/pdftops/PSOutputDev.cxx +++ b/pdftops/PSOutputDev.cxx @@ -11,7 +11,6 @@ #endif #include -#include #include #include #include @@ -20,6 +19,7 @@ #include "config.h" #include "Object.h" #include "Error.h" +#include "Function.h" #include "GfxState.h" #include "GfxFont.h" #include "FontFile.h" @@ -38,32 +38,11 @@ #include "ICSupport.h" #endif -//------------------------------------------------------------------------ -// Parameters -//------------------------------------------------------------------------ - -// Generate Level 1 PostScript? -GBool psOutLevel1 = gFalse; - -// Generate Level 1 separable PostScript? -GBool psOutLevel1Sep = gFalse; - -// Generate Encapsulated PostScript? -GBool psOutEPS = gFalse; - -#if OPI_SUPPORT -// Generate OPI comments? -GBool psOutOPI = gFalse; -#endif - -int paperWidth = defPaperWidth; -int paperHeight = defPaperHeight; - //------------------------------------------------------------------------ // PostScript prolog and setup //------------------------------------------------------------------------ -static const char *prolog[] = { +static char *prolog[] = { "/xpdf 75 dict def xpdf begin", "% PDF special state", "/pdfDictSize 14 def", @@ -94,19 +73,83 @@ static const char *prolog[] = { " /pdfHorizScaling 1 def", "} def", "/pdfEndPage { end } def", + "% separation convention operators", + "/findcmykcustomcolor where {", + " pop", + "}{", + " /findcmykcustomcolor { 5 array astore } def", + "} ifelse", + "/setcustomcolor where {", + " pop", + "}{", + " /setcustomcolor {", + " exch", + " [ exch /Separation exch dup 4 get exch /DeviceCMYK exch", + " 0 4 getinterval cvx", + " [ exch /dup load exch { mul exch dup } /forall load", + " /pop load dup ] cvx", + " ] setcolorspace setcolor", + " } def", + "} ifelse", + "/customcolorimage where {", + " pop", + "}{", + " /customcolorimage {", + " gsave", + " [ exch /Separation exch dup 4 get exch /DeviceCMYK exch", + " 0 4 getinterval cvx", + " [ exch /dup load exch { mul exch dup } /forall load", + " /pop load dup ] cvx", + " ] setcolorspace", + " 10 dict begin", + " /ImageType 1 def", + " /DataSource exch def", + " /ImageMatrix exch def", + " /BitsPerComponent exch def", + " /Height exch def", + " /Width exch def", + " /Decode [1 0] def", + " currentdict end", + " image", + " grestore", + " } def", + "} ifelse", + "% PDF color state", "/sCol {", " pdfLastStroke not {", " pdfStroke aload length", - " dup 1 eq { pop setgray }", - " { 3 eq { setrgbcolor } { setcmykcolor } ifelse } ifelse", + " dup 1 eq {", + " pop setgray", + " }{", + " dup 3 eq {", + " pop setrgbcolor", + " }{", + " 4 eq {", + " setcmykcolor", + " }{", + " findcmykcustomcolor exch setcustomcolor", + " } ifelse", + " } ifelse", + " } ifelse", " /pdfLastStroke true def /pdfLastFill false def", " } if", "} def", "/fCol {", " pdfLastFill not {", " pdfFill aload length", - " dup 1 eq { pop setgray }", - " { 3 eq { setrgbcolor } { setcmykcolor } ifelse } ifelse", + " dup 1 eq {", + " pop setgray", + " }{", + " dup 3 eq {", + " pop setrgbcolor", + " }{", + " 4 eq {", + " setcmykcolor", + " }{", + " findcmykcustomcolor exch setcustomcolor", + " } ifelse", + " } ifelse", + " } ifelse", " /pdfLastFill true def /pdfLastStroke false def", " } if", "} def", @@ -145,6 +188,12 @@ static const char *prolog[] = { " /pdfLastFill true def /pdfLastStroke false def } def", "/K { 4 copy 4 array astore /pdfStroke exch def setcmykcolor", " /pdfLastStroke true def /pdfLastFill false def } def", + "/ck { 6 copy 6 array astore /pdfFill exch def", + " findcmykcustomcolor exch setcustomcolor", + " /pdfLastFill true def /pdfLastStroke false def } def", + "/CK { 6 copy 6 array astore /pdfStroke exch def", + " findcmykcustomcolor exch setcustomcolor", + " /pdfLastStroke true def /pdfLastFill false def } def", "% path segment operators", "/m { moveto } def", "/l { lineto } def", @@ -178,13 +227,10 @@ static const char *prolog[] = { " pdfFontSize mul pdfHorizScaling mul", " 1 index stringwidth pdfTextMat idtransform pop", " sub 1 index length dup 0 ne { div } { pop pop 0 } ifelse", - " pdfWordSpacing 0 pdfTextMat dtransform 32", - " 4 3 roll pdfCharSpacing add 0 pdfTextMat dtransform", -#if 0 /* temporary fix until we can figure out why the width is wrong */ + " pdfWordSpacing pdfHorizScaling mul 0 pdfTextMat dtransform 32", + " 4 3 roll pdfCharSpacing pdfHorizScaling mul add 0", + " pdfTextMat dtransform", " 6 5 roll awidthshow", -#else - " 6 5 roll show pop pop pop pop pop", -#endif /* 0 */ " 0 pdfTextRise neg pdfTextMat dtransform rmoveto } def", "/TJm { pdfFontSize 0.001 mul mul neg 0", " pdfTextMat dtransform rmoveto } def", @@ -216,6 +262,20 @@ static const char *prolog[] = { " not { pop exit } if", " (%-EOD-) eq { exit } if } loop", "} def", + "/pdfImSep {", + " findcmykcustomcolor exch", + " dup /Width get /pdfImBuf1 exch string def", + " begin Width Height BitsPerComponent ImageMatrix DataSource end", + " /pdfImData exch def", + " { pdfImData pdfImBuf1 readstring pop", + " 0 1 2 index length 1 sub {", + " 1 index exch 2 copy get 255 exch sub put", + " } for }", + " 6 5 roll customcolorimage", + " { currentfile pdfImBuf readline", + " not { pop exit } if", + " (%-EOD-) eq { exit } if } loop", + "} def", "/pdfImM {", " fCol imagemask", " { currentfile pdfImBuf readline", @@ -231,19 +291,19 @@ static const char *prolog[] = { //------------------------------------------------------------------------ struct PSFont { - const char *name; // PDF name - const char *psName; // PostScript name + char *name; // PDF name + char *psName; // PostScript name }; struct PSSubstFont { - const char *psName; // PostScript name + char *psName; // PostScript name double mWidth; // width of 'm' character }; static PSFont psFonts[] = { {"Courier", "Courier"}, {"Courier-Bold", "Courier-Bold"}, - {"Courier-Oblique", "Courier-Bold"}, + {"Courier-Oblique", "Courier-Oblique"}, {"Courier-BoldOblique", "Courier-BoldOblique"}, {"Helvetica", "Helvetica"}, {"Helvetica-Bold", "Helvetica-Bold"}, @@ -273,31 +333,87 @@ static PSSubstFont psSubstFonts[] = { {"Courier-BoldOblique", 0.600} }; +//------------------------------------------------------------------------ +// process colors +//------------------------------------------------------------------------ + +#define psProcessCyan 1 +#define psProcessMagenta 2 +#define psProcessYellow 4 +#define psProcessBlack 8 +#define psProcessCMYK 15 + +//------------------------------------------------------------------------ +// PSOutCustomColor +//------------------------------------------------------------------------ + +class PSOutCustomColor { +public: + + PSOutCustomColor(double cA, double mA, + double yA, double kA, GString *nameA); + ~PSOutCustomColor(); + + double c, m, y, k; + GString *name; + PSOutCustomColor *next; +}; + +PSOutCustomColor::PSOutCustomColor(double cA, double mA, + double yA, double kA, GString *nameA) { + c = cA; + m = mA; + y = yA; + k = kA; + name = nameA; + next = NULL; +} + +PSOutCustomColor::~PSOutCustomColor() { + delete name; +} + //------------------------------------------------------------------------ // PSOutputDev //------------------------------------------------------------------------ -PSOutputDev::PSOutputDev(const char *fileName, Catalog *catalog, +extern "C" { +typedef void (*SignalFunc)(int); +} + +PSOutputDev::PSOutputDev(char *fileName, XRef *xrefA, Catalog *catalog, int firstPage, int lastPage, - GBool embedType11, GBool doForm1) { + PSOutLevel levelA, PSOutMode modeA, GBool doOPIA, + GBool embedType1A, GBool embedTrueTypeA, + int paperWidthA, int paperHeightA) { Page *page; + PDFRectangle *box; Dict *resDict; FormWidgets *formWidgets; - const char **p; + char **p; int pg; Object obj1, obj2; int i; // initialize - embedType1 = embedType11; - doForm = doForm1; + xref = xrefA; + level = levelA; + mode = modeA; + doOPI = doOPIA; + embedType1 = embedType1A; + embedTrueType = embedTrueTypeA; + paperWidth = paperWidthA; + paperHeight = paperHeightA; fontIDs = NULL; fontFileIDs = NULL; fontFileNames = NULL; embFontList = NULL; f = NULL; - if (doForm) + if (mode == psModeForm) { lastPage = firstPage; + } + processColors = 0; + customColors = NULL; // open file or pipe ok = gTrue; @@ -308,7 +424,7 @@ PSOutputDev::PSOutputDev(const char *fileName, Catalog *catalog, fileType = psPipe; #ifdef HAVE_POPEN #ifndef WIN32 - signal(SIGPIPE, SIG_IGN); + signal(SIGPIPE, (SignalFunc)SIG_IGN); #endif if (!(f = popen(fileName + 1, "w"))) { error(-1, "Couldn't run print command '%s'", fileName); @@ -344,63 +460,70 @@ PSOutputDev::PSOutputDev(const char *fileName, Catalog *catalog, embFontList = new GString(); // write header - if (doForm) { - writePS("%%!PS-Adobe-3.0 Resource-Form\n"); + switch (mode) { + case psModePS: + writePS("%%!PS-Adobe-3.0\n"); writePS("%%%%Creator: xpdf/pdftops %s\n", xpdfVersion); writePS("%%%%LanguageLevel: %d\n", - (psOutLevel1 || psOutLevel1Sep) ? 1 : 2); - if (psOutLevel1Sep) { - writePS("%%%%DocumentProcessColors: Cyan Magenta Yellow Black\n"); + (level == psLevel1 || level == psLevel1Sep) ? 1 : 2); + if (level == psLevel1Sep || level == psLevel2Sep) { + writePS("%%%%DocumentProcessColors: (atend)\n"); + writePS("%%%%DocumentCustomColors: (atend)\n"); } + writePS("%%%%DocumentMedia: plain %d %d 0 () ()\n", + paperWidth, paperHeight); + writePS("%%%%Pages: %d\n", lastPage - firstPage + 1); writePS("%%%%EndComments\n"); - page = catalog->getPage(firstPage); - writePS("32 dict dup begin\n"); - writePS("/BBox [%d %d %d %d] def\n", - (int)page->getX1(), (int)page->getY1(), - (int)page->getX2(), (int)page->getY2()); - writePS("/FormType 1 def\n"); - writePS("/Matrix [1 0 0 1 0 0] def\n"); - } else if (psOutEPS) { + writePS("%%%%BeginDefaults\n"); + writePS("%%%%PageMedia: plain\n"); + writePS("%%%%EndDefaults\n"); + break; + case psModeEPS: writePS("%%!PS-Adobe-3.0 EPSF-3.0\n"); writePS("%%%%Creator: xpdf/pdftops %s\n", xpdfVersion); writePS("%%%%LanguageLevel: %d\n", - (psOutLevel1 || psOutLevel1Sep) ? 1 : 2); - if (psOutLevel1Sep) { - writePS("%%%%DocumentProcessColors: Cyan Magenta Yellow Black\n"); + (level == psLevel1 || level == psLevel1Sep) ? 1 : 2); + if (level == psLevel1Sep || level == psLevel2Sep) { + writePS("%%%%DocumentProcessColors: (atend)\n"); + writePS("%%%%DocumentCustomColors: (atend)\n"); } page = catalog->getPage(firstPage); + box = page->getBox(); writePS("%%%%BoundingBox: %d %d %d %d\n", - (int)floor(page->getX1()), (int)floor(page->getY1()), - (int)ceil(page->getX2()), (int)ceil(page->getY2())); - if (floor(page->getX1()) != ceil(page->getX1()) || - floor(page->getY1()) != ceil(page->getY1()) || - floor(page->getX2()) != ceil(page->getX2()) || - floor(page->getY2()) != ceil(page->getY2())) { + (int)floor(box->x1), (int)floor(box->y1), + (int)ceil(box->x2), (int)ceil(box->y2)); + if (floor(box->x1) != ceil(box->x1) || + floor(box->y1) != ceil(box->y1) || + floor(box->x2) != ceil(box->x2) || + floor(box->y2) != ceil(box->y2)) { writePS("%%%%HiResBoundingBox: %g %g %g %g\n", - page->getX1(), page->getY1(), - page->getX2(), page->getY2()); + box->x1, box->y1, box->x2, box->y2); } writePS("%%%%DocumentSuppliedResources: (atend)\n"); writePS("%%%%EndComments\n"); - } else { - writePS("%%!PS-Adobe-3.0\n"); + break; + case psModeForm: + writePS("%%!PS-Adobe-3.0 Resource-Form\n"); writePS("%%%%Creator: xpdf/pdftops %s\n", xpdfVersion); writePS("%%%%LanguageLevel: %d\n", - (psOutLevel1 || psOutLevel1Sep) ? 1 : 2); - if (psOutLevel1Sep) { - writePS("%%%%DocumentProcessColors: Cyan Magenta Yellow Black\n"); + (level == psLevel1 || level == psLevel1Sep) ? 1 : 2); + if (level == psLevel1Sep || level == psLevel2Sep) { + writePS("%%%%DocumentProcessColors: (atend)\n"); + writePS("%%%%DocumentCustomColors: (atend)\n"); } - writePS("%%%%DocumentMedia: plain %d %d 0 () ()\n", - paperWidth, paperHeight); - writePS("%%%%Pages: %d\n", lastPage - firstPage + 1); writePS("%%%%EndComments\n"); - writePS("%%%%BeginDefaults\n"); - writePS("%%%%PageMedia: plain\n"); - writePS("%%%%EndDefaults\n"); + page = catalog->getPage(firstPage); + box = page->getBox(); + writePS("32 dict dup begin\n"); + writePS("/BBox [%d %d %d %d] def\n", + (int)box->x1, (int)box->y1, (int)box->x2, (int)box->y2); + writePS("/FormType 1 def\n"); + writePS("/Matrix [1 0 0 1 0 0] def\n"); + break; } // write prolog - if (!doForm) { + if (mode != psModeForm) { writePS("%%%%BeginProlog\n"); } writePS("%%%%BeginResource: procset xpdf %s 0\n", xpdfVersion); @@ -408,13 +531,13 @@ PSOutputDev::PSOutputDev(const char *fileName, Catalog *catalog, writePS("%s\n", *p); } writePS("%%%%EndResource\n"); - if (!doForm) { + if (mode != psModeForm) { writePS("%%%%EndProlog\n"); } // set up fonts and images type3Warning = gFalse; - if (doForm) { + if (mode == psModeForm) { // swap the form and xpdf dicts writePS("xpdf end begin dup begin\n"); } else { @@ -426,7 +549,7 @@ PSOutputDev::PSOutputDev(const char *fileName, Catalog *catalog, if ((resDict = page->getResourceDict())) { setupResources(resDict); } - formWidgets = new FormWidgets(page->getAnnots(&obj1)); + formWidgets = new FormWidgets(xref, page->getAnnots(&obj1)); obj1.free(); for (i = 0; i < formWidgets->getNumWidgets(); ++i) { if (formWidgets->getWidget(i)->getAppearance(&obj1)->isStream()) { @@ -440,17 +563,14 @@ PSOutputDev::PSOutputDev(const char *fileName, Catalog *catalog, } delete formWidgets; } - if (!doForm) { + if (mode != psModeForm) { #if OPI_SUPPORT - if (psOutOPI) { + if (doOPI) { writePS("/opiMatrix matrix currentmatrix def\n"); } #endif - if (!psOutEPS) { - if (!getenv("PPD") || !getenv("SOFTWARE")) { - // pdfSetup not used for CUPS filter... - writePS("%d %d pdfSetup\n", paperWidth, paperHeight); - } + if (mode != psModeEPS) { + writePS("%d %d pdfSetup\n", paperWidth, paperHeight); } writePS("%%%%EndSetup\n"); } @@ -466,20 +586,43 @@ PSOutputDev::PSOutputDev(const char *fileName, Catalog *catalog, } PSOutputDev::~PSOutputDev() { + PSOutCustomColor *cc; int i; if (f) { - if (doForm) { + if (mode == psModeForm) { writePS("/Foo exch /Form defineresource pop\n"); - } else if (psOutEPS) { + } else { writePS("%%%%Trailer\n"); writePS("end\n"); writePS("%%%%DocumentSuppliedResources:\n"); writePS("%s", embFontList->getCString()); - writePS("%%%%EOF\n"); - } else { - writePS("%%%%Trailer\n"); - writePS("end\n"); + if (level == psLevel1Sep || level == psLevel2Sep) { + writePS("%%%%DocumentProcessColors:"); + if (processColors & psProcessCyan) { + writePS(" Cyan"); + } + if (processColors & psProcessMagenta) { + writePS(" Magenta"); + } + if (processColors & psProcessYellow) { + writePS(" Yellow"); + } + if (processColors & psProcessBlack) { + writePS(" Black"); + } + writePS("\n"); + writePS("%%%%DocumentCustomColors:"); + for (cc = customColors; cc; cc = cc->next) { + writePS(" (%s)", cc->name->getCString()); + } + writePS("\n"); + writePS("%%%%CMYKCustomColor:\n"); + for (cc = customColors; cc; cc = cc->next) { + writePS("%%%%+ %g %g %g %g (%s)\n", + cc->c, cc->m, cc->y, cc->k, cc->name->getCString()); + } + } writePS("%%%%EOF\n"); } if (fileType == psFile) { @@ -492,7 +635,7 @@ PSOutputDev::~PSOutputDev() { else if (fileType == psPipe) { pclose(f); #ifndef WIN32 - signal(SIGPIPE, SIG_DFL); + signal(SIGPIPE, (SignalFunc)SIG_DFL); #endif } #endif @@ -512,6 +655,11 @@ PSOutputDev::~PSOutputDev() { } gfree(fontFileNames); } + while (customColors) { + cc = customColors; + customColors = cc->next; + delete cc; + } } void PSOutputDev::setupResources(Dict *resDict) { @@ -546,7 +694,7 @@ void PSOutputDev::setupFonts(Dict *resDict) { resDict->lookup("Font", &fontDict); if (fontDict.isDict()) { - gfxFontDict = new GfxFontDict(fontDict.getDict()); + gfxFontDict = new GfxFontDict(xref, fontDict.getDict()); for (i = 0; i < gfxFontDict->getNumFonts(); ++i) { font = gfxFontDict->getFont(i); setupFont(font); @@ -559,8 +707,8 @@ void PSOutputDev::setupFonts(Dict *resDict) { void PSOutputDev::setupFont(GfxFont *font) { Ref fontFileID; GString *name; - const char *psName; - const char *charName; + char *psName; + char *charName; double xs, ys; GBool do16Bit; int code; @@ -604,6 +752,13 @@ void PSOutputDev::setupFont(GfxFont *font) { psName = font->getEmbeddedFontName(); setupEmbeddedType1CFont(font, &fontFileID, psName); + // check for embedded TrueType font + } else if (embedTrueType && font->getType() == fontTrueType && + font->getEmbeddedFontID(&fontFileID)) { + psName = font->getEmbeddedFontName(); + setupEmbeddedTrueTypeFont(font, &fontFileID, psName); + + // check for Japanese font } else if (font->is16Bit() && font->getCharSet16() == font16AdobeJapan12) { psName = "Ryumin-Light-RKSJ"; do16Bit = gTrue; @@ -673,6 +828,11 @@ void PSOutputDev::setupFont(GfxFont *font) { writePS((i == 0) ? "[ " : " "); for (j = 0; j < 8; ++j) { charName = font->getCharName(i+j); + // this is a kludge for broken PDF files that encode char 32 + // as .notdef + if (i+j == 32 && charName && !strcmp(charName, ".notdef")) { + charName = "space"; + } writePS("/%s", charName ? charName : ".notdef"); } writePS((i == 256-8) ? "]\n" : "\n"); @@ -681,7 +841,7 @@ void PSOutputDev::setupFont(GfxFont *font) { } } -void PSOutputDev::setupEmbeddedType1Font(Ref *id, const char *psName) { +void PSOutputDev::setupEmbeddedType1Font(Ref *id, char *psName) { static char hexChar[17] = "0123456789abcdef"; Object refObj, strObj, obj1, obj2; Dict *dict; @@ -707,7 +867,7 @@ void PSOutputDev::setupEmbeddedType1Font(Ref *id, const char *psName) { // get the font stream and info refObj.initRef(id->num, id->gen); - refObj.fetch(&strObj); + refObj.fetch(xref, &strObj); refObj.free(); if (!strObj.isStream()) { error(-1, "Embedded font file object is not a stream"); @@ -731,12 +891,10 @@ void PSOutputDev::setupEmbeddedType1Font(Ref *id, const char *psName) { obj2.free(); // beginning comment - if (psOutEPS) { - writePS("%%%%BeginResource: font %s\n", psName); - embFontList->append("%%+ font "); - embFontList->append(psName); - embFontList->append("\n"); - } + writePS("%%%%BeginResource: font %s\n", psName); + embFontList->append("%%+ font "); + embFontList->append(psName); + embFontList->append("\n"); // copy ASCII portion of font strObj.streamReset(); @@ -792,9 +950,7 @@ void PSOutputDev::setupEmbeddedType1Font(Ref *id, const char *psName) { writePS("cleartomark\n"); // ending comment - if (psOutEPS) { - writePS("%%%%EndResource\n"); - } + writePS("%%%%EndResource\n"); err1: strObj.streamClose(); @@ -803,7 +959,7 @@ void PSOutputDev::setupEmbeddedType1Font(Ref *id, const char *psName) { //~ This doesn't handle .pfb files or binary eexec data (which only //~ happens in pfb files?). -void PSOutputDev::setupEmbeddedType1Font(GString *fileName, const char *psName) { +void PSOutputDev::setupEmbeddedType1Font(GString *fileName, char *psName) { FILE *fontFile; int c; int i; @@ -824,12 +980,10 @@ void PSOutputDev::setupEmbeddedType1Font(GString *fileName, const char *psName) fontFileNames[fontFileNameLen++] = fileName->copy(); // beginning comment - if (psOutEPS) { - writePS("%%%%BeginResource: font %s\n", psName); - embFontList->append("%%+ font "); - embFontList->append(psName); - embFontList->append("\n"); - } + writePS("%%%%BeginResource: font %s\n", psName); + embFontList->append("%%+ font "); + embFontList->append(psName); + embFontList->append("\n"); // copy the font file if (!(fontFile = fopen(fileName->getCString(), "rb"))) { @@ -841,14 +995,12 @@ void PSOutputDev::setupEmbeddedType1Font(GString *fileName, const char *psName) fclose(fontFile); // ending comment - if (psOutEPS) { - writePS("%%%%EndResource\n"); - } + writePS("%%%%EndResource\n"); } void PSOutputDev::setupEmbeddedType1CFont(GfxFont *font, Ref *id, - const char *psName) { - const char *fontBuf; + char *psName) { + char *fontBuf; int fontLen; Type1CFontConverter *cvt; int i; @@ -868,31 +1020,65 @@ void PSOutputDev::setupEmbeddedType1CFont(GfxFont *font, Ref *id, fontFileIDs[fontFileIDLen++] = *id; // beginning comment - if (psOutEPS) { - writePS("%%%%BeginResource: font %s\n", psName); - embFontList->append("%%+ font "); - embFontList->append(psName); - embFontList->append("\n"); - } + writePS("%%%%BeginResource: font %s\n", psName); + embFontList->append("%%+ font "); + embFontList->append(psName); + embFontList->append("\n"); // convert it to a Type 1 font - fontBuf = font->readEmbFontFile(&fontLen); + fontBuf = font->readEmbFontFile(xref, &fontLen); cvt = new Type1CFontConverter(fontBuf, fontLen, f); cvt->convert(); delete cvt; - gfree((void *)fontBuf); + gfree(fontBuf); // ending comment - if (psOutEPS) { - writePS("%%%%EndResource\n"); + writePS("%%%%EndResource\n"); +} + +void PSOutputDev::setupEmbeddedTrueTypeFont(GfxFont *font, Ref *id, + char *psName) { + char *fontBuf; + int fontLen; + TrueTypeFontFile *ttFile; + int i; + + // check if font is already embedded + for (i = 0; i < fontFileIDLen; ++i) { + if (fontFileIDs[i].num == id->num && + fontFileIDs[i].gen == id->gen) + return; } + + // add entry to fontFileIDs list + if (fontFileIDLen >= fontFileIDSize) { + fontFileIDSize += 64; + fontFileIDs = (Ref *)grealloc(fontFileIDs, fontFileIDSize * sizeof(Ref)); + } + fontFileIDs[fontFileIDLen++] = *id; + + // beginning comment + writePS("%%%%BeginResource: font %s\n", psName); + embFontList->append("%%+ font "); + embFontList->append(psName); + embFontList->append("\n"); + + // convert it to a Type 42 font + fontBuf = font->readEmbFontFile(xref, &fontLen); + ttFile = new TrueTypeFontFile(fontBuf, fontLen); + ttFile->convertToType42(psName, font->getEncoding(), f); + delete ttFile; + gfree(fontBuf); + + // ending comment + writePS("%%%%EndResource\n"); } void PSOutputDev::setupImages(Dict *resDict) { Object xObjDict, xObj, xObjRef, subtypeObj; int i; - if (!doForm) { + if (mode != psModeForm) { return; } @@ -1006,24 +1192,9 @@ void PSOutputDev::setupImage(Ref id, Stream *str) { void PSOutputDev::startPage(int pageNum, GfxState *state) { int x1, y1, x2, y2, width, height, t; - if (doForm) { - - writePS("/PaintProc {\n"); - writePS("begin xpdf begin\n"); - writePS("pdfStartPage\n"); - tx = ty = 0; - xScale = yScale = 1; - landscape = gFalse; - - } else if (psOutEPS) { - - writePS("pdfStartPage\n"); - tx = ty = 0; - xScale = yScale = 1; - landscape = gFalse; - - } else { + switch (mode) { + case psModePS: writePS("%%%%Page: %d %d\n", pageNum, seqPage); writePS("%%%%BeginPageSetup\n"); @@ -1073,11 +1244,28 @@ void PSOutputDev::startPage(int pageNum, GfxState *state) { writePS("%%%%EndPageSetup\n"); ++seqPage; + break; + + case psModeEPS: + writePS("pdfStartPage\n"); + tx = ty = 0; + xScale = yScale = 1; + landscape = gFalse; + break; + + case psModeForm: + writePS("/PaintProc {\n"); + writePS("begin xpdf begin\n"); + writePS("pdfStartPage\n"); + tx = ty = 0; + xScale = yScale = 1; + landscape = gFalse; + break; } } void PSOutputDev::endPage() { - if (doForm) { + if (mode == psModeForm) { writePS("pdfEndPage\n"); writePS("end end\n"); writePS("} def\n"); @@ -1090,21 +1278,15 @@ void PSOutputDev::endPage() { } void PSOutputDev::saveState(GfxState *state) { - (void)state; - writePS("q\n"); } void PSOutputDev::restoreState(GfxState *state) { - (void)state; - writePS("Q\n"); } void PSOutputDev::updateCTM(GfxState *state, double m11, double m12, double m21, double m22, double m31, double m32) { - (void)state; - writePS("[%g %g %g %g %g %g] cm\n", m11, m12, m21, m22, m31, m32); } @@ -1141,39 +1323,134 @@ void PSOutputDev::updateLineWidth(GfxState *state) { } void PSOutputDev::updateFillColor(GfxState *state) { + GfxColor color; + double gray; GfxRGB rgb; GfxCMYK cmyk; + GfxSeparationColorSpace *sepCS; - if (psOutLevel1Sep) { + switch (level) { + case psLevel1: + state->getFillGray(&gray); + writePS("%g g\n", gray); + break; + case psLevel1Sep: state->getFillCMYK(&cmyk); writePS("%g %g %g %g k\n", cmyk.c, cmyk.m, cmyk.y, cmyk.k); - } else { - state->getFillRGB(&rgb); - if (rgb.r == rgb.g && rgb.g == rgb.b) { - writePS("%g g\n", rgb.r); + break; + case psLevel2: + if (state->getFillColorSpace()->getMode() == csDeviceCMYK) { + state->getFillCMYK(&cmyk); + writePS("%g %g %g %g k\n", cmyk.c, cmyk.m, cmyk.y, cmyk.k); + } else { + state->getFillRGB(&rgb); + if (rgb.r == rgb.g && rgb.g == rgb.b) { + writePS("%g g\n", rgb.r); + } else { + writePS("%g %g %g rg\n", rgb.r, rgb.g, rgb.b); + } + } + break; + case psLevel2Sep: + if (state->getFillColorSpace()->getMode() == csSeparation) { + sepCS = (GfxSeparationColorSpace *)state->getFillColorSpace(); + color.c[0] = 1; + sepCS->getCMYK(&color, &cmyk); + writePS("%g %g %g %g %g (%s) ck\n", + state->getFillColor()->c[0], + cmyk.c, cmyk.m, cmyk.y, cmyk.k, + sepCS->getName()->getCString()); + addCustomColor(sepCS); } else { - writePS("%g %g %g rg\n", rgb.r, rgb.g, rgb.b); + state->getFillCMYK(&cmyk); + writePS("%g %g %g %g k\n", cmyk.c, cmyk.m, cmyk.y, cmyk.k); + addProcessColor(cmyk.c, cmyk.m, cmyk.y, cmyk.k); } + break; } } void PSOutputDev::updateStrokeColor(GfxState *state) { + GfxColor color; + double gray; GfxRGB rgb; GfxCMYK cmyk; + GfxSeparationColorSpace *sepCS; - if (psOutLevel1Sep) { + switch (level) { + case psLevel1: + state->getStrokeGray(&gray); + writePS("%g G\n", gray); + break; + case psLevel1Sep: state->getStrokeCMYK(&cmyk); writePS("%g %g %g %g K\n", cmyk.c, cmyk.m, cmyk.y, cmyk.k); - } else { - state->getStrokeRGB(&rgb); - if (rgb.r == rgb.g && rgb.g == rgb.b) { - writePS("%g G\n", rgb.r); + break; + case psLevel2: + if (state->getStrokeColorSpace()->getMode() == csDeviceCMYK) { + state->getStrokeCMYK(&cmyk); + writePS("%g %g %g %g K\n", cmyk.c, cmyk.m, cmyk.y, cmyk.k); } else { - writePS("%g %g %g RG\n", rgb.r, rgb.g, rgb.b); + state->getStrokeRGB(&rgb); + if (rgb.r == rgb.g && rgb.g == rgb.b) { + writePS("%g G\n", rgb.r); + } else { + writePS("%g %g %g RG\n", rgb.r, rgb.g, rgb.b); + } } + break; + case psLevel2Sep: + if (state->getStrokeColorSpace()->getMode() == csSeparation) { + sepCS = (GfxSeparationColorSpace *)state->getStrokeColorSpace(); + color.c[0] = 1; + sepCS->getCMYK(&color, &cmyk); + writePS("%g %g %g %g %g (%s) CK\n", + state->getStrokeColor()->c[0], + cmyk.c, cmyk.m, cmyk.y, cmyk.k, + sepCS->getName()->getCString()); + addCustomColor(sepCS); + } else { + state->getStrokeCMYK(&cmyk); + writePS("%g %g %g %g K\n", cmyk.c, cmyk.m, cmyk.y, cmyk.k); + addProcessColor(cmyk.c, cmyk.m, cmyk.y, cmyk.k); + } + break; } } +void PSOutputDev::addProcessColor(double c, double m, double y, double k) { + if (c > 0) { + processColors |= psProcessCyan; + } + if (m > 0) { + processColors |= psProcessMagenta; + } + if (y > 0) { + processColors |= psProcessYellow; + } + if (k > 0) { + processColors |= psProcessBlack; + } +} + +void PSOutputDev::addCustomColor(GfxSeparationColorSpace *sepCS) { + PSOutCustomColor *cc; + GfxColor color; + GfxCMYK cmyk; + + for (cc = customColors; cc; cc = cc->next) { + if (!cc->name->cmp(sepCS->getName())) { + return; + } + } + color.c[0] = 1; + sepCS->getCMYK(&color, &cmyk); + cc = new PSOutCustomColor(cmyk.c, cmyk.m, cmyk.y, cmyk.k, + sepCS->getName()->copy()); + cc->next = customColors; + customColors = cc; +} + void PSOutputDev::updateFont(GfxState *state) { if (state->getFont()) { writePS("/F%d_%d %g Tf\n", @@ -1215,8 +1492,6 @@ void PSOutputDev::updateTextPos(GfxState *state) { } void PSOutputDev::updateTextShift(GfxState *state, double shift) { - (void)state; - writePS("%g TJm\n", shift); } @@ -1311,13 +1586,9 @@ void PSOutputDev::drawString(GfxState *state, GString *s) { } void PSOutputDev::drawString16(GfxState *state, GString *s) { -#if defined(JAPANESE_SUPPORT) || defined(CHINESE_SUPPORT) int c1, c2; double w; int i; -#else - (void)s; -#endif /* JAPANESE_SUPPORT || CHINESE_SUPPORT */ // check for invisible text -- this is used by Acrobat Capture if ((state->getRender() & 3) == 3) @@ -1360,10 +1631,8 @@ void PSOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, GBool inlineImg) { int len; - (void)state; - len = height * ((width + 7) / 8); - if (psOutLevel1 || psOutLevel1Sep) { + if (level == psLevel1 || level == psLevel1Sep) { doImageL1(NULL, invert, inlineImg, str, width, height, len); } else { doImageL2(ref, NULL, invert, inlineImg, str, width, height, len); @@ -1372,20 +1641,23 @@ void PSOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, void PSOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, - GBool inlineImg) { + int *maskColors, GBool inlineImg) { int len; - (void)state; - len = height * ((width * colorMap->getNumPixelComps() * colorMap->getBits() + 7) / 8); - if (psOutLevel1) { + switch (level) { + case psLevel1: doImageL1(colorMap, gFalse, inlineImg, str, width, height, len); - } else if (psOutLevel1Sep) { + break; + case psLevel1Sep: //~ handle indexed, separation, ... color spaces doImageL1Sep(colorMap, gFalse, inlineImg, str, width, height, len); - } else { + break; + case psLevel2: + case psLevel2Sep: doImageL2(ref, colorMap, gFalse, inlineImg, str, width, height, len); + break; } } @@ -1397,9 +1669,6 @@ void PSOutputDev::doImageL1(GfxImageColorMap *colorMap, double gray; int x, y, i; - (void)inlineImg; - (void)len; - // width, height, matrix, bits per component if (colorMap) { writePS("%d %d 8 [%d 0 0 %d 0 %d] pdfIm1\n", @@ -1518,6 +1787,9 @@ void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap, GString *s; int n, numComps; GBool useRLE, useA85; + GfxSeparationColorSpace *sepCS; + GfxColor color; + GfxCMYK cmyk; int c; int i; @@ -1528,7 +1800,7 @@ void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap, } // set up to use the array created by setupImages() - if (doForm && !inlineImg) { + if (mode == psModeForm && !inlineImg) { writePS("ImData_%d_%d 0\n", ref->getRefNum(), ref->getRefGen()); } @@ -1565,7 +1837,7 @@ void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap, writePS(" /Decode [%d %d]\n", invert ? 1 : 0, invert ? 0 : 1); } - if (doForm) { + if (mode == psModeForm) { if (inlineImg) { @@ -1606,26 +1878,32 @@ void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap, useRLE = gFalse; useA85 = str->isBinary(); } - if (useA85) + if (useA85) { writePS(" /ASCII85Decode filter\n"); - if (useRLE) + } + if (useRLE) { writePS(" /RunLengthDecode filter\n"); - else + } else { writePS("%s", s->getCString()); - if (s) + } + if (s) { delete s; + } // cut off inline image streams at appropriate length - if (inlineImg) + if (inlineImg) { str = new FixedLengthEncoder(str, len); - else if (!useRLE) + } else if (!useRLE) { str = str->getBaseStream(); + } // add RunLengthEncode and ASCII85 encode filters - if (useRLE) + if (useRLE) { str = new RunLengthEncoder(str); - if (useA85) + } + if (useA85) { str = new ASCII85Encoder(str); + } // end of image dictionary writePS(">>\n"); @@ -1650,12 +1928,22 @@ void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap, writePS("%%%%BeginData: %d Hex Bytes\n", n); } #endif - writePS("%s\n", colorMap ? "pdfIm" : "pdfImM"); + if (level == psLevel2Sep && colorMap && + colorMap->getColorSpace()->getMode() == csSeparation) { + color.c[0] = 1; + sepCS = (GfxSeparationColorSpace *)colorMap->getColorSpace(); + sepCS->getCMYK(&color, &cmyk); + writePS("%g %g %g %g (%s) pdfImSep\n", + cmyk.c, cmyk.m, cmyk.y, cmyk.k, sepCS->getName()->getCString()); + } else { + writePS("%s\n", colorMap ? "pdfIm" : "pdfImM"); + } // copy the stream data str->reset(); - while ((c = str->getChar()) != EOF) + while ((c = str->getChar()) != EOF) { fputc(c, f); + } // add newline and trailer to the end fputc('\n', f); @@ -1667,8 +1955,9 @@ void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap, #endif // delete encoders - if (useRLE || useA85) + if (useRLE || useA85) { delete str; + } } } @@ -1679,7 +1968,9 @@ void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace) { GfxIndexedColorSpace *indexedCS; GfxSeparationColorSpace *separationCS; Guchar *lookup; - double x[1], y[gfxColorMaxComps]; + double x[gfxColorMaxComps], y[gfxColorMaxComps]; + GfxColor color; + GfxCMYK cmyk; int n, numComps; int i, j, k; @@ -1687,6 +1978,7 @@ void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace) { case csDeviceGray: writePS("/DeviceGray"); + processColors |= psProcessBlack; break; case csCalGray: @@ -1703,10 +1995,12 @@ void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace) { calGrayCS->getBlackX(), calGrayCS->getBlackY(), calGrayCS->getBlackZ()); writePS(">>]"); + processColors |= psProcessBlack; break; case csDeviceRGB: writePS("/DeviceRGB"); + processColors |= psProcessCMYK; break; case csCalRGB: @@ -1728,10 +2022,12 @@ void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace) { calRGBCS->getBlackX(), calRGBCS->getBlackY(), calRGBCS->getBlackZ()); writePS(">>]"); + processColors |= psProcessCMYK; break; case csDeviceCMYK: writePS("/DeviceCMYK"); + processColors |= psProcessCMYK; break; case csLab: @@ -1757,6 +2053,7 @@ void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace) { writePS(" /BlackPoint [%g %g %g]\n", labCS->getBlackX(), labCS->getBlackY(), labCS->getBlackZ()); writePS(">>]"); + processColors |= psProcessCMYK; break; case csICCBased: @@ -1777,6 +2074,9 @@ void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace) { for (k = 0; k < numComps; ++k) { writePS("%02x", lookup[j * numComps + k]); } + color.c[0] = j; + indexedCS->getCMYK(&color, &cmyk); + addProcessColor(cmyk.c, cmyk.m, cmyk.y, cmyk.k); } writePS("\n"); } @@ -1788,7 +2088,7 @@ void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace) { //~ separation color space, with the specified alternate color //~ space and tint transform separationCS = (GfxSeparationColorSpace *)colorSpace; - writePS(" [/Indexed "); + writePS("[/Indexed "); dumpColorSpaceL2(separationCS->getAlt()); writePS(" 255 <\n"); numComps = separationCS->getAlt()->getNComps(); @@ -1804,6 +2104,7 @@ void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace) { writePS("\n"); } writePS(">]"); + addCustomColor(separationCS); break; case csDeviceN: @@ -1822,7 +2123,7 @@ void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace) { void PSOutputDev::opiBegin(GfxState *state, Dict *opiDict) { Object dict; - if (psOutOPI) { + if (doOPI) { opiDict->lookup("2.0", &dict); if (dict.isDict()) { opiBegin20(state, dict.getDict()); @@ -2184,7 +2485,7 @@ void PSOutputDev::opiTransform(GfxState *state, double x0, double y0, void PSOutputDev::opiEnd(GfxState *state, Dict *opiDict) { Object dict; - if (psOutOPI) { + if (doOPI) { opiDict->lookup("2.0", &dict); if (dict.isDict()) { writePS("%%%%EndIncludedImage\n"); diff --git a/pdftops/PSOutputDev.h b/pdftops/PSOutputDev.h index 62dce66115..81279be4ac 100644 --- a/pdftops/PSOutputDev.h +++ b/pdftops/PSOutputDev.h @@ -21,32 +21,25 @@ class GfxPath; class GfxFont; class GfxColorSpace; +class GfxSeparationColorSpace; +class PSOutCustomColor; //------------------------------------------------------------------------ -// Parameters +// PSOutputDev //------------------------------------------------------------------------ -// Generate Level 1 PostScript? -extern GBool psOutLevel1; - -// Generate Level 1 separable PostScript? -extern GBool psOutLevel1Sep; - -// Generate Encapsulated PostScript? -extern GBool psOutEPS; - -#if OPI_SUPPORT -// Generate OPI comments? -extern GBool psOutOPI; -#endif - -// Paper size. -extern int paperWidth; -extern int paperHeight; +enum PSOutLevel { + psLevel1, + psLevel1Sep, + psLevel2, + psLevel2Sep +}; -//------------------------------------------------------------------------ -// PSOutputDev -//------------------------------------------------------------------------ +enum PSOutMode { + psModePS, + psModeEPS, + psModeForm +}; enum PSFileType { psFile, // write to file @@ -58,9 +51,11 @@ class PSOutputDev: public OutputDev { public: // Open a PostScript output file, and write the prolog. - PSOutputDev(const char *fileName, Catalog *catalog, + PSOutputDev(char *fileName, XRef *xrefA, Catalog *catalog, int firstPage, int lastPage, - GBool embedType11, GBool doForm1); + PSOutLevel levelA, PSOutMode modeA, GBool doOPIA, + GBool embedType1A, GBool embedTrueTypeA, + int paperWidthA, int paperHeightA); // Destructor -- writes the trailer and closes the file. virtual ~PSOutputDev(); @@ -131,7 +126,7 @@ public: GBool inlineImg); virtual void drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, - GBool inlineImg); + int *maskColors, GBool inlineImg); #if OPI_SUPPORT //----- OPI functions @@ -144,11 +139,14 @@ private: void setupResources(Dict *resDict); void setupFonts(Dict *resDict); void setupFont(GfxFont *font); - void setupEmbeddedType1Font(Ref *id, const char *psName); - void setupEmbeddedType1Font(GString *fileName, const char *psName); - void setupEmbeddedType1CFont(GfxFont *font, Ref *id, const char *psName); + void setupEmbeddedType1Font(Ref *id, char *psName); + void setupEmbeddedType1Font(GString *fileName, char *psName); + void setupEmbeddedType1CFont(GfxFont *font, Ref *id, char *psName); + void setupEmbeddedTrueTypeFont(GfxFont *font, Ref *id, char *psName); void setupImages(Dict *resDict); void setupImage(Ref id, Stream *str); + void addProcessColor(double c, double m, double y, double k); + void addCustomColor(GfxSeparationColorSpace *sepCS); void doPath(GfxPath *path); void doImageL1(GfxImageColorMap *colorMap, GBool invert, GBool inlineImg, @@ -160,21 +158,30 @@ private: GBool invert, GBool inlineImg, Stream *str, int width, int height, int len); void dumpColorSpaceL2(GfxColorSpace *colorSpace); +#if OPI_SUPPORT void opiBegin20(GfxState *state, Dict *dict); void opiBegin13(GfxState *state, Dict *dict); void opiTransform(GfxState *state, double x0, double y0, double *x1, double *y1); GBool getFileSpec(Object *fileSpec, Object *fileName); +#endif void writePS(const char *fmt, ...); void writePSString(GString *s); + PSOutLevel level; // PostScript level (1, 2, separation) + PSOutMode mode; // PostScript mode (PS, EPS, form) + GBool doOPI; // generate OPI comments? GBool embedType1; // embed Type 1 fonts? - GBool doForm; // generate a form? + GBool embedTrueType; // embed TrueType fonts? + int paperWidth; // width of paper, in pts + int paperHeight; // height of paper, in pts FILE *f; // PostScript file PSFileType fileType; // file / pipe / stdout int seqPage; // current sequential page number + XRef *xref; // the xref table for this PDF file + Ref *fontIDs; // list of object IDs of all used fonts int fontIDLen; // number of entries in fontIDs array int fontIDSize; // size of fontIDs array @@ -191,6 +198,10 @@ private: GString *embFontList; // resource comments for embedded fonts + int processColors; // used process colors + PSOutCustomColor // used custom colors + *customColors; + #if OPI_SUPPORT int opi13Nest; // nesting level of OPI 1.3 objects int opi20Nest; // nesting level of OPI 2.0 objects diff --git a/pdftops/Page.cxx b/pdftops/Page.cxx index c2ac6b190b..975fcf1b6d 100644 --- a/pdftops/Page.cxx +++ b/pdftops/Page.cxx @@ -31,97 +31,68 @@ //------------------------------------------------------------------------ PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) { - Object obj1, obj2; + Object obj1; double w, h; // get old/default values if (attrs) { - x1 = attrs->x1; - y1 = attrs->y1; - x2 = attrs->x2; - y2 = attrs->y2; - cropX1 = attrs->cropX1; - cropY1 = attrs->cropY1; - cropX2 = attrs->cropX2; - cropY2 = attrs->cropY2; + mediaBox = attrs->mediaBox; + cropBox = attrs->cropBox; + haveCropBox = attrs->haveCropBox; rotate = attrs->rotate; attrs->resources.copy(&resources); } else { // set default MediaBox to 8.5" x 11" -- this shouldn't be necessary // but some (non-compliant) PDF files don't specify a MediaBox - x1 = 0; - y1 = 0; - x2 = 612; - y2 = 792; - cropX1 = cropY1 = cropX2 = cropY2 = 0; + mediaBox.x1 = 0; + mediaBox.y1 = 0; + mediaBox.x2 = 612; + mediaBox.y2 = 792; + cropBox.x1 = cropBox.y1 = cropBox.x2 = cropBox.y2 = 0; + haveCropBox = gFalse; rotate = 0; resources.initNull(); } // media box - dict->lookup("MediaBox", &obj1); - if (obj1.isArray() && obj1.arrayGetLength() == 4) { - obj1.arrayGet(0, &obj2); - if (obj2.isNum()) - x1 = obj2.getNum(); - obj2.free(); - obj1.arrayGet(1, &obj2); - if (obj2.isNum()) - y1 = obj2.getNum(); - obj2.free(); - obj1.arrayGet(2, &obj2); - if (obj2.isNum()) - x2 = obj2.getNum(); - obj2.free(); - obj1.arrayGet(3, &obj2); - if (obj2.isNum()) - y2 = obj2.getNum(); - obj2.free(); - } - obj1.free(); + readBox(dict, "MediaBox", &mediaBox); // crop box - dict->lookup("CropBox", &obj1); - if (obj1.isArray() && obj1.arrayGetLength() == 4) { - obj1.arrayGet(0, &obj2); - if (obj2.isNum()) - cropX1 = obj2.getNum(); - obj2.free(); - obj1.arrayGet(1, &obj2); - if (obj2.isNum()) - cropY1 = obj2.getNum(); - obj2.free(); - obj1.arrayGet(2, &obj2); - if (obj2.isNum()) - cropX2 = obj2.getNum(); - obj2.free(); - obj1.arrayGet(3, &obj2); - if (obj2.isNum()) - cropY2 = obj2.getNum(); - obj2.free(); - } - obj1.free(); + cropBox = mediaBox; + haveCropBox = readBox(dict, "CropBox", &cropBox); // if the MediaBox is excessively larger than the CropBox, // just use the CropBox limitToCropBox = gFalse; - w = 0.25 * (cropX2 - cropX1); - h = 0.25 * (cropY2 - cropY1); - if (cropX2 > cropX1 && - ((cropX1 - x1) + (x2 - cropX2) > w || - (cropY1 - y1) + (y2 - cropY2) > h)) { - limitToCropBox = gTrue; + if (haveCropBox) { + w = 0.25 * (cropBox.x2 - cropBox.x1); + h = 0.25 * (cropBox.y2 - cropBox.y1); + if ((cropBox.x1 - mediaBox.x1) + (mediaBox.x2 - cropBox.x2) > w || + (cropBox.y1 - mediaBox.y1) + (mediaBox.y2 - cropBox.y2) > h) { + limitToCropBox = gTrue; + } } + // other boxes + bleedBox = cropBox; + readBox(dict, "BleedBox", &bleedBox); + trimBox = cropBox; + readBox(dict, "TrimBox", &trimBox); + artBox = cropBox; + readBox(dict, "ArtBox", &artBox); + // rotate dict->lookup("Rotate", &obj1); - if (obj1.isInt()) + if (obj1.isInt()) { rotate = obj1.getInt(); + } obj1.free(); - while (rotate < 0) + while (rotate < 0) { rotate += 360; - while (rotate >= 360) + } + while (rotate >= 360) { rotate -= 360; + } // resource dictionary dict->lookup("Resources", &obj1); @@ -136,17 +107,66 @@ PageAttrs::~PageAttrs() { resources.free(); } +GBool PageAttrs::readBox(Dict *dict, char *key, PDFRectangle *box) { + PDFRectangle tmp; + Object obj1, obj2; + GBool ok; + + dict->lookup(key, &obj1); + if (obj1.isArray() && obj1.arrayGetLength() == 4) { + ok = gTrue; + obj1.arrayGet(0, &obj2); + if (obj2.isNum()) { + tmp.x1 = obj2.getNum(); + } else { + ok = gFalse; + } + obj2.free(); + obj1.arrayGet(1, &obj2); + if (obj2.isNum()) { + tmp.y1 = obj2.getNum(); + } else { + ok = gFalse; + } + obj2.free(); + obj1.arrayGet(2, &obj2); + if (obj2.isNum()) { + tmp.x2 = obj2.getNum(); + } else { + ok = gFalse; + } + obj2.free(); + obj1.arrayGet(3, &obj2); + if (obj2.isNum()) { + tmp.y2 = obj2.getNum(); + } else { + ok = gFalse; + } + obj2.free(); + if (ok) { + *box = tmp; + } + } else { + ok = gFalse; + } + obj1.free(); + return ok; +} + //------------------------------------------------------------------------ // Page //------------------------------------------------------------------------ -Page::Page(int num1, Dict *pageDict, PageAttrs *attrs1) { +Page::Page(XRef *xrefA, int numA, Dict *pageDict, PageAttrs *attrsA, + GBool printCommandsA) { ok = gTrue; - num = num1; + xref = xrefA; + num = numA; + printCommands = printCommandsA; // get attributes - attrs = attrs1; + attrs = attrsA; // annotations pageDict->lookupNF("Annots", &annots); @@ -185,18 +205,22 @@ Page::~Page() { void Page::display(OutputDev *out, double dpi, int rotate, Links *links, Catalog *catalog) { #ifndef PDF_PARSER_ONLY + PDFRectangle *box, *cropBox; Gfx *gfx; Object obj; Link *link; int i; FormWidgets *formWidgets; + box = getBox(); + cropBox = getCropBox(); + if (printCommands) { printf("***** MediaBox = ll:%g,%g ur:%g,%g\n", - getX1(), getY1(), getX2(), getY2()); + box->x1, box->y1, box->x2, box->y2); if (isCropped()) { printf("***** CropBox = ll:%g,%g ur:%g,%g\n", - getCropX1(), getCropY1(), getCropX2(), getCropY2()); + cropBox->x1, cropBox->y1, cropBox->x2, cropBox->y2); } printf("***** Rotate = %d\n", attrs->getRotate()); } @@ -207,10 +231,9 @@ void Page::display(OutputDev *out, double dpi, int rotate, } else if (rotate < 0) { rotate += 360; } - gfx = new Gfx(out, num, attrs->getResourceDict(), - dpi, getX1(), getY1(), getX2(), getY2(), isCropped(), - getCropX1(), getCropY1(), getCropX2(), getCropY2(), rotate); - contents.fetch(&obj); + gfx = new Gfx(xref, out, num, attrs->getResourceDict(), + dpi, box, isCropped(), cropBox, rotate, printCommands); + contents.fetch(xref, &obj); if (!obj.isNull()) { gfx->display(&obj); } @@ -227,7 +250,7 @@ void Page::display(OutputDev *out, double dpi, int rotate, // draw AcroForm widgets //~ need to reset CTM ??? - formWidgets = new FormWidgets(annots.fetch(&obj)); + formWidgets = new FormWidgets(xref, annots.fetch(xref, &obj)); obj.free(); if (printCommands && formWidgets->getNumWidgets() > 0) { printf("***** AcroForm widgets\n"); diff --git a/pdftops/Page.h b/pdftops/Page.h index a144d2cfa7..a40974cfc4 100644 --- a/pdftops/Page.h +++ b/pdftops/Page.h @@ -21,6 +21,12 @@ class OutputDev; class Links; class Catalog; +//------------------------------------------------------------------------ + +struct PDFRectangle { + double x1, y1, x2, y2; +}; + //------------------------------------------------------------------------ // PageAttrs //------------------------------------------------------------------------ @@ -37,24 +43,28 @@ public: ~PageAttrs(); // Accessors. - double getX1() { return limitToCropBox ? cropX1 : x1; } - double getY1() { return limitToCropBox ? cropY1 : y1; } - double getX2() { return limitToCropBox ? cropX2 : x2; } - double getY2() { return limitToCropBox ? cropY2 : y2; } - GBool isCropped() { return cropX2 > cropX1; } - double getCropX1() { return cropX1; } - double getCropY1() { return cropY1; } - double getCropX2() { return cropX2; } - double getCropY2() { return cropY2; } + PDFRectangle *getBox() { return limitToCropBox ? &cropBox : &mediaBox; } + PDFRectangle *getMediaBox() { return &mediaBox; } + PDFRectangle *getCropBox() { return &cropBox; } + GBool isCropped() { return haveCropBox; } + PDFRectangle *getBleedBox() { return &bleedBox; } + PDFRectangle *getTrimBox() { return &trimBox; } + PDFRectangle *getArtBox() { return &artBox; } int getRotate() { return rotate; } Dict *getResourceDict() { return resources.isDict() ? resources.getDict() : (Dict *)NULL; } private: - double x1, y1, x2, y2; - double cropX1, cropY1, cropX2, cropY2; + GBool readBox(Dict *dict, char *key, PDFRectangle *box); + + PDFRectangle mediaBox; + PDFRectangle cropBox; + GBool haveCropBox; GBool limitToCropBox; + PDFRectangle bleedBox; + PDFRectangle trimBox; + PDFRectangle artBox; int rotate; Object resources; }; @@ -67,7 +77,8 @@ class Page { public: // Constructor. - Page(int num1, Dict *pageDict, PageAttrs *attrs1); + Page(XRef *xrefA, int numA, Dict *pageDict, PageAttrs *attrsA, + GBool printCommandsA); // Destructor. ~Page(); @@ -76,27 +87,25 @@ public: GBool isOk() { return ok; } // Get page parameters. - double getX1() { return attrs->getX1(); } - double getY1() { return attrs->getY1(); } - double getX2() { return attrs->getX2(); } - double getY2() { return attrs->getY2(); } + PDFRectangle *getBox() { return attrs->getBox(); } + PDFRectangle *getMediaBox() { return attrs->getMediaBox(); } + PDFRectangle *getCropBox() { return attrs->getCropBox(); } GBool isCropped() { return attrs->isCropped(); } - double getCropX1() { return attrs->getCropX1(); } - double getCropY1() { return attrs->getCropY1(); } - double getCropX2() { return attrs->getCropX2(); } - double getCropY2() { return attrs->getCropY2(); } - double getWidth() { return attrs->getX2() - attrs->getX1(); } - double getHeight() { return attrs->getY2() - attrs->getY1(); } + double getWidth() { return attrs->getBox()->x2 - attrs->getBox()->x1; } + double getHeight() { return attrs->getBox()->y2 - attrs->getBox()->y1; } + PDFRectangle *getBleedBox() { return attrs->getBleedBox(); } + PDFRectangle *getTrimBox() { return attrs->getTrimBox(); } + PDFRectangle *getArtBox() { return attrs->getArtBox(); } int getRotate() { return attrs->getRotate(); } // Get resource dictionary. Dict *getResourceDict() { return attrs->getResourceDict(); } // Get annotations array. - Object *getAnnots(Object *obj) { return annots.fetch(obj); } + Object *getAnnots(Object *obj) { return annots.fetch(xref, obj); } // Get contents. - Object *getContents(Object *obj) { return contents.fetch(obj); } + Object *getContents(Object *obj) { return contents.fetch(xref, obj); } // Display a page. void display(OutputDev *out, double dpi, int rotate, @@ -104,10 +113,12 @@ public: private: + XRef *xref; // the xref table for this PDF file int num; // page number PageAttrs *attrs; // page attributes Object annots; // annotations array Object contents; // page contents + GBool printCommands; // print the drawing commands (for debugging) GBool ok; // true if page is valid }; diff --git a/pdftops/Params.cxx b/pdftops/Params.cxx index efed572435..8536da20d3 100644 --- a/pdftops/Params.cxx +++ b/pdftops/Params.cxx @@ -16,35 +16,38 @@ #include "gfile.h" #include "Params.h" -const char **fontPath = NULL; +char **fontPath = NULL; static int fontPathLen, fontPathSize; DevFontMapEntry *devFontMap = NULL; static int devFontMapLen, devFontMapSize; -void initParams(const char *configFile) { +void initParams(char *userConfigFile, char *sysConfigFile) { GString *fileName; FILE *f; char buf[256]; char *p, *q; // initialize font path and font map - fontPath = (const char **)gmalloc((fontPathSize = 8) * sizeof(const char *)); + fontPath = (char **)gmalloc((fontPathSize = 8) * sizeof(char *)); fontPath[fontPathLen = 0] = NULL; devFontMap = (DevFontMapEntry *)gmalloc((devFontMapSize = 8) * sizeof(DevFontMapEntry)); devFontMap[devFontMapLen = 0].pdfFont = NULL; // read config file - fileName = appendToPath(getHomeDir(), configFile); - if ((f = fopen(fileName->getCString(), "r"))) { + fileName = appendToPath(getHomeDir(), userConfigFile); + if (!(f = fopen(fileName->getCString(), "r"))) { + f = fopen(sysConfigFile, "r"); + } + if (f) { while (fgets(buf, sizeof(buf)-1, f)) { buf[sizeof(buf)-1] = '\0'; p = strtok(buf, " \t\n\r"); if (p && !strcmp(p, "fontpath")) { if (fontPathLen+1 >= fontPathSize) - fontPath = (const char **) - grealloc(fontPath, (fontPathSize += 8) * sizeof(const char *)); + fontPath = (char **) + grealloc(fontPath, (fontPathSize += 8) * sizeof(char *)); p = strtok(NULL, " \t\n\r"); fontPath[fontPathLen++] = copyString(p); } else if (p && !strcmp(p, "fontmap")) { @@ -74,14 +77,14 @@ void freeParams() { if (fontPath) { for (i = 0; i < fontPathLen; ++i) - gfree((void *)fontPath[i]); - gfree((void *)fontPath); + gfree(fontPath[i]); + gfree(fontPath); } if (devFontMap) { for (i = 0; i < devFontMapLen; ++i) { - gfree((void *)devFontMap[i].pdfFont); - gfree((void *)devFontMap[i].devFont); + gfree(devFontMap[i].pdfFont); + gfree(devFontMap[i].devFont); } - gfree((void *)devFontMap); + gfree(devFontMap); } } diff --git a/pdftops/Params.h b/pdftops/Params.h index 2c5936a3f4..1d8ce38282 100644 --- a/pdftops/Params.h +++ b/pdftops/Params.h @@ -9,27 +9,28 @@ #ifndef PARAMS_H #define PARAMS_H -// Print commands as they're executed. -extern GBool printCommands; +#include "gtypes.h" // If this is set, error messages will be silently discarded. extern GBool errQuiet; // Font search path. -extern const char **fontPath; +extern char **fontPath; // Mapping from PDF font name to device font name. struct DevFontMapEntry { - const char *pdfFont; - const char *devFont; + char *pdfFont; + char *devFont; }; extern DevFontMapEntry *devFontMap; //------------------------------------------------------------------------ -// Initialize font path and font map, and read configuration file, -// if present. -extern void initParams(const char *configFile); +// Initialize font path and font map, and read configuration file. If +// exists, read it; else if exists, +// read it. is relative to the user's home +// directory; should be an absolute path. +extern void initParams(char *userConfigFile, char *sysConfigFile); // Free memory used for font path and font map. extern void freeParams(); diff --git a/pdftops/Parser.cxx b/pdftops/Parser.cxx index 6ad0c5a781..57ba05061e 100644 --- a/pdftops/Parser.cxx +++ b/pdftops/Parser.cxx @@ -21,8 +21,9 @@ #include "Decrypt.h" #endif -Parser::Parser(Lexer *lexer1) { - lexer = lexer1; +Parser::Parser(XRef *xrefA, Lexer *lexerA) { + xref = xrefA; + lexer = lexerA; inlineImg = 0; lexer->getObj(&buf1); lexer->getObj(&buf2); @@ -36,7 +37,8 @@ Parser::~Parser() { #ifndef NO_DECRYPTION Object *Parser::getObj(Object *obj, - Guchar *fileKey, int objNum, int objGen) { + Guchar *fileKey, int keyLength, + int objNum, int objGen) { #else Object *Parser::getObj(Object *obj) { #endif @@ -63,10 +65,10 @@ Object *Parser::getObj(Object *obj) { // array if (buf1.isCmd("[")) { shift(); - obj->initArray(); + obj->initArray(xref); while (!buf1.isCmd("]") && !buf1.isEOF()) #ifndef NO_DECRYPTION - obj->arrayAdd(getObj(&obj2, fileKey, objNum, objGen)); + obj->arrayAdd(getObj(&obj2, fileKey, keyLength, objNum, objGen)); #else obj->arrayAdd(getObj(&obj2)); #endif @@ -77,7 +79,7 @@ Object *Parser::getObj(Object *obj) { // dictionary or stream } else if (buf1.isCmd("<<")) { shift(); - obj->initDict(); + obj->initDict(xref); while (!buf1.isCmd(">>") && !buf1.isEOF()) { if (!buf1.isName()) { error(getPos(), "Dictionary key must be a name object"); @@ -88,7 +90,7 @@ Object *Parser::getObj(Object *obj) { if (buf1.isEOF() || buf1.isError()) break; #ifndef NO_DECRYPTION - obj->dictAdd(key, getObj(&obj2, fileKey, objNum, objGen)); + obj->dictAdd(key, getObj(&obj2, fileKey, keyLength, objNum, objGen)); #else obj->dictAdd(key, getObj(&obj2)); #endif @@ -101,7 +103,8 @@ Object *Parser::getObj(Object *obj) { obj->initStream(str); #ifndef NO_DECRYPTION if (fileKey) { - str->getBaseStream()->doDecryption(fileKey, objNum, objGen); + str->getBaseStream()->doDecryption(fileKey, keyLength, + objNum, objGen); } #endif } else { @@ -129,7 +132,7 @@ Object *Parser::getObj(Object *obj) { } else if (buf1.isString() && fileKey) { buf1.copy(obj); s = obj->getString(); - decrypt = new Decrypt(fileKey, objNum, objGen); + decrypt = new Decrypt(fileKey, keyLength, objNum, objGen); for (i = 0, p = obj->getString()->getCString(); i < s->getLength(); ++i, ++p) { diff --git a/pdftops/Parser.h b/pdftops/Parser.h index 6e6184499e..463d99827d 100644 --- a/pdftops/Parser.h +++ b/pdftops/Parser.h @@ -23,7 +23,7 @@ class Parser { public: // Constructor. - Parser(Lexer *lexer1); + Parser(XRef *xrefA, Lexer *lexerA); // Destructor. ~Parser(); @@ -31,7 +31,8 @@ public: // Get the next object from the input stream. #ifndef NO_DECRYPTION Object *getObj(Object *obj, - Guchar *fileKey = NULL, int objNum = 0, int objGen = 0); + Guchar *fileKey = NULL, int keyLength = 0, + int objNum = 0, int objGen = 0); #else Object *getObj(Object *obj); #endif @@ -44,6 +45,7 @@ public: private: + XRef *xref; // the xref table for this PDF file Lexer *lexer; // input stream Object buf1, buf2; // next two tokens int inlineImg; // set when inline image data is encountered diff --git a/pdftops/README b/pdftops/README index f6bc9ebee0..4835a82f82 100644 --- a/pdftops/README +++ b/pdftops/README @@ -1,11 +1,11 @@ -xpdf +Xpdf ==== -version 0.90 -99-aug-02 +version 0.93 +2001-oct-25 -The xpdf software and documentation are -copyright 1996-1999 Derek B. Noonburg. +The Xpdf software and documentation are +copyright 1996-2001 Derek B. Noonburg. Email: derekn@foolabs.com WWW: http://www.foolabs.com/xpdf/ @@ -14,7 +14,7 @@ The PDF data structures, operators, and specification are copyright 1995 Adobe Systems Inc. -What is xpdf? +What is Xpdf? ------------- Xpdf is a viewer for Portable Document Format (PDF) files. (These are @@ -24,8 +24,8 @@ OS/2. The non-X components of the package (pdftops, pdftotext, etc.) also run on Win32 systems and should run on pretty much any system with a decent C++ compiler. -Xpdf is designed to be small and efficient. It does not use the Motif -or Xt libraries. It can use standard X fonts. +Xpdf is designed to be small and efficient. It can use Type 1, +TrueType, or standard X fonts. Distribution @@ -39,16 +39,16 @@ confusing, the basic idea is good. In order to cut down on the confusion a little bit, here are some informal clarifications: -- I don't mind if you redistribute xpdf in source and/or binary form, +- I don't mind if you redistribute Xpdf in source and/or binary form, as long as you include all of the documentation: README, man pages (or help files), and COPYING. (Note that the README file contains a pointer to a web page with the source code.) -- Selling a CD-ROM that contains xpdf is fine with me, as long as it +- Selling a CD-ROM that contains Xpdf is fine with me, as long as it includes the documentation. I wouldn't mind receiving a sample copy, but it's not necessary. -- If you make useful changes to xpdf, please make the source code +- If you make useful changes to Xpdf, please make the source code available -- post it on a web site, email it to me, whatever. If you're interested in commercial licensing, please contact me by @@ -58,7 +58,7 @@ email: derekn@foolabs.com . Compatibility ------------- -Xpdf is developed and tested on a Linux 2.0 x86 system. +Xpdf is developed and tested on a Linux 2.2 x86 system. In addition, it has been compiled by others on Solaris, AIX, HP-UX, SCO UnixWare, Digital Unix, Irix, and numerous other Unix @@ -66,24 +66,24 @@ implementations, as well as VMS and OS/2. It should work on pretty much any system which runs X11 and has Unix-like libraries. You'll need ANSI C++ and C compilers to compile it. -The non-X components of xpdf (pdftops, pdftotext, pdfinfo, pdfimages) -can also be compiled on Win32 systems. See the xpdf web page for +The non-X components of Xpdf (pdftops, pdftotext, pdfinfo, pdfimages) +can also be compiled on Win32 systems. See the Xpdf web page for details. -If you compiled xpdf for a system not listed on the web page, please +If you compile Xpdf for a system not listed on the web page, please let me know. If you're willing to make your binary available by ftp -or on the web, I'll be happy to add a link from the xpdf web page. I +or on the web, I'll be happy to add a link from the Xpdf web page. I have decided not to host any binaries I didn't compile myself (for disk space and support reasons). -If you can't get xpdf to compile on your system, send me email and +If you can't get Xpdf to compile on your system, send me email and I'll try to help. -Xpdf has been ported to the Acorn, Amiga, and BeOS. See the xpdf web -page for links. +Xpdf has been ported to the Acorn, Amiga, BeOS, and EPOC. See the +Xpdf web page for links. -Getting xpdf +Getting Xpdf ------------ The latest version is available from: @@ -102,7 +102,7 @@ list of people. If you'd like to receive email notification of new versions, just let me know. -Running xpdf +Running Xpdf ------------ To run xpdf, simply type: @@ -168,7 +168,22 @@ For Japanese support, you will need a Japanese font of the form: -*-fixed-medium-r-normal-*-NN-*-*-*-*-*-jisx0208.1983-0 -and an X server that can handle 16-bit fonts. +and an X server that can handle 16-bit fonts. You can also set this +font using the xpdf.japaneseFont resource. + +For Chinese GB (simplified Chinese) support, you will need a font of +the form: + + -*-fangsong ti-medium-r-normal-*-%s-*-*-*-*-*-gb2312.1980-0 + +You can replace this font using the xpdf.chineseGBFont resource. + +For Chinese CNS (traditional Chinese) support, you will need a font of +the form: + + -*-fixed-medium-r-normal--*-%s-*-*-*-*-big5-0 + +You can replace this font using the xpdf.chineseCNSFont resource. If compiled with t1lib support, xpdf will use t1lib to render embedded Type 1 and Type 1C fonts. In addition, xpdf can be configured to use @@ -191,6 +206,28 @@ example: xpdf.t1Symbol: /usr/local/fonts/Symbol.pfa xpdf.t1ZapfDingbats: /usr/local/fonts/ZapfDingbats.pfa +Ghostscript comes with a set of free, high-quality Type 1 fonts, +donated by URW++ Design and Development Incorporated. The xpdf X +resources needed for these fonts are: + + xpdf.t1TimesRoman: /usr/ghostscript/fonts/n021003l.pfb + xpdf.t1TimesItalic: /usr/ghostscript/fonts/n021023l.pfb + xpdf.t1TimesBold: /usr/ghostscript/fonts/n021004l.pfb + xpdf.t1TimesBoldItalic: /usr/ghostscript/fonts/n021024l.pfb + xpdf.t1Helvetica: /usr/ghostscript/fonts/n019003l.pfb + xpdf.t1HelveticaOblique: /usr/ghostscript/fonts/n019023l.pfb + xpdf.t1HelveticaBold: /usr/ghostscript/fonts/n019004l.pfb + xpdf.t1HelveticaBoldOblique: /usr/ghostscript/fonts/n019024l.pfb + xpdf.t1Courier: /usr/ghostscript/fonts/n022003l.pfb + xpdf.t1CourierOblique: /usr/ghostscript/fonts/n022023l.pfb + xpdf.t1CourierBold: /usr/ghostscript/fonts/n022004l.pfb + xpdf.t1CourierBoldOblique: /usr/ghostscript/fonts/n022024l.pfb + xpdf.t1Symbol: /usr/ghostscript/fonts/s050000l.pfb + xpdf.t1ZapfDingbats: /usr/ghostscript/fonts/d050000l.pfb + +You will obviously need to replace '/usr/ghostscript/fonts' with the +appropriate path on your system. + The Unisys LZW Patent --------------------- @@ -198,13 +235,13 @@ The Unisys LZW Patent Nearly all PDF files include data which has been compressed with the LZW compression algorithm. Unfortunately, LZW is covered by a software patent which is owned by Unisys Corporation. Unisys refuses -to license this patent for PDF-related use in software such as xpdf +to license this patent for PDF-related use in software such as Xpdf which is released for free and which may be freely redistributed. (This is same algorithm which is used by GIF. However, Unisys is not doing licensing for free PDF viwers in the same way as for free GIF viewers.) -As a workaround, xpdf converts PDF-format LZW data to compress-format +As a workaround, Xpdf converts PDF-format LZW data to compress-format LZW data. (The standard UNIX compress utility also uses LZW, but with a slightly different file format.) This conversion does *not* decompress the data; it simply converts it to a different file format. @@ -221,7 +258,7 @@ For Unisys's slant on things (mostly regarding GIF), see an email address for feedback. -Compiling xpdf +Compiling Xpdf -------------- See the separate file, INSTALL. @@ -230,10 +267,9 @@ See the separate file, INSTALL. Bugs ---- -This release of xpdf should improve the situation with embedded -fonts. However, Type 3 and TrueType fonts are still not handled. +Type 3 fonts are still not well supported by Xpdf. -If you find a bug in xpdf, i.e., if it prints an error message, +If you find a bug in Xpdf, i.e., if it prints an error message, crashes, or incorrectly displays a document, and you don't see that bug listed here, please send me email, with a pointer (URL, ftp site, etc.) to the PDF file. @@ -245,7 +281,8 @@ Acknowledgments Thanks to: * Patrick Voigt for help with the remote server code. -* Patrick Moreau and Martin P.J. Zinser for the VMS port. +* Patrick Moreau, Martin P.J. Zinser, and David Mathog for the VMS + port. * David Boldt and Rick Rodgers for sample man pages. * Brendan Miller for the icon idea. * Olly Betts for help testing pdftotext. @@ -255,40 +292,73 @@ Thanks to: * Leo Smiers for the decryption patches. * Rainer Menzner for creating t1lib, and for helping me adapt it to xpdf. +* Pine Tree Systems A/S for funding the OPI and EPS support in + pdftops. +* Easy Software Products for funding the "sh" operator support. References ---------- -Adobe Systems Inc., _Portable Document Format Reference Manual_. -Addison-Wesley, 1993, ISBN 0-201-62628-4. -[The printed manual for PDF version 1.0.] +Adobe Systems Inc., _PDF Reference_, 2nd ed. +Addison-Wesley, 2000, ISBN 0-201-61588-6. +[The printed manual for PDF version 1.3.] -Adobe Systems Inc., _Portable Document Format Reference Manual_, -Version 1.3. March 11, 1999. -http://partners.adobe.com/asn/developer/PDFS/TN/PDFSPEC.PDF -[Updated manual for PDF 1.3.] +Adobe Systems Inc., _Portable Document Format: Changes from Version +1.3 to 1.4_, Adobe Developer Support Technical Note #5409. +June 11, 2001. +http://partners.adobe.com/asn/developer/acrosdk/docs/filefmtspecs/PDF14Deltas.pdf +[Updates for PDF 1.4.] -Adobe Systems Inc., _PostScript Language Reference Manual_, 2nd ed. -Addison-Wesley, 1990, ISBN 0-201-18127-4. +Adobe Systems Inc., _PostScript Language Reference_, 3rd ed. +Addison-Wesley, 1999, ISBN 0-201-37922-8. [The official PostScript manual.] +Adobe Systems, Inc., _The Type 42 Font Format Specification_, +Adobe Developer Support Technical Specification #5012. 1998. +http://partners.adobe.com/asn/developer/pdfs/tn/5012.Type42_Spec.pdf +[Type 42 is the format used to embed TrueType fonts in PostScript +files.] + Adobe Systems, Inc., _Adobe CMap and CIDFont Files Specification_, Adobe Developer Support Technical Specification #5014. 1995. http://www.adobe.com/supportservice/devrelations/PDFS/TN/5014.CIDFont_Spec.pdf -[CMap file format needed for Japanese font support.] +[CMap file format needed for Japanese and Chinese font support.] Adobe Systems, Inc., _Adobe-Japan1-2 Character Collection for -CID-Keyed Fonts_ (Bitmap Character Image Version), Adobe Developer -Support Technical Note #5078-b. 1994. -http://www.adobe.com/supportservice/devrelations/PDFS/TN/5078b.pdf -[The complete Adobe Japanese character set.] +CID-Keyed Fonts_, Adobe Developer Support Technical Note #5078. +1994. +http://partners.adobe.com/asn/developer/PDFS/TN/5078.CID_Glyph.pdf +[The Adobe Japanese character set.] + +Adobe Systems, Inc., _Adobe-GB1-3 Character Collection for +CID-Keyed Fonts_, Adobe Developer Support Technical Note #5079. +1998. +http://partners.adobe.com/asn/developer/PDFS/TN/5079.GB_CharColl.pdf +[The Adobe Chinese GB character set.] + +Adobe Systems, Inc., _Adobe-CNS1-3 Character Collection for +CID-Keyed Fonts_, Adobe Developer Support Technical Note #5080. +2000. +http://partners.adobe.com/asn/developer/PDFS/TN/5080.CNS_CharColl.pdf +[The Adobe Chinese CNS character set.] Adobe Systems Inc., _Supporting the DCT Filters in PostScript Level 2_, Adobe Developer Support Technical Note #5116. 1992. http://www.adobe.com/supportservice/devrelations/PDFS/TN/5116.PS2_DCT.PDF [Description of the DCTDecode filter parameters.] +Adobe Systems Inc., _Open Prepress Interface (OPI) Specification - +Version 2.0_, Adobe Developer Support Technical Note #5660. 2000. +http://partners.adobe.com/asn/developer/PDFS/TN/5660.OPI_2.0.pdf + +Adobe Systems Inc., CMap files. +ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/adobe/ +[The actual CMap files for the 16-bit CJK encodings.] + +Aldus Corp., _OPI: Open Prepress Interface Specification 1.3_. 1993. +http://partners.adobe.com/asn/developer/PDFS/TN/OPI_13.pdf + Anonymous, RC4 source code. ftp://ftp.ox.ac.uk/pub/crypto/misc/rc4.tar.gz ftp://idea.sec.dsi.unimi.it/pub/crypt/code/rc4.tar.gz @@ -329,6 +399,14 @@ Fast 1-D DCT Algorithms with 11 Multiplications". IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989, 988-991. [The fast IDCT algorithm used in the DCTDecode filter.] +Microsoft, _TrueType 1.0 Font Files_, rev. 1.66. 1995. +http://www.microsoft.com/typography/tt/tt.htm +[The TrueType font spec (in MS Word format, naturally).] + +Charles Poynton, "Color FAQ". +http://www.inforamp.net/~poynton/ColorFAQ.html +[The mapping from the CIE 1931 (XYZ) color space to RGB.] + R. Rivest, "The MD5 Message-Digest Algorithm". RFC 1321. [MD5 is used in PDF document encryption.] diff --git a/pdftops/SFont.h b/pdftops/SFont.h index 4758664fa1..cab17961e2 100644 --- a/pdftops/SFont.h +++ b/pdftops/SFont.h @@ -22,8 +22,8 @@ class SFontEngine { public: - SFontEngine(Display *display, Visual *visual, int depth, - Colormap colormap); + SFontEngine(Display *displayA, Visual *visualA, int depthA, + Colormap colormapA); virtual ~SFontEngine(); // Use a TrueColor visual. Pixel values are computed as: @@ -32,8 +32,8 @@ public: // // where r, g, and b are scaled to the ranges [0,rMax], [0,gMax], // and [0,bMax], respectively. - virtual void useTrueColor(int rMax, int rShift, int gMax, int gShift, - int bMax, int bShift); + virtual void useTrueColor(int rMaxA, int rShiftA, int gMaxA, int gShiftA, + int bMaxA, int bShiftA); // Use an RGB color cube. is an array containing // ** pixel values in red,green,blue order, e.g., @@ -53,7 +53,7 @@ public: // // The array is not copied and must remain valid for the // lifetime of this SFont object. - virtual void useColorCube(Gulong *colors, int nRGB); + virtual void useColorCube(Gulong *colorsA, int nRGBA); protected: diff --git a/pdftops/StdFontInfo.h b/pdftops/StdFontInfo.h index 4b3e43539a..0db033f6bd 100644 --- a/pdftops/StdFontInfo.h +++ b/pdftops/StdFontInfo.h @@ -16,7 +16,7 @@ //------------------------------------------------------------------------ #define type1StdEncodingSize 256 -static const char *type1StdEncodingNames[type1StdEncodingSize] = { +static char *type1StdEncodingNames[type1StdEncodingSize] = { NULL, NULL, NULL, @@ -282,7 +282,7 @@ static FontEncoding type1StdEncoding(type1StdEncodingNames, //------------------------------------------------------------------------ #define type1ExpertEncodingSize 256 -static const char *type1ExpertEncodingNames[type1ExpertEncodingSize] = { +static char *type1ExpertEncodingNames[type1ExpertEncodingSize] = { NULL, NULL, NULL, diff --git a/pdftops/Stream.cxx b/pdftops/Stream.cxx index 5677dff9d9..a8a88e623d 100644 --- a/pdftops/Stream.cxx +++ b/pdftops/Stream.cxx @@ -88,9 +88,7 @@ char *Stream::getLine(char *buf, int size) { return buf; } -GString *Stream::getPSFilter(const char *indent) { - (void)indent; - +GString *Stream::getPSFilter(char *indent) { return new GString(); } @@ -138,7 +136,7 @@ Stream *Stream::addFilters(Object *dict) { return str; } -Stream *Stream::makeFilter(const char *name, Stream *str, Object *params) { +Stream *Stream::makeFilter(char *name, Stream *str, Object *params) { int pred; // parameters int colors; int bits; @@ -267,8 +265,8 @@ Stream *Stream::makeFilter(const char *name, Stream *str, Object *params) { // BaseStream //------------------------------------------------------------------------ -BaseStream::BaseStream(Object *ndict) { - dict = *ndict; +BaseStream::BaseStream(Object *dictA) { + dict = *dictA; #ifndef NO_DECRYPTION decrypt = NULL; #endif @@ -283,8 +281,9 @@ BaseStream::~BaseStream() { } #ifndef NO_DECRYPTION -void BaseStream::doDecryption(Guchar *fileKey, int objNum, int objGen) { - decrypt = new Decrypt(fileKey, objNum, objGen); +void BaseStream::doDecryption(Guchar *fileKey, int keyLength, + int objNum, int objGen) { + decrypt = new Decrypt(fileKey, keyLength, objNum, objGen); } #endif @@ -292,8 +291,8 @@ void BaseStream::doDecryption(Guchar *fileKey, int objNum, int objGen) { // FilterStream //------------------------------------------------------------------------ -FilterStream::FilterStream(Stream *nstr) { - str = nstr; +FilterStream::FilterStream(Stream *strA) { + str = strA; } FilterStream::~FilterStream() { @@ -304,8 +303,6 @@ void FilterStream::close() { } void FilterStream::setPos(int pos) { - (void)pos; - error(-1, "Internal: called setPos() on FilterStream"); } @@ -313,13 +310,13 @@ void FilterStream::setPos(int pos) { // ImageStream //------------------------------------------------------------------------ -ImageStream::ImageStream(Stream *nstr, int nwidth, int nnComps, int nnBits) { +ImageStream::ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA) { int imgLineSize; - str = nstr; - width = nwidth; - nComps = nnComps; - nBits = nnBits; + str = strA; + width = widthA; + nComps = nCompsA; + nBits = nBitsA; nVals = width * nComps; if (nBits == 1) { @@ -400,13 +397,13 @@ void ImageStream::skipLine() { // StreamPredictor //------------------------------------------------------------------------ -StreamPredictor::StreamPredictor(Stream *nstr, int npredictor, - int nwidth, int nnComps, int nnBits) { - str = nstr; - predictor = npredictor; - width = nwidth; - nComps = nnComps; - nBits = nnBits; +StreamPredictor::StreamPredictor(Stream *strA, int predictorA, + int widthA, int nCompsA, int nBitsA) { + str = strA; + predictor = predictorA; + width = widthA; + nComps = nCompsA; + nBits = nBitsA; nVals = width * nComps; pixBytes = (nComps * nBits + 7) >> 3; @@ -556,11 +553,11 @@ GBool StreamPredictor::getNextLine() { // FileStream //------------------------------------------------------------------------ -FileStream::FileStream(FILE *nf, int nstart, int nlength, Object *dict): - BaseStream(dict) { - f = nf; - start = nstart; - length = nlength; +FileStream::FileStream(FILE *fA, int startA, int lengthA, Object *dictA): + BaseStream(dictA) { + f = fA; + start = startA; + length = lengthA; bufPtr = bufEnd = buf; bufPos = start; savePos = -1; @@ -570,8 +567,8 @@ FileStream::~FileStream() { close(); } -Stream *FileStream::makeSubStream(int nstart, int nlength, Object *ndict) { - return new FileStream(f, nstart, nlength, ndict); +Stream *FileStream::makeSubStream(int startA, int lengthA, Object *dictA) { + return new FileStream(f, startA, lengthA, dictA); } void FileStream::reset() { @@ -623,25 +620,29 @@ GBool FileStream::fillBuf() { return gTrue; } -void FileStream::setPos(int pos1) { +void FileStream::setPos(int pos) { long size; - if (pos1 >= 0) { - fseek(f, pos1, SEEK_SET); - bufPos = pos1; + if (pos >= 0) { + fseek(f, pos, SEEK_SET); + bufPos = pos; } else { fseek(f, 0, SEEK_END); size = ftell(f); - if (pos1 < -size) - pos1 = (int)(-size); - fseek(f, pos1, SEEK_END); + if (pos < -size) + pos = (int)(-size); +#ifdef __CYGWIN32__ + //~ work around a bug in cygwin's implementation of fseek + rewind(f); +#endif + fseek(f, pos, SEEK_END); bufPos = (int)ftell(f); } bufPtr = bufEnd = buf; } void FileStream::moveStart(int delta) { - this->start += delta; + start += delta; bufPtr = bufEnd = buf; bufPos = start; } @@ -650,26 +651,20 @@ void FileStream::moveStart(int delta) { // EmbedStream //------------------------------------------------------------------------ -EmbedStream::EmbedStream(Stream *nstr, Object *ndict): - BaseStream(ndict) { - str = nstr; +EmbedStream::EmbedStream(Stream *strA, Object *dictA): + BaseStream(dictA) { + str = strA; } EmbedStream::~EmbedStream() { } -Stream *EmbedStream::makeSubStream(int start, int length, Object *ndict) { - (void)start; - (void)length; - (void)ndict; - +Stream *EmbedStream::makeSubStream(int start, int length, Object *dictA) { error(-1, "Internal: called makeSubStream() on EmbedStream"); return NULL; } void EmbedStream::setPos(int pos) { - (void)pos; - error(-1, "Internal: called setPos() on EmbedStream"); } @@ -679,8 +674,6 @@ int EmbedStream::getStart() { } void EmbedStream::moveStart(int start) { - (void)start; - error(-1, "Internal: called moveStart() on EmbedStream"); } @@ -688,8 +681,8 @@ void EmbedStream::moveStart(int start) { // ASCIIHexStream //------------------------------------------------------------------------ -ASCIIHexStream::ASCIIHexStream(Stream *str): - FilterStream(str) { +ASCIIHexStream::ASCIIHexStream(Stream *strA): + FilterStream(strA) { buf = EOF; eof = gFalse; } @@ -757,17 +750,17 @@ int ASCIIHexStream::lookChar() { return buf; } -GString *ASCIIHexStream::getPSFilter(const char *indent) { +GString *ASCIIHexStream::getPSFilter(char *indent) { GString *s; - s = str->getPSFilter(indent); + if (!(s = str->getPSFilter(indent))) { + return NULL; + } s->append(indent)->append("/ASCIIHexDecode filter\n"); return s; } GBool ASCIIHexStream::isBinary(GBool last) { - (void)last; - return str->isBinary(gFalse); } @@ -775,8 +768,8 @@ GBool ASCIIHexStream::isBinary(GBool last) { // ASCII85Stream //------------------------------------------------------------------------ -ASCII85Stream::ASCII85Stream(Stream *str): - FilterStream(str) { +ASCII85Stream::ASCII85Stream(Stream *strA): + FilterStream(strA) { index = n = 0; eof = gFalse; } @@ -835,17 +828,17 @@ int ASCII85Stream::lookChar() { return b[index]; } -GString *ASCII85Stream::getPSFilter(const char *indent) { +GString *ASCII85Stream::getPSFilter(char *indent) { GString *s; - s = str->getPSFilter(indent); + if (!(s = str->getPSFilter(indent))) { + return NULL; + } s->append(indent)->append("/ASCII85Decode filter\n"); return s; } GBool ASCII85Stream::isBinary(GBool last) { - (void)last; - return str->isBinary(gFalse); } @@ -853,15 +846,15 @@ GBool ASCII85Stream::isBinary(GBool last) { // LZWStream //------------------------------------------------------------------------ -LZWStream::LZWStream(Stream *str, int predictor1, int columns1, int colors1, - int bits1, int early1): - FilterStream(str) { - if (predictor1 != 1) { - pred = new StreamPredictor(this, predictor1, columns1, colors1, bits1); +LZWStream::LZWStream(Stream *strA, int predictor, int columns, int colors, + int bits, int earlyA): + FilterStream(strA) { + if (predictor != 1) { + pred = new StreamPredictor(this, predictor, columns, colors, bits); } else { pred = NULL; } - early = early1; + early = earlyA; zPipe = NULL; bufPtr = bufEnd = buf; } @@ -1149,20 +1142,20 @@ GBool LZWStream::fillBuf() { return n > 0; } -GString *LZWStream::getPSFilter(const char *indent) { +GString *LZWStream::getPSFilter(char *indent) { GString *s; if (pred) { return NULL; } - s = str->getPSFilter(indent); + if (!(s = str->getPSFilter(indent))) { + return NULL; + } s->append(indent)->append("/LZWDecode filter\n"); return s; } GBool LZWStream::isBinary(GBool last) { - (void)last; - return str->isBinary(gTrue); } @@ -1170,8 +1163,8 @@ GBool LZWStream::isBinary(GBool last) { // RunLengthStream //------------------------------------------------------------------------ -RunLengthStream::RunLengthStream(Stream *str): - FilterStream(str) { +RunLengthStream::RunLengthStream(Stream *strA): + FilterStream(strA) { bufPtr = bufEnd = buf; eof = gFalse; } @@ -1186,17 +1179,17 @@ void RunLengthStream::reset() { eof = gFalse; } -GString *RunLengthStream::getPSFilter(const char *indent) { +GString *RunLengthStream::getPSFilter(char *indent) { GString *s; - s = str->getPSFilter(indent); + if (!(s = str->getPSFilter(indent))) { + return NULL; + } s->append(indent)->append("/RunLengthDecode filter\n"); return s; } GBool RunLengthStream::isBinary(GBool last) { - (void)last; - return str->isBinary(gTrue); } @@ -1230,17 +1223,17 @@ GBool RunLengthStream::fillBuf() { // CCITTFaxStream //------------------------------------------------------------------------ -CCITTFaxStream::CCITTFaxStream(Stream *str, int nencoding, GBool nendOfLine, - GBool nbyteAlign, int ncolumns, int nrows, - GBool nendOfBlock, GBool nblack): - FilterStream(str) { - encoding = nencoding; - endOfLine = nendOfLine; - byteAlign = nbyteAlign; - columns = ncolumns; - rows = nrows; - endOfBlock = nendOfBlock; - black = nblack; +CCITTFaxStream::CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA, + GBool byteAlignA, int columnsA, int rowsA, + GBool endOfBlockA, GBool blackA): + FilterStream(strA) { + encoding = encodingA; + endOfLine = endOfLineA; + byteAlign = byteAlignA; + columns = columnsA; + rows = rowsA; + endOfBlock = endOfBlockA; + black = blackA; refLine = (short *)gmalloc((columns + 3) * sizeof(short)); codingLine = (short *)gmalloc((columns + 2) * sizeof(short)); @@ -1736,11 +1729,13 @@ short CCITTFaxStream::lookBits(int n) { return (inputBuf >> (inputBits - n)) & (0xffff >> (16 - n)); } -GString *CCITTFaxStream::getPSFilter(const char *indent) { +GString *CCITTFaxStream::getPSFilter(char *indent) { GString *s; char s1[50]; - s = str->getPSFilter(indent); + if (!(s = str->getPSFilter(indent))) { + return NULL; + } s->append(indent)->append("<< "); if (encoding != 0) { sprintf(s1, "/K %d ", encoding); @@ -1769,8 +1764,6 @@ GString *CCITTFaxStream::getPSFilter(const char *indent) { } GBool CCITTFaxStream::isBinary(GBool last) { - (void)last; - return str->isBinary(gTrue); } @@ -1832,8 +1825,8 @@ static int dctZigZag[64] = { 63 }; -DCTStream::DCTStream(Stream *str): - FilterStream(str) { +DCTStream::DCTStream(Stream *strA): + FilterStream(strA) { int i, j; width = height = 0; @@ -2729,17 +2722,17 @@ int DCTStream::read16() { return (c1 << 8) + c2; } -GString *DCTStream::getPSFilter(const char *indent) { +GString *DCTStream::getPSFilter(char *indent) { GString *s; - s = str->getPSFilter(indent); + if (!(s = str->getPSFilter(indent))) { + return NULL; + } s->append(indent)->append("<< >> /DCTDecode filter\n"); return s; } GBool DCTStream::isBinary(GBool last) { - (void)last; - return str->isBinary(gTrue); } @@ -2816,11 +2809,11 @@ FlateDecode FlateStream::distDecode[flateMaxDistCodes] = { {13, 24577} }; -FlateStream::FlateStream(Stream *str, int predictor1, int columns1, - int colors1, int bits1): - FilterStream(str) { - if (predictor1 != 1) { - pred = new StreamPredictor(this, predictor1, columns1, colors1, bits1); +FlateStream::FlateStream(Stream *strA, int predictor, int columns, + int colors, int bits): + FilterStream(strA) { + if (predictor != 1) { + pred = new StreamPredictor(this, predictor, columns, colors, bits); } else { pred = NULL; } @@ -2915,15 +2908,11 @@ int FlateStream::getRawChar() { return c; } -GString *FlateStream::getPSFilter(const char *indent) { - (void)indent; - +GString *FlateStream::getPSFilter(char *indent) { return NULL; } GBool FlateStream::isBinary(GBool last) { - (void)last; - return str->isBinary(gTrue); } @@ -3252,8 +3241,8 @@ int FlateStream::getCodeWord(int bits) { // EOFStream //------------------------------------------------------------------------ -EOFStream::EOFStream(Stream *str): - FilterStream(str) { +EOFStream::EOFStream(Stream *strA): + FilterStream(strA) { } EOFStream::~EOFStream() { @@ -3264,9 +3253,9 @@ EOFStream::~EOFStream() { // FixedLengthEncoder //------------------------------------------------------------------------ -FixedLengthEncoder::FixedLengthEncoder(Stream *str, int length1): - FilterStream(str) { - length = length1; +FixedLengthEncoder::FixedLengthEncoder(Stream *strA, int lengthA): + FilterStream(strA) { + length = lengthA; count = 0; } @@ -3300,8 +3289,8 @@ int FixedLengthEncoder::lookChar() { // ASCII85Encoder //------------------------------------------------------------------------ -ASCII85Encoder::ASCII85Encoder(Stream *str): - FilterStream(str) { +ASCII85Encoder::ASCII85Encoder(Stream *strA): + FilterStream(strA) { bufPtr = bufEnd = buf; lineLen = 0; eof = gFalse; @@ -3372,8 +3361,8 @@ GBool ASCII85Encoder::fillBuf() { // RunLengthEncoder //------------------------------------------------------------------------ -RunLengthEncoder::RunLengthEncoder(Stream *str): - FilterStream(str) { +RunLengthEncoder::RunLengthEncoder(Stream *strA): + FilterStream(strA) { bufPtr = bufEnd = nextEnd = buf; eof = gFalse; } @@ -3434,7 +3423,6 @@ GBool RunLengthEncoder::fillBuf() { c = 0; // make gcc happy if (c1 == c2) { n = 2; - c = 0; // suppress bogus compiler warning while (n < 128 && (c = str->getChar()) == c1) ++n; buf[0] = (char)(257 - n); diff --git a/pdftops/Stream.h b/pdftops/Stream.h index f77bade503..1f9c561d19 100644 --- a/pdftops/Stream.h +++ b/pdftops/Stream.h @@ -79,10 +79,10 @@ public: virtual int getPos() = 0; // Go to a position in the stream. - virtual void setPos(int pos1) = 0; + virtual void setPos(int pos) = 0; // Get PostScript command for the filter(s). - virtual GString *getPSFilter(const char *indent); + virtual GString *getPSFilter(char *indent); // Does this stream type potentially contain non-printable chars? virtual GBool isBinary(GBool last = gTrue) = 0; @@ -102,7 +102,7 @@ public: private: - Stream *makeFilter(const char *name, Stream *str, Object *params); + Stream *makeFilter(char *name, Stream *str, Object *params); int ref; // reference count }; @@ -116,10 +116,10 @@ private: class BaseStream: public Stream { public: - BaseStream(Object *dict); + BaseStream(Object *dictA); virtual ~BaseStream(); virtual Stream *makeSubStream(int start, int length, Object *dict) = 0; - virtual void setPos(int pos1) = 0; + virtual void setPos(int pos) = 0; virtual BaseStream *getBaseStream() { return this; } virtual Dict *getDict() { return dict.getDict(); } @@ -129,7 +129,7 @@ public: #ifndef NO_DECRYPTION // Set decryption for this stream. - void doDecryption(Guchar *fileKey, int objNum, int objGen); + void doDecryption(Guchar *fileKey, int keyLength, int objNum, int objGen); #endif #ifndef NO_DECRYPTION @@ -152,7 +152,7 @@ private: class FilterStream: public Stream { public: - FilterStream(Stream *str); + FilterStream(Stream *strA); virtual ~FilterStream(); virtual void close(); virtual int getPos() { return str->getPos(); } @@ -175,7 +175,7 @@ public: // Create an image stream object for an image with the specified // parameters. Note that these are the actual image parameters, // which may be different from the predictor parameters. - ImageStream(Stream *str, int width, int nComps, int nBits); + ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA); ~ImageStream(); @@ -209,8 +209,8 @@ public: // Create a predictor object. Note that the parameters are for the // predictor, and may not match the actual image parameters. - StreamPredictor(Stream *str, int predictor, - int width, int nComps, int nBits); + StreamPredictor(Stream *strA, int predictorA, + int widthA, int nCompsA, int nBitsA); ~StreamPredictor(); @@ -242,9 +242,9 @@ private: class FileStream: public BaseStream { public: - FileStream(FILE *f, int start, int length, Object *dict); + FileStream(FILE *fA, int startA, int lengthA, Object *dictA); virtual ~FileStream(); - virtual Stream *makeSubStream(int start, int length, Object *dict); + virtual Stream *makeSubStream(int startA, int lengthA, Object *dictA); virtual StreamKind getKind() { return strFile; } virtual void reset(); virtual void close(); @@ -253,7 +253,7 @@ public: virtual int lookChar() { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } virtual int getPos() { return bufPos + (bufPtr - buf); } - virtual void setPos(int pos1); + virtual void setPos(int pos); virtual GBool isBinary(GBool last = gTrue) { return last; } virtual int getStart() { return start; } virtual void moveStart(int delta); @@ -285,9 +285,9 @@ private: class EmbedStream: public BaseStream { public: - EmbedStream(Stream *str, Object *dict); + EmbedStream(Stream *strA, Object *dictA); virtual ~EmbedStream(); - virtual Stream *makeSubStream(int start, int length, Object *dict); + virtual Stream *makeSubStream(int start, int length, Object *dictA); virtual StreamKind getKind() { return str->getKind(); } virtual void reset() {} virtual int getChar() { return str->getChar(); } @@ -310,14 +310,14 @@ private: class ASCIIHexStream: public FilterStream { public: - ASCIIHexStream(Stream *str); + ASCIIHexStream(Stream *strA); virtual ~ASCIIHexStream(); virtual StreamKind getKind() { return strASCIIHex; } virtual void reset(); virtual int getChar() { int c = lookChar(); buf = EOF; return c; } virtual int lookChar(); - virtual GString *getPSFilter(const char *indent); + virtual GString *getPSFilter(char *indent); virtual GBool isBinary(GBool last = gTrue); private: @@ -333,14 +333,14 @@ private: class ASCII85Stream: public FilterStream { public: - ASCII85Stream(Stream *str); + ASCII85Stream(Stream *strA); virtual ~ASCII85Stream(); virtual StreamKind getKind() { return strASCII85; } virtual void reset(); virtual int getChar() { int ch = lookChar(); ++index; return ch; } virtual int lookChar(); - virtual GString *getPSFilter(const char *indent); + virtual GString *getPSFilter(char *indent); virtual GBool isBinary(GBool last = gTrue); private: @@ -358,15 +358,15 @@ private: class LZWStream: public FilterStream { public: - LZWStream(Stream *str, int predictor1, int columns1, int colors1, - int bits1, int early1); + LZWStream(Stream *strA, int predictor, int columns, int colors, + int bits, int earlyA); virtual ~LZWStream(); virtual StreamKind getKind() { return strLZW; } virtual void reset(); virtual int getChar(); virtual int lookChar(); virtual int getRawChar(); - virtual GString *getPSFilter(const char *indent); + virtual GString *getPSFilter(char *indent); virtual GBool isBinary(GBool last = gTrue); private: @@ -394,7 +394,7 @@ private: class RunLengthStream: public FilterStream { public: - RunLengthStream(Stream *str); + RunLengthStream(Stream *strA); virtual ~RunLengthStream(); virtual StreamKind getKind() { return strRunLength; } virtual void reset(); @@ -402,7 +402,7 @@ public: { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } virtual int lookChar() { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } - virtual GString *getPSFilter(const char *indent); + virtual GString *getPSFilter(char *indent); virtual GBool isBinary(GBool last = gTrue); private: @@ -424,16 +424,16 @@ struct CCITTCodeTable; class CCITTFaxStream: public FilterStream { public: - CCITTFaxStream(Stream *str, int encoding, GBool endOfLine, - GBool byteAlign, int columns, int rows, - GBool endOfBlock, GBool black); + CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA, + GBool byteAlignA, int columnsA, int rowsA, + GBool endOfBlockA, GBool blackA); virtual ~CCITTFaxStream(); virtual StreamKind getKind() { return strCCITTFax; } virtual void reset(); virtual int getChar() { int c = lookChar(); buf = EOF; return c; } virtual int lookChar(); - virtual GString *getPSFilter(const char *indent); + virtual GString *getPSFilter(char *indent); virtual GBool isBinary(GBool last = gTrue); private: @@ -489,13 +489,13 @@ struct DCTHuffTable { class DCTStream: public FilterStream { public: - DCTStream(Stream *str); + DCTStream(Stream *strA); virtual ~DCTStream(); virtual StreamKind getKind() { return strDCT; } virtual void reset(); virtual int getChar(); virtual int lookChar(); - virtual GString *getPSFilter(const char *indent); + virtual GString *getPSFilter(char *indent); virtual GBool isBinary(GBool last = gTrue); Stream *getRawStream() { return str; } @@ -573,15 +573,15 @@ struct FlateDecode { class FlateStream: public FilterStream { public: - FlateStream(Stream *str, int predictor1, int columns1, - int colors1, int bits1); + FlateStream(Stream *strA, int predictor, int columns, + int colors, int bits); virtual ~FlateStream(); virtual StreamKind getKind() { return strFlate; } virtual void reset(); virtual int getChar(); virtual int lookChar(); virtual int getRawChar(); - virtual GString *getPSFilter(const char *indent); + virtual GString *getPSFilter(char *indent); virtual GBool isBinary(GBool last = gTrue); private: @@ -624,14 +624,14 @@ private: class EOFStream: public FilterStream { public: - EOFStream(Stream *str); + EOFStream(Stream *strA); virtual ~EOFStream(); virtual StreamKind getKind() { return strWeird; } virtual void reset() {} virtual int getChar() { return EOF; } virtual int lookChar() { return EOF; } - virtual GString *getPSFilter(const char *indent) { (void)indent; return NULL; } - virtual GBool isBinary(GBool last = gTrue) { (void)last; return gFalse; } + virtual GString *getPSFilter(char *indent) { return NULL; } + virtual GBool isBinary(GBool last = gTrue) { return gFalse; } }; //------------------------------------------------------------------------ @@ -641,15 +641,15 @@ public: class FixedLengthEncoder: public FilterStream { public: - FixedLengthEncoder(Stream *str, int length1); + FixedLengthEncoder(Stream *strA, int lengthA); ~FixedLengthEncoder(); virtual StreamKind getKind() { return strWeird; } virtual void reset(); virtual void close(); virtual int getChar(); virtual int lookChar(); - virtual GString *getPSFilter(const char *indent) { (void)indent; return NULL; } - virtual GBool isBinary(GBool last = gTrue) { (void)last; return gFalse; } + virtual GString *getPSFilter(char *indent) { return NULL; } + virtual GBool isBinary(GBool last = gTrue) { return gFalse; } virtual GBool isEncoder() { return gTrue; } private: @@ -665,7 +665,7 @@ private: class ASCII85Encoder: public FilterStream { public: - ASCII85Encoder(Stream *str); + ASCII85Encoder(Stream *strA); virtual ~ASCII85Encoder(); virtual StreamKind getKind() { return strWeird; } virtual void reset(); @@ -674,8 +674,8 @@ public: { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } virtual int lookChar() { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } - virtual GString *getPSFilter(const char *indent) { (void)indent; return NULL; } - virtual GBool isBinary(GBool last = gTrue) { (void)last; return gFalse; } + virtual GString *getPSFilter(char *indent) { return NULL; } + virtual GBool isBinary(GBool last = gTrue) { return gFalse; } virtual GBool isEncoder() { return gTrue; } private: @@ -696,7 +696,7 @@ private: class RunLengthEncoder: public FilterStream { public: - RunLengthEncoder(Stream *str); + RunLengthEncoder(Stream *strA); virtual ~RunLengthEncoder(); virtual StreamKind getKind() { return strWeird; } virtual void reset(); @@ -705,8 +705,8 @@ public: { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } virtual int lookChar() { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } - virtual GString *getPSFilter(const char *indent) { (void)indent; return NULL; } - virtual GBool isBinary(GBool last = gTrue) { (void)last; return gFalse; } + virtual GString *getPSFilter(char *indent) { return NULL; } + virtual GBool isBinary(GBool last = gTrue) { return gFalse; } virtual GBool isEncoder() { return gTrue; } private: diff --git a/pdftops/T1Font.h b/pdftops/T1Font.h index 9ead397f62..846d253e9f 100644 --- a/pdftops/T1Font.h +++ b/pdftops/T1Font.h @@ -26,8 +26,8 @@ class FontEncoding; class T1FontEngine: public SFontEngine { public: - T1FontEngine(Display *display, Visual *visual, int depth, - Colormap colormap, GBool aa, GBool aaHigh); + T1FontEngine(Display *displayA, Visual *visualA, int depthA, + Colormap colormapA, GBool aaA, GBool aaHighA); GBool isOk() { return ok; } virtual ~T1FontEngine(); @@ -35,7 +35,6 @@ private: GBool aa; // use anti-aliasing? GBool aaHigh; // use high-res anti-aliasing? - GBool bigEndian; GBool ok; friend class T1FontFile; @@ -47,8 +46,8 @@ private: class T1FontFile: public SFontFile { public: - T1FontFile(T1FontEngine *engine, char *fontFileName, - FontEncoding *fontEnc); + T1FontFile(T1FontEngine *engineA, char *fontFileName, + FontEncoding *fontEnc, double *bboxA); GBool isOk() { return ok; } virtual ~T1FontFile(); @@ -58,6 +57,7 @@ private: int id; // t1lib font ID char **enc; char *encStr; + double bbox[4]; GBool ok; friend class T1Font; @@ -74,7 +74,7 @@ struct T1FontCacheTag { class T1Font: public SFont { public: - T1Font(T1FontFile *fontFile, double *m); + T1Font(T1FontFile *fontFileA, double *m); GBool isOk() { return ok; } virtual ~T1Font(); virtual GBool drawChar(Drawable d, int w, int h, GC gc, diff --git a/pdftops/TTFont.h b/pdftops/TTFont.h index 68e5d97364..998087c9c7 100644 --- a/pdftops/TTFont.h +++ b/pdftops/TTFont.h @@ -9,20 +9,18 @@ #ifndef TTFONT_H #define TTFONT_H -#if HAVE_FREETYPE_FREETYPE_H +#if !FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H) #ifdef __GNUC__ #pragma interface #endif -#ifdef VMS -#include -#include -#else -//~ This will be going away; the configure script will add -//~ -I/freetype to CFLAGS. +#if HAVE_FREETYPE_FREETYPE_H #include #include +#else +#include +#include #endif #include "SFont.h" @@ -31,8 +29,8 @@ class TTFontEngine: public SFontEngine { public: - TTFontEngine(Display *display, Visual *visual, int depth, - Colormap colormap, GBool aa); + TTFontEngine(Display *displayA, Visual *visualA, int depthA, + Colormap colormapA, GBool aaA); GBool isOk() { return ok; } virtual ~TTFontEngine(); @@ -52,7 +50,7 @@ private: class TTFontFile: public SFontFile { public: - TTFontFile(TTFontEngine *engine, char *fontFileName); + TTFontFile(TTFontEngine *engineA, char *fontFileName); GBool isOk() { return ok; } virtual ~TTFontFile(); @@ -77,7 +75,7 @@ struct TTFontCacheTag { class TTFont: public SFont { public: - TTFont(TTFontFile *fontFile, double *m); + TTFont(TTFontFile *fontFileA, double *m); GBool isOk() { return ok; } virtual ~TTFont(); virtual GBool drawChar(Drawable d, int w, int h, GC gc, @@ -101,6 +99,6 @@ private: GBool ok; }; -#endif // HAVE_FREETYPE_FREETYPE_H +#endif // !FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H) #endif diff --git a/pdftops/XRef.cxx b/pdftops/XRef.cxx index d70b9f2097..de2db2f23b 100644 --- a/pdftops/XRef.cxx +++ b/pdftops/XRef.cxx @@ -43,18 +43,11 @@ #define defPermFlags 0xfffc #endif -//------------------------------------------------------------------------ -// The global xref table -//------------------------------------------------------------------------ - -XRef *xref = NULL; - //------------------------------------------------------------------------ // XRef //------------------------------------------------------------------------ -XRef::XRef(BaseStream *str, GString *userPassword) { - XRef *oldXref; +XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) { int pos; int i; @@ -64,13 +57,8 @@ XRef::XRef(BaseStream *str, GString *userPassword) { streamEnds = NULL; streamEndsLen = 0; - // get rid of old xref (otherwise it will try to fetch the Root object - // in the new document, using the old xref) - oldXref = xref; - xref = NULL; - // read the trailer - this->str = str; + str = strA; start = str->getStart(); pos = readTrailer(); @@ -78,7 +66,6 @@ XRef::XRef(BaseStream *str, GString *userPassword) { // try to reconstruct the xref table if (pos == 0) { if (!(ok = constructXRef())) { - xref = oldXref; return; } @@ -98,22 +85,21 @@ XRef::XRef(BaseStream *str, GString *userPassword) { size = 0; entries = NULL; if (!(ok = constructXRef())) { - xref = oldXref; return; } } } - // set up new xref table - xref = this; + // now set the trailer dictionary's xref pointer so we can fetch + // indirect objects from it + trailerDict.getDict()->setXRef(this); // check for encryption #ifndef NO_DECRYPTION encrypted = gFalse; #endif - if (checkEncrypted(userPassword)) { + if (checkEncrypted(ownerPassword, userPassword)) { ok = gFalse; - xref = oldXref; return; } } @@ -189,7 +175,8 @@ int XRef::readTrailer() { // read trailer dict obj.initNull(); - parser = new Parser(new Lexer(str->makeSubStream(start + pos1, -1, &obj))); + parser = new Parser(NULL, new Lexer(NULL, str->makeSubStream(start + pos1, + -1, &obj))); parser->getObj(&trailerDict); if (trailerDict.isDict()) { trailerDict.dictLookupNF("Size", &obj); @@ -221,7 +208,7 @@ GBool XRef::readXRef(int *pos) { Object obj, obj2; char s[20]; GBool more; - int first, n, i, j; + int first, newSize, n, i, j; int c; // seek to xref in stream @@ -233,35 +220,56 @@ GBool XRef::readXRef(int *pos) { s[1] = (char)str->getChar(); s[2] = (char)str->getChar(); s[3] = (char)str->getChar(); - if (!(s[0] == 'x' && s[1] == 'r' && s[2] == 'e' && s[3] == 'f')) + if (!(s[0] == 'x' && s[1] == 'r' && s[2] == 'e' && s[3] == 'f')) { goto err2; + } // read xref while (1) { - while ((c = str->lookChar()) != EOF && isspace(c)) + while ((c = str->lookChar()) != EOF && isspace(c)) { str->getChar(); - if (c == 't') + } + if (c == 't') { break; - for (i = 0; (c = str->getChar()) != EOF && isdigit(c) && i < 20; ++i) + } + for (i = 0; (c = str->getChar()) != EOF && isdigit(c) && i < 20; ++i) { s[i] = (char)c; - if (i == 0) + } + if (i == 0) { goto err2; + } s[i] = '\0'; first = atoi(s); - while ((c = str->lookChar()) != EOF && isspace(c)) + while ((c = str->lookChar()) != EOF && isspace(c)) { str->getChar(); - for (i = 0; (c = str->getChar()) != EOF && isdigit(c) && i < 20; ++i) + } + for (i = 0; (c = str->getChar()) != EOF && isdigit(c) && i < 20; ++i) { s[i] = (char)c; - if (i == 0) + } + if (i == 0) { goto err2; + } s[i] = '\0'; n = atoi(s); - while ((c = str->lookChar()) != EOF && isspace(c)) + while ((c = str->lookChar()) != EOF && isspace(c)) { str->getChar(); + } + // check for buggy PDF files with an incorrect (too small) xref + // table size + if (first + n > size) { + newSize = size + 256; + entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry)); + for (i = size; i < newSize; ++i) { + entries[i].offset = -1; + entries[i].used = gFalse; + } + size = newSize; + } for (i = first; i < first + n; ++i) { for (j = 0; j < 20; ++j) { - if ((c = str->getChar()) == EOF) + if ((c = str->getChar()) == EOF) { goto err2; + } s[j] = (char)c; } if (entries[i].offset < 0) { @@ -269,16 +277,16 @@ GBool XRef::readXRef(int *pos) { entries[i].offset = atoi(s); s[16] = '\0'; entries[i].gen = atoi(&s[11]); - if (s[17] == 'n') + if (s[17] == 'n') { entries[i].used = gTrue; - else if (s[17] == 'f') + } else if (s[17] == 'f') { entries[i].used = gFalse; - else + } else { goto err2; -#if 1 //~ - //~ PDF files of patents from the IBM Intellectual Property - //~ Network have a bug: the xref table claims to start at 1 - //~ instead of 0. + } + // PDF files of patents from the IBM Intellectual Property + // Network have a bug: the xref table claims to start at 1 + // instead of 0. if (i == 1 && first == 1 && entries[1].offset == 0 && entries[1].gen == 65535 && !entries[1].used) { @@ -286,21 +294,23 @@ GBool XRef::readXRef(int *pos) { entries[0] = entries[1]; entries[1].offset = -1; } -#endif } } } // read prev pointer from trailer dictionary obj.initNull(); - parser = new Parser(new Lexer(str->makeSubStream(str->getPos(), -1, &obj))); + parser = new Parser(NULL, new Lexer(NULL, str->makeSubStream(str->getPos(), + -1, &obj))); parser->getObj(&obj); - if (!obj.isCmd("trailer")) + if (!obj.isCmd("trailer")) { goto err1; + } obj.free(); parser->getObj(&obj); - if (!obj.isDict()) + if (!obj.isDict()) { goto err1; + } obj.getDict()->lookupNF("Prev", &obj2); if (obj2.isInt()) { *pos = obj2.getInt(); @@ -349,7 +359,7 @@ GBool XRef::constructXRef() { // got trailer dictionary if (!strncmp(p, "trailer", 7)) { obj.initNull(); - parser = new Parser(new Lexer( + parser = new Parser(NULL, new Lexer(NULL, str->makeSubStream(start + pos + 7, -1, &obj))); if (!trailerDict.isNone()) trailerDict.free(); @@ -424,8 +434,9 @@ GBool XRef::constructXRef() { } #ifndef NO_DECRYPTION -GBool XRef::checkEncrypted(GString *userPassword) { - Object encrypt, ownerKey, userKey, permissions, fileID, fileID1; +GBool XRef::checkEncrypted(GString *ownerPassword, GString *userPassword) { + Object encrypt, filterObj, versionObj, revisionObj, lengthObj; + Object ownerKey, userKey, permissions, fileID, fileID1; GBool encrypted1; GBool ret; @@ -435,35 +446,68 @@ GBool XRef::checkEncrypted(GString *userPassword) { trailerDict.dictLookup("Encrypt", &encrypt); if ((encrypted1 = encrypt.isDict())) { ret = gTrue; - encrypt.dictLookup("O", &ownerKey); - encrypt.dictLookup("U", &userKey); - encrypt.dictLookup("P", &permissions); - trailerDict.dictLookup("ID", &fileID); - if (ownerKey.isString() && ownerKey.getString()->getLength() == 32 && - userKey.isString() && userKey.getString()->getLength() == 32 && - permissions.isInt() && - fileID.isArray()) { - permFlags = permissions.getInt(); - fileID.arrayGet(0, &fileID1); - if (fileID1.isString()) { - if (Decrypt::makeFileKey(ownerKey.getString(), userKey.getString(), - permFlags, fileID1.getString(), - userPassword, fileKey)) { - ret = gFalse; + encrypt.dictLookup("Filter", &filterObj); + if (filterObj.isName("Standard")) { + encrypt.dictLookup("V", &versionObj); + encrypt.dictLookup("R", &revisionObj); + encrypt.dictLookup("Length", &lengthObj); + encrypt.dictLookup("O", &ownerKey); + encrypt.dictLookup("U", &userKey); + encrypt.dictLookup("P", &permissions); + trailerDict.dictLookup("ID", &fileID); + if (versionObj.isInt() && + revisionObj.isInt() && + ownerKey.isString() && ownerKey.getString()->getLength() == 32 && + userKey.isString() && userKey.getString()->getLength() == 32 && + permissions.isInt() && + fileID.isArray()) { + encVersion = versionObj.getInt(); + encRevision = revisionObj.getInt(); + if (lengthObj.isInt()) { + keyLength = lengthObj.getInt() / 8; + } else { + keyLength = 5; + } + permFlags = permissions.getInt(); + if (encVersion >= 1 && encVersion <= 2 && + encRevision >= 2 && encRevision <= 3) { + fileID.arrayGet(0, &fileID1); + if (fileID1.isString()) { + if (Decrypt::makeFileKey(encVersion, encRevision, keyLength, + ownerKey.getString(), userKey.getString(), + permFlags, fileID1.getString(), + ownerPassword, userPassword, fileKey, + &ownerPasswordOk)) { + if (ownerPassword && !ownerPasswordOk) { + error(-1, "Incorrect owner password"); + } + ret = gFalse; + } else { + error(-1, "Incorrect password"); + } + } else { + error(-1, "Weird encryption info"); + } + fileID1.free(); } else { - error(-1, "Incorrect user password"); + error(-1, "Unsupported version/revision (%d/%d) of Standard security handler", + encVersion, encRevision); } } else { error(-1, "Weird encryption info"); } - fileID1.free(); + fileID.free(); + permissions.free(); + userKey.free(); + ownerKey.free(); + lengthObj.free(); + revisionObj.free(); + versionObj.free(); } else { - error(-1, "Weird encryption info"); + error(-1, "Unknown security handler '%s'", + filterObj.isName() ? filterObj.getName() : "???"); } - ownerKey.free(); - userKey.free(); - permissions.free(); - fileID.free(); + filterObj.free(); } encrypt.free(); @@ -473,52 +517,50 @@ GBool XRef::checkEncrypted(GString *userPassword) { return ret; } #else -GBool XRef::checkEncrypted(GString *userPassword) { +GBool XRef::checkEncrypted(GString *ownerPassword, GString *userPassword) { Object obj; GBool encrypted; trailerDict.dictLookup("Encrypt", &obj); if ((encrypted = !obj.isNull())) { - error(-1, "PDF file is encrypted and cannot be displayed"); - error(-1, "* Decryption support is currently not included in xpdf"); - error(-1, "* due to legal restrictions: the U.S.A. still has bogus"); - error(-1, "* export controls on cryptography software."); + error(-1, "PDF file is encrypted and this version of the Xpdf tools"); + error(-1, "was built without decryption support."); } obj.free(); return encrypted; } #endif -GBool XRef::okToPrint() { +GBool XRef::okToPrint(GBool ignoreOwnerPW) { #ifndef NO_DECRYPTION - if (!(permFlags & permPrint)) { + if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permPrint)) { return gFalse; } #endif return gTrue; } -GBool XRef::okToChange() { +GBool XRef::okToChange(GBool ignoreOwnerPW) { #ifndef NO_DECRYPTION - if (!(permFlags & permChange)) { + if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permChange)) { return gFalse; } #endif return gTrue; } -GBool XRef::okToCopy() { +GBool XRef::okToCopy(GBool ignoreOwnerPW) { #ifndef NO_DECRYPTION - if (!(permFlags & permCopy)) { + if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permCopy)) { return gFalse; } #endif return gTrue; } -GBool XRef::okToAddNotes() { +GBool XRef::okToAddNotes(GBool ignoreOwnerPW) { #ifndef NO_DECRYPTION - if (!(permFlags & permNotes)) { + if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permNotes)) { return gFalse; } #endif @@ -539,7 +581,7 @@ Object *XRef::fetch(int num, int gen, Object *obj) { e = &entries[num]; if (e->gen == gen && e->offset >= 0) { obj1.initNull(); - parser = new Parser(new Lexer( + parser = new Parser(this, new Lexer(this, str->makeSubStream(start + e->offset, -1, &obj1))); parser->getObj(&obj1); parser->getObj(&obj2); @@ -548,7 +590,8 @@ Object *XRef::fetch(int num, int gen, Object *obj) { obj2.isInt() && obj2.getInt() == gen && obj3.isCmd("obj")) { #ifndef NO_DECRYPTION - parser->getObj(obj, encrypted ? fileKey : (Guchar *)NULL, num, gen); + parser->getObj(obj, encrypted ? fileKey : (Guchar *)NULL, keyLength, + num, gen); #else parser->getObj(obj); #endif @@ -569,20 +612,20 @@ Object *XRef::getDocInfo(Object *obj) { return trailerDict.dictLookup("Info", obj); } -int XRef::getStreamEnd(int start) { +int XRef::getStreamEnd(int streamStart) { int a, b, m; if (streamEndsLen == 0 || - start > streamEnds[streamEndsLen - 1]) { + streamStart > streamEnds[streamEndsLen - 1]) { return -1; } a = -1; b = streamEndsLen - 1; - // invariant: streamEnds[a] < start <= streamEnds[b] + // invariant: streamEnds[a] < streamStart <= streamEnds[b] while (b - a > 1) { m = (a + b) / 2; - if (start <= streamEnds[m]) { + if (streamStart <= streamEnds[m]) { b = m; } else { a = m; diff --git a/pdftops/XRef.h b/pdftops/XRef.h index e2260d0c33..35306bba83 100644 --- a/pdftops/XRef.h +++ b/pdftops/XRef.h @@ -33,7 +33,7 @@ class XRef { public: // Constructor. Read xref table from stream. - XRef(BaseStream *str, GString *userPassword); + XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword); // Destructor. ~XRef(); @@ -49,10 +49,10 @@ public: #endif // Check various permissions. - GBool okToPrint(); - GBool okToChange(); - GBool okToCopy(); - GBool okToAddNotes(); + GBool okToPrint(GBool ignoreOwnerPW = gFalse); + GBool okToChange(GBool ignoreOwnerPW = gFalse); + GBool okToCopy(GBool ignoreOwnerPW = gFalse); + GBool okToAddNotes(GBool ignoreOwnerPW = gFalse); // Get catalog object. Object *getCatalog(Object *obj) { return fetch(rootNum, rootGen, obj); } @@ -75,7 +75,7 @@ public: // Get end position for a stream in a damaged file. // Returns -1 if unknown or file is not damaged. - int getStreamEnd(int start); + int getStreamEnd(int streamStart); private: @@ -93,20 +93,18 @@ private: int streamEndsLen; // number of valid entries in streamEnds #ifndef NO_DECRYPTION GBool encrypted; // true if file is encrypted + int encVersion; // encryption algorithm + int encRevision; // security handler revision + int keyLength; // length of key, in bytes int permFlags; // permission bits Guchar fileKey[16]; // file decryption key + GBool ownerPasswordOk; // true if owner password is correct #endif int readTrailer(); GBool readXRef(int *pos); GBool constructXRef(); - GBool checkEncrypted(GString *userPassword); + GBool checkEncrypted(GString *ownerPassword, GString *userPassword); }; -//------------------------------------------------------------------------ -// The global xref table -//------------------------------------------------------------------------ - -extern XRef *xref; - #endif diff --git a/pdftops/config.h b/pdftops/config.h index ff79d1f889..872aadfd03 100644 --- a/pdftops/config.h +++ b/pdftops/config.h @@ -17,14 +17,14 @@ //------------------------------------------------------------------------ // xpdf version -#define xpdfVersion "0.92" +#define xpdfVersion "0.93a" // supported PDF version -#define supportedPDFVersionStr "1.3" -#define supportedPDFVersionNum 1.3 +#define supportedPDFVersionStr "1.4" +#define supportedPDFVersionNum 1.4 // copyright notice -#define xpdfCopyright "Copyright 1996-2000 Derek B. Noonburg" +#define xpdfCopyright "Copyright 1996-2001 Derek B. Noonburg" // default paper size (in points) for PostScript output #ifdef A4_PAPER @@ -35,13 +35,25 @@ #define defPaperHeight 792 #endif -// config file name +// user config file name, relative to the user's home directory #if defined(VMS) -#define xpdfConfigFile "xpdfrc" +#define xpdfUserConfigFile "xpdfrc" #else -#define xpdfConfigFile ".xpdfrc" +#define xpdfUserConfigFile ".xpdfrc" #endif +#ifndef SYSTEM_XPDFRC +# define SYSTEM_XPDFRC CUPS_SERVERROOT "/pdftops.conf" +#endif // SYSTEM_XPDFRC + +// system config file name (set via the configure script) +#define xpdfSysConfigFile SYSTEM_XPDFRC + +// Support Unicode/etc. +#define JAPANESE_SUPPORT 1 +#define CHINESE_GB_SUPPORT 1 +#define CHINESE_CNS_SUPPORT 1 + //------------------------------------------------------------------------ // X-related constants //------------------------------------------------------------------------ @@ -58,6 +70,9 @@ // number of TrueType (FreeType) fonts to cache #define ttFontCacheSize 32 +// number of FreeType (TrueType and Type 1) fonts to cache +#define ftFontCacheSize 32 + //------------------------------------------------------------------------ // popen //------------------------------------------------------------------------ @@ -67,7 +82,7 @@ #define pclose _pclose #endif -#if defined(VMS) || defined(VMCMS) || defined(DOS) || defined(OS2) || defined(WIN32) || defined(__DJGPP__) || defined(__CYGWIN32) || defined(MACOS) +#if defined(VMS) || defined(VMCMS) || defined(DOS) || defined(OS2) || defined(__EMX__) || defined(WIN32) || defined(__DJGPP__) || defined(__CYGWIN32__) || defined(MACOS) #define POPEN_READ_MODE "rb" #else #define POPEN_READ_MODE "r" diff --git a/pdftops/configure.in b/pdftops/configure.in deleted file mode 100644 index 8ba7984758..0000000000 --- a/pdftops/configure.in +++ /dev/null @@ -1,203 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. -AC_INIT(xpdf/xpdf.cc) - -dnl ##### Optional features. -OPTIONS="" -AC_ARG_ENABLE(a4-paper, -[ --enable-a4-paper use A4 paper size instead of Letter for - PostScript output], -OPTIONS="$OPTIONS -DA4_PAPER") -AC_ARG_ENABLE(japanese, -[ --enable-japanese enable Japanese font support], -OPTIONS="$OPTIONS -DJAPANESE_SUPPORT") -AC_ARG_ENABLE(no-text-select, -[ --enable-no-text-select do not allow text selection], -OPTIONS="$OPTIONS -DNO_TEXT_SELECT") -AC_ARG_WITH(gzip, -[ --with-gzip use gzip instead of uncompress], -OPTIONS="$OPTIONS -DUSE_GZIP") -AC_SUBST(OPTIONS) - -dnl ##### Checks for programs. -AC_PROG_CC -AC_ISC_POSIX -AM_PROG_CC_STDC -#if test -z "$CXX" -a "$CC" = "gcc"; then -# CXX="gcc" -#fi -AC_PROG_CXX -AC_PROG_INSTALL -AC_PROG_RANLIB - -dnl ##### Default values for Unix. -EXE="" -LIBPREFIX="lib" -AR="ar rc" -UP_DIR="" - -dnl ##### Check for OS/2. -AC_CACHE_CHECK([for OS/2 (with EMX)], -xpdf_cv_sys_os2, -[AC_TRY_COMPILE([], -[__EMX__], -xpdf_cv_sys_os2=yes, xpdf_cv_sys_os2=no)]) -if test "$xpdf_cv_sys_os2" = yes; then - EXE=".exe" - LIBPREFIX="" - AR="ar -rc" -fi - -dnl ##### Check for DOS (with DJGPP). -AC_CACHE_CHECK([for DOS (with DJGPP)], -xpdf_cv_sys_dos, -[AC_TRY_COMPILE([], -[__DJGPP__], -xpdf_cv_sys_dos=yes, xpdf_cv_sys_dos=no)]) -if test "$xpdf_cv_sys_dos" = yes; then - EXE=".exe" - LIBPREFIX="lib" - AR="ar -rc" - UP_DIR="../" -fi - -dnl ##### Do substitutions. -AC_SUBST(EXE) -AC_SUBST(LIBPREFIX) -AC_SUBST(AR) -AC_SUBST(UP_DIR) - -dnl ##### Checks for header files. -AC_PATH_XTRA -AC_HEADER_DIRENT - -dnl ##### Look for header that defines fd_set. -AC_MSG_CHECKING([fd_set and sys/select.h or sys/bsdtypes.h]) -AC_TRY_COMPILE([#include ], - [fd_set fds;], xpdf_ok=yes, xpdf_ok=no) -if test $xpdf_ok = yes; then - AC_MSG_RESULT([not needed]) -else - AC_TRY_COMPILE([#include -#include ], - [fd_set fds;], xpdf_ok=yes, xpdf_ok=no) - if test $xpdf_ok = yes; then - AC_DEFINE(HAVE_SYS_SELECT_H) - AC_MSG_RESULT([need sys/select.h]) - else - AC_TRY_COMPILE([#include -#include ], - [fd_set fds;], xpdf_ok=yes, xpdf_ok=no) - if test $xpdf_ok = yes; then - AC_DEFINE(HAVE_SYS_BSDTYPES_H) - AC_MSG_RESULT([need sys/bsdtypes.h]) - else - AC_MSG_RESULT([problem]) - fi - fi -fi - -dnl ##### Look for header that defines FD_ZERO. -AC_MSG_CHECKING([FD_ZERO and strings.h or bstring.h]) -AC_TRY_COMPILE([#include -#ifdef HAVE_SYS_SELECT_H -#include -#endif], -[fd_set fds; FD_ZERO(&fds);], xpdf_ok=yes, xpdf_ok=no) -if test $xpdf_ok = yes; then - AC_MSG_RESULT([not needed]) -else - AC_TRY_COMPILE([#include -#include -#ifdef HAVE_SYS_SELECT_H -#include -#endif], - [fd_set fds; FD_ZERO(&fds);], xpdf_ok=yes, xpdf_ok=no) - if test $xpdf_ok = yes; then - AC_DEFINE(HAVE_STRINGS_H) - AC_MSG_RESULT([need strings.h]) - else - AC_TRY_COMPILE([#include -#include -#ifdef HAVE_SYS_SELECT_H -#include -#endif], - [fd_set fds; FD_ZERO(&fds);], xpdf_ok=yes, xpdf_ok=no) - if test $xpdf_ok = yes; then - AC_DEFINE(HAVE_BSTRING_H) - AC_MSG_RESULT([need bstring.h]) - else - AC_MSG_RESULT([problem]) - fi - fi -fi - -dnl ##### Look for rewinddir. -AC_CHECK_FUNCS(rewinddir) -if test $ac_cv_func_rewinddir = no; then - AC_CHECK_LIB(cposix, rewinddir) -fi - -dnl ##### Checks for library functions. -AC_CHECK_FUNCS(popen) - -dnl ##### Check select argument type: on HP-UX before version 10, select -dnl ##### takes (int *) instead of (fd_set *). -AC_LANG_CPLUSPLUS -AC_CACHE_CHECK([whether select takes fd_set arguments], -xpdf_cv_func_select_arg, -[AC_TRY_COMPILE([#include -#include -#ifdef HAVE_SYS_SELECT_H -#include -#endif], -[fd_set fds; -select(1, &fds, &fds, &fds, 0);], -xpdf_cv_func_select_arg=yes, xpdf_cv_func_select_arg=no)]) -if test "$xpdf_cv_func_select_arg" != yes; then - AC_DEFINE(SELECT_TAKES_INT) -fi -AC_LANG_C - -dnl ##### Check for libXpm. -if test -z "$no_x"; then - smr_CHECK_LIB(Xpm, Xpm, [pixmap library, used only for icon], - XpmCreatePixmapFromData, X11/xpm.h, - $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS, $X_CFLAGS) - AC_SUBST(Xpm_LIBS) - AC_SUBST(Xpm_CFLAGS) -fi - -dnl ##### Check for t1lib. -if test -z "$no_x"; then - smr_CHECK_LIB(t1, t1, [Type 1 font rasterizer], - T1_InitLib, t1lib.h, - $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS -lm, $X_CFLAGS) - AC_SUBST(t1_LIBS) - AC_SUBST(t1_CFLAGS) - smr_CHECK_LIB(t1x, t1x, [Type 1 font rasterizer], - T1_SetX11Params, t1libx.h, - $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS $t1_LIBS -lm, - $X_CFLAGS $t1_CFLAGS) - AC_SUBST(t1x_LIBS) - AC_SUBST(t1x_CFLAGS) -fi - -dnl ##### Disable X-specific stuff in top-level Makefile. -if test -n "$no_x"; then - X="#" - XPDF_TARGET="all-no-x" -else - X="" - XPDF_TARGET="all" -fi -AC_SUBST(X) -AC_SUBST(XPDF_TARGET) - -dnl ##### Write the makefiles. -AC_OUTPUT(Makefile xpdf/Makefile ltk/Makefile goo/Makefile) - -dnl ##### Warn user if X is missing. -if test -n "$no_x"; then - AC_MSG_WARN([Couldn't find X -- you will be able to compile - pdftops, pdftotext, pdfinfo, and pdfimages, but not xpdf]) -fi diff --git a/pdftops/gfile.cxx b/pdftops/gfile.cxx index 5e3781793e..e6428b71b2 100644 --- a/pdftops/gfile.cxx +++ b/pdftops/gfile.cxx @@ -38,6 +38,13 @@ # include #endif // HAVE_LIBCUPS +#ifdef __sun +// Solaris doesn't define mkstemp()... +extern "C" { +extern int mkstemp(char *); +} +#endif // __sun + // Some systems don't define this, so just make it something reasonably // large. #ifndef PATH_MAX @@ -450,23 +457,7 @@ time_t getModTime(const char *fileName) { } GBool openTempFile(GString **name, FILE **f, const char *mode, const char *ext) { -#ifdef HAVE_LIBCUPS - char filename[1024]; // Name of temporary file... - int fd; // File descriptor... - - - (void)ext; - - // Use the CUPS temporary file function on all platforms... - if ((fd = cupsTempFd(filename, sizeof(filename))) < 0) - return (gFalse); - - // Make the file descriptor a FILE *, and copy the temp filename... - *f = fdopen(fd, mode); - *name = new GString(filename); - - return (gTrue); -#elif defined(VMS) || defined(__EMX__) || defined(WIN32) || defined(ACORN) || defined(MACOS) +#if defined(VMS) || defined(__EMX__) || defined(WIN32) || defined(ACORN) || defined(MACOS) //---------- non-Unix ---------- char *s; @@ -488,10 +479,36 @@ GBool openTempFile(GString **name, FILE **f, const char *mode, const char *ext) return gTrue; #else //---------- Unix ---------- - char *s, *p; + char *s; int fd; + // MRS: Currently there is no standard function for creating a temporary + // file with an extension; this is required when uncompressing + // LZW data using the uncompress program on some UNIX, which is + // looking for a ".Z" extension on the temporary filename. Sooo, + // when you print an *OLD* PDF file that uses LZW compression, + // the tmpnam() function is usually the one that is called to + // create the temporary file. Under *BSD, the safer mkstemps() + // function is used instead. + // + // That said, all CUPS filters are run with TMPDIR pointing to + // a private temporary directory, which by default is only + // accessible to the 'lp' user. Also, most files use Flate + // compression now and will be able to use the (safer) + // mkstemp() function for any temporary files... + if (ext) { +# if HAVE_MKSTEMPS + if ((s = getenv("TMPDIR"))) { + *name = new GString(s); + } else { + *name = new GString("/tmp"); + } + (*name)->append("/XXXXXX"); + (*name)->append(ext); + fd = mkstemps((*name)->getCString(), strlen(ext)); +# else // HAVE_MKSTEMPS + char *p; if (!(s = tmpnam(NULL))) { return gFalse; } @@ -502,6 +519,7 @@ GBool openTempFile(GString **name, FILE **f, const char *mode, const char *ext) } (*name)->append(ext); fd = open((*name)->getCString(), O_WRONLY | O_CREAT | O_EXCL, 0600); +# endif // HAVE_MKSTEMPS } else { # if HAVE_MKSTEMP if ((s = getenv("TMPDIR"))) { diff --git a/pdftops/pdftops.cxx b/pdftops/pdftops.cxx index 7002302a69..fe107f9450 100644 --- a/pdftops/pdftops.cxx +++ b/pdftops/pdftops.cxx @@ -26,63 +26,14 @@ #include "Error.h" #include "config.h" -#ifdef HAVE_LIBCUPS -# include -#endif /* HAVE_LIBCUPS */ - -static int firstPage = 1; -static int lastPage = 0; -static GBool noEmbedFonts = gFalse; -static GBool doForm = gFalse; -static char userPassword[33] = ""; -static GBool printVersion = gFalse; -static GBool printHelp = gFalse; - -static ArgDesc argDesc[] = { - {"-f", argInt, &firstPage, 0, - "first page to print"}, - {"-l", argInt, &lastPage, 0, - "last page to print"}, - {"-paperw", argInt, &paperWidth, 0, - "paper width, in points"}, - {"-paperh", argInt, &paperHeight, 0, - "paper height, in points"}, - {"-level1", argFlag, &psOutLevel1, 0, - "generate Level 1 PostScript"}, - {"-level1sep", argFlag, &psOutLevel1Sep, 0, - "generate Level 1 separable PostScript"}, - {"-eps", argFlag, &psOutEPS, 0, - "generate Encapsulated PostScript (EPS)"}, -#if OPI_SUPPORT - {"-opi", argFlag, &psOutOPI, 0, - "generate OPI comments"}, -#endif - {"-noemb", argFlag, &noEmbedFonts, 0, - "don't embed Type 1 fonts"}, - {"-form", argFlag, &doForm, 0, - "generate a PostScript form"}, - {"-upw", argString, userPassword, sizeof(userPassword), - "user password (for encrypted files)"}, - {"-q", argFlag, &errQuiet, 0, - "don't print any messages or errors"}, - {"-v", argFlag, &printVersion, 0, - "print copyright and version info"}, - {"-h", argFlag, &printHelp, 0, - "print usage information"}, - {"-help", argFlag, &printHelp, 0, - "print usage information"}, - {NULL} -}; +#include int main(int argc, char *argv[]) { - PDFDoc *doc; - GString *fileName; - GString *psFileName; - GString *userPW; - PSOutputDev *psOut; - GBool ok; - char *p; -#ifdef HAVE_LIBCUPS + PDFDoc *doc; + GString *fileName; + GString *psFileName; + PSOutLevel level; + PSOutputDev *psOut; int num_options; cups_option_t *options; ppd_file_t *ppd; @@ -92,68 +43,49 @@ int main(int argc, char *argv[]) { char tempfile[1024]; char buffer[8192]; int bytes; + int width, length; - // See if we are being run as a filter... - if (getenv("PPD") && getenv("SOFTWARE")) { - // Yes, make sure status messages are not buffered... - setbuf(stderr, NULL); + // Make sure status messages are not buffered... + setbuf(stderr, NULL); - // Send all error messages... - errQuiet = 0; + // Send all error messages... + errQuiet = 0; + + // Make sure we have the right number of arguments for CUPS! + if (argc < 6 || argc > 7) { + fputs("Usage: pdftops job user title copies options [filename]\n", stderr); + return (1); + } - // Make sure we have the right number of arguments for CUPS! - if (argc < 6 || argc > 7) { - fputs("Usage: pdftops job user title copies options [filename]\n", stderr); + // Copy stdin if needed... + if (argc == 6) { + if ((fp = fopen(cupsTempFile(tempfile, sizeof(tempfile)), "w")) == NULL) { + perror("ERROR: Unable to copy PDF file"); return (1); } - // Copy stdin if needed... - if (argc == 6) { - if ((fp = fopen(cupsTempFile(tempfile, sizeof(tempfile)), "w")) == NULL) { - perror("ERROR: Unable to copy PDF file"); - return (1); - } + fprintf(stderr, "DEBUG: pdftops - copying to temp print file \"%s\"\n", + tempfile); - fprintf(stderr, "DEBUG: pdftops - copying to temp print file \"%s\"\n", - tempfile); + while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0) + fwrite(buffer, 1, bytes, fp); + fclose(fp); - while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0) - fwrite(buffer, 1, bytes, fp); - fclose(fp); - - fileName = new GString(tempfile); - } else { - fileName = new GString(argv[6]); - tempfile[0] = '\0'; - } + fileName = new GString(tempfile); } else { + fileName = new GString(argv[6]); tempfile[0] = '\0'; -#endif // HAVE_LIBCUPS - // parse args - ok = parseArgs(argDesc, &argc, argv); - if (!ok || argc < 2 || argc > 3 || printVersion || printHelp) { - fprintf(stderr, "pdftops version %s\n", xpdfVersion); - fprintf(stderr, "%s\n", xpdfCopyright); - if (!printVersion) { - printUsage("pdftops", " []", argDesc); - } - exit(1); - } - if (psOutLevel1 && psOutLevel1Sep) { - fprintf(stderr, "Error: use -level1 or -level1sep, not both.\n"); - exit(1); - } - if (doForm && (psOutLevel1 || psOutLevel1Sep)) { - fprintf(stderr, "Error: forms are only available with Level 2 output.\n"); - exit(1); - } - fileName = new GString(argv[1]); -#ifdef HAVE_LIBCUPS } + // Default to "Universal" size - min of A4 and Letter... + width = 595; + length = 792; + level = psLevel2; + // Get PPD and initialize options as needed... - if ((ppd = ppdOpenFile(getenv("PPD"))) != NULL) { + if ((ppd = ppdOpenFile(getenv("PPD"))) != NULL) + { fprintf(stderr, "DEBUG: pdftops - opened PPD file \"%s\"...\n", getenv("PPD")); ppdMarkDefaults(ppd); @@ -161,103 +93,55 @@ int main(int argc, char *argv[]) { cupsMarkOptions(ppd, num_options, options); cupsFreeOptions(num_options, options); - if ((size = ppdPageSize(ppd, NULL)) != NULL) { - paperWidth = (int)size->width; - paperHeight = (int)size->length; + if ((size = ppdPageSize(ppd, NULL)) != NULL) + { + width = (int)size->width; + length = (int)size->length; } - psOutLevel1 = ppd->language_level == 1; - - fprintf(stderr, "DEBUG: pdftops - psOutLevel1 = %d, paperWidth = %d, paperHeight = %d\n", - psOutLevel1, paperWidth, paperHeight); + level = ppd->language_level == 1 ? psLevel1 : psLevel2; ppdClose(ppd); } -#endif // HAVE_LIBCUPS + + fprintf(stderr, "DEBUG: pdftops - level = %d, width = %d, length = %d\n", + level, width, length); // init error file errorInit(); // read config file -#ifdef HAVE_LIBCUPS - if ((server_root = getenv("CUPS_SERVERROOT")) != NULL) { - sprintf(tempfile, "%s/pdftops.conf", server_root); - initParams(tempfile); - } else -#endif /* HAVE_LIBCUPS */ - initParams(xpdfConfigFile); + if ((server_root = getenv("CUPS_SERVERROOT")) == NULL) + server_root = CUPS_SERVERROOT; + + sprintf(tempfile, "%s/pdftops.conf", server_root); + initParams("", tempfile); // open PDF file - xref = NULL; - if (userPassword[0]) { - userPW = new GString(userPassword); - } else { - userPW = NULL; - } - doc = new PDFDoc(fileName, userPW); - if (userPW) { - delete userPW; - } - if (!doc->isOk()) { - goto err1; - } + doc = new PDFDoc(fileName, NULL, NULL, getenv("DEBUG") != NULL); // check for print permission - if (!doc->okToPrint()) { - error(-1, "Printing this document is not allowed."); - goto err1; - } - -#ifdef HAVE_LIBCUPS - if (getenv("PPD") && getenv("SOFTWARE")) { - // CUPS always needs every page and writes to stdout... + if (doc->isOk() && doc->okToPrint()) + { + // CUPS always writes to stdout... psFileName = new GString("-"); - firstPage = 1; - lastPage = doc->getNumPages(); - } else { -#endif // HAVE_LIBCUPS - - // construct PostScript file name - if (argc == 3) { - psFileName = new GString(argv[2]); - } else { - p = fileName->getCString() + fileName->getLength() - 4; - if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) - psFileName = new GString(fileName->getCString(), - fileName->getLength() - 4); - else - psFileName = fileName->copy(); - psFileName->append(psOutEPS ? ".eps" : ".ps"); - } - // get page range - if (firstPage < 1) - firstPage = 1; - if (lastPage < 1 || lastPage > doc->getNumPages()) - lastPage = doc->getNumPages(); - if (doForm) - lastPage = firstPage; + // write PostScript file + psOut = new PSOutputDev(psFileName->getCString(), doc->getXRef(), + doc->getCatalog(), 1, doc->getNumPages(), + level, psModePS, 0, 1, 1, width, length); + if (psOut->isOk()) + doc->displayPages(psOut, 1, doc->getNumPages(), 72, 0, gFalse); + delete psOut; - // check for multi-page EPS - if (psOutEPS && firstPage != lastPage) { - error(-1, "EPS files can only contain one page."); - goto err2; + // clean up + delete psFileName; } -#ifdef HAVE_LIBCUPS + else + { + error(-1, "Unable to print this document."); } -#endif // HAVE_LIBCUPS - - // write PostScript file - psOut = new PSOutputDev(psFileName->getCString(), doc->getCatalog(), - firstPage, lastPage, !noEmbedFonts, doForm); - if (psOut->isOk()) - doc->displayPages(psOut, firstPage, lastPage, 72, 0, gFalse); - delete psOut; - // clean up - err2: - delete psFileName; - err1: delete doc; freeParams(); @@ -265,11 +149,9 @@ int main(int argc, char *argv[]) { Object::memCheck(stderr); gMemReport(stderr); -#ifdef HAVE_LIBCUPS // Remove temp file if needed... if (tempfile[0]) unlink(tempfile); -#endif /* HAVE_LIBCUPS */ return 0; } diff --git a/ppd/Makefile b/ppd/Makefile index 117df28abb..5230f58443 100644 --- a/ppd/Makefile +++ b/ppd/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.8.2.1 2001/05/13 18:38:30 mike Exp $" +# "$Id: Makefile,v 1.8.2.2 2001/12/26 16:52:47 mike Exp $" # # PPD file makefile for the Common UNIX Printing System (CUPS). # @@ -28,8 +28,9 @@ include ../Makedefs # PPD files... # -FILES = deskjet.ppd deskjet2.ppd epson9.ppd epson24.ppd laserjet.ppd \ - okidata9.ppd okidat24.ppd stcolor.ppd stphoto.ppd +FILES = deskjet.ppd deskjet2.ppd dymo.ppd epson9.ppd epson24.ppd \ + laserjet.ppd okidata9.ppd okidat24.ppd stcolor.ppd \ + stcolor2.ppd stphoto.ppd stphoto2.ppd # @@ -51,11 +52,12 @@ clean: # install: - -$(MKDIR) $(DATADIR)/model - $(CHMOD) ugo+rx $(DATADIR)/model - $(INSTALL_DATA) $(FILES) $(DATADIR)/model + $(INSTALL_DIR) $(DATADIR)/model + for file in $(FILES); do \ + $(INSTALL_DATA) $$file $(DATADIR)/model; \ + done # -# End of "$Id: Makefile,v 1.8.2.1 2001/05/13 18:38:30 mike Exp $". +# End of "$Id: Makefile,v 1.8.2.2 2001/12/26 16:52:47 mike Exp $". # diff --git a/ppd/deskjet2.ppd b/ppd/deskjet2.ppd index d6f487b9dd..8b86447a70 100644 --- a/ppd/deskjet2.ppd +++ b/ppd/deskjet2.ppd @@ -1,6 +1,6 @@ *PPD-Adobe: "4.3" *% -*% "$Id: deskjet2.ppd,v 1.1.2.1 2001/05/13 18:38:30 mike Exp $" +*% "$Id: deskjet2.ppd,v 1.1.2.2 2001/12/26 16:52:47 mike Exp $" *% *% Second sample HP DeskJet driver PPD file for the Common UNIX Printing *% System (CUPS). @@ -161,7 +161,7 @@ *CloseUI: *ColorModel *OpenUI *Duplex/Double-Sided Printing: PickOne -*OrderDependency: 20 AnySetup *Duplex +*OrderDependency: 20 PageSetup *Duplex *DefaultDuplex: None *Duplex None/Off: "<>setpagedevice" *Duplex DuplexNoTumble/Long Edge (Standard): "<>setpagedevice" @@ -213,5 +213,5 @@ *Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM *Font ZapfDingbats: Special "(001.004S)" Standard ROM *% -*% End of "$Id: deskjet2.ppd,v 1.1.2.1 2001/05/13 18:38:30 mike Exp $". +*% End of "$Id: deskjet2.ppd,v 1.1.2.2 2001/12/26 16:52:47 mike Exp $". *% diff --git a/ppd/dymo.ppd b/ppd/dymo.ppd index cbc619809e..b0ab6c9cbb 100644 --- a/ppd/dymo.ppd +++ b/ppd/dymo.ppd @@ -1,6 +1,6 @@ *PPD-Adobe: "4.3" *% -*% "$Id: dymo.ppd,v 1.4 2001/07/18 18:18:30 mike Exp $" +*% "$Id: dymo.ppd,v 1.4.2.1 2001/12/26 16:52:47 mike Exp $" *% *% Sample DYMO label printer driver PPD file for the Common UNIX Printing *% System (CUPS). @@ -151,5 +151,5 @@ *Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM *Font ZapfDingbats: Special "(001.004S)" Standard ROM *% -*% End of "$Id: dymo.ppd,v 1.4 2001/07/18 18:18:30 mike Exp $". +*% End of "$Id: dymo.ppd,v 1.4.2.1 2001/12/26 16:52:47 mike Exp $". *% diff --git a/pstoraster/Makefile b/pstoraster/Makefile index b3bffac57d..fbc39912e7 100644 --- a/pstoraster/Makefile +++ b/pstoraster/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.31.2.1 2001/05/13 18:38:31 mike Exp $" +# "$Id: Makefile,v 1.31.2.2 2001/12/26 16:52:48 mike Exp $" # # GNU Ghostscript makefile for the Common UNIX Printing System (CUPS). # @@ -376,14 +376,12 @@ clean: # install: $(TARGETS) - -$(MKDIR) $(SERVERBIN)/filter - $(CHMOD) ugo+rx $(SERVERBIN) - $(CHMOD) ugo+rx $(SERVERBIN)/filter + $(INSTALL_DIR) $(SERVERBIN)/filter $(INSTALL_BIN) pstoraster $(SERVERBIN)/filter - -$(MKDIR) $(DATADIR)/pstoraster - $(CHMOD) ugo+rx $(DATADIR) - $(CHMOD) ugo+rx $(DATADIR)/pstoraster - $(INSTALL_DATA) $(DFILES) $(DATADIR)/pstoraster + $(INSTALL_DIR) $(DATADIR)/pstoraster + for file in $(DFILES); do \ + $(INSTALL_DATA) $$file $(DATADIR)/pstoraster; \ + done # @@ -419,6 +417,16 @@ pstoraster: pstoraster.o libgs.a ../Makedefs ../cups/$(LIBCUPS) $(LINKCUPSIMAGE) $(IMGLIBS) $(DSOLIBS) $(LIBS) -lm +# +# purify - target to test Ghostscript to see how leaky it is... +# + +purify: pstoraster.o libgs.a ../Makedefs ../cups/$(LIBCUPS) + echo Linking $@... + purify $(CC) $(LDFLAGS) -o pstoraster.pure pstoraster.o libgs.a \ + $(LINKCUPSIMAGE) $(IMGLIBS) $(DSOLIBS) $(LIBS) -lm + + # # Generate dependencies for Ghostscript source files... # @@ -442,5 +450,5 @@ include Dependencies # -# End of "$Id: Makefile,v 1.31.2.1 2001/05/13 18:38:31 mike Exp $". +# End of "$Id: Makefile,v 1.31.2.2 2001/12/26 16:52:48 mike Exp $". # diff --git a/pstoraster/gdevcups.c b/pstoraster/gdevcups.c index 187ec41de0..d3e6147379 100644 --- a/pstoraster/gdevcups.c +++ b/pstoraster/gdevcups.c @@ -1,5 +1,5 @@ /* - * "$Id: gdevcups.c,v 1.43 2001/03/29 14:58:54 mike Exp $" + * "$Id: gdevcups.c,v 1.43.2.1 2001/12/26 16:52:48 mike Exp $" * * GNU Ghostscript raster output driver for the Common UNIX Printing * System (CUPS). @@ -324,8 +324,8 @@ cups_get_matrix(gx_device *pdev, /* I - Device info */ fprintf(stderr, "DEBUG: cups->ppd->flip_duplex = %d\n", cups->ppd->flip_duplex); } - if (cups->header.Duplex && cups->ppd && cups->ppd->flip_duplex && - !(cups->page & 1)) + if (cups->header.Duplex && !cups->header.Tumble && + cups->ppd && cups->ppd->flip_duplex && !(cups->page & 1)) { pmat->xx = (float)cups->header.HWResolution[0] / 72.0; pmat->xy = 0.0; @@ -1492,6 +1492,7 @@ cups_put_params(gx_device *pdev, /* I - Device info */ gs_param_string stringval; /* String value */ gs_param_float_array arrayval; /* Float array value */ int old_depth; /* Old color depth */ + int size_set; /* Was the size set? */ gdev_prn_space_params sp; /* Space parameter data */ @@ -1570,6 +1571,7 @@ cups_put_params(gx_device *pdev, /* I - Device info */ } old_depth = pdev->color_info.depth; + size_set = param_read_float_array(plist, "PageSize", &arrayval) == 0; stringoption(MediaClass, "MediaClass") stringoption(MediaColor, "MediaColor") @@ -1701,6 +1703,20 @@ cups_put_params(gx_device *pdev, /* I - Device info */ cups->header.PageSize[0] = pdev->PageSize[0]; cups->header.PageSize[1] = pdev->PageSize[1]; + /* + * Reallocate memory if the size or color depth was changed... + */ + + if (old_depth != pdev->color_info.depth || size_set) + { + fputs("DEBUG: Reallocating memory...\n", stderr); + sp = ((gx_device_printer *)pdev)->space_params; + + if ((code = gdev_prn_reallocate_memory(pdev, &sp, pdev->width, + pdev->height)) < 0) + return (code); + } + #ifdef DEBUG fprintf(stderr, "DEBUG: ppd = %8x\n", cups->ppd); fprintf(stderr, "DEBUG: PageSize = [ %.3f %.3f ]\n", @@ -1974,12 +1990,14 @@ cups_print_chunked(gx_device_printer *pdev, /* I - Printer device */ int flip; /* Flip scanline? */ - if (cups->header.Duplex && cups->ppd && cups->ppd->flip_duplex && - !(cups->page & 1)) + if (cups->header.Duplex && !cups->header.Tumble && + cups->ppd && cups->ppd->flip_duplex && !(cups->page & 1)) flip = 1; else flip = 0; + fprintf(stderr, "DEBUG: cups_print_chunked - flip = %d\n", flip); + /* * Loop through the page bitmap and write chunked pixels, reversing as * needed... @@ -2120,12 +2138,14 @@ cups_print_banded(gx_device_printer *pdev, /* I - Printer device */ int flip; /* Flip scanline? */ - if (cups->header.Duplex && cups->ppd && cups->ppd->flip_duplex && - !(cups->page & 1)) + if (cups->header.Duplex && !cups->header.Tumble && + cups->ppd && cups->ppd->flip_duplex && !(cups->page & 1)) flip = 1; else flip = 0; + fprintf(stderr, "DEBUG: cups_print_banded - flip = %d\n", flip); + /* * Loop through the page bitmap and write banded pixels... We have * to separate each chunked color as needed... @@ -2310,14 +2330,20 @@ cups_print_banded(gx_device_printer *pdev, /* I - Printer device */ x > 0; x --, srcptr ++) { + /* + * Note: Because of the way the pointers are setup, + * the following code is correct even though + * the names don't match... + */ + if (*srcptr & 0x20) - *kptr |= bit; - if (*srcptr & 0x10) *cptr |= bit; - if (*srcptr & 0x08) + if (*srcptr & 0x10) *mptr |= bit; - if (*srcptr & 0x04) + if (*srcptr & 0x08) *yptr |= bit; + if (*srcptr & 0x04) + *kptr |= bit; if (*srcptr & 0x02) *lcptr |= bit; if (*srcptr & 0x01) @@ -3035,5 +3061,5 @@ cups_print_planar(gx_device_printer *pdev, /* I - Printer device */ /* - * End of "$Id: gdevcups.c,v 1.43 2001/03/29 14:58:54 mike Exp $". + * End of "$Id: gdevcups.c,v 1.43.2.1 2001/12/26 16:52:48 mike Exp $". */ diff --git a/pstoraster/gscrdp.c b/pstoraster/gscrdp.c index f04803f0cf..c64e703380 100644 --- a/pstoraster/gscrdp.c +++ b/pstoraster/gscrdp.c @@ -22,7 +22,7 @@ GNU software to build or run it. */ -/*$Id: gscrdp.c,v 1.2 2000/10/13 01:04:41 mike Exp $ */ +/*$Id: gscrdp.c,v 1.2.2.1 2001/12/26 16:52:49 mike Exp $ */ /* CIE color rendering dictionary creation */ #include "math_.h" #include "memory_.h" @@ -34,6 +34,7 @@ #include "gscolor2.h" /* for gs_set/currentcolorrendering */ #include "gscrdp.h" #include "gxarith.h" +#include "gsmalloc.h" /* Define the CRD type that we use here. */ #define CRD_TYPE 101 diff --git a/pstoraster/isave.c b/pstoraster/isave.c index e793af8d7f..f9553b0d5f 100644 --- a/pstoraster/isave.c +++ b/pstoraster/isave.c @@ -22,7 +22,7 @@ GNU software to build or run it. */ -/*$Id: isave.c,v 1.2 2000/03/08 23:15:15 mike Exp $ */ +/*$Id: isave.c,v 1.2.2.1 2001/12/26 16:52:49 mike Exp $ */ /* Save/restore manager for Ghostscript interpreter */ #include "ghost.h" #include "memory_.h" @@ -447,9 +447,11 @@ alloc_save_change(gs_dual_memory_t * dmem, const ref * pcont, gs_abort(); } if (r_is_packed(where)) - *(ref_packed *) & cp->contents = *where; + *(ref_packed *)(&(cp->contents)) = *where; else { - ref_assign_inline(&cp->contents, (ref *) where); +/* MRS - the following inline assign didn't work... + ref_assign_inline(&cp->contents, (ref *) where);*/ + ref_assign((&(cp->contents)), (ref *) where); r_set_attrs((ref *) where, l_new); } mem->changes = cp; diff --git a/pstoraster/pstoraster.c b/pstoraster/pstoraster.c index 5b64b0d152..ea95d5ecab 100644 --- a/pstoraster/pstoraster.c +++ b/pstoraster/pstoraster.c @@ -1,5 +1,5 @@ /* - * "$Id: pstoraster.c,v 1.19 2001/01/24 17:20:05 mike Exp $" + * "$Id: pstoraster.c,v 1.19.2.1 2001/12/26 16:52:49 mike Exp $" * * PostScript RIP filter main entry for the Common UNIX Printing System * (CUPS). @@ -49,6 +49,10 @@ #include #include +#ifdef __sgi +# include +#endif /* __sgi */ + #undef bool #undef uchar #undef uint @@ -100,6 +104,16 @@ main(int argc, /* I - Number of command-line arguments */ const char *fontpath; /* CUPS_FONTPATH env variable */ +#ifdef __sgi + /* + * Force unaligned memory access handling on R12K processors... + * (this should be done by default...) Ghostscript is not 64-bit + * safe... + */ + + sysmips(MIPS_FIXADE, 1, 0, 0); +#endif /* __sgi */ + /* * Force the locale to "C" to avoid bugs... */ @@ -235,5 +249,5 @@ define_string(const char *name, /* I - Variable to set */ /* - * End of "$Id: pstoraster.c,v 1.19 2001/01/24 17:20:05 mike Exp $". + * End of "$Id: pstoraster.c,v 1.19.2.1 2001/12/26 16:52:49 mike Exp $". */ diff --git a/scheduler/Makefile b/scheduler/Makefile index f335c29ee6..fa47027081 100644 --- a/scheduler/Makefile +++ b/scheduler/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.36 2001/02/21 17:01:16 mike Exp $" +# "$Id: Makefile,v 1.36.2.1 2001/12/26 16:52:49 mike Exp $" # # Scheduler Makefile for the Common UNIX Printing System (CUPS). # @@ -52,25 +52,17 @@ clean: # install: - -$(MKDIR) $(SBINDIR) - $(CHMOD) ugo+rx $(SBINDIR) + $(INSTALL_DIR) $(SBINDIR) $(INSTALL_BIN) cupsd $(SBINDIR) - -$(MKDIR) $(SERVERBIN)/daemon - $(CHMOD) ugo+rx $(SERVERBIN)/daemon + $(INSTALL_DIR) $(SERVERBIN)/daemon $(INSTALL_BIN) cups-lpd $(SERVERBIN)/daemon $(INSTALL_BIN) cups-polld $(SERVERBIN)/daemon - -$(MKDIR) $(SERVERROOT)/certs - $(CHMOD) ugo+x,go-rw $(SERVERROOT)/certs - -$(MKDIR) $(SERVERROOT)/interfaces - $(CHMOD) ugo+rx $(SERVERROOT)/interfaces - -$(MKDIR) $(SERVERROOT)/ppd - $(CHMOD) ugo+rx $(SERVERROOT)/ppd - -$(MKDIR) $(LOGDIR) - $(CHMOD) ugo+rx $(LOGDIR) - -$(MKDIR) $(REQUESTS) - $(CHMOD) u+rwx,go-rwx $(REQUESTS) - -$(MKDIR) $(REQUESTS)/tmp - $(CHMOD) u+rwx,go-rwx,+t $(REQUESTS)/tmp + $(INSTALL_DIR) -m 711 -o $(CUPS_USER) -g $(CUPS_GROUP) $(SERVERROOT)/certs + $(INSTALL_DIR) $(SERVERROOT)/interfaces + $(INSTALL_DIR) $(SERVERROOT)/ppd + $(INSTALL_DIR) $(LOGDIR) + $(INSTALL_DIR) -m 700 -o $(CUPS_USER) -g $(CUPS_GROUP) $(REQUESTS) + $(INSTALL_DIR) -m 1700 -o $(CUPS_USER) -g $(CUPS_GROUP) $(REQUESTS)/tmp # @@ -80,7 +72,7 @@ install: cupsd: $(CUPSDOBJS) libmime.a ../cups/$(LIBCUPS) echo Linking $@... $(CC) $(LDFLAGS) -o cupsd $(CUPSDOBJS) libmime.a \ - $(LIBZ) $(SSLLIBS) $(LIBS) $(LIBMALLOC) + $(LIBZ) $(SSLLIBS) $(LIBSLP) $(PAMLIBS) $(LIBS) $(LIBMALLOC) $(CUPSDOBJS): auth.h banners.h cert.h classes.h client.h conf.h \ cupsd.h dirsvc.h job.h mime.h printers.h \ @@ -149,5 +141,5 @@ $(OBJS): ../config.h ../Makedefs # -# End of "$Id: Makefile,v 1.36 2001/02/21 17:01:16 mike Exp $". +# End of "$Id: Makefile,v 1.36.2.1 2001/12/26 16:52:49 mike Exp $". # diff --git a/scheduler/auth.c b/scheduler/auth.c index fc0e2d809c..e2420b104a 100644 --- a/scheduler/auth.c +++ b/scheduler/auth.c @@ -1,5 +1,5 @@ /* - * "$Id: auth.c,v 1.41.2.2 2001/05/13 18:38:33 mike Exp $" + * "$Id: auth.c,v 1.41.2.3 2001/12/26 16:52:50 mike Exp $" * * Authorization routines for the Common UNIX Printing System (CUPS). * @@ -42,8 +42,11 @@ * IsAuthorized() - Check to see if the user is authorized... * add_allow() - Add an allow mask to the location. * add_deny() - Add a deny mask to the location. + * cups_crypt() - Encrypt the password using the DES or MD5 + * algorithms, as needed. * get_md5_passwd() - Get an MD5 password. * pam_func() - PAM conversation function. + * to64() - Base64-encode an integer value... */ /* @@ -53,6 +56,7 @@ #include "cupsd.h" #include #include +#include #ifdef HAVE_SHADOW_H # include #endif /* HAVE_SHADOW_H */ @@ -73,11 +77,16 @@ static authmask_t *add_allow(location_t *loc); static authmask_t *add_deny(location_t *loc); +#if !HAVE_LIBPAM +static char *cups_crypt(const char *pw, const char *salt); +#endif /* !HAVE_LIBPAM */ static char *get_md5_passwd(const char *username, const char *group, char passwd[33]); #if HAVE_LIBPAM static int pam_func(int, const struct pam_message **, struct pam_response **, void *); +#else +static void to64(char *s, unsigned long v, int n); #endif /* HAVE_LIBPAM */ @@ -515,7 +524,8 @@ DenyIP(location_t *loc, /* I - Location to add to */ */ location_t * /* O - Location that matches */ -FindBest(client_t *con) /* I - Connection */ +FindBest(const char *path, /* I - Resource path */ + http_state_t state) /* I - HTTP state/request */ { int i; /* Looping var */ location_t *loc, /* Current location */ @@ -541,11 +551,35 @@ FindBest(client_t *con) /* I - Connection */ }; + /* + * First copy the connection URI to a local string so we have drop + * any .ppd extension from the pathname in /printers or /classes + * URIs... + */ + + strncpy(uri, path, sizeof(uri) - 1); + uri[sizeof(uri) - 1] = '\0'; + + if (strncmp(uri, "/printers/", 10) == 0 || + strncmp(uri, "/classes/", 9) == 0) + { + /* + * Check if the URI has .ppd on the end... + */ + + uriptr = uri + strlen(uri) - 4; /* len > 4 if we get here... */ + + if (strcmp(uriptr, ".ppd") == 0) + *uriptr = '\0'; + } + + LogMessage(L_DEBUG2, "FindBest: uri = \"%s\"...", uri); + /* * Loop through the list of locations to find a match... */ - limit = limits[con->http.state]; + limit = limits[state]; best = NULL; bestlen = 0; @@ -612,7 +646,8 @@ IsAuthorized(client_t *con) /* I - Connection */ struct group *grp; /* Group data */ char nonce[HTTP_MAX_VALUE], /* Nonce value from client */ - md5[33]; /* MD5 password */ + md5[33], /* MD5 password */ + basicmd5[33]; /* MD5 of Basic password */ #if HAVE_LIBPAM pam_handle_t *pamh; /* PAM authentication handle */ int pamerr; /* PAM error code */ @@ -653,7 +688,7 @@ IsAuthorized(client_t *con) /* I - Connection */ * not authorized... */ - if ((best = FindBest(con)) == NULL) + if ((best = FindBest(con->uri, con->http.state)) == NULL) return (HTTP_FORBIDDEN); /* @@ -702,6 +737,14 @@ IsAuthorized(client_t *con) /* I - Connection */ auth = AUTH_ALLOW; } + else if (best->num_allow == 0 && best->num_deny == 0) + { + /* + * No allow/deny lines - allow access... + */ + + auth = AUTH_ALLOW; + } else { /* @@ -795,7 +838,10 @@ IsAuthorized(client_t *con) /* I - Connection */ LogMessage(L_DEBUG2, "IsAuthorized: Checking \"%s\", address = %08x, hostname = \"%s\"", con->username, address, con->http.hostname); - if (strcasecmp(con->http.hostname, "localhost") != 0 || + pw = NULL; + + if ((address != 0x7f000001 && + strcasecmp(con->http.hostname, "localhost") != 0) || strncmp(con->http.fields[HTTP_FIELD_AUTHORIZATION], "Local", 5) != 0) { /* @@ -806,172 +852,243 @@ IsAuthorized(client_t *con) /* I - Connection */ return (HTTP_UNAUTHORIZED); /* - * See if we are doing Digest or Basic authentication... + * See what kind of authentication we are doing... */ - if (best->type == AUTH_BASIC) + switch (best->type) { + case AUTH_BASIC : + /* + * Get the user info... + */ + + pw = getpwnam(con->username); /* Get the current password */ + endpwent(); /* Close the password file */ + + if (pw == NULL) /* No such user... */ + { + LogMessage(L_WARN, "IsAuthorized: Unknown username \"%s\"; access denied.", + con->username); + return (HTTP_UNAUTHORIZED); + } + #if HAVE_LIBPAM - /* - * Only use PAM to do authentication. This allows MD5 passwords, among - * other things... - */ + /* + * Only use PAM to do authentication. This allows MD5 passwords, among + * other things... + */ - pamdata.conv = pam_func; - pamdata.appdata_ptr = con; + pamdata.conv = pam_func; + pamdata.appdata_ptr = con; # ifdef __hpux - /* - * Workaround for HP-UX bug in pam_unix; see pam_conv() below for - * more info... - */ + /* + * Workaround for HP-UX bug in pam_unix; see pam_conv() below for + * more info... + */ - auth_client = con; + auth_client = con; # endif /* __hpux */ - DEBUG_printf(("IsAuthorized: Setting appdata_ptr = %p\n", con)); + DEBUG_printf(("IsAuthorized: Setting appdata_ptr = %p\n", con)); - pamerr = pam_start("cups", con->username, &pamdata, &pamh); - if (pamerr != PAM_SUCCESS) - { - LogMessage(L_ERROR, "IsAuthorized: pam_start() returned %d (%s)!\n", - pamerr, pam_strerror(pamh, pamerr)); - pam_end(pamh, 0); - return (HTTP_UNAUTHORIZED); - } - - pamerr = pam_authenticate(pamh, PAM_SILENT); - if (pamerr != PAM_SUCCESS) - { - LogMessage(L_ERROR, "IsAuthorized: pam_authenticate() returned %d (%s)!\n", - pamerr, pam_strerror(pamh, pamerr)); - pam_end(pamh, 0); - return (HTTP_UNAUTHORIZED); - } - - pamerr = pam_acct_mgmt(pamh, PAM_SILENT); - if (pamerr != PAM_SUCCESS) - { - LogMessage(L_ERROR, "IsAuthorized: pam_acct_mgmt() returned %d (%s)!\n", - pamerr, pam_strerror(pamh, pamerr)); - pam_end(pamh, 0); - return (HTTP_UNAUTHORIZED); - } + pamerr = pam_start("cups", con->username, &pamdata, &pamh); + if (pamerr != PAM_SUCCESS) + { + LogMessage(L_ERROR, "IsAuthorized: pam_start() returned %d (%s)!\n", + pamerr, pam_strerror(pamh, pamerr)); + pam_end(pamh, 0); + return (HTTP_UNAUTHORIZED); + } + + pamerr = pam_authenticate(pamh, PAM_SILENT); + if (pamerr != PAM_SUCCESS) + { + LogMessage(L_ERROR, "IsAuthorized: pam_authenticate() returned %d (%s)!\n", + pamerr, pam_strerror(pamh, pamerr)); + pam_end(pamh, 0); + return (HTTP_UNAUTHORIZED); + } + + pamerr = pam_acct_mgmt(pamh, PAM_SILENT); + if (pamerr != PAM_SUCCESS) + { + LogMessage(L_ERROR, "IsAuthorized: pam_acct_mgmt() returned %d (%s)!\n", + pamerr, pam_strerror(pamh, pamerr)); + pam_end(pamh, 0); + return (HTTP_UNAUTHORIZED); + } - pam_end(pamh, PAM_SUCCESS); + pam_end(pamh, PAM_SUCCESS); #elif defined(HAVE_USERSEC_H) - /* - * Use AIX authentication interface... - */ + /* + * Use AIX authentication interface... + */ - LogMessage(L_DEBUG, "IsAuthorized: AIX authenticate of username \"%s\"", - con->username); + LogMessage(L_DEBUG, "IsAuthorized: AIX authenticate of username \"%s\"", + con->username); - reenter = 1; - if (authenticate(con->username, con->password, &reenter, &authmsg) != 0) - { - LogMessage(L_DEBUG, "IsAuthorized: Unable to authenticate username \"%s\": %s", - con->username, strerror(errno)); - return (HTTP_UNAUTHORIZED); - } + reenter = 1; + if (authenticate(con->username, con->password, &reenter, &authmsg) != 0) + { + LogMessage(L_DEBUG, "IsAuthorized: Unable to authenticate username \"%s\": %s", + con->username, strerror(errno)); + return (HTTP_UNAUTHORIZED); + } #else # ifdef HAVE_SHADOW_H - spw = getspnam(con->username); - endspent(); - - if (spw == NULL && strcmp(pw->pw_passwd, "x") == 0) - { /* Don't allow blank passwords! */ - LogMessage(L_WARN, "IsAuthorized: Username \"%s\" has no shadow password; access denied.", - con->username); - return (HTTP_UNAUTHORIZED); /* No such user or bad shadow file */ - } + spw = getspnam(con->username); + endspent(); + + if (spw == NULL && strcmp(pw->pw_passwd, "x") == 0) + { /* Don't allow blank passwords! */ + LogMessage(L_WARN, "IsAuthorized: Username \"%s\" has no shadow password; access denied.", + con->username); + return (HTTP_UNAUTHORIZED); /* No such user or bad shadow file */ + } # ifdef DEBUG - if (spw != NULL) - printf("spw->sp_pwdp = \"%s\"\n", spw->sp_pwdp); - else - puts("spw = NULL"); + if (spw != NULL) + printf("spw->sp_pwdp = \"%s\"\n", spw->sp_pwdp); + else + puts("spw = NULL"); # endif /* DEBUG */ - if (spw != NULL && spw->sp_pwdp[0] == '\0' && pw->pw_passwd[0] == '\0') + if (spw != NULL && spw->sp_pwdp[0] == '\0' && pw->pw_passwd[0] == '\0') # else - if (pw->pw_passwd[0] == '\0') /* Don't allow blank passwords! */ + if (pw->pw_passwd[0] == '\0') # endif /* HAVE_SHADOW_H */ - { /* Don't allow blank passwords! */ - LogMessage(L_WARN, "IsAuthorized: Username \"%s\" has no password; access denied.", - con->username); - return (HTTP_UNAUTHORIZED); - } + { /* Don't allow blank passwords! */ + LogMessage(L_WARN, "IsAuthorized: Username \"%s\" has no password; access denied.", + con->username); + return (HTTP_UNAUTHORIZED); + } - /* - * OK, the password isn't blank, so compare with what came from the client... - */ + /* + * OK, the password isn't blank, so compare with what came from the client... + */ - LogMessage(L_DEBUG2, "IsAuthorized: pw_passwd = %s, crypt = %s", - pw->pw_passwd, crypt(con->password, pw->pw_passwd)); + pass = cups_crypt(con->password, pw->pw_passwd); - pass = crypt(con->password, pw->pw_passwd); + LogMessage(L_DEBUG2, "IsAuthorized: pw_passwd = %s, crypt = %s", + pw->pw_passwd, pass); - if (pass == NULL || - strcmp(pw->pw_passwd, crypt(con->password, pw->pw_passwd)) != 0) - { + if (pass == NULL || strcmp(pw->pw_passwd, pass) != 0) + { # ifdef HAVE_SHADOW_H - if (spw != NULL) - { - LogMessage(L_DEBUG2, "IsAuthorized: sp_pwdp = %s, crypt = %s", - spw->sp_pwdp, crypt(con->password, spw->sp_pwdp)); + if (spw != NULL) + { + pass = cups_crypt(con->password, spw->sp_pwdp); - pass = crypt(con->password, spw->sp_pwdp); + LogMessage(L_DEBUG2, "IsAuthorized: sp_pwdp = %s, crypt = %s", + spw->sp_pwdp, pass); - if (pass == NULL || - strcmp(spw->sp_pwdp, crypt(con->password, spw->sp_pwdp)) != 0) - return (HTTP_UNAUTHORIZED); - } - else + if (pass == NULL || strcmp(spw->sp_pwdp, pass) != 0) + return (HTTP_UNAUTHORIZED); + } + else # endif /* HAVE_SHADOW_H */ - return (HTTP_UNAUTHORIZED); - } + return (HTTP_UNAUTHORIZED); + } #endif /* HAVE_LIBPAM */ - } - else - { - /* - * Do Digest authentication... - */ - - if (!httpGetSubField(&(con->http), HTTP_FIELD_WWW_AUTHENTICATE, "nonce", - nonce)) - { - LogMessage(L_ERROR, "IsAuthorized: No nonce value for Digest authentication!"); - return (HTTP_UNAUTHORIZED); - } - - if (strcmp(con->http.hostname, nonce) != 0) - { - LogMessage(L_ERROR, "IsAuthorized: Nonce value error!"); - LogMessage(L_ERROR, "IsAuthorized: Expected \"%s\",", - con->http.hostname); - LogMessage(L_ERROR, "IsAuthorized: Got \"%s\"!", nonce); - return (HTTP_UNAUTHORIZED); - } + break; + case AUTH_DIGEST : + /* + * Do Digest authentication... + */ - if (!get_md5_passwd(con->username, best->names[0], md5)) - { - LogMessage(L_ERROR, "IsAuthorized: No user:group for \"%s:%s\" in passwd.md5!", - con->username, best->names[0]); - return (HTTP_UNAUTHORIZED); - } + if (!httpGetSubField(&(con->http), HTTP_FIELD_AUTHORIZATION, "nonce", + nonce)) + { + LogMessage(L_ERROR, "IsAuthorized: No nonce value for Digest authentication!"); + return (HTTP_UNAUTHORIZED); + } + + if (strcmp(con->http.hostname, nonce) != 0) + { + LogMessage(L_ERROR, "IsAuthorized: Nonce value error!"); + LogMessage(L_ERROR, "IsAuthorized: Expected \"%s\",", + con->http.hostname); + LogMessage(L_ERROR, "IsAuthorized: Got \"%s\"!", nonce); + return (HTTP_UNAUTHORIZED); + } + + LogMessage(L_DEBUG2, "IsAuthorized: nonce = \"%s\"", nonce); + + if (best->num_names && best->level == AUTH_GROUP) + { + for (i = 0; i < best->num_names; i ++) + if (get_md5_passwd(con->username, best->names[i], md5)) + break; + + if (i >= best->num_names) + md5[0] = '\0'; + } + else if (!get_md5_passwd(con->username, NULL, md5)) + md5[0] = '\0'; + + + if (!md5[0]) + { + LogMessage(L_ERROR, "IsAuthorized: No matching user:group for \"%s\" in passwd.md5!", + con->username); + return (HTTP_UNAUTHORIZED); + } + + httpMD5Final(nonce, states[con->http.state], con->uri, md5); + + if (strcmp(md5, con->password) != 0) + { + LogMessage(L_ERROR, "IsAuthorized: MD5s \"%s\" and \"%s\" don't match!", + md5, con->password); + return (HTTP_UNAUTHORIZED); + } + break; - httpMD5Final(nonce, states[con->http.state], con->uri, md5); + case AUTH_BASICDIGEST : + /* + * Do Basic authentication with the Digest password file... + */ - if (strcmp(md5, con->password) != 0) - { - LogMessage(L_ERROR, "IsAuthorized: MD5s \"%s\" and \"%s\" don't match!", - md5, con->password); - return (HTTP_UNAUTHORIZED); - } + if (best->num_names && best->level == AUTH_GROUP) + { + for (i = 0; i < best->num_names; i ++) + if (get_md5_passwd(con->username, best->names[i], md5)) + break; + + if (i >= best->num_names) + md5[0] = '\0'; + } + else if (!get_md5_passwd(con->username, NULL, md5)) + md5[0] = '\0'; + + if (!md5[0]) + { + LogMessage(L_ERROR, "IsAuthorized: No matching user:group for \"%s\" in passwd.md5!", + con->username); + return (HTTP_UNAUTHORIZED); + } + + httpMD5(con->username, "CUPS", con->password, basicmd5); + + if (strcmp(md5, basicmd5) != 0) + { + LogMessage(L_ERROR, "IsAuthorized: MD5s \"%s\" and \"%s\" don't match!", + md5, basicmd5); + return (HTTP_UNAUTHORIZED); + } + break; } } + else + { + /* + * Get password entry for certificate-based auth... + */ + + pw = getpwnam(con->username); /* Get the current password */ + endpwent(); /* Close the password file */ + } /* * OK, the password is good. See if we need normal user access, or group @@ -1011,37 +1128,52 @@ IsAuthorized(client_t *con) /* I - Connection */ LogMessage(L_DEBUG2, "IsAuthorized: Checking group membership..."); - for (i = 0; i < best->num_names; i ++) + if (best->type == AUTH_BASIC) { - grp = getgrnam(best->names[i]); - endgrent(); + /* + * Check to see if this user is in any of the named groups... + */ + + LogMessage(L_DEBUG2, "IsAuthorized: Checking group membership..."); - if (grp == NULL) /* No group by that name??? */ + for (i = 0; i < best->num_names; i ++) { - LogMessage(L_WARN, "IsAuthorized: group name \"%s\" does not exist!", - best->names[i]); - return (HTTP_FORBIDDEN); - } + grp = getgrnam(best->names[i]); + endgrent(); + + if (grp == NULL) /* No group by that name??? */ + { + LogMessage(L_WARN, "IsAuthorized: group name \"%s\" does not exist!", + best->names[i]); + return (HTTP_FORBIDDEN); + } - for (j = 0; grp->gr_mem[j] != NULL; j ++) - if (strcmp(con->username, grp->gr_mem[j]) == 0) + for (j = 0; grp->gr_mem[j] != NULL; j ++) + if (strcmp(con->username, grp->gr_mem[j]) == 0) + return (HTTP_OK); + + /* + * Check to see if the default group ID matches for the user... + */ + + if (grp->gr_gid == pw->pw_gid) return (HTTP_OK); + } /* - * Check to see if the default group ID matches for the user... + * The user isn't part of the specified group, so deny access... */ - if (grp->gr_gid == pw->pw_gid) - return (HTTP_OK); + LogMessage(L_DEBUG2, "IsAuthorized: user not in group!"); + + return (HTTP_UNAUTHORIZED); } /* - * The user isn't part of the specified group, so deny access... + * All checks passed... */ - LogMessage(L_DEBUG2, "IsAuthorized: user not in group!"); - - return (HTTP_UNAUTHORIZED); + return (HTTP_OK); } @@ -1129,6 +1261,129 @@ add_deny(location_t *loc) /* I - Location to add to */ } +#if !HAVE_LIBPAM +/* + * 'cups_crypt()' - Encrypt the password using the DES or MD5 algorithms, + * as needed. + */ + +static char * /* O - Encrypted password */ +cups_crypt(const char *pw, /* I - Password string */ + const char *salt) /* I - Salt (key) string */ +{ + if (strncmp(salt, "$1$", 3) == 0) + { + /* + * Use MD5 passwords without the benefit of PAM; this is for + * Slackware Linux, and the algorithm was taken from the + * old shadow-19990827/lib/md5crypt.c source code... :( + */ + + int i; /* Looping var */ + unsigned long n; /* Output number */ + int pwlen; /* Length of password string */ + const char *salt_end; /* End of "salt" data for MD5 */ + char *ptr; /* Pointer into result string */ + md5_state_t state; /* Primary MD5 state info */ + md5_state_t state2; /* Secondary MD5 state info */ + md5_byte_t digest[16]; /* MD5 digest result */ + static char result[120]; /* Final password string */ + + + /* + * Get the salt data between dollar signs, e.g. $1$saltdata$md5. + * Get a maximum of 8 characters of salt data after $1$... + */ + + for (salt_end = salt + 3; *salt_end && (salt_end - salt) < 11; salt_end ++) + if (*salt_end == '$') + break; + + /* + * Compute the MD5 sum we need... + */ + + pwlen = strlen(pw); + + md5_init(&state); + md5_append(&state, pw, pwlen); + md5_append(&state, salt, salt_end - salt); + + md5_init(&state2); + md5_append(&state2, pw, pwlen); + md5_append(&state2, salt + 3, salt_end - salt - 3); + md5_append(&state2, pw, pwlen); + md5_finish(&state, digest); + + for (i = pwlen; i > 0; i -= 16) + md5_append(&state, digest, i > 16 ? 16 : i); + + for (i = pwlen; i > 0; i >>= 1) + md5_append(&state, (i & 1) ? "" : pw, 1); + + md5_finish(&state, digest); + + for (i = 0; i < 1000; i ++) + { + md5_init(&state); + + if (i & 1) + md5_append(&state, pw, pwlen); + else + md5_append(&state, digest, 16); + + if (i % 3) + md5_append(&state, salt + 3, salt_end - salt - 3); + + if (i % 7) + md5_append(&state, pw, pwlen); + + if (i & 1) + md5_append(&state, digest, 16); + else + md5_append(&state, pw, pwlen); + + md5_finish(&state, digest); + } + + /* + * Copy the final sum to the result string and return... + */ + + memcpy(result, salt, salt_end - salt); + ptr = result + (salt_end - salt); + *ptr++ = '$'; + + for (i = 0; i < 5; i ++, ptr += 4) + { + n = (((digest[i] << 8) | digest[i + 6]) << 8); + + if (i < 4) + n |= digest[i + 12]; + else + n |= digest[5]; + + to64(ptr, n, 4); + } + + to64(ptr, digest[11], 2); + ptr += 2; + *ptr = '\0'; + + return (result); + } + else + { + /* + * Use the standard crypt() function... + */ + + return (crypt(pw, salt)); + } +} +#endif /* !HAVE_LIBPAM */ + + /* * 'get_md5_passwd()' - Get an MD5 password. */ @@ -1264,9 +1519,29 @@ pam_func(int num_msg, /* I - Number of messages */ return (PAM_SUCCESS); } +#else + + +/* + * 'to64()' - Base64-encode an integer value... + */ + +static void +to64(char *s, /* O - Output string */ + unsigned long v, /* I - Value to encode */ + int n) /* I - Number of digits */ +{ + const char *itoa64 = "./0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + + + for (; n > 0; n --, v >>= 6) + *s++ = itoa64[v & 0x3f]; +} #endif /* HAVE_LIBPAM */ /* - * End of "$Id: auth.c,v 1.41.2.2 2001/05/13 18:38:33 mike Exp $". + * End of "$Id: auth.c,v 1.41.2.3 2001/12/26 16:52:50 mike Exp $". */ diff --git a/scheduler/auth.h b/scheduler/auth.h index cf49207e75..3cdf5884f0 100644 --- a/scheduler/auth.h +++ b/scheduler/auth.h @@ -1,5 +1,5 @@ /* - * "$Id: auth.h,v 1.16.2.1 2001/04/02 19:51:47 mike Exp $" + * "$Id: auth.h,v 1.16.2.2 2001/12/26 16:52:50 mike Exp $" * * Authorization definitions for the Common UNIX Printing System (CUPS) * scheduler. @@ -30,6 +30,7 @@ #define AUTH_NONE 0 /* No authentication */ #define AUTH_BASIC 1 /* Basic authentication */ #define AUTH_DIGEST 2 /* Digest authentication */ +#define AUTH_BASICDIGEST 3 /* Basic authentication w/passwd.md5 */ #define AUTH_ANON 0 /* Anonymous access */ #define AUTH_USER 1 /* Must have a valid username/password */ @@ -125,11 +126,11 @@ extern void DeleteAllLocations(void); extern void DenyHost(location_t *loc, char *name); extern void DenyIP(location_t *loc, unsigned address[4], unsigned netmask[4]); -extern location_t *FindBest(client_t *con); +extern location_t *FindBest(client_t *con, http_state_t state); extern location_t *FindLocation(const char *location); extern http_status_t IsAuthorized(client_t *con); /* - * End of "$Id: auth.h,v 1.16.2.1 2001/04/02 19:51:47 mike Exp $". + * End of "$Id: auth.h,v 1.16.2.2 2001/12/26 16:52:50 mike Exp $". */ diff --git a/scheduler/banners.c b/scheduler/banners.c index dfe0b532de..49a74367ee 100644 --- a/scheduler/banners.c +++ b/scheduler/banners.c @@ -1,5 +1,5 @@ /* - * "$Id: banners.c,v 1.5 2001/01/22 15:03:58 mike Exp $" + * "$Id: banners.c,v 1.5.2.1 2001/12/26 16:52:50 mike Exp $" * * Banner routines for the Common UNIX Printing System (CUPS). * @@ -91,7 +91,6 @@ AddBanner(const char *name, /* I - Name of banner */ memset(temp, 0, sizeof(banner_t)); strncpy(temp->name, name, sizeof(temp->name) - 1); - strncpy(temp->filename, filename, sizeof(temp->filename) - 1); temp->filetype = filetype; } @@ -213,5 +212,5 @@ compare(const banner_t *b0, /* I - First banner */ /* - * End of "$Id: banners.c,v 1.5 2001/01/22 15:03:58 mike Exp $". + * End of "$Id: banners.c,v 1.5.2.1 2001/12/26 16:52:50 mike Exp $". */ diff --git a/scheduler/banners.h b/scheduler/banners.h index c616643ba9..5c7e39949d 100644 --- a/scheduler/banners.h +++ b/scheduler/banners.h @@ -1,5 +1,5 @@ /* - * "$Id: banners.h,v 1.2 2001/01/22 15:03:58 mike Exp $" + * "$Id: banners.h,v 1.2.2.1 2001/12/26 16:52:50 mike Exp $" * * Banner definitions for the Common UNIX Printing System (CUPS). * @@ -29,7 +29,6 @@ typedef struct { char name[256]; /* Name of banner */ - char filename[1024]; /* Full filename */ mime_type_t *filetype; /* Filetype for banner */ } banner_t; @@ -54,5 +53,5 @@ extern void LoadBanners(const char *d); /* - * End of "$Id: banners.h,v 1.2 2001/01/22 15:03:58 mike Exp $". + * End of "$Id: banners.h,v 1.2.2.1 2001/12/26 16:52:50 mike Exp $". */ diff --git a/scheduler/cert.c b/scheduler/cert.c index 325fb1d813..129a47a3e8 100644 --- a/scheduler/cert.c +++ b/scheduler/cert.c @@ -1,5 +1,5 @@ /* - * "$Id: cert.c,v 1.7.2.1 2001/05/13 18:38:34 mike Exp $" + * "$Id: cert.c,v 1.7.2.2 2001/12/26 16:52:50 mike Exp $" * * Authentication certificate routines for the Common UNIX * Printing System (CUPS). @@ -95,7 +95,7 @@ AddCert(int pid, /* I - Process ID */ fchmod(fileno(fp), 0440); - if ((grp = getgrnam(SystemGroup)) == NULL) + if ((grp = getgrnam(SystemGroups[0])) == NULL) fchown(fileno(fp), getuid(), 0); else fchown(fileno(fp), getuid(), grp->gr_gid); @@ -271,5 +271,5 @@ InitCerts(void) /* - * End of "$Id: cert.c,v 1.7.2.1 2001/05/13 18:38:34 mike Exp $". + * End of "$Id: cert.c,v 1.7.2.2 2001/12/26 16:52:50 mike Exp $". */ diff --git a/scheduler/classes.c b/scheduler/classes.c index f18442806d..973072bd5e 100644 --- a/scheduler/classes.c +++ b/scheduler/classes.c @@ -1,5 +1,5 @@ /* - * "$Id: classes.c,v 1.34.2.1 2001/04/02 19:51:47 mike Exp $" + * "$Id: classes.c,v 1.34.2.2 2001/12/26 16:52:50 mike Exp $" * * Printer class routines for the Common UNIX Printing System (CUPS). * @@ -374,12 +374,12 @@ LoadAllClasses(void) continue; /* - * Strip trailing newline, if any... + * Strip trailing whitespace, if any... */ len = strlen(line); - if (line[len - 1] == '\n') + while (len > 0 && isspace(line[len - 1])) { len --; line[len] = '\0'; @@ -600,8 +600,10 @@ SaveAllClasses(void) if (pclass->info[0]) fprintf(fp, "Info %s\n", pclass->info); - if (pclass->more_info[0]) + + if (pclass->location[0]) fprintf(fp, "Location %s\n", pclass->location); + if (pclass->state == IPP_PRINTER_STOPPED) { fputs("State Stopped\n", fp); @@ -609,6 +611,7 @@ SaveAllClasses(void) } else fputs("State Idle\n", fp); + if (pclass->accepting) fputs("Accepting Yes\n", fp); else @@ -617,12 +620,9 @@ SaveAllClasses(void) for (i = 0; i < pclass->num_printers; i ++) fprintf(fp, "Printer %s\n", pclass->printers[i]->name); - if (pclass->quota_period) - { - fprintf(fp, "QuotaPeriod %d\n", pclass->quota_period); - fprintf(fp, "PageLimit %d\n", pclass->page_limit); - fprintf(fp, "KLimit %d\n", pclass->k_limit); - } + fprintf(fp, "QuotaPeriod %d\n", pclass->quota_period); + fprintf(fp, "PageLimit %d\n", pclass->page_limit); + fprintf(fp, "KLimit %d\n", pclass->k_limit); for (i = 0; i < pclass->num_users; i ++) fprintf(fp, "%sUser %s\n", pclass->deny_users ? "Deny" : "Allow", @@ -636,5 +636,5 @@ SaveAllClasses(void) /* - * End of "$Id: classes.c,v 1.34.2.1 2001/04/02 19:51:47 mike Exp $". + * End of "$Id: classes.c,v 1.34.2.2 2001/12/26 16:52:50 mike Exp $". */ diff --git a/scheduler/client.c b/scheduler/client.c index 6fee41f944..dc799158bf 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -1,5 +1,5 @@ /* - * "$Id: client.c,v 1.91.2.3 2001/05/14 18:01:22 mike Exp $" + * "$Id: client.c,v 1.91.2.4 2001/12/26 16:52:50 mike Exp $" * * Client routines for the Common UNIX Printing System (CUPS) scheduler. * @@ -36,6 +36,7 @@ * check_if_modified() - Decode an "If-Modified-Since" line. * decode_auth() - Decode an authorization string. * get_file() - Get a filename and state info. + * install_conf_file() - Install a configuration file. * pipe_command() - Pipe the output of a command to the remote client. */ @@ -58,10 +59,13 @@ * Local functions... */ -static int check_if_modified(client_t *con, struct stat *filestats); -static void decode_auth(client_t *con); -static char *get_file(client_t *con, struct stat *filestats); -static int pipe_command(client_t *con, int infile, int *outfile, char *command, char *options); +static int check_if_modified(client_t *con, + struct stat *filestats); +static void decode_auth(client_t *con); +static char *get_file(client_t *con, struct stat *filestats); +static http_status_t install_conf_file(client_t *con); +static int pipe_command(client_t *con, int infile, int *outfile, + char *command, char *options); /* @@ -160,7 +164,7 @@ AcceptClient(listener_t *lis) /* I - Listener socket */ * Do double lookups as needed... */ - if ((host = gethostbyname(con->http.hostname)) != NULL) + if ((host = httpGetHostByName(con->http.hostname)) != NULL) { /* * See if the hostname maps to the same IP address... @@ -393,7 +397,7 @@ EncryptClient(client_t *con) /* I - Client to encrypt */ #ifdef HAVE_LIBSSL SSL_CTX *context; /* Context for encryption */ SSL *conn; /* Connection for encryption */ - int error; /* Error code */ + unsigned long error; /* Error code */ /* @@ -432,7 +436,7 @@ EncryptClient(client_t *con) /* I - Client to encrypt */ int /* O - 1 on success, 0 on error */ ReadClient(client_t *con) /* I - Client to read from */ { - char line[8192], /* Line from client... */ + char line[32768], /* Line from client... */ operation[64], /* Operation code from socket */ version[64]; /* HTTP version number string */ int major, minor; /* HTTP version numbers */ @@ -519,7 +523,7 @@ ReadClient(client_t *con) /* I - Client to read from */ if (major < 2) { con->http.version = (http_version_t)(major * 100 + minor); - if (con->http.version == HTTP_1_1) + if (con->http.version == HTTP_1_1 && KeepAlive) con->http.keep_alive = HTTP_KEEPALIVE_ON; else con->http.keep_alive = HTTP_KEEPALIVE_OFF; @@ -602,7 +606,8 @@ ReadClient(client_t *con) /* I - Client to read from */ decode_auth(con); - if (strncmp(con->http.fields[HTTP_FIELD_CONNECTION], "Keep-Alive", 10) == 0) + if (strncmp(con->http.fields[HTTP_FIELD_CONNECTION], "Keep-Alive", 10) == 0 && + KeepAlive) con->http.keep_alive = HTTP_KEEPALIVE_ON; if (con->http.fields[HTTP_FIELD_HOST][0] == '\0' && @@ -624,7 +629,7 @@ ReadClient(client_t *con) /* I - Client to read from */ * Do OPTIONS command... */ - if ((best = FindBest(con)) != NULL && + if ((best = FindBest(con->uri, con->http.state)) != NULL && best->type != AUTH_NONE) { if (!SendHeader(con, HTTP_UNAUTHORIZED, NULL)) @@ -669,7 +674,7 @@ ReadClient(client_t *con) /* I - Client to read from */ return (0); } - httpPrintf(HTTP(con), "Allow: GET, HEAD, OPTIONS, POST\r\n"); + httpPrintf(HTTP(con), "Allow: GET, HEAD, OPTIONS, POST, PUT\r\n"); httpPrintf(HTTP(con), "Content-Length: 0\r\n"); httpPrintf(HTTP(con), "\r\n"); } @@ -764,7 +769,8 @@ ReadClient(client_t *con) /* I - Client to read from */ } } - if (strncmp(con->uri, "/admin", 6) == 0 || + if ((strncmp(con->uri, "/admin", 6) == 0 && + strncmp(con->uri, "/admin/conf/", 12) != 0) || strncmp(con->uri, "/printers", 9) == 0 || strncmp(con->uri, "/classes", 8) == 0 || strncmp(con->uri, "/jobs", 5) == 0) @@ -815,6 +821,23 @@ ReadClient(client_t *con) /* I - Client to read from */ if (con->http.version <= HTTP_1_0) con->http.keep_alive = HTTP_KEEPALIVE_OFF; } + else if (strncmp(con->uri, "/admin/conf/", 12) == 0 && + (strchr(con->uri + 12, '/') != NULL || + strlen(con->uri) == 12)) + { + /* + * GET can only be done to configuration files under + * /admin/conf... + */ + + if (!SendError(con, HTTP_FORBIDDEN)) + { + CloseClient(con); + return (0); + } + + break; + } else { /* @@ -887,7 +910,8 @@ ReadClient(client_t *con) /* I - Client to read from */ if (strcmp(con->http.fields[HTTP_FIELD_CONTENT_TYPE], "application/ipp") == 0) con->request = ippNew(); - else if (strncmp(con->uri, "/admin", 6) == 0 || + else if ((strncmp(con->uri, "/admin", 6) == 0 && + strncmp(con->uri, "/admin/conf/", 12) != 0) || strncmp(con->uri, "/printers", 9) == 0 || strncmp(con->uri, "/classes", 8) == 0 || strncmp(con->uri, "/jobs", 5) == 0) @@ -938,6 +962,76 @@ ReadClient(client_t *con) /* I - Client to read from */ break; case HTTP_PUT_RECV : + /* + * Validate the resource name... + */ + + if (strncmp(con->uri, "/admin/conf/", 12) != 0 || + strchr(con->uri + 12, '/') != NULL || + strlen(con->uri) == 12) + { + /* + * PUT can only be done to configuration files under + * /admin/conf... + */ + + if (!SendError(con, HTTP_FORBIDDEN)) + { + CloseClient(con); + return (0); + } + + break; + } + + /* + * See if the PUT request includes a Content-Length field, and if + * so check the length against any limits that are set... + */ + + LogMessage(L_DEBUG2, "PUT %s", con->uri); + LogMessage(L_DEBUG2, "CONTENT_TYPE = %s", con->http.fields[HTTP_FIELD_CONTENT_TYPE]); + + if (con->http.fields[HTTP_FIELD_CONTENT_LENGTH][0] && + atoi(con->http.fields[HTTP_FIELD_CONTENT_LENGTH]) > MaxRequestSize && + MaxRequestSize > 0) + { + /* + * Request too large... + */ + + if (!SendError(con, HTTP_REQUEST_TOO_LARGE)) + { + CloseClient(con); + return (0); + } + + break; + } + + /* + * Open a temporary file to hold the request... + */ + + snprintf(con->filename, sizeof(con->filename), "%s/%08x", + RequestRoot, request_id ++); + con->file = open(con->filename, O_WRONLY | O_CREAT | O_TRUNC, 0640); + fchmod(con->file, 0640); + fchown(con->file, User, Group); + + LogMessage(L_DEBUG2, "ReadClient() %d REQUEST %s=%d", con->http.fd, + con->filename, con->file); + + if (con->file < 0) + { + if (!SendError(con, HTTP_REQUEST_TOO_LARGE)) + { + CloseClient(con); + return (0); + } + } + break; + case HTTP_DELETE : case HTTP_TRACE : SendError(con, HTTP_NOT_IMPLEMENTED); @@ -969,7 +1063,8 @@ ReadClient(client_t *con) /* I - Client to read from */ } } - if (strncmp(con->uri, "/admin/", 7) == 0 || + if ((strncmp(con->uri, "/admin/", 7) == 0 && + strncmp(con->uri, "/admin/conf/", 12) != 0) || strncmp(con->uri, "/printers/", 10) == 0 || strncmp(con->uri, "/classes/", 9) == 0 || strncmp(con->uri, "/jobs/", 6) == 0) @@ -992,6 +1087,23 @@ ReadClient(client_t *con) /* I - Client to read from */ LogRequest(con, HTTP_OK); } + else if (strncmp(con->uri, "/admin/conf/", 12) == 0 && + (strchr(con->uri + 12, '/') != NULL || + strlen(con->uri) == 12)) + { + /* + * HEAD can only be done to configuration files under + * /admin/conf... + */ + + if (!SendError(con, HTTP_FORBIDDEN)) + { + CloseClient(con); + return (0); + } + + break; + } else if ((filename = get_file(con, &filestats)) == NULL) { if (!SendHeader(con, HTTP_NOT_FOUND, "text/html")) @@ -1037,8 +1149,8 @@ ReadClient(client_t *con) /* I - Client to read from */ return (0); } - if (httpPrintf(HTTP(con), "Content-Length: %d\r\n", - filestats.st_size) < 0) + if (httpPrintf(HTTP(con), "Content-Length: %lu\r\n", + (unsigned long)filestats.st_size) < 0) { CloseClient(con); return (0); @@ -1069,6 +1181,90 @@ ReadClient(client_t *con) /* I - Client to read from */ switch (con->http.state) { case HTTP_PUT_RECV : + LogMessage(L_DEBUG2, "ReadClient() %d con->data_encoding = %s, con->data_remaining = %d, con->file = %d", + con->http.fd, + con->http.data_encoding == HTTP_ENCODE_CHUNKED ? "chunked" : "length", + con->http.data_remaining, con->file); + + if ((bytes = httpRead(HTTP(con), line, sizeof(line))) < 0) + { + CloseClient(con); + return (0); + } + else if (bytes > 0) + { + con->bytes += bytes; + + LogMessage(L_DEBUG2, "ReadClient() %d writing %d bytes to %d", + con->http.fd, bytes, con->file); + + if (write(con->file, line, bytes) < bytes) + { + LogMessage(L_ERROR, "ReadClient: Unable to write %d bytes to %s: %s", + bytes, con->filename, strerror(errno)); + + close(con->file); + con->file = 0; + unlink(con->filename); + con->filename[0] = '\0'; + + if (!SendError(con, HTTP_REQUEST_TOO_LARGE)) + { + CloseClient(con); + return (0); + } + } + } + + if (con->http.state == HTTP_WAITING) + { + /* + * End of file, see how big it is... + */ + + fstat(con->file, &filestats); + + LogMessage(L_DEBUG2, "ReadClient() %d Closing data file %d, size = %d.", + con->http.fd, con->file, filestats.st_size); + + close(con->file); + con->file = 0; + + if (filestats.st_size > MaxRequestSize && + MaxRequestSize > 0) + { + /* + * Request is too big; remove it and send an error... + */ + + LogMessage(L_DEBUG2, "ReadClient() %d Removing temp file %s", + con->http.fd, con->filename); + unlink(con->filename); + con->filename[0] = '\0'; + + if (!SendError(con, HTTP_REQUEST_TOO_LARGE)) + { + CloseClient(con); + return (0); + } + } + + /* + * Install the configuration file... + */ + + status = install_conf_file(con); + + /* + * Return the status to the client... + */ + + if (!SendError(con, status)) + { + CloseClient(con); + return (0); + } + } break; case HTTP_POST_RECV : @@ -1143,6 +1339,7 @@ ReadClient(client_t *con) /* I - Client to read from */ close(con->file); con->file = 0; unlink(con->filename); + con->filename[0] = '\0'; if (!SendError(con, HTTP_REQUEST_TOO_LARGE)) { @@ -1180,6 +1377,7 @@ ReadClient(client_t *con) /* I - Client to read from */ LogMessage(L_DEBUG2, "ReadClient() %d Removing temp file %s", con->http.fd, con->filename); unlink(con->filename); + con->filename[0] = '\0'; if (con->request) { @@ -1305,7 +1503,7 @@ SendError(client_t *con, /* I - Connection */ if (con->operation > HTTP_WAITING) LogRequest(con, code); - LogMessage(L_DEBUG2, "SendError() %d code=%d", con->http.fd, code); + LogMessage(L_DEBUG, "SendError() %d code=%d", con->http.fd, code); /* * To work around bugs in some proxies, don't use Keep-Alive for some @@ -1396,7 +1594,8 @@ SendFile(client_t *con, if (httpPrintf(HTTP(con), "Last-Modified: %s\r\n", httpGetDateString(filestats->st_mtime)) < 0) return (0); - if (httpPrintf(HTTP(con), "Content-Length: %d\r\n", filestats->st_size) < 0) + if (httpPrintf(HTTP(con), "Content-Length: %lu\r\n", + (unsigned long)filestats->st_size) < 0) return (0); if (httpPrintf(HTTP(con), "\r\n") < 0) return (0); @@ -1441,9 +1640,13 @@ SendHeader(client_t *con, /* I - Client to send to */ if (code == HTTP_UNAUTHORIZED) { - loc = FindBest(con); /* This already succeeded in IsAuthorized */ + /* + * This already succeeded in IsAuthorized... + */ + + loc = FindBest(con->uri, con->http.state); - if (loc->type == AUTH_BASIC) + if (loc->type != AUTH_DIGEST) { if (httpPrintf(HTTP(con), "WWW-Authenticate: Basic realm=\"CUPS\"\r\n") < 0) return (0); @@ -1609,6 +1812,7 @@ WriteClient(client_t *con) /* I - Client connection */ LogMessage(L_DEBUG2, "WriteClient() %d Removing temp file %s", con->http.fd, con->filename); unlink(con->filename); + con->filename[0] = '\0'; } if (con->request != NULL) @@ -1797,6 +2001,8 @@ get_file(client_t *con, /* I - Client connection */ if (strncmp(con->uri, "/ppd/", 5) == 0) snprintf(filename, sizeof(filename), "%s%s", ServerRoot, con->uri); + else if (strncmp(con->uri, "/admin/conf/", 12) == 0) + snprintf(filename, sizeof(filename), "%s%s", ServerRoot, con->uri + 11); else if (con->language != NULL) snprintf(filename, sizeof(filename), "%s/%s%s", DocumentRoot, con->language->language, con->uri); @@ -1817,7 +2023,8 @@ get_file(client_t *con, /* I - Client connection */ * Drop the language prefix and try the current directory... */ - if (strncmp(con->uri, "/ppd/", 5) != 0) + if (strncmp(con->uri, "/ppd/", 5) != 0 && + strncmp(con->uri, "/admin/conf/", 12) != 0) { snprintf(filename, sizeof(filename), "%s%s", DocumentRoot, con->uri); @@ -1851,6 +2058,160 @@ get_file(client_t *con, /* I - Client connection */ } +/* + * 'install_conf_file()' - Install a configuration file. + */ + +static http_status_t /* O - Status */ +install_conf_file(client_t *con) /* I - Connection */ +{ + FILE *in, /* Input file */ + *out; /* Output file */ + char buffer[1024]; /* Copy buffer */ + int bytes; /* Number of bytes */ + char conffile[1024], /* Configuration filename */ + newfile[1024], /* New config filename */ + oldfile[1024]; /* Old config filename */ + struct stat confinfo; /* Config file info */ + + + /* + * First construct the filenames... + */ + + snprintf(conffile, sizeof(conffile), "%s%s", ServerRoot, con->uri + 11); + snprintf(newfile, sizeof(newfile), "%s%s.N", ServerRoot, con->uri + 11); + snprintf(oldfile, sizeof(oldfile), "%s%s.O", ServerRoot, con->uri + 11); + + LogMessage(L_INFO, "Installing config file \"%s\"...", conffile); + + /* + * Get the owner, group, and permissions of the configuration file. + * If it doesn't exist, assign it to the User and Group in the + * cupsd.conf file with mode 0640 permissions. + */ + + if (stat(conffile, &confinfo)) + { + confinfo.st_uid = User; + confinfo.st_gid = Group; + confinfo.st_mode = 0640; + } + + /* + * Open the request file and new config file... + */ + + if ((in = fopen(con->filename, "rb")) == NULL) + { + LogMessage(L_ERROR, "Unable to open request file \"%s\" - %s", + con->filename, strerror(errno)); + return (HTTP_SERVER_ERROR); + } + + if ((out = fopen(newfile, "wb")) == NULL) + { + fclose(in); + LogMessage(L_ERROR, "Unable to open config file \"%s\" - %s", + newfile, strerror(errno)); + return (HTTP_SERVER_ERROR); + } + + fchmod(fileno(out), confinfo.st_mode); + fchown(fileno(out), confinfo.st_uid, confinfo.st_gid); + + /* + * Copy from the request to the new config file... + */ + + while ((bytes = fread(buffer, 1, sizeof(buffer), in)) > 0) + if (fwrite(buffer, 1, bytes, out) < bytes) + { + LogMessage(L_ERROR, "Unable to copy to config file \"%s\" - %s", + newfile, strerror(errno)); + + fclose(in); + fclose(out); + unlink(newfile); + + return (HTTP_SERVER_ERROR); + } + + /* + * Close the files... + */ + + fclose(in); + if (fclose(out)) + { + LogMessage(L_ERROR, "Error file closing config file \"%s\" - %s", + newfile, strerror(errno)); + + unlink(newfile); + + return (HTTP_SERVER_ERROR); + } + + /* + * Remove the request file... + */ + + unlink(con->filename); + con->filename[0] = '\0'; + + /* + * Unlink the old backup, rename the current config file to the backup + * filename, and rename the new config file to the config file name... + */ + + if (unlink(oldfile)) + if (errno != ENOENT) + { + LogMessage(L_ERROR, "Unable to remove backup config file \"%s\" - %s", + oldfile, strerror(errno)); + + unlink(newfile); + + return (HTTP_SERVER_ERROR); + } + + if (rename(conffile, oldfile)) + if (errno != ENOENT) + { + LogMessage(L_ERROR, "Unable to rename old config file \"%s\" - %s", + conffile, strerror(errno)); + + unlink(newfile); + + return (HTTP_SERVER_ERROR); + } + + if (rename(newfile, conffile)) + { + LogMessage(L_ERROR, "Unable to rename new config file \"%s\" - %s", + newfile, strerror(errno)); + + rename(oldfile, conffile); + unlink(newfile); + + return (HTTP_SERVER_ERROR); + } + + /* + * If the cupsd.conf file was updated, set the NeedReload flag... + */ + + if (strcmp(con->uri, "/admin/conf/cupsd.conf") == 0) + NeedReload = TRUE; + + /* + * Return that the file was created successfully... + */ + + return (HTTP_CREATED); +} + + /* * 'pipe_command()' - Pipe the output of a command to the remote client. */ @@ -2051,7 +2412,7 @@ pipe_command(client_t *con, /* I - Client connection */ if (getuid() == 0) { /* - * Running as root, so change to non-priviledged user... + * Running as root, so change to a non-priviledged user... */ if (setgid(Group)) @@ -2074,11 +2435,13 @@ pipe_command(client_t *con, /* I - Client connection */ if (infile) { close(0); - dup(infile); + if (dup(infile) < 0) + exit(errno); } close(1); - dup(fds[1]); + if (dup(fds[1]) < 0) + exit(errno); /* * Close extra file descriptors... @@ -2098,7 +2461,6 @@ pipe_command(client_t *con, /* I - Client connection */ */ execve(command, argv, envp); - perror("execve failed"); exit(errno); return (0); } @@ -2123,7 +2485,7 @@ pipe_command(client_t *con, /* I - Client connection */ AddCert(pid, con->username); - LogMessage(L_DEBUG, "CGI %s started - PID = %d", argv[0], pid); + LogMessage(L_DEBUG, "CGI %s started - PID = %d", command, pid); *outfile = fds[0]; close(fds[1]); @@ -2134,5 +2496,5 @@ pipe_command(client_t *con, /* I - Client connection */ /* - * End of "$Id: client.c,v 1.91.2.3 2001/05/14 18:01:22 mike Exp $". + * End of "$Id: client.c,v 1.91.2.4 2001/12/26 16:52:50 mike Exp $". */ diff --git a/scheduler/conf.c b/scheduler/conf.c index c0fceaddc0..6da9c3b7fa 100644 --- a/scheduler/conf.c +++ b/scheduler/conf.c @@ -1,5 +1,5 @@ /* - * "$Id: conf.c,v 1.77.2.1 2001/04/02 19:51:48 mike Exp $" + * "$Id: conf.c,v 1.77.2.2 2001/12/26 16:52:51 mike Exp $" * * Configuration routines for the Common UNIX Printing System (CUPS). * @@ -85,6 +85,7 @@ static var_t variables[] = { "BrowseTimeout", &BrowseTimeout, VAR_INTEGER, 0 }, { "Browsing", &Browsing, VAR_BOOLEAN, 0 }, { "Classification", Classification, VAR_STRING, sizeof(Classification) }, + { "ClassifyOverride", &ClassifyOverride, VAR_BOOLEAN, 0 }, { "DataDir", DataDir, VAR_STRING, sizeof(DataDir) }, { "DefaultCharset", DefaultCharset, VAR_STRING, sizeof(DefaultCharset) }, { "DefaultLanguage", DefaultLanguage, VAR_STRING, sizeof(DefaultLanguage) }, @@ -92,7 +93,9 @@ static var_t variables[] = { "ErrorLog", ErrorLog, VAR_STRING, sizeof(ErrorLog) }, { "FilterLimit", &FilterLimit, VAR_INTEGER, 0 }, { "FontPath", FontPath, VAR_STRING, sizeof(FontPath) }, + { "HideImplicitMembers", &HideImplicitMembers, VAR_BOOLEAN, 0 }, { "ImplicitClasses", &ImplicitClasses, VAR_BOOLEAN, 0 }, + { "ImplicitAnyClasses", &ImplicitAnyClasses, VAR_BOOLEAN, 0 }, { "KeepAliveTimeout", &KeepAliveTimeout, VAR_INTEGER, 0 }, { "KeepAlive", &KeepAlive, VAR_BOOLEAN, 0 }, { "LimitRequestBody", &MaxRequestSize, VAR_INTEGER, 0 }, @@ -120,7 +123,6 @@ static var_t variables[] = #endif /* HAVE_LIBSSL */ { "ServerName", ServerName, VAR_STRING, sizeof(ServerName) }, { "ServerRoot", ServerRoot, VAR_STRING, sizeof(ServerRoot) }, - { "SystemGroup", SystemGroup, VAR_STRING, sizeof(SystemGroup) }, { "TempDir", TempDir, VAR_STRING, sizeof(TempDir) }, { "Timeout", &Timeout, VAR_INTEGER, 0 } }; @@ -158,7 +160,10 @@ ReadConfiguration(void) int i; /* Looping var */ FILE *fp; /* Configuration file */ int status; /* Return status */ - char directory[1024];/* Configuration directory */ + char directory[1024],/* Configuration directory */ + *slash; /* Directory separator */ + char type[MIME_MAX_SUPER + MIME_MAX_TYPE]; + /* MIME type name */ struct rlimit limit; /* Runtime limit */ char *language; /* Language string */ struct passwd *user; /* Default user */ @@ -196,6 +201,14 @@ ReadConfiguration(void) if (MimeDatabase != NULL) mimeDelete(MimeDatabase); + if (NumMimeTypes) + { + for (i = 0; i < NumMimeTypes; i ++) + free((void *)MimeTypes[i]); + + free(MimeTypes); + } + for (i = 0; i < NumRelays; i ++) if (Relays[i].from.type == AUTH_NAME) free(Relays[i].from.mask.name.name); @@ -214,7 +227,6 @@ ReadConfiguration(void) gethostname(ServerName, sizeof(ServerName)); snprintf(ServerAdmin, sizeof(ServerAdmin), "root@%s", ServerName); - strcpy(ServerRoot, CUPS_SERVERROOT); strcpy(ServerBin, CUPS_SERVERBIN); strcpy(RequestRoot, CUPS_REQUESTS); strcpy(DocumentRoot, CUPS_DOCROOT); @@ -226,7 +238,12 @@ ReadConfiguration(void) strcpy(FontPath, CUPS_FONTPATH); strcpy(RemoteRoot, "remroot"); + strcpy(ServerRoot, ConfigurationFile); + if ((slash = strrchr(ServerRoot, '/')) != NULL) + *slash = '\0'; + Classification[0] = '\0'; + ClassifyOverride = 0; #ifdef HAVE_LIBSSL strcpy(ServerCertificate, "ssl/server.crt"); @@ -257,39 +274,30 @@ ReadConfiguration(void) * Find the default system group: "sys", "system", or "root"... */ - group = getgrnam("sys"); + group = getgrnam(CUPS_DEFAULT_GROUP); endgrent(); + NumSystemGroups = 0; + if (group != NULL) { - strcpy(SystemGroup, "sys"); + strcpy(SystemGroups[0], CUPS_DEFAULT_GROUP); Group = group->gr_gid; } else { - group = getgrnam("system"); + group = getgrgid(0); endgrent(); if (group != NULL) { - strcpy(SystemGroup, "system"); - Group = group->gr_gid; + strcpy(SystemGroups[0], group->gr_name); + Group = 0; } else { - group = getgrnam("root"); - endgrent(); - - if (group != NULL) - { - strcpy(SystemGroup, "root"); - Group = group->gr_gid; - } - else - { - strcpy(SystemGroup, "unknown"); - Group = 0; - } + strcpy(SystemGroups[0], "unknown"); + Group = 0; } } @@ -297,7 +305,7 @@ ReadConfiguration(void) * Find the default user... */ - if ((user = getpwnam("lp")) == NULL) + if ((user = getpwnam(CUPS_DEFAULT_USER)) == NULL) User = 1; /* Force to a non-priviledged account */ else User = user->pw_uid; @@ -412,14 +420,56 @@ ReadConfiguration(void) ServerCertificate[sizeof(ServerCertificate) - 1] = '\0'; } + chown(ServerCertificate, User, Group); + chmod(ServerCertificate, 0600); + if (ServerKey[0] != '/') { snprintf(directory, sizeof(directory), "%s/%s", ServerRoot, ServerKey); strncpy(ServerKey, directory, sizeof(ServerKey) - 1); ServerKey[sizeof(ServerKey) - 1] = '\0'; } + + chown(ServerKey, User, Group); + chmod(ServerKey, 0600); #endif /* HAVE_LIBSSL */ + /* + * Make sure that ServerRoot and the config files are owned and + * writable by the user and group in the cupsd.conf file... + */ + + chown(ServerRoot, User, Group); + chmod(ServerRoot, 0755); + + snprintf(directory, sizeof(directory), "%s/certs", ServerRoot); + chown(directory, User, Group); + chmod(directory, 0711); + + snprintf(directory, sizeof(directory), "%s/ppd", ServerRoot); + chown(directory, User, Group); + chmod(directory, 0755); + + snprintf(directory, sizeof(directory), "%s/ssl", ServerRoot); + chown(directory, User, Group); + chmod(directory, 0700); + + snprintf(directory, sizeof(directory), "%s/cupsd.conf", ServerRoot); + chown(directory, User, Group); + chmod(directory, 0600); + + snprintf(directory, sizeof(directory), "%s/classes.conf", ServerRoot); + chown(directory, User, Group); + chmod(directory, 0600); + + snprintf(directory, sizeof(directory), "%s/printers.conf", ServerRoot); + chown(directory, User, Group); + chmod(directory, 0600); + + snprintf(directory, sizeof(directory), "%s/passwd.md5", ServerRoot); + chown(directory, User, Group); + chmod(directory, 0600); + /* * Make sure the request and temporary directories have the right * permissions... @@ -445,7 +495,7 @@ ReadConfiguration(void) getrlimit(RLIMIT_NOFILE, &limit); - if (MaxClients > (limit.rlim_max / 3)) + if (MaxClients > (limit.rlim_max / 3) || MaxClients <= 0) MaxClients = limit.rlim_max / 3; if ((Clients = calloc(sizeof(client_t), MaxClients)) == NULL) @@ -465,6 +515,12 @@ ReadConfiguration(void) if (MaxActiveJobs > (limit.rlim_max / 3)) MaxActiveJobs = limit.rlim_max / 3; + if (strcasecmp(Classification, "none") == 0) + Classification[0] = '\0'; + + if (Classification[0]) + LogMessage(L_INFO, "Security set to \"%s\"", Classification); + /* * Read the MIME type and conversion database... */ @@ -472,6 +528,28 @@ ReadConfiguration(void) MimeDatabase = mimeNew(); mimeMerge(MimeDatabase, ServerRoot); + /* + * Create a list of MIME types for the document-format-supported + * attribute... + */ + + NumMimeTypes = MimeDatabase->num_types; + if (!mimeType(MimeDatabase, "application", "octet-stream")) + NumMimeTypes ++; + + MimeTypes = calloc(NumMimeTypes, sizeof(const char *)); + + for (i = 0; i < MimeDatabase->num_types; i ++) + { + snprintf(type, sizeof(type), "%s/%s", MimeDatabase->types[i]->super, + MimeDatabase->types[i]->type); + + MimeTypes[i] = strdup(type); + } + + if (i < NumMimeTypes) + MimeTypes[i] = strdup("application/octet-stream"); + /* * Load banners... */ @@ -526,6 +604,7 @@ read_configuration(FILE *fp) /* I - File to read from */ name[256], /* Parameter name */ *nameptr, /* Pointer into name */ *value; /* Pointer to value */ + int valuelen; /* Length of value */ var_t *var; /* Current variable */ unsigned ip[4], /* Address value */ mask[4]; /* Netmask value */ @@ -533,6 +612,15 @@ read_configuration(FILE *fp) /* I - File to read from */ dirsvc_poll_t *poll; /* Polling data */ http_addr_t polladdr; /* Polling address */ location_t *location; /* Browse location */ + FILE *incfile; /* Include file */ + char incname[1024]; /* Include filename */ + static unsigned netmasks[4] = /* Standard netmasks... */ + { + 0xff000000, + 0xffff0000, + 0xffffff00, + 0xffffffff + }; /* @@ -553,12 +641,12 @@ read_configuration(FILE *fp) /* I - File to read from */ continue; /* - * Strip trailing newline, if any... + * Strip trailing whitespace, if any... */ len = strlen(line); - if (line[len - 1] == '\n') + while (len > 0 && isspace(line[len - 1])) { len --; line[len] = '\0'; @@ -585,7 +673,30 @@ read_configuration(FILE *fp) /* I - File to read from */ * Decode the directive... */ - if (strcasecmp(name, " @@ -726,6 +837,46 @@ read_configuration(FILE *fp) /* I - File to read from */ LogMessage(L_ERROR, "Unknown BrowseOrder value %s on line %d.", value, linenum); } + else if (strcasecmp(name, "BrowseProtocols") == 0) + { + /* + * "BrowseProtocol name [... name]" + */ + + BrowseProtocols = 0; + + for (; *value;) + { + for (valuelen = 0; value[valuelen]; valuelen ++) + if (isspace(value[valuelen]) || value[valuelen] == ',') + break; + + if (value[valuelen]) + { + value[valuelen] = '\0'; + valuelen ++; + } + + if (strcasecmp(value, "cups") == 0) + BrowseProtocols |= BROWSE_CUPS; + else if (strcasecmp(value, "slp") == 0) + BrowseProtocols |= BROWSE_SLP; + else if (strcasecmp(value, "ldap") == 0) + BrowseProtocols |= BROWSE_LDAP; + else if (strcasecmp(value, "all") == 0) + BrowseProtocols |= BROWSE_ALL; + else + { + LogMessage(L_ERROR, "Unknown browse protocol \"%s\" on line %d.", + value, linenum); + break; + } + + for (value += valuelen; *value; value ++) + if (!isspace(*value) || *value != ',') + break; + } + } else if (strcasecmp(name, "BrowseAllow") == 0 || strcasecmp(name, "BrowseDeny") == 0) { @@ -1048,6 +1199,34 @@ read_configuration(FILE *fp) /* I - File to read from */ value); } } + else if (strcasecmp(name, "SystemGroup") == 0) + { + /* + * System (admin) group(s)... + */ + + char *valueptr; /* Pointer into value */ + + + for (i = 0; i < MAX_SYSTEM_GROUPS; i ++) + { + for (valueptr = value; *valueptr; valueptr ++) + if (isspace(*valueptr) || *valueptr == ',') + break; + + if (*valueptr) + *valueptr++ = '\0'; + + strncpy(SystemGroups[i], value, sizeof(SystemGroups[0])); + SystemGroups[i][sizeof(SystemGroups[0]) - 1] = '\0'; + + while (*value == ',' || isspace(*value)) + value ++; + } + + if (i) + NumSystemGroups = i; + } else if (strcasecmp(name, "HostNameLookups") == 0) { /* @@ -1131,7 +1310,31 @@ read_configuration(FILE *fp) /* I - File to read from */ switch (var->type) { case VAR_INTEGER : - *((int *)var->ptr) = atoi(value); + { + float n; /* Number */ + char units[255]; /* Units */ + + + switch (sscanf(value, "%f%254s", &n, units)) + { + case 0 : + n = 0.0; + case 1 : + break; + case 2 : + if (tolower(units[0]) == 'g') + n *= 1024.0 * 1024.0 * 1024.0; + else if (tolower(units[0]) == 'm') + n *= 1024.0 * 1024.0; + else if (tolower(units[0]) == 'k') + n *= 1024.0; + else if (tolower(units[0]) == 't') + n *= 262144.0; + break; + } + + *((int *)var->ptr) = (int)n; + } break; case VAR_BOOLEAN : @@ -1173,6 +1376,7 @@ read_location(FILE *fp, /* I - Configuration file */ char *location, /* I - Location name/path */ int linenum) /* I - Current line number */ { + int i; /* Looping var */ location_t *loc, /* New location */ *parent; /* Parent location */ int len; /* Length of line */ @@ -1203,12 +1407,12 @@ read_location(FILE *fp, /* I - Configuration file */ continue; /* - * Strip trailing newline, if any... + * Strip trailing whitespace, if any... */ len = strlen(line); - if (line[len - 1] == '\n') + while (len > 0 && isspace(line[len - 1])) { len --; line[len] = '\0'; @@ -1290,7 +1494,12 @@ read_location(FILE *fp, /* I - Configuration file */ if (strcasecmp(value, "never") == 0) loc->encryption = HTTP_ENCRYPT_NEVER; else if (strcasecmp(value, "always") == 0) - loc->encryption = HTTP_ENCRYPT_ALWAYS; + { + LogMessage(L_ERROR, "Encryption value \"%s\" on line %d is invalid in this context. " + "Using \"required\" instead.", value, linenum); + + loc->encryption = HTTP_ENCRYPT_REQUIRED; + } else if (strcasecmp(value, "required") == 0) loc->encryption = HTTP_ENCRYPT_REQUIRED; else if (strcasecmp(value, "ifrequested") == 0) @@ -1429,6 +1638,13 @@ read_location(FILE *fp, /* I - Configuration file */ if (loc->level == AUTH_ANON) loc->level = AUTH_USER; } + else if (strcasecmp(value, "basicdigest") == 0) + { + loc->type = AUTH_BASICDIGEST; + + if (loc->level == AUTH_ANON) + loc->level = AUTH_USER; + } else LogMessage(L_WARN, "Unknown authorization type %s on line %d.", value, linenum); @@ -1451,7 +1667,9 @@ read_location(FILE *fp, /* I - Configuration file */ else if (strcasecmp(value, "system") == 0) { loc->level = AUTH_GROUP; - AddName(loc, SystemGroup); + + for (i = 0; i < NumSystemGroups; i ++) + AddName(loc, SystemGroups[i]); } else LogMessage(L_WARN, "Unknown authorization class %s on line %d.", @@ -1510,7 +1728,7 @@ read_location(FILE *fp, /* I - Configuration file */ { if (strcasecmp(value, "all") == 0) loc->satisfy = AUTH_SATISFY_ALL; - if (strcasecmp(value, "any") == 0) + else if (strcasecmp(value, "any") == 0) loc->satisfy = AUTH_SATISFY_ANY; else LogMessage(L_WARN, "Unknown Satisfy value %s on line %d.", value, @@ -1599,11 +1817,11 @@ get_address(const char *value, /* I - Value string */ * Decode the hostname and port number as needed... */ - if (hostname[0] != '\0') + if (hostname[0] && strcmp(hostname, "*") != 0) { - if ((host = gethostbyname(hostname)) == NULL) + if ((host = httpGetHostByName(hostname)) == NULL) { - LogMessage(L_ERROR, "gethostbyname(\"%s\") failed - %s!", hostname, + LogMessage(L_ERROR, "httpGetHostByName(\"%s\") failed - %s!", hostname, strerror(errno)); return (0); } @@ -1777,5 +1995,5 @@ get_addr_and_mask(const char *value, /* I - String from config file */ /* - * End of "$Id: conf.c,v 1.77.2.1 2001/04/02 19:51:48 mike Exp $". + * End of "$Id: conf.c,v 1.77.2.2 2001/12/26 16:52:51 mike Exp $". */ diff --git a/scheduler/conf.h b/scheduler/conf.h index c01210a206..76790818a7 100644 --- a/scheduler/conf.h +++ b/scheduler/conf.h @@ -1,5 +1,5 @@ /* - * "$Id: conf.h,v 1.36 2001/03/14 13:45:34 mike Exp $" + * "$Id: conf.h,v 1.36.2.1 2001/12/26 16:52:51 mike Exp $" * * Configuration file definitions for the Common UNIX Printing System (CUPS) * scheduler. @@ -64,10 +64,12 @@ VAR char ConfigurationFile[256] VALUE(CUPS_SERVERROOT "/cupsd.conf"), /* Root directory for binaries */ RequestRoot[1024] VALUE(CUPS_REQUESTS), /* Directory for request files */ - DocumentRoot[1024] VALUE(CUPS_DOCROOT), + DocumentRoot[1024] VALUE(CUPS_DOCROOT); /* Root directory for documents */ - SystemGroup[32], - /* System group name */ +VAR int NumSystemGroups VALUE(0); + /* Number of system group names */ +VAR char SystemGroups[MAX_SYSTEM_GROUPS][32], + /* System group names */ AccessLog[1024] VALUE(CUPS_LOGDIR "/access_log"), /* Access log filename */ ErrorLog[1024] VALUE(CUPS_LOGDIR "/error_log"), @@ -92,7 +94,9 @@ VAR char ConfigurationFile[256] VALUE(CUPS_SERVERROOT "/cupsd.conf"), /* Remote root user */ Classification[IPP_MAX_NAME] VALUE(""); /* Classification of system */ -VAR int User VALUE(1), +VAR int ClassifyOverride VALUE(0), + /* Allow overrides? */ + User VALUE(1), /* User ID for server */ Group VALUE(0), /* Group ID for server */ @@ -114,6 +118,10 @@ VAR int User VALUE(1), /* Timeout between requests */ ImplicitClasses VALUE(TRUE), /* Are classes implicitly created? */ + ImplicitAnyClasses VALUE(FALSE), + /* Create AnyPrinter classes? */ + HideImplicitMembers VALUE(TRUE), + /* Hide implicit class members? */ FilterLimit VALUE(0), /* Max filter cost at any time */ FilterLevel VALUE(0), @@ -130,6 +138,10 @@ VAR FILE *AccessFile VALUE(NULL), /* Page log file */ VAR mime_t *MimeDatabase VALUE(NULL); /* MIME type database */ +VAR int NumMimeTypes VALUE(0); + /* Number of MIME types */ +VAR const char **MimeTypes VALUE(NULL); + /* Array of MIME types */ #ifdef HAVE_LIBSSL VAR char ServerCertificate[1024] VALUE("ssl/server.crt"), @@ -151,5 +163,5 @@ extern int LogPage(job_t *job, const char *page); /* - * End of "$Id: conf.h,v 1.36 2001/03/14 13:45:34 mike Exp $". + * End of "$Id: conf.h,v 1.36.2.1 2001/12/26 16:52:51 mike Exp $". */ diff --git a/scheduler/cups-lpd.c b/scheduler/cups-lpd.c index 7d6a8e0464..a76f0ae274 100644 --- a/scheduler/cups-lpd.c +++ b/scheduler/cups-lpd.c @@ -1,5 +1,5 @@ /* - * "$Id: cups-lpd.c,v 1.24.2.2 2001/05/13 18:38:34 mike Exp $" + * "$Id: cups-lpd.c,v 1.24.2.3 2001/12/26 16:52:51 mike Exp $" * * Line Printer Daemon interface for the Common UNIX Printing System (CUPS). * @@ -43,6 +43,8 @@ #include #include #include +#include +#include #include #include @@ -228,28 +230,26 @@ main(int argc, /* I - Number of command-line arguments */ case 0x02 : /* Receive a printer job */ syslog(LOG_INFO, "Receive print job for %s", dest); - putchar(0); + /* recv_print_job() sends initial status byte */ status = recv_print_job(dest, num_defaults, defaults); break; case 0x03 : /* Send queue state (short) */ syslog(LOG_INFO, "Send queue state (short) for %s %s", dest, list); - putchar(0); + /* send_state() sends initial status byte */ status = send_state(dest, list, 0); break; case 0x04 : /* Send queue state (long) */ syslog(LOG_INFO, "Send queue state (long) for %s %s", dest, list); - putchar(0); + /* send_state() sends initial status byte */ status = send_state(dest, list, 1); break; case 0x05 : /* Remove jobs */ - putchar(0); - /* * Grab the agent and skip to the list of users and/or jobs. */ @@ -263,6 +263,8 @@ main(int argc, /* I - Number of command-line arguments */ syslog(LOG_INFO, "Remove jobs %s on %s by %s", list, dest, agent); status = remove_jobs(dest, agent, list); + + putchar(status); break; } @@ -282,7 +284,7 @@ print_file(const char *name, /* I - Printer or class name */ const char *file, /* I - File to print */ const char *title, /* I - Title of job */ const char *docname, /* I - Name of job file */ - const char *user, /* I - Title of job */ + const char *user, /* I - Owner of job */ int num_options, /* I - Number of options */ cups_option_t *options) /* I - Options */ { @@ -365,15 +367,21 @@ print_file(const char *name, /* I - Printer or class name */ else jobid = attr->values[0].integer; + if (jobid) + syslog(LOG_INFO, "Print file - job ID = %d", jobid); + else if (response) + syslog(LOG_ERR, "Unable to print file - %s", + ippErrorString(response->request.status.status_code)); + else + syslog(LOG_ERR, "Unable to print file - %s", + ippErrorString(cupsLastError())); + if (response != NULL) ippDelete(response); httpClose(http); cupsLangFree(language); - if (jobid) - syslog(LOG_INFO, "Print file - job ID = %d", jobid); - return (jobid); } @@ -416,6 +424,9 @@ recv_print_job(const char *dest, /* I - Destination */ status = 0; num_data = 0; + fd = -1; + + control[0] = '\0'; strncpy(queue, dest, sizeof(queue) - 1); queue[sizeof(queue) - 1] = '\0'; @@ -432,8 +443,13 @@ recv_print_job(const char *dest, /* I - Destination */ syslog(LOG_ERR, "Unknown destination %s!", queue); cupsFreeDests(num_dests, dests); + + putchar(1); + return (1); } + else + putchar(0); while (smart_gets(line, sizeof(line), stdin) != NULL) { @@ -465,16 +481,38 @@ recv_print_job(const char *dest, /* I - Destination */ break; } - if ((fd = cupsTempFd(control, sizeof(control))) < 0) + if (control[0]) { - syslog(LOG_ERR, "Unable to open temporary control file - %s", - strerror(errno)); - putchar(1); - status = 1; - break; - } + /* + * Append to the existing control file - the LPD spec is + * not entirely clear, but at least the OS/2 LPD code sends + * multiple control files per connection... + */ + + if ((fd = open(control, O_WRONLY)) < 0) + { + syslog(LOG_ERR, "Unable to append to temporary control file - %s", + strerror(errno)); + putchar(1); + status = 1; + break; + } - strcpy(filename, control); + lseek(fd, 0, SEEK_END); + } + else + { + if ((fd = cupsTempFd(control, sizeof(control))) < 0) + { + syslog(LOG_ERR, "Unable to open temporary control file - %s", + strerror(errno)); + putchar(1); + status = 1; + break; + } + + strcpy(filename, control); + } break; case 0x03 : /* Receive data file */ if (strlen(name) < 2) @@ -649,13 +687,14 @@ recv_print_job(const char *dest, /* I - Destination */ case 't' : /* Print troff output file */ case 'v' : /* Print raster file */ /* - * Verify that we have a username... + * Check that we have a username... */ if (!user[0]) { - status = 1; - break; + syslog(LOG_WARNING, "No username specified by client! " + "Using \"anonymous\"..."); + strcpy(user, "anonymous"); } /* @@ -765,7 +804,10 @@ remove_jobs(const char *dest, /* I - Destination */ if ((http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption())) == NULL) + { + syslog(LOG_ERR, "Unable to connect to server: %s", strerror(errno)); return (1); + } language = cupsLangDefault(); @@ -849,7 +891,7 @@ remove_jobs(const char *dest, /* I - Destination */ /* - * 'send_short_state()' - Send the short queue state. + * 'send_state()' - Send the queue state. */ int /* O - Command status */ @@ -919,7 +961,11 @@ send_state(const char *dest, /* I - Destination */ if ((http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption())) == NULL) + { + syslog(LOG_ERR, "Unable to connect to server: %s", strerror(errno)); + putchar(1); return (1); + } /* * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following @@ -961,8 +1007,11 @@ send_state(const char *dest, /* I - Destination */ syslog(LOG_WARNING, "Unable to get printer list: %s\n", ippErrorString(response->request.status.status_code)); ippDelete(response); + putchar(1); return (1); } + else + putchar(0); if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL) state = (ipp_pstate_t)attr->values[0].integer; @@ -988,6 +1037,7 @@ send_state(const char *dest, /* I - Destination */ { syslog(LOG_WARNING, "Unable to get printer list: %s\n", ippErrorString(cupsLastError())); + putchar(1); return (1); } @@ -1238,5 +1288,5 @@ smart_gets(char *s, /* I - Pointer to line buffer */ /* - * End of "$Id: cups-lpd.c,v 1.24.2.2 2001/05/13 18:38:34 mike Exp $". + * End of "$Id: cups-lpd.c,v 1.24.2.3 2001/12/26 16:52:51 mike Exp $". */ diff --git a/scheduler/cups-polld.c b/scheduler/cups-polld.c index 6cbac56687..3932806a2f 100644 --- a/scheduler/cups-polld.c +++ b/scheduler/cups-polld.c @@ -1,5 +1,5 @@ /* - * "$Id: cups-polld.c,v 1.5.2.1 2001/05/13 18:38:35 mike Exp $" + * "$Id: cups-polld.c,v 1.5.2.2 2001/12/26 16:52:52 mike Exp $" * * Polling daemon for the Common UNIX Printing System (CUPS). * @@ -23,6 +23,8 @@ * * Contents: * + * main() - Open socks and poll until we are killed... + * poll_server() - Poll the server for the given set of printers or classes. */ /* @@ -118,11 +120,8 @@ main(int argc, /* I - Number of command-line arguments */ for (;;) { - if (poll_server(http, language, CUPS_GET_PRINTERS, sock, port)) - continue; - - if (poll_server(http, language, CUPS_GET_CLASSES, sock, port)) - continue; + if (!poll_server(http, language, CUPS_GET_PRINTERS, sock, port)) + poll_server(http, language, CUPS_GET_CLASSES, sock, port); sleep(interval); } @@ -151,6 +150,15 @@ poll_server(http_t *http, /* I - HTTP connection */ ipp_pstate_t state; /* printer-state */ struct sockaddr_in addr; /* Broadcast address */ char packet[1540]; /* Data packet */ + static const char *attrs[] = /* Requested attributes */ + { + "printer-info", + "printer-location", + "printer-make-and-model", + "printer-state", + "printer-type", + "printer-uri-supported" + }; /* @@ -180,6 +188,10 @@ poll_server(http_t *http, /* I - HTTP connection */ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", sizeof(attrs) / sizeof(attrs[0]), + NULL, attrs); + /* * Do the request and get back a response... */ @@ -305,5 +317,5 @@ poll_server(http_t *http, /* I - HTTP connection */ /* - * End of "$Id: cups-polld.c,v 1.5.2.1 2001/05/13 18:38:35 mike Exp $". + * End of "$Id: cups-polld.c,v 1.5.2.2 2001/12/26 16:52:52 mike Exp $". */ diff --git a/scheduler/cupsd.h b/scheduler/cupsd.h index 73d6420614..5640089800 100644 --- a/scheduler/cupsd.h +++ b/scheduler/cupsd.h @@ -1,5 +1,5 @@ /* - * "$Id: cupsd.h,v 1.28 2001/02/21 17:01:17 mike Exp $" + * "$Id: cupsd.h,v 1.28.2.1 2001/12/26 16:52:52 mike Exp $" * * Main header file for the Common UNIX Printing System (CUPS) scheduler. * @@ -72,6 +72,7 @@ #define MAX_LISTENERS 10 /* Maximum number of listener sockets */ #define MAX_USERPASS 33 /* Maximum size of username/password */ #define MAX_FILTERS 20 /* Maximum number of filters */ +#define MAX_SYSTEM_GROUPS 32 /* Maximum number of system groups */ /* @@ -83,15 +84,9 @@ #define DEFAULT_TIMEOUT 300 /* Timeout during requests/updates */ #define DEFAULT_KEEPALIVE 60 /* Timeout between requests */ #define DEFAULT_INTERVAL 30 /* Interval between browse updates */ -#ifdef WIN32 /* Fix for broken Linux setlocale() */ -# define DEFAULT_LANGUAGE setlocale(LC_ALL,"") +#define DEFAULT_LANGUAGE setlocale(LC_ALL,"") /* Default language encoding */ -#else -# define DEFAULT_LANGUAGE getenv("LANG") - /* Default language encoding */ -#endif /* !WIN32 */ -#define DEFAULT_CHARSET "utf-8" - /* Default charset */ +#define DEFAULT_CHARSET "utf-8" /* Default charset */ /* @@ -114,12 +109,12 @@ #include "cert.h" #include "client.h" #include "auth.h" -#include "dirsvc.h" #include "printers.h" #include "classes.h" #include "job.h" #include "conf.h" #include "banners.h" +#include "dirsvc.h" /* @@ -177,5 +172,5 @@ extern void StopServer(void); /* - * End of "$Id: cupsd.h,v 1.28 2001/02/21 17:01:17 mike Exp $". + * End of "$Id: cupsd.h,v 1.28.2.1 2001/12/26 16:52:52 mike Exp $". */ diff --git a/scheduler/devices.c b/scheduler/devices.c index f6ac455617..3183200a74 100644 --- a/scheduler/devices.c +++ b/scheduler/devices.c @@ -1,5 +1,5 @@ /* - * "$Id: devices.c,v 1.14 2001/03/23 13:58:17 mike Exp $" + * "$Id: devices.c,v 1.14.2.1 2001/12/26 16:52:52 mike Exp $" * * Device scanning routines for the Common UNIX Printing System (CUPS). * @@ -184,10 +184,13 @@ LoadDevices(const char *d) /* I - Directory to scan */ * Bad format; strip trailing newline and write an error message. */ - line[strlen(line) - 1] = '\0'; + if (line[strlen(line) - 1] == '\n') + line[strlen(line) - 1] = '\0'; + LogMessage(L_ERROR, "LoadDevices: Bad line from \"%s\": %s", dent->d_name, line); compat = 1; + break; } else { @@ -475,5 +478,5 @@ sigalrm_handler(int sig) /* I - Signal number */ /* - * End of "$Id: devices.c,v 1.14 2001/03/23 13:58:17 mike Exp $". + * End of "$Id: devices.c,v 1.14.2.1 2001/12/26 16:52:52 mike Exp $". */ diff --git a/scheduler/dirsvc.c b/scheduler/dirsvc.c index a3dc19fe74..dfad0ea948 100644 --- a/scheduler/dirsvc.c +++ b/scheduler/dirsvc.c @@ -1,5 +1,5 @@ /* - * "$Id: dirsvc.c,v 1.73.2.2 2001/05/13 18:38:35 mike Exp $" + * "$Id: dirsvc.c,v 1.73.2.3 2001/12/26 16:52:52 mike Exp $" * * Directory services routines for the Common UNIX Printing System (CUPS). * @@ -23,12 +23,21 @@ * * Contents: * - * StartBrowsing() - Start sending and receiving broadcast information. - * StopBrowsing() - Stop sending and receiving broadcast information. - * UpdateBrowseList() - Update the browse lists for any new browse data. - * SendBrowseList() - Send new browsing information. - * StartPolling() - Start polling servers as needed. - * StopPolling() - Stop polling servers as needed. + * ProcessBrowseData() - Process new browse data. + * SendBrowseList() - Send new browsing information as necessary. + * SendCUPSBrowse() - Send new browsing information using the CUPS protocol. + * StartBrowsing() - Start sending and receiving broadcast information. + * StartPolling() - Start polling servers as needed. + * StopBrowsing() - Stop sending and receiving broadcast information. + * StopPolling() - Stop polling servers as needed. + * UpdateCUPSBrowse() - Update the browse lists using the CUPS protocol. + * RegReportCallback() - Empty SLPRegReport. + * SendSLPBrowse() - Register the specified printer with SLP. + * SLPDeregPrinter() - SLPDereg() the specified printer + * GetSlpAttrVal() - Get an attribute from an SLP registration. + * AttrCallback() - SLP attribute callback + * SrvUrlCallback() - SLP service url callback + * UpdateSLPBrowse() - Get browsing information via SLP. */ /* @@ -39,6 +48,531 @@ #include +/* + * 'ProcessBrowseData()' - Process new browse data. + */ + +void +ProcessBrowseData(const char *uri, /* I - URI of printer/class */ + cups_ptype_t type, /* I - Printer type */ + ipp_pstate_t state, /* I - Printer state */ + const char *location,/* I - Printer location */ + const char *info, /* I - Printer information */ + const char *make_model) /* I - Printer make and model */ +{ + int i; /* Looping var */ + int update; /* Update printer attributes? */ + char method[HTTP_MAX_URI], /* Method portion of URI */ + username[HTTP_MAX_URI], /* Username portion of URI */ + host[HTTP_MAX_URI], /* Host portion of URI */ + resource[HTTP_MAX_URI]; /* Resource portion of URI */ + int port; /* Port portion of URI */ + char name[IPP_MAX_NAME], /* Name of printer */ + *hptr, /* Pointer into hostname */ + *sptr; /* Pointer into ServerName */ + char local_make_model[IPP_MAX_NAME]; + /* Local make and model */ + printer_t *p, /* Printer information */ + *pclass, /* Printer class */ + *first, /* First printer in class */ + *next; /* Next printer in list */ + int offset, /* Offset of name */ + len; /* Length of name */ + + + /* + * Pull the URI apart to see if this is a local or remote printer... + */ + + httpSeparate(uri, method, username, host, &port, resource); + + /* + * OK, this isn't a local printer; see if we already have it listed in + * the Printers list, and add it if not... + */ + + update = 0; + hptr = strchr(host, '.'); + sptr = strchr(ServerName, '.'); + + if (sptr != NULL && hptr != NULL) + { + /* + * Strip the common domain name components... + */ + + while (hptr != NULL) + { + if (strcasecmp(hptr, sptr) == 0) + { + *hptr = '\0'; + break; + } + else + hptr = strchr(hptr + 1, '.'); + } + } + + if (type & CUPS_PRINTER_CLASS) + { + /* + * Remote destination is a class... + */ + + if (strncmp(resource, "/classes/", 9) == 0) + snprintf(name, sizeof(name), "%s@%s", resource + 9, host); + else + return; + + if ((p = FindClass(name)) == NULL && BrowseShortNames) + { + if ((p = FindClass(resource + 9)) != NULL) + { + if (strcasecmp(p->hostname, host) != 0 && p->hostname[0]) + { + /* + * Nope, this isn't the same host; if the hostname isn't the local host, + * add it to the other class and then find a class using the full host + * name... + */ + + if (p->type & CUPS_PRINTER_REMOTE) + { + /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ + strncat(p->name, "@", sizeof(p->name) - 1); + strncat(p->name, p->hostname, sizeof(p->name) - 1); + SetPrinterAttrs(p); + SortPrinters(); + } + + p = NULL; + } + else if (!p->hostname[0]) + { + /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ + strncpy(p->hostname, host, sizeof(p->hostname) - 1); + strncpy(p->uri, uri, sizeof(p->uri) - 1); + strncpy(p->device_uri, uri, sizeof(p->device_uri) - 1); + update = 1; + } + } + else + { + strncpy(name, resource + 9, sizeof(name) - 1); + name[sizeof(name) - 1] = '\0'; + } + } + else if (p != NULL && !p->hostname[0]) + { + /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ + strncpy(p->hostname, host, sizeof(p->hostname) - 1); + strncpy(p->uri, uri, sizeof(p->uri) - 1); + strncpy(p->device_uri, uri, sizeof(p->device_uri) - 1); + update = 1; + } + + if (p == NULL) + { + /* + * Class doesn't exist; add it... + */ + + p = AddClass(name); + + LogMessage(L_INFO, "Added remote class \"%s\"...", name); + + /* + * Force the URI to point to the real server... + */ + + p->type = type; + /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ + strncpy(p->uri, uri, sizeof(p->uri) - 1); + strncpy(p->device_uri, uri, sizeof(p->device_uri) - 1); + strncpy(p->hostname, host, sizeof(p->hostname) - 1); + + update = 1; + } + } + else + { + /* + * Remote destination is a printer... + */ + + if (strncmp(resource, "/printers/", 10) == 0) + snprintf(name, sizeof(name), "%s@%s", resource + 10, host); + else + return; + + if ((p = FindPrinter(name)) == NULL && BrowseShortNames) + { + if ((p = FindPrinter(resource + 10)) != NULL) + { + if (strcasecmp(p->hostname, host) != 0 && p->hostname[0]) + { + /* + * Nope, this isn't the same host; if the hostname isn't the local host, + * add it to the other printer and then find a printer using the full host + * name... + */ + + if (p->type & CUPS_PRINTER_REMOTE) + { + /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ + strncat(p->name, "@", sizeof(p->name) - 1); + strncat(p->name, p->hostname, sizeof(p->name) - 1); + SetPrinterAttrs(p); + SortPrinters(); + } + + p = NULL; + } + else if (!p->hostname[0]) + { + /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ + strncpy(p->hostname, host, sizeof(p->hostname) - 1); + strncpy(p->uri, uri, sizeof(p->uri) - 1); + strncpy(p->device_uri, uri, sizeof(p->device_uri) - 1); + update = 1; + } + } + else + { + strncpy(name, resource + 10, sizeof(name) - 1); + name[sizeof(name) - 1] = '\0'; + } + } + else if (p != NULL && !p->hostname[0]) + { + /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ + strncpy(p->hostname, host, sizeof(p->hostname) - 1); + strncpy(p->uri, uri, sizeof(p->uri) - 1); + strncpy(p->device_uri, uri, sizeof(p->device_uri) - 1); + update = 1; + } + + if (p == NULL) + { + /* + * Printer doesn't exist; add it... + */ + + p = AddPrinter(name); + + LogMessage(L_INFO, "Added remote printer \"%s\"...", name); + + /* + * Force the URI to point to the real server... + */ + + p->type = type; + /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ + strncpy(p->hostname, host, sizeof(p->hostname) - 1); + strncpy(p->uri, uri, sizeof(p->uri) - 1); + strncpy(p->device_uri, uri, sizeof(p->device_uri) - 1); + + update = 1; + } + } + + /* + * Update the state... + */ + + p->state = state; + p->accepting = state != IPP_PRINTER_STOPPED; + p->browse_time = time(NULL); + + if (p->type != type) + { + p->type = type; + update = 1; + } + + if (strcmp(p->location, location)) + { + /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ + strncpy(p->location, location, sizeof(p->location) - 1); + update = 1; + } + + if (strcmp(p->info, info)) + { + /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ + strncpy(p->info, info, sizeof(p->info) - 1); + update = 1; + } + + if (!make_model[0]) + { + if (type & CUPS_PRINTER_CLASS) + snprintf(local_make_model, sizeof(local_make_model), + "Remote Class on %s", host); + else + snprintf(local_make_model, sizeof(local_make_model), + "Remote Printer on %s", host); + } + else + snprintf(local_make_model, sizeof(local_make_model), + "%s on %s", make_model, host); + + if (strcmp(p->make_model, local_make_model)) + { + /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ + strncpy(p->make_model, local_make_model, sizeof(p->make_model) - 1); + update = 1; + } + + if (update) + SetPrinterAttrs(p); + + /* + * See if we have a default printer... If not, make the first printer the + * default. + */ + + if (DefaultPrinter == NULL && Printers != NULL) + DefaultPrinter = Printers; + + /* + * Do auto-classing if needed... + */ + + if (ImplicitClasses) + { + /* + * Loop through all available printers and create classes as needed... + */ + + for (p = Printers, len = 0, offset = 0, first = NULL; + p != NULL; + p = next) + { + /* + * Get next printer in list... + */ + + next = p->next; + + /* + * Skip classes... + */ + + if (p->type & (CUPS_PRINTER_IMPLICIT | CUPS_PRINTER_CLASS)) + { + len = 0; + continue; + } + + /* + * If len == 0, get the length of this printer name up to the "@" + * sign (if any). + */ + + if (len > 0 && + strncasecmp(p->name, name + offset, len) == 0 && + (p->name[len] == '\0' || p->name[len] == '@')) + { + /* + * We have more than one printer with the same name; see if + * we have a class, and if this printer is a member... + */ + + if ((pclass = FindPrinter(name)) == NULL) + { + /* + * Need to add the class... + */ + + pclass = AddPrinter(name); + pclass->type |= CUPS_PRINTER_IMPLICIT; + pclass->accepting = 1; + pclass->state = IPP_PRINTER_IDLE; + + SetPrinterAttrs(pclass); + + LogMessage(L_INFO, "Added implicit class \"%s\"...", name); + } + + if (first != NULL) + { + for (i = 0; i < pclass->num_printers; i ++) + if (pclass->printers[i] == first) + break; + + if (i >= pclass->num_printers) + AddPrinterToClass(pclass, first); + + first = NULL; + } + + for (i = 0; i < pclass->num_printers; i ++) + if (pclass->printers[i] == p) + break; + + if (i >= pclass->num_printers) + AddPrinterToClass(pclass, p); + } + else + { + /* + * First time around; just get name length and mark it as first + * in the list... + */ + + if ((hptr = strchr(p->name, '@')) != NULL) + len = hptr - p->name; + else + len = strlen(p->name); + + strncpy(name, p->name, len); + name[len] = '\0'; + offset = 0; + + if ((pclass = FindPrinter(name)) != NULL && + !(pclass->type & CUPS_PRINTER_IMPLICIT)) + { + /* + * Can't use same name as a local printer; add "Any" to the + * front of the name, unless we have explicitly disabled + * the "ImplicitAnyClasses"... + */ + + if (ImplicitAnyClasses) + { + /* + * Add "Any" to the class name... + */ + + strcpy(name, "Any"); + strncpy(name + 3, p->name, len); + name[len + 3] = '\0'; + offset = 3; + } + else + { + /* + * Don't create an implicit class if we have a local printer + * with the same name... + */ + + len = 0; + continue; + } + } + + first = p; + } + } + } +} + + +/* + * 'SendBrowseList()' - Send new browsing information as necessary. + */ + +void +SendBrowseList(void) +{ + printer_t *p, /* Current printer */ + *np; /* Next printer */ + time_t ut, /* Minimum update time */ + to; /* Timeout time */ + + + if (!Browsing || !(BrowseProtocols & BROWSE_CUPS)) + return; + + /* + * Compute the update and timeout times... + */ + + ut = time(NULL) - BrowseInterval; + to = time(NULL) - BrowseTimeout; + + /* + * Loop through all of the printers and send local updates as needed... + */ + + for (p = Printers; p != NULL; p = np) + { + np = p->next; + + if (p->type & CUPS_PRINTER_REMOTE) + { + /* + * See if this printer needs to be timed out... + */ + + if (p->browse_time < to) + { + LogMessage(L_INFO, "Remote destination \"%s\" has timed out; deleting it...", + p->name); + DeletePrinter(p); + } + } + else if (p->browse_time < ut && BrowseInterval > 0 && + !(p->type & CUPS_PRINTER_IMPLICIT)) + { + /* + * Need to send an update... + */ + + p->browse_time = time(NULL); + + if (BrowseProtocols & BROWSE_CUPS) + SendCUPSBrowse(p); + +#ifdef HAVE_LIBSLP + if (BrowseProtocols & BROWSE_SLP) + SendSLPBrowse(p); +#endif /* HAVE_LIBSLP */ + } + } +} + + +/* + * 'SendCUPSBrowse()' - Send new browsing information using the CUPS protocol. + */ + +void +SendCUPSBrowse(printer_t *p) /* I - Printer to send */ +{ + int i; /* Looping var */ + int bytes; /* Length of packet */ + char packet[1453]; + /* Browse data packet */ + + + snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\"\n", + p->type | CUPS_PRINTER_REMOTE, p->state, p->uri, + p->location, p->info, p->make_model); + + bytes = strlen(packet); + LogMessage(L_DEBUG2, "SendBrowseList: (%d bytes) %s", bytes, packet); + + /* + * Send a packet to each browse address... + */ + + for (i = 0; i < NumBrowsers; i ++) + if (sendto(BrowseSocket, packet, bytes, 0, + (struct sockaddr *)Browsers + i, sizeof(Browsers[0])) <= 0) + { + LogMessage(L_ERROR, "SendBrowseList: sendto failed for browser %d - %s.", + i + 1, strerror(errno)); + LogMessage(L_ERROR, "Browsing turned off."); + + StopBrowsing(); + Browsing = 0; + return; + } +} + + /* * 'StartBrowsing()' - Start sending and receiving broadcast information. */ @@ -53,112 +587,243 @@ StartBrowsing(void) if (!Browsing) return; - /* - * Create the broadcast socket... - */ + if (BrowseProtocols & BROWSE_CUPS) + { + /* + * Create the broadcast socket... + */ + + if ((BrowseSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + LogMessage(L_ERROR, "StartBrowsing: Unable to create broadcast socket - %s.", + strerror(errno)); + Browsing = 0; + return; + } + + /* + * Set the "broadcast" flag... + */ + + val = 1; + if (setsockopt(BrowseSocket, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val))) + { + LogMessage(L_ERROR, "StartBrowsing: Unable to set broadcast mode - %s.", + strerror(errno)); + + #if defined(WIN32) || defined(__EMX__) + closesocket(BrowseSocket); + #else + close(BrowseSocket); + #endif /* WIN32 || __EMX__ */ + + BrowseSocket = -1; + Browsing = 0; + return; + } + + /* + * Bind the socket to browse port... + */ + + memset(&addr, 0, sizeof(addr)); + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_family = AF_INET; + addr.sin_port = htons(BrowsePort); + + if (bind(BrowseSocket, (struct sockaddr *)&addr, sizeof(addr))) + { + LogMessage(L_ERROR, "StartBrowsing: Unable to bind broadcast socket - %s.", + strerror(errno)); - if ((BrowseSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + #if defined(WIN32) || defined(__EMX__) + closesocket(BrowseSocket); + #else + close(BrowseSocket); + #endif /* WIN32 || __EMX__ */ + + BrowseSocket = -1; + Browsing = 0; + return; + } + + /* + * Finally, add the socket to the input selection set... + */ + + LogMessage(L_DEBUG2, "StartBrowsing: Adding fd %d to InputSet...", + BrowseSocket); + + FD_SET(BrowseSocket, &InputSet); + } + +#ifdef HAVE_LIBSLP + if (BrowseProtocols & BROWSE_SLP) { - LogMessage(L_ERROR, "StartBrowsing: Unable to create broadcast socket - %s.", - strerror(errno)); - Browsing = 0; - return; + /* + * Open SLP handle... + */ + + if (SLPOpen("en", SLP_FALSE, &BrowseSLPHandle) != SLP_OK) + { + LogMessage(L_ERROR, "Unable to open an SLP handle; disabling SLP browsing!"); + BrowseProtocols &= ~BROWSE_SLP; + } + + BrowseSLPRefresh = 0; } +} - /* - * Set the "broadcast" flag... - */ - val = 1; - if (setsockopt(BrowseSocket, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val))) +/* + * 'StartPolling()' - Start polling servers as needed. + */ + +void +StartPolling(void) +{ + int i; /* Looping var */ + dirsvc_poll_t *poll; /* Current polling server */ + int pid; /* New process ID */ + char sport[10]; /* Server port */ + char bport[10]; /* Browser port */ + char interval[10]; /* Poll interval */ + + + sprintf(bport, "%d", BrowsePort); + + if (BrowseInterval) + sprintf(interval, "%d", BrowseInterval); + else + strcpy(interval, "30"); + + for (i = 0, poll = Polled; i < NumPolled; i ++, poll ++) { - LogMessage(L_ERROR, "StartBrowsing: Unable to set broadcast mode - %s.", - strerror(errno)); + sprintf(sport, "%d", poll->port); -#if defined(WIN32) || defined(__EMX__) - closesocket(BrowseSocket); -#else - close(BrowseSocket); -#endif /* WIN32 || __EMX__ */ + if ((pid = fork()) == 0) + { + /* + * Child... + */ - BrowseSocket = -1; - Browsing = 0; - return; + if (getuid() == 0) + { + /* + * Running as root, so change to non-priviledged user... + */ + + if (setgid(Group)) + exit(errno); + + if (setuid(User)) + exit(errno); + } + + /* + * Reset group membership to just the main one we belong to. + */ + + setgroups(0, NULL); + + /* + * Execute the polling daemon... + */ + + execl(CUPS_SERVERBIN "/daemon/cups-polld", "cups-polld", poll->hostname, + sport, interval, bport, NULL); + exit(errno); + } + else if (pid < 0) + { + LogMessage(L_ERROR, "StartPolling: Unable to fork polling daemon - %s", + strerror(errno)); + poll->pid = 0; + break; + } + else + { + poll->pid = pid; + LogMessage(L_DEBUG, "StartPolling: Started polling daemon for %s:%d, pid = %d", + poll->hostname, poll->port, pid); + } } +>>>>>>> 1.86 +} - /* - * Bind the socket to browse port... - */ - memset(&addr, 0, sizeof(addr)); - addr.sin_addr.s_addr = htonl(INADDR_ANY); - addr.sin_family = AF_INET; - addr.sin_port = htons(BrowsePort); +/* + * 'StopBrowsing()' - Stop sending and receiving broadcast information. + */ + +void +StopBrowsing(void) +{ + if (!Browsing) + return; - if (bind(BrowseSocket, (struct sockaddr *)&addr, sizeof(addr))) + if (BrowseProtocols & BROWSE_CUPS) { - LogMessage(L_ERROR, "StartBrowsing: Unable to bind broadcast socket - %s.", - strerror(errno)); + /* + * Close the socket and remove it from the input selection set. + */ + if (BrowseSocket >= 0) + { #if defined(WIN32) || defined(__EMX__) - closesocket(BrowseSocket); + closesocket(BrowseSocket); #else - close(BrowseSocket); + close(BrowseSocket); #endif /* WIN32 || __EMX__ */ - BrowseSocket = -1; - Browsing = 0; - return; + LogMessage(L_DEBUG2, "StopBrowsing: Removing fd %d from InputSet...", + BrowseSocket); + + FD_CLR(BrowseSocket, &InputSet); + BrowseSocket = 0; + } } - /* - * Finally, add the socket to the input selection set... - */ +#ifdef HAVE_LIBSLP + if (BrowseProtocols & BROWSE_SLP) + { + /* + * Close SLP handle... + */ - FD_SET(BrowseSocket, &InputSet); + SLPClose(BrowseSLPHandle); + } +#endif /* HAVE_LIBSLP */ } /* - * 'StopBrowsing()' - Stop sending and receiving broadcast information. + * 'StopPolling()' - Stop polling servers as needed. */ void -StopBrowsing(void) +StopPolling(void) { - if (!Browsing) - return; - - /* - * Close the socket and remove it from the input selection set. - */ + int i; /* Looping var */ + dirsvc_poll_t *poll; /* Current polling server */ - if (BrowseSocket >= 0) - { -#if defined(WIN32) || defined(__EMX__) - closesocket(BrowseSocket); -#else - close(BrowseSocket); -#endif /* WIN32 || __EMX__ */ - FD_CLR(BrowseSocket, &InputSet); - BrowseSocket = 0; - } + for (i = 0, poll = Polled; i < NumPolled; i ++, poll ++) + if (poll->pid) + kill(poll->pid, SIGTERM); } /* - * 'UpdateBrowseList()' - Update the browse lists for any new browse data. + * 'UpdateCUPSBrowse()' - Update the browse lists using the CUPS protocol. */ void -UpdateBrowseList(void) +UpdateCUPSBrowse(void) { int i; /* Looping var */ - int update; /* Update printer attributes? */ int auth; /* Authorization status */ - int len, /* Length of name string */ - offset; /* Offset in name string */ + int len; /* Length of name string */ int bytes; /* Number of bytes left */ char packet[1540], /* Broadcast packet */ *pptr; /* Pointer into packet */ @@ -177,13 +842,6 @@ UpdateBrowseList(void) location[IPP_MAX_NAME], /* Location string */ make_model[IPP_MAX_NAME];/* Make and model string */ int port; /* Port portion of URI */ - char name[IPP_MAX_NAME], /* Name of printer */ - *hptr, /* Pointer into hostname */ - *sptr; /* Pointer into ServerName */ - printer_t *p, /* Printer information */ - *pclass, /* Printer class */ - *first, /* First printer in class */ - *next; /* Next printer in list */ /* @@ -251,7 +909,7 @@ UpdateBrowseList(void) * Do ACL stuff... */ - if (BrowseACL) + if (BrowseACL && (BrowseACL->num_allow || BrowseACL->num_deny)) { if (httpAddrLocalhost(&srcaddr) || strcasecmp(srcname, "localhost") == 0) { @@ -316,8 +974,6 @@ UpdateBrowseList(void) * Parse packet... */ - update = 0; - if (sscanf(packet, "%x%x%1023s", (unsigned *)&type, (unsigned *)&state, uri) < 3) { @@ -412,553 +1068,521 @@ UpdateBrowseList(void) } /* - * OK, this isn't a local printer; see if we already have it listed in - * the Printers list, and add it if not... + * Process the browse data... */ - hptr = strchr(host, '.'); - sptr = strchr(ServerName, '.'); - - if (sptr != NULL && hptr != NULL) - { - /* - * Strip the common domain name components... - */ - - while (hptr != NULL) - { - if (strcasecmp(hptr, sptr) == 0) - { - *hptr = '\0'; - break; - } - else - hptr = strchr(hptr + 1, '.'); - } - } - - if (type & CUPS_PRINTER_CLASS) - { - /* - * Remote destination is a class... - */ - - if (strncmp(resource, "/classes/", 9) == 0) - snprintf(name, sizeof(name), "%s@%s", resource + 9, host); - else - return; - - if ((p = FindClass(name)) == NULL && BrowseShortNames) - { - if ((p = FindClass(resource + 9)) != NULL) - { - if (strcasecmp(p->hostname, host) != 0 && p->hostname[0]) - { - /* - * Nope, this isn't the same host; if the hostname isn't the local host, - * add it to the other class and then find a class using the full host - * name... - */ - - if (p->type & CUPS_PRINTER_REMOTE) - { - /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ - strncat(p->name, "@", sizeof(p->name) - 1); - strncat(p->name, p->hostname, sizeof(p->name) - 1); - SetPrinterAttrs(p); - SortPrinters(); - } + ProcessBrowseData(uri, type, state, location, info, make_model); +} - p = NULL; - } - else if (!p->hostname[0]) - { - /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ - strncpy(p->hostname, host, sizeof(p->hostname) - 1); - strncpy(p->uri, uri, sizeof(p->uri) - 1); - strncpy(p->more_info, uri, sizeof(p->more_info) - 1); - strncpy(p->device_uri, uri, sizeof(p->device_uri) - 1); - update = 1; - } - } - else - { - strncpy(name, resource + 9, sizeof(name) - 1); - name[sizeof(name) - 1] = '\0'; - } - } - else if (!p->hostname[0]) - { - /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ - strncpy(p->hostname, host, sizeof(p->hostname) - 1); - strncpy(p->uri, uri, sizeof(p->uri) - 1); - strncpy(p->more_info, uri, sizeof(p->more_info) - 1); - strncpy(p->device_uri, uri, sizeof(p->device_uri) - 1); - update = 1; - } - if (p == NULL) - { - /* - * Class doesn't exist; add it... - */ +/*********************************************************************** + **** SLP Support Code ************************************************* + ***********************************************************************/ - p = AddClass(name); +#ifdef HAVE_LIBSLP +/* + * SLP service name for CUPS... + */ - /* - * Force the URI to point to the real server... - */ +# define SLP_CUPS_SRVTYPE "service:printer" +# define SLP_CUPS_SRVLEN 15 - p->type = type; - /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ - strncpy(p->uri, uri, sizeof(p->uri) - 1); - strncpy(p->more_info, uri, sizeof(p->more_info) - 1); - strncpy(p->device_uri, uri, sizeof(p->device_uri) - 1); - strncpy(p->hostname, host, sizeof(p->hostname) - 1); +typedef struct _slpsrvurl +{ + struct _slpsrvurl *next; + char url[HTTP_MAX_URI]; +} slpsrvurl_t; - update = 1; - } - } - else - { - /* - * Remote destination is a printer... - */ - if (strncmp(resource, "/printers/", 10) == 0) - snprintf(name, sizeof(name), "%s@%s", resource + 10, host); - else - return; +/* + * 'RegReportCallback()' - Empty SLPRegReport. + */ - if ((p = FindPrinter(name)) == NULL && BrowseShortNames) - { - if ((p = FindPrinter(resource + 10)) != NULL) - { - if (strcasecmp(p->hostname, host) != 0 && p->hostname[0]) - { - /* - * Nope, this isn't the same host; if the hostname isn't the local host, - * add it to the other printer and then find a printer using the full host - * name... - */ +void +RegReportCallback(SLPHandle hslp, + SLPError errcode, + void *cookie) +{ + (void)hslp; + (void)errcode; + (void)cookie; - if (p->type & CUPS_PRINTER_REMOTE) - { - /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ - strncat(p->name, "@", sizeof(p->name) - 1); - strncat(p->name, p->hostname, sizeof(p->name) - 1); - SetPrinterAttrs(p); - SortPrinters(); - } + return; +} - p = NULL; - } - else if (!p->hostname[0]) - { - /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ - strncpy(p->hostname, host, sizeof(p->hostname) - 1); - strncpy(p->uri, uri, sizeof(p->uri) - 1); - strncpy(p->more_info, uri, sizeof(p->more_info) - 1); - strncpy(p->device_uri, uri, sizeof(p->device_uri) - 1); - update = 1; - } - } - else - { - strncpy(name, resource + 10, sizeof(name) - 1); - name[sizeof(name) - 1] = '\0'; - } - } - else if (!p->hostname[0]) - { - /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ - strncpy(p->hostname, host, sizeof(p->hostname) - 1); - strncpy(p->uri, uri, sizeof(p->uri) - 1); - strncpy(p->more_info, uri, sizeof(p->more_info) - 1); - strncpy(p->device_uri, uri, sizeof(p->device_uri) - 1); - update = 1; - } - if (p == NULL) - { - /* - * Printer doesn't exist; add it... - */ +/* + * 'SendSLPBrowse()' - Register the specified printer with SLP. + */ - p = AddPrinter(name); +void +SendSLPBrowse(printer_t *p) /* I - Printer to register */ +{ + char srvurl[HTTP_MAX_URI], /* Printer service URI */ + attrs[8192], /* Printer attributes */ + finishings[1024], /* Finishings to support */ + make_model[IPP_MAX_NAME * 2], + /* Make and model, quoted */ + location[IPP_MAX_NAME * 2], + /* Location, quoted */ + info[IPP_MAX_NAME * 2], + /* Info, quoted */ + *src, /* Pointer to original string */ + *dst; /* Pointer to destination string */ + ipp_attribute_t *authentication; /* uri-authentication-supported value */ + SLPError error; /* SLP error, if any */ + + + LogMessage(L_DEBUG, "SendSLPBrowse(%p = \"%s\")", p, p->name); - /* - * Force the URI to point to the real server... - */ + /* + * Make the SLP service URL that conforms to the IANA + * 'printer:' template. + */ - p->type = type; - /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ - strncpy(p->hostname, host, sizeof(p->hostname) - 1); - strncpy(p->uri, uri, sizeof(p->uri) - 1); - strncpy(p->more_info, uri, sizeof(p->more_info) - 1); - strncpy(p->device_uri, uri, sizeof(p->device_uri) - 1); + snprintf(srvurl, sizeof(srvurl), SLP_CUPS_SRVTYPE ":%s", p->uri); - update = 1; - } - } + LogMessage(L_DEBUG2, "Service URL = \"%s\"", srvurl); /* - * Update the state... + * Figure out the finishings string... */ - p->state = state; - p->accepting = state != IPP_PRINTER_STOPPED; - p->browse_time = time(NULL); + if (p->type & CUPS_PRINTER_STAPLE) + strcpy(finishings, "staple"); + else + finishings[0] = '\0'; - if (p->type != type) + if (p->type & CUPS_PRINTER_BIND) { - p->type = type; - update = 1; + if (finishings[0]) + strncat(finishings, ",bind", sizeof(finishings) - 1); + else + strcpy(finishings, "bind"); } - if (strcmp(p->location, location)) + if (p->type & CUPS_PRINTER_PUNCH) { - /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ - strncpy(p->location, location, sizeof(p->location) - 1); - update = 1; + if (finishings[0]) + strncat(finishings, ",punch", sizeof(finishings) - 1); + else + strcpy(finishings, "punch"); } - if (strcmp(p->info, info)) + if (p->type & CUPS_PRINTER_COVER) { - /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ - strncpy(p->info, info, sizeof(p->info) - 1); - update = 1; + if (finishings[0]) + strncat(finishings, ",cover", sizeof(finishings) - 1); + else + strcpy(finishings, "cover"); } - if (!make_model[0]) + if (p->type & CUPS_PRINTER_SORT) { - if (type & CUPS_PRINTER_CLASS) - snprintf(make_model, sizeof(p->make_model), "Remote Class on %s", - host); + if (finishings[0]) + strncat(finishings, ",sort", sizeof(finishings) - 1); else - snprintf(make_model, sizeof(p->make_model), "Remote Printer on %s", - host); + strcpy(finishings, "sort"); } - else + + if (!finishings[0]) + strcpy(finishings, "none"); + + finishings[sizeof(finishings) - 1] = '\0'; + + /* + * Quote any commas in the make and model, location, and info strings + * (local strings are twice the size of the ones in the printer_t + * structure, so no buffer overflow is possible...) + */ + + for (src = p->make_model, dst = make_model; *src;) + { + if (*src == ',' || *src == '\\' || *src == ')') + *dst++ = '\\'; + + *dst++ = *src++; + } + + *dst = '\0'; + + if (!make_model[0]) + strcpy(make_model, "Unknown"); + + for (src = p->location, dst = location; *src;) { - strncat(make_model, " on ", sizeof(make_model) - 1); - strncat(make_model, host, sizeof(make_model) - 1); - make_model[sizeof(make_model) - 1] = '\0'; + if (*src == ',' || *src == '\\' || *src == ')') + *dst++ = '\\'; + + *dst++ = *src++; } - if (strcmp(p->make_model, make_model)) + *dst = '\0'; + + if (!location[0]) + strcpy(location, "Unknown"); + + for (src = p->info, dst = info; *src;) { - /* No "p->var[sizeof(p->var) - 1] = '\0';" because p is zeroed */ - strncpy(p->make_model, make_model, sizeof(p->make_model) - 1); - update = 1; + if (*src == ',' || *src == '\\' || *src == ')') + *dst++ = '\\'; + + *dst++ = *src++; } - if (update) - SetPrinterAttrs(p); + *dst = '\0'; + + if (!info[0]) + strcpy(info, "Unknown"); + + /* + * Get the authentication value... + */ + + authentication = ippFindAttribute(p->attrs, "uri-authentication-supported", + IPP_TAG_KEYWORD); /* - * See if we have a default printer... If not, make the first printer the - * default. + * Make the SLP attribute string list that conforms to + * the IANA 'printer:' template. */ - if (DefaultPrinter == NULL && Printers != NULL) - DefaultPrinter = Printers; + snprintf(attrs, sizeof(attrs), + "(printer-uri-supported=%s)," + "(uri-authentication-supported=%s>)," +#ifdef HAVE_LIBSSL + "(uri-security-supported=tls>)," +#else + "(uri-security-supported=none>)," +#endif /* HAVE_LIBSSL */ + "(printer-name=%s)," + "(printer-location=%s)," + "(printer-info=%s)," + "(printer-more-info=%s)," + "(printer-make-and-model=%s)," + "(charset-supported=utf-8)," + "(natural-language-configured=%s)," + "(natural-language-supported=de,en,es,fr,it)," + "(color-supported=%s)," + "(finishings-supported=%s)," + "(sides-supported=one-sided%s)," + "(multiple-document-jobs-supported=true)" + "(ipp-versions-supported=1.0,1.1)", + p->uri, authentication->values[0].string.text, p->name, location, + info, p->uri, make_model, DefaultLanguage, + p->type & CUPS_PRINTER_COLOR ? "true" : "false", + finishings, + p->type & CUPS_PRINTER_DUPLEX ? + ",two-sided-long-edge,two-sided-short-edge" : ""); + + LogMessage(L_DEBUG2, "Attributes = \"%s\"", attrs); /* - * Do auto-classing if needed... + * Register the printer with the SLP server... */ - if (ImplicitClasses) + error = SLPReg(BrowseSLPHandle, srvurl, BrowseTimeout, + SLP_CUPS_SRVTYPE, attrs, SLP_TRUE, RegReportCallback, 0); + + if (error != SLP_OK) + LogMessage(L_ERROR, "SLPReg of \"%s\" failed with status %d!", p->name, + error); +} + + +/* + * 'SLPDeregPrinter()' - SLPDereg() the specified printer + */ + +void +SLPDeregPrinter(printer_t *p) +{ + char srvurl[HTTP_MAX_URI]; /* Printer service URI */ + + + if((p->type & CUPS_PRINTER_REMOTE) == 0) { /* - * Loop through all available printers and create classes as needed... + * Make the SLP service URL that conforms to the IANA + * 'printer:' template. */ - for (p = Printers, len = 0, offset = 0, first = NULL; - p != NULL; - p = next) - { - /* - * Get next printer in list... - */ + snprintf(srvurl, sizeof(srvurl), SLP_CUPS_SRVTYPE ":%s", p->uri); - next = p->next; + /* + * Deregister the printer... + */ - /* - * Skip classes... - */ + SLPDereg(BrowseSLPHandle, srvurl, RegReportCallback, 0); + } +} - if (p->type & (CUPS_PRINTER_IMPLICIT | CUPS_PRINTER_CLASS)) - { - len = 0; - continue; - } - /* - * If len == 0, get the length of this printer name up to the "@" - * sign (if any). - */ +/* + * 'GetSlpAttrVal()' - Get an attribute from an SLP registration. + */ - if (len > 0 && - strncasecmp(p->name, name + offset, len) == 0 && - (p->name[len] == '\0' || p->name[len] == '@')) +int /* O - 0 on success */ +GetSlpAttrVal(const char *attrlist, /* I - Attribute list string */ + const char *tag, /* I - Name of attribute */ + char *valbuf, /* O - Value */ + int valbuflen) /* I - Max length of value */ +{ + char *ptr1, /* Pointer into string */ + *ptr2; /* ... */ + + + valbuf[0] = '\0'; + + if ((ptr1 = strstr(attrlist, tag)) != NULL) + { + ptr1 += strlen(tag); + + if ((ptr2 = strchr(ptr1,')')) != NULL) + { + if (valbuflen > (ptr2 - ptr1)) { /* - * We have more than one printer with the same name; see if - * we have a class, and if this printer is a member... + * Copy the value... */ - if ((pclass = FindPrinter(name)) == NULL) - { - /* - * Need to add the class... - */ + strncpy(valbuf, ptr1, ptr2 - ptr1); + valbuf[ptr2 - ptr1] = '\0'; - pclass = AddPrinter(name); - pclass->type |= CUPS_PRINTER_IMPLICIT; - pclass->accepting = 1; - pclass->state = IPP_PRINTER_IDLE; + /* + * Dequote the value... + */ - SetPrinterAttrs(pclass); + for (ptr1 = valbuf; *ptr1; ptr1 ++) + if (*ptr1 == '\\' && ptr1[1]) + strcpy(ptr1, ptr1 + 1); - DEBUG_printf(("Added new class \"%s\", type = %x\n", name, - pclass->type)); - } + return (0); + } + } + } - if (first != NULL) - { - for (i = 0; i < pclass->num_printers; i ++) - if (pclass->printers[i] == first) - break; + return (-1); +} - if (i >= pclass->num_printers) - AddPrinterToClass(pclass, first); - first = NULL; - } +/* + * 'AttrCallback()' - SLP attribute callback + */ - for (i = 0; i < pclass->num_printers; i ++) - if (pclass->printers[i] == p) - break; +SLPBoolean +AttrCallback(SLPHandle hslp, + const char *attrlist, + SLPError errcode, + void *cookie) +{ + char tmp[IPP_MAX_NAME]; + printer_t *p = (printer_t*)cookie; - if (i >= pclass->num_printers) - AddPrinterToClass(pclass, p); - } - else - { - /* - * First time around; just get name length and mark it as first - * in the list... - */ - if ((hptr = strchr(p->name, '@')) != NULL) - len = hptr - p->name; - else - len = strlen(p->name); + /* + * Let the compiler know we won't be using these... + */ - strncpy(name, p->name, len); - name[len] = '\0'; - offset = 0; + (void)hslp; - if ((pclass = FindPrinter(name)) != NULL && - !(pclass->type & CUPS_PRINTER_IMPLICIT)) - { - /* - * Can't use same name as printer; add "Any" to the front of the - * name... - */ + /* + * Bail if there was an error + */ - strcpy(name, "Any"); - strncpy(name + 3, p->name, len); - name[len + 3] = '\0'; - offset = 3; - } + if (errcode != SLP_OK) + return (SLP_TRUE); - first = p; - } - } - } + /* + * Parse the attrlist to obtain things needed to build CUPS browse packet + */ + + memset(p, 0, sizeof(printer_t)); + + p->type = CUPS_PRINTER_REMOTE; + + if (GetSlpAttrVal(attrlist, "(printer-location=", p->location, + sizeof(p->location))) + return (SLP_FALSE); + if (GetSlpAttrVal(attrlist, "(printer-make-and-model=", p->make_model, + sizeof(p->make_model))) + return (SLP_FALSE); + + if (GetSlpAttrVal(attrlist, "(color-supported=", tmp, sizeof(tmp))) + return (SLP_FALSE); + if (strcasecmp(tmp, "true") == 0) + p->type |= CUPS_PRINTER_COLOR; + + if (GetSlpAttrVal(attrlist, "(finishings-supported=", tmp, sizeof(tmp))) + return (SLP_FALSE); + if (strstr(tmp, "staple")) + p->type |= CUPS_PRINTER_STAPLE; + if (strstr(tmp, "bind")) + p->type |= CUPS_PRINTER_BIND; + if (strstr(tmp, "punch")) + p->type |= CUPS_PRINTER_PUNCH; + + if (GetSlpAttrVal(attrlist, "(sides-supported=", tmp, sizeof(tmp))) + return (SLP_FALSE); + if (strstr(tmp,"two-sided")) + p->type |= CUPS_PRINTER_DUPLEX; + + return (SLP_TRUE); } /* - * 'SendBrowseList()' - Send new browsing information. + * 'SrvUrlCallback()' - SLP service url callback */ -void -SendBrowseList(void) +SLPBoolean /* O - TRUE = OK, FALSE = error */ +SrvUrlCallback(SLPHandle hslp, /* I - SLP handle */ + const char *srvurl, /* I - URL of service */ + unsigned short lifetime, /* I - Life of service */ + SLPError errcode, /* I - Existing error code */ + void *cookie) /* I - Pointer to service list */ { - int i; /* Looping var */ - printer_t *p, /* Current printer */ - *np; /* Next printer */ - time_t ut, /* Minimum update time */ - to; /* Timeout time */ - int bytes; /* Length of packet */ - char packet[1453]; - /* Browse data packet */ + slpsrvurl_t *s, /* New service entry */ + **head; /* Pointer to head of entry */ - if (!Browsing) - return; + /* + * Let the compiler know we won't be using these vars... + */ + + (void)hslp; + (void)lifetime; /* - * Compute the update time... + * Bail if there was an error */ - ut = time(NULL) - BrowseInterval; - to = time(NULL) - BrowseTimeout; + if (errcode != SLP_OK) + return (SLP_TRUE); /* - * Loop through all of the printers and send local updates as needed... + * Grab the head of the list... */ - for (p = Printers; p != NULL; p = np) - { - np = p->next; + head = (slpsrvurl_t**)cookie; - if (p->type & CUPS_PRINTER_REMOTE) - { - /* - * See if this printer needs to be timed out... - */ + /* + * Allocate a *temporary* slpsrvurl_t to hold this entry. + */ - if (p->browse_time < to) - { - LogMessage(L_INFO, "Remote destination \"%s\" has timed out; deleting it...", - p->name); - DeletePrinter(p); - } - } - else if (p->browse_time < ut && !(p->type & CUPS_PRINTER_IMPLICIT) && - BrowseInterval > 0) - { - /* - * Need to send an update... - */ + if ((s = (slpsrvurl_t *)calloc(1, sizeof(slpsrvurl_t))) == NULL) + return (SLP_FALSE); - p->browse_time = time(NULL); + /* + * Copy the SLP service URL... + */ - snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\"\n", - p->type | CUPS_PRINTER_REMOTE, p->state, p->uri, - p->location, p->info, p->make_model); + strncpy(s->url, srvurl, sizeof(s->url)); - bytes = strlen(packet); - LogMessage(L_DEBUG2, "SendBrowseList: (%d bytes) %s", bytes, packet); + /* + * Link the SLP service URL into the head of the list + */ - /* - * Send a packet to each browse address... - */ + if (*head) + s->next = *head; - for (i = 0; i < NumBrowsers; i ++) - if (sendto(BrowseSocket, packet, bytes, 0, - (struct sockaddr *)Browsers + i, sizeof(Browsers[0])) <= 0) - { - LogMessage(L_ERROR, "SendBrowseList: sendto failed for browser %d - %s.", - i + 1, strerror(errno)); - LogMessage(L_ERROR, "Browsing turned off."); + *head = s; - StopBrowsing(); - Browsing = 0; - return; - } - } - } + return (SLP_TRUE); } /* - * 'StartPolling()' - Start polling servers as needed. + * 'UpdateSLPBrowse()' - Get browsing information via SLP. */ void -StartPolling(void) +UpdateSLPBrowse(void) { - int i; /* Looping var */ - dirsvc_poll_t *poll; /* Current polling server */ - int pid; /* New process ID */ - char sport[10]; /* Server port */ - char bport[10]; /* Browser port */ - char interval[10]; /* Poll interval */ + slpsrvurl_t *s, /* Temporary list of service URLs */ + *next; /* Next service in list */ + printer_t p; /* Printer information */ + const char *uri; /* Pointer to printer URI */ + char method[HTTP_MAX_URI], /* Method portion of URI */ + username[HTTP_MAX_URI], /* Username portion of URI */ + host[HTTP_MAX_URI], /* Host portion of URI */ + resource[HTTP_MAX_URI]; /* Resource portion of URI */ + int port; /* Port portion of URI */ - sprintf(bport, "%d", BrowsePort); + LogMessage(L_DEBUG, "UpdateSLPBrowse() Start..."); - if (BrowseInterval) - sprintf(interval, "%d", BrowseInterval); - else - strcpy(interval, "30"); + /* + * Reset the refresh time... + */ - for (i = 0, poll = Polled; i < NumPolled; i ++, poll ++) - { - sprintf(sport, "%d", poll->port); + BrowseSLPRefresh = time(NULL) + BrowseTimeout - BrowseInterval; - if ((pid = fork()) == 0) - { - /* - * Child... - */ + /* + * Poll for remote printers using SLP... + */ - if (getuid() == 0) - { - /* - * Running as root, so change to non-priviledged user... - */ + s = NULL; - if (setgid(Group)) - exit(errno); + SLPFindSrvs(BrowseSLPHandle, SLP_CUPS_SRVTYPE, "", "", + SrvUrlCallback, &s); - if (setuid(User)) - exit(errno); - } + /* + * Loop through the list of available printers... + */ + + for (; s; s = next) + { + /* + * Load a printer_t structure with the SLP service attributes... + */ + + SLPFindAttrs(BrowseSLPHandle, s->url, "", "", AttrCallback, &p); + + /* + * Process this printer entry... + */ + + uri = s->url + SLP_CUPS_SRVLEN + 1; + if (strncmp(uri, "http://", 7) == 0 || + strncmp(uri, "ipp://", 6) == 0) + { /* - * Reset group membership to just the main one we belong to. + * Pull the URI apart to see if this is a local or remote printer... */ - setgroups(0, NULL); + httpSeparate(uri, method, username, host, &port, resource); + + if (strcasecmp(host, ServerName) == 0) + continue; /* - * Execute the polling daemon... + * OK, at least an IPP printer, see if it is a CUPS printer or + * class... */ - execl(CUPS_SERVERBIN "/daemon/cups-polld", "cups-polld", poll->hostname, - sport, interval, bport, NULL); - exit(errno); - } - else if (pid < 0) - { - LogMessage(L_ERROR, "StartPolling: Unable to fork polling daemon - %s", - strerror(errno)); - poll->pid = 0; - break; - } - else - { - poll->pid = pid; - LogMessage(L_DEBUG, "StartPolling: Started polling daemon for %s:%d, pid = %d", - poll->hostname, poll->port, pid); + if (strstr(uri, "/printers/") != NULL) + ProcessBrowseData(uri, p.type, IPP_PRINTER_IDLE, p.location, + p.info, p.make_model); + else if (strstr(uri, "/classes/") != NULL) + ProcessBrowseData(uri, p.type | CUPS_PRINTER_CLASS, IPP_PRINTER_IDLE, + p.location, p.info, p.make_model); } - } -} - - -/* - * 'StopPolling()' - Stop polling servers as needed. - */ -void -StopPolling(void) -{ - int i; /* Looping var */ - dirsvc_poll_t *poll; /* Current polling server */ + /* + * Save the "next" pointer and free this listing... + */ + next = s->next; + free(s); + } - for (i = 0, poll = Polled; i < NumPolled; i ++, poll ++) - if (poll->pid) - kill(poll->pid, SIGTERM); + LogMessage(L_DEBUG, "UpdateSLPBrowse() End..."); } +#endif /* HAVE_LIBSLP */ /* - * End of "$Id: dirsvc.c,v 1.73.2.2 2001/05/13 18:38:35 mike Exp $". + * End of "$Id: dirsvc.c,v 1.73.2.3 2001/12/26 16:52:52 mike Exp $". */ diff --git a/scheduler/dirsvc.h b/scheduler/dirsvc.h index ad5fe94055..66990ffde4 100644 --- a/scheduler/dirsvc.h +++ b/scheduler/dirsvc.h @@ -1,5 +1,5 @@ /* - * "$Id: dirsvc.h,v 1.12.2.1 2001/04/02 19:51:48 mike Exp $" + * "$Id: dirsvc.h,v 1.12.2.2 2001/12/26 16:52:52 mike Exp $" * * Directory services definitions for the Common UNIX Printing System * (CUPS) scheduler. @@ -23,6 +23,25 @@ * WWW: http://www.cups.org */ +/* + * Include necessary headers... + */ + +#ifdef HAVE_LIBSLP +# include +#endif /* HAVE_LIBSLP */ + + +/* + * Browse protocols... + */ + +#define BROWSE_CUPS 1 /* CUPS */ +#define BROWSE_SLP 2 /* SLPv2 */ +#define BROWSE_LDAP 4 /* LDAP (not supported yet) */ +#define BROWSE_ALL 7 /* All protocols */ + + /* * Relay structure... */ @@ -52,6 +71,8 @@ typedef struct VAR int Browsing VALUE(TRUE), /* Whether or not browsing is enabled */ + BrowseProtocols VALUE(BROWSE_ALL), + /* Protocols to support */ BrowseShortNames VALUE(TRUE), /* Short names for remote printers? */ BrowseSocket VALUE(-1), @@ -77,20 +98,32 @@ VAR int NumPolled VALUE(0); VAR dirsvc_poll_t Polled[MAX_BROWSERS]; /* Polled servers */ +#ifdef HAVE_LIBSLP +VAR SLPHandle BrowseSLPHandle VALUE(NULL); + /* SLP API handle */ +VAR time_t BrowseSLPRefresh VALUE(0); + /* Next SLP refresh time */ +#endif /* HAVE_LIBSLP */ + /* * Prototypes... */ -extern void StartBrowsing(void); -extern void StopBrowsing(void); -extern void UpdateBrowseList(void); +extern void ProcessBrowseData(const char *uri, cups_ptype_t type, + ipp_pstate_t state, const char *location, + const char *info, const char *make_model); extern void SendBrowseList(void); - +extern void SendCUPSBrowse(printer_t *p); +extern void SendSLPBrowse(printer_t *p); +extern void StartBrowsing(void); extern void StartPolling(void); +extern void StopBrowsing(void); extern void StopPolling(void); +extern void UpdateCUPSBrowse(void); +extern void UpdateSLPBrowse(void); /* - * End of "$Id: dirsvc.h,v 1.12.2.1 2001/04/02 19:51:48 mike Exp $". + * End of "$Id: dirsvc.h,v 1.12.2.2 2001/12/26 16:52:52 mike Exp $". */ diff --git a/scheduler/ipp.c b/scheduler/ipp.c index cecd041b2c..767d38a37b 100644 --- a/scheduler/ipp.c +++ b/scheduler/ipp.c @@ -1,5 +1,5 @@ /* - * "$Id: ipp.c,v 1.127.2.2 2001/05/13 18:38:35 mike Exp $" + * "$Id: ipp.c,v 1.127.2.3 2001/12/26 16:52:53 mike Exp $" * * IPP routines for the Common UNIX Printing System (CUPS) scheduler. * @@ -53,7 +53,7 @@ * get_printer_attrs() - Get printer attributes. * get_printers() - Get a list of printers. * hold_job() - Hold a print job. - * move_job() - Move a job. + * move_job() - Move a job to a new destination. * print_job() - Print a file to a printer or class. * reject_jobs() - Reject print jobs to a printer. * release_job() - Release a held print job. @@ -94,7 +94,8 @@ static void add_queued_job_count(client_t *con, printer_t *p); static void cancel_all_jobs(client_t *con, ipp_attribute_t *uri); static void cancel_job(client_t *con, ipp_attribute_t *uri); static int check_quotas(client_t *con, printer_t *p); -static void copy_attribute(ipp_t *to, ipp_attribute_t *attr); +static void copy_attribute(ipp_t *to, ipp_attribute_t *attr, + int quickcopy); static void copy_attrs(ipp_t *to, ipp_t *from, ipp_attribute_t *req, ipp_tag_t group); static int copy_banner(client_t *con, job_t *job, const char *name); @@ -606,17 +607,22 @@ add_class(client_t *con, /* I - Client connection */ else if (pclass->type & CUPS_PRINTER_IMPLICIT) { /* - * Rename the implicit class to "AnyClass"... + * Rename the implicit class to "AnyClass" or remove it... */ - snprintf(pclass->name, sizeof(pclass->name), "Any%s", resource + 10); - SortPrinters(); + if (ImplicitAnyClasses) + { + snprintf(pclass->name, sizeof(pclass->name), "Any%s", resource + 9); + SortPrinters(); + } + else + DeletePrinter(pclass); /* * Add the class as a new local class... */ - pclass = AddClass(resource + 10); + pclass = AddClass(resource + 9); modify = 0; } else if (pclass->type & CUPS_PRINTER_REMOTE) @@ -626,7 +632,7 @@ add_class(client_t *con, /* I - Client connection */ */ DeletePrinterFilters(pclass); - snprintf(pclass->name, sizeof(pclass->name), "%s@%s", resource + 10, + snprintf(pclass->name, sizeof(pclass->name), "%s@%s", resource + 9, pclass->hostname); SetPrinterAttrs(pclass); SortPrinters(); @@ -635,7 +641,7 @@ add_class(client_t *con, /* I - Client connection */ * Add the class as a new local class... */ - pclass = AddClass(resource + 10); + pclass = AddClass(resource + 9); modify = 0; } else @@ -657,12 +663,6 @@ add_class(client_t *con, /* I - Client connection */ pclass->info[sizeof(pclass->info) - 1] = '\0'; } - if ((attr = ippFindAttribute(con->request, "printer-more-info", IPP_TAG_URI)) != NULL) - { - strncpy(pclass->more_info, attr->values[0].string.text, sizeof(pclass->more_info) - 1); - pclass->more_info[sizeof(pclass->more_info) - 1] = '\0'; - } - if ((attr = ippFindAttribute(con->request, "printer-is-accepting-jobs", IPP_TAG_BOOLEAN)) != NULL) { LogMessage(L_INFO, "Setting %s printer-is-accepting-jobs to %d (was %d.)", @@ -695,7 +695,8 @@ add_class(client_t *con, /* I - Client connection */ sizeof(pclass->state_message) - 1); pclass->state_message[sizeof(pclass->state_message) - 1] = '\0'; } - if ((attr = ippFindAttribute(con->request, "job-sheets-default", IPP_TAG_ZERO)) != NULL) + if ((attr = ippFindAttribute(con->request, "job-sheets-default", IPP_TAG_ZERO)) != NULL && + !Classification[0]) { strncpy(pclass->job_sheets[0], attr->values[0].string.text, sizeof(pclass->job_sheets[0]) - 1); @@ -704,24 +705,6 @@ add_class(client_t *con, /* I - Client connection */ sizeof(pclass->job_sheets[1]) - 1); else strcpy(pclass->job_sheets[1], "none"); - - /* - * Enforce classification level if set... - */ - - if (Classification[0]) - { - if (strcmp(pclass->job_sheets[0], Classification) != 0 && - strcmp(pclass->job_sheets[1], Classification) != 0) - { - /* - * Force the leading banner to have the classification on it... - */ - - strcpy(pclass->job_sheets[0], Classification); - } - } - } if ((attr = ippFindAttribute(con->request, "requesting-user-name-allowed", IPP_TAG_ZERO)) != NULL) @@ -1037,11 +1020,16 @@ add_printer(client_t *con, /* I - Client connection */ else if (printer->type & CUPS_PRINTER_IMPLICIT) { /* - * Rename the implicit printer to "AnyPrinter"... + * Rename the implicit printer to "AnyPrinter" or delete it... */ - snprintf(printer->name, sizeof(printer->name), "Any%s", resource + 10); - SortPrinters(); + if (ImplicitAnyClasses) + { + snprintf(printer->name, sizeof(printer->name), "Any%s", resource + 10); + SortPrinters(); + } + else + DeletePrinter(printer); /* * Add the printer as a new local printer... @@ -1088,14 +1076,47 @@ add_printer(client_t *con, /* I - Client connection */ printer->info[sizeof(printer->info) - 1] = '\0'; } - if ((attr = ippFindAttribute(con->request, "printer-more-info", IPP_TAG_URI)) != NULL) - { - strncpy(printer->more_info, attr->values[0].string.text, sizeof(printer->more_info) - 1); - printer->more_info[sizeof(printer->more_info) - 1] = '\0'; - } - if ((attr = ippFindAttribute(con->request, "device-uri", IPP_TAG_URI)) != NULL) { + ipp_attribute_t *device; /* Current device */ + int methodlen; /* Length of method string */ + + + /* + * Do we have a valid device URI? + */ + + httpSeparate(attr->values[0].string.text, method, username, host, + &port, resource); + methodlen = strlen(method); + + if (strcmp(method, "file") != 0) + { + /* + * See if the backend is listed as a device... + */ + + for (device = ippFindAttribute(Devices, "device-uri", IPP_TAG_URI); + device != NULL; + device = ippFindNextAttribute(Devices, "device-uri", IPP_TAG_URI)) + if (strncmp(method, device->values[0].string.text, methodlen) == 0 && + (device->values[0].string.text[methodlen] == ':' || + device->values[0].string.text[methodlen] == '\0')) + break; + + if (device == NULL) + { + /* + * Could not find device in list! + */ + + LogMessage(L_ERROR, "add_printer: bad device-uri attribute \'%s\'!", + attr->values[0].string.text); + send_ipp_error(con, IPP_NOT_POSSIBLE); + return; + } + } + LogMessage(L_INFO, "Setting %s device-uri to \"%s\" (was \"%s\".)", printer->name, attr->values[0].string.text, printer->device_uri); @@ -1136,7 +1157,8 @@ add_printer(client_t *con, /* I - Client connection */ sizeof(printer->state_message) - 1); printer->state_message[sizeof(printer->state_message) - 1] = '\0'; } - if ((attr = ippFindAttribute(con->request, "job-sheets-default", IPP_TAG_ZERO)) != NULL) + if ((attr = ippFindAttribute(con->request, "job-sheets-default", IPP_TAG_ZERO)) != NULL && + !Classification[0]) { strncpy(printer->job_sheets[0], attr->values[0].string.text, sizeof(printer->job_sheets[0]) - 1); @@ -1145,23 +1167,6 @@ add_printer(client_t *con, /* I - Client connection */ sizeof(printer->job_sheets[1]) - 1); else strcpy(printer->job_sheets[1], "none"); - - /* - * Force classification if necessary... - */ - - if (Classification[0]) - { - if (strcmp(printer->job_sheets[0], Classification) != 0 && - strcmp(printer->job_sheets[1], Classification) != 0) - { - /* - * Force the leading banner to have the classification on it... - */ - - strcpy(printer->job_sheets[0], Classification); - } - } } if ((attr = ippFindAttribute(con->request, "requesting-user-name-allowed", IPP_TAG_ZERO)) != NULL) @@ -1169,7 +1174,9 @@ add_printer(client_t *con, /* I - Client connection */ FreePrinterUsers(printer); printer->deny_users = 0; - if (attr->value_tag == IPP_TAG_NAME) + if (attr->value_tag == IPP_TAG_NAME && + (attr->num_values > 1 || + strcmp(attr->values[0].string.text, "all") != 0)) for (i = 0; i < attr->num_values; i ++) AddPrinterUser(printer, attr->values[i].string.text); } @@ -1179,7 +1186,9 @@ add_printer(client_t *con, /* I - Client connection */ FreePrinterUsers(printer); printer->deny_users = 1; - if (attr->value_tag == IPP_TAG_NAME) + if (attr->value_tag == IPP_TAG_NAME && + (attr->num_values > 1 || + strcmp(attr->values[0].string.text, "none") != 0)) for (i = 0; i < attr->num_values; i ++) AddPrinterUser(printer, attr->values[i].string.text); } @@ -1219,17 +1228,36 @@ add_printer(client_t *con, /* I - Client connection */ srcfile[sizeof(srcfile) - 1] = '\0'; } else if ((attr = ippFindAttribute(con->request, "ppd-name", IPP_TAG_NAME)) != NULL) - snprintf(srcfile, sizeof(srcfile), "%s/model/%s", DataDir, - attr->values[0].string.text); + { + if (strcmp(attr->values[0].string.text, "raw") == 0) + strcpy(srcfile, "raw"); + else + snprintf(srcfile, sizeof(srcfile), "%s/model/%s", DataDir, + attr->values[0].string.text); + } else srcfile[0] = '\0'; LogMessage(L_DEBUG, "add_printer: srcfile = \"%s\"", srcfile); + if (strcmp(srcfile, "raw") == 0) + { + /* + * Raw driver, remove any existing PPD or interface script files. + */ + + snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot, + printer->name); + unlink(dstfile); + + snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot, + printer->name); + unlink(dstfile); + } #ifdef HAVE_LIBZ - if (srcfile[0] && (fp = gzopen(srcfile, "rb")) != NULL) + else if (srcfile[0] && (fp = gzopen(srcfile, "rb")) != NULL) #else - if (srcfile[0] && (fp = fopen(srcfile, "rb")) != NULL) + else if (srcfile[0] && (fp = fopen(srcfile, "rb")) != NULL) #endif /* HAVE_LIBZ */ { /* @@ -1771,7 +1799,7 @@ check_quotas(client_t *con, /* I - Client connection */ if (p->num_users) { for (i = 0; i < p->num_users; i ++) - if (strcmp(username, p->users[i]) == 0) + if (strcasecmp(username, p->users[i]) == 0) break; if ((i < p->num_users) == p->deny_users) @@ -1818,7 +1846,8 @@ check_quotas(client_t *con, /* I - Client connection */ static void copy_attribute(ipp_t *to, /* O - Destination request/response */ - ipp_attribute_t *attr) /* I - Attribute to copy */ + ipp_attribute_t *attr, /* I - Attribute to copy */ + int quickcopy)/* I - Do a quick copy? */ { int i; /* Looping var */ ipp_attribute_t *toattr; /* Destination attribute */ @@ -1827,7 +1856,7 @@ copy_attribute(ipp_t *to, /* O - Destination request/response */ LogMessage(L_DEBUG2, "copy_attribute(%p, %s)\n", to, attr->name ? attr->name : "(null)"); - switch (attr->value_tag) + switch (attr->value_tag & ~IPP_TAG_COPY) { case IPP_TAG_ZERO : ippAddSeparator(to); @@ -1860,12 +1889,19 @@ copy_attribute(ipp_t *to, /* O - Destination request/response */ case IPP_TAG_LANGUAGE : case IPP_TAG_MIMETYPE : toattr = ippAddStrings(to, attr->group_tag, - (ipp_tag_t)(attr->value_tag | IPP_TAG_COPY), - attr->name, attr->num_values, NULL, - NULL); + (ipp_tag_t)(attr->value_tag | quickcopy), + attr->name, attr->num_values, NULL, NULL); - for (i = 0; i < attr->num_values; i ++) - toattr->values[i].string.text = attr->values[i].string.text; + if (quickcopy) + { + for (i = 0; i < attr->num_values; i ++) + toattr->values[i].string.text = attr->values[i].string.text; + } + else + { + for (i = 0; i < attr->num_values; i ++) + toattr->values[i].string.text = strdup(attr->values[i].string.text); + } break; case IPP_TAG_DATE : @@ -1900,13 +1936,30 @@ copy_attribute(ipp_t *to, /* O - Destination request/response */ case IPP_TAG_TEXTLANG : case IPP_TAG_NAMELANG : toattr = ippAddStrings(to, attr->group_tag, - (ipp_tag_t)(attr->value_tag | IPP_TAG_COPY), + (ipp_tag_t)(attr->value_tag | quickcopy), attr->name, attr->num_values, NULL, NULL); - for (i = 0; i < attr->num_values; i ++) + if (quickcopy) + { + for (i = 0; i < attr->num_values; i ++) + { + toattr->values[i].string.charset = attr->values[i].string.charset; + toattr->values[i].string.text = attr->values[i].string.text; + } + } + else { - toattr->values[i].string.charset = attr->values[i].string.charset; - toattr->values[i].string.text = attr->values[i].string.text; + for (i = 0; i < attr->num_values; i ++) + { + if (!i) + toattr->values[i].string.charset = + strdup(attr->values[i].string.charset); + else + toattr->values[i].string.charset = + toattr->values[0].string.charset; + + toattr->values[i].string.text = strdup(attr->values[i].string.text); + } } break; @@ -1975,7 +2028,7 @@ copy_attrs(ipp_t *to, /* I - Destination request */ continue; } - copy_attribute(to, fromattr); + copy_attribute(to, fromattr, IPP_TAG_COPY); } } @@ -2198,7 +2251,8 @@ create_job(client_t *con, /* I - Client connection */ if (attr == NULL) attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD, "job-hold-until", NULL, "no-hold"); - if (attr != NULL && strcmp(attr->values[0].string.text, "no-hold") != 0) + if (attr != NULL && strcmp(attr->values[0].string.text, "no-hold") != 0 && + !(printer->type & CUPS_PRINTER_REMOTE)) { /* * Hold job until specified time... @@ -2219,6 +2273,9 @@ create_job(client_t *con, /* I - Client connection */ if ((attr = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_ZERO)) == NULL) { + LogMessage(L_DEBUG, "Adding default job-sheets values \"%s,%s\"...", + printer->job_sheets[0], printer->job_sheets[1]); + attr = ippAddStrings(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-sheets", 2, NULL, NULL); attr->values[0].string.text = strdup(printer->job_sheets[0]); @@ -2233,9 +2290,35 @@ create_job(client_t *con, /* I - Client connection */ if (Classification[0]) { - if (strcmp(attr->values[0].string.text, Classification) != 0 && - (attr->num_values == 1 || - strcmp(attr->values[1].string.text, Classification) != 0)) + if (ClassifyOverride) + { + if (strcmp(attr->values[0].string.text, "none") == 0 && + (attr->num_values == 1 || + strcmp(attr->values[1].string.text, "none") == 0)) + { + /* + * Force the leading banner to have the classification on it... + */ + + free(attr->values[0].string.text); + attr->values[0].string.text = strdup(Classification); + } + else if (attr->num_values == 2 && + strcmp(attr->values[0].string.text, attr->values[1].string.text) != 0 && + strcmp(attr->values[0].string.text, "none") != 0 && + strcmp(attr->values[1].string.text, "none") != 0) + { + /* + * Can't put two different security markings on the same document! + */ + + free(attr->values[1].string.text); + attr->values[1].string.text = strdup(attr->values[0].string.text); + } + } + else if (strcmp(attr->values[0].string.text, Classification) != 0 && + (attr->num_values == 1 || + strcmp(attr->values[1].string.text, Classification) != 0)) { /* * Force the leading banner to have the classification on it... @@ -2254,6 +2337,8 @@ create_job(client_t *con, /* I - Client connection */ UpdateQuota(printer, job->username, 0, kbytes); } + else if ((attr = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_ZERO)) != NULL) + job->sheets = attr; /* * Save and log the job... @@ -2345,7 +2430,49 @@ copy_banner(client_t *con, /* I - Client connection */ fchmod(fileno(out), 0640); fchown(fileno(out), User, Group); - if ((in = fopen(banner->filename, "r")) == NULL) + if (con->language) + { + /* + * Try the localized banner file under the subdirectory... + */ + + snprintf(filename, sizeof(filename), "%s/banners/%s/%s", DataDir, + con->language->language, name); + + if (access(filename, 0) && con->language->language[2]) + { + /* + * Wasn't able to find "ll_CC" locale file; try the non-national + * localization banner directory. + */ + + attrname[0] = con->language->language[0]; + attrname[1] = con->language->language[1]; + attrname[2] = '\0'; + + snprintf(filename, sizeof(filename), "%s/banners/%s/%s", DataDir, + attrname, name); + } + + if (access(filename, 0)) + { + /* + * Use the non-localized banner file. + */ + + snprintf(filename, sizeof(filename), "%s/banners/%s", DataDir, name); + } + } + else + { + /* + * Use the non-localized banner file. + */ + + snprintf(filename, sizeof(filename), "%s/banners/%s", DataDir, name); + } + + if ((in = fopen(filename, "r")) == NULL) { fclose(out); unlink(filename); @@ -2367,35 +2494,60 @@ copy_banner(client_t *con, /* I - Client connection */ */ for (s = attrname; (ch = getc(in)) != EOF;) - if (ch == '}' || isspace(ch)) + if (!isalpha(ch) && ch != '-' && ch != '?') break; else if (s < (attrname + sizeof(attrname) - 1)) *s++ = ch; + else + break; + + *s = '\0'; - if (isspace(ch) && s == attrname) + if (ch != '}') { /* - * Ignore { followed by whitespace... + * Ignore { followed by stuff that is not an attribute name... */ putc('{', out); + fputs(attrname, out); putc(ch, out); continue; } - *s = '\0'; - /* * See if it is defined... */ - if (strcmp(attrname, "printer-name") == 0) + if (attrname[0] == '?') + s = attrname + 1; + else + s = attrname; + + if (strcmp(s, "printer-name") == 0) { fputs(job->dest, out); continue; } - else if ((attr = ippFindAttribute(job->attrs, attrname, IPP_TAG_ZERO)) == NULL) - continue; /* Nope */ + else if ((attr = ippFindAttribute(job->attrs, s, IPP_TAG_ZERO)) == NULL) + { + /* + * See if we have a leading question mark... + */ + + if (attrname[0] != '?') + { + /* + * Nope, write to file as-is; probably a PostScript procedure... + */ + + putc('{', out); + fputs(attrname, out); + putc('}', out); + } + + continue; + } /* * Output value(s)... @@ -2623,11 +2775,15 @@ delete_printer(client_t *con, /* I - Client connection */ printer = FindPrinter(dest); /* - * Remove any old PPD or script files... + * Remove old jobs... */ CancelJobs(dest); + /* + * Remove any old PPD or script files... + */ + snprintf(filename, sizeof(filename), "%s/interfaces/%s", ServerRoot, dest); unlink(filename); @@ -3130,6 +3286,10 @@ get_printers(client_t *con, /* I - Client connection */ int printer_type, /* printer-type attribute */ printer_mask; /* printer-type-mask attribute */ char *location; /* Location string */ + char name[IPP_MAX_NAME], + /* Printer name */ + *nameptr; /* Pointer into name */ + printer_t *iclass; /* Implicit class */ LogMessage(L_DEBUG2, "get_printers(%d, %x)\n", con->http.fd, type); @@ -3178,6 +3338,45 @@ get_printers(client_t *con, /* I - Client connection */ (printer->type & printer_mask) == printer_type && (location == NULL || strcasecmp(printer->location, location) == 0)) { + /* + * If HideImplicitMembers is enabled, see if this printer or class + * is a member of an implicit class... + */ + + if (ImplicitClasses && HideImplicitMembers && + (printer->type & CUPS_PRINTER_REMOTE)) + { + /* + * Make a copy of the printer name... + * + * Note: name and printer->name are both IPP_MAX_NAME characters + * in size, so strcpy() is safe... + */ + + strcpy(name, printer->name); + + if ((nameptr = strchr(name, '@')) != NULL) + { + /* + * Strip trailing @server... + */ + + *nameptr = '\0'; + + /* + * Find the core printer, if any... + */ + + if ((iclass = FindPrinter(name)) != NULL && + (iclass->type & CUPS_PRINTER_IMPLICIT)) + continue; + } + } + + /* + * Add the group separator as needed... + */ + if (count > 0) ippAddSeparator(con->response); @@ -3372,7 +3571,7 @@ hold_job(client_t *con, /* I - Client connection */ /* - * 'move_job()' - Set job attributes. + * 'move_job()' - Move a job to a new destination. */ static void @@ -3869,7 +4068,8 @@ print_job(client_t *con, /* I - Client connection */ attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD, "job-hold-until", NULL, "no-hold"); - if (attr != NULL && strcmp(attr->values[0].string.text, "no-hold") != 0) + if (attr != NULL && strcmp(attr->values[0].string.text, "no-hold") != 0 && + !(printer->type & CUPS_PRINTER_REMOTE)) { /* * Hold job until specified time... @@ -3887,6 +4087,9 @@ print_job(client_t *con, /* I - Client connection */ if ((attr = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_ZERO)) == NULL) { + LogMessage(L_DEBUG, "Adding default job-sheets values \"%s,%s\"...", + printer->job_sheets[0], printer->job_sheets[1]); + attr = ippAddStrings(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-sheets", 2, NULL, NULL); attr->values[0].string.text = strdup(printer->job_sheets[0]); @@ -3901,9 +4104,35 @@ print_job(client_t *con, /* I - Client connection */ if (Classification[0]) { - if (strcmp(attr->values[0].string.text, Classification) != 0 && - (attr->num_values == 1 || - strcmp(attr->values[1].string.text, Classification) != 0)) + if (ClassifyOverride) + { + if (strcmp(attr->values[0].string.text, "none") == 0 && + (attr->num_values == 1 || + strcmp(attr->values[1].string.text, "none") == 0)) + { + /* + * Force the leading banner to have the classification on it... + */ + + free(attr->values[0].string.text); + attr->values[0].string.text = strdup(Classification); + } + else if (attr->num_values == 2 && + strcmp(attr->values[0].string.text, attr->values[1].string.text) != 0 && + strcmp(attr->values[0].string.text, "none") != 0 && + strcmp(attr->values[1].string.text, "none") != 0) + { + /* + * Can't put two different security markings on the same document! + */ + + free(attr->values[1].string.text); + attr->values[1].string.text = strdup(attr->values[0].string.text); + } + } + else if (strcmp(attr->values[0].string.text, Classification) != 0 && + (attr->num_values == 1 || + strcmp(attr->values[1].string.text, Classification) != 0)) { /* * Force the leading banner to have the classification on it... @@ -3922,6 +4151,8 @@ print_job(client_t *con, /* I - Client connection */ UpdateQuota(printer, job->username, 0, kbytes); } + else if ((attr = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_ZERO)) != NULL) + job->sheets = attr; /* * Add the job file... @@ -4981,7 +5212,7 @@ set_job_attrs(client_t *con, /* I - Client connection */ * Then copy the attribute... */ - copy_attribute(job->attrs, attr); + copy_attribute(job->attrs, attr, 0); /* * See if the job-name or job-hold-until is being changed. @@ -5027,7 +5258,7 @@ set_job_attrs(client_t *con, /* I - Client connection */ * Add new option by copying it... */ - copy_attribute(job->attrs, attr); + copy_attribute(job->attrs, attr, 0); } } @@ -5356,7 +5587,7 @@ validate_user(client_t *con, /* I - Client connection */ char *username, /* O - Authenticated username */ int userlen) /* I - Length of username */ { - int i; /* Looping var */ + int i, j; /* Looping vars */ ipp_attribute_t *attr; /* requesting-user-name attribute */ struct passwd *user; /* User info */ struct group *group; /* System group info */ @@ -5389,7 +5620,7 @@ validate_user(client_t *con, /* I - Client connection */ * Check the username against the owner... */ - if (strcmp(username, owner) != 0 && strcmp(username, "root") != 0) + if (strcasecmp(username, owner) != 0 && strcasecmp(username, "root") != 0) { /* * Not the owner or root; check to see if the user is a member of the @@ -5399,20 +5630,26 @@ validate_user(client_t *con, /* I - Client connection */ user = getpwnam(username); endpwent(); - group = getgrnam(SystemGroup); - endgrent(); - - if (group != NULL) + for (i = 0, j = 0, group = NULL; i < NumSystemGroups; i ++) { - for (i = 0; group->gr_mem[i]; i ++) - if (strcmp(username, group->gr_mem[i]) == 0) + group = getgrnam(SystemGroups[i]); + endgrent(); + + if (group != NULL) + { + for (j = 0; group->gr_mem[j]; j ++) + if (strcasecmp(username, group->gr_mem[j]) == 0) + break; + + if (group->gr_mem[j]) break; + } + else + j = 0; } - else - i = 0; if (user == NULL || group == NULL || - (group->gr_mem[i] == NULL && group->gr_gid != user->pw_gid)) + (group->gr_mem[j] == NULL && group->gr_gid != user->pw_gid)) { /* * Username not found, group not found, or user is not part of the @@ -5428,5 +5665,5 @@ validate_user(client_t *con, /* I - Client connection */ /* - * End of "$Id: ipp.c,v 1.127.2.2 2001/05/13 18:38:35 mike Exp $". + * End of "$Id: ipp.c,v 1.127.2.3 2001/12/26 16:52:53 mike Exp $". */ diff --git a/scheduler/job.c b/scheduler/job.c index e485662ff2..33602ccf06 100644 --- a/scheduler/job.c +++ b/scheduler/job.c @@ -1,5 +1,5 @@ /* - * "$Id: job.c,v 1.124.2.2 2001/05/13 18:38:36 mike Exp $" + * "$Id: job.c,v 1.124.2.3 2001/12/26 16:52:54 mike Exp $" * * Job management routines for the Common UNIX Printing System (CUPS). * @@ -282,8 +282,10 @@ CheckJobs(void) if (pclass->type & CUPS_PRINTER_REMOTE) printer = pclass; - else + else if (pclass->state != IPP_PRINTER_STOPPED) printer = FindAvailablePrinter(current->dest); + else + printer = NULL; } else printer = FindPrinter(current->dest); @@ -294,8 +296,12 @@ CheckJobs(void) * Handle implicit classes... */ - pclass = printer; - printer = FindAvailablePrinter(current->dest); + pclass = printer; + + if (pclass->state != IPP_PRINTER_STOPPED) + printer = FindAvailablePrinter(current->dest); + else + printer = NULL; } if (printer == NULL && pclass == NULL) @@ -731,8 +737,11 @@ MoveJob(int id, /* I - Job ID */ for (current = Jobs; current != NULL; current = current->next) if (current->id == id) { - if (current->state->values[0].integer == IPP_JOB_PENDING) - strncpy(current->dest, dest, sizeof(current->dest) - 1); + if (current->state->values[0].integer >= IPP_JOB_PROCESSING) + break; + + strncpy(current->dest, dest, sizeof(current->dest) - 1); + current->dtype = p->type & CUPS_PRINTER_CLASS; if ((attr = ippFindAttribute(current->attrs, "job-printer-uri", IPP_TAG_URI)) != NULL) { @@ -1072,7 +1081,7 @@ StartJob(int id, /* I - Job ID */ path[1024], /* PATH environment variable */ language[255], /* LANG environment variable */ charset[255], /* CHARSET environment variable */ - classification[1024], /* CLASSIFICATION environmeent variable */ + classification[1024], /* CLASSIFICATION environment variable */ content_type[255],/* CONTENT_TYPE environment variable */ device_uri[1024],/* DEVICE_URI environment variable */ ppd[1024], /* PPD environment variable */ @@ -1141,8 +1150,35 @@ StartJob(int id, /* I - Job ID */ return; } - for (i = 0; i < num_filters; i ++) - current->cost += filters[i].cost; + /* + * Remove NULL ("-") filters... + */ + + for (i = 0; i < num_filters;) + if (strcmp(filters[i].filter, "-") == 0) + { + num_filters --; + if (i < num_filters) + memcpy(filters + i, filters + i + 1, + (num_filters - i) * sizeof(mime_filter_t)); + } + else + i ++; + + if (num_filters == 0) + { + free(filters); + filters = NULL; + } + else + { + /* + * Compute filter cost... + */ + + for (i = 0; i < num_filters; i ++) + current->cost += filters[i].cost; + } } /* @@ -1188,7 +1224,12 @@ StartJob(int id, /* I - Job ID */ */ if (current->job_sheets == NULL) + { LogMessage(L_DEBUG, "No job-sheets attribute."); + if ((current->job_sheets = + ippFindAttribute(current->attrs, "job-sheets", IPP_TAG_ZERO)) != NULL) + LogMessage(L_DEBUG, "... but someone added one without setting job_sheets!"); + } else if (current->job_sheets->num_values == 1) LogMessage(L_DEBUG, "job-sheets=%s", current->job_sheets->values[0].string.text); @@ -1421,8 +1462,19 @@ StartJob(int id, /* I - Job ID */ snprintf(datadir, sizeof(datadir), "CUPS_DATADIR=%s", DataDir); snprintf(fontpath, sizeof(fontpath), "CUPS_FONTPATH=%s", FontPath); if (Classification[0] && !banner_page) - snprintf(classification, sizeof(classification), "CLASSIFICATION=%s", - Classification); + { + if ((attr = ippFindAttribute(current->attrs, "job-sheets", + IPP_TAG_NAME)) == NULL) + snprintf(classification, sizeof(classification), "CLASSIFICATION=%s", + Classification); + else if (attr->num_values > 1 && + strcmp(attr->values[1].string.text, "none") != 0) + snprintf(classification, sizeof(classification), "CLASSIFICATION=%s", + attr->values[1].string.text); + else + snprintf(classification, sizeof(classification), "CLASSIFICATION=%s", + attr->values[0].string.text); + } else classification[0] = '\0'; if (getenv("LD_LIBRARY_PATH") != NULL) @@ -1929,6 +1981,895 @@ UpdateJob(job_t *job) /* I - Job to check */ } +/* + * 'ipp_read_file()' - Read an IPP request from a file. + */ + +static ipp_state_t /* O - State */ +ipp_read_file(const char *filename, /* I - File to read from */ + ipp_t *ipp) /* I - Request to read into */ +{ + int fd; /* File descriptor for file */ + int n; /* Length of data */ + unsigned char buffer[8192], /* Data buffer */ + *bufptr; /* Pointer into buffer */ + ipp_attribute_t *attr; /* Current attribute */ + ipp_tag_t tag; /* Current tag */ + + + /* + * Open the file if possible... + */ + + if (filename == NULL || ipp == NULL) + return (IPP_ERROR); + + if ((fd = open(filename, O_RDONLY)) == -1) + return (IPP_ERROR); + + /* + * Read the IPP request... + */ + + ipp->state = IPP_IDLE; + + switch (ipp->state) + { + default : + break; /* anti-compiler-warning-code */ + + case IPP_IDLE : + ipp->state ++; /* Avoid common problem... */ + + case IPP_HEADER : + /* + * Get the request header... + */ + + if ((n = read(fd, buffer, 8)) < 8) + { + DEBUG_printf(("ipp_read_file: Unable to read header (%d bytes read)!\n", n)); + close(fd); + return (n == 0 ? IPP_IDLE : IPP_ERROR); + } + + /* + * Verify the major version number... + */ + + if (buffer[0] != 1) + { + DEBUG_printf(("ipp_read_file: version number (%d.%d) is bad.\n", buffer[0], + buffer[1])); + close(fd); + return (IPP_ERROR); + } + + /* + * Then copy the request header over... + */ + + ipp->request.any.version[0] = buffer[0]; + ipp->request.any.version[1] = buffer[1]; + ipp->request.any.op_status = (buffer[2] << 8) | buffer[3]; + ipp->request.any.request_id = (((((buffer[4] << 8) | buffer[5]) << 8) | + buffer[6]) << 8) | buffer[7]; + + ipp->state = IPP_ATTRIBUTE; + ipp->current = NULL; + ipp->curtag = IPP_TAG_ZERO; + + case IPP_ATTRIBUTE : + while (read(fd, buffer, 1) > 0) + { + /* + * Read this attribute... + */ + + tag = (ipp_tag_t)buffer[0]; + + if (tag == IPP_TAG_END) + { + /* + * No more attributes left... + */ + + DEBUG_puts("ipp_read_file: IPP_TAG_END!"); + + ipp->state = IPP_DATA; + break; + } + else if (tag < IPP_TAG_UNSUPPORTED_VALUE) + { + /* + * Group tag... Set the current group and continue... + */ + + if (ipp->curtag == tag) + ippAddSeparator(ipp); + + ipp->curtag = tag; + ipp->current = NULL; + DEBUG_printf(("ipp_read_file: group tag = %x\n", tag)); + continue; + } + + DEBUG_printf(("ipp_read_file: value tag = %x\n", tag)); + + /* + * Get the name... + */ + + if (read(fd, buffer, 2) < 2) + { + DEBUG_puts("ipp_read_file: unable to read name length!"); + close(fd); + return (IPP_ERROR); + } + + n = (buffer[0] << 8) | buffer[1]; + + DEBUG_printf(("ipp_read_file: name length = %d\n", n)); + + if (n == 0) + { + /* + * More values for current attribute... + */ + + if (ipp->current == NULL) + { + close(fd); + return (IPP_ERROR); + } + + attr = ipp->current; + + /* + * Finally, reallocate the attribute array as needed... + */ + + if ((attr->num_values % IPP_MAX_VALUES) == 0) + { + ipp_attribute_t *temp, /* Pointer to new buffer */ + *ptr; /* Pointer in attribute list */ + + + /* + * Reallocate memory... + */ + + if ((temp = realloc(attr, sizeof(ipp_attribute_t) + + (attr->num_values + IPP_MAX_VALUES - 1) * + sizeof(ipp_value_t))) == NULL) + { + close(fd); + return (IPP_ERROR); + } + + /* + * Reset pointers in the list... + */ + + for (ptr = ipp->attrs; ptr && ptr->next != attr; ptr = ptr->next); + + if (ptr) + ptr->next = temp; + else + ipp->attrs = temp; + + attr = ipp->current = ipp->last = temp; + } + } + else + { + /* + * New attribute; read the name and add it... + */ + + if (read(fd, buffer, n) < n) + { + DEBUG_puts("ipp_read_file: unable to read name!"); + close(fd); + return (IPP_ERROR); + } + + buffer[n] = '\0'; + DEBUG_printf(("ipp_read_file: name = \'%s\'\n", buffer)); + + attr = ipp->current = _ipp_add_attr(ipp, IPP_MAX_VALUES); + + attr->group_tag = ipp->curtag; + attr->value_tag = tag; + attr->name = strdup((char *)buffer); + attr->num_values = 0; + } + + if (read(fd, buffer, 2) < 2) + { + DEBUG_puts("ipp_read_file: unable to read value length!"); + close(fd); + return (IPP_ERROR); + } + + n = (buffer[0] << 8) | buffer[1]; + DEBUG_printf(("ipp_read_file: value length = %d\n", n)); + + switch (tag) + { + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + if (read(fd, buffer, 4) < 4) + { + close(fd); + return (IPP_ERROR); + } + + n = (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) | + buffer[3]; + + attr->values[attr->num_values].integer = n; + break; + case IPP_TAG_BOOLEAN : + if (read(fd, buffer, 1) < 1) + { + close(fd); + return (IPP_ERROR); + } + + attr->values[attr->num_values].boolean = buffer[0]; + break; + case IPP_TAG_TEXT : + case IPP_TAG_NAME : + case IPP_TAG_KEYWORD : + case IPP_TAG_STRING : + case IPP_TAG_URI : + case IPP_TAG_URISCHEME : + case IPP_TAG_CHARSET : + case IPP_TAG_LANGUAGE : + case IPP_TAG_MIMETYPE : + if (read(fd, buffer, n) < n) + { + close(fd); + return (IPP_ERROR); + } + + buffer[n] = '\0'; + DEBUG_printf(("ipp_read_file: value = \'%s\'\n", buffer)); + + attr->values[attr->num_values].string.text = strdup((char *)buffer); + break; + case IPP_TAG_DATE : + if (read(fd, buffer, 11) < 11) + { + close(fd); + return (IPP_ERROR); + } + + memcpy(attr->values[attr->num_values].date, buffer, 11); + break; + case IPP_TAG_RESOLUTION : + if (read(fd, buffer, 9) < 9) + { + close(fd); + return (IPP_ERROR); + } + + attr->values[attr->num_values].resolution.xres = + (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) | + buffer[3]; + attr->values[attr->num_values].resolution.yres = + (((((buffer[4] << 8) | buffer[5]) << 8) | buffer[6]) << 8) | + buffer[7]; + attr->values[attr->num_values].resolution.units = + (ipp_res_t)buffer[8]; + break; + case IPP_TAG_RANGE : + if (read(fd, buffer, 8) < 8) + { + close(fd); + return (IPP_ERROR); + } + + attr->values[attr->num_values].range.lower = + (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) | + buffer[3]; + attr->values[attr->num_values].range.upper = + (((((buffer[4] << 8) | buffer[5]) << 8) | buffer[6]) << 8) | + buffer[7]; + break; + case IPP_TAG_TEXTLANG : + case IPP_TAG_NAMELANG : + if (read(fd, buffer, n) < n) + return (IPP_ERROR); + + bufptr = buffer; + + /* + * text-with-language and name-with-language are composite + * values: + * + * charset-length + * charset + * text-length + * text + */ + + n = (bufptr[0] << 8) | bufptr[1]; + + attr->values[attr->num_values].string.charset = calloc(n + 1, 1); + + memcpy(attr->values[attr->num_values].string.charset, + bufptr + 2, n); + + bufptr += 2 + n; + n = (bufptr[0] << 8) | bufptr[1]; + + attr->values[attr->num_values].string.text = calloc(n + 1, 1); + + memcpy(attr->values[attr->num_values].string.text, + bufptr + 2, n); + + break; + + default : /* Other unsupported values */ + attr->values[attr->num_values].unknown.length = n; + if (n > 0) + { + attr->values[attr->num_values].unknown.data = malloc(n); + if (read(fd, attr->values[attr->num_values].unknown.data, n) < n) + return (IPP_ERROR); + } + else + attr->values[attr->num_values].unknown.data = NULL; + break; + } + + attr->num_values ++; + } + break; + + case IPP_DATA : + break; + } + + /* + * Close the file and return... + */ + + close(fd); + + return (ipp->state); +} + + +/* + * 'ipp_write_file()' - Write an IPP request to a file. + */ + +static ipp_state_t /* O - State */ +ipp_write_file(const char *filename, /* I - File to write to */ + ipp_t *ipp) /* I - Request to write */ +{ + int fd; /* File descriptor */ + int i; /* Looping var */ + int n; /* Length of data */ + unsigned char buffer[8192], /* Data buffer */ + *bufptr; /* Pointer into buffer */ + ipp_attribute_t *attr; /* Current attribute */ + + + /* + * Open the file if possible... + */ + + if (filename == NULL || ipp == NULL) + return (IPP_ERROR); + + if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) == -1) + return (IPP_ERROR); + + fchmod(fd, 0600); + fchown(fd, User, Group); + + /* + * Write the IPP request... + */ + + ipp->state = IPP_IDLE; + + switch (ipp->state) + { + default : + break; /* anti-compiler-warning-code */ + + case IPP_IDLE : + ipp->state ++; /* Avoid common problem... */ + + case IPP_HEADER : + /* + * Send the request header... + */ + + bufptr = buffer; + + *bufptr++ = ipp->request.any.version[0]; + *bufptr++ = ipp->request.any.version[1]; + *bufptr++ = ipp->request.any.op_status >> 8; + *bufptr++ = ipp->request.any.op_status; + *bufptr++ = ipp->request.any.request_id >> 24; + *bufptr++ = ipp->request.any.request_id >> 16; + *bufptr++ = ipp->request.any.request_id >> 8; + *bufptr++ = ipp->request.any.request_id; + + if (write(fd, (char *)buffer, bufptr - buffer) < 0) + { + DEBUG_puts("ipp_write_file: Could not write IPP header..."); + close(fd); + return (IPP_ERROR); + } + + ipp->state = IPP_ATTRIBUTE; + ipp->current = ipp->attrs; + ipp->curtag = IPP_TAG_ZERO; + + case IPP_ATTRIBUTE : + while (ipp->current != NULL) + { + /* + * Write this attribute... + */ + + bufptr = buffer; + attr = ipp->current; + + ipp->current = ipp->current->next; + + if (ipp->curtag != attr->group_tag) + { + /* + * Send a group operation tag... + */ + + ipp->curtag = attr->group_tag; + + if (attr->group_tag == IPP_TAG_ZERO) + continue; + + DEBUG_printf(("ipp_write_file: wrote group tag = %x\n", attr->group_tag)); + *bufptr++ = attr->group_tag; + } + + if ((n = strlen(attr->name)) > (sizeof(buffer) - 3)) + return (IPP_ERROR); + + DEBUG_printf(("ipp_write_file: writing value tag = %x\n", attr->value_tag)); + DEBUG_printf(("ipp_write_file: writing name = %d, \'%s\'\n", n, attr->name)); + + *bufptr++ = attr->value_tag; + *bufptr++ = n >> 8; + *bufptr++ = n; + memcpy(bufptr, attr->name, n); + bufptr += n; + + switch (attr->value_tag) + { + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + for (i = 0; i < attr->num_values; i ++) + { + if ((sizeof(buffer) - (bufptr - buffer)) < 9) + { + if (write(fd, (char *)buffer, bufptr - buffer) < 0) + { + DEBUG_puts("ippWrite: Could not write IPP attribute..."); + return (IPP_ERROR); + } + + bufptr = buffer; + } + + if (i) + { + /* + * Arrays and sets are done by sending additional + * values with a zero-length name... + */ + + *bufptr++ = attr->value_tag; + *bufptr++ = 0; + *bufptr++ = 0; + } + + *bufptr++ = 0; + *bufptr++ = 4; + *bufptr++ = attr->values[i].integer >> 24; + *bufptr++ = attr->values[i].integer >> 16; + *bufptr++ = attr->values[i].integer >> 8; + *bufptr++ = attr->values[i].integer; + } + break; + + case IPP_TAG_BOOLEAN : + for (i = 0; i < attr->num_values; i ++) + { + if ((sizeof(buffer) - (bufptr - buffer)) < 6) + { + if (write(fd, (char *)buffer, bufptr - buffer) < 0) + { + DEBUG_puts("ippWrite: Could not write IPP attribute..."); + return (IPP_ERROR); + } + + bufptr = buffer; + } + + if (i) + { + /* + * Arrays and sets are done by sending additional + * values with a zero-length name... + */ + + *bufptr++ = attr->value_tag; + *bufptr++ = 0; + *bufptr++ = 0; + } + + *bufptr++ = 0; + *bufptr++ = 1; + *bufptr++ = attr->values[i].boolean; + } + break; + + case IPP_TAG_TEXT : + case IPP_TAG_NAME : + case IPP_TAG_KEYWORD : + case IPP_TAG_STRING : + case IPP_TAG_URI : + case IPP_TAG_URISCHEME : + case IPP_TAG_CHARSET : + case IPP_TAG_LANGUAGE : + case IPP_TAG_MIMETYPE : + for (i = 0; i < attr->num_values; i ++) + { + if (i) + { + /* + * Arrays and sets are done by sending additional + * values with a zero-length name... + */ + + DEBUG_printf(("ipp_write_file: writing value tag = %x\n", + attr->value_tag)); + DEBUG_printf(("ipp_write_file: writing name = 0, \'\'\n")); + + if ((sizeof(buffer) - (bufptr - buffer)) < 3) + { + if (write(fd, (char *)buffer, bufptr - buffer) < 0) + { + DEBUG_puts("ippWrite: Could not write IPP attribute..."); + return (IPP_ERROR); + } + + bufptr = buffer; + } + + *bufptr++ = attr->value_tag; + *bufptr++ = 0; + *bufptr++ = 0; + } + + n = strlen(attr->values[i].string.text); + + if (n > sizeof(buffer)) + return (IPP_ERROR); + + DEBUG_printf(("ipp_write_file: writing string = %d, \'%s\'\n", n, + attr->values[i].string.text)); + + if ((sizeof(buffer) - (bufptr - buffer)) < (n + 2)) + { + if (write(fd, (char *)buffer, bufptr - buffer) < 0) + { + DEBUG_puts("ipp_write_file: Could not write IPP attribute..."); + close(fd); + return (IPP_ERROR); + } + + bufptr = buffer; + } + + *bufptr++ = n >> 8; + *bufptr++ = n; + memcpy(bufptr, attr->values[i].string.text, n); + bufptr += n; + } + break; + + case IPP_TAG_DATE : + for (i = 0; i < attr->num_values; i ++) + { + if ((sizeof(buffer) - (bufptr - buffer)) < 16) + { + if (write(fd, (char *)buffer, bufptr - buffer) < 0) + { + DEBUG_puts("ippWrite: Could not write IPP attribute..."); + return (IPP_ERROR); + } + + bufptr = buffer; + } + + if (i) + { + /* + * Arrays and sets are done by sending additional + * values with a zero-length name... + */ + + *bufptr++ = attr->value_tag; + *bufptr++ = 0; + *bufptr++ = 0; + } + + *bufptr++ = 0; + *bufptr++ = 11; + memcpy(bufptr, attr->values[i].date, 11); + bufptr += 11; + } + break; + + case IPP_TAG_RESOLUTION : + for (i = 0; i < attr->num_values; i ++) + { + if ((sizeof(buffer) - (bufptr - buffer)) < 14) + { + if (write(fd, (char *)buffer, bufptr - buffer) < 0) + { + DEBUG_puts("ippWrite: Could not write IPP attribute..."); + return (IPP_ERROR); + } + + bufptr = buffer; + } + + if (i) + { + /* + * Arrays and sets are done by sending additional + * values with a zero-length name... + */ + + *bufptr++ = attr->value_tag; + *bufptr++ = 0; + *bufptr++ = 0; + } + + *bufptr++ = 0; + *bufptr++ = 9; + *bufptr++ = attr->values[i].resolution.xres >> 24; + *bufptr++ = attr->values[i].resolution.xres >> 16; + *bufptr++ = attr->values[i].resolution.xres >> 8; + *bufptr++ = attr->values[i].resolution.xres; + *bufptr++ = attr->values[i].resolution.yres >> 24; + *bufptr++ = attr->values[i].resolution.yres >> 16; + *bufptr++ = attr->values[i].resolution.yres >> 8; + *bufptr++ = attr->values[i].resolution.yres; + *bufptr++ = attr->values[i].resolution.units; + } + break; + + case IPP_TAG_RANGE : + for (i = 0; i < attr->num_values; i ++) + { + if ((sizeof(buffer) - (bufptr - buffer)) < 13) + { + if (write(fd, (char *)buffer, bufptr - buffer) < 0) + { + DEBUG_puts("ippWrite: Could not write IPP attribute..."); + return (IPP_ERROR); + } + + bufptr = buffer; + } + + if (i) + { + /* + * Arrays and sets are done by sending additional + * values with a zero-length name... + */ + + *bufptr++ = attr->value_tag; + *bufptr++ = 0; + *bufptr++ = 0; + } + + *bufptr++ = 0; + *bufptr++ = 8; + *bufptr++ = attr->values[i].range.lower >> 24; + *bufptr++ = attr->values[i].range.lower >> 16; + *bufptr++ = attr->values[i].range.lower >> 8; + *bufptr++ = attr->values[i].range.lower; + *bufptr++ = attr->values[i].range.upper >> 24; + *bufptr++ = attr->values[i].range.upper >> 16; + *bufptr++ = attr->values[i].range.upper >> 8; + *bufptr++ = attr->values[i].range.upper; + } + break; + + case IPP_TAG_TEXTLANG : + case IPP_TAG_NAMELANG : + for (i = 0; i < attr->num_values; i ++) + { + if (i) + { + /* + * Arrays and sets are done by sending additional + * values with a zero-length name... + */ + + if ((sizeof(buffer) - (bufptr - buffer)) < 3) + { + if (write(fd, (char *)buffer, bufptr - buffer) < 0) + { + DEBUG_puts("ippWrite: Could not write IPP attribute..."); + return (IPP_ERROR); + } + + bufptr = buffer; + } + + *bufptr++ = attr->value_tag; + *bufptr++ = 0; + *bufptr++ = 0; + } + + n = strlen(attr->values[i].string.charset) + + strlen(attr->values[i].string.text) + + 4; + + if (n > sizeof(buffer)) + return (IPP_ERROR); + + if ((sizeof(buffer) - (bufptr - buffer)) < (n + 2)) + { + if (write(fd, (char *)buffer, bufptr - buffer) < 0) + { + DEBUG_puts("ipp_write_file: Could not write IPP attribute..."); + return (IPP_ERROR); + } + + bufptr = buffer; + } + + /* Length of entire value */ + *bufptr++ = n >> 8; + *bufptr++ = n; + + /* Length of charset */ + n = strlen(attr->values[i].string.charset); + *bufptr++ = n >> 8; + *bufptr++ = n; + + /* Charset */ + memcpy(bufptr, attr->values[i].string.charset, n); + bufptr += n; + + /* Length of text */ + n = strlen(attr->values[i].string.text); + *bufptr++ = n >> 8; + *bufptr++ = n; + + /* Text */ + memcpy(bufptr, attr->values[i].string.text, n); + bufptr += n; + } + break; + + default : + for (i = 0; i < attr->num_values; i ++) + { + if (i) + { + /* + * Arrays and sets are done by sending additional + * values with a zero-length name... + */ + + if ((sizeof(buffer) - (bufptr - buffer)) < 3) + { + if (write(fd, (char *)buffer, bufptr - buffer) < 0) + { + DEBUG_puts("ippWrite: Could not write IPP attribute..."); + return (IPP_ERROR); + } + + bufptr = buffer; + } + + *bufptr++ = attr->value_tag; + *bufptr++ = 0; + *bufptr++ = 0; + } + + n = attr->values[i].unknown.length; + + if (n > sizeof(buffer)) + return (IPP_ERROR); + + if ((sizeof(buffer) - (bufptr - buffer)) < (n + 2)) + { + if (write(fd, (char *)buffer, bufptr - buffer) < 0) + { + DEBUG_puts("ipp_write_file: Could not write IPP attribute..."); + return (IPP_ERROR); + } + + bufptr = buffer; + } + + /* Length of unknown value */ + *bufptr++ = n >> 8; + *bufptr++ = n; + + /* Value */ + if (n > 0) + { + memcpy(bufptr, attr->values[i].unknown.data, n); + bufptr += n; + } + } + break; + } + + /* + * Write the data out... + */ + + if (write(fd, (char *)buffer, bufptr - buffer) < 0) + { + DEBUG_puts("ipp_write_file: Could not write IPP attribute..."); + close(fd); + return (IPP_ERROR); + } + + DEBUG_printf(("ipp_write_file: wrote %d bytes\n", bufptr - buffer)); + } + + if (ipp->current == NULL) + { + /* + * Done with all of the attributes; add the end-of-attributes tag... + */ + + buffer[0] = IPP_TAG_END; + if (write(fd, (char *)buffer, 1) < 0) + { + DEBUG_puts("ipp_write_file: Could not write IPP end-tag..."); + close(fd); + return (IPP_ERROR); + } + + ipp->state = IPP_DATA; + } + break; + + case IPP_DATA : + break; + } + + /* + * Close the file and return... + */ + + close(fd); + + return (ipp->state); +} + + /* * 'set_time()' - Set one of the "time-at-xyz" attributes... */ @@ -2049,5 +2990,5 @@ start_process(const char *command, /* I - Full path to command */ /* - * End of "$Id: job.c,v 1.124.2.2 2001/05/13 18:38:36 mike Exp $". + * End of "$Id: job.c,v 1.124.2.3 2001/12/26 16:52:54 mike Exp $". */ diff --git a/scheduler/listen.c b/scheduler/listen.c index a0c2549079..3b565bf35b 100644 --- a/scheduler/listen.c +++ b/scheduler/listen.c @@ -1,5 +1,5 @@ /* - * "$Id: listen.c,v 1.9.2.1 2001/04/02 19:51:50 mike Exp $" + * "$Id: listen.c,v 1.9.2.2 2001/12/26 16:52:54 mike Exp $" * * Server listening routines for the Common UNIX Printing System (CUPS) * scheduler. @@ -107,7 +107,7 @@ StartListening(void) memset(&ServerAddr, 0, sizeof(ServerAddr)); - if ((host = gethostbyname(ServerName)) != NULL) + if ((host = httpGetHostByName(ServerName)) != NULL) { /* * Found the server's address! @@ -216,5 +216,5 @@ StopListening(void) /* - * End of "$Id: listen.c,v 1.9.2.1 2001/04/02 19:51:50 mike Exp $". + * End of "$Id: listen.c,v 1.9.2.2 2001/12/26 16:52:54 mike Exp $". */ diff --git a/scheduler/log.c b/scheduler/log.c index 5a92b0ccfb..7ea92f3b03 100644 --- a/scheduler/log.c +++ b/scheduler/log.c @@ -1,5 +1,5 @@ /* - * "$Id: log.c,v 1.19 2001/02/21 20:16:47 mike Exp $" + * "$Id: log.c,v 1.19.2.1 2001/12/26 16:52:54 mike Exp $" * * Log file routines for the Common UNIX Printing System (CUPS). * @@ -86,7 +86,7 @@ GetDateTime(time_t t) /* I - Time value */ * log files. If you want GMT, set the TZ environment variable accordingly * before starting the scheduler. * - * (*BSD stores the timezone offset in the tm structure) + * (*BSD and Darwin store the timezone offset in the tm structure) */ date = localtime(&t); @@ -94,11 +94,11 @@ GetDateTime(time_t t) /* I - Time value */ snprintf(s, sizeof(s), "[%02d/%s/%04d:%02d:%02d:%02d %+03ld%02ld]", date->tm_mday, months[date->tm_mon], 1900 + date->tm_year, date->tm_hour, date->tm_min, date->tm_sec, -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +#ifdef HAVE_TM_GMTOFF -date->tm_gmtoff / 3600, (date->tm_gmtoff / 60) % 60); #else -timezone / 3600, (timezone / 60) % 60); -#endif /* __*BSD__ */ +#endif /* HAVE_TM_GMTOFF */ return (s); } @@ -436,5 +436,5 @@ check_log_file(FILE **log, /* IO - Log file */ /* - * End of "$Id: log.c,v 1.19 2001/02/21 20:16:47 mike Exp $". + * End of "$Id: log.c,v 1.19.2.1 2001/12/26 16:52:54 mike Exp $". */ diff --git a/scheduler/main.c b/scheduler/main.c index 494a4b7805..e143e3eef5 100644 --- a/scheduler/main.c +++ b/scheduler/main.c @@ -1,5 +1,5 @@ /* - * "$Id: main.c,v 1.57.2.1 2001/05/13 18:38:37 mike Exp $" + * "$Id: main.c,v 1.57.2.2 2001/12/26 16:52:55 mike Exp $" * * Scheduler main loop for the Common UNIX Printing System (CUPS). * @@ -446,7 +446,12 @@ main(int argc, /* I - Number of command-line arguments */ if (Browsing) { if (FD_ISSET(BrowseSocket, &input)) - UpdateBrowseList(); + UpdateCUPSBrowse(); + +#ifdef HAVE_LIBSLP + if ((BrowseProtocols & BROWSE_SLP) && BrowseSLPRefresh <= time(NULL)) + UpdateSLPBrowse(); +#endif /* HAVE_LIBSLP */ SendBrowseList(); } @@ -740,5 +745,5 @@ usage(void) /* - * End of "$Id: main.c,v 1.57.2.1 2001/05/13 18:38:37 mike Exp $". + * End of "$Id: main.c,v 1.57.2.2 2001/12/26 16:52:55 mike Exp $". */ diff --git a/scheduler/ppds.c b/scheduler/ppds.c index 578d5b6102..d17d6ff554 100644 --- a/scheduler/ppds.c +++ b/scheduler/ppds.c @@ -1,5 +1,5 @@ /* - * "$Id: ppds.c,v 1.14.2.1 2001/05/13 18:38:38 mike Exp $" + * "$Id: ppds.c,v 1.14.2.2 2001/12/26 16:52:55 mike Exp $" * * PPD scanning routines for the Common UNIX Printing System (CUPS). * @@ -168,10 +168,26 @@ LoadPPDs(const char *d) /* I - Directory to scan... */ PPDs = ippNew(); + /* + * First the raw driver... + */ + + ippAddString(PPDs, IPP_TAG_PRINTER, IPP_TAG_NAME, + "ppd-name", NULL, "raw"); + ippAddString(PPDs, IPP_TAG_PRINTER, IPP_TAG_TEXT, + "ppd-make", NULL, "Raw"); + ippAddString(PPDs, IPP_TAG_PRINTER, IPP_TAG_TEXT, + "ppd-make-and-model", NULL, "Raw Queue"); + ippAddString(PPDs, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE, + "ppd-natural-language", NULL, "en"); + + /* + * Then the PPD files... + */ + for (i = num_ppds, ppd = ppds; i > 0; i --, ppd ++) { - if (i) - ippAddSeparator(PPDs); + ippAddSeparator(PPDs); ippAddString(PPDs, IPP_TAG_PRINTER, IPP_TAG_NAME, "ppd-name", NULL, ppd->ppd_name); @@ -399,11 +415,8 @@ static void load_ppds(const char *d, /* I - Actual directory */ const char *p) /* I - Virtual path in name */ { -#ifdef HAVE_LIBZ - gzFile fp; /* Pointer to file */ -#else - FILE *fp; /* Pointer to file */ -#endif /* HAVE_LIBZ */ + int i; /* Looping var */ + buf_t fp; /* Pointer to file */ DIR *dir; /* Directory pointer */ DIRENT *dent; /* Directory entry */ struct stat fileinfo; /* File information */ @@ -411,10 +424,37 @@ load_ppds(const char *d, /* I - Actual directory */ line[1024], /* Line from backend */ *ptr, /* Pointer into name */ name[128], /* Name of PPD file */ - language[64], /* Device class */ - manufacturer[1024], /* Manufacturer */ - make_model[256]; /* Make and model */ - ppd_info_t *ppd; /* New PPD file */ + language[64], /* PPD language version */ + country[64], /* Country code */ + manufacturer[256], /* Manufacturer */ + make_model[256], /* Make and Model */ + model_name[256], /* ModelName */ + nick_name[256]; /* NickName */ + ppd_info_t *ppd, /* New PPD file */ + key; /* Search key */ + int new_ppd; /* Is this a new PPD? */ + struct /* LanguageVersion translation table */ + { + const char *version, /* LanguageVersion string */ + *language; /* Language code */ + } languages[] = + { + { "chinese", "cn" }, + { "english", "en" }, + { "french", "fr" }, + { "german", "de" }, + { "danish", "da" }, + { "finnish", "fi" }, + { "italian", "it" }, + { "dutch", "du" }, + { "japanese", "jp" }, + { "norwegian", "no" }, + { "polish", "pl" }, + { "portugese", "pt" }, + { "russian", "ru" }, + { "swedish", "sv" }, + { "turkish", "tr" } + }; if ((dir = opendir(d)) == NULL) @@ -568,8 +608,9 @@ load_ppds(const char *d, /* I - Actual directory */ *ptr = '\0'; else if (strncasecmp(manufacturer, "agfa", 4) == 0) strcpy(manufacturer, "AGFA"); - else if (strncasecmp(manufacturer, "herk", 4) == 0) - strcpy(manufacturer, "Linotype"); + else if (strncasecmp(manufacturer, "herk", 4) == 0 || + strncasecmp(manufacturer, "linotype", 8) == 0) + strcpy(manufacturer, "LHAG"); else strcpy(manufacturer, "Other"); @@ -595,24 +636,57 @@ load_ppds(const char *d, /* I - Actual directory */ else if (strcasecmp(manufacturer, "designjet") == 0) strcpy(manufacturer, "HP"); } + else if (strncasecmp(manufacturer, "LHAG", 4) == 0 || + strncasecmp(manufacturer, "linotype", 8) == 0) + strcpy(manufacturer, "LHAG"); /* * Fix the language as needed... */ - if (strcasecmp(language, "german") == 0) - strcpy(language, "de"); - else if (strcasecmp(language, "spanish") == 0) - strcpy(language, "es"); - else if (strlen(language) > 2) + if ((ptr = strchr(language, '-')) != NULL) + *ptr++ = '\0'; + else if ((ptr = strchr(language, '_')) != NULL) + *ptr++ = '\0'; + + if (ptr) + { + /* + * Setup the country suffix... + */ + + country[0] = '_'; + strcpy(country + 1, ptr); + } + else + { + /* + * No country suffix... + */ + + country[0] = '\0'; + } + + for (i = 0; i < (int)(sizeof(languages) / sizeof(languages[0])); i ++) + if (strcasecmp(languages[i].version, language) == 0) + break; + + if (i < (int)(sizeof(languages) / sizeof(languages[0]))) + { + /* + * Found a known language... + */ + + snprintf(language, sizeof(language), "%s%s", languages[i].language, + country); + } + else { /* - * en, fr, it, etc. + * Unknown language; use "xx"... */ - language[0] = tolower(language[0]); - language[1] = tolower(language[1]); - language[2] = '\0'; + strcpy(language, "xx"); } /* @@ -661,5 +735,5 @@ load_ppds(const char *d, /* I - Actual directory */ /* - * End of "$Id: ppds.c,v 1.14.2.1 2001/05/13 18:38:38 mike Exp $". + * End of "$Id: ppds.c,v 1.14.2.2 2001/12/26 16:52:55 mike Exp $". */ diff --git a/scheduler/printers.c b/scheduler/printers.c index f2b34a6cff..05e0b2ff17 100644 --- a/scheduler/printers.c +++ b/scheduler/printers.c @@ -1,5 +1,5 @@ /* - * "$Id: printers.c,v 1.93.2.3 2001/05/13 18:38:38 mike Exp $" + * "$Id: printers.c,v 1.93.2.4 2001/12/26 16:52:55 mike Exp $" * * Printer routines for the Common UNIX Printing System (CUPS). * @@ -500,12 +500,12 @@ LoadAllPrinters(void) continue; /* - * Strip trailing newline, if any... + * Strip trailing whitespace, if any... */ len = strlen(line); - if (line[len - 1] == '\n') + while (len > 0 && isspace(line[len - 1])) { len --; line[len] = '\0'; @@ -754,10 +754,13 @@ SaveAllPrinters(void) if (printer->info[0]) fprintf(fp, "Info %s\n", printer->info); - if (printer->more_info[0]) + + if (printer->location[0]) fprintf(fp, "Location %s\n", printer->location); + if (printer->device_uri[0]) fprintf(fp, "DeviceURI %s\n", printer->device_uri); + if (printer->state == IPP_PRINTER_STOPPED) { fputs("State Stopped\n", fp); @@ -765,19 +768,18 @@ SaveAllPrinters(void) } else fputs("State Idle\n", fp); + if (printer->accepting) fputs("Accepting Yes\n", fp); else fputs("Accepting No\n", fp); + fprintf(fp, "JobSheets %s %s\n", printer->job_sheets[0], printer->job_sheets[1]); - if (printer->quota_period) - { - fprintf(fp, "QuotaPeriod %d\n", printer->quota_period); - fprintf(fp, "PageLimit %d\n", printer->page_limit); - fprintf(fp, "KLimit %d\n", printer->k_limit); - } + fprintf(fp, "QuotaPeriod %d\n", printer->quota_period); + fprintf(fp, "PageLimit %d\n", printer->page_limit); + fprintf(fp, "KLimit %d\n", printer->k_limit); for (i = 0; i < printer->num_users; i ++) fprintf(fp, "%sUser %s\n", printer->deny_users ? "Deny" : "Allow", @@ -807,8 +809,8 @@ SetPrinterAttrs(printer_t *p) /* I - Printer to setup */ char filename[1024]; /* Name of PPD file */ int num_media; /* Number of media options */ location_t *auth; /* Pointer to authentication element */ - int auth_len; /* Length of class or printer resource */ const char *auth_supported; /* Authentication supported */ + cups_ptype_t printer_type; /* Printer type data */ ppd_file_t *ppd; /* PPD file data */ ppd_option_t *input_slot, /* InputSlot options */ *media_type, /* MediaType options */ @@ -926,15 +928,9 @@ SetPrinterAttrs(printer_t *p) /* I - Printer to setup */ if (!(p->type & CUPS_PRINTER_REMOTE)) { if (p->type & CUPS_PRINTER_CLASS) - { - auth_len = 8; snprintf(resource, sizeof(resource), "/classes/%s", p->name); - } else - { - auth_len = 9; snprintf(resource, sizeof(resource), "/printers/%s", p->name); - } for (i = NumLocations, auth = Locations; i > 0; i --, auth ++) if (strcmp(auth->location, resource) == 0) @@ -987,7 +983,7 @@ SetPrinterAttrs(printer_t *p) /* I - Printer to setup */ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info", NULL, p->info); ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-more-info", - NULL, p->more_info); + NULL, p->uri); ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "pdl-override-supported", NULL, "not-attempted"); ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, @@ -1013,8 +1009,9 @@ SetPrinterAttrs(printer_t *p) /* I - Printer to setup */ "generated-natural-language-supported", NULL, DefaultLanguage); ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE, "document-format-default", NULL, "application/octet-stream"); - ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE, - "document-format-supported", NULL, "application/octet-stream"); + ippAddStrings(p->attrs, IPP_TAG_PRINTER, + (ipp_tag_t)(IPP_TAG_MIMETYPE | IPP_TAG_COPY), + "document-format-supported", NumMimeTypes, NULL, MimeTypes); ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "compression-supported", NULL, "none"); ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, @@ -1059,9 +1056,9 @@ SetPrinterAttrs(printer_t *p) /* I - Printer to setup */ * Setup the job-sheets-supported and job-sheets-default attributes... */ - if (Classification[0]) - attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME, - "job-sheets-supported", 2, NULL, NULL); + if (Classification[0] && !ClassifyOverride) + attr = ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME, + "job-sheets-supported", NULL, Classification); else attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME, "job-sheets-supported", NumBanners + 1, NULL, NULL); @@ -1070,7 +1067,7 @@ SetPrinterAttrs(printer_t *p) /* I - Printer to setup */ LogMessage(L_EMERG, "SetPrinterAttrs: Unable to allocate memory for " "job-sheets-supported attribute: %s!", strerror(errno)); - else + else if (!Classification[0] || ClassifyOverride) { attr->values[0].string.text = strdup("none"); @@ -1083,16 +1080,21 @@ SetPrinterAttrs(printer_t *p) /* I - Printer to setup */ } } - attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME, - "job-sheets-default", 2, NULL, NULL); - - if (attr != NULL) + if (!(p->type & CUPS_PRINTER_REMOTE)) { - attr->values[0].string.text = strdup(p->job_sheets[0]); - attr->values[1].string.text = strdup(p->job_sheets[1]); + attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME, + "job-sheets-default", 2, NULL, NULL); + + if (attr != NULL) + { + attr->values[0].string.text = strdup(p->job_sheets[0]); + attr->values[1].string.text = strdup(p->job_sheets[1]); + } } } + printer_type = p->type; + if (p->type & CUPS_PRINTER_REMOTE) { /* @@ -1216,7 +1218,12 @@ SetPrinterAttrs(printer_t *p) /* I - Printer to setup */ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-make-and-model", NULL, ppd->nickname); - strncpy(p->make_model, ppd->nickname, sizeof(p->make_model) - 1); + if (ppd->nickname) + strncpy(p->make_model, ppd->nickname, sizeof(p->make_model) - 1); + else if (ppd->modelname) + strncpy(p->make_model, ppd->modelname, sizeof(p->make_model) - 1); + else + strcpy(p->make_model, "Bad PPD File"); /* * Add media options from the PPD file... @@ -1337,6 +1344,8 @@ SetPrinterAttrs(printer_t *p) /* I - Printer to setup */ AddPrinterFilter(p, "application/vnd.cups-postscript 0 -"); ppdClose(ppd); + + printer_type = p->type; } else if (access(filename, 0) == 0) { @@ -1365,6 +1374,38 @@ SetPrinterAttrs(printer_t *p) /* I - Printer to setup */ ServerRoot, p->name); AddPrinterFilter(p, filename); } + else if (strncmp(p->device_uri, "ipp://", 6) == 0 && + (strstr(p->device_uri, "/printers/") != NULL || + strstr(p->device_uri, "/classes/") != NULL)) + { + /* + * Tell the client this is really a hard-wired remote printer. + */ + + printer_type |= CUPS_PRINTER_REMOTE; + + /* + * Reset the printer-uri-supported attribute to point at the + * remote printer... + */ + + attr = ippFindAttribute(p->attrs, "printer-uri-supported", IPP_TAG_URI); + free(attr->values[0].string.text); + attr->values[0].string.text = strdup(p->device_uri); + + /* + * Then set the make-and-model accordingly... + */ + + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, + "printer-make-and-model", NULL, "Remote Printer"); + + /* + * Print all files directly... + */ + + AddPrinterFilter(p, "*/* 0 -"); + } else { /* @@ -1390,7 +1431,8 @@ SetPrinterAttrs(printer_t *p) /* I - Printer to setup */ * Add the CUPS-specific printer-type attribute... */ - ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-type", p->type); + ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-type", + printer_type); DEBUG_printf(("SetPrinterAttrs: leaving name = %s, type = %x\n", p->name, p->type)); @@ -1793,5 +1835,5 @@ write_printcap(void) /* - * End of "$Id: printers.c,v 1.93.2.3 2001/05/13 18:38:38 mike Exp $". + * End of "$Id: printers.c,v 1.93.2.4 2001/12/26 16:52:55 mike Exp $". */ diff --git a/scheduler/printers.h b/scheduler/printers.h index fb0f550779..5f2329a023 100644 --- a/scheduler/printers.h +++ b/scheduler/printers.h @@ -1,5 +1,5 @@ /* - * "$Id: printers.h,v 1.22 2001/01/22 15:04:01 mike Exp $" + * "$Id: printers.h,v 1.22.2.1 2001/12/26 16:52:55 mike Exp $" * * Printer definitions for the Common UNIX Printing System (CUPS) scheduler. * @@ -47,8 +47,7 @@ typedef struct printer_str name[IPP_MAX_NAME], /* Printer name */ location[IPP_MAX_NAME], /* Location code */ make_model[IPP_MAX_NAME],/* Make and model */ - info[IPP_MAX_NAME], /* Description */ - more_info[HTTP_MAX_URI];/* URL for site-specific info */ + info[IPP_MAX_NAME]; /* Description */ int accepting; /* Accepting jobs? */ ipp_pstate_t state; /* Printer state */ char state_message[1024]; /* Printer state message */ @@ -114,5 +113,5 @@ extern const char *ValidateDest(const char *hostname, /* - * End of "$Id: printers.h,v 1.22 2001/01/22 15:04:01 mike Exp $". + * End of "$Id: printers.h,v 1.22.2.1 2001/12/26 16:52:55 mike Exp $". */ diff --git a/scheduler/quotas.c b/scheduler/quotas.c index f569bbd557..339a75c9f6 100644 --- a/scheduler/quotas.c +++ b/scheduler/quotas.c @@ -1,5 +1,5 @@ /* - * "$Id: quotas.c,v 1.4 2001/01/22 15:04:01 mike Exp $" + * "$Id: quotas.c,v 1.4.2.1 2001/12/26 16:52:55 mike Exp $" * * Quota routines for the Common UNIX Printing System (CUPS). * @@ -182,7 +182,7 @@ UpdateQuota(printer_t *p, /* I - Printer */ next = job->next; if (strcasecmp(job->dest, p->name) != 0 || - strcmp(job->username, q->username) != 0) + strcasecmp(job->username, q->username) != 0) continue; if ((attr = ippFindAttribute(job->attrs, "time-at-completion", @@ -227,10 +227,10 @@ static int /* O - Result of comparison */ compare(const quota_t *q1, /* I - First quota record */ const quota_t *q2) /* I - Second quota record */ { - return (strcmp(q1->username, q2->username)); + return (strcasecmp(q1->username, q2->username)); } /* - * End of "$Id: quotas.c,v 1.4 2001/01/22 15:04:01 mike Exp $". + * End of "$Id: quotas.c,v 1.4.2.1 2001/12/26 16:52:55 mike Exp $". */ diff --git a/scheduler/type.c b/scheduler/type.c index fcb444d23f..c44f7c1c74 100644 --- a/scheduler/type.c +++ b/scheduler/type.c @@ -1,5 +1,5 @@ /* - * "$Id: type.c,v 1.11 2001/02/07 19:41:38 mike Exp $" + * "$Id: type.c,v 1.11.2.1 2001/12/26 16:52:55 mike Exp $" * * MIME typing routines for the Common UNIX Printing System (CUPS). * @@ -902,7 +902,7 @@ checkrules(const char *filename, /* I - Filename */ break; case MIME_MAGIC_LOCALE : - result = (strcmp(rules->value.localev, setlocale(LC_ALL, NULL)) == 0); + result = (strcmp(rules->value.localev, setlocale(LC_MESSAGES, NULL)) == 0); break; case MIME_MAGIC_CONTAINS : @@ -1086,5 +1086,5 @@ patmatch(const char *s, /* I - String to match against */ /* - * End of "$Id: type.c,v 1.11 2001/02/07 19:41:38 mike Exp $". + * End of "$Id: type.c,v 1.11.2.1 2001/12/26 16:52:55 mike Exp $". */ diff --git a/systemv/Makefile b/systemv/Makefile index 270277692b..7d9b1a5e70 100644 --- a/systemv/Makefile +++ b/systemv/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.23 2001/01/22 15:04:02 mike Exp $" +# "$Id: Makefile,v 1.23.2.1 2001/12/26 16:52:56 mike Exp $" # # System V commands makefile for the Common UNIX Printing System (CUPS). # @@ -24,10 +24,10 @@ include ../Makedefs -TARGETS = accept cancel lp lpadmin lpinfo lpmove lpoptions lppasswd \ - lpstat -OBJS = accept.o cancel.o lp.o lpadmin.o lpinfo.o lpmove.o \ - lpoptions.o lppasswd.o lpstat.o +TARGETS = accept cancel cupsaddsmb lp lpadmin lpinfo lpmove \ + lpoptions lppasswd lpstat +OBJS = accept.o cancel.o cupsaddsmb.o lp.o lpadmin.o \ + lpinfo.o lpmove.o lpoptions.o lppasswd.o lpstat.o # @@ -49,30 +49,24 @@ clean: # Install all targets... # -install: $(INSTALL_SYSV) - -$(MKDIR) $(BINDIR) - $(CHMOD) ugo+rx $(BINDIR) - $(INSTALL_BIN) accept lpadmin lpinfo lpmove $(SBINDIR) - $(INSTALL_BIN) cancel lp lpoptions lppasswd lpstat $(BINDIR) - $(CHMOD) u+s $(BINDIR)/lppasswd +install: + $(INSTALL_DIR) $(BINDIR) + $(INSTALL_BIN) accept $(SBINDIR) $(RM) $(SBINDIR)/reject $(LN) accept $(SBINDIR)/reject + $(INSTALL_BIN) cupsaddsmb $(SBINDIR) + $(INSTALL_BIN) lpadmin $(SBINDIR) + $(INSTALL_BIN) lpinfo $(SBINDIR) + $(INSTALL_BIN) lpmove $(SBINDIR) + $(INSTALL_BIN) cancel $(BINDIR) $(RM) $(BINDIR)/disable $(LN) ../sbin/accept $(BINDIR)/disable $(RM) $(BINDIR)/enable $(LN) ../sbin/accept $(BINDIR)/enable - -install-sysv: - -$(MKDIR) $(LIBDIR) - $(CHMOD) ugo+rx $(LIBDIR) - $(RM) $(LIBDIR)/lpadmin - $(LN) ../sbin/lpadmin $(LIBDIR) - $(RM) $(LIBDIR)/lpmove - $(LN) ../sbin/lpmove $(LIBDIR) - $(RM) $(LIBDIR)/accept - $(LN) ../sbin/accept $(LIBDIR) - $(RM) $(LIBDIR)/reject - $(LN) ../sbin/accept $(LIBDIR)/reject + $(INSTALL_BIN) lp $(BINDIR) + $(INSTALL_BIN) lpoptions $(BINDIR) + $(INSTALL_BIN) lpstat $(BINDIR) + $(INSTALL_BIN) -m 4755 -o $(CUPS_USER) -g $(CUPS_GROUP) lppasswd $(BINDIR) # @@ -82,6 +76,10 @@ install-sysv: accept: accept.o ../cups/$(LIBCUPS) echo Linking $@... $(CC) $(LDFLAGS) -o accept accept.o $(LIBS) + $(RM) reject enable disable + $(LN) accept reject + $(LN) accept enable + $(LN) accept disable accept.o: ../cups/cups.h @@ -97,6 +95,17 @@ cancel: cancel.o ../cups/$(LIBCUPS) cancel.o: ../cups/cups.h +# +# cupsaddsmb +# + +cupsaddsmb: cupsaddsmb.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o cupsaddsmb cupsaddsmb.o $(LIBS) + +cupsaddsmb.o: ../cups/cups.h ../cups/string.h + + # # lp # @@ -177,5 +186,5 @@ lpstat.o: ../cups/cups.h $(OBJS): ../Makedefs # -# End of "$Id: Makefile,v 1.23 2001/01/22 15:04:02 mike Exp $". +# End of "$Id: Makefile,v 1.23.2.1 2001/12/26 16:52:56 mike Exp $". # diff --git a/systemv/accept.c b/systemv/accept.c index 272098c15c..e8726d0643 100644 --- a/systemv/accept.c +++ b/systemv/accept.c @@ -1,5 +1,5 @@ /* - * "$Id: accept.c,v 1.11.2.1 2001/05/13 18:38:40 mike Exp $" + * "$Id: accept.c,v 1.11.2.2 2001/12/26 16:52:56 mike Exp $" * * "accept", "disable", "enable", and "reject" commands for the Common * UNIX Printing System (CUPS). @@ -57,6 +57,7 @@ main(int argc, /* I - Number of command-line arguments */ /* Name of printer or class */ uri[1024], /* Printer URI */ *reason; /* Reason for reject/disable */ + const char *server; /* Server name */ ipp_t *request; /* IPP request */ ipp_t *response; /* IPP response */ ipp_op_t op; /* Operation */ @@ -90,6 +91,7 @@ main(int argc, /* I - Number of command-line arguments */ return (1); } + server = cupsServer(); http = NULL; reason = NULL; encryption = cupsEncryption(); @@ -123,7 +125,7 @@ main(int argc, /* I - Number of command-line arguments */ httpClose(http); if (argv[i][2] != '\0') - http = httpConnectEncrypt(argv[i] + 2, ippPort(), encryption); + server = argv[i] + 2; else { i ++; @@ -134,9 +136,11 @@ main(int argc, /* I - Number of command-line arguments */ return (1); } - http = httpConnectEncrypt(argv[i], ippPort(), encryption); + server = argv[i]; } + http = httpConnectEncrypt(server, ippPort(), encryption); + if (http == NULL) { fputs(argv[0], stderr); @@ -173,7 +177,10 @@ main(int argc, /* I - Number of command-line arguments */ */ if (sscanf(argv[i], "%1023[^@]@%1023s", printer, hostname) == 1) - strcpy(hostname, "localhost"); + { + strncpy(hostname, server, sizeof(hostname) - 1); + hostname[sizeof(hostname) - 1] = '\0'; + } if (http != NULL && strcasecmp(http->hostname, hostname) != 0) { @@ -304,5 +311,5 @@ main(int argc, /* I - Number of command-line arguments */ /* - * End of "$Id: accept.c,v 1.11.2.1 2001/05/13 18:38:40 mike Exp $". + * End of "$Id: accept.c,v 1.11.2.2 2001/12/26 16:52:56 mike Exp $". */ diff --git a/systemv/cupsaddsmb.c b/systemv/cupsaddsmb.c index d4876a0891..3fffa42707 100644 --- a/systemv/cupsaddsmb.c +++ b/systemv/cupsaddsmb.c @@ -1,5 +1,5 @@ /* - * "$Id: cupsaddsmb.c,v 1.3 2001/12/18 21:08:21 mike Exp $" + * "$Id: cupsaddsmb.c,v 1.3.2.1 2001/12/26 16:52:56 mike Exp $" * * "cupsaddsmb" command for the Common UNIX Printing System (CUPS). * @@ -282,5 +282,5 @@ export_dest(const char *dest) /* I - Destination to export */ /* - * End of "$Id: cupsaddsmb.c,v 1.3 2001/12/18 21:08:21 mike Exp $". + * End of "$Id: cupsaddsmb.c,v 1.3.2.1 2001/12/26 16:52:56 mike Exp $". */ diff --git a/systemv/lp.c b/systemv/lp.c index 902c0c1254..b1b7dedde4 100644 --- a/systemv/lp.c +++ b/systemv/lp.c @@ -1,5 +1,5 @@ /* - * "$Id: lp.c,v 1.29.2.1 2001/05/13 18:38:40 mike Exp $" + * "$Id: lp.c,v 1.29.2.2 2001/12/26 16:52:56 mike Exp $" * * "lp" command for the Common UNIX Printing System (CUPS). * @@ -375,8 +375,9 @@ main(int argc, /* I - Number of command-line arguments */ if (strcmp(val, "hold") == 0) num_options = cupsAddOption("job-hold-until", "indefinite", num_options, &options); - if (strcmp(val, "resume") == 0) - num_options = cupsAddOption("job-hold-until", "none", + else if (strcmp(val, "resume") == 0 || + strcmp(val, "release") == 0) + num_options = cupsAddOption("job-hold-until", "no-hold", num_options, &options); else if (strcmp(val, "immediate") == 0) num_options = cupsAddOption("job-priority", "100", @@ -529,7 +530,7 @@ main(int argc, /* I - Number of command-line arguments */ return (1); } - while ((i = fread(buffer, 1, sizeof(buffer), stdin)) > 0) + while ((i = read(0, buffer, sizeof(buffer))) > 0) write(temp, buffer, i); i = lseek(temp, 0, SEEK_CUR); @@ -556,8 +557,7 @@ main(int argc, /* I - Number of command-line arguments */ return (1); } else if (!silent) - fprintf(stderr, "request id is %s-%d (%d file(s))\n", printer, job_id, - num_files); + printf("request id is %s-%d (%d file(s))\n", printer, job_id, num_files); return (0); } @@ -650,5 +650,5 @@ sighandler(int s) /* I - Signal number */ /* - * End of "$Id: lp.c,v 1.29.2.1 2001/05/13 18:38:40 mike Exp $". + * End of "$Id: lp.c,v 1.29.2.2 2001/12/26 16:52:56 mike Exp $". */ diff --git a/systemv/lpadmin.c b/systemv/lpadmin.c index 11ae41aed5..6432ce657d 100644 --- a/systemv/lpadmin.c +++ b/systemv/lpadmin.c @@ -1,5 +1,5 @@ /* - * "$Id: lpadmin.c,v 1.22.2.1 2001/05/13 18:38:41 mike Exp $" + * "$Id: lpadmin.c,v 1.22.2.2 2001/12/26 16:52:57 mike Exp $" * * "lpadmin" command for the Common UNIX Printing System (CUPS). * @@ -33,6 +33,7 @@ * set_printer_file() - Set the interface script or PPD file. * set_printer_info() - Set the printer description string. * set_printer_location() - Set the printer location string. + * set_printer_model() - Set the driver model file. * set_printer_options() - Set the printer options. * validate_name() - Make sure the printer name only contains * letters, numbers, and the underscore... @@ -68,6 +69,7 @@ static void set_printer_device(http_t *, char *, char *); static void set_printer_file(http_t *, char *, char *); static void set_printer_info(http_t *, char *, char *); static void set_printer_location(http_t *, char *, char *); +static void set_printer_model(http_t *, char *, char *); static void set_printer_options(http_t *, char *, int, cups_option_t *); static int validate_name(const char *); @@ -99,9 +101,6 @@ main(int argc, /* I - Number of command-line arguments */ options = NULL; encryption = cupsEncryption(); - if ((datadir = getenv("CUPS_DATADIR")) == NULL) - datadir = CUPS_DATADIR; - for (i = 1; i < argc; i ++) if (argv[i][0] == '-') switch (argv[i][1]) @@ -298,8 +297,7 @@ main(int argc, /* I - Number of command-line arguments */ } if (argv[i][2]) - snprintf(filename, sizeof(filename), "%s/model/%s", datadir, - argv[i] + 2); + set_printer_model(http, printer, argv[i] + 2); else { i ++; @@ -310,11 +308,8 @@ main(int argc, /* I - Number of command-line arguments */ return (1); } - snprintf(filename, sizeof(filename), "%s/model/%s", datadir, - argv[i]); + set_printer_model(http, printer, argv[i]); } - - set_printer_file(http, printer, filename); break; case 'o' : /* Set option */ @@ -1589,6 +1584,70 @@ set_printer_location(http_t *http, /* I - Server connection */ } +/* + * 'set_printer_model()' - Set the driver model file. + */ + +static void +set_printer_model(http_t *http, /* I - Server connection */ + char *printer, /* I - Printer */ + char *model) /* I - Driver model file */ +{ + ipp_t *request, /* IPP Request */ + *response; /* IPP Response */ + cups_lang_t *language; /* Default language */ + char uri[HTTP_MAX_URI]; /* URI for printer/class */ + + + /* + * Build a CUPS_ADD_PRINTER request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + * ppd-name + */ + + snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer); + + request = ippNew(); + + request->request.op.operation_id = CUPS_ADD_PRINTER; + request->request.op.request_id = 1; + + language = cupsLangDefault(); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, + "printer-uri", NULL, uri); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "ppd-name", NULL, model); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/admin/")) == NULL) + fprintf(stderr, "lpadmin: add-printer failed: %s\n", + ippErrorString(cupsLastError())); + else + { + if (response->request.status.status_code > IPP_OK_CONFLICT) + fprintf(stderr, "lpadmin: add-printer failed: %s\n", + ippErrorString(response->request.status.status_code)); + + ippDelete(response); + } +} + + /* * 'set_printer_options()' - Set the printer options. */ @@ -1770,5 +1829,5 @@ validate_name(const char *name) /* I - Name to check */ /* - * End of "$Id: lpadmin.c,v 1.22.2.1 2001/05/13 18:38:41 mike Exp $". + * End of "$Id: lpadmin.c,v 1.22.2.2 2001/12/26 16:52:57 mike Exp $". */ diff --git a/templates/Makefile b/templates/Makefile index 46ea7f6017..d439eda9ba 100644 --- a/templates/Makefile +++ b/templates/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.6 2001/01/22 15:04:03 mike Exp $" +# "$Id: Makefile,v 1.6.2.1 2001/12/26 16:52:57 mike Exp $" # # Template makefile for the Common UNIX Printing System (CUPS). # @@ -51,6 +51,7 @@ FILES = add-class.tmpl \ job-cancel.tmpl \ job-hold.tmpl \ job-release.tmpl \ + job-restart.tmpl \ modify-class.tmpl \ modify-printer.tmpl \ option-boolean.tmpl \ @@ -91,12 +92,12 @@ clean: # install: - -$(MKDIR) $(DATADIR)/templates - $(CHMOD) ugo+rx $(DATADIR) - $(CHMOD) ugo+rx $(DATADIR)/templates - $(INSTALL_DATA) $(FILES) $(DATADIR)/templates + $(INSTALL_DIR) $(DATADIR)/templates + for file in $(FILES); do \ + $(INSTALL_DATA) $$file $(DATADIR)/templates; \ + done # -# End of "$Id: Makefile,v 1.6 2001/01/22 15:04:03 mike Exp $". +# End of "$Id: Makefile,v 1.6.2.1 2001/12/26 16:52:57 mike Exp $". # diff --git a/templates/choose-uri.tmpl b/templates/choose-uri.tmpl index a432d99ca6..63bee8529b 100644 --- a/templates/choose-uri.tmpl +++ b/templates/choose-uri.tmpl @@ -22,14 +22,14 @@ diff --git a/templates/jobs.tmpl b/templates/jobs.tmpl index a32677b882..d168cc1ae8 100644 --- a/templates/jobs.tmpl +++ b/templates/jobs.tmpl @@ -2,27 +2,27 @@
              Table 1: Directory structure changes + from CUPS 1.0.x to 1.1.x.
              DescriptionCUPS 1.0.xCUPS 1.1.x
              Backends/var/cups/backend/usr/lib/cups/backend
              Examples: -
                -
                file:/path/to/filename.prn
                -
                http://hostname:631/ipp/port1
                -
                ipp://hostname/ipp/port1
                -
                lpd://hostname/queue
                -
                socket://hostname
                -
                socket://hostname:9100
                -
              +
              +    file:/path/to/filename.prn
              +    http://hostname:631/ipp/port1
              +    ipp://hostname/ipp/port1
              +    lpd://hostname/queue
              +    socket://hostname
              +    socket://hostname:9100
              +	
              - - - - - - + + + + + + {[job_id] - + - - - - - + + + + + +   }
              IDNameUserSizeStateControlID Name User Size State Control 
              {job_id}{?job_name=?Unknown:{job_name}}{job_originating_user_name}{job_k_octets}k{job_state=3?pending:{job_state=4?held: - {job_state=5?processing:{job_state=6?stopped: - {job_state=7?cancelled:{job_state=8?aborted:completed}}}}}}{job_printer_name}-{job_id} {?job_name=?Unknown:{job_name}} {job_originating_user_name} {job_k_octets}k {job_state=3?pending since
              {time_at_creation}:{job_state=4?held since
              {time_at_creation}: + {job_state=5?processing since
              {time_at_processing}:{job_state=6?stopped at
              {time_at_completed}: + {job_state=7?cancelled at
              {time_at_completed}:{job_state=8?aborted:completed at
              {time_at_completed}}}}}}} 
              {job_state>5? {job_k_octets>0? @@ -40,8 +40,7 @@ Cancel Job } - -
              diff --git a/templates/option-header.tmpl b/templates/option-header.tmpl index a23b1d2c1b..23a904178d 100644 --- a/templates/option-header.tmpl +++ b/templates/option-header.tmpl @@ -1,6 +1,6 @@ - {group} + {group} diff --git a/templates/printer-accept.tmpl b/templates/printer-accept.tmpl index 23d8c2f3cd..3a269eb0df 100644 --- a/templates/printer-accept.tmpl +++ b/templates/printer-accept.tmpl @@ -1 +1 @@ -

              Printer {printer_name} is now accepting jobs. +

              Printer {printer_name} is now accepting jobs. diff --git a/templates/printer-reject.tmpl b/templates/printer-reject.tmpl index 6cf330c4c5..e73d87380d 100644 --- a/templates/printer-reject.tmpl +++ b/templates/printer-reject.tmpl @@ -1 +1 @@ -

              Printer {printer_name} is no longer accepting jobs. +

              Printer {printer_name} is no longer accepting jobs. diff --git a/templates/trailer.tmpl b/templates/trailer.tmpl index dc01c3771e..a584af7233 100644 --- a/templates/trailer.tmpl +++ b/templates/trailer.tmpl @@ -1,7 +1,7 @@


              -

              The Common UNIX Printing System, CUPS, and the CUPS logo are the -trademark property of Easy Software -Products. CUPS is copyright 1997-2001 by Easy Software Products, -All Rights Reserved. +

              Copyright 1993-2001 Easy Software Products, All Rights Reserved. +The Common UNIX Printing System, CUPS, and the CUPS logo +are the trademark property of Easy Software Products. +All other trademarks are the property of their respective owners. diff --git a/test/Makefile b/test/Makefile index 97e41ebe5d..50b7de9a90 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.2 2001/01/22 15:04:04 mike Exp $" +# "$Id: Makefile,v 1.2.2.1 2001/12/26 16:52:58 mike Exp $" # # IPP test makefile for the Common UNIX Printing System (CUPS). # @@ -59,5 +59,14 @@ ipptest.o: ../cups/cups.h ../Makedefs # -# End of "$Id: Makefile,v 1.2 2001/01/22 15:04:04 mike Exp $". +# purify target for doing tests on the CUPS API... +# + +purify: ipptest.o ../cups/$(LIBCUPS) + echo Linking $@... + purify $(CC) $(LDFLAGS) -o ipptest.pure ipptest.o $(LIBS) + + +# +# End of "$Id: Makefile,v 1.2.2.1 2001/12/26 16:52:58 mike Exp $". # diff --git a/visualc/config.h b/visualc/config.h index c8fee625fd..3d9db35126 100644 --- a/visualc/config.h +++ b/visualc/config.h @@ -1,5 +1,5 @@ /* - * "$Id: config.h,v 1.5 2001/03/02 22:34:21 andy Exp $" + * "$Id: config.h,v 1.5.2.1 2001/12/26 16:52:58 mike Exp $" * * Configuration file for the Common UNIX Printing System (CUPS). * @@ -28,7 +28,7 @@ * Version of software... */ -#define CUPS_SVERSION "CUPS v1.1.6" +#define CUPS_SVERSION "CUPS v1.2.0" /* * Where are files stored? @@ -143,5 +143,5 @@ /* - * End of "$Id: config.h,v 1.5 2001/03/02 22:34:21 andy Exp $". + * End of "$Id: config.h,v 1.5.2.1 2001/12/26 16:52:58 mike Exp $". */