diff --git a/.idea/CUPS-for-Android.iml b/.idea/CUPS-for-Android.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/CUPS-for-Android.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..15a15b2 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..fe097cd --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Android.mk b/Android.mk index 112b924..ed00e26 100644 --- a/Android.mk +++ b/Android.mk @@ -21,7 +21,6 @@ LOCAL_SRC_FILES:= \ cups/array.c \ cups/auth.c \ cups/backchannel.c \ - cups/backend.c \ cups/debug.c \ cups/dest.c \ cups/dest-job.c \ @@ -31,7 +30,6 @@ LOCAL_SRC_FILES:= \ cups/encode.c \ cups/file.c \ cups/getdevices.c \ - cups/getifaddrs.c \ cups/getputfile.c \ cups/globals.c \ cups/hash.c \ @@ -47,14 +45,10 @@ LOCAL_SRC_FILES:= \ cups/md5passwd.c \ cups/notify.c \ cups/options.c \ - cups/ppd.c \ - cups/ppd-attr.c \ - cups/ppd-cache.c \ - cups/ppd-conflicts.c \ - cups/ppd-custom.c \ - cups/ppd-mark.c \ - cups/ppd-page.c \ cups/pwg-media.c \ + cups/raster-error.c \ + cups/raster-stream.c \ + cups/raster-stubs.c \ cups/request.c \ cups/sidechannel.c \ cups/snmp.c \ @@ -66,8 +60,6 @@ LOCAL_SRC_FILES:= \ cups/transcode.c \ cups/usersys.c \ cups/util.c \ - filter/error.c \ - filter/raster.c \ mopria.c \ disabled_src_files:= \ @@ -78,7 +70,7 @@ LOCAL_C_INCLUDES := \ LOCAL_CFLAGS := -D_PPD_DEPRECATED= -Wno-implicit-function-declaration -Wno-empty-body LOCAL_MODULE := lib$(PRIV_LIB_NAME)cups LOCAL_MODULE_TAGS := optional -LOCAL_LDLIBS += -lz -llog -Wl,--no-warn-shared-textrel +LOCAL_LDLIBS += -lz -llog LOCAL_STATIC_LIBRARIES := libgnutls LOCAL_DISABLE_FATAL_LINKER_WARNINGS := true include $(BUILD_SHARED_LIBRARY) \ No newline at end of file diff --git a/CHANGES-1.0.txt b/CHANGES-1.0.txt deleted file mode 100644 index 296d89f..0000000 --- a/CHANGES-1.0.txt +++ /dev/null @@ -1,217 +0,0 @@ -CHANGES-1.0.txt ---------------- - -CHANGES IN CUPS v1.0.5 - - - The HP-GL/2 filter did not correctly set the pen color - for pens other than #1. - - The scheduler would only accept 26 simultaneous jobs - under some OS releases (mkstemp() limitation.) It now - handles up to 2^32 simultaneous jobs. - - The PostScript filter loaded the printer's PPD file - twice. - - The PAM authentication code now uses pam_strerror() to - provide a textual error message in the error_log file. - - The scheduler now copies PPD and interface script - files instead of moving them; this fixes installations - with a separate requests directory. - - The PostScript RIP did not generate correct 6-color - output. - - Several filters were marking PPD options twice when - they didn't need to. - - The scheduler did not save the printer or class state - after an accept-jobs or reject-jobs operation. - - The cupsGetDefault() function now ignores the PRINTER - environment variable if it is set to "lp". - - New ippErrorString() function to get textual error - messages. - - Better error reporting in the System V commands. - - The lpadmin and lpstat commands always tried to - connect to the default server. - - The text filter didn't load the charset files from the - correct location. - - Wasn't sending a WWW-Authenticate: field to HTTP - clients when authentication was required. - - httpSeparate() didn't always set the default port - number for known methods. - - The HP-GL/2 filter now looks for "PSwidth,length" - instead of (the correct) "PSlength,width" as - documented by HP. It appears that many major CAD - applications are broken and this change allows the - auto-rotation to work with them. - - The IPP "printer-resolution" option was not being - translated. - - The charset files did not include the Microsoft - "standard" characters from 128 to 159 (unused by the - ISO-8859-x charsets) - - The scheduler was chunking the Content-Type field from - CGI programs; this problem was most noticeable with - Microsoft Internet Explorer 5. - - By popular demand, the printers, jobs, and classes - CGIs no longer force a reload of the page every 10/30 - seconds. - - The scheduler incorrectly required that the IPP client - provide a document-format attribute for the - validate-job operation. - - Clients that sent bad IPP requests without the - required attributes-natural-language and - attributes-charset attributes would crash the - scheduler. - - -CHANGES IN CUPS v1.0.4 - - - Documentation updates. - - Jobs would get stuck in the queue and wouldn't print - until you enabled the queue. - - The lp and lpr commands now catch SIGHUP and SIGINTR. - - The lp and lpr commands now use sigaction or sigset - when available. - - CUPS library updates for WIN32/OS-2 - - -CHANGES IN CUPS v1.0.3 - - - Documentation updates. - - The lpq man page was missing. - - The configure script was not properly detecting the - image libraries. - - The top-level makefile was calling "make" instead of - "$(MAKE)". - - PostScript filter fixes for number-up, OutputOrder, - and %Trailer. - - The imagetops filter didn't end the base-85 encoding - properly if the image data was not a multiple of 4 - bytes in length. - - The imagetoraster filter didn't generate good banded - RGB or CMY data (was dividing the line width by 4 - instead of 3...) - - The imagetoraster filter now records the bounding - box of the image on the page. - - The CUPS image library cache code wasn't working as - designed; images larger than the maximum RIP cache - would eventually thrash using the same cache tile. - - The CUPS image library TIFF loading code didn't - handle unknown resolution units properly; the fixed - code uses a default resolution of 128 PPI. - - cupsGetClasses() and cupsGetPrinters() did not free - existing strings if they ran out of memory. - - The scheduler logs incorrectly contained 3 digits for - the timezone offset instead of 4. - - The scheduler now does a lookup for the default user - and group ID; the previous hardcoded values caused - problems with the LPD backend. - - The cancel-job operation now allows any user in the - system group to cancel any job. - - The cancel-job operation stopped the print queue if - the job was being printed. - - Now only stop printers if the backend fails. If the - filter fails then the failure is noted in the - error_log and printing continues with the next file in - the queue. - - Now log whether a filter fails because of a signal - or because it returned a non-zero exit status. - - The root user now always passes the system group test. - - Printers with an interface script and remote printers - and classes didn't have a printer-make-and-model - attribute. - - Added logging of lost/timed-out remote printers. - - The HP-GL/2 filter was scaling the pen width twice. - - Updated the HP-GL/2 filter to use a single SP (Set - Pen) procedure. This makes the output smaller and is - more appropriate since the filter keeps track of the - pen states already. - - The scheduler didn't handle passwords with spaces. - - The IPP backend now does multiple copies and retries - if the destination server requires it (e.g. HP - JetDirect.) - - The disable command didn't implement the "-c" option - (cancel all jobs.) - - Changed the CMYK generation function for the image file - and PostScript RIPs. - - The lp command didn't support the "-h" option as - documented. - - The AppSocket, IPP, and LPD backends now retry on all - network errors. This should prevent stopped queues - caused by a printer being disconnected from the - network or powered off. - - The scheduler now restarts a job if the corresponding - printer is modified. - - The image RIPs now rotate the image if needed to fit - on the page. - - -CHANGES IN CUPS v1.0.2 - - - The HP-GL/2 filter didn't always scale the output - correctly. - - The HP-GL/2 filter now supports changing the page size - automatically when the "fitplot" option is not used. - - The cancel-job operation was expecting a resource name - of the form "/job/#" instead of "/jobs/#"; this - prevented the cancel and lprm commands from working. - - The backends didn't log pages when files were printed - using the "-oraw" option. - - The authorization code did not work with the Slackware - long shadow password package because its crypt() can - return NULL. - - The chunking code didn't work for reading the response - of a POST request. - - cupsGetPPD() now does authentication as needed. - - The N-up code in the PostScript filter didn't work - with some printers (grestoreall would restore the - default blank page and device settings). - - The N-up code in the PostScript filter didn't scale - the pages to fit within the imageable area of the - page. - - Wasn't doing an fchown() on the request files. This - caused problems when the default root account group - and CUPS group were not the same. - - -CHANGES IN CUPS v1.0.1 - - - Documentation updates. - - Fixed a bunch of possible buffer-overflow conditions. - - The scheduler now supports authentication using PAM. - - Updated the Italian message file. - - httpEncode64() didn't add an extra "=" if there was - only one byte in the last three-byte group. - - Now drop any trailing character set from the locale - string (e.g. "en_US.ISO_8859-1" becomes "en_US") - - Fixed "timezone" vs "tm_gmtoff" usage for BSD-based - operating systems. - - Updated IPP security so that "get" operations can be - done from any resource name; this allows the CGIs to - work with printer authentication enabled so long as - authentication isn't turned on for the whole "site". - - The IPP code didn't properly handle the "unsupported" - group; this caused problems with the HP JetDirect since - it doesn't seem to support the "copies" attribute. - - The HTTP chunking code was missing a CR LF pair at the - end of a 0-length chunk. - - The httpSeparate() function didn't handle embedded - usernames and passwords in the URI properly. - - Doing "lpadmin -p printer -E" didn't restart printing - if there were pending jobs. - - The cancel-job operation now requires either a - requesting-user-name attribute or an authenticated - username. - - The add-printer code did not report errors if the - interface script or PPD file could not be renamed. - - Request files are now created without world read - permissions. - - Added a cupsLastError() function to the CUPS API to - retrieve the IPP error code from the last request. - - Options are now case-insensitive. - - The lpq command now provides 10 characters for the - username instead of the original (Berkeley standard) - 7. - - The cancel command needed a local CUPS server to work - (or the appropriate ServerName in cupsd.conf) - - The cancel and lprm commands didn't report the IPP - error if the job could not be cancelled. - - The lp and lpr commands didn't intercept SIGTERM to - remove temporary files when printing from stdin. - - The lp and lpr commands didn't report the IPP error if - the job could not be printed. diff --git a/CHANGES-1.1.txt b/CHANGES-1.1.txt deleted file mode 100644 index c641e79..0000000 --- a/CHANGES-1.1.txt +++ /dev/null @@ -1,3462 +0,0 @@ -CHANGES-1.1.txt ---------------- - -CHANGES IN CUPS V1.1.23 - - - Updated the Spanish man pages (STR #1041) - - The lpstat man page contained a typo (STR #1040) - - The scheduler's is_path_absolute() code could cause a - DoS (STR #1042) - - The scheduler's device loading code used the wrong - size limits for the make/model and info parameters - (STR #1035) - - The PNG loading code did not use a "long unsigned - integer" format specifier for the width and height - (STR #1032) - - The web interface only showed the first 4 or 8 - characters of "{variable-name}" for undefined template - variables (STR #1031) - - The hpgltops filter did not handle a common PCL - command to enter HP-GL/2 mode (STR #1037) - - -CHANGES IN CUPS V1.1.23rc1 - - - The lpr man page did not document the "-U" option (STR - #998) - - The scheduler no longer sends the page-set option when - printing banner pages (STR #995) - - Fixed a debug message in the imagetops filter (STR - #1012) - - The lprm man page listed the "-" option in the wrong - order (STR #911) - - The hpgltops filter contained two buffer overflows - that could potentially allow remote access to the "lp" - account (STR #1024) - - The lppasswd command did not protect against file - descriptor or ulimit attacks (STR #1023) - - The "lpc status" command used the wrong resource path - when querying the list of printers and jobs, causing - unnecessary authentication requests (STR #1018) - - The httpWait() function did not handle signal - interruptions (STR #1020) - - The USB backend used the wrong size status variable - when checking the printer status (STR #1017) - - The scheduler did not delete classes from other - classes or implicit classes, which could cause a crash - (STR #1015) - - The IPP backend now logs the remote print job ID at - log level NOTICE instead of INFO (so it shows up in - the error_log file...) - - -CHANGES IN CUPS V1.1.22 - - - The lpstat man page incorrectly listed the "-s" option - as using the equivalent of the "-p" option to list the - printers; it uses the "-v" option to list the printers - (STR #986) - - Now allow 0-length reads in the CUPS file API (STR - #985) - - cupsDoFileRequest() now sets cupsLastError() to - IPP_ERROR on network errors (STR #953) - - The pdftops filter didn't scale small pages up to the - output page size when the fitplot option was used (STR - #984) - - Fixed the ipptest program usage message (STR #959) - - Added Spanish man pages (STR #963) - - Fixed the order of comparisons in the client.conf - reading code (STR #971) - - cupsLangGet() incorrectly set the current locale (STR - #970) - - -CHANGES IN CUPS V1.1.22rc2 - - - The pdftops filter didn't check the range of all - integer attributes (STR #972) - - Documentation corrections (STR #944, STR #946) - - Also sanitize device URI in argv[0] (STR #933) - - cupsRasterReadHeader() didn't swap bytes for the - numeric fields properly (STR #930) - - -CHANGES IN CUPS V1.1.22rc1 - - - Now sanitize the device URI that is reported in the - error_log file (STR #920) - - Fixed some memory and file descriptor leaks in the job - dispatch code (STR #921) - - Deleting a printer could cause a crash with browsing - enabled (STR #865, STR #881, STR #928) - - Browsing would turn off if the scheduler got an EAGAIN - error (STR #924) - - The mime.types file didn't recognize PostScript as a - PJL language name (STR #925) - - -CHANGES IN CUPS V1.1.21 - - - The scheduler did not separate Digest authentication - parameters with commas (STR #882) - - Fixed some problems with image printing to custom page - sizes (STR #891) - - Removed the remaining scheduler code that did not use - the "close-on-exec" file descriptor flag to speed up - program invocations (STR #890) - - The "lpr -r" command removed the print file even if it - was not printed. It now only removes the file if the - job is successfully created (STR #886) - - Revamped the custom page size orientation fix (STR - #127) - - The lp, lpq, lpr, and lpstat commands now report when - an environment variable is pointing to a non-existent - printer instead of just saying "no default - destination" (STR #879) - - Queue names with 2 periods (e.g. "printer..2") were - not supported (STR #866) - - -CHANGES IN CUPS V1.1.21rc2 - - - Fixed a denial-of-service bug in the CUPS browse - protocol support (STR #863) - - The scheduler used a select() timeout of INT_MAX - seconds when there was nothing to do, which doesn't - work on IRIX (STR #864) - - Updated the cupsaddsmb program to use the new Windows - 2000 PostScript drivers instead of the Windows NT - printer drivers (STR #390) - - The gziptoany filter did not produce copies for raw - print jobs (STR #808) - - The cupsLangGet() function now uses nl_langinfo(), - when available, to get the current encoding (STR #856) - - Added a ReloadTimeout directive to control how long - the scheduler waits for jobs to complete before - restarting the scheduler (STR #861) - - Added a note to the default cupsd.conf file which - mentions that you must allow connections from - localhost for the command-line and web interfaces to - work (STR #850) - - The IPP backend incorrectly used the local port when - communicating with a remote server; this caused - problems with some custom configurations (STR #852) - - The cups-lpd mini-daemon wasn't using the right - default banner option (STR #851) - - Updated the new httpDecode64_2() and httpEncode64_2() - functions to handle arbitrary binary data, not just - text (STR #860) - - String options with quotes in their values were not - quoted properly by the scheduler (STR #839) - - Configure script changes for GNU/Hurd (STR #838) - - The lppasswd program was not installed properly by GNU - install when the installer was not root (STR #836) - - Updated the cups-lpd man page (STR #843) - - Fixed a typo in the cupsd man page (STR #833) - - The USB backend now defaults to using the newer - /dev/usb/lpN filenames; this helps on systems which - use the devfs filesystem type on Linux (STR #818) - - The config.h file did not define the HAVE_USERSEC_H - constant when the configure script detected the - usersec.h header file. This caused authentication - errors on AIX (STR #832) - - The lp and lpr commands now report the temporary - filename and error if they are unable to create a - temporary file (STR #812) - - Added ServerTokens directive to control the Server - header in HTTP responses (STR #792) - - Added new httpDecode64_2(), httpEncode64_2(), and - httpSeparate2() functions which offer buffer size - arguments (STR #797) - - The cupsGetFile() and cupsPutFile() code did not - support CDSA or GNUTLS (STR #794) - - The httpSeparate() function did not decode all - character escapes (STR #795) - - The cupstestppd program now checks for invalid Duplex - option choices and fails PPD files that use - non-standard values (STR #791) - - Updated the printer name error message to indicate - that spaces are not allowed (STR #675) - - The scheduler didn't handle HTTP GET form data - properly (STR #744) - - The pstops filter now makes sure that the prolog code - is sent before the setup code (STR #776) - - The pstops filter now handles print files that - incorrectly start @PJL commands without a language - escape (STR #734) - - Miscellaneous build fixes for NetBSD (STR #788) - - Added support for quoted system group names (STR #784) - - Added "version" option to IPP backend to workaround - serious bug in Linksys's IPP implementation (STR #767) - - Added Spanish translation of web interface (STR #772, - STR #802) - - The LPD backend now uses geteuid() instead of getuid() - when it is available (STR #752) - - The IPP backend did not report the printer state if - the wait option was set to "no" (STR #761) - - The printer state was not updated for "STATE: foo,bar" - messages (STR #745) - - Added new CUPS API convenience functions which accept - a HTTP connection to eliminate extra username/password - prompts. This resolves a previous authentication - caching issue (STR #729, STR #743) - - The scheduler did not correctly throttle the browse - broadcasts, resulting in missing printers on client - machines (STR #754) - - The scheduler did not pass the correct CUPS_ENCRYPTION - setting to CGI programs which caused problems on - systems which used non-standard encryption settings - (STR #773) - - The lpq command showed 11st, 12nd, and 13rd instead of - 11th, 12th, and 13th for the rank (STR #769) - - "make install" didn't work on some platforms due to an - error in the man page makefiles (STR #775) - - Changed some calls to snprintf() in the scheduler to - SetStringf() (STR #740) - - -CHANGES IN CUPS V1.1.21rc1 - - - Fixed some "type-punned" warnings produced by GCC when - -fstrict-aliasing is specified (STR #679) - - The PDF filter incorrectly calculated the bounding box - of a page (STR #682) - - The IPP backend did not use SSL when printing over a - port other than 443 (STR #730) - - The scheduler could crash when processing a Limit or - LimitExcept directive (STR #728) - - The lpq, lpr, and lp commands did not differentiate - between the server being unresponsive and the lack of - a default printer (STR #728) - - The PAM checks in the configure script did not stop - after the first match (STR #728) - - The cups-config man page was incorrectly placed in - section 3 (STR #728) - - The cupstestppd utility did not show a warning message - when a PPD file indicated BCP protocol support with - PJL (STR #720) - - The scheduler did not return the correct exit code - when startup failed (STR #718) - - The cupsRasterReadPixels() function checked for - EAGAIN, which caused problems on FreeBSD (STR #723) - - The cupsGetDests() function did not use the current - encryption setting (STR #653) - - The scheduler did not properly parse name-based - BrowseRelay directives in the cupsd.conf file (STR - #711) - - The IPP backend now supports the following options in - the device URI: encryption, waitjob, and waitprinter - (STR #699) - - The parallel, serial, socket, and USB backends did not - return a non-zero exit status when a job failed to - print in the middle of sending it (STR #715) - - Location directives in the cupsd.conf file were - case-sensitive for printer and class names, so - queue-specific access control was not reliable (STR - #700) - - cupsDoFileRequest() did not handle HTTP continue - status messages in all cases, causing sporatic - problems with IPP printers from some vendors (STR - #716) - - The rastertodymo driver now supports the Zebra ZPL - language (STR #713) - - The test suite no longer generates a printcap file, - which caused problems when testing as the root user - (STR #693) - - The scheduler now updates the accepting state of an - implicit class based upon the accepting state of its - member printers (STR #697) - - The pstops filter didn't properly skip leading PJL - commands (STR #664) - - The reinterpret_cast keyword was not highlighted when - printing C/C++ source files in prettyprint mode (STR - #694) - - Fixed a segfault problem with some of the client - programs (STR #668) - - When using RunAsUser, the scheduler did not correctly - set the ownership of the log files, preventing log - file rotation (STR #686) - - The image filters did not correctly load 1-bit PNG - files (STR #687) - - The pdftops filter did not show all annotation objects - in a PDF file (STR #674) - - The pdftops filter did not print the contents of - textual form elements, making it impossible to print a - filled-in form (STR #663) - - Integrated the MacOS X/Darwin USB backend into the - CUPS baseline (STR #661) - - The USB backend incorrectly reported "media tray - empty" (STR #660) - - The scheduler did not use a case-insensitive - comparison when checking for group membership, which - caused problems with Win9x clients printing via SAMBA - (STR #647) - - The scheduler did not report the addresses associated - with certain network errors, making troubleshooting - difficult (STR #648, #649) - - The cupstestppd program did not allow a default choice - of "Unknown" as required by the PPD spec (STR #651) - - The select() buffers are now allocated to be at least - as large as sizeof(fd_set) (STR #639) - - The LPD backend now supports overriding the print job - username via the device URI (STR #631) - - The scheduler did not handle an unknown MIME type when - checking for a CGI script (STR #603) - - Added a timeout optimization to the scheduler's main - loop to allow CUPS to sleep more of the time (STR - #629) - - The USB backend now retries printing to devices of the - form "usb://make/model" if any USB port shows up as - "busy" (STR #617) - - The httpGetHostByName() function did not range check - IP address values (STR #608) - - The httpUpdate() function could return HTTP_ERROR - instead of the HTTP status if the server closed the - connection before the client received the whole - response (STR #611) - - The LPD mini-daemon did not allow the administrator to - force banner pages on (STR #605) - - Added PAM support for Darwin/MacOS X (STR #550) - - The web interface now provides a "Set As Default" - button to set the default printer or class on a server - (STR #577) - - The HTTP authentication cache was broken (STR #517) - - The cupstestppd utility now fails PPD files that have - a DefaultOption keyword for a non-existance option - name (STR #476) - - Optimized the scanning of new PPD files on scheduler - startup (STR #424) - - The EPM list file did not include the bin, lib, or - sbin directories (STR #598) - - The web interface did not redirect administration - tasks to the primary server for a class or printer - (STR #491, #652) - - The cups-lpd mini-daemon did not reject print jobs to - queues that were rejecting new print jobs (STR #515) - - Some calls to the ctype functions did not account for - platforms that use a signed char type by default (STR - #518) - - The scheduler could use excess amounts of CPU if a CGI - program was sending data faster than the client could - take it (STR #595) - - Updated the Ghostscript 8.x integration stuff (STR - #484) - - The lpd backend used a source port of 732 by default, - which is outside of the range defined by RFC 1179; - also added a new (default) "reserve=any" option for - any priviledged port from 1 to 1023 (STR #474) - - The scheduler did not check for a valid Listen/Port - configuration (STR #499) - - The cupsPrintFiles() function did not always set the - last IPP error message (STR #538) - - The pstops filter did not write the PostScript header - line if the file began with a PJL escape sequence (STR - #574) - - The printer-is-accepting-jobs status of remote - printers was not sent to clients via browsing or - polling (STR #571) - - Browse packets did not indicate whether a printer - was accepting or rejecting jobs. - - The web interface did not show the printer state - history information (STR #592) - - The rastertoepson filter would crash under certain - cirsumstances (STR #583) - - The USB backend did not handle serial numbers using - the (incorrect) SN keyword and did not terminate the - make and model name strings properly (STR #471, STR - #588) - - The USB backend did not build on Solaris x86 (STR - #585) - - The cupsDoAuthentication() function did not use the - method name for Digest authentication (STR #584) - - The scheduler could crash if a print job could not be - printed and the PreserveJobHistory option was turned - off (STR #535) - - cups-lpd now logs the temporary filenames that could - not be opened in order to make troubleshooting easier - (STR #565) - - cupsGetJobs() now returns -1 on error (STR #569) - - Added localization for Belarusian (STR #575) - - The LPD backend used the full length of the hostname - when creating the data and control filenames, which - causes problems with older systems that can't handle - long filenames (STR #560) - - The scheduler did not refresh the common printer data - after a fast reload; this prevented banner and other - information from being updated (STR #562) - - The scheduler did not send common or history data to - the client when processing a CUPS-Get-Default request - (STR #559) - - The httpFlush() function did not always flush the - remaining response data in requests (STR #558) - - The scheduler could complete a job before it collected - the exit status from all filters and the backend (STR - #448) - - The PPD conformance tests did not catch group - translation strings that exceeded the maximum allowed - size (STR #454) - - Updated the client code in the scheduler to close the - client connection on errors rather than shutting down - the receive end of the socket; this caused resource - problems on some systems (STR #434) - - cups-polld didn't compile on Tru64 5.1B (STR #436) - - "lpc stat" crashed if the device URI was empty (STR - #548) - - The scheduler did not compile without zlib (STR #433) - - std:floor() cast needed on IRIX 6.5 with SGI C++ - compiler (STR #497) - - cupsRasterReadPixels() and cupsRasterWritePixels() did - not handle EAGAIN and EINTR properly (STR #473) - - RequiresPageRegion should not be consulted for Manual - Feed (STR #514) - - International characters were not substituted in - banner files properly (STR #468) - - Updated pdftops to Xpdf 2.03 code to fix printing bugs - (STR #470) - - The Digest authentication code did not include the - (required) "uri" attribute in the Authorization - response, preventing interoperation with Apache - (STR #408) - - The web interface could lockup when displaying certain - URLs (STR #459) - - The PostScript filters now convert underscores ("_") - to spaces for custom classification names (STR #555) - - -CHANGES IN CUPS V1.1.20 - - - The pstops filter didn't properly handle collated, - duplexed copies of documents with an odd number of - pages on printers that did not do their own collated - copies (STR #389) - - Tru64 doesn't define a prototype for hstrerror() (STR - #430) - - Updated the pdftops filter to use the annotation flags - instead of the subtype to determine whether to print - an annotation (STR #425) - - The French web interface localization did not use - absolute paths for the navigation bar (STR #428) - - The CUPS test suite did not undefine the PRINTER and - LPDEST environment variables. This could lead to bogus - test results (STR #380) - - The cupsLangDefault() function now works if you don't - have the base OS localization installed (STR #418) - - The pdftops filter no longer needs to create temporary - files with tmpnam (STR #406) - - The HTTP code did not use a case-insensitive - comparison when checking for the Basic authentication - method (STR #407) - - The httpEncode() function always added a trailing "=" - character, which is not required by the Base64 - encoding specification (STR #407) - - The signal handlers did not need to call sigset(); - this caused a recursion problem on some versions of - IRIX (STR #422) - - Moved the scheduler termination code into the mainline - to be consistent with the way other signals are - handled (STR #423) - - The cupsaddsmb program didn't export the new CUPS - driver for Windows properly (STR #390) - - The ppdOpen() functions did not issue an error when a - translation string exceeded the maximum allowed by the - Adobe PPD specification (STR #399) - - The default landscape orientation was not the same as - that defined in the PPD file (STR #397) - - Updated the pstoraster patch files and CUPS driver to - work with Ghostscript 8 (STR #402) - - The hpgltops filter did not skip PJL commands (STR - #379) - - -CHANGES IN CUPS V1.1.20rc6 - - - "lp -i jobid -H restart" would often return an error - even though the job restarted successfully (STR #362) - - The scheduler did not check for invalid allow/deny - addresses such as "11.22.33.44/24". It now masks off - the extra address bits and logs a warning message in - the error_log file (STR #337) - - The cupstestppd utility now checks for missing - ImageableArea and PaperDimension attributes for each - defined PageSize (STR #365) - - The IPP code did not wait for a reply indefinitely on - HTTP connections in "blocking" mode (STR #377) - - The web interfaces did not rewrite the default printer - URI properly (STR #299 and #369) - - The LPD backend passed the C and L commands in the - wrong order (STR #378) - - The Dymo label printer driver did not set the label - length properly (STR #373) - - The scheduler did not support job IDs higher than - 99999 (STR #371) - - The Visual C++ project files did not work (STR #366) - - The scheduler's cupsLangSeek() function did not reset - the "EOF" flag, preventing compressed files from being - typed properly in some cases (STR #368) - - The cupsLangGet() cache was only used if the locale - name provided an explicit character set name (STR - #354) - - The CUPS API convenience functions did not call - cupsLangFree() when they were done with the - localization data (STR #354) - - The scheduler did not return the - job-hold-until-supported or job-hold-until-default - attributes (STR #356) - - The cupsaddsmb program did not support the new CUPS - driver for Windows (STR #357) - - -CHANGES IN CUPS V1.1.20rc5 - - - The scheduler did not initialize the browse socket - file descriptor properly when only SLP browsing was - enabled (STR #259) - - The scheduler accessed the job attributes before they - were set (STR #347, fix to STR #335) - - The cupsCancelJob() function did not return 0 when the - job could not be canceled (STR #340) - - -CHANGES IN CUPS V1.1.20rc4 - - - The scheduler did not move the incoming job attributes - in the operation group to the job group (STR #335) - - The cupsDoFileRequest() function did not check for an - early HTTP response while sending the file (STR #314) - - The web interfaces did not quote #, ?, or . in printer - names, which caused some problems with the generated - URLs (STR #320) - - CUPS couldn't be completely compiled with the -dDEBUG - option (STR #331) - - -CHANGES IN CUPS V1.1.20rc3 - - - More SLP changes (STR #259) - - Revamped the child signal handling code to completely - avoid deadlock issues on Solaris (STR #325) - - The lpadmin command displayed an incorrect error - message when the "-u" option was provided with no - arguments (STR #313) - - The web admin interface did not display an error - message if the PPD file could not be loaded (STR #308) - - The ppdEmit() functions did not use the correct - orientation value position for custom page sizes (STR - #292) - - -CHANGES IN CUPS V1.1.20rc2 - - - The serial backend set the IXANY option on the port - for XON/XOFF flow control; this caused problems with - printers that returned status info but were not ready - for more print data (STR #287) - - The scheduler didn't support scripted index files - (index.php, index.pl, etc. - STR #290) - - The scheduler did not correctly localize script files - with "GET" variables (STR #268) - - Changes in job classification are now logged (STR - #289) - - Fixed a few more SLP-related bugs (STR #259) - - Updated the user/group configure checks for MacOS X - 10.3 (STR #270) - - Fixed an offset bug in the PDF filter (STR #284) - - The cupsDoRequest() and cupsDoFileRequest() functions - did not map several HTTP status codes to their IPP - counterparts. This made detecting certain conditions - very difficult (STR #277) - - Config, spool, and status files are now owned by the - scheduler user (usually root) with read permission for - the filter group (STR #283) - - The HP-GL/2 filter did not support the SI command, - some values for the AD and SD commands, and did not - rotate labels properly via the DI command (STR #282) - - The fax support did not update/set the job-hold-until - attribute when a fax job fails (STR #269) - - The cupsLangGet() function didn't support locales of - the form "ll.charset" (STR #271) - - The scheduler did not use the charset when getting the - language localization for a request; this caused extra - disk IO for every request (STR #271) - - The scheduler did not support requests with more than - one language specified (STR #267) - - -CHANGES IN CUPS V1.1.20rc1 - - - The scheduler now waits up to 60 seconds before - restarting to allow active jobs to complete printing - and pending requests to be processed (STR #226) - - The web interface did not work on systems where time_t - is 64 bits (STR #262) - - Added backend tweeks and content-length check from Red - Hat (STR #253) - - The USB backend now uses the 8255 constants instead of - the standard constants when reporting printer status - bits on Linux (STR #254) - - Added new cupsDoAuthentication(), cupsGetFd(), - cupsGetFile(), cupsPutFd(), and cupsPutFile() functions - to the CUPS API (STR #112) - - The PDF filter always scaled and offset pages; this - caused problems under MacOS X, so now the "fitplot" - option controls whether PDF files are scaled to fit - within the printable area of the page (STR #250) - - The LPD backend did not support the port number in a - URI (STR #247) - - Some filters didn't properly support boolean options - (STR #249) - - Landscape PDF files were not always offset by the - correct amount when rotating (STR #243) - - The scheduler could hang in a call to localtime() when - logging messages from the signal handler (STR #242) - - The PDF filter no longer prints form widgets; this - duplicates the behavior of Acrobat Reader (STR #241) - - cupsGetPPD() didn't handle a late termination of a - HTTP connection with the server (STR #220) - - ppdOpen() did not correctly check for "*PPD-Adobe-4." - on the first line of a PPD file. This caused incorrect - PASS results for some PPD files (STR #233) - - cupsEncodeOptions() did not allow boolean options to - use "yes" and "on" for true values (STR #227) - - The pstops filter only sent the TBCP exit sequence if - it was defined in the JCLEnd attribute in the PPD file - (STR #224) - - Support for more than 1024 files was broken on Solaris - 9 (STR #217) - - The setgroups() calls now pass in 1 group (the - configured group) instead of 0 for compatibility with - BSD and Darwin (STR #213) - - The scheduler's built-in broadcast throttling was - ineffective since incoming packets would cause the - next group of outgoing packets to be sent immediately - rather than waiting for the next time slot (STR #211) - - Added a new ppdSetConformance() function to set the - conformance requirements for PPD files. Currently only - two levels are defined, PPD_CONFORM_RELAXED and - PPD_CONFORM_STRICT, and the default is the relaxed - level (STR #212) - - The IPP backend did not correctly execute the - pictwpstops filter on OSX (STR #210) - - The LPD backend did not set the banner class when the - "banner=yes" option was specified in the device URI - (STR #209) - - The imagetoraster filter did not support all of the - page device attributes (STR #208) - - The pdftops filter incorrectly auto-rotated pages when - the user already had specified the proper orientation - (STR #207) - - Fixed AIX shared library support (STR #201) - - Added support for live testing with Valgrind (STR - #193) - - The CGI programs now collect the list of needed - attributes for the class, job, and printer template - files (STR #192) - - The scheduler now passes the first port that is bound - to the local loopback or "any" addresses to the CGI - programs rather than the port that the browser - connected to (STR #103) - - The cupstestppd program now checks for bad - JobPatchFile attributes and incorrect versions of the - Manufacturer attribute for HP printers (STR #155) - - The filter makefile incorrectly installed - libcupsimage.a in the filter directory (STR #180) - - The scheduler did not verify that the job history - files define the job-priority and - job-originating-user-name attributes (STR #178) - - The pstops filter didn't handle poorly-formed binary - PostScript files that had CTRL-D's in them (STR #156) - - The ppdOpen*() and cupsLangGet() functions did not - make a copy of the old locale strings when using the - POSIX locale when reading files, which apparently - caused problems with some implementations of the - standard C library. (STR #159) - - The pdftops filter did not work properly with some - embedded Type1C fonts (STR #177) - - Updated the pdftops filter to be based upon Xpdf - 2.02pl1 (STR #191) - - The scheduler did not reset the group list when - running CGI and filter processes (STR #185) - - The scheduler no longer calls malloc and free from the - signal handlers (STR #190) - - The USB backend now uses the manufacturer and model - strings if the description string is not available - (STR #174) - - The ppdOpen functions still supported the - VariablePaperSize attribute, which was removed in v4.0 - of the PPD spec. This caused problems with PPD files - that relocated the PageSize option to a non-standard - group (STR #158) - - The cups.list file referenced MAN1EXT, MAN3EXT, and - MAN5EXT, but none of those were actually defined (STR - #147) - - Chunked requests could cause a Denial of Service if - the connection is terminated before the first byte of - chunk data is sent/received (STR #143) - - Printers with special characters in their names were - not accessible from the web interface (STR #120) - - The lpstat command now shows the correct interface - script or PPD file, if any, for a print queue (STR #89) - - The lpstat command now shows the printer-state-message - and printer-state-reasons attributes whenever they are - not blank (STR #152) - - The French and German option-conflict.tmpl template - files did not get installed (STR #148) - - The cups.list.in file did not work when compiling - without shared libraries (STR #149) - - The DSOFLAGS included the LDFLAGS, which causes - problems on at least HP-UX (STR #150) - - The fax printer support did not keep track of the fax - capability bit (STR #144) - - The appleLangDefault() function could leak a small - amount of memory (STR #145) - - The ppdOpen() functions now mirror all normal - attributes to the attribute list; previously only - certain unassigned attributes would be added (STR - #139) - - The ppdEmitJCL() function wrote JCL commands to stdout - instead of the passed file pointer (STR #142) - - The httpGets() function could, in certain states, - block waiting for data (STR #132) - - The cupsEmitJCL() function not outputs an empty @PJL - command after the PJL language escape to work around - bugs in certain PJL implementations (STR #131) - - The cupsEmit*() functions didn't set the orientation - value properly (STR #127) - - The cups.spec file didn't list the rc2.d init - directory or the cupstestppd file (STR #134) - - -CHANGES IN CUPS V1.1.19 - - - The GNU TLS code incorrectly used - gnutls_check_pending() instead of - gnutls_record_check_pending() (STR #128) - - The ppdEmit() functions output "PageSize Custom" - instead of "CustomPageSize True" in the DSC comments. - Also, the custom page size code did not use the - ParamCustomPageSize attributes (STR #127) - - The cupstestppd command did not list the conflicting - options (STR #123) - - The lpq command did not ensure that there was - whitespace between the fields in the job listing (STR - #117) - - The German web templates had errors (STR #119) - - The configure script didn't specify the static - libraries properly when configuring with the - --disable-shared option (STR #104) - - The cups.list file used file dependencies for package - formats other than portable, RPM, and Debian (STR #98) - - cupsLangGet() didn't use its language cache (STR #97) - - "lpq -P" would segfault instead of showing a usage - message (STR #94) - - Fixed compiler warnings in pdftops filter (STR #96) - - -CHANGES IN CUPS V1.1.19rc5 - - - Jobs with banner pages that were printed to implicit - classes would get double banner pages for each - file/banner in the job (STR #68) - - The mime.convs file was missing the filter definition - for Windows BMP (image/x-bitmap) files (STR #85) - - The scheduler allowed some READ-ONLY job attributes to - be set, which could cause the scheduler to fail on the - next restart (STR #82) - - The lp and lpr commands did not report when the - scheduler was not responding; instead, the user would - incorrectly see a "no default destination" error (STR - #70) - - cupsLangGet() could fail on OSX due to a corrupt - language preference (STR #78) - - Added more checks for HTTP request timeouts. - - The scheduler dropped the first non-alpha character - after an open brace when doing attribute substitutions - in banner pages (STR #77) - - The scheduler child might send SIGUSR1 to the parent - before the signal handler was installed; this didn't - prevent the scheduler from starting but produced an - annoying error message (STR #45) - - -CHANGES IN CUPS V1.1.19rc4 - - - The lp command did not accept "-" for printing from - the standard input as required by POSIX 1003.1 (STR - #59) - - Added the job-originating-host-name information for - the page_log file documentation in the SAM (STR #31) - - The German web interface templates did not use the - right paths for job operations (STR #54) - - The scheduler would consume all available CPU if - started with a pending job in the queue (STR #35) - - The polling daemon allocated an extra localization - buffer but did not free it, causing cups-polld to - eventually use all available memory (STR #40) - - -CHANGES IN CUPS V1.1.19rc3 - - - The scheduler could get in an infinite loop cancelling - jobs using "cancel -u user dest" (STR #48) - - The "cancel -u user" command did nothing (it should - cancel all jobs on all printers owned by the named - user - STR #48) - - The scheduler would write 0-length job control files - (STR #46) - - Updated the French man pages (translation provided by - Gilles QUERRET) - - The scheduler would delete all printers from - printers.conf if a job was active when a HUP signal - was handled (STR #47) - - The cups-polld program would leak memory if it was - unable to send browse packets to the loopback - interface (STR #40) - - The scheduler did not put the - job-originating-host-name attribute in the job - attributes group. - - The text filter did not default to wrapping text as - defined by the IPP implementation document. - - Scan backends first, PPDs second (STR #37) - - Updated the Netatalk documentation in the SAM (STR #38 - and #39) - - The test suite sent text files to a non-PS print queue, - which requires ESP Ghostscript (provided separately). - Now send the JPEG test file (STR #33) - - The test suite did not show the estimated disk space - requirements (STR #33) - - The test suite did not set the MaxLogSize directive to - 0 to prevent log file rotation (STR #33) - - The test suite still setup the old CUPS Ghostscript - symlinks (STR #33) - - The pstops filter did not report the correct number of - copies for the page_log file when printing collated - copies to a printer that doesn't support them in - hardware (STR #32) - - cupsLangGet() needs to set the CTYPE locale to "C" - (POSIX) to avoid erroneous tolower/toupper values (fix - suggested by Bjoern Jacke) - - Fixed a typo in the cups.list.in file. - - Updated all of the Western European locales to default - to ISO-8859-15 (for Euro support, suggested by Bjoern - Jacke) - - Updated the German message catalog (update provided by - Bjoern Jacke) - - -CHANGES IN CUPS V1.1.19rc2 - - - cupsLangGet() now sets the encoding field based on the - trailing charset in the locale name, and doesn't look - for a message catalog in a specific locale.charset - directory. This fixes STR #26 and is more in line - with the CUPS 1.2 implementation. - - The configure script now aborts if the "ar" command or - compilers cannot be found. - - The static cupsimage library was not built by default. - - The path for the "ln" command was hardcoded in - Makedefs.in instead of being checked at configure time - (STR #28). - - Banner pages containing unescaped { characters would - not work. - - The printer-state-time collection attribute was - encoded as an enumeration instead of an integer. - - The printer-is-accepting-jobs collection attribute was - was not added to the collection value. - - The printer-state-sequence-number collection attribute - was not added to the collection value. - - Fixed typo and const mismatch in IPP backend. - - Updated the man pages for the new configuration - directives. - - Updated the SAM for MacOS 10.2, the CUPS drivers for - windows, the available LPD backend options, and the - new configuration directives. - - The imagetops filter didn't position images properly - on the page (STR #18) - - The configure script didn't add CPPFLAGS to the - compiler options or LDFLAGS to the DSO options (STR - #13) - - The scheduler would try to write a debug log message - when starting a job that contained a NULL string. - Since not all versions of snprintf() support NULL - string pointers this caused some problems (STR #20) - - The testipp program now supports reading of IPP - message files such as those used for the job history - in /var/spool/cups. - - -CHANGES IN CUPS V1.1.19rc1 - - - Added CUPS support files for Java, Perl, and PHP - (located in the "scripting" subdirectory...) - - The scheduler now supports fast-reloads of the - cupsd.conf file when it is updated via HTTP. - - The scheduler always changed the ownership of log - files; it now only does so if they are not in the /dev - directory (i.e. don't want to change the ownership and - permissions of /dev/null...) - - Added libpaper support (patch from Jeff Licquia) - - Added a new istring() rule for MIME types files that - does a case-insensitive comparison of strings. - - The cups-lpd mini-daemon now sends jobs to the default - queue when an empty queue name (or "lp" and there is - no "lp" queue) is sent. - - The scheduler now supports fax queues identified by a - "*cupsFax: True" attribute in the PPD file. When a job - can't be sent, it is held for 5 minutes by default - while other jobs are attempted. The FaxRetryLimit and - FaxRetryInterval directives control the number of - retries and the time between retries. - - The scheduler now preserves the default options of PPD - files when modifying/upgrading an existing PPD file. - When installing a new printer, the scheduler sets the - default media size to Letter or A4 as appropriate for - your locale. - - The scheduler no longer limits the number of - BrowseAddress, BrowsePoll, BrowseRelay, Listen, Port, - SSLListen, and SSLPort directives to 10. - - The scheduler now supports print files that have been - compressed using gzip. - - The scheduler used the stdio functions to read any job - ticket information in a PostScript print job. Since - some platforms limit the number of stdio files to 256, - job ticket information was ignored when the server had - a large number of clients connected to the system. - - Filters and backends may now report the total number - of pages ("PAGE: total NNN") to the scheduler. - - The LPD backend now supports timeout and - sanitize_title options (default to 300 and yes, - respectively) and has some additional changes to - reduce the chances of multiple copies being printed - when only one copy was requested. - - Fixed a polygon drawing bug in the HP-GL/2 filter. - - Added a robots.txt file to the standard install to - prevent search engines from indexing the CUPS server. - - Added support for STATE: messages - (printer-state-reasons), printer-state-history, and - printer-state-time to the scheduler. - - When using RunAsUser, the scheduler would initially - start any previously queued (pending) jobs with - RunAsUser disabled - all backends would be running as - root. - - If a backend failed for a printer, CUPS would - incorrectly requeue the job for printing again. - - Added support for IPP collections and files. - - Added experimental support for generic CGI scripts and - programs, Java, Perl, PHP, and Python to the - scheduler. See the file "CGI.txt" for more - information. - - The CUPS API now supports HTTP cookies and the Expect: - field. - - The cancel command now correctly supports the "-u - user" option to cancel all jobs for the named user. - - The Purge-Jobs operation now supports the my-jobs - boolean attribute and a new purge-jobs boolean - attribute to control whether job history data is - purged from the scheduler; the default is false for - my-jobs and true for purge-jobs to match the original - implementation. - - The scheduler would not timeout printers when only - using SLP browsing. - - If the scheduler was unable to execute a filter, it - would try to restart the job indefinitely until the - filter could be executed. - - When writing BSD printcap files, the scheduler now - includes the rm and rp attributes, allowing the file - to be exported to LPD clients. [Patch from Dominic - Kubla] - - The scheduler optimization to reference IPP attribute - data instead of performing a full copy caused problems - when the referenced data was deleted before it was - sent. It now only references attributes that change - only when the scheduler is restarted. The change also - reduced the memory footprint of a printer object to - 2k. - - The scheduler now holds signals while logging messages - to avoid potential deadlock issues when handling - signals on Solaris 8. - - The lpadmin command now allows printer access control - by group name as well as user name. - - "lpoptions -l" got in an infinite loop if no default - printer was available. - - The scheduler now logs the job-originating-host-name - attribute in the page_log file, and uses "-" for any - empty fields (patch from Dominik Kubla). - - The pdftops filter now scales PDF pages within the - printable area of the page. - - The pstops filter didn't include the page-label and - classification boxes when printing EPS or non- - conformant PS files. - - The imagetops filter didn't always correctly position - the image on the page when printing in landscape - orientation. - - The ppdEmit() functions now support the - RequiresPageRegion attribute when sending InputSlot - and ManualFeed commands. - - The PPD loading code now supports standard options - outside of OpenUI/CloseUI as required by the PPD spec. - - The cupstestppd program has been upgraded to provide a - concise PASS/FAIL report, additional detailed - conformance testing, and support for gzip'd PPD files. - - The PPD loading code is now much more strict when - loading a PPD file, and tracks more format errors. - - The scheduler ignored child signals when gathering the - list of available devices, when it should have been - using the default signal handler. - - The cupsEncodeOptions() function could encode an - option with a NULL last string. - - The socket backend could report the wrong number of - backchannel bytes if an error occurred on the link. - - The cups-polld program now only sleeps after getting - all printers and classes. This allows for longer - intervals without excessive delays before classes show - up... - - Added a new httpWait() function to support waiting for - data for a specific number of milliseconds. - - httpGets() now times out after 1 second on - non-blocking HTTP connections. - - The scheduler no longer accepts rangeOfInteger values - that are out of order (e.g. 5-1) - - The sides attribute was incorrectly sent as a name - value; it is a keyword value. - - The IPP backend now detects if the destination queue - has gone away and reports an error. - - The scheduler and HTTP API now allocate their select() - sets to support larger numbers of clients on systems - that support it. - - The scheduler now sets the CFProcessPath environment - variable under MacOS X. - - The cupsLangDefault() function now uses the - CoreFoundation localization API under MacOS X. - - The httpSeparate() function didn't handle file URIs of - the form "file:///path" properly. - - The lpadmin command now supports a "protocol" option - for specifying the binary communications protocol to - use when printing binary PostScript data. - - The scheduler did not properly parse the SystemGroup - directive, so only the first group would be used. - - Revamped how strings are stored in the scheduler, - providing a substantial improvement in memory usage - for systems with large numbers of printers. - - The PostScript filter now supports binary PostScript - files and files beginning with the PJL language escape - sequence. - - The PPD API now provides additional information from - the PPD file. - - The USB backend didn't compile on Solaris Intel. - - The cupstestppd utility now supports the "-q" option - (quiet) for use in scripts, etc. - - Merged several weight-reducing changes into the CUPS - baseline donated by Apple. - - Added preliminary support for CDSA; patch provided by - Apple. - - Implicit classes are now created from identical - printer classes on the network. - - The lp command now supports a "-H restart" option to - restart previously printed jobs. This functionality - only works if you have enabled the PreserveJobFiles - option. - - The scheduler now supports URIs in HTTP request lines - to conform to the HTTP/1.1 specification. - - The time-at-xyz attributes were not recognized in - banner files if prefixed by a question mark, e.g. - "{?time-at-creation}". - - Added support for pre-filtering application/pictwps - files on MacOS clients before sending them to a server - via IPP. - - The scheduler now allows file:/dev/null device URIs - even if FileDevices is set to No. - - CUPS uses strerror() for hostname resolution errors, - when it should have used hstrerror(). - - The USB backend no longer tries to guess the serial - number of a device from the USB devices file; this - means that printers that don't report their serial - numbers in the device ID string will not be - individually selectable. - - The pstops filter didn't handle page ranges properly - when a page contained an embedded document. - - Added a translation of the web interface to German. - - When printing using the OutputOrder=Reverse option - with duplexing, the output order is now truly - reversed; the order of sub-pages when printing N-up is - the same. - - The pstops filter did not always output the extra - blank page when printing a document with an odd number - of pages with duplexing enabled. - - The ippAddXYZ functions no longer allow the - application to add less than 1 value. - - Fixed a URL rewrite bug in the web interface - local - access was sometimes redirected away from localhost... - - The ppdOpen() functions could get in an infinite loop - if the PPD file contained a keyword or text that was - too large for the buffer. - - Added preliminary support for GNU TLS; patch provided - by Jeff Licquia. - - Now timeout IPP attribute reads after 1 second inside - an attribute definition. - - Now timeout connections that have been shutdown (due - to errors) after 30 seconds instead of the Timeout - setting (300 seconds by default). This provides - faster recovery from DoS attacks. - - A denial-of-service attack warning message was being - written to the log files by the scheduler for every - detection. This caused a DoS of its own in some - situations. The warning message is now written no more - than once per minute. - - Fixed the CIE colorspace support code in the image and - PS RIPs. - - The job-quota-period, job-page-limit, and job-k-limit - attributes were not flagged as integers, so setting - quotas would not work. - - Added an additional response check in the scheduler to - more quickly recover from denial-of-service attacks. - - The cupstestppd file was incorrectly installed in the - /usr/sbin directory instead of /usr/bin. - - The EPM list file did not include the cupstestppd - program or man page files. - - -CHANGES IN CUPS V1.1.18 - - - Fixed a bug in the Set-Job-Attributes code in the - scheduler that would cause it to crash or continuously - write a job control file. - - SECURITY FIX: The scheduler now provides a FileDevice - directive to control whether new printers can be added - using device URIs of the form "file:/filename". The - default is to not allow printers with these device - URIs. - - The scheduler did not compute the cost of filters - properly, nor did it choose a multi-filter solution - with a lower cost than a single filter solution. - - Now install CUPS PPD file test utility (cupstestppd) - to support basic conformance testing of PPD files. - - The scheduler now logs an error message when it sees a - non-conforming PPD file. - - Upgraded pdftops filter to Xpdf 2.01 with fixes for - TrueType fonts. - - Added a MaxClientsPerHost configuration directive to - provide limited protection against Denial of Service - attacks. - - SECURITY FIX: Potential underflow/overflow bug in web - interface. - - SECURITY FIX: Race condition in certificate creation. - - SECURITY FIX: Bad URIs in browse packets could be used - to exploint the web interface underflow/overflow bug. - - SECURITY FIX: Some types of Denial of Service attacks - were not handled properly, so once the attack was over - the scheduler did not close the connections - immediately on all platforms. - - SECURITY FIXES: Added integer overflow/underflow - checks for all image formats. - - The pstops filter didn't reset the showpage operator - back to its original at the end of a job; this - prevented the concatenation of documents (used - primarily for CUPS 1.2...) - - The cupsGetPPD() function didn't always set the - cupsLastError() value when an error occurred. - - The IPP media, output-bin, and sides attributes took - precedence over the corresponding PPD options, which - caused inconsistent behavior under MacOS X with some - PPD files. - - The cupsaddsmb utility specified the wrong number of - arguments to the adddriver command when adding the - Win9x PostScript drivers. - - The web interface did not always report the correct - error message. - - The scheduler did not clear the POSIX signal action - structure when waiting for the child to send it a - SIGUSR1 signal; this could cause the signal handler - not to be called properly, preventing the parent - process from returning. - - -CHANGES IN CUPS V1.1.17 - - - The "manual_copies" option did not work when the LPD - backend had to retry a print job. - - The image filters did not convert GIF images properly. - - The RunAsUser option was incompatible with the new - daemon-mode code in 1.1.16. - - Fixed a problem with the Set-Job-Attributes and - PostScript job ticket code in the scheduler - the - "last" attribute pointer was never updated, which - could cause the scheduler to crash when applying job - ticket data. - - Fixed a problem in the scheduler that caused it to - continue processing HTTP requests on a connection - after it was shutdown. - - The scheduler now allows accounts authenticated via - PAM to not have a corresponding UNIX account, but - group membership still requires the account name to be - listed in the UNIX group file(s)... - - The scheduler used a fixed-size (16k) buffer for - encoding job options for filters; it now dynamically - allocates and expands the buffer as needed depending - on the options that are sent in a job. - - The pdftops filter didn't support all of the MacOS - characters for MacRoman encoded fonts. - - The cupsEncodeOptions() and cupsParseOptions() - functions now conform to the grammer defined by the - current draft of the PAPI specification. The main - difference is that option=yes and option=no are no - longer treated as boolean options. - - The IPP backend didn't honor the encryption settings - in /etc/cups/client.conf. - - Fixed a potential bug in the HTTP code which was - caused by servers sending the status line and - newline(s) in separate packets. - - User-defined classification strings are now printed - verbatim - previously the classification box would be - empty. - - Re-added Spanish to the list of PPD languages that - CUPS supports. - - CUPS API library user and temp file updates for - Windows. - - The image filters did not properly handle grayscale - printing of Sun Raster images. - - The scheduler never reset the NumJobs variable before - loading the job list (previously this only happened on - a full start, so the problem was never apparent...) - - The HTTP and IPP read/write code didn't handle EINTR - (interrupted system call) errors. - - When under high load, the scheduler could abort due to - the wrong errno value after a select() call. This was - caused by the child signal handler. - - Added new load tests to the test target to verify that - cupsd can handle hundreds of simultaneous jobs without - error. - - The Solaris USB backend now supports the new device - URI syntax. - - The ppdOpen*() functions now reset the numeric locale - settings while loading a PPD file. - - Fixed the libtool build rules. - - The manpage make rules didn't use $(MAKE) and - $(MFLAGS) for the language subdirectories. - - Now set the LC_TIME locale category to get the - properly localized time string. - - Fixed a problem in the scheduler that would cause the - web interface problems when adding, modifying, or - configuring a printer or class. - - The backends now ignore SIGPIPE so that failed job - filters will not stop a print queue. - - The lpstat command did not allow for destination lists - ("lpstat -v printer1,printer2") - - Fixed parsing of long filter status messages in the - scheduler. - - Added some startup performance enhancements to the - scheduler so that the printer object information is - regenerated fewer times and the MIME type database is - not filled with lots of empty filters for raw/direct - queues. - - The LPD backend now sends the job title as the print - filename. - - Added support for variable sizes in the EPSON dot - matrix printer drivers. This allows for pages as - short as 1/2" (1 row of labels) and does not do an - automatic form feed. - - French translation updates. - - The filters did not quote the page label string when - embedding it in PostScript output. - - The serial backend now enumerates serial ports under - MacOS X. - - The pdftops filter contained font rasterizer code that - wasn't being used and that depended on X11. This code - has been removed. - - -CHANGES IN CUPS V1.1.16 - - - The cancel and lprm commands now both display an error - message and return a non-zero exit status if an - attempt is made to cancel a job on a non-existent - printer. - - The lpoptions command incorrectly complained if a - request to delete a non-existent printer was made. - - If the client.conf file defines an alternate server - name, the "configure printer" action in the web - interface might not work. - - The lpstat command now supports a "-W" option so that - you can display completed jobs as well as - not-completed (pending) jobs. - - The lp and lpr commands did not return an error when - one or more files in a set of files for printing could - not be printed. - - The lp, lpadmin, and lpstat commands now consistently - return with a non-zero exit status when an error - occurs. - - The scheduler would not accept print jobs sent to a - stopped remote printer. - - The texttops filter incorrectly converted the page - numbers in the prettyprint header to double-byte - characters when printing a non-Unicode text file. This - caused an extra space to appear between each digit in - the page number. - - The scheduler did not use a case-insensitive - comparison when adding filters for a printer. - - Upgraded the pdftops filter to Xpdf 1.01. - - The scheduler no longer passes the page-border and - number-up-layout attributes to filters when printing - banner pages. - - The LPD backend now uses a 30-second timeout when - sending commands and control files, and a 30-second - timeout when retrieving responses from an LPD server. - If a timeout occurs, it retries indefinitely. This - helps to make LPD printing over VPNs work more - reliably. - - The USB backend now supports device URIs based on the - printer serial number and/or model number under Linux. - This avoids the "wrong device filename" problem when - using more than one USB printer. - - Now just shutdown the receiving end of a client - connection when sending an error that requires the - server to disconnect from the client afterwards. This - fixes a problem when doing remote administration with - encryption enabled. - - The scheduler did not send a printer-state-message - attribute if the string was empty; it now always sends - this attribute. This caused the printer message to be - displayed for other printers in the web interface. - - The LPD backend now supports a "manual_copies" option, - e.g.: "lpd://server/queue?manual_copies=no", in order - to handle copies for raw jobs to printers that don't - implement the LPD protocol properly... - - The "mirror" option was not being handled by the - PostScript or image filters. - - Updated the cupsaddsmb command to support the new CUPS - driver for Windows NT/2k/XP. - - Filter status lines longer than 1023 characters could - cause the scheduler to get into an infinite loop. - - The scheduler didn't reset the job state to pending - when modifying an active printer. - - Now limit the maximum number of recursion steps when - searching for a filter for a job, in case a user - defines a circular filter rule. - - The PostScript filter would embed an invalid - requirements comment in some cases. - - Added support for embedded job tickets in PostScript - files. - - The PostScript filter now detects EPS files and should - better handle printing EPS files. - - The cancel command now ignores a trailing destination - name when cancelling a specific job ID (Solaris - compatibility). - - The scheduler now rejects jobs with copies outside the - range of 1 to MaxCopies, inclusive. - - Added new MaxCopies directive to set the maximum - number of copies that a user can request. - - The scheduler didn't block signals while it processed - others and when it forked processes. - - The scheduler checked for new jobs to print when - stopping a job. This caused jobs to restart before a - shutdown. - - Updated the CUPS startup script to better support - different timezones and to support the RedHat/Mandrake - init script functions, if available. - - The scheduler did not properly handle backslashes in - banner files; it incorrectly assumed that "\c" should - always be replaced by "c", instead of only looking for - "\{" and replacing it by "{". - - The texttops filter didn't handle prettyprint=no. - - The text and HP-GL/2 filters didn't check for other - common duplex option names like cupsMarkOptions() did. - - "lpoptions -x printer" no longer clears the "default - printer" status of the printer. - - cupsTempFd() now stops trying to create a temporary - file after 1000 tries, and aborts on any error other - than EEXIST. This should prevent lp/lpr hangs due to - a bad or missing temporary directory. - - The lpadmin command did not send the right URI to the - scheduler when setting options on classes. This - caused a client-error-bad-request error. - - The CUPS API convenience functions would attempt to - connect to the remote server name in a - "printer@server" printer name instead of dealing with - the default (usually local) server. Aside from - causing user confusion, the remote server name might - not be resolved properly, causing further problems. - - "lp -q" would cause the "lp" command to segfault, as - the program would try to print the option letter that - caused the error using the wrong index into the - command-line; bugfix from Debian. - - Fixed a minor inconsistancy in the encoding of boolean - attributes from printer options in - cupsEncodeOptions(). - - Added a FilterNice directive which sets the priority - of job filter processes that are run by the scheduler. - - Added Solaris x86 USB printer support. - - The USB backend now reports both the ulpt and unlpt - devices under *BSD. - - The "lpstat -o" command would truncate the - "printer-jobid" string if it was longer than 21 - characters. - - The PJL-based MIME type rules now look in the first - 1024 bytes instead of just the first 512 bytes to find - the language mode. - - The image file types are now listed explicitly in the - mime.convs file so that additional image file formats - do not use the standard CUPS image filters by default. - - Updated the Software Programmers Manual to include - all of the CUPS API functions. - - ppdOpen*() no longer sorts choices for an option. - - The web interface now enforces constraints in PPD - files when configuring a printer. - - When stopping a printer, the scheduler didn't set the - printer state before stopping the current job. - - The cupsaddsmb utility now lists all data files for - Win9x and WinMe clients when installing that Windows - driver. - - Jobs submitted to a class now bounce immediately to - the next available printer rather than waiting until - that printer is available. - - Filters and backends now also get the CLASS - environment variable set when a job is printed to a - printer class instead of a normal printer. - - Added French translations of the web interface, CUPS - Overview, Software Administrators Manual, and Software - Users Manual contributed by Marian REYT-LLABRES. - - Added several "hint" messages for common configuration - problems that are stored in the error_log file. - - httpSeparate() now unquotes %xx characters in the - username:password field of a URI. - - When starting the scheduler in daemon mode, the parent - process now waits for the child to signal it is ready - to accept connections. - - Added -F option to cupsd to run cupsd in the - foreground but detach from the controlling terminal - and current directory. - - The scheduler did not reload jobs when receiving a HUP - signal; this would cause problems since the pointers - into the file type database would no longer be valid - for existing jobs. - - The scheduler did not save the network interface list - update time, thus no caching of the network data was - actually provided. - - Updated the SuSE PAM configuration file. - - The LPD backend now supports a "reserve" option and no - longer reserves a priviledged port by default. - - The cupsaddsmb command now continues past printers - that do not have a PPD file to export. - - The lpstat command didn't treat printer names as - case-insensitive. - - The lpstat command now reports the printer location - attribute with "lpstat -l -p". - - Fixed a bug in the vsnprintf() emulation function, - which was used on old versions of HP-UX, IRIX, and - Solaris. - - The number-up option was incorrectly being used when - printing banner pages. - - Added support for Greek and Slovak PPD files. - - CUPS now supports printer names containing any - printable character, e.g. "123-abc", "foo-bar", etc. - - The null filter was not supported in mime.convs due to - a bug in the filter validation code. - - Changes in the default printer and printer attributes - were not always reflected in the generated printcap - file. - - Implicit classes did not inherit the location or - description from member printers. - - The httpGetHostByName() function did not handle - hostnames that started with a number. - - Updated the filters to use the %cupsRotation comment - instead of %%Orientation to auto-rotate pages, since - the use of %%Orientation is inconsistent. - - Added the RootCertDuration directive to control how - often the root authentication certificate is updated. - - Increased the size of the IPP write buffer to 32k to - allow for larger attribute values and to provide more - efficient output of large numbers of attributes. - - The polling daemon now retries the initial connection - to the remote server; this fixes a problem when the - remote server is unavailable when the scheduler starts - up... - - The scheduler didn't validate Digest users against the - system group(s), so Digest and BasicDigest - authentication didn't work for administration - operations. - - The scheduler now passes the SHLIB_PATH environment - variable to child processes (HP-UX shared libraries) - - The scheduler now maps accesses from the loopback - interface to "localhost". - - The cups-lpd mini-daemon sent a status code byte in - response to queue state commands, but those commands - only return textual data. - - -CHANGES IN CUPS V1.1.15-1 - - - The lpc and lprm sources didn't include the CUPS - string function header, which is required on systems - that don't have their own snprintf() function. - - The French manpage Makefile tried to install the - language subdirectories when it (obviously) didn't - have to. - - -CHANGES IN CUPS V1.1.15 - - - Updated the CUPS license agreement for the new MacOS - license exception. - - The printer-info attribute now defaults to the printer - name if no value has been set. - - ppdOpen() and friends now add an "Auto" InputSlot - option if none is provided to automatically select the - correct tray. - - Updated the ppdEmit() and ppdEmitFd() functions to - (re)mark the correct PageSize or PageRegion option - depending on the selected ManualFeed or InputSlot - options. - - ppdEmitFd() didn't handle custom page sizes. - - Darwin uses instead of - . - - The jobs.cgi web interface now handles all job - operations, allowing the administrator to allow "job - administrators" or operators to manage jobs (but not - queues) on the server. - - The cupsDoFileRequest() function now checks if the - filename passed into the function is a directory, and - returns the IPP_NOT_POSSIBLE error if so. - - New SCSI printer backend. - - Cleaned up handling of locales with trailing character - set definitions. - - Fixed handling of invalid PPD attributes inside - OpenUI/CloseUI. - - Fixed a problem with SSL and the job, printer, and - admin CGIs on ports other than 443. - - The scheduler didn't handle AuthClass properly. - - Added French translation of man pages. - - Updated the text filter to support the const_cast, - dynamic_cast, and static_cast keywords in ISO C++. - - Now use strlcat() and strlcpy() (or emulation - functions) for easier string/buffer protection. - - The auto-generated printcap/printers.conf files now - have a small comment header explaining where the file - comes from... - - The PostScript filter now supports 6, 9, and 16-up - output, as well as new page-border and - number-up-layout options. - - The lpoptions command didn't set options properly when - using the default printer. - - Added ConfigFilePerm and LogFilePerm directives. - - Increased maximum size of MIME types to IPP_MAX_NAME - to allow for longer printer names. - - No longer create remote printers when loading job - history data. - - The printer-make-and-model attribute wasn't set when - the PPD file didn't contain a NickName attribute. - - Now handle PPD files with translation strings longer - than 80 bytes - they are truncated if they go over... - - The scheduler didn't handle signals until after it - loaded the configuration files the first time; this - caused problems on some installations that would - restart the scheduler as the system booted into run - level 3. - - Now throttle broadcasts like we do for polling. - - Fixed a bug in the reading of PPD files using CR's - instead of CR LF's or LF's. - - The scheduler would crash if cupsd.conf contained a - BrowseProtocols line with no protocols listed. - - The HTML job operation templates now link back to the - destination printer or class. - - The serial backend now detects USB serial devices. - - The LPD mini-daemon (cups-lpd) now passes the - job-originating-host-name attribute to the scheduler - (cupsd). - - Updated the IPP backend to reconnect after downgrading - from IPP/1.1 to 1.0, and when sending requests to HP - JetDirect interfaces that don't support HTTP - Keep-Alive like they should. - - Now pass NLSPATH and DYLD_LIBRARY_PATH environment - variables, if defined, to CGI and job processes. - - Removed the pstoraster filter (based on GNU - Ghostscript 5.50) and now provide the raster "driver" - and patch file necessary to use the current GNU - Ghostscript 7.05 release. - - Removed unnecessary fonts and updated the Courier and - Symbol fonts to the latest versions to better support - non-ISOLatin1 text. - - The text filter now always embeds the Courier and - Symbol fonts to ensure that they contain the full set - of glyphs. - - The lp and lpr commands now only override the SIGINT - handler if it is not being ignored (patch from Robert - Ambrose for some interactive software that catches - SIGINT and will gracefully cancel the print...) - - The PostScript image filter (imagetops) now supports - printing CMYK images using the CMYK colorspace. - - The image filters now support CMYK JPEG files, and - correctly handles the inverted files from Photoshop - (which seems to save RGBW data, not CMYK...) - - Added a "check" target to the top-level makefile to - conform with GNU standards (same as "test"). - - The IPP code didn't always map the POSIX locale "C" to - the proper IPP language code. - - The cupsaddsmb program was updated to use the - setdriver command instead of addprinter. - - Banner pages were not handled properly for implicit - classes. - - When tunneling to a remote system using SSH, the - printer URIs for local printers on the remote system - did not reflect the correct port number. - - The Allow, Deny, BrowseAllow, BrowseDeny, and - BrowseAddress directives now support the network - interface names "@LOCAL" and "@IF(name)" for access - control and browsing based on the current interface - addresses instead of fixed names or IP addresses. - - The texttops filter did not properly recognize the - "nowrap" (wrap=false) option. - - The InstallableOptions group name in a PPD file is now - translated separately (CUPS_MSG_OPTIONS_INSTALLED) so - that UIs can accurately detect the presence of this - group. - - The scheduler no longer keeps job history data for - remote printers on the client (just on the server.) - - The parallel and USB backends now retry if the backend - detects that the printer is not connected to the - system (rather than stopping the queue...) - - The network backends now retry if the backend detects - that the printer is not connected to the network or is - unreachable (rather than stopping the queue...) - - The cupsGetDests() function no longer lists options - and instances for printers that no longer exist. - - The scheduler now converts the document language to - the correct LANG string. - - The cupsaddsmb program now supports alternative CUPS - and SAMBA server names. - - The PostScript filter now supports the Orientation - comment and rotates the page as needed automatically. - - Revamped the makefiles slightly to use automatically - generated dependencies. - - Build fixes for OS X. - - The TIFF reading code depended on the newest version - of libtiff; now conditionally compile that portion of - the loader. - - The PPD code now decodes all JCL options in the - JCLSetup group, not just those options that start with - the prefix "JCL". - - The backends now read print data using the read() - system call to ensure that the current page is printed - while the next page is being processed. - - The pdftops filter did not support shading type 3 - (radial fill) for the "sh" operator. - - The cups-polld program now throttles the local - broadcasts of polled printers and classes so that the - local system is not overwhelmed with hundreds of - printers and classes all at once. - - Updated the serial backend to support 230,400 baud for - the Linux PPC port. - - The cupsGetJobs() function wouldn't report completed - jobs that did not have a document-format attribute - value. - - The cupsEncodeOptions() function now maintains a table - of known boolean and numeric options, and encodes all - other options as strings. - - Now add a newline before the end-of-page code in the - PostScript filter; this fixes a problem with files - that don't end with a newline. - - The image filters looked for the "orientation" option - instead of the correctly named "orientation-requested" - option. - - The cupsEncodeOptions() function now handles mixed - integers and ranges. - - New translation guide for developers to provide native - language support for CUPS. - - -CHANGES IN CUPS V1.1.14 - - - The ippRead() function did not verify that the - attribute name length or string with language value - was not larger than the read buffer. - - The scheduler set the signal handlers before loading - the configuration files the first time; this prevented - the RunAsUser directive from blocking server reloads. - - Added Swedish message catalog. - - The parallel backend now recognizes the /dev/printers - device directory under Linux 2.4.x. - - MacOS X fixes. - - The cupsaddsmb utility sent the server name after the - user information when executing the rpcclient program. - This caused problems with some versions of SAMBA - 2.2.x. - - The IPP backend did not pass the requesting user name - when checking on the print job status. This prevented - it from waiting for the job to complete when - communicating with some IPP implementations that - require it. - - -CHANGES IN CUPS V1.1.13 - - - The lpstat command did not report jobs submitted to - regular printer classes. - - The texttops filter didn't use sufficient precision - when positioning text with some values of cpi and lpi. - This could cause the alignment of text to stray. - - cupsGetDests() didn't merge the options from the - /etc/cups/lpoptions file with ~/.lpoptions - options - in ~/.lpoptions overrode them completely. - - Added support for KOI8-R and KOI8-U character sets, - and added several Russian message catalogs. - - The scheduler put the wrong timezone offset in the log - files (e.g. +0500 instead of -0500 for EST...) - - The scheduler did not ignore trailing whitespace in - *.convs files. - - The scheduler now forces all processes to exit (kill - -9) when it is stopped. This prevents parallel and - USB devices from running in the background after cupsd - goes away. - - The cupsParseOptions() function didn't skip trailing - whitespace after quoted values. - - More changes to support CUPS on OS/2. - - Added Simplified Chinese message catalog. - - Added PAM support for IRIX. - - The cupsGetPPD() function didn't remove the @server - portion of the printer name, and since it would - connect immediately to the remote server instead of - the local server, the printer would not be found. - - Classification and page labels were not rotated to - match the page orientation. - - Now set the TCP "no delay" option on network - connections to improve performance/response time. - - Improved the IRIX printing tools support with patches - from Andrea Suatoni. - - Added a new PrintcapGUI directive to specify the GUI - option panel program to use for the IRIX printing - tools support. - - The cupsGetDests() function did not check to see if a - user-defined default printer (set via lpoptions) still - existed. - - The pstops filter no longer assumes that the default - dictionary is writable when doing N-up processing. - - The pstops filter now supports printing N-up with the - page-set option. - - The imagetoraster filter now supports direct printing - of CMYK image data without conversion/correction. - - The IPP backend now reports printer state/error - conditions when possible (toner low, media empty, - etc.) - - The lpstat command now supports the (undocumented) - IRIX -l option ("-lprintername") for a compact job - listing for a printer. - - The lpstat command now includes printer date/time - information in the output (always Jan 01 00:00) to - make third-party tools happy. - - The text filter now supports non-integer cpi and lpi - values. - - The Margins field in the CUPS raster header was not - initialized by the pstoraster filter. - - Added --with-optim="flags" option to configure script. - - Updated the Italian message translations. - - Updated the cups.list file to install the correct - files. - - The pstoraster filter accessed the third element of a - 2 element array. - - The scheduler did not setup a status pipe for polling - processes, so error messages went to whatever file - descriptor 2 was pointing to when they were started. - - The httpMD5Final() function didn't put a colon between - the password and nonce strings. - - The pstops filter did not default to Binary data for - "%%BeginData:". - - The pstops filter did not stop processing when a line - containing a CTRL-D is seen. - - The scheduler no longer replaces the JobSheets values - from the printers.conf and classes.conf files with the - classification level, if set. This way the original - banner settings are preserved when classification - levels are changed or turned off. - - The serial backend didn't drain the output queue, nor - did it restore the original settings. - - Updated the default system group under MacOS X. - - If no SystemGroup was defined in cupsd.conf, the - system default group was not used. - - 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 - package for pstoraster. - - The spec file wasn't setting LOGDIR in the install. - - The scheduler might restart a stopped printer after - stopping a print job. Thanks to Florent - Guiliani for finding this bug! - - The init script showed run level 0 for the Red Hat - chkconfig program. This is incorrect because Red Hat - doesn't use run level 0 for shutdown scripts. - - The IPP backend did not handle the - client-error-not-found error when checking the status - of the job that was sent. This caused remote queues - to stop on client machines when the server had job - history disabled. - - Added httpConnectEncrypt() function to avoid - performance penalty for setting up encrypted - connections initially. - - Use httpConnectEncrypt() in all client apps and in the - CUPS API to ensure consistent usage of encryption - throughout. - - Jobs weren't queued to remote classes (fix from - Richard Begg.) - - AIX changes from Richard Begg. - - Fixed the pstops fix for GNOME output - no longer use - the page numbers in the %%Page: comment since GNOME - puts a filename instead (!?@!#?!). There is still an - issue with N-up printing since GNOME defines its fonts - in the first page instead of the document setup section - (pages must be independent according to the DSC spec) - People with GNOME printing problems should consult bug - #54489... - - The imagetops filter produced PAGE: messages when - generating PostScript for a non-PostScript printer - (only affects page-label and Classification - options.) - - The updated pdftops filter was looking for an options - file called xpdf.conf instead of pdftops.conf. - - -CHANGES IN CUPS V1.1.7 - - - Configuration script changes, including new - "--with-docdir=/dir" option to relocate CUPS - documentation and web content according to your - favorite version of the FHS. - - Documentation updates for encryption, SLP, etc. - - New Software Test Plan and automated test script to - test CUPS prior to installation. - - All scheduler configuration files are now case - insensitive to match Apache. - - Added support for Apache ListenBackLog, Require, - Satisfy, , , and LimitRequestSize - directives. - - Added support for all Apache log levels... - - Added support for "double" HostNameLookups. - - Added new "RunAsUser" directive to support non-root - configurations on the standard (priviledged) ports. - - Added support for non-root invocation of the lpd - backend (does no reserve a priviledged port, which - might not work with some LPD servers...) - - Added new PrintcapFormat directive to control the - output format of the printcap file (BSD or Solaris - formats are supported at present.) - - The CUPS directory service routines now handle - ECONNREFUSED errors gracefully rather than shutting - all browsing off. - - ippErrorString() now returns the recommended error - messages from the IPP/1.1 Model and Semantics - document. - - Fixed a minor IPP compliance issue with responses - to requests without the attributes-charset or - attributes-natural-language attributes. - - Sun fix: need httpFlush() call for chunked IPP - requests in cupsDoFileRequest(). - - httpConnect() now looks up "localhost" by name and - by address (127.0.0.1) for users the go to the - trouble of removing the required localhost entry - in /etc/hosts or on their DNS server... - - Added support for Linux 2.4.x devfs parallel port - filenames (/dev/parallel/N). - - cupsDo[File]Request() and cupsGetPPD() no longer - block trying to reconnect to a crashed or inaccessable - server. - - Added new ppdEmitJCL() function to better handle - PJL commands from PPD files. - - A bug in UpdateJob() would cause the scheduler to - consume 100% CPU until another request was submitted. - - The cancel command did not support the "-" option to - cancel all jobs on all printers. - - The cancel and lprm commands did not support cancelling - the next/current job in the queue. - - The pdftops and pstoraster filters were using unsafe - temporary file functions; while this is not a problem - in normal configurations (the CUPS temporary directory - is restricted), they now use the cupsTempFd() function. - - The mime.types file was missing the recognition rule - for Sun Raster images. - - The admin CGI was passing a printer make string to - ippSetCGIVars() that was being replaced in that - function. - - "lpoptions -l" would resave the options... - - The EPSON drivers now send the "end packet mode" - command when printing to USB devices. - - The scheduler initialized certificates before loading - the cupsd.conf file. - - The scheduler used /dev/random to collect random data, - which could block if insufficient entropy information - had been collected by the kernel. Now use - /dev/urandom. - - Fixed a bug in the whitespace skipping code in - httpGetSubField(). - - The LPD backend now supports a new "order" option: - "lpd://server/queue?order=control,data" (default) and - "lpd://server/queue?order=data,control". - - The scheduler enforced a 30 second timeout on all - clients regardless of the Timeout directive and if a - CGI was currently running. - - cupsParseOptions() now sets boolean options to - option=true or option=false. - - The "percent complete" calculations in the LPD backend - could overflow on large files, causing the percentage - to wrap to 0 every 40MB or so. - - Fixed a memory reallocation bug in pstoraster that - could cause it to crash. - - The LPD backend now sanitizes the job title to avoid - potential problems on remote LPD servers. - - The lp command did not send the requesting-user-name - attribute when altering a job. - - The pstops filter did not handle PostScript files with - lines longer than 8191 bytes. - - The scheduler no longer uses inet_addr() to convert IP - addresses in dot format (mmm.nnn.ooo.ppp) to the - 32-bit format, since it will not work for IPv6 - addresses. - - New "Classification" directive to force labeling of - the current classification on each page. - - New "page-label" attribute to add per-page labels - ("For Official Use Only", "Draft", etc.) - - The scheduler now sets the HTTPS environment variable - for CGI programs when a client connects using - encryption. - - Fixed a recursion bug in the scheduler that could - cause cupsd to crash when a printer was removed. - - The LPDEST and PRINTER environment variables didn't - support instances. - - Dropped the "file" backend from the device list that - is reported, since it is only available for *testing* - and should never be used in a production environment. - The file: device can still be used, but it won't show - up in the list of devices from lpinfo or the web - interface. - - Added support for /dev/lpa# parallel ports under *BSD. - - Added META variables to the CGI header template to - prevent caching of the results. - - Fixed an unaligned memory buffer for the pstoraster - clist states; this caused bus errors for some - combinations of printers, drivers, and options. - - Re-added black reduction for colorful colors; this - helps to prevent dark colors from getting desaturated. - (only used when converting RGB to CMYK) - - Added two new directives - MaxJobsPerPrinter and - MaxJobsPerUser - to allow an administrator to set - the maximum number of pending jobs in a queue or - submitted by a user. - - The scheduler no longer stops a printer if it can't - create the status pipe or run the filters or backend. - This will allow heavily loaded servers to service - clients or start print jobs as the load allows. - - Fixed a bug in the Set-Job-Attributes code that could - crash the scheduler (patch from Martin Zielinski) - - cupsSetDests() did not quote option values with - embedded spaces. - - Added support for the Enable-Printer and - Disable-Printer extension operations (same as - CUPS-Accept-Jobs and CUPS-Reject-Jobs.) - - The AppSocket and IPP backends now wait for the print - job to be finished before exiting; this should prevent - the loss of print jobs with older JetDirect firmware - and make consecutive print jobs print faster. - - The BMP loading code did not handle resolution values - of 0. This is a problem with BMP image files produced - by the GIMP. - - The HTTP Upgrade code (upgrade to TLS encryption) - bypassed the authentication checks. - - The HTTP Upgrade code did not send a 426 status code - to the client and end the current request. This caused - a race condition between the client and server for the - upgrade to TLS. - - Fixed a bug in the EOF and Trailer detection code in - the pstops filter. - - The imagetoraster filter did not add the margins to - the custom page size in the raster header. - - The imagetops filter did not adjust the custom page - size to the size of the printed image. - - The imagetops filter did not include DSC comments - which are required by some printers. - - The imagetops filter did not insert newlines in - Base85 encoded output, causing files to contain - lines longer than 255 characters (violation of the - DSC). - - Added support for the DeskJet 900 series duplexer - and CRET color modes in the HP driver. - - Added support for PPD-defined margins in the HP - driver. - - Fixed the debugging output from pstoraster - the - font list was not terminated by a newline. - - Some versions of the HP-UX pam_unix authentication - module apparently do not pass the appdata_ptr argument - to the conversation function, preventing the scheduler - from authenticating users using PAM under HP-UX. A - workaround using a static variable has been added to - address this problem. - - Fixed a bug in the scheduler SortPrinters() function - that could cause printers to disappear or the - scheduler to crash when adding a printer. - - Changed the pstops filter to not do per-page filtering - if the file does not conform to at least version 3.0 - of the document structuring conventions. This seems - to "fix" printing with broken apps. - - The image filters did not handle older TIFF files that - lacked the samples-per-pixel and bits-per-pixel tags. - - Added new cupsGetJobs() and cupsFreeJobs() functions - to manage print jobs. - - cupsEncodeOptions() would encode names of 0 length and - cupsAddOption() and cupsParseOptions() would add names - of 0 length. - - The scheduler might block waiting for status messages - after starting a new print job. Thanks to Florent - Guiliani for finding this bug! - - -CHANGES IN CUPS V1.1.6-3 - - - The configure script put the JPEG library before the - TIFF library; this caused problems in some - configurations since the TIFF library also supports - JPEG compression of TIFF images. - - Updated the configure script and makefiles to handle - admin man pages with the "1m" extension (HP-UX, IRIX, - Solaris, Tru64) and in odd directories (IRIX) - - The updated cupsTempFile() function did not return - the filename when called with a filename buffer of - NULL (previously it used a static buffer.) - - FreeBSD uses /dev/unlptN, but NetBSD and OpenBSD use - /dev/ulptN. - - DeletePrinter() didn't remove the printer from any - classes it was a member of. - - DeletePrinterFromClass() didn't preserve the - implicit status of a class. - - DeletePrinterFromClasses() didn't remove printers - from implicit classes. - - StartJob() didn't send the job-sheets, job-priority, - and job-hold-until attributes to remote printers. - - LoadAllJobs() was looking for job-sheets-completed - instead of job-media-sheets-completed. This would - prevent accumulation of page data after a restart - of the scheduler. - - The pstops and imagetops filters now generate copies - using the appropriate method for a Level 1, 2, or 3 - printer since some Level 2/3 printers don't support - the /#copies variable anymore. - - The man page for cups-lpd did not mention the "-o" - option. - - The IPP backend didn't handle version-not-supported - errors and revert to IPP/1.0 (previously it only checked - for a bad-request error) - - Caldera fix: lpc now reports unimplemented commands as - unimplemented, not invalid. - - Caldera fix: lpq didn't recognize BSD lpq "-a" option. - - Caldera fix: lpr didn't recognize BSD lpr "-1", "-2", - "-3", "-4", "-q", or "-U" options. - - RedHat fixes: patches to GNU Ghostscript - - SuSE fix: temp file creation patch to GNU Ghostscript - (pstoraster). - - SuSE fix: remove cgi-bin/abort.c and cgi-bin/email.c, - which are not used. - - SuSE fix: missing NULL check in cgi_initialize_post(). - - SuSE fix: potential buffer overflows in - cgi_initialize_string(). - - SuSE fix: potential buffer overflows in - ippSetCGIVars() - - SuSE fix: more NULL checks in ppdOpen(); also make - sure that all memory is freed on error to avoid memory - leaks. - - SuSE fix: Exit from child if setgid() or setuid() - fails. - - SuSE fix: Added setgroups() calls after setgid() and - setuid() calls. - - SuSE fix: potential buffer overflows in httpEncode64() - calls. - - SuSE fix: potential buffer overflows in httpSeparate() - - SuSE fix: potential buffer overflows in ippWrite() for - bad input. - - SuSE fix: potential nul skip in ppd_decode() for - missing hex digits. - - -CHANGES IN CUPS V1.1.6-2 - - - Added changes to support NetBSD startup scripts. - - Added separate compiler options for pstoraster - (Ghostscript) to avoid compiler-induced errors - from Ghostscript's twisted code. - - The mime.types file contained syntax errors. - - Updated the *BSD USB device filenames to use - the /dev/unlptN files so that the USB device - is not reset prior to printing (causes print - corruption on many printers) - - Added new cupsTempFd() function to avoid serious - security bug in glibc fopen() function. The glibc - fopen() function unlinks a file before creating it, - which opens up possible symlink attacks. - - Now reject 0-length names in add-printer and add-class - requests. - - Fix for pstoraster when ZLIB is not available. - - cupsGetPPD() didn't reconnect when a HTTP connection - was lost. - - SuSE fix: httpConnect() didn't check that the - value from gethostbyname() was a valid IPv4 address. - - SuSE fix: httpConnect() didn't allow file descriptor 0 - to be used for a socket. - - SuSE fix: ippRead() didn't confirm that all values in - a set were numeric or string types. - - SuSE fix: lppasswd race condition fixes. - - SuSE fix: directive names could overflow buffer when - reading *.conf files. - - SuSE fix: HEAD requests for PPD files did not use the - same logic as GET requests. - - SuSE fix: possible buffer overflow when adding - /index.html to requested directory name. - - SuSE fix: possible buffer overflow when converting - IPP attributes to string options for filters. - - SuSE fix: creating file: device output with mode 0666 - instead of mode 0600. - - SuSE fix: creating job info files with mode 0640 - instead of 0600. - - SuSE fix: don't rely on snprintf() for including - system name in log filenames. - - SuSE fix: add bounds checking when copying quoted - and hex strings. - - -CHANGES IN CUPS V1.1.6-1 - - - Added configure check for getting the correct - strftime() format string; %c is not Y2k safe, - and %KC and NULL are not universally supported. - - -CHANGES IN CUPS V1.1.6 - - - Fixed another possible DoS attack in httpGets() - - Added check for "LANGUAGE = PCL" and "LANGUAGE = - POSTSCRIPT" in mime.types. - - Resolution options were not being passed into the - filter programs properly. - - The default compiler options for GCC no longer include - "-g3", which apparently is deprecated in newer - versions of GCC. - - CheckJobs() could cause cupsd to crash if a job is - cancelled in StartJob(). - - The printers.conf and classes.conf files are now - written with restricted permissions. - - The round-robin algorithm used by FindAvailablePrinter() - had problems; fixes contributed by Joel Fredrikson. - - If LoadAllJobs() is unable to determine the file type - of a print job, assume "application/vnd.cups-raw". - - The web interface now provides a job_printer_name - value for any corresponding job_printer_uri value. - - The cups-lpd mini-daemon now logs the client address - and hostname as well as all commands and errors in the - syslog file. - - The IPP backend now detects the supported file formats - and only specifies the document format if it is - supported. This makes IPP printing to network print - servers and cards more reliable without affecting the - capabilities of CUPS servers. - - The time_at_xyz attributes are now converted to human- - readable dates and times for the web interfaces. - - The HP and EPSON sample drivers now correctly catch - signals and eject the current page when a job is - cancelled. - - Fixed bug in CGI code - did not ignore control - characters (e.g. newlines) in form data. This caused - sporatic web interface problems. - - The file type logging code in the scheduler referenced - the optional document-format attribute; the new code - uses the resolved MIME type instead. - - The client.conf parsing code now removes trailing - whitespace. - - The MaxJobs directive was being treated as a boolean - instead of an integer. - - The scheduler would not timeout remote printers if - BrowseInterval was set to 0. - - The lpadmin command now supports setting of options - and user-level access control. - - Added "-E" option to all printing commands to force - encryption. - - The client code did not consume the response to the - OPTIONS request when switching to secure mode. - - The scheduler did not output a Content-Length field - when responding to an OPTIONS request. - - Added documentation on using cups-lpd with xinetd - to the man page. - - The socket backend now starts retries at 5 seconds and - increases the interval to 30 seconds. This should - provide faster printing when multiple jobs/files are - queued for a printer. - - The filters and backends no longer buffer output to - stderr. This should provide much more accurate status - reporting. - - -CHANGES IN CUPS V1.1.5-2 - - - Fixed configure check for OpenSSL to work with RSA - code. - - Added configure check for , and use this - check in backend/serial.c. - - Updated configure script handling of data, - configuration, and state directories to use datadir, - sysconfdir, and localstatedir variables. - - NetBSD uses different serial port filenames than - FreeBSD and OpenBSD. - - The pdftops filter didn't need some X-specific files. - - The scheduler makefile doesn't do a chown anymore when - installing (cupsd did this automatically on startup - anyways) - - -CHANGES IN CUPS V1.1.5-1 - - - There was a typo in the top-level Makefile - - The top-level Makefile did not install an init script - for run level 5. - - The configure script did not add the "crypto" library - when checking for the OpenSSL library. - - The OKIDATA PPD files were missing. - - The config.h.in file defined the wrong version number. - - The serial backend did not define "funky_hex" under *BSD. - - Updated the Visual C++ project files and some of the - CUPS API sources to compile under Windows again. - - -CHANGES IN CUPS V1.1.5 - - - Security updates - new default configuration does - not broadcast printer information and only allows - access from the local system. - - EXPERIMENTAL encryption support - CUPS now optionally - supports TLS/SSL encryption via the OpenSSL library. - - Documentation updates. - - Makefile/configure script updates. - - The RPM spec file didn't work out-of-the-box under - RedHat or Mandrake. - - Minor code cleanup to remove extraneous compiler - warnings. - - cupsTempFile() was using %p for the temporary - filename; this should have been %08x (just 8 digit - hex) - - Deleting a printer with active print jobs would still - crash the server. - - ippWrite() and ipp_write_file() didn't send the - correct value length for name-with-language and - text-with-language attributes. - - Updated IPP code to support copied strings (that - should not be freed); this provides slightly more - efficient IPP server performance. - - Updated PDF filter to Xpdf 0.91. - - httpGets() could go into an infinite loop if a line - longer than the input buffer size was sent by a - client. This could be used in a Denial-of-Service - attack. - - The lpstat and CUPS API functions now request only the - data required when getting the list of printer or - class information. This should improve performance - with large numbers of printers on slower machines. - - The scheduler was always enforcing the FilterLimit, - even if FilterLimit was set to 0. - - Updated the Linux USB backend to support Mandrake's - /dev/usb/usblp# filenames. - - The PRINTER and LPDEST environment variables did not - override the lpoptions default printer. - - The PPD read functions incorrectly included trailing - characters (usually whitespace) after quoted string - attributes. - - The multiple-document-handling attribute handling code - did not check for the correct value for collated - copies (separate-documents-uncollated-copies). - - The EPSON driver did not work with OKIDATA printers in - EPSON emulation mode (needed change-emulation command) - - The HP-GL/2 filter did not scale the plot properly in - scale mode 2. - - Added PPD files for 9-pin and 24-pin OKIDATA printers. - - The httpSeparate() function didn't handle passwords - that started with a number. - - ippDelete() could free the character set string - multiple times in name-with-language and - text-with-language attributes. - - The scheduler would access freed memory right after - freeing it (for debug messages); these parts of the - code have been reordered to avoid this situation - which was causing sporatic errors and crashes. - - The ppdClose() function didn't free all of the strings - in the ppd_file_t structure. - - The LoadAllJobs() function in the scheduler did not - close the spool directory. - - Changed all sprintf's that use string formats to - snprintf's, even if the destination buffer is - larger than the source string(s); this protects - against buffer overflows caused outside of CUPS... - - Changed all strcpy's to strncpy's between local and - global variables, even if the destination buffer is - larger than the source string; this protects - against buffer overflows caused outside of CUPS... - - The CUPS certificate functions didn't use the - CUPS_SERVERROOT environment variable when set. - - The directory services code was copying instead of - comparing the remote printer info, resulting in - unnecessary updates of the printer attributes for - remote printers. - - Added new mime.types rules to allow automatic raw - printing of PCL and ESC/P files; PJL headers are - parsed to differentiate between PostScript and - PCL job files. This should eliminate a lot of - the reports of SAMBA printing problems due to - the missing "-oraw" or "-l" options. - - The mimeLoadType() function didn't handle the - 3-argument contains() function. - - The LoadPPDs() function in the scheduler didn't - properly set the alloc_ppds variable or handle a PPD - database containing 0 printers. - - The scheduler FindAvailablePrinter() function didn't - use the same queuing logic as the CheckJobs() - function. This caused classes to stall if a remote - printer was always busy. - - Jobs are now assigned to printers in a class - round-robin style. This should prevent the first - server in the class from bearing the brunt of the - jobs. - - The scheduler's LoadAllJobs() function didn't always - restore remote printers for queued jobs on startup. - - The serial backend didn't support the higher baud - rates with the old termios interface. It now supports - 57600 and 115200 baud. - - The serial backend now supports different types of - flow control; previously it ignored the flow=XYZ - option in the device URI. - - The serial backend now supports DTR/DSR flow control, - which is popular on dot-matrix printers (access with - "flow=dtrdsr" in the device URI) - - Added new job-originating-host-name attribute for - jobs. The new attribute provides the hostname or - IP address of the machine that submitted the job. - - The set-job-attributes code no longer allows read-only - job attributes to be changed. - - Expanded the click area for the navigation bar in the - web interface. - - Updated the lp and cancel commands to support all of - the Solaris print options (some are simply ignored - since they do not map) - - Updated the scheduler to limit the number of file - descriptors to the maximum select() set size. This - was causing problems on Solaris systems where the - max FD count was increased beyond 1024. - - The scheduler's LoadDevices() function was getting - interrupted by the SIGCHLD signal handler; now ignore - child signals while loading devices. - - Added quota and allow/deny user support for printers - and classes. - - Removed black/CMY adjustment code from the PS and - image file RIPs; it was interfering with some CUPS - driver dithering code. - - The lpc program stopped listing the queue statuses - after the first active printer. - - The cups-lpd program used an output format that the - Solaris printing system did not understand. - - Updated the lpq program to use the Solaris format - except under Tru64 UNIX. - - Some DEC PPD files incorrectly use "Off" for the null - value in UI constraints. Added "Off" to the list of - accepted null values. - - Changed the *BSD define constants to __*BSD__ in all - of the backends. - - Added support for "lpstat printername", which is an - undocumented feature in Solaris. - - The HP-GL/2 filter now only sets the plot size if it - is set in the plot file. - - The lpmove command wasn't sending the requesting - user name, causing it to always fail. - - Updated the cupsTempFile() code to use GetTempPath() - under Windows. - - The cups-lpd mini-daemon didn't limit the number of - data files accepted, didn't use cupsTempFile(), - didn't handle control file job information in any - order, and didn't free job options after printing - a file. - - The scheduler copy_banner() function did not - explicitly set the owner and permissions of the banner - files, which could prevent the banner pages from - printing on some systems. - - The lpstat program wasn't listing remote classes. - - The scheduler did not verify that the printer-uri - attribute was specified in all requests that required - it. - - -CHANGES IN CUPS v1.1.4 - - - Makefile and configure script fixes. - - **** Changed the default Printcap setting **** to - /etc/printcap. There are just too many people asking - why application XYZ doesn't see their printers! - - The web admin interface now displays an error if it - can't get the list of printer drivers from cupsd. - - The IPP backend was putting the copies option before - the other job options were set. This caused the IPP - request to contain attribute groups in the wrong - order, which prevented remote printing. - - Added checks in scheduler to free memory used for - IPP requests and language information when closing - a client connection. - - Fixed the duplex option in the HP LaserJet driver. It - should now work with all LaserJet printers (and - compatibles) - - The add-printer web interface didn't initialize the - "old info" data pointer, which caused random crashes - on many OS's. - - Fixed many page sizes defined in the Level 1 - compatibility file "gs_statd.ps" to match reality. - - Fixed another bug in the setpagedevice "code" in - Ghostscript. It should now accept all standard - Adobe attributes on all platforms. - - Fixed pstoraster so that it reallocates memory for - color depth changes as well as size/resolution - changes. This removes an ordering constraint on - the color, page size, and resolution options in - PPD files. - - The IPP backend didn't use the job's character set - when the destination printer supported it. This - caused problems when printing text files to other - CUPS servers. - - Updated the logic used to determine when to rebuild - the PPD file database. The scheduler now checks the - dates and the number of PPD files (was just checking - the dates.) - - Updated the ippSetCGIVars() function (used by the - web interfaces) to only filter valid string values. - - The PostScript filter was scaling 2-up pages - incorrectly. This caused the edges of some pages to - be clipped. - - -CHANGES IN CUPS v1.1.3 - - - Makefile fixes. - - RPM spec file changes. - - Documentation updates. - - Enabled pstoraster debug messages for everything - (only logged when LogLevel set to "debug"...) - - Changed the Input/OutputAttributes fix in - pstoraster so that it works on all platforms. - - The HP-GL/2 filter didn't set the right green - color value in encoded polylines or text. - - Updated the "fitplot" code to handle plot sizes - specified as "PSwidth,length" and "PSlength,width". - - Updated the Linux parallel and USB backends to open - the device files prior to looking in /proc for - autoprobe info. This makes sure that loadable device - driver modules are in fact loaded... - - Added new FilterLimit directive to limit the number - of processing jobs/filters on a system. - - set-job-attributes didn't change the job-state to - held/pending when the job-hold-until attribute was - specified. - - set-job-attributes didn't save the new job attributes. - - Now change the "requesting-user-name" attribute in - requests from remote systems to "remroot" when an - unauthenticated "root" user is sent. This can be - changed using the new RemoteRoot directive in - cupsd.conf. - - The cancel-job, hold-job, release-job, and restart-job - operations didn't log the authenticated username. - - The cups-lpd mini-daemon now checks for a - document-format option before forcing raw mode with - filter mode 'l'. - - The cups-lpd mini-daemon now supports "-o" options - on the command-line (passed by inetd) to set global - defaults for all print queues. - - The pstops filter assumed that a file with a Trailer - comment would also have an EOF comment. - - Added new cupsSetPasswordCB(), cupsSetServer(), - cupsSetUser(), and ippSetPort() functions to better - support client applications (especially GUIs...) - - The CUPS-add-class and CUPS-add-printer operations - didn't reset the printer-name attribute on remote - print queues that had to be renamed when a local - printer was defined with the same name. - - The lpoptions command now supports a "-r" option to - remove options for a printer or instance. - - The lpadmin and admin.cgi programs no longer allow - class and printer names to begin with a number; this - caused the command-line utilities to become confused. - - The Linux USB backend now looks for both the parallel - and usblp driver names in the device list. - - Added a new FontPath directive to cupsd.conf, and also - a "--with-fontpath" option for the configure script to - specify alternate font paths for pstoraster. - - The CUPS-move-job operation didn't update the - job-printer-uri attribute. - - The scheduler only looked up printers and classes by - name in IPP requests, instead of using the full URI. - This caused problems with KUPS and friends with - remote printers. - - The scheduler now handles better localization of - hostnames (e.g. server is host.foo.com, remote is - host.subfoo.foo.com, localized is not host.subfoo...) - - The scheduler logging functions now use a common - log file checking/rotation function (courtesy of - Crutcher Dunnavant at Red Hat) - - The scheduler could accept more client connections - than it allocated for if more than one Port or Listen - line was present in cupsd.conf. - - Other minor scheduler performance tweeks. - - The lpq and lprm commands didn't support the default - printer set using lpoptions. - - The lpoptions command now supports a "-l" option to - list the printer-specific options and their current - settings. - - The web printer and class lists now show a link to the - default printer or class at the top of the page. - - The text filter now supports pretty printing of shell - and perl scripts as well as C/C++ source files. - - The top and bottom margins were reversed for landscape - text printing. - - The lpq and lprm commands didn't understand printer - instances. - - The scheduler only selected on the first 100 file - descriptors instead of the maximum file descriptor - limit. - - The scheduler client, listener, and mainline functions - now share code to disable and enable monitoring for - new client connections. - - The imagetoraster filter didn't support all of the - required pagedevice parameters. - - The serial backend now checks for 100 serial ports - under Linux. - - The scheduler used sscanf() to pull out the remote - printer location, description, and make/model strings, - but if any of these options was empty then sscanf() - would stop processing. - - Added "debug2" log level to provide a little less - verbose debugging information at the "debug" level. - - The scheduler would crash if you stopped a printer - that was currently printing a job. - - The scheduler incorrectly allowed jobs in the cancelled, - aborted, or completed state to be cancelled. - - The image filters did not load TIFF images properly - for bottom-to-top and right-to-left orientations. - - Added new cupsEncodeOptions() function to encode - CUPS options as IPP job attributes. - - The IPP backend, LPD mini-daemon, client commands, - and CUPS API did not properly encode multiple - option values separated by commas. - - Added new scheduler malloc logging in debug mode - (provides summary of total arena size, allocated, - and free bytes once a minute) - - The EPM-based distributions didn't install the - correct symlinks for a few man pages. - - Fixed a memory leak in the scheduler - wasn't - freeing old filters when deleting or renaming - printers. - - The scheduler now queries the primary IP address - for the name of the server and maps any incoming - requests from that address to the server name. - This fixes web admin mapping problems from - server.domain.com to localhost. - - The web printer modify interface now remembers - the previous device and driver settings (except - for serial ports.) - - The job-k-octets attribute is now stored as part of - the job attributes; this preserves the information - after a job is completed when job file history is - turned off. - - Dropped option sub-group parsing code for the moment, - since many Xerox PPD files abuse this feature in PPD - files and don't follow the hierarchy rules. - - Added new wrapper code around options so that duplex - options for some HP printers don't prevent prints. - - Added support for Digital UNIX/Tru64 UNIX/OSF/1 format - for "lpstat -v" output. - - Now show the URI for remote printers instead of - /dev/null in "lpstat -v" output. - - Creating classes and adding printers to a class with - the lpadmin command didn't work. - - The banner pages and test page should now format - correctly in both portrait and landscape orientations. - - Updated banner page substitution so that { can appear - by itself without quoting. - - -CHANGES IN CUPS v1.1.2 - - - Makefile/configure fixes - - RPM spec file and EPM list file fixes - - The cupsTempFile() function now uses a different - algorithm for generating temp files and "reserves" - them to avoid possible security exploitation. - - Now use /dev/random (if available) to seed the random - number generator for certificates. - - The /var/spool/cups and /var/spool/cups/tmp directories - were incorrectly owned by root; they are now owned by - the filter user, typically "lp". - - The scheduler now resets the permissions on the spool - and temp directories as needed to match the filter - user. - - Now expose ppdCollect() as an externally callable - function. - - The image filters now support filtering from the - standard input. - - The imagetoraster filter now collects all printer - options and job patch files and applies them to the - page header as needed. - - Added format and banner options to LPD backend. - - The send-document operation didn't start a job - immediately when last-document was true. - - The set-job-attributes operation didn't correctly - replace the current job-hold-until value. - - Removed the option wrapper code from ppdEmit() and - friends since it caused problems with Ghostscript - and many PS printers. - - Was setting TZ environment variable twice for job - filters. - - Added syslog logging in cups-lpd to aide in - debugging problems. - - The HP-UX parallel port backend did not list the - available parallel ports on some systems (printf - calling problem...) - - The lp and lpr commands overrode user options if - -d/-P were specified after -o. - - The scheduler would crash with a */* filter. - - Added support for a "default" filter for unknown file - types. The example provided in the mime.types and - mime.convs file prints unknown files as if "-oraw" was - specified for the job. This functionality is disabled - by default. - - The "compatibility" mode fix for older backends did not - work for smbspool. Added a workaround for it. - - The HP-GL/2 filter didn't perform the right pen scaling - with some files and the "fitplot" option. - - New Software Performance Specification document that - describes the memory, disk, and CPU usage of all the - CUPS software. - - -CHANGES IN CUPS v1.1.1 - - - The pstoraster Makefile still referenced one of the - old PDF filter files. - - The filter Makefile used INSTALL_DATA instead of - INSTALL_LIB to install the CUPS image library. - - The administration CGI didn't work properly with - network devices. - - The BrowseACL variable was not updated after the - cupsd.conf file was loaded. - - The lpd mini-daemon didn't support printer instances. - - Now use a default umask of 077 for child processes. - - Now put temp files in /var/spool/cups/tmp for child - processes and the root user, unless TMPDIR or TempDir - is defined otherwise. - - cupsGetPPD() no longer uses easy-to-guess filenames. - - The CUPS-Delete-Class and CUPS-Delete-Printer - operations now save classes.conf file as needed. - - The lppasswd command wouldn't add a user. - - The ppdOpen() function could cause a segfault if a - 0-length PPD file was read. - - The image filters were not handling images with - different X and Y resolutions properly. - - The imagetoraster filter defaulted to RGB output - instead of black output like pstoraster. - - The pstops filter didn't handle binary data properly. - - The pstops filter didn't handle copies properly for - PS files lacking DSC comments. - - The pstops filter now appends %%EOF to the end of - documents if they don't have it. - - The cupsGetPPD() function didn't work with remote - printers lacking the @server in the name. - - The configure script didn't work right when only - --prefix was specified. - - The ppdEmit() code now wraps all printer commands so - that buggy PostScript printers will still print a file - after receiving an option that isn't available. - - Fixed the DeskJet margin bug, and disabled 600dpi - color mode until it can be fixed. - - The cupsAddDest() function didn't sort instances - correctly in all cases. - - The time-at-xyz attributes now expand to the date and - time in banner files. - - -CHANGES IN CUPS v1.1 - - - Documentation updates. - - Configuration script updates. - - Didn't map charset and language value strings to lowercase - and _ to - as required by SLP and IPP. - - ppdLoadXYZ() didn't add the list of available fonts to the - ppd_file_t structure. - - The text filter common code was freeing the PPD file data - before it was used. - - The text filter now embeds missing fonts. - - The CGI interface now maps local access to the server to - the localhost address. - - The HP-GL/2 filter didn't use the specified (or default) - color ranges, resulting in strange colors. - - The HP-GL/2 filter didn't default to no input window, which - caused unnecessary clipping of plots. - - Integrated Xpdf's pdftops filter into CUPS, which is a - lightweight and reliable replacement for Ghostscript's - PDF support. - - Removed all PDF support from Ghostscript. - - Updated HP driver to set top margin; this seems to fix - the offset problem seen on HP DeskJet printers. - - Fixed dependencies on the ZLIB and JPEG libraries in - pstoraster. - - The lpr command wasn't using the lpoptions defined by - the user. - - The lpr command would segfault if the CUPS server was - not running. - - The top-level makefile was not installing the CUPS - initialization script. It now does so if it sees there - is an init.d directory in /sbin, /etc/rc.d, or /etc. - - "lpstat -v all" didn't work. - - pstoraster would crash on some platforms doing the - setpagedevice operator. - - The web administration interface now allows you to set - the default banner pages. - - Images can now be positioned on the page using the new - "position" option. - - The AccessLog, ErrorLog, and PageLog directives now - support "%s" to insert the server name. - - Added a new BrowseShortNames directive to allow for - short remote printer names ("printer" instead of - "printer@server") when possible. - - The scheduler could crash if given an invalid PPD file - with no PageSize attributes. - - Updated the serial, parallel, and usb backends to do - multiple writes and ignore ioctl() errors as needed; - this should fix problems with serial printing on old - serial drivers and with the UltraSPARC parallel port - driver under Solaris 2.7. - - Now propagate LD_LIBRARY_PATH to child processes from - cupsd. - - New DataDir directive for installing in alternate - locations. - - New CUPS_SERVERROOT and CUPS_DATADIR environment - variables to specify installation directories as - needed. - - Queued remote jobs recreate remote printers as needed - when the scheduler is started. - - Deleting a printer also purges all jobs on that - printer. - - Old job and control files that don't belong to a - printer are automatically deleted. - - Wasn't updating time-at-processing and - time-at-completed attributes in job. - - Didn't send required multiple-operation-time-out - attribute in response to a get-printer-attributes - request. - - cups-lpd now supports options set with lpoptions. - - The job-hold-until attribute is now provided with all - jobs. For jobs that are not currently held the value - is "no-hold". - - The scheduler was not sending "unknown" values in IPP - responses. - - The lpoptions command now accumulates options from - previous runs rather than replacing all options for a - printer. - - The IPP backend now switches to IPP/1.0 if a 1.1 - request fails. - - The lpadmin and admin.cgi programs now validate new - printer and class names. - - The access_log file now includes the number of IPP bytes - received in a POST request. - - -CHANGES IN CUPS v1.1b5 - - - Documentation updates. - - The pstoraster filter didn't compile without the JPEG library. - - The cupsd server didn't support the HTTP OPTIONS request - method. - - Dropped the "CLOSE" method supported by the cupsd server. - (not defined in HTTP specification) - - Makefile/configure script fixes. - - Missing the job-restart template. - - Added IPP test suite for testing. - - Missing IPP documentation from binary distributions. - - Fixed multiple-document handling code when last-document - not specified. - - Added more checks to IPP requests to prevent bad requests - from getting through. - - Not all of the Ghostscript error output was being sent to - stderr. - - The PostScript filter now added PJL commands to set the - job name and display string, if supported. - - The scheduler would crash if the browse socket could not - be bound. Now disables browsing if port 631 (reserved for - IPP) is being used by a misbehaving daemon. - - The USB backend now looks for the older Linux 2.2.x USB - printer device filenames as well as the newer ones. - - The IPP backend now uses the UTF-8 charset exclusively, - since apparently only CUPS handles more than US-ASCII and - UTF-8... - - Wasn't quoting ( in PostScript banners... - - Send-document requests with no document-format attribute - could cause cupsd to crash. - - Old jobs in the spool directory might cause cupsd to - crash. - - CUPS now supports all of the recommended job-hold-until - keywords as well as name values of the form "HH:MM" and - "HH:MM:SS". - - Added placeholder pointer for TLS encryption to the HTTP - connection structure. - - Fixed the "fast poll" bug reported by DISA - the - status pipe wasn't being closed for multi-file jobs. - - Revamped put_params code in pstoraster to fix bitmap - allocation bug with FrameMaker output. - - Ripped out filename, etc. code from pstoraster as it - is a potential security hole. - - Added support for RIP_CACHE environment variable in the - new pstoraster. - - Fixed USB device filenames for Linux; now support new - pre-2.4 devices (/dev/usb/lp#) and 2.2 devices - (/dev/usblp#) - - Fixed accept-jobs crash with classes. - - Didn't include dot-matrix EPSON drivers in previous - release. - - -CHANGES IN CUPS v1.1b4 - - - Documentation updates. - - Many makefile and configuration script fixes (should - now compile better under *BSD.) - - The MediaPosition attribute was being mishandled by - GhostScript, causing the RIP to fail whenever a paper - tray was selected. - - The scheduler now logs the final line of log information - from a filter, even if it doesn't end with a newline; this - primarily affects GhostScript error output. - - The scheduler was saving implicit classes, so after a few - restarts you'll end up with AnyPrinter, AnyAnyPrinter, etc. - - The JPEG autodetection didn't work with some JPEG files that - came from digital cameras (JPEG but not JFIF); the new - magic types should work with all images that the JPEG library - can handle. - - Fixed a bug in the new contains() MIME type rule that could - cause cupsd to crash. - - Switched to using strtol() in the MIME type code so that you - can use hex, octal, or decimal constants as desired in the - mime.types file. - - Banner files are now treated as templates, allowing any type - of file to be used as a banner. - - Added a 30-second timeout to backend device reports so that a - hung backend will not prevent the scheduler from starting. - - Backends are once again terminated when jobs are stopped; the - CUPS-supplied backends will stay alive until the downstream - filters have had a chance to clear out old page data. - - The charset lookup in the CUPS localization support was wrong - (iso8859-x instead of iso-8859-x) - - Changed the "cpNNNN" code page files to "windows-NNNN" to match - the IANA registrations. - - New PostScript banner pages. - - Added Windows BMP and Alias PIX image file support to the image - filter. - - The PNG reading coded didn't free all of its buffers. - - Added Digest authentication support to the client and server - code. - - Added Solaris options to System V commands. - - Now support the output-bin job template attribute. - - Now log the job-billing attribute in the page_log file, and - keep track of the total number of pages in the - job-media-sheets-completed attribute. - - The penwidth option is now in micrometers to support more - accurate width specification. - - The image filters now support interlaced and transparent PNG - files. - - Didn't handle Keep-Alive for HTTP/1.0 clients. - - The BrowsePoll support didn't handle when BrowseInterval - was set to 0 (now uses 30 seconds if BrowseInterval is 0) - - The DeskJet driver now supports 600 DPI color for printers - that support it. - - New lpinfo and lpmove commands. - - The lpq command now supports the Digital UNIX output format. - - The LPD mini-daemon now supports all required LPD operations. - - Implemented timeouts for multi-file documents. - - New cupsPrintFiles() function in the CUPS API library to - print multiple files using create-job and send-document - requests (1 job ID for multiple files) - - The lp command now sends multiple files as a single job, - matching the behavior of the System V command. - - The "cancel -a" command now purges job history files. - - -CHANGES IN CUPS v1.1b3 - - - Documentation updates. - - The startup script redirected stderr before stdout, - which caused problems with some versions of Bourne - shell and Bash. - - Fixed a bug in the scheduler's PPD language reading - code. - - Fixed a bug in the scheduler's check for the - manufacturer in the PPD. - - The pstoraster filter didn't allow some input and - output attributes to be set. - - Added banner page support. - - Added missing PAM configuration file. - - Configuration script fixes for Linux and *BSD. - - The log file code was using the wrong sign for the - timezone offset. - - The default printcap file is now empty (no printcap - file is generated). - - The scheduler did not start jobs destined for remote - printers when they became available. - - The scheduler now sends jobs to remote printers - immediately. (when sending jobs to a class, the remote - printer is only used when it becomes available) - - The scheduler now supports printing of banner pages - via the job-sheets attribute (banner files go in - /usr/share/cups/banners) - - The cupsd process now forks itself into the background - (override with -f) - - Added several *BSD enhancements. - - Added UNSUPPORTED libtool option to configuration - script to allow the use of libtool. Note that this is - UNSUPPORTED by us, but added by request of the *BSD - folks. - - The parallel, serial, and usb backends now retry the - opening of their ports. This allows multiple print - queues to be associated with a single physical port, - and will allow CUPS to support several types of - parallel port auto-switches in the near future. - - Set-Job-Attributes now supports adding, changing, and - deleting job template attributes, and no longer allows - job-printer-uri to be set (see CUPS-Move-Job) - - Added CUPS-Move-Job operation to support moving of jobs. - - The CGI template functionality now supports multiple - languages (still only have templates for English) - - The CUPS-Get-Printers and CUPS-Get-Classes operations - now support filtering as defined in the IDD. - - The Get-Jobs, CUPS-Get-Printers, and CUPS-Get-Classes - operations no longer limit themselves to 1000 jobs, - printers, or classes (believe it or not, this is - needed for some sites) - - The web interfaces now support language-specific - templates. - - The web admin interface now supports class management. - - The web admin interface now shows a list of - manufacturers before selecting the PPD/driver for a - specific printer. - - The web admin interface now supports configuration of - the default printer options in the PPD file. - - The web interface now uses printer/class - authentication for the test page instead of admin - authentication. - - Updated the RPM spec file for the current release. - - Updated language support for Windows code pages. - - 8-bit character set files can now use multiple fonts - (needed for Arabic, Greek, Hebrew, etc.) - - Added basic right-to-left text support in the text - filter. - - The POSIX locale now uses ISO-8859-1 instead of - US-ASCII. - - Fixed PDF printing problems. - - Fixed PostScript RIP page device dictionary elements - that weren't getting passed in cups_get_params(). - - Added a new "contains" rule for the magic file typing. - - The "printable" rule now accepts characters from 128 to 255 - (needed for Microsoft character sets) - - Added support for ~/.cupsrc as well as /etc/cups/client.conf - so that the default server can be configured on a per-user - basis without environment variables. - - Added LPD mini-daemon to support incoming LPD jobs. - - -CHANGES IN CUPS v1.1b2 - - - Documentation updates. - - The lp command didn't always load the user-defined - destinations, preventing it from seeing the default - printer. - - Many configure script and makefile fixes. - - The Microsoft code page files were missing from the - distribution. - - Added a workaround for the HP IPP client (which is sending - an invalid printer-uri in requests) - - Fixed the encoding of text-with-language and name-with-language - to match the IPP spec. - - Added support for unknown value tags in the IPP routines - (previously they would be ignored) - - Integrated GNU GhostScript 5.50 into the pstoraster filter. - - Client hostname resolution was broken on little-endian - machines. - - Now look at client.conf file for client's default server - and printer. - - The cupsServer() function did not close the client.conf file - if it contained a ServerName directive. - - Added BrowseAllow, BrowseDeny, BrowseOrder, BrowsePoll, and - BrowseRelay directives. - - BrowseInterval 0 disables advertising of local printers, but - still receives information on remote printers. - - New browse polling daemon (for polling servers on different - networks) - - New PPD cache file for faster startup times with large numbers - of PPD files. - - The Host: field was incorrectly required for HTTP/1.0 clients. - - New set-job-attributes operation now supported. - - The mime_load_types() and mime_load_convs() functions did not - close their input files. - - -CHANGES IN CUPS v1.1b1 - - - NEW web-based administration interface. - - NEW EPSON printer drivers. - - NEW user-defined printers and options. - - NEW persistent jobs and job history - - NEW IPP/1.1 support - - NEW template-based web interfaces. - - NEW CUPS-get-devices and CUPS-get-ppds operations. - - NEW support for create-job and send-file operations. - - NEW certificate-based authentication for local - administration. - - NEW USB backend. - - The lpr command now produces human-readable error messages. - - The lpq command now produces BSD standard format output - instead of OSF/1 output. This should resolve the SAMBA - print queue problems that have been reported. - - The IPP backend did not always detect when the "raw" option - was being used. - - The "lpstat -p" command would stop after the first active - printer. - - The "lpstat -v" command would stop before the first remote - printer. diff --git a/CHANGES-1.2.txt b/CHANGES-1.2.txt deleted file mode 100644 index 7b0b1f2..0000000 --- a/CHANGES-1.2.txt +++ /dev/null @@ -1,1261 +0,0 @@ -CHANGES-1.2.txt ---------------- - -CHANGES IN CUPS V1.2.12 - - - The PHP cups_print_file() function crashed if the options - array contained non-string option values (STR #2430) - - The image/tiff file matching rule incorrectly identified - some text files as TIFF files (STR #2431) - - The filter(7) man page incorrectly documented the - "PAGE: total #-pages" message (STR #2427) - - PCL text files were mis-identified as HP-GL/2 and - caused the HP-GL/2 filter to hang (STR #2423) - - When printing to a queue with user ACLs, the scheduler - incorrectly returned a quota error instead of a "not - allowed to print" error (STR #2409) - - cupsaddsmb could get in a loop if no printer drivers - were installed (STR #2407) - - cupsRasterReadHeader() did not byte-swap the header - properly when compiled with certain versions of GCC. - - The IPP backend did not send the document-format - attribute for filtered jobs (STR #2411) - - Some PPD files could cause a crash in ppdOpen2 (STR - #2408) - - The web admin interface incorrectly handled the "share - printers" and "show remote printers" settings (STR - #2393) - - The scheduler's log messages about AuthClass and - AuthGroupName advised using a replacement directive but - had the wrong syntax (STR #2400) - - Updated the PostScript/PJL and HP-GL/2 MIME rules to - look in the first 4k of the file, not just the first 1k - (STR #2386) - - Updated the Italian localization (STR #2382) - - -CHANGES IN CUPS V1.2.11 - - - Fixed the "relaying from" log message (STR #2376) - - Updated the launchd support on Mac OS X to better - support reconfiguration. - - "make distclean" didn't remove all generated files - (STR #2366) - - Fixed a bug in the advertisement of classes (STR - #2373) - - The IPP backend now stays running until the job is - actually printed by the remote server; previously - it would stop monitoring the job if it was held or - temporarily stopped (STR #2352) - - PDF files were not always printed using the correct - orientation (STR #2348) - - The scheduler could crash if you specified a bad file: - URI for a printer (STR #2351) - - The Renew-Subscription operation now returns the - notify-lease-duration value that was used (STR #2346) - - The IPP backend sent job options to IPP printers, - however some printers tried to override the options - embedded in the PS/PCL stream with those job options - (STR #2349) - - ppdLocalize() now also tries a country-specific - localization for when localizing to a generic locale - name. - - The cupstestppd program now allows for partial - localizations to reduce the size of universal PPD - files. - - Chinese PPD files were incorrectly tagged with the - "cn" locale (should have been "zh") - - The backends now manage the printer-state-reasons - attribute more accurately (STR #2345) - - Java, PHP, Perl, and Python scripts did not work - properly (STR #2342) - - The scheduler would take forever to start if the - maximum number of file descriptors was set to - "unlimited" (STR #2329) - - The page-ranges option was incorrectly applied to the - banner pages (STR #2336) - - Fixed some GCC compile warnings (STR #2340) - - The DBUS notification code was broken for older - versions of DBUS (STR #2327) - - The IPv6 code did not compile on HP-UX 11.23 (STR - #2331) - - PPD constraints did not work properly with custom - options. - - Regular PPD options with the name "CustomFoo" did - not work. - - The USB backend did not work on NetBSD (STR #2324) - - The printer-state-reasons attribute was incorrectly - cleared after a job completed (STR #2323) - - The scheduler did not set the printer operation policy - on startup, only on soft reload (STR #2319) - - The AP_FIRSTPAGE_InputSlot option did not clear any - ManualFeed setting that was made, which caused problems - with some PPD files (STR #2318) - - cupsDoFileRequest() and cupsDoRequest() did not abort - when getting an error in the response (STR #2315) - - The scheduler did not schedule jobs properly to remote - or nested classes (STR #2317) - - Updated the mime.types and mime.convs headers to warn - that the files are overwritten when CUPS is installed. - Local changes should go in local.types or local.convs, - respectively (STR #2310) - - The scheduler could get in an infinite loop if a - printer in an implicit class disappeared (STR #2311) - - The pstops filter did not handle %%EndFeature comments - properly (STR #2306) - - Fixed a problem with the Polish web page printer icons - (STR #2305) - - ppdLocalize() now also localizes the cupsICCProfile - attributes. - - The scheduler still had a reference to the incorrect - "notify-recipient" attribute (STR #2307) - - The "make check" and "make test" subscription tests did - not set the locale (STR #2307) - - The "make check" and "make test" subscription tests - incorrectly used the notify-recipient attribute instead - of notify-recipient-uri (STR #2307) - - cupsRasterInterpretPPD() incorrectly limited the - cupsBorderlessScalingFactor when specified in the - job options. - - -CHANGES IN CUPS V1.2.10 - - - ppdLocalize() now supports localizing for Japanese - using the "jp" locale name used by the ppdmerge - program from the CUPS DDK 1.1.0 (STR #2301) - - _cupsAdminSetServerSettings() did not support changing - of top-level directives as designed. - - The init script path check was broken. - - CUPS incorrectly used the attribute "notify-recipient" - instead of "notify-recicpient-uri" in several places - (STR #2297) - - Fixed a configure script bug on MirBSD (STR #2294) - - The pdftops filter did not limit the amount of recursion - of page sets (STR #2293) - - Custom page sizes with fractional point sizes did not - work (STR #2296) - - The lpoptions command would crash when adding or removing - options on a system with no printers (STR #2295) - - -CHANGES IN CUPS V1.2.9 - - - The scheduler did not use the default job-sheets - (banners) for implicit classes (STR #2284) - - The scheduler could crash when listing complete jobs - that had been unloaded from memory (STR #2288) - - The French localization was doubled up (STR #2287) - - Build system fixes for several platforms (STR #2260, - STR #2275) - - The scheduler's openssl certificate generation code was - broken on some platforms (STR #2282) - - The scheduler's log rotation check for devices was - broken (STR #2278) - - The LPD mini-daemon did not handle the document-format - option correctly (STR #2266) - - The pdftops filter ignored the "match" size option in the - pdftops.conf file (STR #2285) - - cupstestppd now validates UTF-8 text strings in - globalized PPD files (STR #2283) - - The outputorder=reverse option did not work with all - printers (STR #2279) - - Classes containing other classes did not always work - (STR #2255) - - Printer location and description information was lost - if the corresponding string contained the "#" character - (STR #2254) - - cupsRemoveOption() did not work properly (STR #2264) - - The USB backend did not work with some USB to parallel - cables on Mac OS X. - - The test page did not print the rulers properly on - large media sizes (STR #2252) - - The text filter could crash when pretty printing certain - types of files (STR #2158) - - -CHANGES IN CUPS V1.2.8 - - - Documentation fixes (STR #2141, STR #2157) - - The HTTP upgrade redirection used by the scheduler did - not work with Internet Explorer (STR #2235) - - Members of a class with Unicode names did not appear - correctly in the web interface (STR #2154) - - Changing the "Save debugging information" setting in - the web interface no longer affects the other server - settings (STR #1993) - - The scheduler did not choose SSL certificates correctly - on Mac OS X (STR #2225) - - The scheduler could get in an infinite loop when - printing to a remote class (STR #2228) - - The jobs web page did not have separating space after - the number of pages column (STR #2230) - - Added French localization (STR #2221) - - Updated Spanish localization (STR #2223) - - Updated Japanese localization (STR #2216) - - cupsBorderlessScalingFacter was limited to a range of - 0.9 to 1.1, but some printers need larger values (STR - #2222) - - Landscape printing of PDF files did not always work - (STR #2149) - - Fixed slow USB printing on Minolta printers (STR #2104, - STR #2219) - - The ZPL label printer driver could produce stretched - output (PR #6448) - - The IPP backend now clears the printer-state-message - when there are no outstanding errors or warnings (STR - #2126) - - The CUPS Java scripting support did not work with - recent versions of Java due to the use of Sun's private - Base64 class (STR #2152) - - The scheduler did not pass HTTP GET form variables to - custom CGI programs (STR #2173) - - The lpoptions command now displays the reason why a PPD - file cannot be found (STR #2184) - - The scheduler did not accept "none" as a browse - protocol name (STR #2200) - - The scheduler still loaded the remote printer cache, - even when browsing was disabled (STR #2198) - - The SNMP backend now shows OfficeJet printers with the - "HP" manufacturer prefix (STR #2151) - - Web interface HTML cleanup (STR #2153) - - The parallel backend consumed 100% CPU on FreeBSD due - to an apparently common parallel port driver bug (STR - #2161) - - ippReadIO() incorrectly returned IPP_IDLE when the - initial IPP message header could not be read (STR - #2179) - - cupsRasterInterpretPPD() did not support custom options - (STR #1960) - - Collated output produced by the PostScript filter could - lose some options (STR #2137) - - job-hold-until with time values for the next day would - be held for 60 days (STR #2144) - - Some types of Sun raster files did not print correctly - (STR #2107) - - Raw PBM files did not print correctly (STR #2106) - - The SNMP backend no longer uses IPP with HP printers, - as some recent firmware versions appear to not work - (STR #2055) - - cupsMarkOptions() did not handle the - multiple-document-handling option (STR #2135) - - lpstat did not show the local job ID of active printers - (STR #2125) - - The backends incorrectly used STATUS: - media-tray-empty-error messages for out-of-paper - conditions (STR #2123, STR #2124) - - cupsGetPPD2() returned the wrong error when the PPD - file did not exist (STR #2122) - - cupsDoAuthentication() did not translate the password - prompt (STR #2121) - - httpGetLength2() did not handle error messages without - content correctly (STR #2133) - - Added support for 32/64-bit libraries on HP-UX Itanium - systems (STR #2115) - - Fixed a configure script problem with the 32/64-bit - library support (STR #2114) - - The PostScript filter did not properly output document - setup commands for reversed output (STR #2111) - - The scheduler did not parse IPv6 netmasks properly (STR - #2117) - - -CHANGES IN CUPS V1.2.7 - - - Documentation updates (STR #2089) - - Added an Italian translation (STR #2105) - - The PostScript filter now rotates the bounding box - values as needed (STR #2079) - - The scheduler no longer loads the remote printer cache - when browsing is disabled (STR #2084) - - The scheduler no longer writes a new launchd - configuration file if it doesn't have to (STR #2083) - - Updated the USB and PAP backends for Mac OS X (STR - #2086) - - The scheduler now picks up on changes to IPv6 and DNS - configuration on Mac OS X (STR #2085) - - The lpstat program could still hang (STR #2098) - - Fixed an inefficiency in the SNMP IPP detection code - (STR #2100) - - The SSL negotiation code did not implement short - timeouts (STR #2091) - - -CHANGES IN CUPS V1.2.6 - - - The web interface was not localized on Mac OS X (STR - #2075) - - "lpc status" did not show the number of queued jobs for - disabled queues (STR #2069) - - The lpstat program could hang (STR #2073) - - The serial backend did not support the new USB serial - filenames on Linux (STR #2061) - - The parallel backend did not support bidirectional I/O - properly (STR #2056) - - The network backends now log the numeric address that - is being used (STR #2046) - - Fixed a compile error when using libpaper. - - Fixed a compile error when compiling on Solaris with - threading enabled (STR #2049, STR #2050) - - Missing printer-state-changed event for - printer-state-message updates (STR #2047) - - -CHANGES IN CUPS V1.2.5 - - - Documentation updates (STR #2038) - - The SNMP backend no longer uses IPP for Epson printers - (STR #2028) - - Updated the configure script for Tru64 UNIX 5.1 (STR - #2033) - - Tru64 5.1B's getaddrinfo() and getnameinfo() functions - leak file descriptors (STR #2034) - - cupsAddDest() didn't add the parent destination's - options and attributes. - - ppdConflicts() did not handle custom option - constraints. - - Raw printing of gzip'd files did not work (STR #2009) - - The scheduler no longer preserves default option - choices when the new PPD no longer provides the old - default choice (STR #1929) - - The Linux SCSI backend is now only built if the SCSI - development headers are installed. - - USB printing to Minolta printers did not work (STR - #2019) - - Windows clients could not monitor the queue status (STR - #2006) - - The scheduler didn't log the operation name in the - access_log file for Create-Job and Print-Job requests. - - The PostScript filter now separates collated copies - with any required JCL commands so that JCL-based - finishing options act on the individual copies and not - all of the copies as a single document. - - The PostScript filter now disables duplex printing when - printing a 1-page document. - - cups-lpd didn't pass the correct - job-originating-host-name value (STR #2023) - - Fixed some speling errors in the German message catalog - (STR #2012) - - cupstestppd did not catch PPD files with bad - UIConstraints values (STR #2016) - - The USB backend did not work with the current udev- - created printers if the first printer was disconnected - (STR #2017) - - Mirrored and rotated printing did not work with some - documents (STR #2004) - - 2-sided printing with banners did not work properly on - some printers (STR #2018) - - Updated the raw type rule to handle PJL within the - first 4k of a print job (STR #1969) - - Added an Estonian translation (STR #1957) - - Clarified the documentation for the cupsd.conf @LOCAL - and @IF(name) allow/deny functionality (STR #1992) - - The PostScript filters did not escape the Title and For - comments in the print job header (STR #1988) - - The scheduler would use 100% CPU if browsing was - disabled and the cupsd.conf file contained BrowsePoll - lines (STR #1994) - - The cupsDirRead() function did not work properly on - non-POSIX-compliant systems (STR #2001) - - The cupsFile functions didn't handle read/write errors - properly (STR #1996) - - The DBUS support now works with older versions of the - DBUS library. - - -CHANGES IN CUPS V1.2.4 - - - The --with-printcap configure option did not work (STR - #1984) - - The character set reported by cupsLangGet() did not - always reflect the default character set of a given - locale (STR #1983) - - Older Lexmark and Tektronix printers did not work with - IPP (STR #1980) - - Failsafe printing did not work (PR #6328) - - Some web interface redirects did not work (STR #1978) - - The web interface change settings button could - introduce a "Port 0" line in cupsd.conf if there was no - loopback connection available (STR #1979) - - The web interface change settings and edit - configuration file buttons would truncate the - cupsd.conf file (STR #1976) - - The German web interface used the wrong printer icon - images (STR #1973) - - The "All Documents" link in the on-line help was - missing a trailing slash (STR #1971) - - The Polish web interface translation used the wrong - URLs for the job history (STR #1963) - - The "reprint job" button did not work (STR #1956) - - The scheduler did not always report printer or job - events properly (STR #1955) - - The scheduler always stopped the queue on error, - regardless of the exit code, if the error policy was - set to "stop-printer" (STR #1959) - - ppdEmitJCL() included UTF-8 characters in the JCL job - name, which caused problems on some printers (STR - #1959) - - Fixed a buffering problem that cause high CPU usage - (STR #1968) - - The command-line applications did not convert - command-line strings to UTF-8 as needed (STR #1958) - - cupsDirRead() incorrectly aborted when reading a - symbolic link that pointed to a file/directory that did - not exist (STR #1953) - - The cupsInterpretRasterPPD() function did not handle - custom page sizes properly. - - -CHANGES IN CUPS V1.2.3 - - - The scheduler did not send job-state or - job-config-changed events when a job was held, - released, or changed (STR #1947) - - The scheduler now aborts if the configuration file and - directory checks fail (STR #1941) - - Fixed a problem with ippPort() not using the port - number that was set via the client.conf file or - CUPS_SERVER environment variable (STR #1945) - - HTTP headers were not buffered (STR #1899) - - Some IPP printers (HP) did not like UTF-8 job names - (STR #1837) - - The CUPS desktop icon is now localized for Polish (STR - #1920) - - Printer options were not always honored when printing - from Windows clients (STR #1839) - - The openssl command would lock up the scheduler when - generating an encryption certificate on some platforms - due to a lack of entropy for the random number - generator (STR #1876) - - The web admin page did not recognize that "Listen 631" - enabled remote access (STR #1908) - - The web admin page did not check whether changes were - made to the Basic Server Settings check boxes (STR - #1908) - - The IPP backend could generate N*N copies in certain - edge cases. - - The scheduler did not restore remote printers properly - when BrowseShortNames was enabled (STR #1893) - - Polling did not handle changes to the network - environment on Mac OS X (STR #1896) - - The "make test" subscription tests used invalid - notify-recipient-uri values (STR #1910) - - Printers could be left in an undefined state on system - sleep (STR #1905) - - The Berkeley and System V commands did not always use - the expected character set (STR #1915) - - Remote printing fixes (STR #1881) - - The cupstestppd utility did not validate translation - strings for custom options properly. - - Multi-language PPD files were not properly localized in - the web interface (STR #1913) - - The admin page's simple settings options did not check - for local domain socket or IPv6 addresses and did not - use "localhost" as the listen address. - - An empty BrowseProtocols, BrowseLocalProtocols, or - BrowseRemoteProtocols line would crash the scheduler - instead of disabling the corresponding browsing options. - - The scheduler now logs IPP operation status as debug - messages instead of info or error. - - cupsFileRewind() didn't clear the end-of-file state. - - cupstestppd didn't report the actual misspelling of the - 1284DeviceID attribute (STR #1849) - - BrowseRelay didn't work on Debian (STR #1887) - - configure --without-languages didn't work (STR #1879) - - Manually added remote printers did not work (STR #1881) - - The header was not installed. - - Updated the build files for Autoconf 2.60 (STR #1853) - - The scheduler incorrectly terminated the polling - processes after receiving a partial log line. - - The cups-lpd mini-daemon reported "No printer-state - attribute found" errors when reporting the queue status - (PR #6250, STR #1821) - - SNMP backend improvements (STR #1737, STR #1742, STR - #1790, STR #1835, STR #1880) - - The scheduler erroneously reported an error with the - CGI pipe (STR #1860) - - Fixed HP-UX compile problems (STR #1858, STR #1859) - - cupstestppd crashed with some PPD files (STR #1864) - - The and header files did not - work with C++. - - -CHANGES IN CUPS V1.2.2 - - - Documentation updates (STR #1765, STR #1780) - - CUPS didn't know about alternate character set names - for Asian text (STR #1819) - - The lpoptions -o and -r options did not work unless you - specified a printer. - - The lpoptions command incorrectly allowed users to set - printer attributes like printer-type (STR #1791) - - httpWait() did not flush the write buffer, causing "bad - request" errors when communicating with CUPS 1.1.x - servers (STR #1717) - - Polling did not sanitize the printer description, - location, or make and model strings like broadcasts - did. - - Polled printers did not show the server's default - job-sheets option value. - - The Samba password prompt was not properly localized - (STR #1814) - - Added a German translation (STR #1842) - - The scheduler now creates self-signed SSL certficates - automatically when using OpenSSL and CDSA for - encryption, just as for GNU TLS. - - The SNMP backend sporatically reported some printers as - "unknown" (STR #1774) - - The scheduler now forces BrowseTimeout to be at least - twice the BrowseInterval value and non-zero to avoid - common configuration errors. - - The scheduler incorrectly returned printer URIs of the - form "ipp://server/printers/classname" for classes (STR - #1813) - - Updated Japanese localization (STR #1805) - - The scheduler's SSL certificate/key directory was not - created on installation (STR #1788) - - Added a mailto.conf man page and help page (STR #1754) - - The parallel and USB backends no longer wait for the - printer to go on-line - this caused problems with - certain printers that don't follow with the IEEE-1284 - standard (STR #1738) - - The scheduler could crash on a reload when implicit - classes were present (STR #1828) - - The IPP backend incorrectly used the CUPS_ENCRYPTION - environment variable to determine the default - encryption mode when printing (STR #1820) - - USB printing did not work on Solaris (STR #1756) - - The scheduler sorted job priorities in the wrong order - (STR #1811) - - The scheduler did not automatically restart notifiers - that exited or crashed (STR #1793) - - IPv6 support did not work on NetBSD (STR #1834) - - The EPM packaging file did not work (STR #1804) - - The scheduler used up the CPU if BrowseRemoteProtocols - was empty (STR #1792) - - Custom page sizes did not work (STR #1787) - - The SNMP backend could crash on some systems when SNMP - logging was enabled (STR #1789) - - Browsing could produce some funny printer names when - ServerName was set to an IP address (STR #1799) - - Fixed the log message for BrowseRelay (STR #1798) - - Fixes to allow CUPS to compile on MirBSD (STR #1796) - - The scheduler incorrectly set the FINAL_CONTENT_TYPE - environment variable (STR #1795) - - The pdftops filter incorrectly embedded a "produced by" - comment, causing PDF printing not to work on some - operating systems (STR #1801) - - Sending raw jobs from a client system could cause the - client's scheduler to eventually crash (STR #1786) - - The scheduler now checks that the notifier exists prior - to accepting a new subscription request. - - The scheduler now reports the supported - notify-recipient schemes based on the contents of the - ServerBin/notifier directory. - - Event notifications did not include the - notify-sequence-number or other required attributes - (STR #1747) - - Allow/Deny addresses of the form "11.22.33.*" did not - work on Linux (STR #1769) - - cupsGetPPD() did not work if the scheduler was only - listening on a domain socket (STR #1766) - - The scheduler could crash advertising a class (STR - #1768) - - The scheduler could crash if the default printer was - deleted (STR #1776) - - Added a new default CUPS raster format (v3) which does - not compress the raster stream in order to provide the - same cupsRasterReadPixels() and cupsRasterWritePixels() - performance as CUPS 1.1.x. - - The cupsaddsmb man page listed the wrong files for the - CUPS driver. - - Some configure --with options did not work (STR #1746) - - "Allow @IF(name)" didn't work if "name" wasn't the - first network interface (STR #1758) - - The lpstat command did not use the correct character - set when reporting the date and time (STR #1751) - - The cupsaddsmb command and web interface did not update - the Windows PPD files properly, resulting in corrupt - PPD files for the Windows client to use (STR #1750) - - The cupsd.conf man page didn't describe the Listen - domain socket syntax (STR #1753) - - The scheduler no longer tries to support more than - FD_SETSIZE file descriptors. - - CDSA (encryption) support fixes for MacOS X. - - The lppasswd program needs to be setuid to root to - create and update the /etc/cups/passwd.md5 file (STR - #1735) - - 32/64-bit library installation was broken (STR #1741) - - The USB backend now reports a "no such device" error - when using the old filename-based USB URIs instead of - the "success" error. - - Increased the HTTP and IPP read timeouts to 10 seconds, - as 1 second was too short on congested networks (STR - #1719) - - The SNMP backend now uses the device description over - the printer-make-and-model attribute when the attribute - contains a generic name (STR #1728) - - Fixed another file descriptor leak when printing raw - files (STR #1736) - - Raw queues were not shared via LDAP (STR #1739) - - The pstops filter didn't always embed PageSetup - commands from the PPD file (STR #1740) - - "make install" didn't work if you disabled all of the - localizations. - - The scheduler didn't always choose the least costly - filter. - - Fixed parsing of IPv6 addresses in Allow, Deny, - BrowseAllow, BrowseDeny, and BrowseRelay directives - (STR #1713) - - Printers that were shared via LDAP did not get added to - the LDAP server properly (STR #1733) - - LDAP browsing would crash the scheduler if a required - value was missing (STR #1731) - - Special cases for the "localhost" hostname did not - work, causing printing to not work when the /etc/hosts - file did not contain a localhost entry (STR #1723) - - Updated the Spanish translation (STR #1720, STR #1770) - - Reverse-order page output was broken when N-up or - landscape orientations were used (STR #1725) - - The parallel, serial, socket, and USB backends needed - print data before they would report back-channel data, - causing problems with several new drivers (STR #1724) - - -CHANGES IN CUPS V1.2.1 - - - "lprm -h hostname" did not work (STR #1800) - - The web interface did not handle reloads properly for - MSIE (STR #1716) - - The configure script no longer adds linker rpath - options when they are unnecessary. - - The scheduler could crash printing a debug message on - Solaris (STR #1714) - - The --enable-32bit and --enable-64bit configure options - did not always work. - - The password prompt showed the domain socket address - instead of "localhost" for local authentication (STR - #1706) - - The web interface filtered the list of printers even if - the user wasn't logged in (STR #1700) - - The IPP backend did not work reliably with some Xerox - printers (STR #1704) - - Trailing banners were not added when printing a single - file (STR #1698) - - The web interface support programs crashed on Solaris - (STR #1699) - - cupstestppd incorrectly reported problems with - *1284DeviceID attributes (STR #1710) - - Browsing could get disabled after a restart (STR #1670) - - Custom page sizes were not parsed properly (STR #1709) - - The -U option wasn't supported by lpadmin (STR #1702) - - The -u option didn't work with lpadmin (STR #1703) - - The scheduler did not create non-blocking back-channel - pipes, which caused problems when the printer driver - did not read the back-channel data (STR #1705) - - The scheduler no longer uses chunking in responses to - clients - this caused problems with older versions of - CUPS like 1.1.17 (PR #6143) - - Automatic raw printing was broken (STR #1667) - - 6-up printing was broken (STR #1697) - - The pstops filter did not disable CTRL-D processing on - the printer/RIP. - - ppdOpen*() did not load custom options properly (STR - #1680) - - "Set Printer Options" in the web interface did not - update the DefaultImageableArea or - DefaultPaperDimension attributes in the PPD file (STR - #1689) - - Fixed compile errors (STR #1682, STR #1684, STR #1685, - STR #1690) - - The lpstat command displayed the wrong error message - for a missing destination (STR #1683) - - Revised and completed the Polish translation (STR - #1669) - - Stopped jobs did not show up in the list of active jobs - (STR #1676) - - The configure script did not use the GNU TLS - "libgnutls-config" script to find the proper compiler - and linker options. - - The imagetoraster filter did not correctly generate - several 1, 2, and 4-bit color modes. - - cupsRasterWritePixels() could lose track of the current - output row. - - cupsRasterReadPixels() did not automatically swap - 12/16-bit chunked pixel data. - - Moved the private _cups_raster_s structure out of the - public header. - - Updated the CUPS raster format specification to include - encoding rules and colorspace definitions. - - The Zebra PPD files had the wrong PostScript code for - the "default" option choices. - - The imagetoraster filter did not generate correct CIE - XYZ or Lab color data. - - The cups-config script did not work when invoked from a - source directory (STR #1673) - - The SNMP backend did not compile on systems that used - the getifaddrs emulation functions (STR #1668) - - -CHANGES IN CUPS V1.2.0 - - - Documentation updates (STR #1618, STR #1620, STR #1622, - STR #1637) - - Static file copy buffers reduced from 64k to 32k to - work around bogus MallocDebug library assumptions (STR - #1660) - - The scheduler did not decode the backend exit code - properly (STR #1648) - - The MacOS X USB backend did not report the 1284 device ID, - nor did it fix device IDs returned by HP printers. - - The scheduler started more slowly than 1.1.x with large - numbers of printers (STR #1653) - - cupsRasterInterpretPPD() didn't support the - cupsPreferredBitsPerColor attribute, and imagetoraster - didn't use the new API. - - The "make test" script did not create all of the necessary - subdirectories for testing (STR #1638) - - The scheduler did not prevent rotation of logs - redirected to /dev/null (STR #1651) - - "make test" did not include the SNMP backend in the - test environment (STR #1625) - - The EPM packaging files did not work (STR #1621) - - "Use Default Configuration" inserted a broken - configuration file (STR #1624) - - Redirects in the web interface did not always preserve - the encrypted status of a connection (STR #1603) - - Added the Apple "pap" backend. - - Added CUPS library to CUPS Image shared library - linkage to support Linux --as-needed linker option - (STR #1606) - - Fixed support for --enable-pie (STR #1609) - - The pdftops filter did not validate the length of the - encryption key (STR #1608) - - Updated the Polish localization. - - "Encryption Required" in the cupsd.conf file now only - requires encryption when the connection is not over the - loopback interface or domain socket. - - Printer names containing "+" were not quoted properly in - the web interface (STR #1600) - - The SNMP backend now reports the make and model in the - information string so that the auto-generated printer - name is more useful than just an IP address. - - -CHANGES IN CUPS V1.2rc3 - - - The cups-lpd program always did reverse lookups on the - client address, which could be a performance problem. - Added a "-n" option to disable lookups. - - When configured with SSL support, require encryption by - default when displaying the /admin location (STR #1592) - - The next job ID was not computed correctly if the job - cache file got out of sync with the spool directory - (STR #1582) - - The PNG image handling code used deprecated functions - from libpng (STR #1587) - - Added a Polish translation (STR #1584, STR #1586) - - More changes to the scheduler to improve battery life - on portable devices (STR #1583) - - Changed the default log level for status messages back - to "DEBUG" to be consistent with CUPS 1.1.x (STR #1579) - - The error string was not set properly when - cupsDoFileRequest() was given the name of a directory - (STR #1578) - - Fixed handling of job-hold-until (STR #1581) - - Added explicit notes to the cupsaddsmb man page - explaining that the driver filenames are case-sensitive - under UNIX and that they must be all lowercase (Windows - 2000) or all UPPERCASE (Windows 95/98/Me) to work (STR - #1568) - - The USB backend incorrectly split the manufacturer name - if it contained spaces (STR #1566) - - The scheduler would hang when listing PPD files for a - manufacturer whose name contained spaces (STR #1567) - - Added the SNMP backend for network printer discovery - (STR #1555) - - cupstestppd now fails PPD files with 1284DeviceId - instead of 1284DeviceID, and cups-driverd uses a - case-insensitive comparison when looking for it (STR - #1573) - - cupsDoFileRequest() and cupsDoRequest() now work - properly with non-blocking HTTP connections. - - Added Swedish translation (STR #1569) - - "make install" now installs the MIME files with world - read permissions (STR #1565) - - More CDSA encryption support fixes (STR #1563) - - Updated the default mime.types file to support printing - of files that do not have a locally-recognized MIME - media type to raw or System V queues. - - Updated the serial port detection code on Linux (STR - #1562) - - Added some more error checking to httpGetHostname() - (STR #1561) - - The title of some administration pages was not - localized (STR #1548) - - The edit-config.tmpl file was not generated or - installed for the Spanish or Japanese localizations - (STR #1547) - - The mimeDelete() function freed the types before the - filters, but the filters needed the type data (STR #1558) - - The scheduler didn't keep track of the status pipes - properly, leading to a bad select() for multi-file jobs - (STR #1559) - - The cupstestdsc program didn't validate the ordinal - page number value for %%Page: comments. - - -CHANGES IN CUPS V1.2rc2 - - - The scheduler was not always using the string pool, - causing random crashes. - - The lpmove and the web interface's Move Job button did - not work with stopped jobs (STR #1534) - - The PostScript filter did not handle the page-set - option properly with number-up printing (STR #1543) - - The scheduler now only warns about unsupported ACLs - once (STR #1532) - - The "fitplot" option did not work with output from - Mozilla (STR #1542) - - The imagetops filter did not work with Level 2 or 3 - printers (STR #1533) - - The scheduler now recognizes PostScript files with PJL - commands that do not include an ENTER LANGUAGE command. - - Added --with-printcap configure option. - - 64-bit SSL fixes for MacOS X. - - The scheduler didn't send some printer state change - events. - - The scheduler didn't send jobs to busy remote printers. - - Fixed some problems with the launchd support. - - Added new USB printer backend for MacOS X. - - The PostScript filter now handles files that start with - an incomplete PJL header (PR #6076) - - The web interface language selection code did not try - the generic language localization (STR #1531) - - The language cache, string pool, and transcoding caches - are now process global instead of per-thread to avoid - problems with GNOME and to allow for data sharing - between threads (STR #1530) - - Fixed a CUPS 1.1.x compatibility bug (STR #1528) - - The web interface redirection after certain printer - administration tasks was broken (STR #1516) - - Web interface authorization could get stuck (STR #1512) - - Localization updates (STR #1513, STR #1518, STR #1520) - - The pstops filter didn't work with some files (STR - #1523) - - "./configure --enable-static" didn't work (STR #1522) - - The scheduler was not using the configured default - Group (STR #1521) - - The web interface still did not show the localized time - and date for some locales and systems (STR #1509) - - httpAddrGetList() would crash on systems without - getaddrinfo(). - - Socket URIs without a trailing slash would cause the - port number to not be accepted (STR #1519) - - Local raw and System V printers were not advertised as - such for printer browsing (STR #1502) - - The RPM spec file incorrectly put duplicate copies of - the Japanese and Spanish web interface templates in the - main cups package (STR #1517) - - cupsSetDests() did not explicitly set the permissions - of the /etc/cups/lpoptions file (STR #1508) - - The lpq command crashed with the -h option (STR #1515) - - -CHANGES IN CUPS V1.2rc1 - - - Documentation updates (STR #1497, STR #1498) - - The scheduler now redirects browsers to https: URLs - when encryption is required. - - The scheduler would crash when printing with a banner - (STR #1500) - - cups-driverd did not use the LanguageEncoding attribute - in PPD files to convert the NickName to UTF-8 (STR - #1503) - - The lpadmin command could not set the - printer-error-policy attribute (STR #1504) - - The web interface did not show the time and date in the - correct format for the locale (STR #1505) - - CUPS no longer accepts print jobs if a printer does not - support the file format (STR #1501) - - Cleaned up the PostScript filter (pstops) so that it - properly supports %%IncludeFeature and page scaling - (STR #1453) - - Fixed the cupsFileRewind() and cupsFileSeek() functions - to work properly with uncompressed files. - - Added cupsFileGetLine(), cupsFileStderr(), - cupsFileStdin(), and cupsFileStdout() functions to the - CUPS library. - - Added a new cupstestdsc program to test the DSC - conformance of PostScript files. - - Added KDE/GNOME icons and a Manage Printers menu item. - - Added --enable-image and --enable-pdftops configure - options to control whether the image and PDF filters - are built and installed (default = yes for all - platforms but MacOS X) - - Fixed a minor memory leak in the PPD API. - - Fixed transcoding issues (STR #1493) - - The scheduler now enforces a minimum job cost of 100 - when doing FilterLimit checks. - - The scheduler would leak file descriptors when printing - to raw queues (STR #1491) - - The IPv6 support did not compile on Tru64 UNIX (STR - #1488) - - ppdOpen2() now converts the NickName and all UI text to - UTF-8 (STR #1475) - - The Set Allowed Users web page did not work (STR #1486) - - When the default policy was not set or set to a non- - existing policy, the scheduler did not set the default - policy name to "default" (STR #1484) - - The Zebra CPCL driver did not use the correct righthand - margin for the 4" wide label sizes. - - Fixed a problem with the parsing of fractional real - numbers in PPD files. - - Added Spanish localization files (STR #1480) - - Fixed localization of a few scheduler messages (STR - #1478) - - Fixed support for HEAD requests in the scheduler (STR - #1481) - - -CHANGES IN CUPS V1.2b2 - - - Updated the CUPS design description. - - Added --enable-32bit and --enable-64bit configure - options to allow building of separate 32/64-bit - libraries on systems that support both environments - (STR #1472) - - Various compiler warning fixes. - - Fixes for Solaris 10 builds against old GNU TLS and - LDAP libraries. - - Added a cupsArrayUserData() function to retrieve the - user data pointer for an array (useful for typing - arrays) - - The ppdEmitString() function did not compute the - required buffer size properly, leading to dropped - characters on the end of the printer commands in pstops - and imagetops (STR #1470) - - -CHANGES IN CUPS V1.2b1 - - - The serial backend now supports Equinox 8-port serial - hubs (STR #526) - - The IPP backend now supports a compression option to - compress print files as they are sent to the remote - server (STR #956) - - The CUPS browse protocol now supports passing of - default options and browse timeout values from the - server to the clients (STR #800) - - Implicit classes that timed out could cause the - scheduler to crash (STR #1439) - - Added DragonFly support in local device backends (STR - #1362) - - Added LDAP printer browsing support (STR #338) - - Added official support for printer maintenance commands - via the CUPS Command file format and hooks in the - printer-type and web interfaces (STR #932) - - The HP-GL/2 filter could get in an infinite loop trying - to convert HP-PCL files (STR #1415) - - CUPS now implements the HTTP/1.1 Expect header (STR - #1407) - - Options in PPD files are no longer automatically put in - an "Extra" group; rather, all options that are not - inside an Open/CloseGroup will be placed in the - "General" group (STR #1385) - - The scheduler now creates a job-uuid attribute that - uniquely identifies a job on a network (STR #1410) - - The init script now unsets the TMPDIR environment - variable to prevent user temporary directories from - being used by cupsd accidentally (STR #1424) - - Added support for launchd on MacOS X. - - Added support for notify_post on MacOS X. - - Added support for DBUS on Linux. - - All of the Berkeley (except for lpc) and System V - commands now support specification of user, host, and - port (STR #1028, STR #1029, STR #1087) - - The lpmove command now allows you to move all jobs for - a given queue (STR #56) - - The web interface now supports moving of a job or jobs - to another queue (STR #56) - - The web interface now provides searching, paging, and - changing of the sort/display order of classes, jobs, - and printers. - - cupsaddsmb now accepts a password on the command-line - and supports passwords with special characters (STR - #822, STR #1236) - - ppdLoad*() no longer tries to "fix" bad characters in - UI text (STR #1101) - - Printer names can now (reliably) contain Unicode - characters (STR #896) - - The lpstat command now shows the time and date of the - last printer state change instead of the hardcoded "Jan - 01 00:00" (STR #659) - - The scheduler now adds a job-actual-printer-uri - attribute to job objects when printing to a class (STR - #116) - - The scheduler now logs log file open errors to the - system log (STR #1289) - - The scheduler now sets the job-originating-user-name to - the authenticated username, if available (STR #1318) - - The scheduler now only updates the permissions of SSL - keys and certificates when they are under the - ServerRoot directory (STR #1324) - - The rastertodymo driver has been renamed to - rastertolabel (a symlink is installed so that existing - queues continue to work) and now also supports Zebra's - CPCL language. - - The lpstat command could show the wrong active job for - a printer (STR #1301) - - Fixed a potential crash problem in the scheduler when - aborting a CGI program (STR #1290) - - Added a "cancel all jobs" button to the class and - printer web interfaces (STR #1140) - - The add-printer web page now shows the - set-printer-options page after the printer has been - added (STR #690) - - The classes web page now provides links to each of the - member printers (STR #307) - - CUPS now handles HTTP request/response lines up to 32k - in length; this is mainly for better cookie support - (STR #1274) - - Added support for the Apache PassEnv and SetEnv - directives to cupsd.conf (STR #853) - - Added large file (64-bit) support (STR #541) - - Fixed a performance issue with the ippReadIO() - implementation (STR #1284) - - Fixed a performance issue with the scheduler's implicit - class implementation (STR #1283) - - The pdftops filter now adds the Title and Creator - fields from the PDF file to the PostScript document - comments section (STR #539, STR #830) - - Added a new cups_array_t and cupsArray*() functions to - the CUPS API to support sorted lists of data. - - Made the CUPS API library thread-safe (STR #1276) - - Added "media" option support for EFI EFMediaType option - (STR #902) - - Added write buffering to the HTTP code to improve - performance (STR #547) - - The scheduler now uses the attributes-natural-language - attribute to localize banner pages (STR #386) - - The scheduler now returns the address that was used to - connect to it (STR #1076) - - Fixed a problem with N-up printing and OpenOffice (STR - #576) - - Added support for the GCC position independent - executable options (STR #1209) - - Added new BrowseLocalProtocols and - BrowseRemoteProtocols directives to cupsd.conf, - allowing for different browse protocols for local and - remote printers (STR #877) - - PPD files can now contain strings up to 256k in length - (STR #1215) - - The pstops filter now supports the IncludeFeature DSC - comment (STR #1212) - - The pstops filter now disables the setpagedevice - procedure when doing N-up printing (STR #1161) - - The serial backend now supports "stop=1", "stop=2", - "parity=space", and "parity=mark" options (STR #1155) - - "make install" no longer overwrites an existing PAM - configuration file (STR #1064) - - The scheduler now closes all files on startup when run - in daemon mode (STR #1009) - - Added a new RGBW colorspace to the CUPS raster format - (STR #1071) - - The pdftops filter now sets the page size based on the - media box when not scaling the output (STR #912) - - The pdftops filter now supports masked images (STR - #281) - - The pdftops filter produced large output when rendering - PDF files containing lot of repeated images (STR #327) - - The pdftops filter now minimizes print processing of - PDF files when using the page-ranges option (STR #273) - - Updated pdftops filter to Xpdf 3.01. - - Added new cupsBackchannelRead() and - cupsBackchannelWrite() functions, as well as - backchannel support to the parallel, serial, socket, - and USB backends (STR #1252) - - The parallel and USB backends now treat a "no space - available" error as an out-of-paper condition (STR - #1225) - - The "lpc" command now supports the "status all" command - (STR #1004) - - ippReadIO() did not read collections properly (STR - #1249) - - The "make test" script now creates the test files in - "/tmp/cups-$USER" instead of "/tmp/$USER" (STR #981) - - All backends now abort on error when printing a job to - a class - this allows the next printer in the class to - print the job (STR #1084) - - The scheduler now verifies that a printer supports - Letter or A4 media sizes before setting them as the - initial default (STR #1250) - - The cupstestppd program now flags bad Resolution - options (STR #1269) - - The USB backend now retries printing when the printer - is disconnected or turned off (STR #1267) - - Added new httpGetHostname() function to CUPS API, and - use it instead of gethostname() so that the web - interface will work correctly on systems whose hostname - is not the FQDN (STR #1266) - - The scheduler now stops printers if the backend for the - queue is missing on startup (STR #1265) - - The configure script now supports "--disable-library" - to disable particular image file format support - libraries, even if they are available on the build - system (STR #1248) - - The IPP backend did not always report on the total - number of pages that were printed (STR #1251) - - The lpstat program could display garbage date and time - values for locales whose date format exceeded 31 - characters (STR #1263) - - The cupstestppd program would segfault when testing - certain broken PPD files (STR #1268) - - Dramatically reduced the overhead of implicit classes. - - Added new cupsDir*() functions to CUPS API. - - Printers can now be published individually for sharing. - - Fixed a bug in the scheduler's startup signalling code - which caused cupsd to send the SIGUSR1 signal to the - init process instead of the original parent process - (STR #1258) - - Added new on-line help CGI to web interface to provide - searchable help. - - Devices are now tracked dynamically, with each query - doing a new device scan. This eliminates a previous - startup delay caused by slow backends and allows new - printers to be seen without restarting the server, - however it limits the amount of device URI checking - that can be done (basically now the scheduler only - requires a URI with a method that is a listed backend) - - Added new printer auto-detection, server configuration, - and log file viewing to the administration web page. - - Added new "set allowed users" web interface to set the - list of allowed users for a printer or class. - - The scheduler, command-line, and web interfaces now - limit the list of printers and classes to those - accessible by a user. - - cupsMarkOptions() now handles more non-standard - duplexing options and choices (STR #915) - - cups-lpd now honors remote banner requests with the - "standard" banner whenever a printer does not have one - defined (STR #1220) - - The scheduler's denial-of-service checks did not work - properly with IPv6 addresses (STR #1134) - - The lp and lpr commands did not error out properly when - they were unable to write to a temporary file (STR - #1129) - - The pstops filter did not handle Adobe-specific - comments in Windows NT driver output (STR #1085) - - "lpstat -l -p" incorrectly reported the printer - interface (STR #936) - - The web interface now operates exclusively with the - UTF-8 encoding, and sends the appropriate character set - and header information to the web browser (STR #919, - STR #1007) - - Added a "set allowed users" interface to the web - interface so that you can set the list of allowed or - denied users/groups for a printer or class. - - Disallow the "#" character in printer names, since it - has special meaning in the shell, config files, and in - URIs (STR #917, STR #1202) - - Added a new application/x-csource MIME type, and - support for it to the texttops filter so that you can - pretty print plain text files without the C/C++ - keywords being highlighted. - - The pdftops filter did not compile with GCC 4.0 (STR - #1226) - - The texttops filter did not highlight preprocessor - directives followed by a tab properly. - - HP PJL output now uses both JOB DISPLAY and RDYMSG - commands to show the current job on the printer's - display (STR #1218) - - Local authentication certificates are now stored in - /var/run/cups/certs by default instead of - /etc/cups/certs (STR #1211) - - Backends now use "&" to separate options in device - URIs; "+" is still recognized but is deprecated (STR - #842) - - The USB backend no longer supports the usb:/dev/foo - format on systems that support device ID queries. - - Forced classification markings did not work when the - job-sheets parameters were "none,none". - - "lpstat -l -p" incorrectly showed all users as allowed, - even if the queue was restricted to certain users (STR - #801) - - The scheduler now automatically detects SSL/TLS clients - without using the SSLPort/SSLListen directives. - - The CUPS API and scheduler no longer support SSLv2- - encrypted connections. - - Updated the cupsaddsmb utility to correctly export the - CUPS driver for Windows. - - Fixed a signal-handling bug in httpRead() which - ultimately caused the server to print multiple copies - when it was busy (STR #1184) - - The cupsFile API now uses the O_APPEND option when - opening files in append mode (STR #990) - - The md5.h header and md5_* functions are now officially - private and have been renamed to avoid conflicts with - other implementations with the same name. - - The pdftops filter incorrectly embedded some Type1 - fonts (STR #1093) - - The scheduler didn't detect a closed connection in the - middle of an IPP request (STR #1153) - - The scheduler could block trying to read the job status - if there was input pending and the job was cancelled in - the same input cycle (STR #1157) - - The scheduler could crash when deleting a class due to - infinite recursion. - - Updated the Zebra ZPL label printer driver to use the - run-length encoding and support more options. - - Updated serial backend to scan for /dev/ttyC* as well - as /dev/ttyc* for Cyclades serial ports (STR #1049) - - The scheduler could hang reading the job status under - certain circumstances (STR #1068) - - The USB backend termination signal code was inverted - (STR #1046) - - Moved enable and disable commands to sbindir to be - consistent. - - Added new cupsRasterInterpretPPD() function for RIP - filters to setup the raster page header from - PostScript commands in a PPD file. - - The CUPS browsing protocol now offers a "delete" bit - to remove printers as soon as they are deleted on the - server or as soon as the server shuts down gracefully - (STR #793) - - The CUPS_SERVER and ServerName directives (client.conf - and ~/.cupsrc) may now contain names of the form - "server:port" and "/path/to/domain/socket". - - The "cancel -u user" command now works for ordinary - users (STR #751) - - Added test run support to "make test" target (STR #64) - - Added domain socket support (STR #656) - - Added BrowseLocalOptions directive to allow the - administrator to add printer URI options to the browse - URI, e.g. "encryption=required" (STR #732) - - Added BrowseRemoteOptions directive to allow the - administrator to add standard URI options to the - remote printer URI, e.g. "encryption=required" (STR - #732) - - Now put "-I.." compiler option in front of all others - to ensure that local CUPS headers are used before - installed headers (STR #437) - - New cupsLangPrintf() and cupsLangPuts() for localized - interfaces. - - Now support custom attributes and extended options in - PPD files. - - Now provide functions to save PPD files. - - New policy mechanism allows per-operation and - per-printer control over what users and groups are - allowed to do various IPP operations. - - New error policy mechanism to control how aborted - backend errors are handled by the scheduler - (abort-job, retry-job, requeue-job, stop-printer) - - Updated the printer test page with a better color - wheel and a separate grayscale ramp. - - A single backend process is now run to send all print - data for a job. - - Backends and filters can now send and receive - backchannel data over file descriptor 3. - - Updated the raster stream format to support more - user-defined attributes and to do compression of the - page data. diff --git a/CHANGES-1.3.txt b/CHANGES-1.3.txt deleted file mode 100644 index 9af534f..0000000 --- a/CHANGES-1.3.txt +++ /dev/null @@ -1,856 +0,0 @@ -CHANGES-1.3.txt ---------------- - -CHANGES IN CUPS V1.3.11 - - - The scheduler did not prevent nested classes (STR #3211) - - The scheduler did not reprint processing jobs that were moved to - another destination (STR #3222) - - The scheduler did not reset the current job file when stopping a - printer (STR #3226) - - The scheduler did not handle POSTs to custom CGIs properly (STR #3221) - - The pdftops filter did not print landscape PDF pages properly - (STR #2881) - - The scheduler did not handle partial header lines properly from CGI - programs (STR #3194) - - The web interface could hang on OpenBSD (STR #3176, STR #3196) - - The scheduler and cupsfilter utility did not handle rules starting - with a negation operator properly (STR #3160) - - The scheduler and cupsfilter utility would crash with certain MIME - .types rules (STR #3159) - - httpSetField wasn't bracketing IPv6 numeric addresses for the Host: - field (STR #3164) - - The ServerName, if specified, was not treated as a valid alias for the - local system (STR #3167) - - "make epm" did not work (STR #3166) - - "lpstat -h server" showed non-shared printers (STR #3147) - - "make check" did not work on Linux (STR #3161) - - -CHANGES IN CUPS V1.3.10 - - - Documentation fixes (STR #2994, STR #2995, STR #3008, STR #3056, - STR #3057) - - SECURITY: The scheduler now protects against DNS rebinding attacks - (STR #3118) - - SECURITY: Fixed TIFF integer overflow in image filters (STR #3031) - - The scheduler did not support the job-hold-until attribute with the - Restart-Job operation (STR #3130) - - SECURITY: The PNG image reading code did not validate the - image size properly, leading to a potential buffer overflow - (STR #2974) - - The rastertohp driver did not set the 1-sided printing mode when - needed (STR #3131) - - Now use a wrapper program instead of our fork of the Xpdf code to - support printing of PDF files. The new wrapper supports using Xpdf, - poppler, or Ghostscript to convert PDF files to PostScript (STR #3129) - - Long job names caused problems with some PJL printers (STR #3125) - - The lpq command did not work when showing all destinations (STR #3117) - - The scheduler used a codeset name of UTF8 which is not supported on - Solaris (STR #3113) - - cupsGetJobs() did not work with a NULL destination (STR #3107) - - Fixed a localization problem for option choices (incorrectly) named - "Custom" (STR #3106) - - The fallback OpenSSL random number seeding would not work (STR #3079) - - The scheduler might miss a child signal, causing high CPU usage. - - The scheduler did not enforce quotas after the job history was - unloaded (STR #3078) - - The job-k-limit, job-page-limit, and job-quota-period attributes - could not be set using the lpadmin command (STR #3077) - - httpSeparateURI() did not error out on URIs with a missing port - number after a colon. - - Fixed a Valgrind-detected initialization error when creating a - missing directory on startup. - - The scheduler did not always read all of the HTTP headers from a - CGI script/program. - - The scheduler did not always set the "air" property in Bonjour/DNS-SD - registrations. - - The scheduler incorrectly compared Mac OS X UUIDs for access - control, preventing access in certain configurations. - - The IPP backend incorrectly reset the required authentication - to Kerberos when authentication failed. - - The scheduler no longer looks up the local hostname by default; - turn on hostname lookups to restore the previous behavior. - - The scheduler did not always load MIME type rules correctly - (STR #3059) - - The test page did not format correctly on A4 paper (STR #3060) - - The web interface sometimes incorrectly redirected users to - 127.0.0.1 (STR #3022) - - cupsPrintFile*() did not send the document filename for single - file submissions (STR #3055) - - The scheduler did not update the member-names attribute when - removing the last printer from a class. - - The scheduler did not report PPD Products with parenthesis - in them properly (STR #3046) - - The wrong italic fonts were listed in the UTF-8 charset file - for the text filter. - - The backends did not return an OK status for the - CUPS_SC_CMD_GET_BIDI side-channel command (STR #3029) - - The scheduler did not purge jobs that were missing a - time-at-creation attribute, indicating a bad job control file - (STR #3030) - - The "-o job-hold-until=week-end" option did not work properly - (STR #3025) - - The Solaris USB printer device does not support select or poll - (STR #3028) - - The scheduler would crash if you exceeded the MaxSubscriptions - limit. - - The lp "-H immediate" option did not specify that the job - should not be held (STR #3013) - - The scheduler did not support the "Connection: close" - HTTP header (STR #3010) - - The mailto notifier didn't terminate messages properly - (STR #3011) - - Backends could spin trying to read back-channel data - (STR #3001) - - The HP-GL/2 filter was using the wrong default colors - (STR #2966) - - The scheduler incorrectly allowed Get-Jobs operations without a - printer-uri (STR #2996) - - The compression option was not being encoded properly - (STR #2997) - - Added a missing character map for JIS-X0213/ShiftJIS. - - The scheduler now rejects ATTR: messages with empty values. - - The scheduler could consume all CPU handling closed connections - (STR #2988) - - Fixed some configure script bugs with rc/xinetd directories - (STR #2970) - - The Epson sample driver PPDs contained errors (STR #2979) - - -CHANGES IN CUPS V1.3.9 - - - SECURITY: The HP-GL/2 filter did not range check pen numbers - (STR #2911) - - SECURITY: The SGI image file reader did not range check - 16-bit run lengths (STR #2918) - - SECURITY: The text filter did not range check cpi, lpi, or - column values (STR #2919) - - Documentation updates (STR #2904, STR #2944) - - The French web admin page was never updated (STR #2963) - - The IPP backend did not retry print jobs when the printer - reported itself as busy or unavailable (STR #2951) - - The "Set Allowed Users" web interface did not handle trailing - whitespace correctly (STR #2956) - - The PostScript filter did not work with Adobe applications - using custom page sizes (STR #2968) - - The Mac OS X USB backend did not work with some printers - that reported a bad 1284 device ID. - - The scheduler incorrectly resolved the client connection - address when HostNameLookups was set to Off (STR #2946) - - The IPP backend incorrectly stopped the local queue if - the remote server reported the "paused" state. - - The cupsGetDests() function did not catch all types of - request errors. - - The scheduler did not always log "job queued" messages - (STR #2943) - - The scheduler did not support destination filtering using - the printer-location attribute properly (STR #2945) - - The scheduler did not send the server-started, - server-restarted, or server-stopped events (STR #2927) - - The scheduler no longer enforces configuration file - permissions on symlinked files (STR #2937) - - CUPS now reinitializes the DNS resolver on failures - (STR #2920) - - The CUPS desktop menu item was broken (STR #2924) - - The PPD parser was too strict about missing keyword - values in "relaxed" mode. - - The PostScript filter incorrectly mirrored landscape - documents. - - The scheduler did not correctly update the - auth-info-required value(s) if the AuthType was Default. - - The scheduler required Kerberos authentication for - all operations on remote Kerberized printers instead - of just for the operations that needed it. - - The socket backend could wait indefinitely for back- - channel data with some devices. - - PJL panel messages were not reset correctly on older - printers (STR #2909) - - cupsfilter used the wrong default path (STR #2908) - - Fixed address matching for "BrowseAddress @IF(name)" - (STR #2910) - - Fixed compiles on AIX. - - Firefox 3 did not work with the CUPS web interface in SSL - mode (STR #2892) - - Custom options with multiple parameters were not emitted - correctly. - - Refined the cupstestppd utility. - - ppdEmit*() did not support custom JCL options (STR #2889) - - The cupstestppd utility incorrectly reported missing - "en" base translations (STR #2887) - - -CHANGES IN CUPS V1.3.8 - - - Documentation updates (STR #2785, STR #2861, STR #2862) - - The scheduler did not add the ending job sheet when the - job was released. - - The IPP backend did not relay marker-* attributes. - - The CUPS GNOME/KDE menu item was not localized for - Chinese (STR #2880) - - The CUPS GNOME/KDE menu item was not localized for - Japanese (STR #2876) - - The cupstestppd utility reported mixed line endings for - Mac OS and Windows PPD files (STR #2874) - - The pdftops filter did not print landscape orientation PDF - pages correctly on all printers (STR #2850) - - The scheduler did not handle expiring of implicit classes - or their members properly, leading to a configuration where - one of the members would have a short name (STR #2766) - - The scheduler and cupstestppd utilities did not support - cupsFilter and cupsPreFilter programs with spaces in their - names (STR #2866) - - Removed unused variables and assignments found by the - LLVM "clang" tool. - - Added NULL checks recommended by the LLVM "clang" tool. - - The scheduler would crash if you started a printer that - pointed to a backend that did not exist (STR #2865) - - The ppdLocalize functions incorrectly mapped all generic - locales to country-specific locales. - - The cups-driverd program did not support Simplified Chinese - or Traditional Chinese language version strings (STR #2851) - - Added an Indonesian translation (STR #2792) - - Fixed a timing issue in the backends that could cause data - corruption with the CUPS_SC_CMD_DRAIN_OUTPUT side-channel - command (STR #2858) - - The scheduler did not support "HostNameLookups" with all of - the boolean names (STR #2861) - - Fixed a compile problem with glibc 2.8 (STR #2860) - - The scheduler incorrectly filtered out queues with ACLs and - authentication. - - The PostScript filter did not support %%IncludeFeature lines - in the page setup section of each page (STR #2831) - - The scheduler did not generate printer-state events when the - default printer was changed (STR #2764) - - cupstestppd incorrectly reported a warning about the PPD format - version in some locales (STR #2854) - - cupsGetPPD() and friends incorrectly returned a PPD file for - a class with no printers. - - The member-uris values for local printers in a class returned - by the scheduler did not reflect the connected hostname or - port. - - The CUPS PHP extension was not thread-safe (STR #2828) - - The scheduler incorrectly added the document-format-default - attribute to the list of "common" printer attributes, which - over time would slow down the printing system (STR #2755, - STR #2836) - - The cups-deviced and cups-driverd helper programs did not set - the CFProcessPath environment variable on Mac OS X (STR #2837) - - "lpstat -p" could report the wrong job as printing (STR #2845) - - The scheduler would crash when some cupsd.conf directives - were missing values (STR #2849) - - The web interface "move jobs" operation redirected users to - the wrong URL (STR #2815) - - The Polish web interface translation contained errors - (STR #2815) - - The scheduler did not report PostScript printer PPDs with - filters as PostScript devices. - - The scheduler did not set the job document-format attribute - for jobs submitted using Create-Job and Send-Document. - - cupsFileTell() did not work for log files opened in append - mode (STR #2810) - - The scheduler did not set QUERY_STRING all of the time - for CGI scripts (STR #2781, STR #2816) - - The scheduler now returns an error for bad job-sheets - values (STR #2775) - - Authenticated remote printing did not work over domain - sockets (STR #2750) - - The scheduler incorrectly logged errors for print filters - when a job was canceled (STR #2806, #2808) - - The scheduler no longer allows multiple RSS subscriptions - with the same URI (STR #2789) - - The scheduler now supports Kerberized printing with - multiple server names (STR #2783) - - "Satisfy any" did not work in IPP policies (STR #2782) - - The CUPS imaging library would crash with very large - images - more than 16Mx16M pixels (STR #2805) - - The PNG image loading code would crash with large images - (STR #2790) - - The scheduler did not limit the total number of filters. - - The scheduler now ensures that the RSS directory has - the correct permissions. - - The RSS notifier did not quote the feed URL in the RSS - file it created (STR #2801) - - The web interface allowed the creation and cancellation - of RSS subscriptions without a username (STR #2774) - - Increased the default MaxCopies value on Mac OS X to - 9999 to match the limit imposed by the print dialog. - - The scheduler did not reject requests with an empty - Content-Length field (STR #2787) - - The scheduler did not log the current date and time and - did not escape special characters in request URIs when - logging bad requests to the access_log file (STR #2788) - - -CHANGES IN CUPS V1.3.7 - - - CVE-2008-0047: cgiCompileSearch buffer overflow (STR #2729) - - CVE-2008-1373: CUPS GIF image filter overflow (STR #2765) - - Updated the "make check" tests to do a more thorough - automated test. - - cups-driverd complained about missing directories (STR - #2777) - - cupsaddsmb would leave the Samba username and password on - disk if no Windows drivers were installed (STR #2779) - - The Linux USB backend used 100% CPU when a printer was - disconnected (STR #2769) - - The sample raster drivers did not properly handle SIGTERM - (STR #2770) - - The scheduler sent notify_post() messages too often on - Mac OS X. - - Kerberos access to the web interface did not work - (STR #2748) - - The scheduler did not support "AuthType Default" in IPP - policies (STR #2749) - - The scheduler did not support the "HideImplicitMembers" - directive as documented (STR #2760) - - "make check" didn't return a non-zero exit code on - error (STR #2758) - - The scheduler incorrectly logged AUTH_foo environment - variables in debug mode (STR #2751) - - The image filters inverted PBM files (STR #2746) - - cupsctl would crash if the scheduler was not running - (STR #2741) - - The scheduler could crash when printing using a port - monitor (STR #2742) - - The scheduler would crash if PAM was broken (STR #2734) - - The image filters did not work with some CMYK JPEG files - produced by Adobe applications (STR #2727) - - The Mac OS X USB backend did not work with printers that - did not report a make or model. - - The job-sheets option was not encoded properly (STR #2715) - - The scheduler incorrectly complained about missing LSB - PPD directories. - - -CHANGES IN CUPS V1.3.6 - - - Documentation updates (STR #2646, STR #2647, STR #2649) - - Fixed a problem with the web interface "Use Kerberos - Authentication" check box (STR #2703) - - The scheduler unconditionally overwrote the printer-state- - message with "process-name failed" when a filter or backend - failed, preventing a useful error message from being shown - to the user. - - Policies on CUPS-Move-Job didn't work as expected (STR - #2699) - - The configure script only supported D-BUS on Linux - (STR #2702) - - The scheduler did not support (STR #2701) - - The scheduler did not reset the job-hold-until attribute - after a job's hold time was reached. - - The scheduler did not support printer supply attributes - (STR #1307) - - The Kerberos credentials provided by some Windows KDCs - were still too large - now use a dynamic buffer to - support credentials up to 64k in size (STR #2695) - - Printing a test page from the web interface incorrectly - defaulted to the "guest" user (STR #2688) - - The cupsEncodeOptions2() function did not parse multiple- - value attribute values properly (STR #2690) - - The scheduler incorrectly sent printer-stopped events for - status updates from the print filters (STR #2680) - - The IPP backend could crash when handling printer errors - (STR #2667) - - Multi-file jobs did not print to remote CUPS servers - (STR #2673) - - The scheduler did not provide the Apple language ID to - job filters. - - Kerberos authentication did not work with the web - interface (STR #2606, STR #2669) - - The requesing-user-name-allowed and -denied functionality - did not work for Kerberos-authenticated usernames (STR - #2670) - - CUPS didn't compile on HP-UX 11i (STR #2679) - - cupsEncodeOptions2() did not handle option values like - "What's up, doc?" properly. - - Added lots of memory allocation checks (Fortify) - - The scheduler would crash if it was unable to add a job - file (Fortify) - - ppdOpen*() did not check all memory allocations (Coverity) - - ippReadIO() did not check all memory allocations (Coverity) - - The PostScript filter did not detect read errors (Coverity) - - The scheduler did not check for a missing job-sheets-completed - attribute when sending an event notification (Coverity) - - "Set Printer Options" might not work with raw queues (Coverity) - - cupsRasterInterpretPPD() could crash on certain PostScript - errors (Coverity) - - The USB backend did not check for back-channel support - properly on all systems (Coverity) - - Fixed memory leaks in the GIF and PNM image loading code - (Coverity) - - Removed some dead code in the CUPS API and scheduler (Coverity) - - Fixed two overflow bugs in the HP-GL/2 filter (Coverity) - - Fixed another ASN1 string parsing bug (STR #2665) - - The RSS notifier directory was not installed with the - correct permissions. - - The standard CUPS backends could use 100% CPU while waiting - for print data (STR #2664) - - Filename-based MIME rules did not work (STR #2659) - - The cups-polld program did not exit if the scheduler crashed - (STR #2640) - - The scheduler would crash if you tried to set the port-monitor - on a raw queue (STR #2639) - - The scheduler could crash if a polled remote printer was - converted to a class (STR #2656) - - The web interface and cupsctl did not correctly reflect - the "allow printing from the Internet" state (STR #2650) - - The scheduler incorrectly treated MIME types as case- - sensitive (STR #2657) - - The Java support classes did not send UTF-8 strings to - the scheduler (STR #2651) - - The CGI code did not handle interrupted POST requests - properly (STR #2652) - - The PostScript filter incorrectly handled number-up when - the number of pages was evenly divisible by the number-up - value. - - The PDF filter incorrectly filtered pages when page-ranges - and number-up were both specified (STR #2643) - - The IPP backend did not handle printing of pictwps files - to a non-Mac CUPS server properly. - - The scheduler did not detect network interface changes - on operating systems other than Mac OS X (STR #2631) - - The scheduler now logs the UNIX error message when it - is unable to create a request file such as a print job. - - Added support for --enable-pie on Mac OS X. - - -CHANGES IN CUPS V1.3.5 - - - The SNMP backend did not check for negative string - lengths (STR #2589) - - The scheduler incorrectly removed auth-info attributes, - potentially leading to a loss of all options for a job. - - The scheduler stopped sending CUPS browse packets on a - restart when using fixed addresses (STR #2618) - - Fixed PDF filter security issues (CVE-2007-4352 - CVE-2007-5392 CVE-2007-5393) - - Changing settings would always change the DefaultAuthType - and Allow lines (STR #2580) - - The scheduler would crash when submitting an undefined - format file from Samba with LogLevel debug2 (STR #2600) - - The scheduler did not use poll() when epoll() was not - supported by the running kernel (STR #2582) - - Fixed a compile problem with Heimdal Kerberos (STR #2592) - - The USB backend now retries connections to a printer - indefinitely rather than stopping the queue. - - Printers with untranslated JCL options were not exported - to Samba correctly (STR #2570) - - The USB backend did not work with some Minolta USB - printers (STR #2604) - - The strcasecmp() emulation code did not compile (STR - #2612) - - The scheduler would crash if a job was sent to an empty - class (STR #2605) - - The lpc command did not work in non-UTF-8 locales (STR - #2595) - - Subscriptions for printer-stopped events also received - other state changes (STR #2572) - - cupstestppd incorrectly reported translation errors for - the "en" locale. - - ppdOpen() did not handle custom options properly when the - Custom attribute appeared before the OpenUI for that - option. - - The scheduler could crash when deleting a printer or - listing old jobs. - - The Mac OS X USB backend did not allow for requeuing of - jobs submitted to a class. - - lpmove didn't accept a job ID by itself. - - The scheduler incorrectly removed job history information - for remote print jobs. - - The scheduler incorrectly sent the - "com.apple.printerListChanged" message for printer state - changes. - - The PostScript filter drew the page borders (when enabled) - outside the imageable area. - - The LPD and IPP backends did not default to the correct - port numbers when using alternate scheme names. - - The scheduler incorrectly deleted hardwired remote - printers on system sleep. - - The scheduler would abort if a bad browse protocol name - was listed in the cupsd.conf file. - - The online cupsd.conf help file incorrectly showed - "dns-sd" instead of "dnssd" for Bonjour sharing. - - The scheduler could crash changing the port-monitor value. - - The scheduler generated CoreFoundation errors when run as - a background process. - - When printing with number-up > 1, it was possible to get - an extra blank page. - - -CHANGES IN CUPS V1.3.4 - - - Documentation updates (STR #2560, STR #2563, STR #2569) - - CUPS now maps the "nb" locale to "no" on all platforms - (STR #2575) - - CUPS did not work with a Windows 2003 R2 KDC (STR #2568) - - ippReadIO() could read past the end of a buffer (STR - #2561) - - The scheduler would crash on shutdown if it was unable - to create a Kerberos context. - - Multiple AuthTypes in cupsd.conf did not work (STR - #2545) - - The snmp.conf file referenced the wrong man page (STR - #2564) - - The cupsaddsmb program didn't handle domain sockets - properly (STR #2556) - - The scheduler now validates device URIs when adding - printers. - - Updated httpSeparateURI() to support hostnames with - the backslash character. - - Updated the Japanese localization (STR #2546) - - The parallel backend now gets the current IEEE-1284 - device ID string on Linux (STR #2553) - - The IPP backend now checks the job status at - variable intervals (from 1 to 10 seconds) instead - of every 10 seconds for faster remote printing - (STR #2548) - - "lpr -p" and "lpr -l" did not work (STR #2544) - - Compilation failed when a previous version of CUPS - was installed and was included in the SSL include - path (STR #2538) - - The scheduler did not reject requests with charsets - other than US-ASCII or UTF-8, and the CUPS API - incorrectly passed the locale charset to the scheduler - instead of UTF-8 (STR #2537) - - cups-deviced did not filter out duplicate devices. - - The AppleTalk backend incorrectly added a scheme - listing when AppleTalk was disabled or no printers - were found. - - The PostScript filter generated N^2 copies when the - printer supported collated copies and user requested - reverse-order output. - - The scheduler did not reprint all of the files in a - job that was held. - - The scheduler did not update the printcap file after - removing stale remote queues. - - The cupsd.conf man page incorrectly referenced - "AuthType Kerberos" instead of "AuthType Negotiate". - - -CHANGES IN CUPS V1.3.3 - - - The scheduler did not use the attributes-natural-language - attribute when passing the LANG environment variable to - cups-deviced or cups-driverd. - - The scheduler did not use the printer-op-policy when - modifying classes or printers (STR #2525) - - The auth-info-required attribute was not always updated - for remote queues that required authentication. - - The German web interface localization contained errors - (STR #2523) - - The Swedish localization contained errors (STR #2522) - - -CHANGES IN CUPS V1.3.2 - - - The 1.3.1 release was incorrectly created from the - 1.4.x source tree (STR #2519) - - Added support for 32/64-bit libraries on HP-UX - (STR #2520) - - The scheduler incorrectly used portrait as the default - orientation (STR #2513) - - The scheduler no longer writes the printcap file for - every remote printer update (STR #2512) - - Remote raw printing with multiple copies did not work - (STR #2518) - - Updated the configure script to require at least autoconf - 2.60 (STR #2515) - - Some gzip'd PPD files were not read in their entirety - (STR #2510) - - -CHANGES IN CUPS V1.3.1 - - - Documentation updates. - - The USB backend on Mac OS X could hang if the driver and - printer did not match. - - Delegated Kerberos credentials were not working. - - "make distclean" incorrectly removed the edit-config.tmpl - files (STR #2508) - - Fix compile problem on HP-UX (STR #2501) - - The cupstestppd utility now tests for resolutions greater - than 99999 DPI to detect a missing "x" between the X and Y - resolutions. - - Fixed many problems in the various translations and added - a new "checkpo" utility to validate them. - - The cupstestppd utility now tests the custom page size code - for CUPS raster drivers. - - cupsLangDefault() did not attempt to return a language that - was supported by the calling application. - - If a remote printer stopped while a job was being sent, the - local queue would also get stopped and the job re-queued, - resulting in duplicate prints in some cases. - - A few Apple-specific job options needed to be omitted when - printing a banner page. - - The new peer credential support did not compile on FreeBSD - (STR #2495) - - Direct links to help files did not set the current section - so the table-of-contents was not shown. - - The configure script did not support --localedir=foo (STR #2488) - - The backends were not displaying their localized messages. - - CUPS-Authenticate-Job did not require Kerberos authentication - on queues protected by Kerberos. - - The Zebra ZPL driver did not work with Brady label printers - (STR #2487) - - Norwegian wasn't localized on Mac OS X. - - getnameinfo() returns an error on some systems when DNS is - not available, leading to numerous problems (STR #2486) - - The cupsfilter command did not work properly on Mac OS X. - - The scheduler makefile contained a typo (STR #2483) - - The TBCP and BCP port monitors did not handle the trailing - CTRL-D in some PostScript output properly. - - Fixed the localization instructions and German template for - the "Find New Printers" button (STR #2478) - - The web interface did not work with the Chinese localization - (STR #2477) - - The web interface home page did not work for languages that - were only partially localized (STR #2472) - - Updated the Spanish web interface localization (STR #2473) - - ppdLocalize() did not work for country-specific localizations. - - -CHANGES IN CUPS V1.3.0 - - - The scheduler did not handle out-of-file conditions - gracefully when accepting new connections, leading to - heavy CPU usage. - - The scheduler did not detect ServerBin misconfigurations - (STR #2470) - - "AuthType Default" did not work as expected when the - "DefaultAuthType foo" line appeared after it in the - cupsd.conf file. - - The on-line help did not describe many common printing - options (STR #1846) - - The IPP backend did not return the "auth required" status - when printing to a Kerberos-protected queue. - - The scheduler was not looking in the correct directories - for LSB PPD files (STR #2464) - - Changed references to ESP Ghostscript to GPL Ghostscript - (STR #2463) - - The PostScript filter did not cleanly terminate when - the job was canceled or stopped. - - Fixed generation of Kerberos credentials for remote - printing. Note that this requires a recent version of - MIT Kerberos with a working krb5_cc_new_unique() - function or Heimdal Kerberos. - - Added Portuguese and updated Italian message catalogs. - - -CHANGES IN CUPS V1.3rc2 - - - Added more range checking to the pdftops filter. - - The scheduler would crash if a remote IPP queue was stopped - (STR #2460) - - The scheduler did not allow "DefaultAuthType None". - - -CHANGES IN CUPS V1.3rc1 - - - Updated the German localization (STR #2443) - - cupsAdminGetServerSettings() did not handle properly. - - When lprm and cancel are run with no job ID, they now will - cancel the first stopped job if no pending or processing - jobs are left in the queue. - - The scheduler now logs successful print jobs, filter - failures, and the job file types at the default log - level (STR #2458) - - The scheduler now logs the usernames it is using for - authorization at LogLevel debug instead of debug2 (STR #2448) - - Added Intellitech Intellibar and Zebra CPCL PPDs to the list - of installed PPDs. - - Added 6" and 8" wide label sizes for the Zebra ZPL Label - Printer driver (STR #2442) - - The cupsaddsmb program and web interface now support - exporting of 64-bit Windows drivers, when available - (STR #2439) - - Moving a job that was printing did not stop the job on the - original printer (STR #2262) - - The cups-lpd mini-daemon did not work on Mac OS X server. - - Added httpGetAuthString() and httpSetAuthString() APIs to get - and set the current (cached) authorization string to use for - HTTP requests. - - Updated the default cupsd.conf policy to list the - "administrative" operations separately from the "printer - control" operations so that it is easier to define a - group of users that are "printer operators". - - The web interface now pulls the default cupsd.conf file - from cupsd.conf.default in the CUPS config directory. - - Added a help file for using Kerberos with CUPS. - - The scheduler now strips the "@KDC" portion of Kerberos - usernames since those usernames typically do not appear in - the group membership lists used by CUPS. - - cupsMarkOptions() could (incorrectly) leave multiple option - choices marked. - - Backends could (incorrectly) run as root during discovery - (STR #2454) - - Avahi is now supported for DNS-SD (Bonjour) printer sharing - (STR #2455) - - The default cupsd.conf file had typos and old operation names - (STR #2450) - - The scheduler now erases authentication cache files using the - 7-pass US DoD algorithm. - - Delegated Kerberos credentials (proxy authentication) did not - work. - - The filter makefile did not optimize the libcupsimage.2.dylib - with a sectorder file. - - The IPP backend incorrectly wrote an empty printer message - when processing the "none" state reason. - - The USB backend could deadlock on Mac OS X while performing - a side-channel command. - - The scheduler did not prevent remote queues from being - shared/published. - - The scheduler did not remove the temporary request file on - authentication errors. - - ppdLocalizeIPPReason() did not handle "scheme:" schemes or - "file" URLs. - - ppdLocalizeIPPReason() was not exported on Mac OS X. - - -CHANGES IN CUPS V1.3b1 - - - Copyright updates - CUPS is now owned by Apple Inc. - - Documentation updates (STR #1775, STR #2027, STR #2130, - STR #2131, STR #2263, STR #2356, STR #2397) - - Added new cupsfilter utility (STR #1734) - - Added new job-printer-state-message and - job-printer-state-reasons attributes to jobs (STR #2418) - - Added LDAP+SSL support (STR #1967) - - CUPS now supports authentication via peer credentials - over domain sockets (STR #2242, STR #2277) - - The CUPS sample driver PPDs are now generated by the PPD - compiler and include all of the localized languages by - default (STR #2164) - - You can now specify "AuthType Default" in the cupsd.conf - file to use the default authentication defined by the - DefaultAuthType directive. - - The SNMP backend no longer adds a default Address line - when none is specified in the snmp.conf file; this allows - the backend to be easily disabled as needed (STR #2434) - - Added a new cupsctl command for doing basic changes to - the cupsd.conf file (STR #1777) - - Added a new ppdLocalizeIPPReason() function to get the - localized text/URI for a given IPP reason keyword for a - driver. - - Removed the deskjet2.ppd driver, as it only worked with - a very small subset of HP DeskJet printers and was - confusing to users. The rastertohp driver still - supports the deskjet2.ppd options for existing queues. - - The scheduler did not add a trailing banner page if a - client did not specify the last document in a job (STR - #1711) - - The scheduler did not report Bonjour shared printers as - remote printers (STR #2384) - - Added new -R and -W options to the cupstestppd program - for greater control over the testing of PPDs. - - Added a new cupsGetServerPPD() function for getting - an available PPD from the server (STR #2334) - - Added a new cupsDoIORequest() function for reading - and writing files via IPP requests (STR #2334) - - Added a new CUPS_GET_PPD operation for getting an - available PPD file on the server (STR #2334) - - CUPS_GET_PPDS now reports multiple ppd-product values - based on the PPD ModelName and Product strings (STR - #2334, STR #2383) - - CUPS_GET_PPDS now reports the PSVersion attributes - from a PPD file in the ppd-psversion attribute - (STR #2334) - - CUPS_GET_PPDS now reports the cupsModelNumber attribute - from a PPD file in the ppd-model-number attribute (STR - #2383) - - CUPS_GET_PPDS now reports a driver type string in the - ppd-type attribute based on the cupsFax and cupsFilter - attributes in a PPD file (STR #2383) - - Added a new printer attribute called "cups-version" - which reports the version of CUPS that is running - (STR #2240) - - backendRunLoop() now aborts immediately on SIGTERM - if no data has been written yet (STR #2103) - - Due to poor IPP support from the vendors, the SNMP - backend no longer tries IPP connections; instead, - it now uses a lookup file with fallback to port 9100 - (socket://address) and 515 (lpd://address) printing - (STR #2035, STR #2354) - - The scheduler now recreates the CUPS log directory as - needed (STR #2353) - - cupsLangDefault() now maps new-style Apple locale names - to the traditional ll_CC form (STR #2357) - - Add new cupsArrayNew2() API to support hashed lookups - of array elements (STR #2358) - - ppdConflicts() optimizations (STR #2358) - - The cupstestppd program now tests for existing filters, - icons, profiles, and dialog extensions (STR #2326) - - The web interface no longer lists new printers on the - main administration page. Instead, a new "List Available - Printers" button is provided that shows a separate page - with the list of printers. - - The web interface now supports setting the banner and - policy options on raw printers and classes (STR #2238) - - The socket backend now reads any pending back-channel - data before shutting down the socket (STR #2325) - - Added a new ErrorPolicy directive in the cupsd.conf - file (STR #1871) - - Printers that use JCL options are now exported to Samba - correctly (STR #1985) - - The IPP backend now relays printer-state-message values - from the server to the client (STR #2109) - - Added support for the PWG printer-alert and - printer-alert-description attributes (STR #2088) - - Added support for LPD "stream" mode (STR #2036) - - The scheduler now reports the PostScript product string - from PPD files in CUPS-Get-PPDs responses (STR #1900) - - Raw printing with queues pointing to the file pseudo- - device and multiple files and/or banners now works (STR - #1933) - - Added new public cupsAdminGetServerSettings() and - cupsAdminSetServerSettings() APIs. - - Added new "makebuttons" script in the "tools" directory - for creating web interface buttons (STR #2231) - - Added support for DNS-SD (aka "Bonjour") printer sharing - (STR #1171) - - Job operations (cancel, hold, release, etc.) from the - web interface now return back to the original page (STR - #2239) - - The classes or printers list is now shown after a - successful deletion from the web interface (STR #1999) - - The default configuration now allows browse packets from - any address (STR #2008) - - The web interface now provides an "allow printing from the - Internet" check box (STR #1897) - - The notify-events-default and - notify-lease-duration-default attributes can now be set - (STR #1671) - - Server-side default options are now sent to clients when - the "printer-defaults" attribute group is requested (STR - #1923) - - Added support for Linux "relro" linker option (STR #1614) - - CUPS now validates the number-up option value (STR #1329) - - The on-line help now provides better search capabilities - (STR #1701) - - The web interface "Add This Printer" button now allows you - to change the printer name, description, and location - (STR #1646) - - Added support for Mac OS X authorization services - (STR #2206) - - Added support for driver-specific pre-filters (STR #2108) - - Added a new side-channel API for drivers and backends - for basic device control and information queries (STR - #1898) - - The scheduler now uses poll(), epoll(), or /dev/kqueue - instead of select() when possible (STR #1261) - - Added new cupsArrayGetIndex() and cupsArrayGetInsert() - functions to get the current index and insertion - positions of an array. - - Added a new --with-max-copies configure option (STR - #2090) - - Added new cupsRemoveDest() and cupsSetDefaultDest() - functions. - - Added support for cupsPJLCharset attribute in PPD files - which specifies the character set that is used in PJL - strings (STR #1969) - - Moved the definition of the (private) _http_s structure - to http-private.h; code that directly accesses the - http_t members will no longer compile! - - Added support for setting the document-format-default - attribute on a per-printer basis. - - Added support for IntelliBar label printers. diff --git a/CHANGES-1.4.txt b/CHANGES-1.4.txt deleted file mode 100644 index 09326b2..0000000 --- a/CHANGES-1.4.txt +++ /dev/null @@ -1,843 +0,0 @@ -CHANGES-1.4.txt ---------------- - -CHANGES IN CUPS V1.4.8 - - - The scheduler would delete job data files when restarted (STR #3880) - - The network backends could crash if a printer returned a value of 0 - for the maximum capacity for a supply (STR #3875) - - -CHANGES IN CUPS V1.4.7 - - - Documentation changes (STR #3710, STR #3720, STR #3745, STR #3750, - STR #3757, STR #3758, STR #3782, STR #3826, STR #3829, STR #3837) - - Web interface fixes (STR #3412, STR #3345, STR #3455, STR #3707, - STR #3755, STR #3769, STR #3783) - - Configure script fixes (STR #3659, STR #3691) - - Compilation fixes (STR #3718, STR #3771, STR #3774) - - The imageto* filters could crash with bad GIF files (STR #3867) - - The scheduler might leave old job data files in the spool directory - (STR #3795) - - CUPS did not work with locales using the ASCII character set - (STR #3832) - - httpAddrString() did not return a URI-style IPv6 numeric address - (STR #3814) - - Fixed an issue when reading compressed CUPS raster streams (STR #3812) - - Fixed an issue with PostScript printer auto-configuration (STR #3443) - - Fixed some compatibility issues with the libusb-based USB backend - (STR #3799) - - The network backends no longer try to collect SNMP supply and status - information for raw queues (STR #3809) - - The DBUS notifier did not report job state changes (STR #3805) - - The scheduler did not always report that the "normal" print-quality - value was supported (STR #3803) - - The gziptoany filter did not report the correct error if it was unable - to write the uncompressed document to the next filter or backend in - the chain (STR #3797) - - The Epson and Oki 9-pin drivers had a bad resolution option - (STR #3798) - - The scheduler did not always register the correct default ICC profile - on Mac OS X. - - The scheduler did not use the job owner when authorizing access for - the CUPS-Get-Document operation, preventing non-admins from accessing - their own jobs. - - CUPS did not work with some printers that incorrectly implemented the - HTTP/1.1 standard (STR #3778, STR #3791) - - The scheduler did not retry fax jobs properly. - - The scheduler now recognizes an empty cupsCommands PPD keyword as - meaning that CUPS commands are not supported for a printer (STR #3773) - - Fixed a crash bug in the scheduler when the application/octet-stream - MIME type was not defined (STR #3690) - - Polled printers were advertised more slowly than necessary (STR #3574) - - cupsResolveConflicts() did not handle resolving multiple UIConstraints - issues (STR #3705) - - The SetEnv and PassEnv directives had no effect (STR #3664) - - The libusb-based USB backend printed slowly to the LaserJet 1300 and - other printers (STR #3405) - - "lp" and "lpr" failed to print with Kerberos enabled (STR #3768) - - The cupsctl program now displays an error if you try to directly set - the Port or Listen directives (STR #3749) - - PPD files with "*JobPatchFile: bla" no longer fail to load in relaxed - conformance mode (STR #3747) - - The scheduler generated a bad notify-text string for printer state - change notifications (STR #3739) - - The scheduler incorrectly updated printers.conf when it really needed - to update classes.conf or remote.cache (STR #3726) - - Hardwired remote printers with options did not work (STR #3717) - - Accessing the CUPS web interface using a CNAME-based hostname would - sometimes fail due to redirection to the actual hostname (STR #3701) - - Subscription events had a misspelled attribute (STR #3693) - - "make check" failed if LC_MESSAGES was set (STR #3765) - - Fixed the configure script to always look for the pkg-config script - (STR #3761) - - The scheduler now only looks up interface hostnames if HostNameLookups - are enabled (STR #3737) - - Fixed a compilation problem on DragonFly BSD (STR #3738) - - The default PageLogFormat value had the username and job ID swapped - from CUPS 1.3.x (STR #3727) - - The scheduler could crash if a browsed printer times out while a job - is printing (STR #3754) - - The scheduler incorrectly mapped custom page sizes to standard sizes - (STR #3764) - - cupsfilter and pstops did not map IPP attributes to PPD options due to - a change in cupsMarkOptions (STR #3756) - - The scheduler did not always show the most recent status message from - the print filters (STR #3731) - - The PostScript filter did not apply the mirror and number-up options - properly, leading to offset and clipped output (STR #3732) - - The network backends always reported "low toner" or "out of toner" - states, even for inkjet printers (STR #3733) - - -CHANGES IN CUPS V1.4.6 - - - Fixed a "make check" issue on Solaris (STR #3729) - - Regression: The pstops filter did not support landscape printing of - PostScript files (STR #3722) - - The scheduler killed retried (fax) jobs after restarting them - (STR #3697) - - The cupsAdminSetServerSettings() function disabled sharing when - debug logging was enabled (STR #3712) - - -CHANGES IN CUPS V1.4.5 - - - Documentation fixes (STR #3542, STR #3650) - - Localization fixes (STR #3635, STR #3636, STR #3647, STR #3666) - - Security: Fixed a memory corruption bug reported in CVE-2010-2941 - (STR #3648) - - The CUPS API incorrectly mapped the HTTP_UNAUTHORIZED status to the - IPP_NOT_AUTHORIZED status code, when IPP_NOT_AUTHENTICATED would be - the correct mapping (STR #3684) - - The scheduler would restart jobs while shutting down (STR #3679) - - Fixed a PPD loader bug that could cause a crash in cupsd (STR #3680) - - Improved the mapping of non-standard PPD and PWG names (STR #3671) - - The scheduler did not initialize Kerberos in all cases (STR #3662) - - cupsAdminSetServerSettings duplicated Listen and Order lines - (STR #3645) - - Added DeviceN colorspace support to the CUPS Raster format (STR #3419) - - ppdMarkDefaults() did not clear the marked field of the previous - choices (STR #3642) - - The serial backend would not allow a raw job to be canceled - (STR #3649) - - The socket backend could go into an infinite loop with certain - printers (STR #3622) - - Setting the PRINTER or LPDEST environment variables to "name/instance" - did not work (STR #3485) - - The scheduler did not handle the JobRetryLimit setting properly - (STR #3466) - - The lpstat command always showed a remote job ID of 0 for shared - printers (STR #3627) - - Increased the write timeout for the libusb-based USB backend to 5 - minutes (STR #3595) - - The libusb-base USB backend did not check whether the printer has a - serial number (STR #3590) - - The lpadmin command did not support setting of custom option values - (STR #3631) - - The lpadmin command did not support setting of the location or - description of a class (STR #3613) - - The cupsaddsmb command did not give up after too many failed attempts - (STR #3615) - - The CUPS library no longer uses certain problematic ctype macros that - change based on the locale's character set. - - PJL value substitution of more than 9 values was broken (STR #3621) - - Custom options with missing string values caused ppdEmit* to segfault - (STR #3620) - - Fixed an issue with the Italian version of the web interface - (STR #3624) - - Fixed the Solaris SMF configuration file for cups-lpd (STR #3611) - - The scheduler did not set the notify-subscribed-event attribute when - delivering printer-added or printer-modified events (STR #3608) - - The mailto notifier could get into an infinite loop (STR #3609) - - Date/time information was not shown in banner pages. - - Relational operators were broken in #if/#elif/#else/#endif expressions - for the PPD compiler. - - Moving a job via the web interface failed without asking for - authentication (STR #3559) - - The scheduler now clears the printer-state-reasons when the driver is - changed (STR #3570) - - The web interface did not allow a user to change the driver - (STR #3537, STR #3601) - - The scheduler was not setting the PATH_INFO environment variable when - needed (STR #3600) - - The scheduler incorrectly set the CUPSD_AUTH_TYPE environment - variable instead of AUTH_TYPE (STR #3599) - - Fixed a buffer overrun in the PPD compiler (STR #3594) - - Fixed some additional IPP job template attribute mapping issues in the - scheduler. - - -CHANGES IN CUPS V1.4.4 - - - Documentation updates (STR #3453, STR #3527, STR #3528, STR #3529) - - Security: The fix for CVE-2009-3553 was incomplete (STR #3490) - - Security: The texttops filter did not check the results of allocations - (STR #3516) - - Security: The web admin interface could disclose the contents of - memory (STR #3577) - - Security: CUPS could overwrite files as root in directories owned or - writable by non-root users (STR #3510) - - The cups-config utility did not return the correct linker options on - AIX (STR #3587) - - Fixed some IPP conformance issues with the scheduler's - ippget-event-life, operations-supported, output-bin, and sides - attributes (STR #3554) - - The OpenSSL interfaces have been made thread-safe and the GNU TLS - interface is explicitly forbidden when threading is enabled - (STR #3461) - - Fixed an IPP conformance issue with the scheduler's Send-Document - implementation (STR #3514) - - Added additional validation checks for the 1284 device ID (STR #3534) - - Fixed a problem with the RPM spec file (STR #3544) - - The lpstat command did not limit the job list to the specified - printers (STR #3541) - - The cupsfilter command did not set the RIP_MAX_CACHE environment - variable (STR #3531) - - Fixed support for media-col and page size variants (STR #3394) - - The PostScript filter did not support all media selection options for - the first page (STR #3525) - - The scheduler did not always remove job control files (STR #3425) - - The scheduler could crash on restart if classes were defined - (STR #3524) - - The scheduler no longer looks up network interface hostnames by - default on Mac OS X (STR #3523) - - ippWriteIO did not write collection (member) attributes properly in - all cases (STR #3521) - - The "cupsctl --remote-any" and corresponding web interface check box - (allow printing from the Internet) did not work reliably (STR #3520) - - The lpq and lpr commands would sometimes choose different default - printers (STR #3503) - - cupsDo*Request did not flush error text, leading to multiple issues - (STR #3325, STR #3519) - - cupsDoAuthentication did not cancel password authentication after 3 - failures (STR #3518) - - Fixed several LDAP browsing bugs (STR #3392) - - The Dymo driver did not support copies (STR #3457) - - The scheduler did not update the classes.conf file when deleting a - printer belonging to a class (STR #3505) - - The lppasswd command did not use localized password prompts - (STR #3492) - - The socket backend no longer waits for back-channel data on platforms - other than Mac OS X (STR #3495) - - The scheduler didn't send events when a printer started accepting or - rejecting jobs (STR #3480) - - The web interface now includes additional CSRF protection (STR #3498) - - -CHANGES IN CUPS V1.4.3 - - - SECURITY: The scheduler could try responding on a closed client - connection, leading to a crash (STR #3200) - - SECURITY: The lppasswd program allowed the localization files to be - overridden when running in setuid mode (STR #3482) - - Localization updates (STR #3352, STR #3409, STR #3422, STR #3452, - STR #3473, STR #3502) - - Documentation updates (STR #3451, STR #3504) - - The IPP backend now sets the printer-state-message to "Ready to - print." at the end of a successful job (STR #3460) - - The PPD compiler did not correctly add the manufacturer to the output - filename when using the "-m" option (STR #3469) - - The IPP backend did not handle authentication properly for the Get- - Printer-Attributes operation (STR 3458) - - Getting SNMP values larger than 127 bytes did not work. - - IPP conformance: Get-Jobs has a default value for requested-attributes - (STR #3383) - - cupsPrintFiles() did not report all errors (STR #3449) - - cupsAddDest() could read freed memory (STR #3448) - - The DBUS notifier did not build (STR #3447) - - The scheduler would crash when an active printer was deleted. - - The snmp backend did not work with some printers (STR #3413) - - The web interface did not show the conflicting values when setting - options (STR #3440) - - Setting options in the web interface did not always work (STR #3439) - - The scheduler did not use the Get-Job-Attributes policy for a printer - (STR #3431) - - The scheduler added two job-name attributes to each job object - (STR #3428) - - CSS files would not print (STR #3442) - - The scheduler did not clean out completed jobs when PreserveJobHistory - was turned off (STR #3425) - - The web interface did not show completed jobs for a printer - (STR #3436) - - Authenticated printing did not always work when printing directly to - a remote server (STR #3435) - - The USB backend did not work on Solaris (STR #3423) - - cupstestppd didn't catch problems with JobPatchFile definitions - (STR #3421) - - The socket backend could crash if a SNMP string had a negative length. - - Fixed some termination issues with the USB backend on Mac OS X. - - The side-channel APIs did not handle interrupts properly. - - The network backends incorrectly cleared the media-empty-warning - state. - - The web interface did not allow users to successfully add serial - printers (STR #3391) - - cupsTempFd() did not work in some situations (STR #3382) - - Some C API headers were missing C++ wrapper logic. - - The PPD compiler did not localize single-language PPD options properly - (STR #3386) - - Modifying a printer from the web interface sometimes caused the wrong - driver to be selected (STR #3418) - - The scheduler did not handle out-of-memory conditions properly when - loading a job (STR #3407) - - When adding printers from the web interface, the dynamic updates of - the device list made it hard to pick a device (STR #3406) - - Fixed a typo in the web interface admin page template (STR 3403) - - The web interface did not preserve the "printer is shared" state when - modifying a printer (STR #3390) - - The PPD compiler incorrectly inserted translations of empty strings - (STR #3411) - - The scheduler did not reset the SIGPIPE handler of child processes - (STR #3399) - - cupsGetNamedDest() incorrectly returned the default printer if the - named printer did not exist (STR #3397) - - Fixed a GNU TLS error handling bug (STR #3381) - - -CHANGES IN CUPS V1.4.2 - - - SECURITY: The CUPS web interface was vulnerable to several XSS and - HTTP header/body attacks via attribute injection (STR #3367, - STR #3401) - - Fixed localization errors (STR #3359, STR #3372, STR #3380, STR #3387) - - The documentation for classes.conf and printers.conf did not provide - the correct instructions for manual changes (STR #3351) - - The scheduler did not always rebuild printer cache files when the - driver was changed (STR #3356) - - The documentation makefile failed to install localizations when using - newer versions of Bash (STR #3360) - - The configure script did not use the --with-xinetd value for the - default LPD configuration path (STR #3347) - - The configure script incorrectly required glib for DBUS support - (STR #3346) - - The cupstestppd program incorrectly reported filters with bad - permisssions as missing (STR #3363) - - The cups.desktop file used the wrong locale names (STR #3358) - - cupsSideChannelRead() did not return an error for short reads. - - The installed PAM configuration file did not use the correct options - with the pam_unix2 module (STR #3313) - - The scheduler did not preserve default options that contained special - characters (STR #3340) - - The scheduler did not remove old pre-filters when updating a printer - driver (STR #3342) - - The HP/GL-2 filter did not check for early end-of-file (STR #3319) - - The USB backend did not compile on some platforms (STR #3332) - - cupsSideChannelSNMPWalk() could go into an infinite loop with broken - SNMP implementations. - - -CHANGES IN CUPS V1.4.1 - - - Documention fixes (STR #3296) - - SNMP supply levels and states were wrong for some printers. - - The IPP backend did not update the auth-info-required value. - - The libusb-based USB backend would hang at the end of the job - (STR #3315, STR #3318) - - DNS-SD registrations for raw queues had an empty "ty" key (STR #3299) - - The JPEG and BMP MIME type rules were broken (STR #3284) - - cupsGetNamedDest returned the default printer when the named - destination did not exist (STR #3285) - - The JobKillDelay was not triggered for canceled jobs (STR #3292) - - The PPD compiler could get in an infinite loop (STR #3293) - - The configure check for dns-sd.h was broken (STR #3297) - - The "Query Printer for Default Options" page did not go away if the - query job was held (STR #3302) - - Boolean options did not show up as selected in the web interface - (STR #3303) - - The scheduler did not cache or report driver information files - correctly, leading to a variety of issues (STR #3283, STR #3297, - STR #3305) - - cupsDoIORequest() did not abort on permanent errors (STR #3311) - - Modifying a class in the web interface did not work (STR #3312) - - BrowseLocalProtocols could be cleared when changing the sharing - setting (STR #3287) - - The scheduler could return an empty supported document format - (STR #3308) - - The PPD compiler generated invalid PPD files when the locale used - something other than "." for the decimal point (STR #3300) - - The IPP backend did not handle some non-comforming IPP printer - implementations (STR #3262) - - The scheduler leaked three file descriptors to each job filter - (STR #3263) - - The scheduler now uses a default CUPS-Get-Devices timeout of 15 - seconds (STR #3307) - - -CHANGES IN CUPS V1.4.0 - - - Localization updates (STR #3223, STR #3246, STR #3248, STR #3250) - - Documentation updates (STR #3225, STR #3230, STR #3242, STR #3260) - - The --with-pdftops configure option did not accept a full path to the - filter (STR #3278) - - The banner filter did not position the back side image correctly - (STR #3277) - - The dnssd backend could crash (STR #3272) - - The 1284 device ID sometimes contained trailing garbage (STR #3266) - - The USB backend returned different URIs for some printers than in - CUPS 1.3 (STR #3259) - - The scheduler did not do local job-hold-until processing for remote - queues (STR #3258) - - The scheduler did not try all possible SSL certificates on Mac OS X. - - The scheduler did not always remove a file descriptor when using the - kqueue interface (STR #3256) - - The scheduler did not protect against bad job control files in all - cases (STR #3253) - - The scheduler did not encode "+" in model names (STR #3254) - - The web interface didn't show the default options (STR #3244) - - The IPP and LPD backends needed print data before they would do an - SNMP query. - - Fixed a GNU TLS compatibility issue (STR #3231) - - Fixed a HTML error in the add and modify printer web interface - templates (STR #3229) - - The scheduler did not minimize the number of printer state events that - were generated by filter STATE: messages, which could lead to poor - performance. - - The USB backend on Mac OS X did not cleanly cancel a job. - - The network backends now set the connecting-to-device printer-state- - reasons value when looking up the address and copying the print data - for consistency. - - The scheduler now supports the com.apple.print.recoverable-warning - reason on all platforms. - - -CHANGES IN CUPS V1.4rc1 - - - The PPD compiler documentation was missing information on localization - (STR #3212) - - The IPP backend now reconnects after every request when talking to - printers that claim IPP support but only use HTTP/1.0. - - The PPD compiler crashed when both "Resolution" and "Group foo Option - Resolution" were specified in the .drv file. - - The PPD compiler's #if/#elif/#else/#endif did not work for undefined - variables (STR #3210) - - Static libraries could not be installed by a non-root user on systems - needing a ranlib program (STR #3209) - - The scheduler incorrectly always tried to copy Kerberos credentials - for print jobs. - - Updated the Spanish localization (STR #3204) - - The scheduler crashed when getting the default paper size from - libpaper (STR #3205, STR #3206) - - The PPD compiler now defines six variables: CUPS_VERSION, - CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR, CUPS_VERSION_PATCH, - PLATFORM_NAME, and PLATFORM_ARCH (STR #3203) - - Fixed a whitespace skipping bug in cupsRasterInterpretPPD. - - The scheduler did not return HTTP 403 (Forbidden) for authenticated - users that were not authorized to do IPP operations (STR #3193) - - The scheduler did not report more than 8 Product strings from a PPD - file. Some PPD files have as many as 24. - - ppdOpen*() could crash if a keyword had no value string (something - that cupstestppd looks for...) - - cupsLangDefault() did not return the correct language on Mac OS X. - - The Mac OS X USB backend did not handle aborted or stalled pipe - conditions properly, which prevented drivers from ejecting partial - pages when a job was canceled or held. - - -CHANGES IN CUPS V1.4b3 - - - Documentation fixes (STR #3044, STR #3057, STR #3153, STR #3158, - STR #3173) - - Added complete localizations for German, Japanese, Polish, and - Russian and partial localizations for Chinese, Danish, Finnish, - French, Italian, Korean, Norwegian, Portuguese, and Swedish - (STR #3096, STR #3098, STR #3109, STR #3111, STR #3141) - - Updated the configure check for -fstack-protector (STR #3198) - - The network backends now correctly convert SNMP supply descriptions to - UTF-8 encoding as needed. - - The scheduler could crash when deleting an attribute (STR #3197) - - The cups-driverd program did not detect symlink loops (STR #3185) - - The EPSON 24-pin series driver should now feed the correct amount - (STR #2624) - - The scheduler now automatically logs the last N debug messages for - failed print jobs. - - You can now modify a raw print queue (STR #3133) - - Fixed a number of ppdi issues and added a unit test to validate that - ppdc + ppdi can generate and import the same data (STR #3152) - - Moving jobs in the web interface now shows an error if you only have - one printer or class added (STR #3094) - - Since classes have never truly supported the printer-error-policy - stuff added in CUPS 1.2, update the code to reflect the current - reality and support only the retry-current-job policy for now - (STR #3171) - - Revised the password callback support (STR #2953) - - ppdEmit*() did not choose between PageSize and PageRegion properly. - - Make some fairly substantial changes to the Kerberos support code so - that CUPS can work in multi-realm environments and does not require - delegatable credentials. Shared printing still requires delegation, - however "delegation by policy" can be enabled in the KDC to make this - all work. - - "AccessLogLevel actions" did not hide client-error-not-found errors. - - AP_FIRST_InputSlot did not work with number-up. - - cupsBackChannelRead() and cupsBackChannelWrite() could fail due to a - lack of kernel buffers. - - The IPP and LPD backends did not respond to side-channel requests - while copying print data to a temporary file. - - cupsWriteRequestData() flushed the output buffer unnecessarily, - causing reduced performance in some situations. - - If a CGI process died before sending its MIME headers, the request - would hang on the client. - - The printer/class/job search feature on the web interface did not - work (STR #3132) - - The scheduler did not write the printers out for classes. - - CUPS-Get-PPDs did not work properly when filtering by language, - product, or psversion (STR #3136) - - The scheduler now kills job filters when it takes more than 30 seconds - (configurable) to cancel or hold the job. - - The cupstestppd program did not validate the capitalization of - filenames in the PPD file. - - The cupstestppd program did not validate the PageSize and PageRegion - values. - - The cups-deviced helper program could miss reporting some backend - devices (STR #3108) - - The cupsSideChannelSNMP* functions did not work. - - The scheduler could consume 100% CPU when jobs were canceled. - - Clicking on "Select Another Make/Manufacturer" in the web interface - incorrectly added the printer (STR #3095) - - The scheduler no longer uses programs with insecure file - permissions. - - httpAssembleURI*() did not escape backslashes in hostnames. - - The dnssd backend did not unquote "full names" before creating the - device URI. - - The scheduler now supports JobRetryInterval values less than 10 - seconds. - - Updated the Spanish localization (STR #3090) - - The scheduler did not redo Bonjour/DNS-SD registrations when updating - them failed. - - The "authenticated" policy incorrectly required authentication for - status operations. - - ppdOpen*() incorrectly loaded PPDs with multiple JobPatchFile - keywords. - - The network backends no longer report the SNMP "offline" or - maintenance status bits since they are inconsistently implemented and - often unreliable. - - The scheduler no longer logs child processes killed via SIGKILL as - "crashed". - - The printer link shown on the "job moved" template was bad (STR #3085) - - Updated the HTML templates to use the final HTML 4 DOCTYPE (STR #3086) - - The scheduler did not track the "paused" reason properly if a - printer had other reasons associated with it. - - cupsSendRequest() did not clear old local certificate auth data. - - The PPD compiler did not search for localization files properly - (STR #3084) - - cupsGetNamedDest() did not use the fallback default like - cupsGetDests*() (STR #3082) - - The scheduler now provides a LogTimeFormat directive to enable - microseconds in the date and time that are logged. - - The scheduler now provides a MultipleOperationTimeout directive to - control the timeout for multi-file print jobs. - - The configure script incorrectly allowed Avahi to be used for DNS-SD - printer discovery (STR #3065) - - The web interface and scheduler did not support URIs up to 1024 bytes - in length (STR #3072) - - Fixed pdftops issues with page sizes (STR #3063) - - Fixed pdftops issues with Ghostscript (STR #3062) - - The scheduler incorrectly registered default profiles for PostScript - printers with no specified colorspace. - - The scheduler incorrectly created an empty org.cups.printers.plist - file on Mac OS X. - - cupsGetPPD3() did not look for local PPDs in the right directory. - - SNMP lookups via side-channel did not work for NULL-VALUE and - and OCTET-STRING OIDs containing nul characters. - - The libusb-based USB backend did not work. - - The scheduler did not set the printer-commands attribute correctly - for some PPDs. - - The ppdi utility did not work. - - The web interface no longer uses multi-part output with old or broken - web browsers (STR #3049) - - CUPS now conforms to the draft IPP/2.0 and IPP/2.1 specification. - - Added a new cupsGetConflicts() API to get a list of conflicting - options. - - The PPD compiler didn't localize options or choices that did not - have associated translation text (STR #3045) - - Updated the Spanish localization (STR #3043) - - Fixed build problems (STR #3040, STR #3047) - - cupsResolveConflicts() did not resolve using the default option - choice in some cases due to the mirror UIConstraints that are - present in most PPD files. - - The scheduler did not honor MIME type priorities. - - The commandtops filter incorrectly used the JCLBegin code to end - its jobs. - - The default BrowseLocalProtocols value was not set properly. - - Since the commandtops filter does not actually support ReportLevels - all on its own, don't list that printer command by default for PS - printers. - - The scheduler did not give filters a chance to log errors or update - printer attributes when a job was canceled. - - The scheduler did not clear the "connecting-to-device" reason keyword - when a job finished. - - -CHANGES IN CUPS V1.4b2 - - - Documentation updates (STR #2983, STR #2998, STR #3021) - - The cupstestppd utility now validates the FileVersion and - FormatVersion values in PPD files. - - The default cupsd.conf file did not reflect the - --with-local-protocols value set at compile-time (STR #3037) - - The cupsGetPPD* APIs now create symlinks to local PPD files - rather than copying them whenever possible. - - Various performance optimizations in the string pool, dests, and - options implementations. - - The cupsGetDests* APIs now return the marker and printer-commands - attributes. - - Side-channel SNMP lookups would not work when cupsSNMPSupplies - was set to False in the PPD file. - - Localized the device descriptions for the SCSI, serial, - and network backends (STR #3014) - - Added a Spanish localization (STR #3015) - - Added support for marker-low-levels and marker-high-levels - attributes. - - The scheduler could hang writing a long log line. - - The cupsGetDevices() function now has an "include_schemes" - parameter. - - The lpinfo command now supports --include-schemes and - --exclude-schemes options. - - The CUPS-Get-PPDs operation now supports the include-schemes - and exclude-schemes attributes. - - The CUPS-Get-Devices operation now supports the include-schemes - attribute. - - The print filters now support a replacement for the fitplot - option called "fit-to-page". - - The LPD backend no longer tries to collect page accounting - information since the LPD protocol does not allow us to - prevent race conditions. - - The scheduler did not save the last marker-change-time value. - - Fixed a problem with printing to some IPP printers, including - CUPS 1.1.x. - - Fixed a redirection problem with the printer web page (STR #3012) - - Fixed a PPD compiler problem with the loading of message - catalogs (STR #2990) - - Fixed a PPD compiler problem with the loading of .strings files - (STR #2989) - - The cupsfilter utility did not set the CONTENT_TYPE environment - variable when running filters. - - The scheduler now waits to allow system sleep until the jobs - have all stopped. - - The IPP, LPD, and socket backends used different "connecting" - progress messages. - - -CHANGES IN CUPS V1.4b1 - - - Documentation updates (STR #2567) - - The PPD compiler now allows local message catalogs to - override the standard CUPS translations (STR #2642) - - The ppdmerge command did not merge custom option strings - (STR #2863) - - The scheduler now supports the Hold-New-Jobs and - Release-Held-New-Jobs operations; these are exposed via the - cupsdisable and cupsenable commands (STR #2332) - - The lpstat command is now much faster when displaying the - status of a single printer (STR #2843) - - The scheduler now caches information from PPD files to provide - significantly faster startup time with large numbers of PPDs - (STR #1293) - - CUPS-Get-Driver now provides much better driver matching based - on the IEEE-1284 device ID and make/model strings (STR #2707) - - Now support the cupsSNMPSupplies keyword to control whether - the network backends query the SNMP Printer MIB for supply - levels. - - Now support and use a new banner file format for better text - support and easier customization (STR #2490) - - The scheduler now sets the PRINTER_INFO and PRINTER_LOCATION - environment variables from the corresponding IPP attributes. - - The ippRead*() and ippWrite*() functions no longer use a - stack-based buffer (STR #2388) - - The CUPS-Add-Modify-Printer operation now allows you to set - the printer-state-reasons attribute. - - The "set printer options" page now supports auto-configuration - of printer options (STR #1440) - - The web interface now provides an advanced server settings - form. - - The web interface's "modify printer" pages now make it - easier to change just one setting (STR #1919) - - The scheduler now supports a plist PrintcapFormat. - - The scheduler now supports multiple addresses in Allow and - Deny lines, just like Apache (STR #2947) - - Added CUPS_JOBTYPE environment variable for job filters so - they know whether they are printing a banner or document - file (STR #2799) - - Added support for printer filtering by the cupsfilter - command (STR #2562) - - Added a SSLOptions directive to allow Windows clients to - talk to CUPS in FIPS mode (STR #2827) - - Renamed the accept and reject commands to cupsaccept and - cupsreject; the old names are still available (STR #2936) - - The locale/translate utility needed an update to work with - Google (STR #2882) - - The lpstat command now supports a -H option to display the - default server (STR #2833) - - The scheduler now supports a FatalErrors directive to control - which errors should cause the scheduler to exit (STR #2536) - - The scheduler now uses the php-cgi program if it is available - (STR #2923) - - The scheduler now supports a DefaultPaperSize directive - (STR #2848) - - The scheduler now passes the job-originating-host-name - value to filters in the options argument (STR #2558) - - CUPS now supports job tickets in PDF files (STR #2903) - - Added a DBUS notifier (STR #2529) - - The LPD mini-daemon now passes the document name when queuing - print jobs (STR #2482) - - The IPP backend did not relay com.apple.print.recoverable-message - values. - - The scheduler now supports a job-media-progress attribute to - track the progress of individual pages. - - The sample HP driver now supports A5 (STR #2798) - - The CUPS web interface menu item now uses the xdg-open - command, when available (STR #2724) - - The cups-lpd program now supports the -h option (STR #2794) - - The scheduler now sets the PAM_TTY parameter and the - PAM_ESTABLISH_CRED credential flag (STR #2745) - - The scheduler now logs unsuccessful requests to the error_log - file as errors (STR #2616) - - Added support for a "retry-current-job" error policy that - retries the current job immediately when the backend encounters - an error (STR #2555) - - The scheduler now returns a "forbidden" error when a user - correctly authenticates but does not have permission to - continue further (STR #2101) - - The scheduler now loads both the server and CA certificates - (if present) from the ServerCertificate file (STR #2146) - - New RSS subscriptions now create their feed files immediately - (STR #2853) - - Added support for a device-location attribute which provides - the physical location of a printer device. - - Added a cupsBackendReport() API which handles quoting of the - device data by a backend. - - Added support for custom options in the web interface - (STR #1729) - - Added support for Mozilla LDAP, reconnection to LDAP servers, - and improved LDAP performance (STR #1962) - - Added Solaris SMF support (STR #1477) - - Added optional support for using TCP wrappers to limit access - to CUPS (STR #263) - - Added ppdPageSizeLimits API. - - Added support for new cupsMediaQualifier2, cupsMediaQualifier3, - cupsMinSize, and cupsMaxSize attributes. - - Added cupsResolveConflicts and ppdInstallableConflict APIs. - - Added support for new cupsUIConstraints and cupsUIResolver - attributes for better option conflict detection and - resolution. - - Increased the maximum size of 1284 device ID strings to - 256 bytes (STR #2877) - - Added an AccessLogLevel directive to cupsd.conf to control - what is logged to the access_log file. - - The default LogLevel is now "warn" instead of "info" to reduce - the amount of logging that is done to disk by default. - - The PPD compiler did not include OID query keywords in PPD - files (STR #2871) - - The cups-driverd helper program now directly supports driver - information files. - - The USB backend now uses libusb when available (STR #1575) - - Added ppdLocalizeAttr function to get the localized version - of an attribute. - - MIME types now support a priority() attribute (STR #2719) - - The standard MIME types are now installed in - DataDir/mime (STR #2719) - - The lpoptions command now describes custom options and - the necessary parameters (STR #2660) - - The ppdmerge program did not support Simplified Chinese - or Traditional Chinese language version strings (STR #2851) - - The PPD compiler now supports localizable attributes - (STR #2738) - - The ppdpo utility now includes cupsIPPReasons values in - the message catalogs it generates (STR #2754) - - The PPD compiler now supports conditional directives - (STR #2636) - - The ppdc utility now supports a "-t" option to test PPD - files (STR #2739) - - The ppdc utility now supports a "-m" option to use the - ModelName value as the output filename. - - The ppdc utility now supports a FileName directive to - set an alternate output filename (STR #2740) - - The side-channel API now supports SNMP queries for the - standard network backends. - - Added a PageLogFormat directive to the cupsd.conf file to - control the format of lines in the page_log file. - - Filters can now send PPD: messages to stderr to set PPD - keywords like DefaultPageSize while a job is printing. - - Added a mdns backend for discovery and printing to printers - that advertise themselves via DNS-SD (Bonjour) - - The ipp, lpd, and socket backends now support DNS-SD service - name resolution. - - The scheduler now uses a single shared file descriptor for - all DNS-SD registrations (STR #2674) - - The ipp, lpd, and socket backends now support SNMP-based - page accounting and supply level monitoring (STR #1655) - - Added support for cupsPJLDisplay attribute to control what - PJL commands are used to display the job information. - - Driver information files can now be installed in - /Library/Printers/PPDs.drv on Mac OS X. - - The CUPS image library now supports reading images larger - than 2GB. - - The scheduler now delays writing config and state files to - reduce disk activity (STR #2684) - - The CUPS-Get-Devices operation now supports the - exclude-schemes and timeout attributes to control which - backends are polled and for how long. - - The cups-deviced helper application now runs backends in - parallel to get the list of devices faster. - - Added --enable-pap configure option. - - The default cupsd.conf file now includes an "authenticated" - policy which requires authentication for remote print jobs. - - Added support for Czech and Hungarian in PPD files - (STR #2735, STR #2736) - - The PPD compiler tools now support Mac OS X .strings files - for localization (STR #2737) - - ppdOpen*() now default the colorspace member to PPD_CS_N - when no DefaultColorSpace attribute is present in the PPD - file. - - The build system has been updated to support separate - installation of data, program, header, and library files. - - All support libraries are now built as shared libraries - by default. - - The scheduler now manages ICC color profiles on Mac OS X. - - The network backends (ipp, lpd, socket) now support - SNMP-based supply and page count monitoring (STR #1655) - - The lppasswd program is no longer installed setuid to - root to make the default installation more secure. - - Added a new ppdLocalizeMarkerName() function to get - the localized version of a marker-names value. - - The scheduler now provides the printer-dns-sd-name - attribute for printers shared via DNS-SD/Bonjour. - - The pdftops filter now executes the Xpdf or poppler - pdftops utility to convert PDF files (STR #1471) - - Bonjour printer registrations now advertise as local or - global based on the current access policies for the - printer. - - cupsGetDests*() and cupsSetDests*() now track the last - used printer preference on Mac OS X. - - Added a new streaming request API (STR #2261) - - Added a new cupsGetNamedDest() function to the CUPS - library for faster printing with lp and lpr (STR #2638) - - The scheduler now sets the PAM RHOST value on systems - that support it (STR #2637) - - The scheduler now sandboxes child processes when - possible. - - The Cancel-Job operation now supports a purge-job - attriibute to purge a specified job. - - ppdEmit* and ppdCollect* now use the NonUIOrderDependency - attributes for custom option selections. - - The web interface now enables/disables the printer - sharing (formerly publishing) controls based on the - server-is-sharing-printers state (STR #2233) - - The scheduler now tracks printer sharing via the - server-is-sharing-printers attribute, and manages LPD - and SMB sharing as well (STR #2233) - - The web interface now allows you to go back to the make/ - manufacturer page if there is no matching printer driver - on the model page (STR #2436) - - The printer list now shows the default media, banner, and - duplex options as well as the color and duplex capabilities - of printers (STR #1175) - - The web interface look-n-feel has been updated (STR #2492) - - The scheduler now supports a CUPS-Get-Document operation - that returns the specified print job document (STR #118) - - The cupsfilter utility now supports a "-J jobid" option - to filter the document from the specified job. - - The scheduler (cupsd) now supports a new option (-t) to - do a syntax check of the cupsd.conf file (STR #2003) - - Added new cupsGetPPD3() API to allow applications to - cache PPDs safely (STR #1473) - - Added generic PostScript and PCL printer driver PPDs. diff --git a/CHANGES-1.5.txt b/CHANGES-1.5.txt deleted file mode 100644 index 39edb42..0000000 --- a/CHANGES-1.5.txt +++ /dev/null @@ -1,312 +0,0 @@ -CHANGES-1.5.txt ---------------- - -CHANGES IN CUPS V1.5.4 - - - Documentation updates (STR #4112, STR #4130, STR #4134) - - Fixes for libusb-based USB backend (STR #4128) - - The lpq command did not show the owner or title of jobs unless passed - a username on the command-line (STR #4135) - - Localized empty strings contained the message catalog metadata - (STR #4119) - - Fixed a crash in the libusb-based USB backend (STR #4099) - - The cups-lpd mini-daemon no longer handled jobs with multiple copies - (STR #4118) - - Multiple libusb backend fixes (STR #4098, STR #4100) - - The IPP backend no longer tries to get the job status for printers - that do not implement the required operation (STR #4083) - - Sending a document in an unsupported format to an IPP printer now - automatically cancels the job (STR #4093) - - Fix some error reporting issues when printing from /dev/null and - other unusual situations (STR #4015) - - The scheduler now sets the CUPS_MAX_MESSAGE environment variable for - filters (STR #4074) - - Fixed a build issue when using older versions of autoconf (STR #4084) - - The IPP backend now treats the client-error-not-possible status code - as a job history issue, allowing IPP printing to Windows to work - (STR #4047) - - The IPP backend incorrectly included the document-format and - compression attributes in Create-Job requests (STR #4086) - - The libusb-based USB backend did not work on non-Linux platforms - (STR #4088) - - -CHANGES IN CUPS V1.5.3 - - - httpReconnect() did not reset the read/write buffers (STR #4065) - - Compiling without threading support failed (STR #4060) - - Fixed compile problem with old versions of OpenSSL (STR #4036) - - The network backends did not check SNMP supply levels regularly - (STR #4040) - - The online help always included the "help on help" text (STR #4042) - - Fixed a SSL handshake issue on OS X (STR #4045) - - The scheduler could crash if a PPD file contained an invalid paper - size (STR #4049) - - The CUPS polling daemon did not reinitialize its connection to the - remote server on errors in all cases (STR #4031) - - PostScript auto-configuration was slow and unreliable with some - printers (STR #4028) - - Missing localizations caused empty output (STR #4033) - - The cups-driverd program could temporarily "forget" a PPD file if it - was updated in place. - - The dnssd backend now prefers IPPS over IPP. - - The USB backend now uses and requires LIBUSB 1.0 or later (STR #3477) - - The LIBUSB-based USB backend now supports the back-channel (STR #2890) - - Changed how timeouts are implemented in the LPD backend (STR #4013) - - Added more supported color names for SNMP supplies (STR #3981) - - The default InputSlot setting was never used (STR #3957) - - POSIX ACLs are now set properly on certificate files (STR #3970) - - Supplies with commas in their names were not reported correctly - (STR #4020) - - The cupsGetPPD3() function created a temporary file when one was not - needed (STR #4018) - - The scheduler now ensures that job notifications contain a value for - the notify-printer-uri attribute (STR #4014) - - The lp and lpr commands did not cancel jobs queued from stdin on an - error (STR #4015) - - Fixed the IPP backend's handling of HTTP/1.0 compatibility (STR #3988) - - The IPP backend did not always setup username/password authentication - for printers (STR #3985) - - The IPP backend no longer re-queues print jobs that are too large for - the printer/server (STR #3977) - - The RPM spec file did not work (STR #4021, STR #4057) - - Encryption did not work when the server name ended with "." - (STR #4011) - - The multi-purpose tray is now mapped to the IPP "by-pass-tray" - (STR #4009) - - The correct media size was not always passed to IPP printers - (STR #4001) - - Finishing options were not passed to IPP printers (STR #3995) - - Fixed iCloud-based Back to My Mac printing (STR #3996) - - -CHANGES IN CUPS V1.5.2 - - - Reposted what should have been CUPS 1.5.1. - - -CHANGES IN CUPS V1.5.1 - - - Documentation updates (STR #3885, STR #3886, STR #3946, STR #3969) - - Localization updates (STR #3840, STR #3989, STR #3997) - - Build fixes (STR #3956, STR #3999) - - The SNMP backend did not validate the device URIs reported by printers - (STR #4004) - - cupsBackendReport() did not handle newlines in 1284 Device IDs - (STR #4005) - - USB backend fixes for libusb (STR #3965, STR #3978) - - The DBUS notifier did not validate string parameters (STR #3984) - - Group quota ACLs did not work with Kerberos (STR #3972) - - The IPP backend did not retry when a printer responded with - client-error-not-possible (STR #3963) - - PostScript PPDs with filters used the wrong command filter (STR #3973) - - The scheduler incorrectly used free() on a POSIX ACL value, which - could cause a crash (STR #3970) - - PPD files using the MacStandard encoding did not work. - - The web interface did not work on some platforms (STR #3902) - - The lpstat command would crash when then "-u" option was used by a - non-administrator (STR #3953) - - Japanese supply level reporting did not always work. - - The DBUS notifier could crash (STR #3947) - - Relaxed some of the page size checks in cupstestppd. - - The ipptool program now reports attributes that are repeated within - the same attribute group. - - Updated the PWG raster support to match the current draft - specification. - - Fixed some IPP conformance issues in the scheduler. - - Added ipptool support for repeating requests. - - Added IPP/2.2 conformance tests and greatly improved the IPP/1.1, - IPP/2.0, and IPP/2.1 conformance testing. - - IPP messages containing mixed integer/rangeOfInteger values did not - work (STR #3942) - - The ipptool program now provides additional diagnostics for badly- - formatted responses (STR #3857) - - When possible, the IPP backend now stops sending job data early on a - cancel. - - cupsSendRequest and cupsWriteRequestData did not properly read all - HTTP headers, preventing authentication and encryption upgrades from - working in all cases. - - The client.conf Server directive is no longer supported on Mac OS X - 10.7 and later. - - The IPP backend sent the wrong margins in media-col. - - The scheduler did not save or restore large Kerberos credentials for - jobs. - - The dnssd backend did not properly browse for secure IPP printers. - - httpAssembleURI* did not properly escape all special characters in the - username/password field. - - The scheduler now logs config file errors to stderr (STR #3936) - - The configure script incorrectly used bundle-based localizations on - Linux (STR #3938) - - The cups-driverd helper program did not cache .drv files properly, - sometimes leading to a crash (STR #3921) - - CUPS did not build on stock Mac OS X installations. - - Encryption was broken with OpenSSL. - - ipptool's XML output used date/time values with timezone offsets, - which are not supported by Mac OS X's NSDate class. - - Several programs did not support the cupsFilter2 keyword in PPD files. - - The IPP backend incorrectly reported spool-area-full states. - - cupsMarkOptions() did not protect against a bad PPD that was missing - one or more standard Duplex options. - - The PostScript filter did not mirror N-up output properly. - - The ipptool program did not validate UTF-8 strings in XML output. - - Fixed supply level reporting for some printers. - - The scheduler no longer automatically logs debug messages for jobs - that were held or canceled. - - The cupsSendRequest function did not flush remaining response data - from a previous request, leading to apparent chunking issues. - - The scheduler did not report the correct version in the Server: header - (STR #3903) - - The scheduler did not support 1284 device IDs reported by driver - interface programs longer than 127 characters (STR #3871) - - The image filters did not support loading images larger than the - RIPCache setting (STR #3901) - - "PAGE: total NNN" messages did not get logged properly (STR #3887) - - Updated the PWG Raster support to conform to the current draft of the - PWG Raster Format specification. - - The PWG Raster filter did not always write the correct number of - padding lines on the bottom of the page (STR #3904) - - When reporting a denial-of-service attack from the domain socket, the - address reported does not always contain the correct path (STR #3888) - - Badly formed GIF files could cause the image filters to crash - (STR #3914) - - Jobs canceled at the printer were retried by the IPP backend. - - "cupsfilter -u" deleted the input file instead of the PPD file. - - The scheduler did not compute the cost of PPD filters defined using - the cupsFilter2 keyword properly. - - The scheduler did not correctly support the maxsize() attribute for - PPD filters. - - -CHANGES IN CUPS V1.5.0 - - - Documentation updates. - - Localization update (STR #3865) - - Needed to limit TLS to v1.0 on some versions of Mac OS X. - - The snmp backend did not work with some printers. - - -CHANGES IN CUPS V1.5rc1 - - - Compile fixes (STR #3849, STR #3850) - - The scheduler didn't check for empty values for several configuration - directives (STR #3861) - - ipptool didn't generate valid XML when a test was skipped. - - Added additional error checking to the 1284 device ID code (STR #3858) - - Fixed some compatibility issues migrating from the old usblp backend - to the libusb backend (STR #3860) - - Fixed the wake-from-sleep printing behavior on Mac OS X. - - The scheduler incorrectly allowed jobs to be held from a terminating - state. - - The cups-driverd program could crash when a PPD was renamed. - - The dnssd backend took too long to discover printers on large or busy - networks with the new default timeout used by lpinfo and the web - interface. This resulted in "lost" printers. - - -CHANGES IN CUPS V1.5b2 - - - Documentation updates. - - Localization updates (STR #3845) - - Compiler warning cleanup. - - Fixed PIE support for Linux (STR #3846) - - Made httpSetTimeout API public and use it in the IPP backend to avoid - timeout errors. - - The scheduler incorrectly set the "authenticated" printer-type bit for - remote queues using authentication. - - -CHANGES IN CUPS V1.5b1 - - - The CUPS library now supports per-connection HTTP timeouts and - callbacks. - - The CUPS library now supports (limited) SSL/TLS X.509 certificate - validation and revocation (STR #1616) - - Updated the PostScript filter to support IncludeFeature in more - circumstances (STR #3417) - - The schedule did not correctly parse some IPv6 addresses and masks in - the cupsd.conf file (STR #3533) - - Fixed a case-insensitive string comparison issue for locales that do - not treat "I" and "i" as equivalent (STR #3800) - - The scheduler reported an incorrect job-printer-uri value when sharing - was not enabled (STR #3639) - - The scheduler now allows the ServerAlias directive to contain multiple - hostnames separated by spaces or commas (STR #3813) - - The scheduler now sets the process group for child processes and - manages the group (STR #2829) - - Fixed some minor issues discovered by a Coverity scan (STR #3838) - - The scheduler now more carefully creates and removes configuration, - cache, and state files (STR #3715) - - The lpadmin command now allows default option values to be deleted - (STR #2959) - - The lpadmin command now allows the cupsIPPSupplies and - cupsSNMPSupplies keywords to be set in a PPD file (STR #3825) - - Moving a held job no longer releases it (STR #3839) - - Restored support for GNU TLS and OpenSSL with threading enabled - (STR #3605) - - Fixed a confusing error message from cups-polld (STR #3806) - - Increased the default RIPCache value to 128MB (STR #3535) - - MIME errors are now routed to the error_log file (STR #2410) - - Updated PDF filter to support new Ghostscript ps2write device - (STR #3766) - - Updated PDF filter to support new Poppler option to preserve page - sizes in PDF files when the user has not selected a particular media - size (STR #3689) - - Added new PWG Raster filter for IPP Everywhere printer support. - - Added job-uuid, printer-uuid, and subscription-uuid attributes. - - Added support for the cupsSingleFile PPD keyword. - - Dropped support for the printer-state-history attribute (STR #3654) - - Added support for a new cupsIPPSupplies keyword in PPD files to allow - drivers to disable IPP supply level reporting. - - Added support for a new cupsFilter2 keyword in PPD files to allow for - the propagation of the actual MIME media type produced by a filter. - - The scheduler did not always get the correct Kerberos username when - authenticating (STR #3670) - - Added new cupsRasterOpenIO function and CUPS_RASTER_WRITE_PWG to the - CUPS imaging library to support printing to IPP Everywhere raster - printers. - - The scheduler now provides default values for the pages-per-minute and - pages-per-minute-color attributes for PPD files that lack a - Throughput keyword. - - Email notifications did not work on Mac OS X. - - The cupstestppd program now shows an error for files missing a - CloseGroup keyword (STR #3668) - - Name resolution errors no longer cause queues to stop (STR #3719, - STR #3753) - - Added a new cups-exec helper program that applies security profiles - to filters, port monitors, backends, CGI programs, and mini-daemons. - - The web interface can now be disabled using the WebInterface directive - in cupsd.conf (STR #2625) - - The scheduler now provides privacy controls for jobs and subscriptions - (STR #2969) - - Added new cupsArrayNew3 API which offers memory management of array - elements. - - Added several new color spaces to the CUPS raster format (STR #3419) - - The Validate-Job operation now uses the same policy as Print-Job by - default. - - CUPS now uses iconv to implement all of its character encoding - support (STR #3097) - - The scheduler now implements the Cancel-Jobs, Cancel-My-Jobs, and - Close-Job operations along with the job-ids operation attribute from - PWG 5100.11. - - The main CUPS header () no longer includes the PPD header - (). - - The scheduler and CUPS API now support the print-quality job template - attribute. - - The scheduler no longer supports the old Mac OS X Server quota - plugin. - - The scheduler now allows writing to /Users/Shared from print filters - on Mac OS X. - - CUPS no longer supports the old ~/.cupsrc or ~/.lpoptions files from - CUPS 1.1.x. The ~/.cups/client.conf and ~/.cups/lpoptions files that - were introduced in CUPS 1.2 must now be used. - - The ipptest tool is now a first-class user program and has several - improvements along with new documentation (STR #3484) - - The cupstestppd tool now warns about non-unique filenames and - provides a way to ignore all filename warnings. - - Dropped support for the recoverable: and recovered: message prefixes. - - The scheduler now requires that filters and backends have group write - permissions disabled. - - The PPD compiler now checks for overlapping filenames when writing - PPD files. - - The HP-GL/2 filter is no longer included with CUPS (STR #3322) - - The SCSI backend is no longer included with CUPS (STR #3500) diff --git a/CHANGES-1.6.txt b/CHANGES-1.6.txt deleted file mode 100644 index 23e1422..0000000 --- a/CHANGES-1.6.txt +++ /dev/null @@ -1,244 +0,0 @@ -CHANGES-1.6.txt ---------------- - -CHANGES IN CUPS V1.6.4 - - - Removed some duplicate size definitions for some ISO sizes that were - causing problems () - - The IPP backend did not add the "last-document" attribute - () - - Added a SyncOnClose directive to cups-files.conf to force cupsd to - call fsync before closing any configuration/state files it writes - () - - Added USB quirk rule for Lexmark E238 () - - Closed server connections were still not always detected - () - - The libusb-based USB backend now loads its list of quirks from files - in /usr/share/cups/usb instead of using a hardcoded table - () - - The scheduler did not properly register ICC color profiles with - colord () - - -CHANGES IN CUPS V1.6.3 - - - The configure script now prefers Clang over GCC. - - Fixed a compile problem on AIX (STR #4307) - - The default IPP version did not always get set before creating a new - IPP request message () - - The lp, lpq, lpr, and lpstat now display an error message advising the - use of the /version=1.1 ServerName option () - - Added documentation about the /version=1.1 option to ServerName in - client.conf () - - httpStatus(HTTP_ERROR) did not return a useful error message - () - - The lp, lpq, lpr, and lpstat commands incorrectly ignored the default - printer set in the lpoptions file () - - Fixed a URI encoding issue for hostnames containing the ` (backquote) - character () - - Added support for RFC 6874's IPv6 link local address format in URIs - () - - The USB backend could crash on libusb-based systems if USB was - disabled in the BIOS () - - Fixed a rounding error in the PWG media size mapping code - () - - Fixed several ipptool test files that used old STATUS names. - - Kerberos credentials could get truncated when printing to a shared - printer. - - Printing using "ipps" URIs was not encrypted. - - Insecure ICC profiles prevented installation of user profiles for a - printer on OS X. - - Added more USB quirks for the libusb-based backend (STR #4311, - ) - - The Russian web interface templates were broken (STR #4310) - - The scheduler no longer tries to do Kerberos authentication over the - loopback interface. - - The IPP backend could fail to pause a job for authentication - (STR #4298) - - Fixed a regression on the handling of auth keys on OS X if the - cups-files.conf was not present or did not contain a SystemAuthKey - value. - - The scheduler incorrectly did a reverse lookup of the server address - when HostNameLookups was turned off (STR #4302) - - The scheduler incorrectly computed the final content type value when - null filters were present. - - -CHANGES IN CUPS V1.6.2 - - - Documentation fixes (STR #4229, STR #4239, STR #4234, STR #4248, - STR #4259) - - Security: All file, directory, user, and group settings are now stored - in a separate cups-files.conf configuration file that cannot be set - through the CUPS web interface or APIs (STR #4223) - - Added a Czech localization (STR #4201) - - Added a French localization (STR #4247) - - Added a Russian localization (STR #4228, STR #4285) - - Updated the Catalan localization (STR #4202) - - Local certificate authentication did not guard against an empty - certification file (STR #4293) - - The scheduler did not reject device URIs with spaces. - - Added USB quirk rule for Epson Stylus Photo 750 (STR #4286) - - The IPP backend could crash if the printer disconnects early - (STR #4284) - - cupsGetPPD did not work with statically-configured CUPS shared - queues (STR #4178) - - The scheduler did not support long MIME media types (STR #4270) - - The cupsfilter command did not set the CHARSET environment variable - for the text filters (STR #4273) - - The lp command did not show errors for unknown "--foo" (STR #4261) - - Bad IPP responses could crash ipptool (STR #4262) - - Updated USB quirk rules for Canon and Xerox printers (STR #4217, - STR #4263) - - Added USB blacklisting for printers that require a custom backend - (STR #4218) - - The PPD compiler did not correctly JCL options (STR #4115, STR #4203) - - The ipptool program now supports DEFINE-MATCH and DEFINE-NO-MATCH - predicates for STATUS directives. - - Fixed a problem with local Kerberos authentication (STR #4140) - - Coverity scan: fixed some minor issues (STR #4242) - - The scheduler did not remove color profiles after deleting a printer - (STR #4232, STR #4276) - - The CUPS library did not always detect a timed out connection to the - server which could cause temporary loss of printing from applications - (STR #4187) - - The ipptool program now supports variable substitution in OPERATION - and DELAY directives (STR #4175) - - The IPP backend now stops queues when the server configuration - prevents successful job submission (STR #4125) - - The XML output of ipptool contained empty dictionaries (STR #4136) - - The scheduler did not delete job control backup files (STR #4244) - - cupsGetPPD3 could return a local PPD instead of the correct remote - PPD. - - The scheduler incorrectly advertised auth-info-required for local - queues needing local authentication (STR #4205) - - CUPS 1.6 clients using the ServerName directive in client.conf did not - work with CUPS 1.3.x or older servers (STR #4231, STR #4291) - - The SNMP backend now tries to work around broken printers that use a - newline to separate key/value pairs. - - The IPP backend did not send a cancel request to printers when a job - was canceled and the printer did not support Create-Job. - - Fixed EPM packaging files (STR #4199) - - OpenBSD build fix (STR #4195, STR #4196, STR #4197) - - The scheduler could crash when using Avahi (STR #4183, STR #4192, - STR #4200, STR #4213) - - The IPP backend could get stuck in an endless loop on certain network - errors (STR #4194) - - 32-bit builds failed on Debian (STR #4133) - - The scheduler no longer accepts or sends job description attributes. - - The IPP backend now works around some conformance issues for broken - printers (STR #4190) - - cupsBackendReport() now filters out all control characters from the - reported 1284 device IDs (STR #4124) - - The scheduler no longer allows job-name values that are not valid - network Unicode strings (STR #4072) - - The web interface did not preserve the order of classes, jobs, or - printers (STR #4170) - - The network backends now support disabling of SNMP supply level - queries via the "snmp" URI option (STR #4106) - - The IPP backend did not specify the compression used (STR #4181) - - ipptool did not support octetString values. - - The scheduler did not recognize dnssd: or ipps: URIs as Bonjour shared - queues (STR #4158) - - Applications could not get the PPD file for statically-configured - Bonjour-shared print queues (STR #4159) - - The cupsd.conf file included obsolete browsing directives (STR #4157) - - Fixed a USB backend compatibility issue on systems using libusb - (STR #4155, STR #4191) - - Some Bonjour features were not available on systems with Avahi - (STR #4156) - - CUPS now includes the port number in the Host: header for HTTP - requests. - - Fixed REPEAT-MATCH for STATUS and EXPECT - was incorrectly erroring - out. - - -CHANGES IN CUPS V1.6.1 - - - Documentation fix (STR #4149) - - RPM packaging fixes (STR #4129, #4145) - - The Japanese and English web interface headers were swapped - (STR #4148) - - -CHANGES IN CUPS V1.6.0 - - - Document changes (STR #4131) - - Added new Catalan (STR #4107) and Spanish (STR #4137) localizations. - - -CHANGES IN CUPS V1.6rc1 - - - Added a new Japanese localization (STR #4122) - - The SNMP backend no longer exits if it is unable to obtain an IPv6 - socket (STR #4109) - - The LPD backend incorrectly used "localhost" in the control file - instead of the current hostname. - - -CHANGES IN CUPS V1.6b1 - - - Documentation updates (STR #3927, STR #3980, STR #4010, STR #4068) - - The scheduler now consolidates all PPD updates from filters at the - end of the job (STR #4075) - - CUPS now supports color management using colord (STR #3808) - - CUPS now supports Bonjour using Avahi (STR #3066) - - The PreserveJobFiles and PreserveJobHistory directives now support - specification of a time interval (STR #3143) - - PPD files can now be archived in (gzip'd) tar files to further reduce - the disk space used by PPD files (STR #3772) - - The network backends now deal with printers that report their levels - in percent but do not specify a maximum capacity of 100 (STR #3551) - - The network backends now report full/almost-full waste bins in - printers along with end-of-life for cleaning pads (STR #4017) - - Added a configure option to set the permissions of the installed - cupsd (STR #3459) - - Added a new WITH-ALL-VALUES directive to ipptool EXPECT predicates - (STR #3949) - - CUPS now supports a User directive in client.conf and the CUPS_USER - environment variable for overriding the default username (STR #3114) - - Now set the PJL USERNAME variable as needed (STR #3100) - - Added support for usernames and passwords longer than 32 characters - (STR #2856) - - Added a new MaxHoldTime directive to automatically cancel jobs that - have been held indefinitely after a specific number of seconds - (STR #2291) - - The LPD backend now uses the originating host name when it is not the - local system (STR #2053) - - CUPS now prefers the suffix "dpcm" when reporting resolution in dots- - per-centimeter (STR #4006) - - The configure script and build system no longer support building of - separate 32-bit and 64-bit libraries. - - The "brightness", "columns", "fitplot", "gamma", "hue", - "natural-scaling", "penwidth", "position", "ppi", "saturation", and - "scaling" options are not longer supported (STR #4010) - - The "page-bottom", "page-left", "page-right", "page-top", - "prettyprint", and "wrap" options have been deprecated (STR #4010) - - The scheduler now reports the standard "number-of-documents" attribute - instead of the CUPS-specific "document-count" attribute in - job objects. - - Added new destination connection and enumeration functions (STR #3924) - - Added new option, localization, and job submission functions that do - not depend on PPD files (STR #3925) - - Added a new MaxJobTime directive for cupsd that specifies the maximum - amount of time allowed for a job to complete before it is canceled. - - The default password callback now supports passwords up to 127 - characters. - - The scheduler now supports a DefaultAuthType of "auto" to - automatically choose between Basic (username/password) and Negotiate - (Kerberos) authentication. - - cupsSideChannelSNMPGet/Walk now support OIDs and values up to 64k in - length. - - CUPS no longer supports automatic remote printers or implicit classes - via the CUPS, LDAP, or SLP protocols (STR #3922, STR #3923) - - The PPD APIs are now deprecated and will be removed in a future - version of CUPS (STR #3927) - - The default IPP version for requests is now 2.0 (STR #3929) - - The IPP APIs no longer expose the ipp_t or ipp_attribute_t structures - and instead provide accessor functions (STR #3928) - - The scheduler will no longer run programs with group write permission. - - The PHP module has been removed (STR #3932) - - The bannertops, commandtoescpx, commandtopclx, imagetops, - imagetoraster, pdftops, rastertoescpx, rastertopclx, and texttops - filters have been removed (STR #3930) - - The serial and parallel backends have been removed (STR 3935) diff --git a/CHANGES-1.7.txt b/CHANGES-1.7.txt deleted file mode 100644 index d3438ff..0000000 --- a/CHANGES-1.7.txt +++ /dev/null @@ -1,250 +0,0 @@ -CHANGES-1.7.txt ---------------- - -CHANGES IN CUPS V1.7.5 - - - Security: Addressed some more situations where symlinked files would - be served by the web interface (STR #4455) - - The LPD backend did not work with some versions of glibc (STR #4452) - - CGI scripts did not work (STR #4454) - - The cupsd.conf man page did not list the ErrorPolicy directive - (STR #4457) - - Updated the Brazilian Portuguese translation (STR #4456) - - -CHANGES IN CUPS V1.7.4 - - - Security: The web interface incorrectly served symlinked files and - files that were not world-readable, potentially leading to a - disclosure of information (STR #4450) - - The CUPS headers incorrectly needed libdispatch for blocks support - (STR #4397) - - CUPS did not compile when Avahi or mDNSResponder was not present - (STR #4402, STR #4424) - - The "snmp" option did not work with the network backends (STR #4422) - - The User directive in client.conf did not override the USER - environment variable (STR #4426) - - The web interface now properly shows a "Go" button for all text-based - browsers (STR #4425) - - The MaxJobTime directive now properly supports time values (STR #4434) - - The RPM spec file did not work due to the new Brazilian Portuguese - localization (STR #4436) - - Fixed an "IPP read error" issue (STR #4440) - - Fixed the --disable-libusb configure option (STR #4439) - - Fixed the debug output from the DNS-SD backend when using Avahi - (STR #4444) - - Fixed a bug in the CUPS_SC_GET_DEVICE_ID handling by the network - backends (STR #4447) - - Added USB quirk rule for Lexmark E230 (STR #4448) - - -CHANGES IN CUPS V1.7.3 - - - Added Brazilian Portuguese translation (STR #4409) - - Fixed mapping of OutputBin values such as "Tray1" - () - - Several ippGet* functions incorrectly returned -1 instead of 0 on - error. - - The cupsGetResponse function did not work properly with - CUPS_HTTP_DEFAULT () - - The IPP backend did not abort a job when the printer did not validate - the supplied options () - - Fixed an authentication race condition in cupsSendRequest (STR #4403) - - The scheduler did not add the "job-hold-until-specified" reason when - holding a job using the lp command (STR #4405) - - The configure script incorrectly added libgcrypt as a GNU TLS - dependency (STR #4399) - - cupsGetDestMediaCount did not work for CUPS_MEDIA_FLAGS DEFAULT - (STR #4414) - - Auto-typing of PWG Raster files did not work (STR #4417) - - IPP queues using hardcoded credentials would ask for credentials - (STR #4371) - - Dates in non-UTF-8 locales did not display correctly (STR #4388) - - The RPM spec file now looks for libusb-devel 1.0 or later. - - Fixed the "create-printer-subscription.test" file for IPPTOOL - (STR #4420) - - -CHANGES IN CUPS V1.7.2 - - - Security: The scheduler now blocks URLs containing embedded HTML - (STR #4356) - - Documentation fixes (STR #3259, STR #4346, STR #4355) - - Fixed the Japanese localization (STR #4385) - - Added a German localization (STR #4363) - - The cupsfilter command incorrectly read the cupsd.conf file; it now - reads the cups-files.conf file instead. - - Fixed OS X builds with Xcode 5.x () - - Fixed SSL support on Windows (STR #4358) - - Fixed documentation and naming of Create-Job/Printer-Subscriptions - operations (STR #4389) - - Phone numbers in fax jobs were not properly filtered for IPP FaxOut - () - - Updated Linux "relro" support (STR #4349) - - Fixed a memory leak in the label printer driver (STR #4393) - - cupsEnumDests did not set the "is_default" field (STR #4332) - - cupsDoIORequest could miss the server status, causing failed lpadmin - and other administrative commands (STR #4386) - - cupsEnumDests didn't always call the callback function (STR #4380) - - "lp -i job-id -H hold" did not work (STR #nnn) - - CUPS didn't compile on older platforms (STR #4338) - - Several libcups files did not have the Apple license exception - notice (STR #4361) - - Fixed a D-BUS threading issue that caused the scheduler to crash - (STR #4347) - - The scheduler now automatically reconnects to Avahi as needed - (STR #4370, STR #4373) - - The scheduler did not handle GET requests for the log files properly - (STR #3265) - - The dnssd backend did not always report all discovered printers using - Avahi (STR #4365) - - The Zebra printer driver did not properly handle negative "label top" - values (STR #4354) - - The scheduler did not always update the MakeModel value in - printers.conf after updating the driver (STR #4264) - - The LPD mini daemon did not support print jobs larger than 2GB - (STR #4351) - - Fixed a bug in the status reading code when sending a compressed data - stream to an IPP printer/server () - - The IPP backend might not include all job attributes in Validate-Job - operations () - - Fixed some clang-reported issues () - - -CHANGES IN CUPS V1.7.1 - - - Security: the lppasswd program incorrectly used settings from - ~/.cups/client.conf (STR #4319) - - Auto debug logging was broken in 1.7.0 () - - Some gzip'd PPD files could not be used () - - Cleaned up some job logging in the scheduler - () - - ATTR messages could cause string pool memory corruption in the - scheduler () - - The RPM spec file did not list the build requirements; this was on - purpose, but now we are listing the Red Hat package names - (, STR #4322) - - Printing to a raw queue could result in corrupt output due to - opportunistic compression () - - The GNU TLS support code triggered many compiler warnings due to the - use of old GNU TLS compatibility type names - () - - The "make check" test suite did not work on Linux without the - cups-filters package installed () - - Japanese PPDs using with the Shift-JIS encoding did not work - () - - "tel:" URIs incorrectly had slashes () - - The libusb-based USB backend incorrectly used write timeouts - () - - Shared printers could become inaccessible after a few days on OS X - () - - The IPP backend did not wait for a busy printer to become available - before attempting to print () - - CUPS did not support "auto-monochrome" or "process-monochrome" for the - "print-color-mode" option () - - Using "@IF(name)" in an Allow or Deny rule did not work (STR #4328) - - lpq and lpstat did not list jobs in the correct order when priorities - were specified (STR #4326) - - The D-BUS notifier did not remove its lockfile (STR #4314) - - CUPS incorrectly used the USER environment variable when the name did - not match the user ID (STR #4327) - - -CHANGES IN CUPS V1.7.0 - - - Updated the Japanese localization. - - The lpadmin command did not send the PPD name from the "-m" option - () - - Network backends now use the prtMarkerSuppliesClass property to - determine the direction of supply level values - () - - The scheduler did not remove backup PPD files when a printer was - deleted () - - The scheduler incorrectly responded to HEAD requests when the web - interface was disabled () - - The scheduler did not respond using the hostname specified by the - client () - - Fax queues did not work when shared via Bonjour - () - - Error messages from the scheduler were not localized using the - language specified in the client's IPP request - () - - Added an Italian localization () - - Fixed a couple memory leaks in ippfind that were reported by Clang. - - Fixed a compile issue on 64-bit Linux with Clang - need to use the - -pie option instead of -Wl,-pie now () - - The ippfind utility reported the wrong port numbers when compiled - against Avahi () - - httpGetFd, httpGetFile, httpPutFd, and httpPutFile did not - automatically reconnect if the server closed the connecion after the - previous response. - - Fixed a compile error in libcups () - - The scheduler incorrectly did not pass a FINAL_CONTENT_TYPE - environment variable to the filters or backend - () - - The cups-exec helper program could fail randomly on OS X due to - sandbox violations when closing excess file descriptors - () - - The scheduler incorrectly did not use the kqueue interface on OS X. - - -CHANGES IN CUPS V1.7rc1 - - - Printer xxx-default values were not reported by Get-Printer-Attributes - or lpoptions () - - Fixed deprecation warnings for many functions on OS X so they are tied - to the deployment version when building () - - Fixed a build issue on ARM-based Linux systems - unable to validate - va_list arguments. - - Added a new ippfind tool for finding IPP printers and other Bonjour - services () - - Fixed some issues with conversion of PWG media size names to - hundredths of millimeters () - - The IPP backend could crash on OS X when printing to a Kerberized - printer () - - The ipptool program now automatically extends timeouts when the - output buffer is filled () - - The ipptool program now supports the --help and --version options. - - The ipptool program did not continue past include file errors by - default () - - The ipptool program now supports FILE-ID and TEST-ID directives and - includes their values in its XML output () - - The ipptool program now supports WITH-HOSTNAME, WITH-RESOURCE, and - WITH-SCHEME expect predicates to compare the corresponding URI - components () - - -CHANGES IN CUPS V1.7b1 - - - The configure script now supports a --with-rundir option to change - the transient run-time state directory from the default to other - locations like /run/cups (STR #4306) - - The scheduler now supports PPD lookups for classes (STR #4296) - - The cupsfilter program did not set the FINAL_CONTENT_TYPE - environment variable for filters. - - Added a new "-x" option to the cancel command (STR #4103) - - Made the PWG media handling APIs public (STR #4267) - - Implemented ready media support for the cupsGetDestMediaXxx APIs - (STR #4289) - - Added new cupsFindDestDefault, cupsFindDestReady, and - cupsFindDestSupported APIs (STR #4289) - - Added new cupsGetDestMediaByIndex, cupsGetDestMediaCount, and - cupsGetDestMediaDefault APIs (STR #4289) - - Added new ippGet/SetOctetString APIs for getting and setting an - octetString value (STR #4289) - - Added new ippCreateRequestedArray API for generating a array of - attributes from the requested-attributes attribute. - - The ipptool utility now supports compression, conditional tests based - on the presence of files, and new DEFINE predicates for STATUS. - - Added new IPP APIs for checking values (STR #4167) - - Added new IPP APis for adding and setting formatted strings. - - Added new HTTP APIs to support basic server functionality via libcups. - - The dnssd backend now generates a 1284 device ID as needed (STR #3702) - - CUPS now supports compressing and decompressing streamed data - (STR #4168) - - CUPS now supports higher-level PIN printing, external accounting - systems, and "print here" printing environments (STR #4169) - - IRIX is no longer a supported operating system (STR #4092) - - The PPD compiler now supports JCL options properly (STR #4115) - - The web interface now checks whether the web browser has cookies - enabled and displays a suitable error message (STR #4141) diff --git a/CHANGES-2.0.txt b/CHANGES-2.0.txt deleted file mode 100644 index dc46f03..0000000 --- a/CHANGES-2.0.txt +++ /dev/null @@ -1,215 +0,0 @@ -CHANGES-2.0.txt ---------------- - -CHANGES IN CUPS V2.0.4 - - - Fixed a bug in cupsRasterWritePixels (STR #4650) - - Fixed redirection in the web interface (STR #4538) - - The IPP backend did not respond to side-channel requests (STR #4645) - - The scheduler did not start all pending jobs at once (STR #4646) - - The web search incorrectly searched time-at-xxx values (STR #4652) - - Fixed an RPM spec file issue (STR #4657) - - The scheduler incorrectly started jobs while canceling multiple jobs - (STR #4648) - - Fixed processing of server overrides without port numbers (STR #4675) - - Documentation changes (STR #4651, STR #4674) - - -CHANGES IN CUPS V2.0.3 - - - Security: Fixed CERT VU #810572 exploiting the dynamic linker - (STR #4609) - - Security: The scheduler could hang with malformed gzip data - (STR #4602) - - Restored missing generic printer icon file (STR #4587) - - Fixed logging of configuration errors to show up as errors (STR #4582) - - Fixed potential buffer overflows in raster code and filters - (STR #4598, STR #4599, STR #4600, STR #4601) - - Fixed a gzip processing bug (#4602) - - Fixed inside (STR #4575) - - Fixed lpadmin when both -m and -o are used (STR #4578) - - The web interface always showed support for 2-sided printing - (STR #4595) - - cupsRasterReadHeader did not fully validate the raster header - (STR #4596) - - The rastertopwg filter did not check for truncated input (STR #4597) - - The cups-lpd mini-daemon did not check for request parameters - (STR #4603) - - The scheduler could get caught in a busy loop (STR #4605) - - The sample Epson driver could crash (STR #4616) - - The IPP backend now correctly monitors jobs - () - - The ppdhtml and ppdpo utilities crashed when the -D option was used - before a driver information file (STR #4627) - - ippfind incorrectly substituted "=port" for service_port. - - The IPP/1.1 test file did not handle the initial print job - completing early (STR #4576) - - Fixed a memory leak in cupsConnectDest (STR #4634) - - PWG Raster Format output contained invalid ImageBox values - () - - Added Russian translation (STR #4577) - - Added German translation (STR #4635) - - -CHANGES IN CUPS V2.0.2 - - - Security: cupsRasterReadPixels buffer overflow with invalid page - header and compressed raster data (STR #4551) - - Command-line programs were not localized on Mac OS X - () - - The scheduler incorrectly cleared the MakeModel string in the - printers.conf file after a restart () - - CUPS did not compile with older versions of GNU TLS (STR #4527) - - CUPS did not compile without Avahi or mDNSResponder (STR #4523) - - ippLength() did not return the correct length for IPP_TAG_CONST - string values. - - The scheduler incorrectly aborted jobs after a job was restarted - () - - The cups-files.conf file contained the old ServerCertificate/Key - directives instead of ServerKeychain. - - Fixed builds when no SSL/TLS library is available, or when explicitly - disabled (STR #4531) - - Fixed an OpenBSD charset transcoding issue. - - Fixed USB printing on OpenBSD (STR #4525) - - The --without-xinetd configure option did not work (STR #4542) - - Backends needing to load OS X kernel extensions did not work - () - - Mapping of PPD keywords to IPP keywords did not work if the PPD - keyword was already an IPP keyword () - - cupsGetPPD* sent bad requests (STR #4567) - - ippserver used the wrong temporary directory on Windows (STR #4547) - - ippserver did not handle Bonjour registrations properly (STR #4548) - - The scheduler could crash during shutdown if Avahi was shutdown - first (STR #4550) - - Added a USB quirk rule for Intermec printers (STR #4553) - - The scheduler did not always log which configuration file had the - error (STR #4559) - - The ippfind and ipptool programs now correctly match hostnames with - trailing dots (STR #4563) - - The ipptool timeout option did not work (STR #4515) - - Fixed several issues with client.conf, CUPS_SERVER, and the "-h" - option of most commands (STR #4528) - - Another change for OpenBSD (STR #4526) - - Added Japanese localization (STR #4524) - - Documentation changes (STR #4569) - - -CHANGES IN CUPS V2.0.1 - - - Security: SSLv3 is now disabled by default to protect against the - POODLE attack (STR #4476) - - Printer sharing did not work when systemd was being used (STR #4497) - - cupsGetPPD* would return a symlink to the PPD in /etc/cups/ppd even if - it was not readable by the user (STR #4500) - - The web interface now protects against frame "click-jacking" attacks - (STR #4492) - - Fixed a crash in ippAttributeString () - - Fixed a crash in the scheduler on Linux/*BSD if colord was not running - (STR #4496) - - Fixed a random crash in the scheduler when not using systemd - (STR #4484) - - Added systemd support for cups-lpd (STR #4493) - - The scheduler did not honor the FatalErrors directive for mis- - configured Group and SystemGroup values (STR #4495) - - The network backends no longer report waste-receptacle conditions when - using SNMP (STR #4499) - - The IPP backend did not work with some configurations of Windows - (STR #4503) - - RPMs did not build (STR #4490) - - Added a USB quirk rule for the Brother HL-1250 (STR #4519) - - Fixed compiles on unsupported platforms (STR #4510) - - "cancel -a" did not cancel all jobs on all destinations (STR #4513) - - The web interface did not work on OpenBSD (STR #4496) - - -CHANGES IN CUPS V2.0.0 - - - The scheduler did not preserve listener sockets from launchd or - systemd after a restart () - - Added some USB quirk rules for the libusb-based USB backend - (STR #4482) - - Spanish localization update (STR #4487) - - Updated documentation for 2.0.0 release. - - -CHANGES IN CUPS V2.0rc1 - - - Documentation updates (STR #4464) - - The scheduler now monitors the AC power status on OS X, allowing for - "sleep printing" when sharing printers () - - The scheduler incorrectly called launch_activate_socket multiple times - on OS X () - - The ippserver test program now passes the IPP Everywhere self- - certification tests (STR #4101) - - Relaxed the new OS X filter sandbox slightly (STR #4471, - ) - - Dropped the old Epson Stylus Color/Photo sample drivers since they - don't work with any current printers and there are free alternatives - that produce much better output () - - Log and configuration files that are not world-readable are again - accessible via the web interface (STR #4461) - - PPD files are now created using the permissions specified by the - ConfigFilePerm directive. - - Fixed RPM build issues (STR #4459) - - Fixed the spinner image and restart page when reconfiguring the - scheduler through the web interface (STR #4475) - - -CHANGES IN CUPS V2.0b1 - - - Added a "--list-filters" option to the cupsfilter command (STR #4325) - - Added systemd support (STR #3917) - - Added support for re-sending a job as a raster file if a higher-level - format such as PDF fails () - - Added support for regular expression matching in the MIME type rules - () - - Added support for TLS certificate validation and policy enforcement - (STR #1616) - - Added support for simultaneous XML and test output from ipptool. - - Added support for PAUSE directive in ipptool test files. - - Added support for auto-typing of TIFF files by ipptool (STR #4418) - - The scheduler now returns completed jobs in the correct newest-to- - oldest order (STR #4396) - - The configure script now supports target-specific tools for pkg-config - and others (STR #4423) - - The ipptool program now supports EXPECT statements for collection - member attributes () - - The ipptool program now supports collection attributes with multiple - values () - - The sample drivers now include all of the installed localizations by - default () - - Adopted Linux man page conventions and updated all man pages - (STR #4372, STR #4329) - - The scheduler now supports the "first-index" operation attribute for - the Get-Jobs operation (STR #2913) - - Changed the default AccessLogLevel and PageLogFormat to disable the - access_log and page_log files by default () - - cupsRasterInterpretPPD now supports the Orientation header in order to - support long-edge feed raster printers () - - The scheduler now allows run-as-root backends to have group read and - execute permissions (STR #2935) - - The ippFindAttribute and ippFindNextAttribute functions now support - hierarchical searches (STR #4395) - - Dropped OpenSSL support in favor of GNU TLS. - - Dropped "dark wake" support on OS X, which was preventing portables - from going to sleep when there was a stuck job. We now use a variation - of the CUPS 1.4 sleep support to do a cleaner sleep - () - - Dropped support for AIX, HP-UX, and OSF/1 (aka Digital UNIX) - - Dropped lppasswd and support for Digest authentication in in the - scheduler (STR #4321) - - The cupsGetClasses, cupsGetPrinters, and cupsTempFile functions are no - longer supported. - - The scheduler now caches more job history data and limits the number - of completed jobs returned by Get-Jobs as needed in order to prevent a - denial-of-service on busy servers (STR #2913) - - The filter/backend sandbox on OS X now defaults to a more strict - whitelist () - - Increased the default idle exit timeout to 60 seconds on OS X - () - - Printer classes were not accessible on OS X - () - - The scheduler now uses to close the default printer - definition in printers.conf (STR #4153) - - Canceling all jobs in the web interface now just cancels the jobs - (STR #1914) diff --git a/CHANGES-2.1.txt b/CHANGES-2.1.txt deleted file mode 100644 index 7a6b548..0000000 --- a/CHANGES-2.1.txt +++ /dev/null @@ -1,150 +0,0 @@ -CHANGES-2.1.txt ---------------- - -CHANGES IN CUPS V2.1.4 - - - Fixed reporting of 1284 Device IDs (Issue #3835, PR #3836) - - Fixed printing of multiple files to raw queues (Issue #4782) - - The scheduler did not implement the Hold-New-Jobs opertion correctly - (Issue #4767) - - The ipptool program truncated values at 8k (Issue #4786) - - The ipptool program did not correctly report uriScheme values in plist - output (Issue #4785) - - The cups-lpd mini-daemon incorrectly included the document-name - attribute when creating a job. It should only be included when - sending a job (Issue #4790) - - USB quirk updates (Issue #4778, Issue #4789) - - Documentation update (Issue #4772) - - -CHANGES IN CUPS V2.1.3 - - - The default password function did not work on some platforms - (Issue #4750) - - The scheduler should not exit under memory pressure - () - - The EPL2 and ZPL sample drivers did not properly support the CutMedia - option. - - Pending subscriptions would prevent the scheduler from idle exiting - (Issue #4754) - - Fixed some issues in ipptool for skipped tests - () - - The "lp -H resume" command did not reset the "job-state-reasons" - attribute value (Issue #4752) - - cupsEncodeOptions2 incorrectly handled escaped values - () - - The scheduler did not allow access to resource files (icons, etc.) - when the web interface was disabled (Issue #4755) - - Localization fix (Issue #4756) - - -CHANGES IN CUPS V2.1.2 - - - Re-release of CUPS 2.1.1 as CUPS 2.1.2 due to error in tagging of the - 2.1.1 release (pulled content from the 2.2.x tree instead) - - -CHANGES IN CUPS V2.1.1 - - - Security hardening fixes (, - , , - , , - , , - , , - , , - , , - , , - , , - , , - ) - - The cupsGetPPD* functions did not work with IPP printers (Issue #4725) - - Some older HP LaserJet printers need a delayed close when printing - using the libusb-based USB backend (Issue #4549) - - The libusb-based USB backend did not unload the kernel usblp module - if it was preventing the backend from accessing the printer - (Issue #4707) - - Current Primera printers were incorrectly reported as Fargo printers - (Issue #4708) - - The IPP backend did not always handle jobs getting canceled at the - printer () - - Scheduler logging change (Issue #4728) - - Added USB quirk for Canon MP530 (Issue #4730) - - The scheduler did not deliver job notifications for jobs submitted to - classes (Issue #4733) - - Changing the printer-is-shared value for a remote queue did not - produce an error (Issue #4738) - - The IPP backend incorrectly included the job-password attribute in - Validate-Job requests () - - Updated localizations (Issue #4709) - - -CHANGES IN CUPS V2.1.0 - - - Fixed more scheduler crash bugs in the new logging code (Issue #4687, - Issue #4690) - - The scheduler did not use the ConfigFilePerm setting when copying PPD - files or interface scripts attached to a request (Issue #4703) - - Now support new Chinese locale IDs and their correct fallback locales - (, ) - - "make check" incorrectly reported an expectation of 18 warning - messages when 8 were expected (Issue #4684) - - The new PDF file type rule did not work (Issue #4692) - - The scheduler did not update the jobs.cache file when job files were - expired (Issue #4706) - - Fixed some configure script issues (Issue #4694, Issue #4695, Issue #4698) - - Documentation updates (Issue #4691, Issue #4693) - - -CHANGES IN CUPS V2.1rc1 - - - Added support for 3D printers (basic types only, no built-in filters) - based on PWG white paper. - - Fixed bugs in the new journald support (Issue #4655, Issue #4658, - Issue #4661) - - Fixed domain socket support on Linux (Issue #4679) - - Fixed signal handlers in the dnssd and usb backends (Issue #4671) - - in sections now applies to all operations when - used by itself (Issue #4659) - - Configure script changes for systemd support (Issue #4669) - - Updated autoconf sources to use newer form of AC_INIT (Issue #4664) - - -CHANGES IN CUPS V2.1b1 - - - Improved speed of ppdMarkDefaults for complex/large PPDs - () - - The IPP backend now stops sending print data if the printer indicates - the job has been aborted or canceled () - - The IPP backend now sends the job-pages-per-set attribute when - printing multiple copy jobs with finishings - () - - The IPP backend now updates the cupsMandatory values when the printer - configuration changes () - - No longer install banner files since third-party banner filters now - supply their own (Issue #4518) - - Added support for EXPECT-ALL directive in ipptool test files - (Issue #4469) - - Added support for WITH-VALUE-FROM predicate in ipptool test files - (Issue #4470) - - The scheduler no longer listens on the loopback interface unless the - web interface or printer sharing are enabled - () - - Added a PPD generator for IPP Everywhere printers (Issue #4258) - - Now install "default" versions of more configuration files - () - - The cupstestppd program did not handle "maxsize(nnn)" entries in - cupsFilter/cupsFilter2 values () - - The scheduler now checks the return value of rename() calls - (Issue #4589) - - The scheduler now validates ErrorPolicy values in config files - (Issue #4591) - - Long cookies caused the web interface to stop working (Issue #4619) - - Added SSLOptions values to allow Diffie-Hellman key exchange and - disable TLS/1.0 support. - - Updated the scheduler to support more IPP Everywhere attributes - (Issue #4630) - - The scheduler now supports advanced ASL and journald logging when - "syslog" output is configured (Issue #4474) - - The scheduler now supports logging to stderr when running in the - foreground (Issue #4505) - diff --git a/CHANGES.txt b/CHANGES.txt index 24270ba..ce57fe2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,183 +1,352 @@ -CHANGES - 2.2.4 - 2017-06-30 +CHANGES - 2.3.0 - 2019-08-23 ============================ -CHANGES IN CUPS V2.2.4 + +Changes in CUPS v2.3.0 ---------------------- -- The scheduler did not remove old job files (Issue #4987) -- cupsEnumDests did not return early when all printers had been discovered - (Issue #4989) -- The CUPS build system now supports cross-compilation (Issue #4897) -- Added a new CUPS Programming Manual to replace the aging API documentation. -- Added the `cupsAddIntegerOption` and `cupsGetIntegerOption` functions - (Issue #4992) -- The `cupsGetDests` and `cupsCreateJob` functions now support Bonjour printers - (Issue #4993) -- Added a USB quirk rule for Lexmark E260dn printers (Issue #4994) -- Fixed a potential buffer overflow in the `cupstestppd` utility (Issue #4996) -- IPP Everywhere improvements (Issue #4998) -- Fixed the "cancel all jobs" function in the web interface for several - languages (Issue #4999) -- Fixed issues with local queues (Issue #5003, Issue #5008, Issue #5009) -- The `lpstat` command now supports a `-e` option to enumerate local printers - (either previously added or on the network) that can be accessed - (Issue #5005) -- The `lp` and `lpr` commands now support printing to network printers that - haven't yet been added (Issue #5006) -- Fixed a typo in the mime.types file. -- Fixed a bug in the Spanish web interface template (Issue #5016) -- The `cupsEnumDests*` and `cupsGetDest*` functions now report the value of the - "printer-is-temporary" Printer Status attribute (Issue #5028) -- Added Chinese localization (Issue #5029) -- The `cupsCheckDestSupported` function did not support `NULL` values - (Issue #5031) -- Fixed some issues in the RPM spec file (Issue #5032) -- The `cupsConnectDest` function now supports the `CUPS_DEST_FLAGS_DEVICE` flag - for explicitly connecting to the device (printer) associated with the - destination. -- The `SSLOptions` directive in "client.conf" and "cupsd.conf" now supports - `DenyCBC` and `DenyTLS1.0` options (Issue #5037) +- CVE-2019-8696 and CVE-2019-8675: Fixed SNMP buffer overflows (rdar://51685251) +- Added a GPL2/LGPL2 exception to the new CUPS license terms. +- Documentation updates (Issue #5604) +- Localization updates (Issue #5637) +- Fixed a bug in the scheduler job cleanup code (Issue #5588) +- Fixed builds when there is no TLS library (Issue #5590) +- Eliminated some new GCC compiler warnings (Issue #5591) +- Removed dead code from the scheduler (Issue #5593) +- "make" failed with GZIP options (Issue #5595) +- Fixed potential excess logging from the scheduler when removing job files + (Issue #5597) +- Fixed a NULL pointer dereference bug in `httpGetSubField2` (Issue #5598) +- Added FIPS-140 workarounds for GNU TLS (Issue #5601, Issue #5622) +- The scheduler no longer provides a default value for the description + (Issue #5603) +- The scheduler now logs jobs held for authentication using the error level so + it is clear what happened (Issue #5604) +- The `lpadmin` command did not always update the PPD file for changes to the + `cupsIPPSupplies` and `cupsSNMPSupplies` keywords (Issue #5610) +- The scheduler now uses both the group's membership list as well as the + various OS-specific membership functions to determine whether a user belongs + to a named group (Issue #5613) +- Added USB quirks rule for HP LaserJet 1015 (Issue #5617) +- Fixed some PPD parser issues (Issue #5623, Issue #5624) +- The IPP parser no longer allows invalid member attributes in collections + (Issue #5630) +- The configure script now treats the "wheel" group as a potential system + group (Issue #5638) +- Fixed a USB printing issue on macOS (rdar://31433931) +- Fixed IPP buffer overflow (rdar://50035411) +- Fixed memory disclosure issue in the scheduler (rdar://51373853) +- Fixed DoS issues in the scheduler (rdar://51373929) +- Fixed an issue with unsupported "sides" values in the IPP backend + (rdar://51775322) +- The scheduler would restart continuously when idle and printers were not + shared (rdar://52561199) +- Fixed an issue with `EXPECT !name WITH-VALUE ...` tests. +- Fixed a command ordering issue in the Zebra ZPL driver. +- Fixed a memory leak in `ppdOpen`. -CHANGES IN CUPS V2.2.3 ----------------------- - -- The IPP backend could get into an infinite loop for certain errors, causing a - hung queue () -- The scheduler could pause responding to client requests in order to save state - changes to disk () -- Added support for PPD finishing keywords (Issue #4960, Issue #4961, - Issue #4962) -- The IPP backend did not send a media-col attribute for just the source or type - (Issue #4963) -- IPP Everywhere print queues did not always support all print qualities - supported by the printer (Issue #4953) -- IPP Everywhere print queues did not always support all media types supported - by the printer (Issue #4953) -- The IPP Everywhere PPD generator did not return useful error messages - (Issue #4954) -- The IPP Everywhere finishings support did not work correctly with common UI or - command-line options (Issue #4976) -- Fixed an error handling issue for the network backends (Issue #4979) -- The default cupsd.conf file did not work on systems compiled without Kerberos - support (Issue #4947) -- The "reprint job" option was not available for some canceled jobs - (Issue #4915) -- Updated the job listing in the web interface (Issue #4978) -- Fixed some localization issues on macOS () - - -CHANGES IN CUPS V2.2.2 ----------------------- - -- Fixed some issues with the Zebra ZPL printer driver (Issue #4898) -- Fixed some issues with IPP Everywhere printer support (Issue #4893, - Issue #4909, Issue #4916, Issue #4921, Issue #4923, Issue #4932, Issue #4933, - Issue #4938) -- The rastertopwg filter could crash with certain input (Issue #4942) -- Optimized connection usage in the IPP backend () -- The scheduler did not detect when an encrypted connection was closed by the - client on Linux (Issue #4901) -- The cups-lpd program did not catch all legacy usage of ISO-8859-1 - (Issue #4899) -- Fixed builds on systems without a working poll() implementation (Issue #4905) -- Added a USB quirk rule for the Kyocera Ecosys P6026cdn (Issue #4900) -- The scheduler no longer creates log files on startup - () -- The ippContainsString function now uses case-insensitive comparisons for - mimeMediaType, name, and text values in conformance with RFC 2911. -- The network backends now log the addresses that were found for a printer - () -- Let's Encrypt certificates did not work when the hostname contained uppercase - letters (Issue #4919) -- Fixed reporting of printed pages in the web interface (Issue #4924) -- Updated systemd config files (Issue #4935) -- Updated documentation (PR #4896) -- Updated localizations (PR #4894, PR #4895, PR #4904, PR #4908, Issue #4946) -- Updated packaging files (Issue #4940) - - -CHANGES IN CUPS V2.2.1 ----------------------- - -- Added "CreateSelfSignedCerts" directive for cups-files.conf to control whether - the scheduler automatically creates its own self-signed X.509 certificates for - TLS connections (Issue #4876) -- http*Connect did not handle partial failures (Issue #4870) -- Addressed some build warnings on Linux (Issue #4881) -- cupsHashData did not use the correct hashing algorithm - () -- Updated man pages (PR #4885) -- Updated localizations (PR #4877, PR #4886) - - -CHANGES IN CUPS V2.2.0 ----------------------- - -- Normalized the TLS certificate validation code and added additional error - messages to aid troubleshooting. -- The httpConnect functions did not work on Linux when cupsd was not running - (Issue #4870) -- The --no-remote-any option of cupsctl had no effect (Issue #4866) -- http*Connect did not return early when all addresses failed (Issue #4870) - - -CHANGES IN CUPS V2.2rc1 +Changes in CUPS v2.3rc1 ----------------------- -- Updated the list of supported IPP Everywhere media types. -- The IPP backend did not validate TLS credentials properly. -- The printer-state-message attribute was not cleared after a print job with no - errors (Issue #4851) -- The CUPS-Add-Modify-Class and CUPS-Add-Modify-Printer operations did not - always return an error for failed adds (Issue #4854) -- PPD files with names longer than 127 bytes did not work (Issue #4860) -- Updated localizations (Issue #4846, PR #4858) +- The `cups-config` script no longer adds extra libraries when linking against + shared libraries (Issue #5261) +- The supplied example print documents have been optimized for size + (Issue #5529) +- The `cupsctl` command now prevents setting "cups-files.conf" directives + (Issue #5530) +- The "forbidden" message in the web interface is now explained (Issue #5547) +- The footer in the web interface covered some content on small displays + (Issue #5574) +- The libusb-based USB backend now enforces read limits, improving print speed + in many cases (Issue #5583) +- The `ippeveprinter` command now looks for print commands in the "command" + subdirectory. +- The `ipptool` command now supports `$date-current` and `$date-start` variables + to insert the current and starting date and time values, as well as ISO-8601 + relative time values such as "PT30S" for 30 seconds in the future. -CHANGES IN CUPS V2.2b2 +Changes in CUPS v2.3b8 ---------------------- -- Added Upstart support (PR #4825) -- CUPS now supports Let's Encrypt certificates on Linux. +- Media size matching now uses a tolerance of 0.5mm (rdar://33822024) +- The lpadmin command would hang with a bad PPD file (rdar://41495016) +- Fixed a potential crash bug in cups-driverd (rdar://46625579) +- Fixed a performance regression with large PPDs (rdar://47040759) +- Fixed a memory reallocation bug in HTTP header value expansion + (rdar://problem/50000749) +- Timed out job submission now yields an error (Issue #5570) +- Restored minimal support for the `Emulators` keyword in PPD files to allow + old Samsung printer drivers to continue to work (Issue #5562) +- The scheduler did not encode octetString values like "job-password" correctly + for the print filters (Issue #5558) +- The `cupsCheckDestSupported` function did not check octetString values + correctly (Issue #5557) +- Added support for `UserAgentTokens` directive in "client.conf" (Issue #5555) +- Updated the systemd service file for cupsd (Issue #5551) +- The `ippValidateAttribute` function did not catch all instances of invalid + UTF-8 strings (Issue #5509) +- Fixed an issue with the self-signed certificates generated by GNU TLS + (Issue #5506) +- Fixed a potential memory leak when reading at the end of a file (Issue #5473) +- Fixed potential unaligned accesses in the string pool (Issue #5474) +- Fixed a potential memory leak when loading a PPD file (Issue #5475) +- Added a USB quirks rule for the Lexmark E120n (Issue #5478) +- Updated the USB quirks rule for Zebra label printers (Issue #5395) +- Fixed a compile error on Linux (Issue #5483) +- The lpadmin command, web interface, and scheduler all queried an IPP + Everywhere printer differently, resulting in different PPDs for the same + printer (Issue #5484) +- The web interface no longer provides access to the log files (Issue #5513) +- Non-Kerberized printing to Windows via IPP was broken (Issue #5515) +- Eliminated use of private headers and some deprecated macOS APIs (Issue #5516) +- The scheduler no longer stops a printer if an error occurs when a job is + canceled or aborted (Issue #5517) +- Added a USB quirks rule for the DYMO 450 Turbo (Issue #5521) +- Added a USB quirks rule for Xerox printers (Issue #5523) +- The scheduler's self-signed certificate did not include all of the alternate + names for the server when using GNU TLS (Issue #5525) +- Fixed compiler warnings with newer versions of GCC (Issue #5532, Issue #5533) +- Fixed some PPD caching and IPP Everywhere PPD accounting/password bugs + (Issue #5535) +- Fixed `PreserveJobHistory` bug with time values (Issue #5538) +- The scheduler no longer advertises the HTTP methods it supports (Issue #5540) +- Localization updates (Issue #5461, Issues #5471, Issue #5481, Issue #5486, + Issue #5489, Issue #5491, Issue #5492, Issue #5493, Issue #5494, Issue #5495, + Issue #5497, Issue #5499, Issue #5500, Issue #5501, Issue #5504) +- The scheduler did not always idle exit as quickly as it could. +- Added a new `ippeveprinter` command based on the old ippserver sample code. -CHANGES IN CUPS V2.2b1 +Changes in CUPS v2.3b7 ---------------------- -- All CUPS commands now support POSIX options (Issue #4813) -- The scheduler now restarts faster (Issue #4760) -- Improved performance of web interface with large numbers of jobs (Issue #3819) -- Encrypted printing can now be limited to only trusted printers and servers - () -- The scheduler now advertises PWG Raster attributes for IPP Everywhere clients - (Issue #4428) -- The scheduler now logs informational messages for jobs at LogLevel "info" - (Issue #4815) -- The scheduler now uses the getgrouplist function when available (Issue #4611) -- The IPP backend no longer enables compression by default except for certain - raster formats that generally benefit from it () -- The scheduler did not handle out-of-disk situations gracefully (Issue #4742) -- The LPD mini-daemon now detects invalid UTF-8 sequences in job, document, and - user names (Issue #4748) -- The IPP backend now continues on to the next job when the remote server/ - printer puts the job on hold () -- The scheduler did not cancel multi-document jobs immediately - () -- The scheduler did not return non-shared printers to local clients unless they - connected to the domain socket () -- The scheduler now reads the spool directory if one or more job cache entries - point to deleted jobs () -- Added support for disc media sizes () -- The httpAddrConnect and httpConnect* APIs now try connecting to multiple - addresses in parallel () -- The cupsd domain socket is no longer world-accessible on macOS - () -- Interface scripts are no longer supported for security reasons - () -- Added a new cupsHashData API and support for hashed job passwords - () -- Localization fixes (, , - Issue #4041, Issue #4796) -- Documentation changes (Issue #4624, Issue #4781) -- Packaging fixes (PR #4832) +- Fixed some build failures (Issue #5451, Issue #5463) +- Running ppdmerge with the same input and output filenames did not work as + advertised (Issue #5455) + + +Changes in CUPS v2.3b6 +---------------------- + +- Localization update (Issue #5339, Issue #5348, Issue #5362, Issue #5408, + Issue #5410) +- Documentation updates (Issue #5369, Issue #5402, Issue #5403, Issue #5404) +- CVE-2018-4300: Linux session cookies used a predictable random number seed. +- All user commands now support the `--help` option (Issue #5326) +- The `lpoptions` command now works with IPP Everywhere printers that have not + yet been added as local queues (Issue #5045) +- The lpadmin command would create a non-working printer in some error cases + (Issue #5305) +- The scheduler would crash if an empty `AccessLog` directive was specified + (Issue #5309) +- The scheduler did not idle-exit on some Linux distributions (Issue #5319) +- Fixed a regression in the changes to ippValidateAttribute (Issue #5322, + Issue #5330) +- Fixed a crash bug in the Epson dot matrix driver (Issue #5323) +- Automatic debug logging of job errors did not work with systemd (Issue #5337) +- The web interface did not list the IPP Everywhere "driver" (Issue #5338) +- The scheduler did not report all of the supported job options and values + (Issue #5340) +- The IPP Everywhere "driver" now properly supports face-up printers + (Issue #5345) +- Fixed some typos in the label printer drivers (Issue #5350) +- Setting the `Community` name to the empty string in `snmp.conf` now disables + SNMP supply level monitoring by all the standard network backends + (Issue #5354) +- Multi-file jobs could get stuck if the backend failed (Issue #5359, + Issue #5413) +- The IPP Everywhere "driver" no longer does local filtering when printing to + a shared CUPS printer (Issue #5361) +- The lpadmin command now correctly reports IPP errors when configuring an + IPP Everywhere printer (Issue #5370) +- Fixed some memory leaks discovered by Coverity (Issue #5375) +- The PPD compiler incorrectly terminated JCL options (Issue #5379) +- The cupstestppd utility did not generate errors for missing/mismatched + CloseUI/JCLCloseUI keywords (Issue #5381) +- The scheduler now reports the actual location of the log file (Issue #5398) +- Added USB quirk rules (Issue #5395, Issue #5420, Issue #5443) +- The generated PPD files for IPP Everywhere printers did not contain the + cupsManualCopies keyword (Issue #5433) +- Kerberos credentials might be truncated (Issue #5435) +- The handling of `MaxJobTime 0` did not match the documentation (Issue #5438) +- Fixed a bug adding a queue with the `-E` option (Issue #5440) +- The `cupsaddsmb` program has been removed (Issue #5449) +- The `cupstestdsc` program has been removed (Issue #5450) +- The scheduler was being backgrounded on macOS, causing applications to spin + (rdar://40436080) +- The scheduler did not validate that required initial request attributes were + in the operation group (rdar://41098178) +- Authentication in the web interface did not work on macOS (rdar://41444473) +- Fixed an issue with HTTP Digest authentication (rdar://41709086) +- The scheduler could crash when job history was purged (rdar://42198057) +- Fixed a crash bug when mapping PPD duplex options to IPP attributes + (rdar://46183976) +- Fixed a memory leak for some IPP (extension) syntaxes. +- The `cupscgi`, `cupsmime`, and `cupsppdc` support libraries are no longer + installed as shared libraries. +- The `snmp` backend is now deprecated. + + +Changes in CUPS v2.3b5 +---------------------- + +- The `ipptool` program no longer checks for duplicate attributes when running + in list or CSV mode (Issue #5278) +- The `cupsCreateJob`, `cupsPrintFile2`, and `cupsPrintFiles2` APIs did not use + the supplied HTTP connection (Issue #5288) +- Fixed another crash in the scheduler when adding an IPP Everywhere printer + (Issue #5290) +- Added a workaround for certain web browsers that do not support multiple + authentication schemes in a single response header (Issue #5289) +- Fixed policy limits containing the `All` operation (Issue #5296) +- The scheduler was always restarted after idle-exit with systemd (Issue #5297) +- Added a USB quirks rule for the HP LaserJet P1102 (Issue #5310) +- The mailto notifier did not wait for the welcome message (Issue #5312) +- Fixed a parsing bug in the pstops filter (Issue #5321) +- Documentation updates (Issue #5299, Issue #5301, Issue #5306) +- Localization updates (Issue #5317) +- The scheduler allowed environment variables to be specified in the + `cupsd.conf` file (rdar://37836779, rdar://37836995, rdar://37837252, + rdar://37837581) +- Fax queues did not support pause (p) or wait-for-dialtone (w) characters + (rdar://39212256) +- The scheduler did not validate notify-recipient-uri values properly + (rdar://40068936) +- The IPP parser allowed invalid group tags (rdar://40442124) +- Fixed a parsing bug in the new authentication code. + + +Changes in CUPS v2.3b4 +---------------------- + +- NOTICE: Printer drivers are now deprecated (Issue #5270) +- Kerberized printing to another CUPS server did not work correctly + (Issue #5233) +- Fixed printing to some IPP Everywhere printers (Issue #5238) +- Fixed installation of filters (Issue #5247) +- The scheduler now supports using temporary print queues for older IPP/1.1 + print queues like those shared by CUPS 1.3 and earlier (Issue #5241) +- Star Micronics printers need the "unidir" USB quirk rule (Issue #5251) +- Documentation fixes (Issue #5252) +- Fixed a compile issue when PAM is not available (Issue #5253) +- Label printers supported by the rastertolabel driver don't support SNMP, so + don't delay printing to test it (Issue #5256) +- The scheduler could crash while adding an IPP Everywhere printer (Issue #5258) +- The Lexmark Optra E310 printer needs the "no-reattach" USB quirk rule + (Issue #5259) +- Systemd did not restart cupsd when configuration changes were made that + required a restart (Issue #5263) +- The IPP Everywhere PPD generator did not include the `cupsJobPassword` + keyword, when supported (Issue #5265) +- Fixed an Avahi crash bug in the scheduler (Issue #5268) +- Raw print queues are now deprecated (Issue #5269) +- Fixed an RPM packaging problem (Issue #5276) +- The IPP backend did not properly detect failed PDF prints (rdar://34055474) +- TLS connections now properly timeout (rdar://34938533) +- Temp files could not be created in some sandboxed applications + (rdar://37789645) +- The ipptool `--ippserver` option did not encode out-of-band attributes + correctly. +- Added public `cupsEncodeOption` API for encoding a single option as an IPP + attribute. +- Removed support for the `-D_PPD_DEPRECATED=""` developer cheat - the PPD API + should no longer be used. +- Removed support for `-D_IPP_PRIVATE_STRUCTURES=1` developer cheat - the IPP + accessor functions should be used instead. + + +Changes in CUPS v2.3b3 +---------------------- + +- More fixes for printing to old CUPS servers (Issue #5211) +- The IPP Everywhere PPD generator did not support deep grayscale or 8-bit per + component AdobeRGB (Issue #5227) +- Additional changes for the scheduler to substitute default values for invalid + job attributes when running in "relaxed conformance" mode (Issue #5229) +- Localization changes (Issue #5232, rdar://37068158) +- The `cupsCopyDestInfo` function did not work with all print queues + (Issue #5235) + + +Changes in CUPS v2.3b2 +---------------------- + +- Localization changes (Issue #5210) +- Build fixes (Issue #5217) +- IPP Everywhere PPDs were not localized to English (Issue #5205) +- The `cupsGetDests` and `cupsEnumDests` functions no longer filter out local + print services like IPP USB devices (Issue #5206) +- The `cupsCopyDest` function now correctly copies the `is_default` value + (Issue #5208) +- Printing to old CUPS servers has been fixed (Issue #5211) +- The `ppdInstallableConflict` tested too many constraints (Issue #5213) +- All HTTP field values can now be longer than `HTTP_MAX_VALUE` bytes + (Issue #5216) +- Added a USB quirk rule for Canon MP280 series printers (Issue #5221) +- The `cupsRasterWritePixels` function did not correctly swap bytes for some + formats (Issue #5225) +- Fixed an issue with mapping finishing options (rdar://34250727) +- The `ppdLocalizeIPPReason` function incorrectly returned a localized version + of "none" (rdar://36566269) +- The scheduler did not add ".local" to the default DNS-SD host name when + needed. + + +Changes in CUPS v2.3b1 +---------------------- + +- CUPS is now provided under the Apache License, Version 2.0. +- Documentation updates (Issue #4580, Issue #5177, Issue #5192) +- The `cupsCopyDestConflicts` function now handles collection attribute + ("media-col", "finishings-col", etc.) constraints (Issue #4096) +- The `lpoptions` command incorrectly saved default options (Issue #4717) +- The `lpstat` command now reports when new jobs are being held (Issue #4761) +- The `ippfind` command now supports finding printers whose name starts with an + underscore (Issue #4833) +- The CUPS library now supports the latest HTTP Digest authentication + specification including support for SHA-256 (Issue #4862) +- The scheduler now supports the "printer-id" attribute (Issue #4868) +- No longer support backslash, question mark, or quotes in printer names + (Issue #4966) +- The scheduler no longer logs pages as they are printed, instead just logging + a total of the pages printed at job completion (Issue #4991) +- Dropped RSS subscription management from the web interface (Issue #5012) +- Bonjour printer sharing now uses the DNS-SD hostname (or ServerName value if + none is defined) when registering shared printers on the network (Issue #5071) +- The `ipptool` command now supports writing `ippserver` attributes files + (Issue #5093) +- The `lp` and `lpr` commands now provide better error messages when the default + printer cannot be found (Issue #5096) +- The `lpadmin` command now provides a better error message when an unsupported + System V interface script is used (Issue #5111) +- The scheduler did not write out dirty configuration and state files if there + were open client connections (Issue #5118) +- The `SSLOptions` directive now supports `MinTLS` and `MaxTLS` options to + control the minimum and maximum TLS versions that will be allowed, + respectively (Issue #5119) +- Dropped hard-coded CGI scripting language support (Issue #5124) +- The `cupsEnumDests` function did not include options from the lpoptions + files (Issue #5144) +- Fixed the `ippserver` sample code when threading is disabled or unavailable + (Issue #5154) +- Added label markup to checkbox and radio button controls in the web interface + templates (Issue #5161) +- Fixed group validation on OpenBSD (Issue #5166) +- Improved IPP Everywhere media support, including a new + `cupsAddDestMediaOptions` function (Issue #5167) +- IPP Everywhere PPDs now include localizations of printer-specific media types, + when available (Issue #5168) +- The cups-driverd program incorrectly stopped scanning PPDs as soon as a loop + was seen (Issue #5170) +- IPP Everywhere PPDs now support IPP job presets (Issue #5179) +- IPP Everywhere PPDs now support finishing templates (Issue #5180) +- Fixed a journald support bug in the scheduler (Issue #5181) +- Fixed PAM module detection and added support for the common PAM definitions + (Issue #5185) +- The scheduler now substitutes default values for invalid job attributes when + running in "relaxed conformance" mode (Issue #5186) +- The scheduler did not work with older versions of uClibc (Issue #5188) +- The scheduler now generates a strings file for localizing PPD options + (Issue #5194) diff --git a/CONTRIBUTING.txt b/CONTRIBUTING.txt new file mode 100644 index 0000000..2421d0d --- /dev/null +++ b/CONTRIBUTING.txt @@ -0,0 +1,15 @@ +Contributing to CUPS +==================== + +CUPS is developed by Apple Inc. and distributed as open source software under +the Apache License, Version 2.0 with exceptions to allow linking to GPL2/LGPL2 +code. Significant contributions to CUPS must be licensed to Apple using the +Apple Contributor Agreement: + + https://www.cups.org/AppleContributorAgreement_2011-03-10.pdf + +Contributions should be submitted as attachments to bug reports on the +[CUPS Github project](https://github.com/apple/cups). Changes to existing +source files should be submitted as unified diffs while new source files +should be provided as-is or in an archive. Github pull requests can also be +used to submit changes. diff --git a/CREDITS.txt b/CREDITS.txt index 7d5a8b9..8b1a15d 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1,4 +1,4 @@ -CREDITS - 2017-05-01 +CREDITS - 2019-08-21 ==================== Few projects are completed by one person, and CUPS is no exception. We'd like diff --git a/DEVELOPING.txt b/DEVELOPING.txt new file mode 100644 index 0000000..df76323 --- /dev/null +++ b/DEVELOPING.txt @@ -0,0 +1,626 @@ +Developing for CUPS +=================== + +Please see the [Contributing to CUPS](CONTRIBUTING.md) file for information on +contributing to the CUPS project. + + +How To Contact The Developers +----------------------------- + +The CUPS mailing lists are the primary means of asking questions and informally +discussing issues and feature requests with the CUPS developers and other +experienced CUPS users and developers. The "cups" mailing list is intended for +CUPS usage questions and new software announcements while the "cups-devel" +mailing list provides a forum for CUPS developers and monitoring new bugs. + + +Interfaces +---------- + +CUPS interfaces, including the C APIs and command-line arguments, environment +variables, configuration files, and output format, are stable across patch +versions and are generally backwards-compatible with interfaces used in prior +major and minor versions. However, program interfaces such as those used by +the scheduler to run filter, port monitor, and backend processes for job +processing should only be considered stable from the point of view of a +filter, port monitor, or backend. Software that simulates the scheduler in +order to run those programs outside of CUPS must necessarily be updated when +the corresponding interface is changed in a subsequent CUPS release, otherwise +undefined behavior can occur. + +CUPS C APIs starting with an underscore (`_`) are considered to be private to +CUPS and are not subject to the normal guarantees of stability between CUPS +releases and must never be used in non-CUPS source code. Similarly, +configuration and state files written by CUPS are considered private if a +corresponding man page is not provided with the CUPS release. Never rely on +undocumented files or formats when developing software for CUPS. Always use a +published C API to access data stored in a file to avoid compatibility problems +in the future. + + +Build System +------------ + +The CUPS build system uses GNU autoconf to tailor the library to the local +operating system. Project files for the current release of Microsoft Visual +Studio are also provided for Microsoft Windows®. To improve portability, +makefiles must not make use of features unique to GNU make. See the MAKEFILE +GUIDELINES section for a description of the allowed make features and makefile +guidelines. + +Additional GNU build programs such as GNU automake and GNU libtool must not be +used. GNU automake produces non-portable makefiles which depend on GNU- +specific extensions, and GNU libtool is not portable or reliable enough for +CUPS. + + +Version Numbering +----------------- + +CUPS uses a three-part version number separated by periods to represent the +major, minor, and patch release numbers. Major release numbers indicate large +design changes or backwards-incompatible changes to the CUPS API or CUPS +Imaging API. Minor release numbers indicate new features and other smaller +changes which are backwards-compatible with previous CUPS releases. Patch +numbers indicate bug fixes to the previous feature or patch release. This +version numbering scheme is consistent with the +[Semantic Versioning](http://semver.org) specification. + +> Note: +> +> When we talk about compatibility, we are talking about binary compatibility +> for public APIs and output format compatibility for program interfaces. +> Changes to configuration file formats or the default behavior of programs +> are not generally considered incompatible as the upgrade process can +> normally address such changes gracefully. + +Production releases use the plain version numbers: + + MAJOR.MINOR.PATCH + 1.0.0 + ... + 1.1.0 + ... + 1.1.23 + ... + 2.0.0 + ... + 2.1.0 + 2.1.1 + 2.1.2 + 2.1.3 + +The first production release in a MAJOR.MINOR series (MAJOR.MINOR.0) is called +a feature release. Feature releases are the only releases that may contain new +features. Subsequent production releases in a MAJOR.MINOR series may only +contain bug fixes. + +Beta-test releases are identified by appending the letter B to the major and +minor version numbers followed by the beta release number: + + MAJOR.MINORbNUMBER + 2.2b1 + +Release candidates are identified by appending the letters RC to the major and +minor version numbers followed by the release candidate number: + + MAJOR.MINORrcNUMBER + 2.2rc1 + + +Coding Guidelines +----------------- + +Contributed source code must follow the guidelines below. While the examples +are for C and C++ source files, source code for other languages should conform +to the same guidelines as allowed by the language. + +Source code comments provide the reference portion of the CUPS Programming +Manual, which is generated using the [codedoc](https://www.msweet.org/codedoc) +software. + + +### Source Files + +All source files names must be 16 characters or less in length to ensure +compatibility with older UNIX filesystems. Source files containing functions +have an extension of ".c" for C and ".cxx" for C++ source files. All other +"include" files have an extension of ".h". Tabs are set to 8 characters or +columns. + +> Note: +> +> The ".cxx" extension is used because it is the only common C++ extension +> between Linux, macOS, UNIX, and Windows. + +The top of each source file contains a header giving the purpose or nature of +the source file and the copyright and licensing notice: + + /* + * Description of file contents. + * + * Copyright 2017 by Apple Inc. + * + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. + */ + + +### Header Files + +All public header files must include the "versioning.h" header file, or a header +that does so. Function declarations are then "decorated" with the correct +`_CUPS_API_major_minor` macro to define its availability based on the build +environment, for example: + + extern int cupsDoThis(int foo, int bar) _CUPS_API_2_2; + +Private API header files must be named with the suffix "-private", for example +the "cups.h" header file defines all of the public CUPS APIs while the +"cups-private.h" header file defines all of the private CUPS APIs as well. +Typically a private API header file will include the corresponding public API +header file. + + +### Comments + +All source code utilizes block comments within functions to describe the +operations being performed by a group of statements; avoid putting a comment +per line unless absolutely necessary, and then consider refactoring the code +so that it is not necessary. C source files use the block comment format +("/* comment */") since many vendor C compilers still do not support C99/C++ +comments ("// comment"): + + /* + * Clear the state array before we begin... + */ + + for (i = 0; i < (sizeof(array) / sizeof(sizeof(array[0])); i ++) + array[i] = CUPS_STATE_IDLE; + + /* + * Wait for state changes on another thread... + */ + + do + { + for (i = 0; i < (sizeof(array) / sizeof(sizeof(array[0])); i ++) + if (array[i] != CUPS_STATE_IDLE) + break; + + if (i == (sizeof(array) / sizeof(array[0]))) + sleep(1); + } while (i == (sizeof(array) / sizeof(array[0]))); + + +### Indentation + +All code blocks enclosed by brackets 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: + + { + int i; /* Looping var */ + + /* + * Process foobar values from 0 to 999... + */ + + for (i = 0; i < 1000; i ++) + { + do_this(i); + do_that(i); + } + } + +Single-line statements following "do", "else", "for", "if", and "while" are +indented 2 spaces as well. Blocks of code in a "switch" block are indented 4 +spaces after each "case" and "default" case: + + switch (array[i]) + { + case CUPS_STATE_IDLE : + do_this(i); + do_that(i); + break; + + default : + do_nothing(i); + break; + } + + +### Spacing + +A space follows each reserved word such as `if`, `while`, etc. Spaces are not +inserted between a function name and the arguments in parenthesis. + + +### Return Values + +Parenthesis surround values returned from a function: + + return (CUPS_STATE_IDLE); + + +### Functions + +Functions with a global scope have a lowercase prefix followed by capitalized +words, e.g., `cupsDoThis`, `cupsDoThat`, `cupsDoSomethingElse`, etc. Private +global functions begin with a leading underscore, e.g., `_cupsDoThis`, +`_cupsDoThat`, etc. + +Functions with a local scope are declared static with lowercase names and +underscores between words, e.g., `do_this`, `do_that`, `do_something_else`, etc. + +Each function begins with a comment header describing what the function does, +the possible input limits (if any), the possible output values (if any), and +any special information needed: + + /* + * 'do_this()' - Compute y = this(x). + * + * Notes: none. + */ + + static float /* O - Inverse power value, 0.0 <= y <= 1.1 */ + do_this(float x) /* I - Power value (0.0 <= x <= 1.1) */ + { + ... + return (y); + } + +Return/output values are indicated using an "O" prefix, input values are +indicated using the "I" prefix, and values that are both input and output use +the "IO" prefix for the corresponding in-line comment. + +The [codedoc](https://www.msweet.org/codedoc) documentation generator also +understands the following special text in the function description comment: + + @deprecated@ - Marks the function as deprecated: not recommended + for new development and scheduled for removal. + @link name@ - Provides a hyperlink to the corresponding function + or type definition. + @since CUPS version@ - Marks the function as new in the specified version + of CUPS. + @private@ - Marks the function as private so it will not be + included in the documentation. + + +### Variables + +Variables with a global scope are capitalized, e.g., `ThisVariable`, +`ThatVariable`, `ThisStateVariable`, etc. Globals in CUPS libraries are either +part of the per-thread global values managed by the `_cupsGlobals` function +or are suitably protected for concurrent access. Global variables should be +replaced by function arguments whenever possible. + +Variables with a local scope are lowercase with underscores between words, +e.g., `this_variable`, `that_variable`, etc. Any "local global" variables +shared by functions within a source file are declared static. As for global +variables, local static variables are suitably protected for concurrent access. + +Each variable is declared on a separate line and is immediately followed by a +comment block describing the variable: + + int ThisVariable; /* The current state of this */ + static int that_variable; /* The current state of that */ + + +### Types + +All type names are lowercase with underscores between words and `_t` appended +to the end of the name, e.g., `cups_this_type_t`, `cups_that_type_t`, etc. +Type names start with a prefix, typically `cups` or the name of the program, +to avoid conflicts with system types. Private type names start with an +underscore, e.g., `_cups_this_t`, `_cups_that_t`, etc. + +Each type has a comment block immediately after the typedef: + + typedef int cups_this_type_t; /* This type is for CUPS foobar options. */ + + +### Structures + +All structure names are lowercase with underscores between words and `_s` +appended to the end of the name, e.g., `cups_this_s`, `cups_that_s`, etc. +Structure names start with a prefix, typically `cups` or the name of the +program, to avoid conflicts with system types. Private structure names start +with an underscore, e.g., `_cups_this_s`, `_cups_that_s`, etc. + +Each structure has a comment block immediately after the struct and each member +is documented similar to the variable naming policy above: + + struct cups_this_struct_s /* This structure is for CUPS foobar options. */ + { + int this_member; /* Current state for this */ + int that_member; /* Current state for that */ + }; + + +### Constants + +All constant names are uppercase with underscores between words, e.g., +`CUPS_THIS_CONSTANT`, `CUPS_THAT_CONSTANT`, etc. Constants begin with an +uppercase prefix, typically `CUPS_` or the program or type name. Private +constants start with an underscore, e.g., `_CUPS_THIS_CONSTANT`, +`_CUPS_THAT_CONSTANT`, etc. + +Typed enumerations should be used whenever possible to allow for type checking +by the compiler. + +Comment blocks immediately follow each constant: + + typedef enum cups_tray_e /* Tray enumerations */ + { + CUPS_TRAY_THIS, /* This tray */ + CUPS_TRAY_THAT /* That tray */ + } cups_tray_t; + + +## Makefile Guidelines + +The following is a guide to the makefile-based build system used by CUPS. +These standards have been developed over the years to allow CUPS to be built on +as many systems and environments as possible. + + +### General Organization + +The CUPS source code is organized functionally into a top-level makefile, +include file, and subdirectories each with their own makefile and dependencies +files. The ".in" files are template files for the autoconf software and are +used to generate a static version of the corresponding file. + + +### Makefile Documentation + +Each makefile starts with the standard CUPS header containing the description +of the file, and CUPS copyright and license notice: + + # + # Makefile for ... + # + # Copyright 2017 by Apple Inc. + # + # Licensed under Apache License v2.0. See the file "LICENSE" for more + # information. + # + + +### Portable Makefile Construction + +CUPS uses a common subset of make program syntax to ensure that the software +can be compiled "out of the box" on as many systems as possible. The following +is a list of assumptions we follow when constructing makefiles: + +- Targets; we assume that the make program supports the notion of simple + targets of the form "name:" that perform tab-indented commands that follow + the target, e.g.: + + target: + TAB target commands + +- Dependencies; we assume that the make program supports recursive dependencies + on targets, e.g.: + + target: foo bar + TAB target commands + + foo: bla + TAB foo commands + + bar: + TAB bar commands + + bla: + TAB bla commands + +- Variable Definition; we assume that the make program supports variable + definition on the command-line or in the makefile using the following form: + + name=value + +- Variable Substitution; we assume that the make program supports variable + substitution using the following forms: + + - `$(name)`; substitutes the value of "name", + - `$(name:.old=.new)`; substitutes the value of "name" with the filename + extension ".old" changed to ".new", + - `$(MAKEFLAGS)`; substitutes the command-line options passed to the + program without the leading hyphen (-), + - `$$`; substitutes a single $ character, + - `$<`; substitutes the current source file or dependency, and + - `$@`; substitutes the current target name. + +- Suffixes; we assume that the make program supports filename suffixes with + assumed dependencies, e.g.: + + .SUFFIXES: .c .o + .c.o: + TAB $(CC) $(CFLAGS) -o $@ -c $< + +- Include Files; we assume that the make program supports the include + directive, e.g.: + + include ../Makedefs + include Dependencies + +- Comments; we assume that comments begin with a # character and proceed to the + end of the current line. + +- Line Length; we assume that there is no practical limit to the length of + lines. + +- Continuation of long lines; we assume that the `\` character may be placed at + the end of a line to concatenate two or more lines in a makefile to form a + single long line. + +- Shell; we assume a POSIX-compatible shell is present on the build system. + + +### Standard Variables + +The following variables are defined in the "Makedefs" file generated by the +autoconf software: + +- `ALL_CFLAGS`; the combined C compiler options, +- `ALL_CXXFLAGS`; the combined C++ compiler options, +- `AMANDIR`; the administrative man page installation directory (section 8/1m + depending on the platform), +- `AR`; the library archiver command, +- `ARFLAGS`; options for the library archiver command, +- `AWK`; the local awk command, +- `BINDIR`; the binary installation directory, +- `BUILDROOT`; optional installation prefix (defaults to DSTROOT), +- `CC`; the C compiler command, +- `CFLAGS`; options for the C compiler command, +- `CHMOD`; the chmod command, +- `CXX`; the C++ compiler command, +- `CXXFLAGS`; options for the C++ compiler command, +- `DATADIR`; the data file installation directory, +- `DSO`; the C shared library building command, +- `DSOXX`; the C++ shared library building command, +- `DSOFLAGS`; options for the shared library building command, +- `INCLUDEDIR`; the public header file installation directory, +- `INSTALL`; the install command, +- `INSTALL_BIN`; the program installation command, +- `INSTALL_COMPDATA`; the compressed data file installation command, +- `INSTALL_CONFIG`; the configuration file installation command, +- `INSTALL_DATA`; the data file installation command, +- `INSTALL_DIR`; the directory installation command, +- `INSTALL_LIB`; the library installation command, +- `INSTALL_MAN`; the documentation installation command, +- `INSTALL_SCRIPT`; the shell script installation command, +- `LD`; the linker command, +- `LDFLAGS`; options for the linker, +- `LIBDIR`; the library installation directory, +- `LIBS`; libraries for all programs, +- `LN`; the ln command, +- `MAN1EXT`; extension for man pages in section 1, +- `MAN3EXT`; extension for man pages in section 3, +- `MAN5EXT`; extension for man pages in section 5, +- `MAN7EXT`; extension for man pages in section 7, +- `MAN8DIR`; subdirectory for man pages in section 8, +- `MAN8EXT`; extension for man pages in section 8, +- `MANDIR`; the man page installation directory, +- `OPTIM`; common compiler optimization options, +- `PRIVATEINCLUDE`; the private header file installation directory, +- `RM`; the rm command, +- `SHELL`; the sh (POSIX shell) command, +- `STRIP`; the strip command, +- `srcdir`; the source directory. + + +### Standard Targets + +The following standard targets are defined in each makefile: + +- `all`; creates all target programs, libraries, and documentation files, +- `clean`; removes all target programs libraries, documentation files, and object + files, +- `depend`; generates automatic dependencies for any C or C++ source files (also + see "DEPENDENCIES"), +- `distclean`; removes autoconf-generated files in addition to those removed by + the "clean" target, +- `install`; installs all distribution files in their corresponding locations + (also see "INSTALL/UNINSTALL SUPPORT"), +- `install-data`; installs all data files in their corresponding locations (also + see "INSTALL/UNINSTALL SUPPORT"), +- `install-exec`; installs all executable files in their corresponding locations + (also see "INSTALL/UNINSTALL SUPPORT"), +- `install-headers`; installs all include files in their corresponding locations + (also see "INSTALL/UNINSTALL SUPPORT"), +- `install-libs`; installs all library files in their corresponding locations + (also see "INSTALL/UNINSTALL SUPPORT"), and +- `uninstall`; removes all distribution files from their corresponding locations + (also see "INSTALL/UNINSTALL SUPPORT"). + + +### Object Files + +Object files (the result of compiling a C or C++ source file) have the +extension ".o". + + +### Programs + +Program files are the result of linking object files and libraries together to +form an executable file. A typical program target looks like: + + program: $(OBJS) + TAB echo Linking $@... + TAB $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + +### Static Libraries + +Static libraries have a prefix of "lib" and the extension ".a". A typical +static library target looks like: + + libname.a: $(OBJECTS) + TAB echo Creating $@... + TAB $(RM) $@ + TAB $(AR) $(ARFLAGS) $@ $(OBJECTS) + TAB $(RANLIB) $@ + +### Shared Libraries + +Shared libraries have a prefix of "lib" and the extension ".dylib" or ".so" +depending on the operating system. A typical shared library is composed of +several targets that look like: + + libname.so: $(OBJECTS) + TAB echo $(DSOCOMMAND) libname.so.$(DSOVERSION) ... + TAB $(DSOCOMMAND) libname.so.$(DSOVERSION) $(OBJECTS) + TAB $(RM) libname.so libname.so.$(DSOMAJOR) + TAB $(LN) libname.so.$(DSOVERSION) libname.so.$(DSOMAJOR) + TAB $(LN) libname.so.$(DSOVERSION) libname.so + + libname.dylib: $(OBJECTS) + TAB echo $(DSOCOMMAND) libname.$(DSOVERSION).dylib ... + TAB $(DSOCOMMAND) libname.$(DSOVERSION).dylib \ + TAB TAB -install_name $(libdir)/libname.$(DSOMAJOR).dylib \ + TAB TAB -current_version libname.$(DSOVERSION).dylib \ + TAB TAB -compatibility_version $(DSOMAJOR).0 \ + TAB TAB $(OBJECTS) $(LIBS) + TAB $(RM) libname.dylib + TAB $(RM) libname.$(DSOMAJOR).dylib + TAB $(LN) libname.$(DSOVERSION).dylib libname.$(DSOMAJOR).dylib + TAB $(LN) libname.$(DSOVERSION).dylib libname.dylib + +### Dependencies + +Static dependencies are expressed in each makefile following the target, for +example: + + foo: bar + +Static dependencies are only used when it is not possible to automatically +generate them. Automatic dependencies are stored in a file named +"Dependencies" and included at the end of the makefile. The following "depend" +target rule is used to create the automatic dependencies: + + depend: + TAB $(CC) -MM $(ALL_CFLAGS) $(OBJS:.o=.c) >Dependencies + +We regenerate the automatic dependencies on an macOS system and express any +non-macOS dependencies statically in the makefile. + + +### Install/Uninstall Support + +All makefiles contains install and uninstall rules which install or remove the +corresponding software. These rules must use the $(BUILDROOT) variable as a +prefix to any installation directory so that CUPS can be installed in a +temporary location for packaging by programs like rpmbuild. + +The `INSTALL_BIN`, `INSTALL_COMPDATA`, `INSTALL_CONFIG`, `INSTALL_DATA`, +`INSTALL_DIR`, `INSTALL_LIB`, `INSTALL_MAN`, and `INSTALL_SCRIPT` variables +must be used when installing files so that the proper ownership and permissions +are set on the installed files. + +The `$(RANLIB)` command must be run on any static libraries after installation +since the symbol table is invalidated when the library is copied on some +platforms. diff --git a/INSTALL.txt b/INSTALL.txt index 4a2529a..d2afc4c 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -1,14 +1,28 @@ -INSTALL - CUPS v2.2.4 - 2017-06-30 +INSTALL - CUPS v2.3.0 - 2019-08-21 ================================== This file describes how to compile and install CUPS from source code. For more -information on CUPS see the file called "README.txt". A complete change log can -be found in "CHANGES.txt". +information on CUPS see the file called "README.md". A complete change log can +be found in "CHANGES.md". -> USING CUPS REQUIRES ADDITIONAL THIRD-PARTY SUPPORT SOFTWARE AND PRINTER -> DRIVERS. THESE ARE TYPICALLY INCLUDED WITH YOUR OPERATING SYSTEM -> DISTRIBUTION. APPLE DOES NOT ENDORSE OR SUPPORT THIRD-PARTY SUPPORT SOFTWARE -> FOR CUPS. +Using CUPS requires additional third-party support software and printer drivers. +These are typically included with your operating system distribution. Apple +does not endorse or support third-party support software for CUPS. + +> Note: Current versions of macOS DO NOT allow installation to /usr with the +> default System Integrity Protection (SIP) settings. In addition, we do not +> recommend replacing the CUPS supplied with macOS because: +> +> a. not all versions of CUPS are compatible with every macOS release, +> +> b. code signing prevents replacement of system libraries and access to the +> system keychain (needed for encrypted printer sharing), and +> +> c. software updates will often replace parts of your local installation, +> potentially rendering your system unusable. +> +> Apple only supports using the Clang supplied with Xcode to build CUPS on +> macOS. BEFORE YOU BEGIN @@ -52,12 +66,15 @@ main CUPS source directory. To configure CUPS for your system, type: 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 +commands on your system. Use the `--prefix` option to install the CUPS software in another location: ./configure --prefix=/some/directory -To see a complete list of configuration options, use the --help option: +> Note: Current versions of macOS DO NOT allow installation to /usr with the +> default System Integrity Protection (SIP) settings. + +To see a complete list of configuration options, use the `--help` option: ./configure --help @@ -82,26 +99,20 @@ or: LDFLAGS="-L/some/directory" \ ./configure ... -The "--enable-debug" option compiles CUPS with debugging information enabled. +The `--enable-debug` option compiles CUPS with debugging information enabled. Additional debug logging support can be enabled using the -"--enable-debug-printfs" option - these debug messages are enabled using the -CUPS_DEBUG_LOG environment variable at run-time. +`--enable-debug-printfs` option - these debug messages are enabled using the +`CUPS_DEBUG_xxx` environment variables at run-time. CUPS also includes an extensive set of unit tests that can be used to find and diagnose a variety of common problems - use the "--enable-unit-tests" configure option to run them at build time. -On macOS, use the "--with-archflags" option to build with the correct set of +On macOS, use the `--with-archflags` option to build with the correct set of architectures: ./configure --with-archflags="-arch i386 -arch x86_64" ... -> Note: Current versions of macOS DO NOT allow installation to /usr with the -> default system integrity settings. In addition, we do not recommend replacing -> the CUPS supplied with macOS because not all versions of CUPS are compatible -> with every macOS release, and because software updates will replace parts -> of your local installation potentially rendering your system unusable. - Once you have configured things, just type: make ENTER @@ -184,7 +195,7 @@ for FreeBSD, NetBSD, and OpenBSD. The target is one of the following: GETTING DEBUG LOGGING FROM CUPS ------------------------------- -When configured with the "--enable-debug-printfs" option, CUPS compiles in +When configured with the `--enable-debug-printfs` option, CUPS compiles in additional debug logging support in the scheduler, CUPS API, and CUPS Imaging API. The following environment variables are used to enable and control debug logging: @@ -195,13 +206,14 @@ logging: the logging. The default level is 1. - `CUPS_DEBUG_LOG`: Specifies a log file to use. Specify the name "-" to send the messages to stderr. Prefix a filename with "+" to append to an existing - file. + file. You can include a single "%d" in the filename to embed the current + process ID. REPORTING PROBLEMS ------------------ -If you have problems, READ THE DOCUMENTATION FIRST! If the documentation does +If you have problems, *read the documentation first*! If the documentation does not solve your problems, please post a message on the users forum at: https://www.cups.org/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index 51d42e2..0000000 --- a/LICENSE.txt +++ /dev/null @@ -1,965 +0,0 @@ - CUPS License Agreement - - Copyright 2007-2016 by Apple Inc. - 1 Infinite Loop - Cupertino, CA 95014 USA - - WWW: http://www.cups.org/ - - -INTRODUCTION - -CUPS(tm) is provided under the GNU General Public License ("GPL") -and GNU Library General Public License ("LGPL"), Version 2, with an -exception for Apple operating systems. A copy of the exception and -licenses follow this introduction. - -The GNU LGPL applies to the CUPS and CUPS Imaging libraries -located in the "cups" and "filter" subdirectories of the CUPS -source distribution and the files in the "test" subdirectory. The -GNU GPL applies to the remainder of the CUPS distribution. - -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. - -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 changes or additions -to the software, and all code must be provided under the GPL or -LGPL as appropriate. The only exceptions to this are the portions -of the CUPS software covered by the Apple operating system -license exceptions outlined later in this license agreement. - -The GNU LGPL relaxes the "link-to" restriction, allowing you to -develop applications that use the CUPS and CUPS Imaging libraries -under other licenses and/or conditions as appropriate for your -application, driver, or filter. - - -LICENSE EXCEPTIONS - -In addition, as the copyright holder of CUPS, Apple Inc. grants -the following special exception: - - 1. Apple Operating System Development License Exception; - - a. Software that is developed by any person or entity - for an Apple Operating System ("Apple OS-Developed - Software"), including but not limited to Apple and - third party printer drivers, filters, and backends - for an Apple Operating System, that is linked to the - CUPS imaging library or based on any sample filters - or backends provided with CUPS shall not be - considered to be a derivative work or collective work - based on the CUPS program and is exempt from the - mandatory source code release clauses of the GNU GPL. - You may therefore distribute linked combinations of - the CUPS imaging library with Apple OS-Developed - Software without releasing the source code of the - Apple OS-Developed Software. You may also use sample - filters and backends provided with CUPS to develop - Apple OS-Developed Software without releasing the - source code of the Apple OS-Developed Software. - - b. An Apple Operating System means any operating system - software developed and/or marketed by Apple Inc., - including but not limited to all existing releases and - versions of Apple's Darwin, iOS, macOS, macOS Server, and - tvOS products and all follow-on releases and future - versions thereof. - - c. This exception is only available for Apple - OS-Developed Software and does not apply to software - that is distributed for use on other operating - systems. - - d. All CUPS software that falls under this license - exception have the following text at the top of each - source file: - - This file is subject to the Apple OS-Developed - Software exception. - -No developer is required to provide this exception in a derived -work. - - -KERBEROS SUPPORT CODE - -The Kerberos support code ("KSC") is copyright 2006 by Jelmer -Vernooij and is provided 'as-is', without any express or implied -warranty. In no event will the author or Apple Inc. be held -liable for any damages arising from the use of the KSC. - -Sources files containing KSC have the following text at the top -of each source file: - - This file contains Kerberos support code, copyright 2006 by - Jelmer Vernooij. - -The KSC copyright and license apply only to Kerberos-related -feature code in CUPS. Such code is typically conditionally -compiled based on the present of the HAVE_GSSAPI preprocessor -definition. - -Permission is granted to anyone to use the KSC for any purpose, -including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - - 1. The origin of the KSC must not be misrepresented; you - must not claim that you wrote the original software. If - you use the KSC in a product, an acknowledgment in the - product documentation would be appreciated but is not - required. - - 2. Altered source versions must be plainly marked as such, - and must not be misrepresented as being the original - software. - - 3. This notice may not be removed or altered from any source - distribution. - - -TRADEMARKS - -CUPS and the CUPS logo (the "CUPS Marks") are trademarks of Apple -Inc. Apple grants you a non-exclusive and non-transferable right -to use the CUPS Marks in any direct port or binary distribution -incorporating CUPS software and in any promotional material -therefor. You agree that your products will meet the highest -levels of quality and integrity for similar goods, not be unlawful, -and be developed, manufactured, and distributed in compliance with -this license. You will not interfere with Apple's rights in the -CUPS Marks, and all use of the CUPS Marks shall inure to the -benefit of Apple. This license does not apply to use of the CUPS -Marks in a derivative products, which requires prior written -permission from Apple Inc. - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim 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. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. 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". - -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. - - 1. 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. - -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 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: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) 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. - - c) 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.) - -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. - - 3. 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: - - a) 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, - - b) 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, - - c) 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.) - -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. - - 4. 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. - - 5. 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. - - 6. 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. - - 7. 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. - -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. - - 8. 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. - - 9. 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. - -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. - - 10. 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 - - 11. 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. - - 12. 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 - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. - - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - [This is the first released version of the library GPL. It is - 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. - - GNU LIBRARY GENERAL PUBLIC LICENSE - 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: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) 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. - - (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: - - a) 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.) - - b) 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. - - c) 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. - - d) 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: - - a) 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. - - b) 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. - - 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. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/Makedefs.in b/Makedefs.in index f958c26..9ee7585 100644 --- a/Makedefs.in +++ b/Makedefs.in @@ -1,32 +1,39 @@ # # Common makefile definitions for CUPS. # -# Copyright 2007-2017 by Apple Inc. -# Copyright 1997-2007 by Easy Software Products, all rights reserved. +# Copyright © 2007-2019 by Apple Inc. +# Copyright © 1997-2007 by Easy Software Products, all rights reserved. # -# These coded instructions, statements, and computer programs are the -# property of Apple Inc. and are protected by Federal copyright -# law. Distribution and use rights are outlined in the file "LICENSE.txt" -# which should have been included with this file. If this file is -# missing or damaged, see the license at "http://www.cups.org/". +# Licensed under Apache License v2.0. See the file "LICENSE" for more +# information. # +# +# CUPS version... +# + +CUPS_VERSION = @CUPS_VERSION@ + + # # Programs... # AR = @AR@ AWK = @AWK@ -CC = @LIBTOOL@ @CC@ +CC = @LIBTOOL_CC@ @CC@ CHMOD = @CHMOD@ -CXX = @LIBTOOL@ @CXX@ +CXX = @LIBTOOL_CXX@ @CXX@ DSO = @DSO@ DSOXX = @DSOXX@ -GZIP = @GZIP@ +GZIPPROG = @GZIPPROG@ INSTALL = @INSTALL@ LD = @LD@ +LD_CC = @LD_CC@ +LD_CXX = @LD_CXX@ LIBTOOL = @LIBTOOL@ LN = @LN@ -sf +MKDIR = @MKDIR@ -p MV = @MV@ RANLIB = @RANLIB@ RM = @RM@ -f @@ -38,12 +45,12 @@ SHELL = /bin/sh # Installation programs... # -INSTALL_BIN = $(LIBTOOL) $(INSTALL) -c -m @CUPS_EXE_FILE_PERM@ @INSTALL_STRIP@ +INSTALL_BIN = @LIBTOOL_INSTALL@ $(INSTALL) -c -m @CUPS_EXE_FILE_PERM@ @INSTALL_STRIP@ INSTALL_COMPDATA = $(INSTALL) -c -m 444 @INSTALL_GZIP@ INSTALL_CONFIG = $(INSTALL) -c -m @CUPS_CONFIG_FILE_PERM@ INSTALL_DATA = $(INSTALL) -c -m 444 INSTALL_DIR = $(INSTALL) -d -INSTALL_LIB = $(LIBTOOL) $(INSTALL) -c -m @CUPS_EXE_FILE_PERM@ @INSTALL_STRIP@ +INSTALL_LIB = @LIBTOOL_INSTALL@ $(INSTALL) -c -m @CUPS_EXE_FILE_PERM@ @INSTALL_STRIP@ INSTALL_MAN = $(INSTALL) -c -m 444 INSTALL_SCRIPT = $(INSTALL) -c -m @CUPS_EXE_FILE_PERM@ @@ -85,14 +92,13 @@ LOCALTARGET = @LOCALTARGET@ # LIBCUPS = @LIBCUPS@ -LIBCUPSCGI = @LIBCUPSCGI@ LIBCUPSIMAGE = @LIBCUPSIMAGE@ -LIBCUPSMIME = @LIBCUPSMIME@ -LIBCUPSPPDC = @LIBCUPSPPDC@ +LIBCUPSOBJS = @LIBCUPSOBJS@ LIBCUPSSTATIC = @LIBCUPSSTATIC@ LIBGSSAPI = @LIBGSSAPI@ +LIBHEADERS = @LIBHEADERS@ +LIBHEADERSPRIV = @LIBHEADERSPRIV@ LIBMALLOC = @LIBMALLOC@ -LIBMXML = @LIBMXML@ LIBPAPER = @LIBPAPER@ LIBUSB = @LIBUSB@ LIBWRAP = @LIBWRAP@ @@ -110,12 +116,27 @@ INSTALLSTATIC = @INSTALLSTATIC@ IPPALIASES = @IPPALIASES@ + +# +# ippeveprinter commands... +# + +IPPEVECOMMANDS = @IPPEVECOMMANDS@ + + # # Install XPC backends? # INSTALLXPC = @INSTALLXPC@ +# +# Code signing... +# + +CODE_SIGN = @CODE_SIGN@ +CODE_SIGN_IDENTITY = - + # # Program options... # @@ -126,10 +147,15 @@ INSTALLXPC = @INSTALLXPC@ # for extra debug info) # -ALL_CFLAGS = -I.. -D_CUPS_SOURCE $(CFLAGS) $(SSLFLAGS) \ - @LARGEFILE@ @PTHREAD_FLAGS@ $(ONDEMANDFLAGS) $(OPTIONS) -ALL_CXXFLAGS = -I.. -D_CUPS_SOURCE $(CXXFLAGS) $(SSLFLAGS) \ - @LARGEFILE@ @PTHREAD_FLAGS@ $(ONDEMANDFLAGS) $(OPTIONS) +ALL_CFLAGS = -I.. -D_CUPS_SOURCE $(CFLAGS) \ + $(SSLFLAGS) @LARGEFILE@ @PTHREAD_FLAGS@ \ + $(ONDEMANDFLAGS) $(OPTIONS) +ALL_CXXFLAGS = -I.. -D_CUPS_SOURCE $(CXXFLAGS) \ + $(SSLFLAGS) @LARGEFILE@ @PTHREAD_FLAGS@ \ + $(ONDEMANDFLAGS) $(OPTIONS) +ALL_DSOFLAGS = -L../cups @ARCHFLAGS@ @RELROFLAGS@ $(DSOFLAGS) $(OPTIM) +ALL_LDFLAGS = -L../cups @LDARCHFLAGS@ @RELROFLAGS@ $(LDFLAGS) \ + @PIEFLAGS@ $(OPTIM) ARCHFLAGS = @ARCHFLAGS@ ARFLAGS = @ARFLAGS@ BACKLIBS = @BACKLIBS@ @@ -141,21 +167,18 @@ CXXLIBS = @CXXLIBS@ DBUS_NOTIFIER = @DBUS_NOTIFIER@ DBUS_NOTIFIERLIBS = @DBUS_NOTIFIERLIBS@ DNSSD_BACKEND = @DNSSD_BACKEND@ -DSOFLAGS = -L../cups @DSOFLAGS@ -DSOLIBS = @DSOLIBS@ $(COMMONLIBS) +DSOFLAGS = @DSOFLAGS@ DNSSDLIBS = @DNSSDLIBS@ IPPFIND_BIN = @IPPFIND_BIN@ IPPFIND_MAN = @IPPFIND_MAN@ -LDFLAGS = -L../cgi-bin -L../cups -L../filter -L../ppdc \ - -L../scheduler @LDARCHFLAGS@ \ - @LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM) -LINKCUPS = @LINKCUPS@ $(LIBGSSAPI) $(DNSSDLIBS) $(SSLLIBS) $(LIBZ) -LINKCUPSIMAGE = @LINKCUPSIMAGE@ -LIBS = $(LINKCUPS) $(COMMONLIBS) +LDFLAGS = @LDFLAGS@ +LINKCUPS = @LINKCUPS@ +LINKCUPSSTATIC = ../cups/$(LIBCUPSSTATIC) $(LIBS) +LIBS = $(LIBGSSAPI) $(DNSSDLIBS) $(SSLLIBS) $(LIBZ) $(COMMONLIBS) ONDEMANDFLAGS = @ONDEMANDFLAGS@ ONDEMANDLIBS = @ONDEMANDLIBS@ OPTIM = @OPTIM@ -OPTIONS = +OPTIONS = @WARNING_OPTIONS@ PAMLIBS = @PAMLIBS@ SERVERLIBS = @SERVERLIBS@ SSLFLAGS = @SSLFLAGS@ @@ -197,9 +220,8 @@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ top_srcdir = @top_srcdir@ -BUILDROOT = $(DSTROOT) +BUILDROOT = $(DSTROOT)$(DESTDIR) -AMANDIR = $(BUILDROOT)@AMANDIR@ BINDIR = $(BUILDROOT)@bindir@ BUNDLEDIR = @CUPS_BUNDLEDIR@ CACHEDIR = $(BUILDROOT)@CUPS_CACHEDIR@ @@ -212,23 +234,17 @@ LOCALEDIR = $(BUILDROOT)@CUPS_LOCALEDIR@ LOGDIR = $(BUILDROOT)@CUPS_LOGDIR@ MANDIR = $(BUILDROOT)@mandir@ MENUDIR = @MENUDIR@ -PMANDIR = $(BUILDROOT)@PMANDIR@ PRIVATEINCLUDE = $(BUILDROOT)@PRIVATEINCLUDE@ RCLEVELS = @RCLEVELS@ RCSTART = @RCSTART@ RCSTOP = @RCSTOP@ REQUESTS = $(BUILDROOT)@CUPS_REQUESTS@ +RESOURCEDIR = @CUPS_RESOURCEDIR@ SBINDIR = $(BUILDROOT)@sbindir@ SERVERBIN = $(BUILDROOT)@CUPS_SERVERBIN@ SERVERROOT = $(BUILDROOT)@CUPS_SERVERROOT@ STATEDIR = $(BUILDROOT)@CUPS_STATEDIR@ -MAN1EXT = @MAN1EXT@ -MAN5EXT = @MAN5EXT@ -MAN7EXT = @MAN7EXT@ -MAN8EXT = @MAN8EXT@ -MAN8DIR = @MAN8DIR@ - PAMDIR = @PAMDIR@ PAMFILE = @PAMFILE@ @@ -248,7 +264,7 @@ USBQUIRKS = @USBQUIRKS@ # .SILENT: -.SUFFIXES: .1 .1.gz .1m .1m.gz .3 .3.gz .5 .5.gz .7 .7.gz .8 .8.gz .a .c .cxx .h .man .o .gz +.SUFFIXES: .a .c .cxx .h .o .c.o: echo Compiling $<... @@ -257,13 +273,3 @@ USBQUIRKS = @USBQUIRKS@ .cxx.o: echo Compiling $<... $(CXX) $(ARCHFLAGS) $(OPTIM) $(ALL_CXXFLAGS) -c -o $@ $< - -.man.1 .man.1m .man.3 .man.5 .man.7 .man.8: - echo Linking $<... - $(RM) $@ - $(LN) $< $@ - -.man.1.gz .man.1m.gz .man.3.gz .man.5.gz .man.7.gz .man.8.gz .man.gz: - echo -n Compressing $<... - $(RM) $@ - gzip -v9 <$< >$@ diff --git a/Makefile b/Makefile index afc90ce..1554462 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,11 @@ # # Top-level Makefile for CUPS. # -# Copyright 2007-2016 by Apple Inc. -# Copyright 1997-2007 by Easy Software Products, all rights reserved. +# Copyright © 2007-2019 by Apple Inc. +# Copyright © 1997-2007 by Easy Software Products, all rights reserved. # -# These coded instructions, statements, and computer programs are the -# property of Apple Inc. and are protected by Federal copyright -# law. Distribution and use rights are outlined in the file "LICENSE.txt" -# which should have been included with this file. If this file is -# missing or damaged, see the license at "http://www.cups.org/". +# Licensed under Apache License v2.0. See the file "LICENSE" for more +# information. # include Makedefs @@ -18,7 +15,14 @@ include Makedefs # Directories to make... # -DIRS = cups test $(BUILDDIRS) +DIRS = cups $(BUILDDIRS) + + +# +# Test suite options - normally blank, override with make command... +# + +TESTOPTIONS = # @@ -98,16 +102,14 @@ distclean: clean $(RM) Makedefs config.h config.log config.status $(RM) conf/cups-files.conf conf/cupsd.conf conf/mime.convs conf/pam.std conf/snmp.conf $(RM) cups-config - $(RM) data/testprint $(RM) desktop/cups.desktop $(RM) doc/index.html - $(RM) man/client.conf.man man/cups-files.conf.man man/cups-lpd.man man/cups-snmp.man man/cupsaddsmb.man man/cupsd.conf.man man/cupsd.man man/lpoptions.man $(RM) packaging/cups.list $(RM) scheduler/cups-lpd.xinetd scheduler/cups.sh scheduler/cups.xml scheduler/org.cups.cups-lpd.plist scheduler/org.cups.cups-lpdAT.service scheduler/org.cups.cupsd.path scheduler/org.cups.cupsd.service scheduler/org.cups.cupsd.socket $(RM) templates/header.tmpl -$(RM) doc/*/index.html -$(RM) templates/*/header.tmpl - -$(RM) -r autom4te*.cache clang cups/charmaps cups/locale + -$(RM) -r autom4te*.cache cups/charmaps cups/locale # @@ -121,25 +123,6 @@ depend: done -# -# Run the Clang static code analysis tool on the sources, available here: -# -# http://clang-analyzer.llvm.org -# -# At least checker-231 is required. -# -# Alternatively, use "--analyze -Xanalyzer -analyzer-output=text" for OPTIM (text -# output instead of HTML...) -# - -.PHONY: clang clang-changes -clang: - $(RM) -r clang - scan-build -V -k -o `pwd`/clang $(MAKE) $(MFLAGS) clean all -clang-changes: - scan-build -V -k -o `pwd`/clang $(MAKE) $(MFLAGS) all - - # # Run the STACK tool on the sources, available here: # @@ -249,7 +232,7 @@ uninstall: test: all unittests echo Running CUPS test suite... - cd test; ./run-stp-tests.sh + cd test; ./run-stp-tests.sh $(TESTOPTIONS) check: all unittests @@ -262,7 +245,7 @@ debugcheck: all unittests # -# Create HTML documentation using Mini-XML's mxmldoc (http://www.msweet.org/)... +# Create HTML documentation using codedoc (http://www.msweet.org/codedoc)... # apihelp: @@ -272,32 +255,6 @@ apihelp: done -# -# Create an Xcode docset using Mini-XML's mxmldoc (http://www.msweet.org/)... -# - -docset: apihelp - echo Generating docset directory tree... - $(RM) -r org.cups.docset - mkdir -p org.cups.docset/Contents/Resources/Documentation/help - mkdir -p org.cups.docset/Contents/Resources/Documentation/images - cd man; $(MAKE) $(MFLAGS) html - cd doc; $(MAKE) $(MFLAGS) docset - cd cgi-bin; $(MAKE) $(MFLAGS) makedocset - cgi-bin/makedocset org.cups.docset \ - `svnversion . | sed -e '1,$$s/[a-zA-Z]//g'` \ - doc/help/api-*.tokens - $(RM) doc/help/api-*.tokens - echo Indexing docset... - /Applications/Xcode.app/Contents/Developer/usr/bin/docsetutil index org.cups.docset - echo Generating docset archive and feed... - $(RM) org.cups.docset.atom - /Applications/Xcode.app/Contents/Developer/usr/bin/docsetutil package --output org.cups.docset.xar \ - --atom org.cups.docset.atom \ - --download-url http://www.cups.org/org.cups.docset.xar \ - org.cups.docset - - # # Lines of code computation... # diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..bf088fd --- /dev/null +++ b/NOTICE @@ -0,0 +1,51 @@ +CUPS + +Copyright © 2007-2019 by Apple Inc. +Copyright © 1997-2007 by Easy Software Products. + +CUPS and the CUPS logo are trademarks of Apple Inc. + +The MD5 Digest code is Copyright 1999 Aladdin Enterprises. + +The Kerberos support code ("KSC") is copyright 2006 by Jelmer Vernooij and is +provided 'as-is', without any express or implied warranty. In no event will the +author or Apple Inc. be held liable for any damages arising from the use of the +KSC. + +Sources files containing KSC have the following text at the top of each source +file: + + This file contains Kerberos support code, copyright 2006 by Jelmer Vernooij. + +The KSC copyright and license apply only to Kerberos-related feature code in +CUPS. Such code is typically conditionally compiled based on the present of the +HAVE_GSSAPI preprocessor definition. + +Permission is granted to anyone to use the KSC for any purpose, including +commercial applications, and to alter it and redistribute it freely, subject to +the following restrictions: + + 1. The origin of the KSC must not be misrepresented; you must not claim that + you wrote the original software. If you use the KSC in a product, an + acknowledgment in the product documentation would be appreciated but is not + required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + +-- CUPS Exceptions to the Apache 2.0 License -- + +As an exception, if, as a result of your compiling your source code, portions +of this Software are embedded into an Object form of such source code, you +may redistribute such embedded portions in such Object form without complying +with the conditions of Sections 4(a), 4(b) and 4(d) of the License. + +In addition, if you combine or link compiled forms of this Software with +software that is licensed under the GPLv2 ("Combined Software") and if a +court of competent jurisdiction determines that the patent provision (Section +3), the indemnity provision (Section 9) or other Section of the License +conflicts with the conditions of the GPLv2, you may retroactively and +prospectively choose to deem waived or otherwise exclude such Section(s) of +the License, but only in their entirety and only with respect to the Combined +Software. diff --git a/README.md b/README.md index 209c9bb..48948d9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ # CUPS-for-Android This project contains code derived from CUPS (see https://github.com/apple/cups) and modified for use as a dynamically-linked library within the Mopria Print Service. -CUPS-for-Android version 1.6.3 is a derivative of CUPS 1.6.3 used in Mopria Print Service 2.1.10 and earlier versions. Later versions of Mopria Print Service use a derivative of CUPS 2.2.1. +CUPS-for-Android version 1.6.3 is a derivative of CUPS 1.6.3 used in Mopria Print Service 2.1.10 and earlier versions. Latest version of Mopria Print Service use a derivative of CUPS 2.3. diff --git a/README.txt b/README.txt index 97672e9..3d3ddb9 100644 --- a/README.txt +++ b/README.txt @@ -1,13 +1,9 @@ -README - CUPS v2.2.4 - 2017-06-30 +README - CUPS v2.3.0 - 2019-08-21 ================================= -Looking for compile instructions? Read the file "INSTALL.md" instead... - - INTRODUCTION ------------ - CUPS is a standards-based, open source printing system developed by Apple Inc. for macOS® and other UNIX®-like operating systems. CUPS uses the Internet Printing Protocol ("IPP") and provides System V and Berkeley command-line @@ -22,20 +18,31 @@ included with CUPS to support many Dymo, EPSON, HP, Intellitech, OKIDATA, and Zebra printers. Many more drivers are available online and (in some cases) on the driver CD-ROM that came with your printer. -CUPS is licensed under the GNU General Public License and GNU Library General -Public License versions 2. See the file "LICENSE.txt" for more information. +CUPS is licensed under the Apache License Version 2.0. See the file +"LICENSE" for more information. READING THE DOCUMENTATION ------------------------- -Once you have installed the software you can access the documentation (and a -bunch of other stuff) online at: +Initial documentation to get you started is provided in the root directory of +the CUPS sources: - http://localhost:631/ +- `CHANGES.md`: A list of changes in the current major release of CUPS. +- `CONTRIBUTING.md`: Guidelines for contributing to the CUPS project. +- `CREDITS.md`: A list of past contributors to the CUPS project. +- `DEVELOPING.md`: Guidelines for developing code for the CUPS project. +- `INSTALL.md`: Instructions for building and installing CUPS. +- `LICENSE`: The CUPS license agreement (Apache 2.0). +- `NOTICE`: Copyright notices and exceptions to the CUPS license agreement. +- `README.md`: This file. + +Once you have installed the software you can access the documentation (and a +bunch of other stuff) online at and using the `man` +command, for example `man cups`. If you're having trouble getting that far, the documentation is located under -the "doc/help" directory. +the `doc/help` and `man` directories. Please read the documentation before asking questions. @@ -43,10 +50,8 @@ Please read the documentation before asking questions. GETTING SUPPORT AND OTHER RESOURCES ----------------------------------- -If you have problems, READ THE DOCUMENTATION FIRST! We also provide two mailing -lists which are available at: - - https://lists.cups.org/mailman/listinfo +If you have problems, *read the documentation first!* We also provide two +mailing lists which are available at . See the CUPS web site at for other resources. @@ -55,14 +60,12 @@ SETTING UP PRINTER QUEUES USING YOUR WEB BROWSER ------------------------------------------------ CUPS includes a web-based administration tool that allows you to manage -printers, classes, and jobs on your server. Open the following URL in your -browser to access the printer administration tools: - - http://localhost:631/admin/ +printers, classes, and jobs on your server. Open +in your browser to access the printer administration tools: *Do not* use the hostname for your machine - it will not work with the default CUPS configuration. To enable administration access on other addresses, check -the "Allow Remote Administration" box and click on the "Change Settings" button. +the `Allow Remote Administration` box and click on the `Change Settings button. You will be asked for the administration password (root or any other user in the sys/system/root/admin/lpadmin group on your system) when performing any @@ -72,63 +75,69 @@ administrative function. SETTING UP PRINTER QUEUES FROM THE COMMAND-LINE ----------------------------------------------- -CUPS works best with PPD (PostScript Printer Description) files. In a pinch you -can also use System V style printer interface scripts. +CUPS currently uses PPD (PostScript Printer Description) files that describe +printer capabilities and driver programs needed for each printer. The +`everywhere` PPD is used for nearly all modern networks printers sold since +about 2009. For example, the following command creates a print queue for a +printer at address 11.22.33.44: -CUPS includes several sample PPD files you can use: + lpadmin -p printername -E -v ipp://11.22.33.44/ipp/print -m everywhere - Driver PPD Name - ----------------------------- ------------------------------ - Dymo Label Printers drv:///sample.drv/dymo.ppd - Intellitech Intellibar drv:///sample.drv/intelbar.ppd - EPSON 9-pin Series drv:///sample.drv/epson9.ppd - EPSON 24-pin Series drv:///sample.drv/epson24.ppd - Generic PCL Laser Printer drv:///sample.drv/generpcl.ppd - Generic PostScript Printer drv:///sample.drv/generic.ppd - HP DeskJet Series drv:///sample.drv/deskjet.ppd - HP LaserJet Series drv:///sample.drv/laserjet.ppd - OKIDATA 9-Pin Series drv:///sample.drv/okidata9.ppd - OKIDATA 24-Pin Series drv:///sample.drv/okidat24.ppd - Zebra CPCL Label Printer drv:///sample.drv/zebracpl.ppd - Zebra EPL1 Label Printer drv:///sample.drv/zebraep1.ppd - Zebra EPL2 Label Printer drv:///sample.drv/zebraep2.ppd - Zebra ZPL Label Printer drv:///sample.drv/zebra.ppd +CUPS also includes several sample PPD files you can use for "legacy" printers: -Run the "lpinfo -m" command to list the available drivers: + Driver | PPD Name + ----------------------------- | ------------------------------ + Dymo Label Printers | drv:///sample.drv/dymo.ppd + Intellitech Intellibar | drv:///sample.drv/intelbar.ppd + EPSON 9-pin Series | drv:///sample.drv/epson9.ppd + EPSON 24-pin Series | drv:///sample.drv/epson24.ppd + Generic PCL Laser Printer | drv:///sample.drv/generpcl.ppd + Generic PostScript Printer | drv:///sample.drv/generic.ppd + HP DeskJet Series | drv:///sample.drv/deskjet.ppd + HP LaserJet Series | drv:///sample.drv/laserjet.ppd + OKIDATA 9-Pin Series | drv:///sample.drv/okidata9.ppd + OKIDATA 24-Pin Series | drv:///sample.drv/okidat24.ppd + Zebra CPCL Label Printer | drv:///sample.drv/zebracpl.ppd + Zebra EPL1 Label Printer | drv:///sample.drv/zebraep1.ppd + Zebra EPL2 Label Printer | drv:///sample.drv/zebraep2.ppd + Zebra ZPL Label Printer | drv:///sample.drv/zebra.ppd + +You can run the `lpinfo -m` command to list all of the available drivers: lpinfo -m -Run the "lpinfo -v" command to list the available printers: +Run the `lpinfo -v` command to list the available printers: lpinfo -v -Then use the correct URI to add the printer using the "lpadmin" command: +Then use the correct URI to add the printer using the `lpadmin` command: lpadmin -p printername -E -v device-uri -m ppd-name -Network printers typically use "socket" or "lpd" URIs: +Current network printers typically use `ipp` or `ipps` URIS: + + lpadmin -p printername -E -v ipp://11.22.33.44/ipp/print -m everywhere + lpadmin -p printername -E -v ipps://11.22.33.44/ipp/print -m everywhere + +Older network printers typically use `socket` or `lpd` URIs: lpadmin -p printername -E -v socket://11.22.33.44 -m ppd-name lpadmin -p printername -E -v lpd://11.22.33.44/ -m ppd-name The sample drivers provide basic printing capabilities, but generally do not -exercise the full potential of the printers or CUPS. - -CUPS also supports IPP Everywhere printers using the "everywhere" model, for -example: - - lpadmin -p printername -E -v ipp://11.22.33.44/ipp/print -m everywhere +exercise the full potential of the printers or CUPS. Other drivers provide +greater printing capabilities. PRINTING FILES -------------- -CUPS provides both the System V "lp" and Berkeley "lpr" commands for printing: +CUPS provides both the System V `lp` and Berkeley `lpr` commands for printing: lp filename lpr filename -Both the "lp" and "lpr" commands support printing options for the driver: +Both the `lp` and `lpr` commands support printing options for the driver: lp -o media=A4 -o resolution=600dpi filename lpr -o media=A4 -o resolution=600dpi filename @@ -137,7 +146,7 @@ CUPS recognizes many types of images files as well as PDF, PostScript, and text files, so you can print those files directly rather than through an application. If you have an application that generates output specifically for your printer -then you need to use the "-oraw" or "-l" options: +then you need to use the `-oraw` or `-l` options: lp -o raw filename lpr -l filename @@ -148,13 +157,14 @@ This will prevent the filters from misinterpreting your print file. LEGAL STUFF ----------- -CUPS is copyright © 2007-2017 by Apple Inc. CUPS and the CUPS logo are -trademarks of Apple Inc. +Copyright © 2007-2019 by Apple Inc. +Copyright © 1997-2007 by Easy Software Products. -The MD5 Digest code is Copyright 1999 Aladdin Enterprises. +CUPS is provided under the terms of the Apache License, Version 2.0 with +exceptions for GPL2/LGPL2 software. A copy of this license can be found in the +file `LICENSE`. Additional legal information is provided in the file `NOTICE`. -CUPS is provided under the terms of version 2 of the GNU General Public License -and GNU Library General Public License. This program is distributed in the hope -that it will be useful, but WITHOUT ANY WARRANTY; without even the implied -warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -"doc/help/license.html" or "LICENSE.txt" files for more information. +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. diff --git a/config.guess b/config.guess new file mode 100644 index 0000000..9afd676 --- /dev/null +++ b/config.guess @@ -0,0 +1,1568 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2013 Free Software Foundation, Inc. + +timestamp='2013-11-29' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# +# Please send patches with a ChangeLog entry to config-patches@gnu.org. + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2013 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + ;; + or1k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.h b/config.h index af9d7bd..7360eaf 100644 --- a/config.h +++ b/config.h @@ -1,17 +1,12 @@ /* config.h. Generated from config.h.in by configure. */ /* - * "$Id: config.h.in 10776 2012-12-17 22:17:08Z mike $" + * Configuration file for CUPS. * - * Configuration file for CUPS. + * Copyright 2007-2019 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* 07/22/2016 Mopria-notice: some config changes were applied directly to this generated file @@ -27,8 +22,8 @@ * Version of software... */ -#define CUPS_SVERSION "CUPS v2.2.3" -#define CUPS_MINIMAL "CUPS/2.2.3" +#define CUPS_SVERSION "CUPS v2.3" +#define CUPS_MINIMAL "CUPS/2.3" /* diff --git a/config.h.in b/config.h.in index f3b5e4c..5e93a9d 100644 --- a/config.h.in +++ b/config.h.in @@ -1,14 +1,11 @@ /* * Configuration file for CUPS. * - * Copyright 2007-2017 by Apple Inc. + * Copyright 2007-2019 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ #ifndef _CUPS_CONFIG_H_ @@ -20,6 +17,7 @@ #define CUPS_SVERSION "" #define CUPS_MINIMAL "" +#define CUPS_LITE 0 /* @@ -303,6 +301,13 @@ #undef HAVE_SSL +/* + * Do we have the gnutls_fips140_set_mode function? + */ + +#undef HAVE_GNUTLS_FIPS140_SET_MODE + + /* * Do we have the gnutls_transport_set_pull_timeout_function function? */ @@ -322,21 +327,9 @@ */ #undef HAVE_AUTHORIZATION_H -#undef HAVE_SECBASEPRIV_H #undef HAVE_SECCERTIFICATE_H -#undef HAVE_SECIDENTITYSEARCHPRIV_H #undef HAVE_SECITEM_H -#undef HAVE_SECITEMPRIV_H #undef HAVE_SECPOLICY_H -#undef HAVE_SECPOLICYPRIV_H -#undef HAVE_SECURETRANSPORTPRIV_H - - -/* - * Do we have the cssmErrorString function? - */ - -#undef HAVE_CSSMERRORSTRING /* @@ -346,20 +339,6 @@ #undef HAVE_SECGENERATESELFSIGNEDCERTIFICATE -/* - * Do we have the SecKeychainOpen function? - */ - -#undef HAVE_SECKEYCHAINOPEN - - -/* - * Do we have (a working) SSLSetEnabledCiphers function? - */ - -#undef HAVE_SSLSETENABLEDCIPHERS - - /* * Do we have libpaper? */ @@ -502,26 +481,10 @@ /* - * Various scripting languages... - */ - -#undef HAVE_JAVA -#define CUPS_JAVA "/usr/bin/java" -#undef HAVE_PERL -#define CUPS_PERL "/usr/bin/perl" -#undef HAVE_PHP -#define CUPS_PHP "/usr/bin/php" -#undef HAVE_PYTHON -#define CUPS_PYTHON "/usr/bin/python" - - -/* - * Do we have CoreFoundation public and private headers? + * Do we have CoreFoundation public headers? */ #undef HAVE_COREFOUNDATION_H -#undef HAVE_CFPRIV_H -#undef HAVE_CFBUNDLEPRIV_H /* @@ -550,7 +513,6 @@ */ #undef HAVE_MEMBERSHIP_H -#undef HAVE_MEMBERSHIPPRIV_H #undef HAVE_MBR_UID_TO_UUID @@ -703,14 +665,6 @@ */ #undef HAVE_XPC -#undef HAVE_XPC_PRIVATE_H - - -/* - * Do we have Mini-XML? - */ - -#undef HAVE_MXML_H /* diff --git a/config.sub b/config.sub new file mode 100644 index 0000000..61cb4bc --- /dev/null +++ b/config.sub @@ -0,0 +1,1793 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2013 Free Software Foundation, Inc. + +timestamp='2013-10-01' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches with a ChangeLog entry to config-patches@gnu.org. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2013 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 \ + | or1k | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or1k-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.sh b/configure similarity index 88% rename from config.sh rename to configure index 494b768..d3df145 100644 --- a/config.sh +++ b/configure @@ -1,6 +1,8 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69. +# Generated by GNU Autoconf 2.69 for CUPS 2.3.0. +# +# Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -264,7 +266,8 @@ fi $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else - $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: https://github.com/apple/cups/issues about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." @@ -575,14 +578,13 @@ MFLAGS= MAKEFLAGS= # Identity of this package. -PACKAGE_NAME= -PACKAGE_TARNAME= -PACKAGE_VERSION= -PACKAGE_STRING= -PACKAGE_BUGREPORT= -PACKAGE_URL= +PACKAGE_NAME='CUPS' +PACKAGE_TARNAME='cups' +PACKAGE_VERSION='2.3.0' +PACKAGE_STRING='CUPS 2.3.0' +PACKAGE_BUGREPORT='https://github.com/apple/cups/issues' +PACKAGE_URL='https://www.cups.org/' -ac_unique_file="cups/cups.h" # Factoring default headers for most tests. ac_includes_default="\ #include @@ -624,11 +626,6 @@ ac_subst_vars='LTLIBOBJS LIBOBJS UNINSTALL_LANGUAGES INSTALL_LANGUAGES -PYTHON -PHP -PHPCGI -PERL -JAVA CUPS_WEBIF DEFAULT_IPP_PORT CUPS_SNMP_COMMUNITY @@ -645,16 +642,30 @@ CUPS_USER CUPS_DEFAULT_SHARED CUPS_BROWSE_LOCAL_PROTOCOLS CUPS_BROWSING +CUPS_PAGE_LOG_FORMAT CUPS_ACCESS_LOG_LEVEL CUPS_LOG_LEVEL CUPS_FATAL_ERRORS CUPS_LOG_FILE_PERM CUPS_CUPSD_FILE_PERM CUPS_CONFIG_FILE_PERM +CUPS_EXE_FILE_PERM +CUPS_RESOURCEDIR CUPS_BUNDLEDIR LANGUAGES -LAUNCHDLIBS -DEFAULT_LAUNCHD_CONF +XINETD +RCSTOP +RCSTART +RCLEVELS +INITDDIR +INITDIR +SMFMANIFESTDIR +SYSTEMD_DIR +LAUNCHD_DIR +ONDEMANDLIBS +ONDEMANDFLAGS +IPPFIND_MAN +IPPFIND_BIN DNSSD_BACKEND DNSSDLIBS LARGEFILE @@ -667,9 +678,7 @@ EXPORT_SSLLIBS SSLLIBS SSLFLAGS IPPALIASES -CUPS_SERVERKEY -CUPS_SERVERCERT -LIBGCRYPTCONFIG +CUPS_SERVERKEYCHAIN LIBGNUTLSCONFIG PTHREAD_FLAGS CUPS_DEFAULT_GSSSERVICENAME @@ -677,6 +686,7 @@ KRB5CONFIG LIBGSSAPI CUPS_LISTEN_DOMAINSOCKET CUPS_DEFAULT_DOMAINSOCKET +WARNING_OPTIONS RELROFLAGS PIEFLAGS CXXLIBS @@ -685,31 +695,22 @@ ARCHFLAGS UNITTESTS OPTIM INSTALL_STRIP +LIBTOOL_INSTALL +LIBTOOL_CXX +LIBTOOL_CC LIBTOOL +LD_CXX +LD_CC EXPORT_LDFLAGS -IMGLIBS -DSOLIBS -LINKCUPSIMAGE LINKCUPS -EXTLINKCUPSIMAGE EXTLINKCUPS LIBCUPSSTATIC -LIBCUPSPPDC -LIBCUPSMIME LIBCUPSIMAGE -LIBCUPSCGI LIBCUPSBASE LIBCUPS DSOFLAGS DSOXX DSO -MAN8DIR -MAN8EXT -MAN7EXT -MAN5EXT -MAN1EXT -PMANDIR -AMANDIR CUPS_STATEDIR CUPS_SERVERROOT INSTALL_SYSV @@ -723,15 +724,12 @@ MENUDIR ICONDIR CUPS_DATADIR CUPS_CACHEDIR -XINETD -SMFMANIFESTDIR -RCSTOP -RCSTART -RCLEVELS -INITDDIR -INITDIR PRIVATEINCLUDE privateinclude +LIBHEADERSPRIV +LIBHEADERS +LIBCUPSOBJS +IPPEVECOMMANDS BUILDDIRS INSTALLXPC CUPS_SYSTEM_AUTHKEY @@ -745,24 +743,25 @@ ARFLAGS LIBZ INSTALL_GZIP LIBWRAP +USBQUIRKS LIBUSB -LIBMXML EGREP GREP LIBPAPER LIBMALLOC PKGCONFIG INSTALLSTATIC -INSTALL CUPS_HTMLVIEW XDGOPEN SED RMDIR RM MV +MKDIR LN LD -GZIP +INSTALL +GZIPPROG CHMOD AR RANLIB @@ -781,6 +780,16 @@ AWK CUPS_BUILD CUPS_REVISION CUPS_VERSION +CODE_SIGN +LOCALTARGET +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build target_alias host_alias build_alias @@ -800,7 +809,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -836,12 +844,6 @@ with_adminkey with_operkey with_components with_privateinclude -with_rcdir -with_rclevels -with_rcstart -with_rcstop -with_smfmanifestdir -with_xinetd with_lpdconfig with_smbconfig with_cachedir @@ -850,6 +852,7 @@ with_menudir with_docdir with_fontpath with_logdir +with_rundir enable_shared enable_libtool_unsupported with_optim @@ -860,6 +863,7 @@ enable_unit_tests with_archflags with_ldarchflags enable_relro +enable_sanitizer with_domainsocket enable_gssapi with_gssservicename @@ -867,9 +871,6 @@ enable_threads enable_ssl enable_cdsassl enable_gnutls -enable_openssl -with_openssl_libs -with_openssl_includes enable_pam with_pam_module enable_largefile @@ -878,14 +879,26 @@ enable_dnssd with_dnssd_libs with_dnssd_includes enable_launchd +enable_systemd +with_systemd +enable_upstart +with_smfmanifestdir +with_rcdir +with_rclevels +with_rcstart +with_rcstop +with_xinetd with_languages with_bundledir +with_bundlelang +with_exe_file_perm with_config_file_perm with_cupsd_file_perm with_log_file_perm with_fatal_errors with_log_level with_access_log_level +enable_page_logging enable_browsing with_local_protocols enable_default_shared @@ -901,10 +914,6 @@ with_snmp_address with_snmp_community with_ipp_port enable_webif -with_java -with_perl -with_php -with_python ' ac_precious_vars='build_alias host_alias @@ -956,10 +965,9 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE}' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' @@ -1209,15 +1217,6 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1355,7 +1354,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1468,7 +1467,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures this package to adapt to many kinds of systems. +\`configure' configures CUPS 2.3.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1508,7 +1507,6 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1517,7 +1515,7 @@ Fine tuning of the installation directories: --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --docdir=DIR documentation root [DATAROOTDIR/doc/cups] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] @@ -1525,11 +1523,17 @@ Fine tuning of the installation directories: _ACEOF cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then - + case $ac_init_help in + short | recursive ) echo "Configuration of CUPS 2.3.0:";; + esac cat <<\_ACEOF Optional Features: @@ -1542,31 +1546,34 @@ Optional Features: --enable-libusb use libusb for USB printing --enable-tcp-wrappers use libwrap for TCP wrappers support --enable-acl build with POSIX ACL support - --enable-dbus build with DBUS support + --disable-dbus build without DBUS support --disable-shared do not create shared libraries - --enable-libtool-unsupported + --enable-libtool-unsupported=/path/to/libtool build with libtool (UNSUPPORTED!) --enable-debug build with debugging symbols --enable-debug-guards build with memory allocation guards --enable-debug-printfs build with CUPS_DEBUG_LOG support --enable-unit-tests build and run unit tests --enable-relro build with the GCC relro option + --enable-sanitizer build with AddressSanitizer --disable-gssapi disable GSSAPI support --disable-threads disable multi-threading support --disable-ssl disable SSL/TLS support --enable-cdsassl use CDSA for SSL/TLS support, default=first --enable-gnutls use GNU TLS for SSL/TLS support, default=second - --enable-openssl use OpenSSL for SSL/TLS support, default=third --disable-pam disable PAM support --disable-largefile omit support for large files --disable-avahi disable DNS Service Discovery support using Avahi --disable-dnssd disable DNS Service Discovery support using mDNSResponder --disable-launchd disable launchd support + --disable-systemd disable systemd support + --enable-upstart enable upstart support + --enable-page-logging enable page_log by default --disable-browsing disable Browsing by default --disable-default-shared disable DefaultShared by default --disable-raw-printing do not allow raw printing by default - --enable-webif enable the web interface by default, default=no for OS X + --enable-webif enable the web interface by default, default=no for macOS Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -1578,13 +1585,9 @@ Optional Packages: --with-components set components to build: - "all" (default) builds everything - "core" builds libcups and ipptool + - "libcups" builds just libcups + - "libcupslite" builds just libcups without driver support --with-privateinclude set path for private include files, default=none - --with-rcdir set path for rc scripts - --with-rclevels set run levels for rc scripts - --with-rcstart set start number for rc scripts - --with-rcstop set stop number for rc scripts - --with-smfmanifestdir set path for Solaris SMF manifest - --with-xinetd set path for xinetd config files --with-lpdconfig set URI for LPD config file --with-smbconfig set URI for Samba config file --with-cachedir set path for cache files @@ -1593,24 +1596,32 @@ Optional Packages: --with-docdir set path for documentation --with-fontpath set font path for pstoraster --with-logdir set path for log files + --with-rundir set transient run-time state directory --with-optim set optimization flags --with-archflags set default architecture flags --with-ldarchflags set program architecture flags --with-domainsocket set unix domain socket name --with-gssservicename set default gss service name - --with-openssl-libs set directory for OpenSSL library - --with-openssl-includes set directory for OpenSSL includes - --with-pam-module specify the PAM module to use + --with-pam-module set the PAM module to use --with-dnssd-libs set directory for DNS Service Discovery library --with-dnssd-includes set directory for DNS Service Discovery includes + --with-systemd set directory for systemd service files + --with-smfmanifestdir set path for Solaris SMF manifest + --with-rcdir set path for rc scripts + --with-rclevels set run levels for rc scripts + --with-rcstart set start number for rc scripts + --with-rcstop set stop number for rc scripts + --with-xinetd set path for xinetd config files --with-languages set installed languages, default=all - --with-bundledir set OS X localization bundle directory + --with-bundledir set localization bundle directory + --with-bundlelang set localization bundle base language (English or en) + --with-exe-file-perm set default executable permissions value, default=0555 --with-config-file-perm set default ConfigFilePerm value, default=0640 --with-cupsd-file-perm set default cupsd permissions, default=0500 --with-log-file-perm set default LogFilePerm value, default=0644 --with-fatal-errors set default FatalErrors value, default=config --with-log-level set default LogLevel value, default=warn - --with-access-log-level set default AccessLogLevel value, default=actions + --with-access-log-level set default AccessLogLevel value, default=none --with-local-protocols set default BrowseLocalProtocols, default="" --with-cups-user set default user for CUPS --with-cups-group set default group for CUPS @@ -1622,10 +1633,6 @@ Optional Packages: --with-snmp-address set SNMP query address, default=auto --with-snmp-community set SNMP community, default=public --with-ipp-port set port number for IPP, default=631 - --with-java set Java interpreter for web interfaces - --with-perl set Perl interpreter for web interfaces - --with-php set PHP interpreter for web interfaces - --with-python set Python interpreter for web interfaces Some influential environment variables: CC C compiler command @@ -1642,7 +1649,8 @@ Some influential environment variables: Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. -Report bugs to the package provider. +Report bugs to . +CUPS home page: . _ACEOF ac_status=$? fi @@ -1705,7 +1713,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -configure +CUPS configure 2.3.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1990,6 +1998,10 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## --------------------------------------------------- ## +## Report this to https://github.com/apple/cups/issues ## +## --------------------------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 @@ -2165,7 +2177,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by $as_me, which was +It was created by CUPS $as_me 2.3.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2515,34 +2527,175 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -uname=`uname` -uversion=`uname -r | sed -e '1,$s/^[^0-9]*\([0-9]*\)\.\([0-9]*\).*/\1\2/'` -uarch=`uname -m` +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi -case "$uname" in - GNU* | GNU/*) - uname="GNU" - ;; - IRIX*) - uname="IRIX" - ;; - Linux*) - uname="Linux" - ;; +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + +host_os_name=`echo $host_os | sed -e '1,$s/[0-9.]*$//g'` +host_os_version=`echo $host_os | sed -e '1,$s/^[^0-9.]*//g' | awk -F. '{print $1 $2}'` +# Linux often does not yield an OS version we can use... +if test "x$host_os_version" = x; then + host_os_version="0" +fi + +if test "$build" = "$host"; then + # No, build local targets + LOCALTARGET="local" +else + # Yes, don't build local targets + LOCALTARGET="" +fi + + +for ac_prog in codesign true +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_CODE_SIGN+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $CODE_SIGN in + [\\/]* | ?:[\\/]*) + ac_cv_path_CODE_SIGN="$CODE_SIGN" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_CODE_SIGN="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +CODE_SIGN=$ac_cv_path_CODE_SIGN +if test -n "$CODE_SIGN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CODE_SIGN" >&5 +$as_echo "$CODE_SIGN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CODE_SIGN" && break +done ac_config_headers="$ac_config_headers config.h" -CUPS_VERSION="1.6.3" +CUPS_VERSION="2.3.0" CUPS_REVISION="" -#if test -z "$CUPS_REVISION" -a -d .svn; then -# CUPS_REVISION="-r`svnversion . | awk -F: '{print $NF}' | sed -e '1,$s/[[a-zA-Z]]*//g'`" -#fi CUPS_BUILD="cups-$CUPS_VERSION" @@ -3778,12 +3931,12 @@ fi set dummy gzip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_GZIP+:} false; then : +if ${ac_cv_path_GZIPPROG+:} false; then : $as_echo_n "(cached) " >&6 else - case $GZIP in + case $GZIPPROG in [\\/]* | ?:[\\/]*) - ac_cv_path_GZIP="$GZIP" # Let the user override the test with a path. + ac_cv_path_GZIPPROG="$GZIPPROG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -3793,7 +3946,7 @@ do test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_GZIP="$as_dir/$ac_word$ac_exec_ext" + ac_cv_path_GZIPPROG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -3804,16 +3957,22 @@ IFS=$as_save_IFS ;; esac fi -GZIP=$ac_cv_path_GZIP -if test -n "$GZIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GZIP" >&5 -$as_echo "$GZIP" >&6; } +GZIPPROG=$ac_cv_path_GZIPPROG +if test -n "$GZIPPROG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GZIPPROG" >&5 +$as_echo "$GZIPPROG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for install-sh script" >&5 +$as_echo_n "checking for install-sh script... " >&6; } +INSTALL="`pwd`/install-sh" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: using $INSTALL" >&5 +$as_echo "using $INSTALL" >&6; } # Extract the first word of "ld", so it can be a program name with args. set dummy ld; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -3894,6 +4053,46 @@ $as_echo "no" >&6; } fi +# Extract the first word of "mkdir", so it can be a program name with args. +set dummy mkdir; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MKDIR+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MKDIR in + [\\/]* | ?:[\\/]*) + ac_cv_path_MKDIR="$MKDIR" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_MKDIR="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +MKDIR=$ac_cv_path_MKDIR +if test -n "$MKDIR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR" >&5 +$as_echo "$MKDIR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + # Extract the first word of "mv", so it can be a program name with args. set dummy mv; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -4094,6 +4293,7 @@ $as_echo "no" >&6; } fi + if test "x$XDGOPEN" = x; then CUPS_HTMLVIEW="htmlview" else @@ -4101,13 +4301,6 @@ else fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for install-sh script" >&5 -$as_echo_n "checking for install-sh script... " >&6; } -INSTALL="`pwd`/install-sh" - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: using $INSTALL" >&5 -$as_echo "using $INSTALL" >&6; } - if test "x$AR" = x; then as_fn_error $? "Unable to find required library archive command." "$LINENO" 5 fi @@ -4129,8 +4322,9 @@ fi -# Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKGCONFIG+:} false; then : @@ -4169,6 +4363,63 @@ $as_echo "no" >&6; } fi +fi +if test -z "$ac_cv_path_PKGCONFIG"; then + ac_pt_PKGCONFIG=$PKGCONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKGCONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKGCONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKGCONFIG="$ac_pt_PKGCONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKGCONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKGCONFIG=$ac_cv_path_ac_pt_PKGCONFIG +if test -n "$ac_pt_PKGCONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKGCONFIG" >&5 +$as_echo "$ac_pt_PKGCONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKGCONFIG" = x; then + PKGCONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKGCONFIG=$ac_pt_PKGCONFIG + fi +else + PKGCONFIG="$ac_cv_path_PKGCONFIG" +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing abs" >&5 @@ -4849,13 +5100,6 @@ if test "x$ac_cv_header_bstring_h" = xyes; then : fi -ac_fn_c_check_header_mongrel "$LINENO" "usersec.h" "ac_cv_header_usersec_h" "$ac_includes_default" -if test "x$ac_cv_header_usersec_h" = xyes; then : - $as_echo "#define HAVE_USERSEC_H 1" >>confdefs.h - -fi - - ac_fn_c_check_header_mongrel "$LINENO" "sys/ioctl.h" "ac_cv_header_sys_ioctl_h" "$ac_includes_default" if test "x$ac_cv_header_sys_ioctl_h" = xyes; then : $as_echo "#define HAVE_SYS_IOCTL_H 1" >>confdefs.h @@ -4877,13 +5121,6 @@ if test "x$ac_cv_header_sys_ucred_h" = xyes; then : fi -ac_fn_c_check_header_mongrel "$LINENO" "scsi/sg.h" "ac_cv_header_scsi_sg_h" "$ac_includes_default" -if test "x$ac_cv_header_scsi_sg_h" = xyes; then : - $as_echo "#define HAVE_SCSI_SG_H 1" >>confdefs.h - -fi - - ac_fn_c_check_header_mongrel "$LINENO" "iconv.h" "ac_cv_header_iconv_h" "$ac_includes_default" if test "x$ac_cv_header_iconv_h" = xyes; then : @@ -4947,18 +5184,9 @@ if test "$ac_res" != no; then : SAVELIBS="$SAVELIBS $LIBS" fi - LIBS="$SAVELIBS" -fi - - - -LIBMXML="" -ac_fn_c_check_header_mongrel "$LINENO" "mxml.h" "ac_cv_header_mxml_h" "$ac_includes_default" -if test "x$ac_cv_header_mxml_h" = xyes; then : - SAVELIBS="$LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing mmxlNewElement" >&5 -$as_echo_n "checking for library containing mmxlNewElement... " >&6; } -if ${ac_cv_search_mmxlNewElement+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing libiconv_open" >&5 +$as_echo_n "checking for library containing libiconv_open... " >&6; } +if ${ac_cv_search_libiconv_open+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS @@ -4971,16 +5199,16 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char mmxlNewElement (); +char libiconv_open (); int main () { -return mmxlNewElement (); +return libiconv_open (); ; return 0; } _ACEOF -for ac_lib in '' mxml; do +for ac_lib in '' iconv; do if test -z "$ac_lib"; then ac_res="none required" else @@ -4988,30 +5216,30 @@ for ac_lib in '' mxml; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_mmxlNewElement=$ac_res + ac_cv_search_libiconv_open=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext - if ${ac_cv_search_mmxlNewElement+:} false; then : + if ${ac_cv_search_libiconv_open+:} false; then : break fi done -if ${ac_cv_search_mmxlNewElement+:} false; then : +if ${ac_cv_search_libiconv_open+:} false; then : else - ac_cv_search_mmxlNewElement=no + ac_cv_search_libiconv_open=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_mmxlNewElement" >&5 -$as_echo "$ac_cv_search_mmxlNewElement" >&6; } -ac_res=$ac_cv_search_mmxlNewElement +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_libiconv_open" >&5 +$as_echo "$ac_cv_search_libiconv_open" >&6; } +ac_res=$ac_cv_search_libiconv_open if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - $as_echo "#define HAVE_MXML_H 1" >>confdefs.h + $as_echo "#define HAVE_ICONV_H 1" >>confdefs.h - LIBMXML="-lmxml" + SAVELIBS="$SAVELIBS $LIBS" fi LIBS="$SAVELIBS" @@ -5019,7 +5247,6 @@ fi - ac_fn_c_check_header_mongrel "$LINENO" "sys/mount.h" "ac_cv_header_sys_mount_h" "$ac_includes_default" if test "x$ac_cv_header_sys_mount_h" = xyes; then : $as_echo "#define HAVE_SYS_MOUNT_H 1" >>confdefs.h @@ -5073,7 +5300,7 @@ _ACEOF fi done -if test "$uname" = "HP-UX" -a "$uversion" = "1020"; then +if test "$host_os_name" = "hp-ux" -a "$host_os_version" = "1020"; then echo Forcing snprintf emulation for HP-UX. else for ac_func in snprintf vsnprintf @@ -5139,8 +5366,8 @@ fi done -case "$uname" in - Linux | GNU) +case "$host_os_name" in + linux* | gnu*) # Do not use sigset on Linux or GNU HURD ;; *) @@ -5184,6 +5411,30 @@ fi done +for ac_func in posix_spawn +do : + ac_fn_c_check_func "$LINENO" "posix_spawn" "ac_cv_func_posix_spawn" +if test "x$ac_cv_func_posix_spawn" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_POSIX_SPAWN 1 +_ACEOF + +fi +done + + +for ac_func in getgrouplist +do : + ac_fn_c_check_func "$LINENO" "getgrouplist" "ac_cv_func_getgrouplist" +if test "x$ac_cv_func_getgrouplist" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GETGROUPLIST 1 +_ACEOF + +fi +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tm_gmtoff member in tm structure" >&5 $as_echo_n "checking for tm_gmtoff member in tm structure... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -5253,10 +5504,12 @@ fi LIBUSB="" +USBQUIRKS="" + if test "x$PKGCONFIG" != x; then - if test x$enable_libusb = xyes -o $uname != Darwin; then + if test x$enable_libusb != xno -a $host_os_name != darwin; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libusb-1.0" >&5 $as_echo_n "checking for libusb-1.0... " >&6; } if $PKGCONFIG --exists libusb-1.0; then @@ -5266,9 +5519,13 @@ $as_echo "yes" >&6; } CFLAGS="$CFLAGS `$PKGCONFIG --cflags libusb-1.0`" LIBUSB="`$PKGCONFIG --libs libusb-1.0`" + USBQUIRKS="\$(DATADIR)/usb" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } + if test x$enable_libusb = xyes; then + as_fn_error $? "libusb required for --enable-libusb." "$LINENO" 5 + fi fi fi elif test x$enable_libusb = xyes; then @@ -5376,11 +5633,53 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzgets" >&5 $as_echo "$ac_cv_lib_z_gzgets" >&6; } if test "x$ac_cv_lib_z_gzgets" = xyes; then : - $as_echo "#define HAVE_LIBZ 1" >>confdefs.h + + $as_echo "#define HAVE_LIBZ 1" >>confdefs.h LIBZ="-lz" LIBS="$LIBS -lz" - if test "x$GZIP" != z; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -lz" >&5 +$as_echo_n "checking for inflateCopy in -lz... " >&6; } +if ${ac_cv_lib_z_inflateCopy+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lz $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char inflateCopy (); +int +main () +{ +return inflateCopy (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_z_inflateCopy=yes +else + ac_cv_lib_z_inflateCopy=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_inflateCopy" >&5 +$as_echo "$ac_cv_lib_z_inflateCopy" >&6; } +if test "x$ac_cv_lib_z_inflateCopy" = xyes; then : + $as_echo "#define HAVE_INFLATECOPY 1" >>confdefs.h + +fi + + if test "x$GZIPPROG" != x; then INSTALL_GZIP="-z" fi fi @@ -5391,8 +5690,8 @@ fi -case $uname in - Darwin* | *BSD*) +case $host_os_name in + darwin* | *bsd*) ARFLAGS="-rcv" ;; *) @@ -5476,12 +5775,6 @@ fi fi LIBS="$SAVELIBS" -if test -d /etc/dbus-1; then - DBUSDIR="/etc/dbus-1" -else - DBUSDIR="" -fi - # Check whether --enable-dbus was given. if test "${enable_dbus+set}" = set; then : enableval=$enable_dbus; @@ -5494,10 +5787,11 @@ if test "${with_dbusdir+set}" = set; then : fi +DBUSDIR="" DBUS_NOTIFIER="" DBUS_NOTIFIERLIBS="" -if test "x$enable_dbus" != xno -a "x$PKGCONFIG" != x; then +if test "x$enable_dbus" != xno -a "x$PKGCONFIG" != x -a "x$host_os_name" != xdarwin; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DBUS" >&5 $as_echo_n "checking for DBUS... " >&6; } if $PKGCONFIG --exists dbus-1; then @@ -5515,9 +5809,18 @@ $as_echo "yes" >&6; } if test "x$ac_cv_func_dbus_message_iter_init_append" = xyes; then : $as_echo "#define HAVE_DBUS_MESSAGE_ITER_INIT_APPEND 1" >>confdefs.h +fi + + ac_fn_c_check_func "$LINENO" "dbus_threads_init" "ac_cv_func_dbus_threads_init" +if test "x$ac_cv_func_dbus_threads_init" = xyes; then : + $as_echo "#define HAVE_DBUS_THREADS_INIT 1" >>confdefs.h + fi LIBS="$SAVELIBS" + if test -d /etc/dbus-1; then + DBUSDIR="/etc/dbus-1" + fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } @@ -5533,11 +5836,11 @@ CUPS_DEFAULT_SYSTEM_AUTHKEY="" CUPS_SYSTEM_AUTHKEY="" INSTALLXPC="" -case $uname in - Darwin*) +case $host_os_name in + darwin*) BACKLIBS="$BACKLIBS -framework IOKit" SERVERLIBS="$SERVERLIBS -framework IOKit -weak_framework ApplicationServices" - LIBS="-framework SystemConfiguration -framework CoreFoundation -framework Security $LIBS" + LIBS="-framework CoreFoundation -framework Security $LIBS" ac_fn_c_check_header_mongrel "$LINENO" "ApplicationServices/ApplicationServices.h" "ac_cv_header_ApplicationServices_ApplicationServices_h" "$ac_includes_default" if test "x$ac_cv_header_ApplicationServices_ApplicationServices_h" = xyes; then : @@ -5553,29 +5856,10 @@ if test "x$ac_cv_header_CoreFoundation_CoreFoundation_h" = xyes; then : fi - ac_fn_c_check_header_mongrel "$LINENO" "CoreFoundation/CFPriv.h" "ac_cv_header_CoreFoundation_CFPriv_h" "$ac_includes_default" -if test "x$ac_cv_header_CoreFoundation_CFPriv_h" = xyes; then : - $as_echo "#define HAVE_CFPRIV_H 1" >>confdefs.h -fi - - - ac_fn_c_check_header_mongrel "$LINENO" "CoreFoundation/CFBundlePriv.h" "ac_cv_header_CoreFoundation_CFBundlePriv_h" "$ac_includes_default" -if test "x$ac_cv_header_CoreFoundation_CFBundlePriv_h" = xyes; then : - $as_echo "#define HAVE_CFBUNDLEPRIV_H 1" >>confdefs.h - -fi - - - ac_fn_c_check_header_mongrel "$LINENO" "IOKit/pwr_mgt/IOPMLibPrivate.h" "ac_cv_header_IOKit_pwr_mgt_IOPMLibPrivate_h" "$ac_includes_default" -if test "x$ac_cv_header_IOKit_pwr_mgt_IOPMLibPrivate_h" = xyes; then : - $as_echo "#define HAVE_IOKIT_PWR_MGT_IOPMLIBPRIVATE_H 1" >>confdefs.h - -fi - - - - for ac_func in SCDynamicStoreCopyComputerName + SAVELIBS="$LIBS" + LIBS="-framework SystemConfiguration $LIBS" + for ac_func in SCDynamicStoreCopyComputerName do : ac_fn_c_check_func "$LINENO" "SCDynamicStoreCopyComputerName" "ac_cv_func_SCDynamicStoreCopyComputerName" if test "x$ac_cv_func_SCDynamicStoreCopyComputerName" = xyes; then : @@ -5583,6 +5867,11 @@ if test "x$ac_cv_func_SCDynamicStoreCopyComputerName" = xyes; then : #define HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME 1 _ACEOF + $as_echo "#define HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME 1" >>confdefs.h + +else + + LIBS="$SAVELIBS" fi done @@ -5594,13 +5883,6 @@ if test "x$ac_cv_header_membership_h" = xyes; then : fi - ac_fn_c_check_header_mongrel "$LINENO" "membershipPriv.h" "ac_cv_header_membershipPriv_h" "$ac_includes_default" -if test "x$ac_cv_header_membershipPriv_h" = xyes; then : - $as_echo "#define HAVE_MEMBERSHIPPRIV_H 1" >>confdefs.h - -fi - - for ac_func in mbr_uid_to_uuid do : ac_fn_c_check_func "$LINENO" "mbr_uid_to_uuid" "ac_cv_func_mbr_uid_to_uuid" @@ -5609,18 +5891,6 @@ if test "x$ac_cv_func_mbr_uid_to_uuid" = xyes; then : #define HAVE_MBR_UID_TO_UUID 1 _ACEOF -fi -done - - - for ac_func in vproc_transaction_begin -do : - ac_fn_c_check_func "$LINENO" "vproc_transaction_begin" "ac_cv_func_vproc_transaction_begin" -if test "x$ac_cv_func_vproc_transaction_begin" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_VPROC_TRANSACTION_BEGIN 1 -_ACEOF - fi done @@ -5678,33 +5948,21 @@ if test "x$ac_cv_header_Security_Authorization_h" = xyes; then : if test "x$default_adminkey" != xdefault; then CUPS_SYSTEM_AUTHKEY="SystemGroupAuthKey $default_adminkey" CUPS_DEFAULT_SYSTEM_AUTHKEY="$default_adminkey" - elif grep -q system.print.operator /etc/authorization; then + else CUPS_SYSTEM_AUTHKEY="SystemGroupAuthKey system.print.admin" CUPS_DEFAULT_SYSTEM_AUTHKEY="system.print.admin" - else - CUPS_SYSTEM_AUTHKEY="SystemGroupAuthKey system.preferences" - CUPS_DEFAULT_SYSTEM_AUTHKEY="system.preferences" fi if test "x$default_operkey" != xdefault; then CUPS_DEFAULT_PRINTOPERATOR_AUTH="@AUTHKEY($default_operkey) @admin @lpadmin" - elif grep -q system.print.operator /etc/authorization; then - CUPS_DEFAULT_PRINTOPERATOR_AUTH="@AUTHKEY(system.print.operator) @admin @lpadmin" else - CUPS_DEFAULT_PRINTOPERATOR_AUTH="@AUTHKEY(system.print.admin) @admin @lpadmin" + CUPS_DEFAULT_PRINTOPERATOR_AUTH="@AUTHKEY(system.print.operator) @admin @lpadmin" fi fi - ac_fn_c_check_header_mongrel "$LINENO" "Security/SecBasePriv.h" "ac_cv_header_Security_SecBasePriv_h" "$ac_includes_default" -if test "x$ac_cv_header_Security_SecBasePriv_h" = xyes; then : - $as_echo "#define HAVE_SECBASEPRIV_H 1" >>confdefs.h -fi - - - - if test $uversion -ge 100; then + if test $host_os_version -ge 100; then ac_fn_c_check_header_mongrel "$LINENO" "sandbox.h" "ac_cv_header_sandbox_h" "$ac_includes_default" if test "x$ac_cv_header_sandbox_h" = xyes; then : $as_echo "#define HAVE_SANDBOX_H 1" >>confdefs.h @@ -5713,7 +5971,7 @@ fi fi - if test $uversion -ge 110 -a $uversion -lt 120; then + if test $host_os_version -ge 110 -a $host_os_version -lt 120; then # Broken public headers in 10.7.x... { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sandbox/private.h presence" >&5 $as_echo_n "checking for sandbox/private.h presence... " >&6; } @@ -5735,13 +5993,6 @@ if test "x$ac_cv_header_xpc_xpc_h" = xyes; then : fi - ac_fn_c_check_header_mongrel "$LINENO" "xpc/private.h" "ac_cv_header_xpc_private_h" "$ac_includes_default" -if test "x$ac_cv_header_xpc_private_h" = xyes; then : - $as_echo "#define HAVE_XPC_PRIVATE_H 1" >>confdefs.h - -fi - - ;; esac @@ -5766,13 +6017,44 @@ if test "${with_components+set}" = set; then : fi +cupsimagebase="cupsimage" +IPPEVECOMMANDS="ippevepcl ippeveps" +LIBCUPSOBJS="\$(COREOBJS) \$(DRIVEROBJS)" +LIBHEADERS="\$(COREHEADERS) \$(DRIVERHEADERS)" +LIBHEADERSPRIV="\$(COREHEADERSPRIV) \$(DRIVERHEADERSPRIV)" + case "$COMPONENTS" in all) - BUILDDIRS="filter backend berkeley cgi-bin monitor notifier ppdc scheduler systemv conf data desktop locale man doc examples templates" + BUILDDIRS="tools filter backend berkeley cgi-bin monitor notifier ppdc scheduler systemv conf data desktop locale man doc examples templates" ;; core) - BUILDDIRS="data locale" + BUILDDIRS="tools examples locale" + ;; + + corelite) + $as_echo "#define CUPS_LITE 1" >>confdefs.h + + BUILDDIRS="tools examples locale" + cupsimagebase="" + LIBCUPSOBJS="\$(COREOBJS)" + LIBHEADERS="\$(COREHEADERS)" + LIBHEADERSPRIV="\$(COREHEADERSPRIV)" + ;; + + libcups) + BUILDDIRS="locale" + cupsimagebase="" + ;; + + libcupslite) + $as_echo "#define CUPS_LITE 1" >>confdefs.h + + BUILDDIRS="locale" + cupsimagebase="" + LIBCUPSOBJS="\$(COREOBJS)" + LIBHEADERS="\$(COREHEADERS)" + LIBHEADERSPRIV="\$(COREHEADERSPRIV)" ;; *) @@ -5786,6 +6068,9 @@ esac + + + if test "$prefix" = "NONE"; then prefix="/" fi @@ -5844,7 +6129,7 @@ fi if test "$localstatedir" = "\${prefix}/var"; then if test "$prefix" = "/"; then - if test "$uname" = Darwin; then + if test "$host_os_name" = darwin; then localstatedir="/private/var" else localstatedir="/var" @@ -5856,7 +6141,7 @@ fi if test "$sysconfdir" = "\${prefix}/etc"; then if test "$prefix" = "/"; then - if test "$uname" = Darwin; then + if test "$host_os_name" = darwin; then sysconfdir="/private/etc" else sysconfdir="/etc" @@ -5867,20 +6152,12 @@ if test "$sysconfdir" = "\${prefix}/etc"; then fi if test "$libdir" = "\${exec_prefix}/lib"; then - case "$uname" in - IRIX*) - libdir="$exec_prefix/lib32" - ;; - Linux*) + case "$host_os_name" in + linux*) if test -d /usr/lib64 -a ! -d /usr/lib64/fakeroot; then libdir="$exec_prefix/lib64" fi ;; - HP-UX*) - if test -d /usr/lib/hpux32; then - libdir="$exec_prefix/lib/hpux32" - fi - ;; esac fi @@ -5902,166 +6179,6 @@ fi -# Check whether --with-rcdir was given. -if test "${with_rcdir+set}" = set; then : - withval=$with_rcdir; rcdir="$withval" -else - rcdir="" -fi - - -# Check whether --with-rclevels was given. -if test "${with_rclevels+set}" = set; then : - withval=$with_rclevels; rclevels="$withval" -else - rclevels="2 3 5" -fi - - -# Check whether --with-rcstart was given. -if test "${with_rcstart+set}" = set; then : - withval=$with_rcstart; rcstart="$withval" -else - rcstart="99" -fi - - -# Check whether --with-rcstop was given. -if test "${with_rcstop+set}" = set; then : - withval=$with_rcstop; rcstop="$withval" -else - rcstop="00" -fi - - -# Check whether --with-smfmanifestdir was given. -if test "${with_smfmanifestdir+set}" = set; then : - withval=$with_smfmanifestdir; smfmanifestdir="$withval" -else - smfmanifestdir="" -fi - - -INITDIR="" -INITDDIR="" -RCLEVELS="$rclevels" -RCSTART="$rcstart" -RCSTOP="$rcstop" -SMFMANIFESTDIR="" - -if test x$rcdir = x; then - case "$uname" in - AIX*) - INITDIR="/etc/rc.d" - ;; - - Darwin*) - # Darwin and MacOS X... - if test -x /sbin/launchd; then - INITDDIR="/System/Library/LaunchDaemons" - else - INITDDIR="/System/Library/StartupItems/PrintingServices" - fi - ;; - - FreeBSD* | OpenBSD* | MirBSD* | ekkoBSD*) - # FreeBSD and OpenBSD - ;; - - HP-UX*) - INITDIR="/sbin" - RCLEVELS="2" - RCSTART="380" - RCSTOP="620" - ;; - - IRIX*) - # IRIX - INITDIR="/etc" - RCSTART="60" - RCSTOP="25" - ;; - - Linux | GNU | GNU/k*BSD*) - # Linux/HURD seems to choose an init.d directory at random... - if test -d /sbin/init.d; then - # SuSE - INITDIR="/sbin/init.d" - else - if test -d /etc/init.d; then - # Others - INITDIR="/etc" - else - # RedHat - INITDIR="/etc/rc.d" - fi - fi - RCSTART="81" - RCSTOP="36" - ;; - - NetBSD*) - # NetBSD - INITDDIR="/etc/rc.d" - ;; - - OSF1*) - INITDIR="/sbin" - ;; - - SunOS*) - # Solaris - if test "x$smfmanifestdir" != x; then - SMFMANIFESTDIR=$smfmanifestdir - else - INITDIR="/etc" - RCSTART="81" - fi - ;; - - *) - INITDIR="/etc" - ;; - - esac -elif test "x$rcdir" != xno; then - if test "x$rclevels" = x; then - INITDDIR="$rcdir" - else - INITDIR="$rcdir" - fi -fi - - - - - - - - - -# Check whether --with-xinetd was given. -if test "${with_xinetd+set}" = set; then : - withval=$with_xinetd; XINETD="$withval" -else - XINETD="" -fi - - -if test "x$XINETD" = x -a ! -x /sbin/launchd; then - for dir in /private/etc/xinetd.d /etc/xinetd.d /usr/local/etc/xinetd.d; do - if test -d $dir; then - XINETD="$dir" - break - fi - done -elif test "x$XINETD" = xno; then - XINETD="" -fi - - - - # Check whether --with-lpdconfig was given. if test "${with_lpdconfig+set}" = set; then : withval=$with_lpdconfig; LPDCONFIG="$withval" @@ -6135,7 +6252,7 @@ fi if test x$cachedir = x; then - if test "x$uname" = xDarwin; then + if test "x$host_os_name" = xdarwin; then CUPS_CACHEDIR="$localstatedir/spool/cups/cache" else CUPS_CACHEDIR="$localstatedir/cache/cups" @@ -6240,15 +6357,11 @@ _ACEOF # Locale data if test "$localedir" = "\${datarootdir}/locale"; then - case "$uname" in - Linux | GNU | *BSD* | Darwin*) + case "$host_os_name" in + linux* | gnu* | *bsd* | darwin*) CUPS_LOCALEDIR="$datarootdir/locale" ;; - OSF1* | AIX*) - CUPS_LOCALEDIR="$exec_prefix/lib/nls/msg" - ;; - *) # This is the standard System V location... CUPS_LOCALEDIR="$exec_prefix/lib/locale" @@ -6298,9 +6411,9 @@ _ACEOF # Server executables... -case "$uname" in - *BSD* | Darwin*) - # *BSD and Darwin (MacOS X) +case "$host_os_name" in + *bsd* | darwin*) + # *BSD and Darwin (macOS) INSTALL_SYSV="" CUPS_SERVERBIN="$exec_prefix/libexec/cups" ;; @@ -6327,16 +6440,24 @@ _ACEOF # Transient run-time state -case "$uname" in - Darwin*) - # Darwin (OS X) - CUPS_STATEDIR="$CUPS_SERVERROOT" - ;; - *) - # All others - CUPS_STATEDIR="$localstatedir/run/cups" - ;; -esac + +# Check whether --with-rundir was given. +if test "${with_rundir+set}" = set; then : + withval=$with_rundir; CUPS_STATEDIR="$withval" +else + + case "$host_os_name" in + darwin*) + # Darwin (macOS) + CUPS_STATEDIR="$CUPS_SERVERROOT" + ;; + *) + # All others + CUPS_STATEDIR="$localstatedir/run/cups" + ;; + esac +fi + cat >>confdefs.h <<_ACEOF #define CUPS_STATEDIR "$CUPS_STATEDIR" _ACEOF @@ -6344,7 +6465,6 @@ _ACEOF - if test "$mandir" = "\${datarootdir}/man" -a "$prefix" = "/"; then # New GNU "standards" break previous ones, so make sure we use # the right default location for the operating system... @@ -6352,78 +6472,20 @@ if test "$mandir" = "\${datarootdir}/man" -a "$prefix" = "/"; then fi if test "$mandir" = "\${prefix}/man" -a "$prefix" = "/"; then - case "$uname" in - Darwin* | Linux | GNU | *BSD* | AIX*) - # Darwin, MacOS X, Linux, GNU HURD, *BSD, and AIX + case "$host_os_name" in + darwin* | linux* | gnu* | *bsd*) + # Darwin, macOS, Linux, GNU HURD, and *BSD mandir="/usr/share/man" - AMANDIR="/usr/share/man" - PMANDIR="/usr/share/man" - ;; - IRIX) - # SGI IRIX - mandir="/usr/share/catman/u_man" - AMANDIR="/usr/share/catman/a_man" - PMANDIR="/usr/share/catman/p_man" ;; *) # All others mandir="/usr/man" - AMANDIR="/usr/man" - PMANDIR="/usr/man" ;; esac -else - AMANDIR="$mandir" - PMANDIR="$mandir" fi - -case "$uname" in - IRIX*) - # SGI IRIX - MAN1EXT=1 - MAN5EXT=5 - MAN7EXT=7 - MAN8EXT=1m - MAN8DIR=1 - ;; - SunOS* | HP-UX*) - # Solaris and HP-UX - MAN1EXT=1 - MAN5EXT=5 - MAN7EXT=7 - MAN8EXT=1m - MAN8DIR=1m - ;; - Linux* | GNU* | Darwin*) - # Linux, GNU Hurd, and OS X - MAN1EXT=1.gz - MAN5EXT=5.gz - MAN7EXT=7.gz - MAN8EXT=8.gz - MAN8DIR=8 - ;; - *) - # All others - MAN1EXT=1 - MAN5EXT=5 - MAN7EXT=7 - MAN8EXT=8 - MAN8DIR=8 - ;; -esac - - - - - - - - - - PICFLAG=1 DSOFLAGS="${DSOFLAGS:=}" @@ -6435,115 +6497,56 @@ fi cupsbase="cups" LIBCUPSBASE="lib$cupsbase" +LIBCUPSIMAGE="" LIBCUPSSTATIC="lib$cupsbase.a" if test x$enable_shared != xno; then - case "$uname" in - SunOS*) + case "$host_os_name" in + sunos*) LIBCUPS="lib$cupsbase.so.2" - LIBCUPSCGI="libcupscgi.so.1" - LIBCUPSIMAGE="libcupsimage.so.2" - LIBCUPSMIME="libcupsmime.so.1" - LIBCUPSPPDC="libcupsppdc.so.1" + if test "x$cupsimagebase" != x; then + LIBCUPSIMAGE="lib$cupsimagebase.so.2" + fi DSO="\$(CC)" DSOXX="\$(CXX)" - DSOFLAGS="$DSOFLAGS -Wl,-h\`basename \$@\` -G \$(OPTIM)" + DSOFLAGS="$DSOFLAGS -Wl,-h\`basename \$@\` -G" ;; - UNIX_S*) + linux* | gnu* | *bsd*) LIBCUPS="lib$cupsbase.so.2" - LIBCUPSCGI="libcupscgi.so.1" - LIBCUPSIMAGE="libcupsimage.so.2" - LIBCUPSMIME="libcupsmime.so.1" - LIBCUPSPPDC="libcupsppdc.so.1" + if test "x$cupsimagebase" != x; then + LIBCUPSIMAGE="lib$cupsimagebase.so.2" + fi DSO="\$(CC)" DSOXX="\$(CXX)" - DSOFLAGS="$DSOFLAGS -Wl,-h,\`basename \$@\` -G \$(OPTIM)" + DSOFLAGS="$DSOFLAGS -Wl,-soname,\`basename \$@\` -shared" ;; - HP-UX*) - case "$uarch" in - ia64) - LIBCUPS="lib$cupsbase.so.2" - LIBCUPSCGI="libcupscgi.so.1" - LIBCUPSIMAGE="libcupsimage.so.2" - LIBCUPSMIME="libcupsmime.so.1" - LIBCUPSPPDC="libcupsppdc.so.1" - DSO="\$(CC)" - DSOXX="\$(CXX)" - DSOFLAGS="$DSOFLAGS -Wl,-b,-z,+h,\`basename \$@\`" - ;; - *) - LIBCUPS="lib$cupsbase.sl.2" - LIBCUPSCGI="libcupscgi.sl.1" - LIBCUPSIMAGE="libcupsimage.sl.2" - LIBCUPSMIME="libcupsmime.sl.1" - LIBCUPSPPDC="libcupsppdc.sl.1" - DSO="\$(LD)" - DSOXX="\$(LD)" - DSOFLAGS="$DSOFLAGS -b -z +h \`basename \$@\`" - ;; - esac - ;; - IRIX) - LIBCUPS="lib$cupsbase.so.2" - LIBCUPSCGI="libcupscgi.so.1" - LIBCUPSIMAGE="libcupsimage.so.2" - LIBCUPSMIME="libcupsmime.so.1" - LIBCUPSPPDC="libcupsppdc.so.1" - DSO="\$(CC)" - DSOXX="\$(CXX)" - DSOFLAGS="$DSOFLAGS -set_version,sgi2.6,-soname,\`basename \$@\` -shared \$(OPTIM)" - ;; - OSF1* | Linux | GNU | *BSD*) - LIBCUPS="lib$cupsbase.so.2" - LIBCUPSCGI="libcupscgi.so.1" - LIBCUPSIMAGE="libcupsimage.so.2" - LIBCUPSMIME="libcupsmime.so.1" - LIBCUPSPPDC="libcupsppdc.so.1" - DSO="\$(CC)" - DSOXX="\$(CXX)" - DSOFLAGS="$DSOFLAGS -Wl,-soname,\`basename \$@\` -shared \$(OPTIM)" - ;; - Darwin*) + darwin*) LIBCUPS="lib$cupsbase.2.dylib" - LIBCUPSCGI="libcupscgi.1.dylib" - LIBCUPSIMAGE="libcupsimage.2.dylib" - LIBCUPSMIME="libcupsmime.1.dylib" - LIBCUPSPPDC="libcupsppdc.1.dylib" + if test "x$cupsimagebase" != x; then + LIBCUPSIMAGE="lib$cupsimagebase.2.dylib" + fi DSO="\$(CC)" DSOXX="\$(CXX)" - DSOFLAGS="$DSOFLAGS -dynamiclib -single_module -lc" - ;; - AIX*) - LIBCUPS="lib${cupsbase}_s.a" - LIBCUPSBASE="${cupsbase}_s" - LIBCUPSCGI="libcupscgi_s.a" - LIBCUPSIMAGE="libcupsimage_s.a" - LIBCUPSMIME="libcupsmime_s.a" - LIBCUPSPPDC="libcupsppdc_s.a" - DSO="\$(CC)" - DSOXX="\$(CXX)" - DSOFLAGS="$DSOFLAGS -Wl,-bexpall,-bM:SRE,-bnoentry,-blibpath:\$(libdir)" + DSOFLAGS="$DSOFLAGS -Wl,-no_warn_inits -dynamiclib -single_module -lc" ;; *) echo "Warning: shared libraries may not be supported. Trying -shared" echo " option with compiler." LIBCUPS="lib$cupsbase.so.2" - LIBCUPSCGI="libcupscgi.so.1" - LIBCUPSIMAGE="libcupsimage.so.2" - LIBCUPSMIME="libcupsmime.so.1" - LIBCUPSPPDC="libcupsppdc.so.1" + if test "x$cupsimagebase" != x; then + LIBCUPSIMAGE="lib$cupsimagebase.so.2" + fi DSO="\$(CC)" DSOXX="\$(CXX)" - DSOFLAGS="$DSOFLAGS -Wl,-soname,\`basename \$@\` -shared \$(OPTIM)" + DSOFLAGS="$DSOFLAGS -Wl,-soname,\`basename \$@\` -shared" ;; esac else PICFLAG=0 LIBCUPS="lib$cupsbase.a" - LIBCUPSCGI="libcupscgi.a" - LIBCUPSIMAGE="libcupsimage.a" - LIBCUPSMIME="libcupsmime.a" - LIBCUPSPPDC="libcupsppdc.a" + if test "x$cupsimagebase" != x; then + LIBCUPSIMAGE="lib$cupsimagebase.a" + fi DSO=":" DSOXX=":" fi @@ -6556,64 +6559,25 @@ fi - - - if test x$enable_shared = xno; then - LINKCUPS="../cups/lib$cupsbase.a" - LINKCUPSIMAGE="../filter/libcupsimage.a" - - EXTLINKCUPS="-lcups" - EXTLINKCUPSIMAGE="-lcupsimage" + LINKCUPS="../cups/lib$cupsbase.a \$(LIBS)" + EXTLINKCUPS="-lcups \$LIBS" else - if test $uname = AIX; then - LINKCUPS="-l${cupsbase}_s" - LINKCUPSIMAGE="-lcupsimage_s" - - EXTLINKCUPS="-lcups_s" - EXTLINKCUPSIMAGE="-lcupsimage_s" - else - LINKCUPS="-l${cupsbase}" - LINKCUPSIMAGE="-lcupsimage" - - EXTLINKCUPS="-lcups" - EXTLINKCUPSIMAGE="-lcupsimage" - fi + LINKCUPS="-L../cups -l${cupsbase}" + EXTLINKCUPS="-lcups" fi - - EXPORT_LDFLAGS="" 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="\$(LIBZ)" - IMGLIBS="" - # Tell the run-time linkers where to find a DSO. Some platforms # need this option, even when the library is installed in a # standard location... - case $uname in - HP-UX*) - # HP-UX needs the path, even for /usr/lib... - case "$uarch" in - ia64) - DSOFLAGS="-Wl,+s,+b,$libdir $DSOFLAGS" - ;; - *) - DSOFLAGS="+s +b $libdir $DSOFLAGS" - ;; - esac - LDFLAGS="$LDFLAGS -Wl,+s,+b,$libdir" - EXPORT_LDFLAGS="-Wl,+s,+b,$libdir" - ;; - SunOS*) + case $host_os_name in + sunos*) # Solaris... if test $exec_prefix != /usr; then DSOFLAGS="-R$libdir $DSOFLAGS" @@ -6621,7 +6585,7 @@ if test "$DSO" != ":"; then EXPORT_LDFLAGS="-R$libdir" fi ;; - *BSD*) + *bsd*) # *BSD... if test $exec_prefix != /usr; then DSOFLAGS="-Wl,-R$libdir $DSOFLAGS" @@ -6629,8 +6593,8 @@ if test "$DSO" != ":"; then EXPORT_LDFLAGS="-Wl,-R$libdir" fi ;; - IRIX | Linux | GNU) - # IRIX, Linux, and HURD... + linux* | gnu*) + # Linux, and HURD... if test $exec_prefix != /usr; then DSOFLAGS="-Wl,-rpath,$libdir $DSOFLAGS" LDFLAGS="$LDFLAGS -Wl,-rpath,$libdir" @@ -6638,20 +6602,17 @@ if test "$DSO" != ":"; then fi ;; esac -else - DSOLIBS="" - IMGLIBS="\$(LIBZ)" fi - - - # Check whether --enable-libtool_unsupported was given. if test "${enable_libtool_unsupported+set}" = set; then : enableval=$enable_libtool_unsupported; if test x$enable_libtool_unsupported != xno; then + if test x$enable_libtool_unsupported == xyes; then + as_fn_error $? "Use --enable-libtool-unsupported=/path/to/libtool." "$LINENO" 5 + fi LIBTOOL="$enable_libtool_unsupported" enable_shared=no echo "WARNING: libtool is not supported or endorsed by Apple Inc." @@ -6662,29 +6623,58 @@ if test "${enable_libtool_unsupported+set}" = set; then : fi - - if test x$LIBTOOL != x; then + DSO="\$(LIBTOOL) --mode=link --tag=CC ${CC}" + DSOXX="\$(LIBTOOL) --mode=link --tag=CXX ${CXX}" + + LD_CC="\$(LIBTOOL) --mode=link --tag=CC ${CC}" + LD_CXX="\$(LIBTOOL) --mode=link --tag=CXX ${CXX}" + LIBCUPS="libcups.la" + LIBCUPSSTATIC="libcups.la" + LIBCUPSCGI="libcupscgi.la" LIBCUPSIMAGE="libcupsimage.la" + LIBCUPSMIME="libcupsmime.la" + LIBCUPSPPDC="libcupsppdc.la" + + LIBTOOL_CC="\$(LIBTOOL) --mode=compile --tag=CC" + LIBTOOL_CXX="\$(LIBTOOL) --mode=compile --tag=CXX" + LIBTOOL_INSTALL="\$(LIBTOOL) --mode=install" + LINKCUPS="../cups/\$(LIBCUPS)" - LINKCUPSIMAGE="../filter/\$(LIBCUPSIMAGE)" - DSO="\$(CC)" + LINKCUPSIMAGE="../cups/\$(LIBCUPSIMAGE)" + +else + LD_CC="\$(CC)" + LD_CXX="\$(CXX)" + + LIBTOOL_CC="" + LIBTOOL_CXX="" + LIBTOOL_INSTALL="" fi -INSTALL_STRIP="" -OPTIM="" + + + +INSTALL_STRIP="" + + + # Check whether --with-optim was given. if test "${with_optim+set}" = set; then : - withval=$with_optim; + withval=$with_optim; OPTIM="$withval" +else + OPTIM="" fi + + # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then : enableval=$enable_debug; @@ -6706,7 +6696,7 @@ if test "${enable_unit_tests+set}" = set; then : fi -if test x$enable_debug = xyes; then +if test x$enable_debug = xyes -a "x$OPTIM" = x; then OPTIM="-g" else INSTALL_STRIP="-s" @@ -6723,6 +6713,10 @@ if test x$enable_debug_guards = xyes; then fi if test x$enable_unit_tests = xyes; then + if test "$build" != "$host"; then + as_fn_error $? "Sorry, cannot build unit tests when cross-compiling." "$LINENO" 5 + fi + UNITTESTS="unittests" else UNITTESTS="" @@ -6749,7 +6743,7 @@ else fi if test -z "$with_ldarchflags"; then - if test "$uname" = Darwin; then + if test "$host_os_name" = darwin; then # Only create Intel programs by default LDARCHFLAGS="`echo $ARCHFLAGS | sed -e '1,$s/-arch ppc64//'`" else @@ -6768,6 +6762,12 @@ if test "${enable_relro+set}" = set; then : fi +# Check whether --enable-sanitizer was given. +if test "${enable_sanitizer+set}" = set; then : + enableval=$enable_sanitizer; +fi + + CXXLIBS="${CXXLIBS:=}" @@ -6777,27 +6777,40 @@ PIEFLAGS="" RELROFLAGS="" +WARNING_OPTIONS="" + + if test -n "$GCC"; then # Add GCC-specific compiler options... + + # Address sanitizer is a useful tool to use when developing/debugging + # code but adds about 2x overhead... + if test x$enable_sanitizer = xyes; then + # Use -fsanitize=address with debugging... + OPTIM="$OPTIM -g -fsanitize=address" + else + # Otherwise use the Fortify enhancements to catch any unbounded + # string operations... + CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2" + CXXFLAGS="$CXXFLAGS -D_FORTIFY_SOURCE=2" + fi + + # Default optimization options... if test -z "$OPTIM"; then - if test "x$with_optim" = x; then - # Default to optimize-for-size and debug - OPTIM="-Os -g" - else - OPTIM="$with_optim $OPTIM" - fi + # Default to optimize-for-size and debug + OPTIM="-Os -g" fi # Generate position-independent code as needed... - if test $PICFLAG = 1 -a $uname != AIX; then + if test $PICFLAG = 1; then OPTIM="-fPIC $OPTIM" fi # The -fstack-protector option is available with some versions of # GCC and adds "stack canaries" which detect when the return address # has been overwritten, preventing many types of exploit attacks. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if GCC supports -fstack-protector" >&5 -$as_echo_n "checking if GCC supports -fstack-protector... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -fstack-protector" >&5 +$as_echo_n "checking whether compiler supports -fstack-protector... " >&6; } OLDCFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fstack-protector" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -6812,7 +6825,12 @@ main () } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - OPTIM="$OPTIM -fstack-protector" + if test "x$LSB_BUILD" = xy; then + # Can't use stack-protector with LSB binaries... + OPTIM="$OPTIM -fno-stack-protector" + else + OPTIM="$OPTIM -fstack-protector" + fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else @@ -6823,14 +6841,19 @@ rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$OLDCFLAGS" - # The -fPIE option is available with some versions of GCC and adds - # randomization of addresses, which avoids another class of exploits - # that depend on a fixed address for common functions. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if GCC supports -fPIE" >&5 -$as_echo_n "checking if GCC supports -fPIE... " >&6; } - OLDCFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -fPIE" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + if test "x$LSB_BUILD" != xy; then + # The -fPIE option is available with some versions of GCC and + # adds randomization of addresses, which avoids another class of + # exploits that depend on a fixed address for common functions. + # + # Not available to LSB binaries... + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -fPIE" >&5 +$as_echo_n "checking whether compiler supports -fPIE... " >&6; } + OLDCFLAGS="$CFLAGS" + case "$host_os_name" in + darwin*) + CFLAGS="$CFLAGS -fPIE -Wl,-pie" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -6842,149 +6865,70 @@ main () } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - case "$CC" in - *clang) - PIEFLAGS="-fPIE -Wl,-pie" + + PIEFLAGS="-fPIE -Wl,-pie" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ;; + *) - PIEFLAGS="-fPIE -pie" + CFLAGS="$CFLAGS -fPIE -pie" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + PIEFLAGS="-fPIE -pie" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ;; esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS="$OLDCFLAGS" - - if test "x$with_optim" = x; then - # Add useful warning options for tracking down problems... - OPTIM="-Wall -Wno-format-y2k -Wunused $OPTIM" - - # Additional warning options for development testing... - if test -d .svn; then - OPTIM="-Wshadow -Werror $OPTIM" - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if GCC supports -Wno-tautological-compare" >&5 -$as_echo_n "checking if GCC supports -Wno-tautological-compare... " >&6; } - OLDCFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Werror -Wno-tautological-compare" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - OPTIM="$OPTIM -Wno-tautological-compare" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS="$OLDCFLAGS" - fi + CFLAGS="$OLDCFLAGS" fi - case "$uname" in - Darwin*) - # -D_FORTIFY_SOURCE=2 adds additional object size - # checking, basically wrapping all string functions - # with buffer-limited ones. Not strictly needed for - # CUPS since we already use buffer-limited calls, but - # this will catch any additions that are broken. - CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2" - ;; + # Add useful warning options for tracking down problems... + WARNING_OPTIONS="-Wall -Wno-format-y2k -Wunused -Wno-unused-result -Wsign-conversion" - Linux*) - # The -z relro option is provided by the Linux linker command to - # make relocatable data read-only. - if test x$enable_relro = xyes; then - RELROFLAGS="-Wl,-z,relro" - fi + # Test GCC version for certain warning flags since -Werror + # doesn't trigger... + gccversion=`$CC --version | head -1 | awk '{print $NF}'` + case "$gccversion" in + 1.* | 2.* | 3.* | 4.* | 5.* | 6.* | \(clang-*) + ;; + *) + WARNING_OPTIONS="$WARNING_OPTIONS -Wno-format-truncation -Wno-format-overflow -Wno-tautological-compare" ;; esac + + # Additional warning options for development testing... + if test -d .git; then + WARNING_OPTIONS="-Werror -Wno-error=deprecated-declarations $WARNING_OPTIONS" + fi else # Add vendor-specific compiler options... - case $uname in - AIX*) - if test -z "$OPTIM"; then - if test "x$with_optim" = x; then - OPTIM="-O2 -qmaxmem=6000" - else - OPTIM="$with_optim $OPTIM" - fi - fi - ;; - HP-UX*) - if test -z "$OPTIM"; then - if test "x$with_optim" = x; then - OPTIM="+O2" - else - OPTIM="$with_optim $OPTIM" - fi - fi - - CFLAGS="-Ae $CFLAGS" - - if test $PICFLAG = 1; then - OPTIM="+z $OPTIM" - fi - ;; - IRIX) - if test -z "$OPTIM"; then - if test "x$with_optim" = x; then - OPTIM="-O2" - else - OPTIM="$with_optim $OPTIM" - fi - fi - - if test "x$with_optim" = x; then - OPTIM="-fullwarn -woff 1183,1209,1349,1506,3201 $OPTIM" - fi - ;; - OSF*) - # Tru64 UNIX aka Digital UNIX aka OSF/1 - if test -z "$OPTIM"; then - if test "x$with_optim" = x; then - OPTIM="-O" - else - OPTIM="$with_optim" - fi - fi - ;; - SunOS*) + case $host_os_name in + sunos*) # Solaris if test -z "$OPTIM"; then - if test "x$with_optim" = x; then - OPTIM="-xO2" - else - OPTIM="$with_optim $OPTIM" - fi - fi - - if test $PICFLAG = 1; then - OPTIM="-KPIC $OPTIM" - fi - ;; - UNIX_SVR*) - # UnixWare - if test -z "$OPTIM"; then - if test "x$with_optim" = x; then - OPTIM="-O" - else - OPTIM="$with_optim $OPTIM" - fi + OPTIM="-xO2" fi if test $PICFLAG = 1; then @@ -6992,50 +6936,41 @@ else 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-bugs@cups.org with uname and compiler options needed" - echo "for your platform, or set the CFLAGS and LDFLAGS environment" - echo "variables before running configure." + # Running some other operating system; inform the user + # they should contribute the necessary options via + # Github... + echo "Building CUPS with default compiler optimizations; contact the CUPS developers on Github" + echo "(https://github.com/apple/cups/issues) with the uname and compiler options needed for" + echo "your platform, or set the CFLAGS and LDFLAGS environment variables before running" + echo "configure." ;; esac fi # Add general compiler options per platform... -case $uname in - HP-UX*) - # HP-UX 10.20 (at least) needs this definition to get the - # h_errno global... - OPTIM="$OPTIM -D_XOPEN_SOURCE_EXTENDED" - - # HP-UX 11.00 (at least) needs this definition to get the - # u_short type used by the IP headers... - OPTIM="$OPTIM -D_INCLUDE_HPUX_SOURCE" - - # HP-UX 11.23 (at least) needs this definition to get the - # IPv6 header to work... - OPTIM="$OPTIM -D_HPUX_SOURCE" - ;; - - Linux*) +case $host_os_name in + linux*) # glibc 2.8 and higher breaks peer credentials unless you # define _GNU_SOURCE... OPTIM="$OPTIM -D_GNU_SOURCE" - ;; - OSF*) - # Tru64 UNIX aka Digital UNIX aka OSF/1 need to be told - # to be POSIX-compliant... - OPTIM="$OPTIM -D_XOPEN_SOURCE=500 -D_XOPEN_SOURCE_EXTENDED -D_OSF_SOURCE" + # The -z relro option is provided by the Linux linker command to + # make relocatable data read-only. + if test x$enable_relro = xyes; then + RELROFLAGS="-Wl,-z,relro,-z,now" + fi ;; esac - -ac_fn_c_check_header_mongrel "$LINENO" "resolv.h" "ac_cv_header_resolv_h" "$ac_includes_default" +ac_fn_c_check_header_compile "$LINENO" "resolv.h" "ac_cv_header_resolv_h" " +#include +#include +#include +#include +#include +" if test "x$ac_cv_header_resolv_h" = xyes; then : $as_echo "#define HAVE_RESOLV_H 1" >>confdefs.h @@ -7501,7 +7436,7 @@ fi # Tru64 5.1b leaks file descriptors with these functions; disable until # we can come up with a test for this... -if test "$uname" != "OSF1"; then +if test "$host_os_name" != "osf1"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing getaddrinfo" >&5 $as_echo_n "checking for library containing getaddrinfo... " >&6; } if ${ac_cv_search_getaddrinfo+:} false; then : @@ -7645,9 +7580,9 @@ fi if test x$enable_domainsocket != xno -a x$default_domainsocket != xno; then if test "x$default_domainsocket" = x; then - case "$uname" in - Darwin*) - # Darwin and MaxOS X do their own thing... + case "$host_os_name" in + darwin*) + # Darwin and macOS do their own thing... CUPS_DEFAULT_DOMAINSOCKET="$localstatedir/run/cupsd" ;; *) @@ -7672,22 +7607,6 @@ fi -for ac_header in AppleTalk/at_proto.h -do : - ac_fn_c_check_header_compile "$LINENO" "AppleTalk/at_proto.h" "ac_cv_header_AppleTalk_at_proto_h" "#include -" -if test "x$ac_cv_header_AppleTalk_at_proto_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_APPLETALK_AT_PROTO_H 1 -_ACEOF - $as_echo "#define HAVE_APPLETALK_AT_PROTO_H 1" >>confdefs.h - -fi - -done - - - ac_fn_c_check_func "$LINENO" "poll" "ac_cv_func_poll" if test "x$ac_cv_func_poll" = xyes; then : @@ -7709,7 +7628,6 @@ fi - # Check whether --enable-gssapi was given. if test "${enable_gssapi+set}" = set; then : enableval=$enable_gssapi; @@ -7720,8 +7638,9 @@ LIBGSSAPI="" if test x$enable_gssapi != xno; then - # Extract the first word of "krb5-config", so it can be a program name with args. -set dummy krb5-config; ac_word=$2 + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}krb5-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}krb5-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_KRB5CONFIG+:} false; then : @@ -7760,10 +7679,67 @@ $as_echo "no" >&6; } fi +fi +if test -z "$ac_cv_path_KRB5CONFIG"; then + ac_pt_KRB5CONFIG=$KRB5CONFIG + # Extract the first word of "krb5-config", so it can be a program name with args. +set dummy krb5-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_KRB5CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_KRB5CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_KRB5CONFIG="$ac_pt_KRB5CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_KRB5CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_KRB5CONFIG=$ac_cv_path_ac_pt_KRB5CONFIG +if test -n "$ac_pt_KRB5CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_KRB5CONFIG" >&5 +$as_echo "$ac_pt_KRB5CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_KRB5CONFIG" = x; then + KRB5CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + KRB5CONFIG=$ac_pt_KRB5CONFIG + fi +else + KRB5CONFIG="$ac_cv_path_KRB5CONFIG" +fi + if test "x$KRB5CONFIG" != x; then - case "$uname" in - Darwin) - # OS X weak-links to the Kerberos framework... + case "$host_os_name" in + darwin) + # macOS weak-links to the Kerberos framework... LIBGSSAPI="-weak_framework Kerberos" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GSS framework" >&5 $as_echo_n "checking for GSS framework... " >&6; } @@ -7776,7 +7752,7 @@ $as_echo "yes" >&6; } $as_echo "no" >&6; } fi ;; - SunOS*) + sunos*) # Solaris has a non-standard krb5-config, don't use it! { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_display_status in -lgss" >&5 $as_echo_n "checking for gss_display_status in -lgss... " >&6; } @@ -7836,8 +7812,8 @@ $as_echo "#define HAVE_GSSAPI 1" >>confdefs.h else # Check for vendor-specific implementations... - case "$uname" in - HP-UX*) + case "$host_os_name" in + hp-ux*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_display_status in -lgss" >&5 $as_echo_n "checking for gss_display_status in -lgss... " >&6; } if ${ac_cv_lib_gss_gss_display_status+:} false; then : @@ -7882,7 +7858,7 @@ $as_echo "#define HAVE_GSSAPI 1" >>confdefs.h fi ;; - SunOS*) + sunos*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_display_status in -lgss" >&5 $as_echo_n "checking for gss_display_status in -lgss... " >&6; } if ${ac_cv_lib_gss_gss_display_status+:} false; then : @@ -7939,53 +7915,27 @@ fi if test -d /System/Library/Frameworks/GSS.framework; then - gssdir="/System/Library/Frameworks/GSS.framework" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GSS/gssapi.h presence" >&5 -$as_echo_n "checking for GSS/gssapi.h presence... " >&6; } - if test -f $gssdir/Headers/gssapi.h; then - $as_echo "#define HAVE_GSS_GSSAPI_H 1" >>confdefs.h + ac_fn_c_check_header_mongrel "$LINENO" "GSS/gssapi.h" "ac_cv_header_GSS_gssapi_h" "$ac_includes_default" +if test "x$ac_cv_header_GSS_gssapi_h" = xyes; then : + $as_echo "#define HAVE_GSS_GSSAPI_H 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GSS/gssapi_generic.h presence" >&5 -$as_echo_n "checking for GSS/gssapi_generic.h presence... " >&6; } - if test -f $gssdir/Headers/gssapi_generic.h; then - $as_echo "#define HAVE_GSSAPI_GENERIC_H 1" >>confdefs.h +fi + + + ac_fn_c_check_header_mongrel "$LINENO" "GSS/gssapi_generic.h" "ac_cv_header_GSS_gssapi_generic_h" "$ac_includes_default" +if test "x$ac_cv_header_GSS_gssapi_generic_h" = xyes; then : + $as_echo "#define HAVE_GSS_GSSAPI_GENERIC_H 1" >>confdefs.h + +fi + + + ac_fn_c_check_header_mongrel "$LINENO" "GSS/gssapi_spi.h" "ac_cv_header_GSS_gssapi_spi_h" "$ac_includes_default" +if test "x$ac_cv_header_GSS_gssapi_spi_h" = xyes; then : + $as_echo "#define HAVE_GSS_GSSAPI_SPI_H 1" >>confdefs.h + +fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GSS/gssapi_spi.h presence" >&5 -$as_echo_n "checking for GSS/gssapi_spi.h presence... " >&6; } - if test -f $gssdir/PrivateHeaders/gssapi_spi.h; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GSS/gssapi_spi.h usability" >&5 -$as_echo_n "checking for GSS/gssapi_spi.h usability... " >&6; } - if test -s $gssdir/PrivateHeaders/gssapi_spi.h; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - $as_echo "#define HAVE_GSS_GSSAPI_SPI_H 1" >>confdefs.h - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - if test $uversion -ge 110 -a $uversion -lt 120; then - # Broken public headers in 10.7.x... - as_fn_error $? "Run 'sudo mkdir -p $gssdir/PrivateHeaders' and 'sudo touch $gssdir/PrivateHeaders/gssapi_spi.h' to build CUPS." "$LINENO" 5 - fi - fi else ac_fn_c_check_header_mongrel "$LINENO" "gssapi.h" "ac_cv_header_gssapi_h" "$ac_includes_default" if test "x$ac_cv_header_gssapi_h" = xyes; then : @@ -8113,7 +8063,6 @@ _ACEOF - # Check whether --enable-threads was given. if test "${enable_threads+set}" = set; then : enableval=$enable_threads; @@ -8164,7 +8113,7 @@ $as_echo "$have_pthread" >&6; } # Solaris requires -D_POSIX_PTHREAD_SEMANTICS to # be POSIX-compliant... :( - if test $uname = SunOS; then + if test $host_os_name = sunos; then PTHREAD_FLAGS="$PTHREAD_FLAGS -D_POSIX_PTHREAD_SEMANTICS" fi break @@ -8176,7 +8125,6 @@ fi - # Check whether --enable-ssl was given. if test "${enable_ssl+set}" = set; then : enableval=$enable_ssl; @@ -8192,35 +8140,15 @@ if test "${enable_gnutls+set}" = set; then : enableval=$enable_gnutls; fi -# Check whether --enable-openssl was given. -if test "${enable_openssl+set}" = set; then : - enableval=$enable_openssl; -fi - - -# Check whether --with-openssl-libs was given. -if test "${with_openssl_libs+set}" = set; then : - withval=$with_openssl_libs; LDFLAGS="-L$withval $LDFLAGS" - DSOFLAGS="-L$withval $DSOFLAGS" -fi - - -# Check whether --with-openssl-includes was given. -if test "${with_openssl_includes+set}" = set; then : - withval=$with_openssl_includes; CFLAGS="-I$withval $CFLAGS" - CPPFLAGS="-I$withval $CPPFLAGS" -fi - SSLFLAGS="" SSLLIBS="" have_ssl=0 -CUPS_SERVERCERT="" -CUPS_SERVERKEY="" +CUPS_SERVERKEYCHAIN="" if test x$enable_ssl != xno; then if test $have_ssl = 0 -a "x$enable_cdsassl" != "xno"; then - if test $uname = Darwin; then + if test $host_os_name = darwin; then ac_fn_c_check_header_mongrel "$LINENO" "Security/SecureTransport.h" "ac_cv_header_Security_SecureTransport_h" "$ac_includes_default" if test "x$ac_cv_header_Security_SecureTransport_h" = xyes; then : @@ -8229,16 +8157,9 @@ if test "x$ac_cv_header_Security_SecureTransport_h" = xyes; then : $as_echo "#define HAVE_CDSASSL 1" >>confdefs.h - CUPS_SERVERCERT="/Library/Keychains/System.keychain" + CUPS_SERVERKEYCHAIN="/Library/Keychains/System.keychain" - ac_fn_c_check_header_mongrel "$LINENO" "Security/SecureTransportPriv.h" "ac_cv_header_Security_SecureTransportPriv_h" "$ac_includes_default" -if test "x$ac_cv_header_Security_SecureTransportPriv_h" = xyes; then : - $as_echo "#define HAVE_SECURETRANSPORTPRIV_H 1" >>confdefs.h - -fi - - - ac_fn_c_check_header_mongrel "$LINENO" "Security/SecCertificate.h" "ac_cv_header_Security_SecCertificate_h" "$ac_includes_default" + ac_fn_c_check_header_mongrel "$LINENO" "Security/SecCertificate.h" "ac_cv_header_Security_SecCertificate_h" "$ac_includes_default" if test "x$ac_cv_header_Security_SecCertificate_h" = xyes; then : $as_echo "#define HAVE_SECCERTIFICATE_H 1" >>confdefs.h @@ -8252,14 +8173,6 @@ if test "x$ac_cv_header_Security_SecItem_h" = xyes; then : fi - ac_fn_c_check_header_compile "$LINENO" "Security/SecItemPriv.h" "ac_cv_header_Security_SecItemPriv_h" "#include -" -if test "x$ac_cv_header_Security_SecItemPriv_h" = xyes; then : - $as_echo "#define HAVE_SECITEMPRIV_H 1" >>confdefs.h - -fi - - ac_fn_c_check_header_mongrel "$LINENO" "Security/SecPolicy.h" "ac_cv_header_Security_SecPolicy_h" "$ac_includes_default" if test "x$ac_cv_header_Security_SecPolicy_h" = xyes; then : $as_echo "#define HAVE_SECPOLICY_H 1" >>confdefs.h @@ -8267,75 +8180,16 @@ if test "x$ac_cv_header_Security_SecPolicy_h" = xyes; then : fi - ac_fn_c_check_header_mongrel "$LINENO" "Security/SecPolicyPriv.h" "ac_cv_header_Security_SecPolicyPriv_h" "$ac_includes_default" -if test "x$ac_cv_header_Security_SecPolicyPriv_h" = xyes; then : - $as_echo "#define HAVE_SECPOLICYPRIV_H 1" >>confdefs.h - fi - ac_fn_c_check_header_mongrel "$LINENO" "Security/SecBasePriv.h" "ac_cv_header_Security_SecBasePriv_h" "$ac_includes_default" -if test "x$ac_cv_header_Security_SecBasePriv_h" = xyes; then : - $as_echo "#define HAVE_SECBASEPRIV_H 1" >>confdefs.h - -fi - - - ac_fn_c_check_header_mongrel "$LINENO" "Security/SecIdentitySearchPriv.h" "ac_cv_header_Security_SecIdentitySearchPriv_h" "$ac_includes_default" -if test "x$ac_cv_header_Security_SecIdentitySearchPriv_h" = xyes; then : - $as_echo "#define HAVE_SECIDENTITYSEARCHPRIV_H 1" >>confdefs.h - -fi - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SecCertificateCopyData" >&5 -$as_echo_n "checking for SecCertificateCopyData... " >&6; } - if test $uversion -ge 100; then - $as_echo "#define HAVE_SECCERTIFICATECOPYDATA 1" >>confdefs.h - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SecIdentitySearchCreateWithPolicy" >&5 -$as_echo_n "checking for SecIdentitySearchCreateWithPolicy... " >&6; } - if test $uversion -ge 80; then - $as_echo "#define HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY 1" >>confdefs.h - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SecPolicyCreateSSL" >&5 -$as_echo_n "checking for SecPolicyCreateSSL... " >&6; } - if test $uversion -ge 110; then - $as_echo "#define HAVE_SECPOLICYCREATESSL 1" >>confdefs.h - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi -fi - - - - $as_echo "#define HAVE_CSSMERRORSTRING 1" >>confdefs.h - fi fi if test $have_ssl = 0 -a "x$enable_gnutls" != "xno" -a "x$PKGCONFIG" != x; then - # Extract the first word of "libgnutls-config", so it can be a program name with args. -set dummy libgnutls-config; ac_word=$2 + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}libgnutls-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}libgnutls-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_LIBGNUTLSCONFIG+:} false; then : @@ -8374,16 +8228,19 @@ $as_echo "no" >&6; } fi - # Extract the first word of "libgcrypt-config", so it can be a program name with args. -set dummy libgcrypt-config; ac_word=$2 +fi +if test -z "$ac_cv_path_LIBGNUTLSCONFIG"; then + ac_pt_LIBGNUTLSCONFIG=$LIBGNUTLSCONFIG + # Extract the first word of "libgnutls-config", so it can be a program name with args. +set dummy libgnutls-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LIBGCRYPTCONFIG+:} false; then : +if ${ac_cv_path_ac_pt_LIBGNUTLSCONFIG+:} false; then : $as_echo_n "(cached) " >&6 else - case $LIBGCRYPTCONFIG in + case $ac_pt_LIBGNUTLSCONFIG in [\\/]* | ?:[\\/]*) - ac_cv_path_LIBGCRYPTCONFIG="$LIBGCRYPTCONFIG" # Let the user override the test with a path. + ac_cv_path_ac_pt_LIBGNUTLSCONFIG="$ac_pt_LIBGNUTLSCONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -8393,7 +8250,7 @@ do test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_LIBGCRYPTCONFIG="$as_dir/$ac_word$ac_exec_ext" + ac_cv_path_ac_pt_LIBGNUTLSCONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -8404,15 +8261,29 @@ IFS=$as_save_IFS ;; esac fi -LIBGCRYPTCONFIG=$ac_cv_path_LIBGCRYPTCONFIG -if test -n "$LIBGCRYPTCONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBGCRYPTCONFIG" >&5 -$as_echo "$LIBGCRYPTCONFIG" >&6; } +ac_pt_LIBGNUTLSCONFIG=$ac_cv_path_ac_pt_LIBGNUTLSCONFIG +if test -n "$ac_pt_LIBGNUTLSCONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_LIBGNUTLSCONFIG" >&5 +$as_echo "$ac_pt_LIBGNUTLSCONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi + if test "x$ac_pt_LIBGNUTLSCONFIG" = x; then + LIBGNUTLSCONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIBGNUTLSCONFIG=$ac_pt_LIBGNUTLSCONFIG + fi +else + LIBGNUTLSCONFIG="$ac_cv_path_LIBGNUTLSCONFIG" +fi if $PKGCONFIG --exists gnutls; then have_ssl=1 @@ -8433,105 +8304,30 @@ fi fi if test $have_ssl = 1; then - CUPS_SERVERCERT="ssl/server.crt" - CUPS_SERVERKEY="ssl/server.key" + CUPS_SERVERKEYCHAIN="ssl" - if $PKGCONFIG --exists gcrypt; then - SSLLIBS="$SSLLIBS `$PKGCONFIG --libs gcrypt`" - SSLFLAGS="$SSLFLAGS `$PKGCONFIG --cflags gcrypt`" - elif test "x$LIBGCRYPTCONFIG" != x; then - SSLLIBS="$SSLLIBS `$LIBGCRYPTCONFIG --libs`" - SSLFLAGS="$SSLFLAGS `$LIBGCRYPTCONFIG --cflags`" - fi - fi - fi - - if test $have_ssl = 0 -a "x$enable_openssl" != "xno"; then - ac_fn_c_check_header_mongrel "$LINENO" "openssl/ssl.h" "ac_cv_header_openssl_ssl_h" "$ac_includes_default" -if test "x$ac_cv_header_openssl_ssl_h" = xyes; then : - - SAVELIBS="$LIBS" - - - for libcrypto in \ - "-lcrypto" \ - "-lcrypto -lrsaref" \ - "-lcrypto -lRSAglue -lrsaref" - do - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_new in -lssl" >&5 -$as_echo_n "checking for SSL_new in -lssl... " >&6; } -if ${ac_cv_lib_ssl_SSL_new+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lssl $libcrypto $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char SSL_new (); -int -main () -{ -return SSL_new (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ssl_SSL_new=yes -else - ac_cv_lib_ssl_SSL_new=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_new" >&5 -$as_echo "$ac_cv_lib_ssl_SSL_new" >&6; } -if test "x$ac_cv_lib_ssl_SSL_new" = xyes; then : - have_ssl=1 - SSLFLAGS="-DOPENSSL_DISABLE_OLD_DES_SUPPORT" - SSLLIBS="-lssl $libcrypto" - $as_echo "#define HAVE_SSL 1" >>confdefs.h - - $as_echo "#define HAVE_LIBSSL 1" >>confdefs.h + SAVELIBS="$LIBS" + LIBS="$LIBS $SSLLIBS" + ac_fn_c_check_func "$LINENO" "gnutls_fips140_set_mode" "ac_cv_func_gnutls_fips140_set_mode" +if test "x$ac_cv_func_gnutls_fips140_set_mode" = xyes; then : + $as_echo "#define HAVE_GNUTLS_FIPS140_SET_MODE 1" >>confdefs.h fi - - if test "x${SSLLIBS}" != "x"; then - break - fi - done - - if test "x${SSLLIBS}" != "x"; then - CUPS_SERVERCERT="ssl/server.crt" - CUPS_SERVERKEY="ssl/server.key" - - LIBS="$SAVELIBS $SSLLIBS" - for ac_func in SSL_set_tlsext_host_name -do : - ac_fn_c_check_func "$LINENO" "SSL_set_tlsext_host_name" "ac_cv_func_SSL_set_tlsext_host_name" -if test "x$ac_cv_func_SSL_set_tlsext_host_name" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SSL_SET_TLSEXT_HOST_NAME 1 -_ACEOF + ac_fn_c_check_func "$LINENO" "gnutls_transport_set_pull_timeout_function" "ac_cv_func_gnutls_transport_set_pull_timeout_function" +if test "x$ac_cv_func_gnutls_transport_set_pull_timeout_function" = xyes; then : + $as_echo "#define HAVE_GNUTLS_TRANSPORT_SET_PULL_TIMEOUT_FUNCTION 1" >>confdefs.h fi -done - fi + ac_fn_c_check_func "$LINENO" "gnutls_priority_set_direct" "ac_cv_func_gnutls_priority_set_direct" +if test "x$ac_cv_func_gnutls_priority_set_direct" = xyes; then : + $as_echo "#define HAVE_GNUTLS_PRIORITY_SET_DIRECT 1" >>confdefs.h + +fi LIBS="$SAVELIBS" -fi - - + fi fi fi @@ -8542,7 +8338,7 @@ $as_echo " Using SSLLIBS=\"$SSLLIBS\"" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using SSLFLAGS=\"$SSLFLAGS\"" >&5 $as_echo " Using SSLFLAGS=\"$SSLFLAGS\"" >&6; } IPPALIASES="http https ipps" -elif test x$enable_cdsa = xyes -o x$enable_gnutls = xyes -o x$enable_openssl = xyes; then +elif test x$enable_cdsa = xyes -o x$enable_gnutls = xyes; then as_fn_error $? "Unable to enable SSL support." "$LINENO" 5 fi @@ -8551,12 +8347,10 @@ fi - EXPORT_SSLLIBS="$SSLLIBS" - # Check whether --enable-pam was given. if test "${enable_pam+set}" = set; then : enableval=$enable_pam; @@ -8569,10 +8363,6 @@ if test "${with_pam_module+set}" = set; then : fi -if test $uname = AIX; then - enable_pam=no -fi - PAMDIR="" PAMFILE="pam.std" PAMLIBS="" @@ -8789,9 +8579,9 @@ fi LIBS="$SAVELIBS" - case "$uname" in - Darwin*) - # Darwin/OS X + case "$host_os_name" in + darwin*) + # Darwin/macOS if test "x$with_pam_module" != x; then PAMFILE="pam.$with_pam_module" elif test -f /usr/lib/pam/pam_opendirectory.so.2; then @@ -8806,10 +8596,22 @@ fi # as Linux distributors move things around... if test "x$with_pam_module" != x; then PAMMOD="pam_${with_pam_module}.so" - elif test -f /lib/security/pam_unix2.so; then - PAMMOD="pam_unix2.so" - elif test -f /lib/security/pam_unix.so; then - PAMMOD="pam_unix.so" + elif test -f /etc/pam.d/common-auth; then + PAMFILE="pam.common" + else + moddir="" + for dir in /lib/security /lib64/security /lib/x86_64-linux-gnu/security /var/lib/pam; do + if test -d $dir; then + moddir=$dir + break; + fi + done + + if test -f $moddir/pam_unix2.so; then + PAMMOD="pam_unix2.so" + elif test -f $moddir/pam_unix.so; then + PAMMOD="pam_unix.so" + fi fi if test "x$PAMMOD" = xpam_unix.so; then @@ -8828,7 +8630,6 @@ fi - # Check whether --enable-largefile was given. if test "${enable_largefile+set}" = set; then : enableval=$enable_largefile; @@ -8854,7 +8655,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -8900,7 +8701,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -8924,7 +8725,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -8969,7 +8770,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -8993,7 +8794,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -9087,7 +8888,6 @@ fi - # Check whether --enable-avahi was given. if test "${enable_avahi+set}" = set; then : enableval=$enable_avahi; @@ -9115,8 +8915,10 @@ fi DNSSDLIBS="" DNSSD_BACKEND="" +IPPFIND_BIN="" +IPPFIND_MAN="" -if test "x$PKGCONFIG" != x -a x$enable_avahi != xno; then +if test "x$PKGCONFIG" != x -a x$enable_avahi != xno -a x$host_os_name != xdarwin; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Avahi" >&5 $as_echo_n "checking for Avahi... " >&6; } if $PKGCONFIG --exists avahi-client; then @@ -9125,6 +8927,8 @@ $as_echo "yes" >&6; } CFLAGS="$CFLAGS `$PKGCONFIG --cflags avahi-client`" DNSSDLIBS="`$PKGCONFIG --libs avahi-client`" DNSSD_BACKEND="dnssd" + IPPFIND_BIN="ippfind" + IPPFIND_MAN="ippfind.1" $as_echo "#define HAVE_AVAHI 1" >>confdefs.h else @@ -9137,13 +8941,14 @@ if test "x$DNSSD_BACKEND" = x -a x$enable_dnssd != xno; then ac_fn_c_check_header_mongrel "$LINENO" "dns_sd.h" "ac_cv_header_dns_sd_h" "$ac_includes_default" if test "x$ac_cv_header_dns_sd_h" = xyes; then : - case "$uname" in - Darwin*) - # Darwin and MacOS X... + case "$host_os_name" in + darwin*) + # Darwin and macOS... $as_echo "#define HAVE_DNSSD 1" >>confdefs.h - DNSSDLIBS="-framework CoreFoundation -framework SystemConfiguration" DNSSD_BACKEND="dnssd" + IPPFIND_BIN="ippfind" + IPPFIND_MAN="ippfind.1" ;; *) # All others... @@ -9174,7 +8979,9 @@ $as_echo "yes" >&6; } DNSSDLIBS="-ldns_sd" DNSSD_BACKEND="dnssd" else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + IPPFIND_BIN="ippfind" + IPPFIND_MAN="ippfind.1" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext @@ -9193,19 +9000,26 @@ fi +ONDEMANDFLAGS="" +ONDEMANDLIBS="" + + + # Check whether --enable-launchd was given. if test "${enable_launchd+set}" = set; then : enableval=$enable_launchd; fi +LAUNCHD_DIR="" -DEFAULT_LAUNCHD_CONF="" -LAUNCHDLIBS="" if test x$enable_launchd != xno; then - ac_fn_c_check_func "$LINENO" "launch_msg" "ac_cv_func_launch_msg" -if test "x$ac_cv_func_launch_msg" = xyes; then : - $as_echo "#define HAVE_LAUNCHD 1" >>confdefs.h + ac_fn_c_check_func "$LINENO" "launch_activate_socket" "ac_cv_func_launch_activate_socket" +if test "x$ac_cv_func_launch_activate_socket" = xyes; then : + + $as_echo "#define HAVE_LAUNCHD 1" >>confdefs.h + + $as_echo "#define HAVE_ONDEMAND 1" >>confdefs.h fi @@ -9217,21 +9031,227 @@ fi - case "$uname" in - Darwin*) - # Darwin, MacOS X - DEFAULT_LAUNCHD_CONF="/System/Library/LaunchDaemons/org.cups.cupsd.plist" - # liblaunch is already part of libSystem - ;; - *) - # All others; this test will need to be updated - ;; - esac + if test "$host_os_name" = darwin; then + LAUNCHD_DIR="/System/Library/LaunchDaemons" + # liblaunch is already part of libSystem + fi +fi + +# Check whether --enable-systemd was given. +if test "${enable_systemd+set}" = set; then : + enableval=$enable_systemd; +fi + + +# Check whether --with-systemd was given. +if test "${with_systemd+set}" = set; then : + withval=$with_systemd; SYSTEMD_DIR="$withval" +else + SYSTEMD_DIR="" fi +if test x$enable_systemd != xno; then + if test "x$PKGCONFIG" = x; then + if test x$enable_systemd = xyes; then + as_fn_error $? "Need pkg-config to enable systemd support." "$LINENO" 5 + fi + else + have_systemd=no + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libsystemd" >&5 +$as_echo_n "checking for libsystemd... " >&6; } + if $PKGCONFIG --exists libsystemd; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + have_systemd=yes + ONDEMANDFLAGS=`$PKGCONFIG --cflags libsystemd` + ONDEMANDLIBS=`$PKGCONFIG --libs libsystemd` + elif $PKGCONFIG --exists libsystemd-daemon; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes - legacy" >&5 +$as_echo "yes - legacy" >&6; } + have_systemd=yes + ONDEMANDFLAGS=`$PKGCONFIG --cflags libsystemd-daemon` + ONDEMANDLIBS=`$PKGCONFIG --libs libsystemd-daemon` + if $PKGCONFIG --exists libsystemd-journal; then + ONDEMANDFLAGS="$ONDEMANDFLAGS `$PKGCONFIG --cflags libsystemd-journal`" + ONDEMANDLIBS="$ONDEMANDLIBS `$PKGCONFIG --libs libsystemd-journal`" + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + + if test $have_systemd = yes; then + $as_echo "#define HAVE_SYSTEMD 1" >>confdefs.h + + $as_echo "#define HAVE_ONDEMAND 1" >>confdefs.h + + ac_fn_c_check_header_mongrel "$LINENO" "systemd/sd-journal.h" "ac_cv_header_systemd_sd_journal_h" "$ac_includes_default" +if test "x$ac_cv_header_systemd_sd_journal_h" = xyes; then : + $as_echo "#define HAVE_SYSTEMD_SD_JOURNAL_H 1" >>confdefs.h + +fi + + + if test "x$SYSTEMD_DIR" = x; then + SYSTEMD_DIR="`$PKGCONFIG --variable=systemdsystemunitdir systemd`" + fi + fi + fi +fi + +# Check whether --enable-upstart was given. +if test "${enable_upstart+set}" = set; then : + enableval=$enable_upstart; +fi + +if test "x$enable_upstart" = "xyes"; then + if test "x$have_systemd" = "xyes"; then + as_fn_error $? "Cannot support both systemd and upstart." "$LINENO" 5 + fi + $as_echo "#define HAVE_UPSTART 1" >>confdefs.h + + $as_echo "#define HAVE_ONDEMAND 1" >>confdefs.h + +fi + +SMFMANIFESTDIR="" + + +# Check whether --with-smfmanifestdir was given. +if test "${with_smfmanifestdir+set}" = set; then : + withval=$with_smfmanifestdir; SMFMANIFESTDIR="$withval" +fi + + + +# Check whether --with-rcdir was given. +if test "${with_rcdir+set}" = set; then : + withval=$with_rcdir; rcdir="$withval" +else + rcdir="" +fi + + +# Check whether --with-rclevels was given. +if test "${with_rclevels+set}" = set; then : + withval=$with_rclevels; rclevels="$withval" +else + rclevels="2 3 5" +fi + + +# Check whether --with-rcstart was given. +if test "${with_rcstart+set}" = set; then : + withval=$with_rcstart; rcstart="$withval" +else + rcstart="" +fi + + +# Check whether --with-rcstop was given. +if test "${with_rcstop+set}" = set; then : + withval=$with_rcstop; rcstop="$withval" +else + rcstop="" +fi + + +if test x$rcdir = x; then + if test x$LAUNCHD_DIR = x -a x$SYSTEMD_DIR = x -a x$SMFMANIFESTDIR = x; then + # Fall back on "init", the original service startup interface... + if test -d /sbin/init.d; then + # SuSE + rcdir="/sbin/init.d" + elif test -d /etc/init.d; then + # Others + rcdir="/etc" + else + # RedHat, NetBSD + rcdir="/etc/rc.d" + fi + else + rcdir="no" + fi +fi + +if test "x$rcstart" = x; then + case "$host_os_name" in + linux* | gnu*) + # Linux + rcstart="81" + ;; + + sunos*) + # Solaris + rcstart="81" + ;; + + *) + # Others + rcstart="99" + ;; + esac +fi + +if test "x$rcstop" = x; then + case "$host_os_name" in + linux* | gnu*) + # Linux + rcstop="36" + ;; + + *) + # Others + rcstop="00" + ;; + esac +fi + +INITDIR="" +INITDDIR="" +RCLEVELS="$rclevels" +RCSTART="$rcstart" +RCSTOP="$rcstop" + + + + + + +if test "x$rcdir" != xno; then + if test "x$rclevels" = x; then + INITDDIR="$rcdir" + else + INITDIR="$rcdir" + fi +fi + + +# Check whether --with-xinetd was given. +if test "${with_xinetd+set}" = set; then : + withval=$with_xinetd; xinetd="$withval" +else + xinetd="" +fi + +XINETD="" + + +if test "x$xinetd" = x; then + if test ! -x /sbin/launchd; then + for dir in /etc/xinetd.d /usr/local/etc/xinetd.d; do + if test -d $dir; then + XINETD="$dir" + break + fi + done + fi +elif test "x$xinetd" != xno; then + XINETD="$xinetd" +fi LANGUAGES="`ls -1 locale/cups_*.po 2>/dev/null | sed -e '1,$s/locale\/cups_//' -e '1,$s/\.po//' | tr '\n' ' '`" @@ -9254,7 +9274,8 @@ fi if test "${with_bundledir+set}" = set; then : withval=$with_bundledir; CUPS_BUNDLEDIR="$withval" else - if test "x$uname" = xDarwin -a $uversion -ge 100; then + + if test "x$host_os_name" = xdarwin -a $host_os_version -ge 100; then CUPS_BUNDLEDIR="/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/PrintCore.framework/Versions/A" LANGUAGES="" else @@ -9272,11 +9293,49 @@ _ACEOF fi +# Check whether --with-bundlelang was given. +if test "${with_bundlelang+set}" = set; then : + withval=$with_bundlelang; cups_bundlelang="$withval" +else + + if test $host_os_version -ge 190; then + cups_bundlelang="en" + else + cups_bundlelang="English" + fi +fi + + +if test "x$cups_bundlelang" != x -a "x$CUPS_BUNDLEDIR" != x; then + CUPS_RESOURCEDIR="$CUPS_BUNDLEDIR/Resources/$cups_bundlelang.lproj" +else + CUPS_RESOURCEDIR="" +fi + + + +# Check whether --with-exe_file_perm was given. +if test "${with_exe_file_perm+set}" = set; then : + withval=$with_exe_file_perm; CUPS_EXE_FILE_PERM="$withval" +else + case "$host_os_name" in + linux* | gnu*) + CUPS_EXE_FILE_PERM="755" + ;; + *) + CUPS_EXE_FILE_PERM="555" + ;; + esac +fi + + + + # Check whether --with-config_file_perm was given. if test "${with_config_file_perm+set}" = set; then : withval=$with_config_file_perm; CUPS_CONFIG_FILE_PERM="$withval" else - if test "x$uname" = xDarwin; then + if test "x$host_os_name" = xdarwin; then CUPS_CONFIG_FILE_PERM="644" else CUPS_CONFIG_FILE_PERM="640" @@ -9294,7 +9353,14 @@ _ACEOF if test "${with_cupsd_file_perm+set}" = set; then : withval=$with_cupsd_file_perm; CUPS_CUPSD_FILE_PERM="$withval" else - CUPS_CUPSD_FILE_PERM="500" + case "$host_os_name" in + linux* | gnu*) + CUPS_CUPSD_FILE_PERM="700" + ;; + *) + CUPS_CUPSD_FILE_PERM="500" + ;; + esac fi @@ -9346,7 +9412,7 @@ _ACEOF if test "${with_access_log_level+set}" = set; then : withval=$with_access_log_level; CUPS_ACCESS_LOG_LEVEL="$withval" else - CUPS_ACCESS_LOG_LEVEL="actions" + CUPS_ACCESS_LOG_LEVEL="none" fi @@ -9355,6 +9421,18 @@ cat >>confdefs.h <<_ACEOF _ACEOF +# Check whether --enable-page_logging was given. +if test "${enable_page_logging+set}" = set; then : + enableval=$enable_page_logging; +fi + +if test "x$enable_page_logging" = xyes; then + CUPS_PAGE_LOG_FORMAT="" +else + CUPS_PAGE_LOG_FORMAT="PageLogFormat" +fi + + # Check whether --enable-browsing was given. if test "${enable_browsing+set}" = set; then : enableval=$enable_browsing; @@ -9431,7 +9509,7 @@ if test "${with_cups_user+set}" = set; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default print user" >&5 $as_echo_n "checking for default print user... " >&6; } - if test x$uname = xDarwin; then + if test x$host_os_name = xdarwin; then if test x`id -u _lp 2>/dev/null` = x; then CUPS_USER="lp"; else @@ -9474,7 +9552,7 @@ if test "${with_cups_group+set}" = set; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default print group" >&5 $as_echo_n "checking for default print group... " >&6; } - if test x$uname = xDarwin; then + if test x$host_os_name = xdarwin; then if test x`id -g _lp 2>/dev/null` = x; then CUPS_GROUP="lp"; else @@ -9516,14 +9594,14 @@ fi if test "${with_system_groups+set}" = set; then : withval=$with_system_groups; CUPS_SYSTEM_GROUPS="$withval" else - if test x$uname = xDarwin; then + if test x$host_os_name = xdarwin; then CUPS_SYSTEM_GROUPS="admin" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default system groups" >&5 $as_echo_n "checking for default system groups... " >&6; } if test -f /etc/group; then CUPS_SYSTEM_GROUPS="" - GROUP_LIST="lpadmin sys system root" + GROUP_LIST="lpadmin sys system root wheel" for group in $GROUP_LIST; do if test "`grep \^${group}: /etc/group`" != ""; then if test "x$CUPS_SYSTEM_GROUPS" = x; then @@ -9588,15 +9666,15 @@ fi if test x$default_printcap != xno; then if test "x$default_printcap" = "xdefault"; then - case $uname in - Darwin*) - if test $uversion -ge 90; then + case $host_os_name in + darwin*) + if test $host_os_version -ge 90; then CUPS_DEFAULT_PRINTCAP="/Library/Preferences/org.cups.printers.plist" else CUPS_DEFAULT_PRINTCAP="/etc/printcap" fi ;; - SunOS*) + sunos*) CUPS_DEFAULT_PRINTCAP="/etc/printers.conf" ;; *) @@ -9627,8 +9705,8 @@ fi if test x$default_lpdconfigfile != xno; then if test "x$default_lpdconfigfile" = "xdefault"; then - case $uname in - Darwin*) + case $host_os_name in + darwin*) CUPS_DEFAULT_LPD_CONFIG_FILE="launchd:///System/Library/LaunchDaemons/org.cups.cups-lpd.plist" ;; *) @@ -9717,7 +9795,7 @@ if test "${with_snmp_address+set}" = set; then : CUPS_SNMP_ADDRESS="Address $withval" fi else - if test "x$uname" = xDarwin; then + if test "x$host_os_name" = xdarwin; then CUPS_SNMP_ADDRESS="" else CUPS_SNMP_ADDRESS="Address @LOCAL" @@ -9767,7 +9845,7 @@ case "x$enable_webif" in CUPS_DEFAULT_WEBIF=1 ;; *) - if test $uname = Darwin; then + if test $host_os_name = darwin; then CUPS_WEBIF=No CUPS_DEFAULT_WEBIF=0 else @@ -9784,307 +9862,6 @@ _ACEOF - - -# Check whether --with-java was given. -if test "${with_java+set}" = set; then : - withval=$with_java; CUPS_JAVA="$withval" -else - CUPS_JAVA="" -fi - - -if test "x$CUPS_JAVA" = x; then - # Extract the first word of "java", so it can be a program name with args. -set dummy java; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_JAVA+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $JAVA in - [\\/]* | ?:[\\/]*) - ac_cv_path_JAVA="$JAVA" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_JAVA="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -JAVA=$ac_cv_path_JAVA -if test -n "$JAVA"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVA" >&5 -$as_echo "$JAVA" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - CUPS_JAVA="$JAVA" -fi - -cat >>confdefs.h <<_ACEOF -#define CUPS_JAVA "$CUPS_JAVA" -_ACEOF - - -if test "x$CUPS_JAVA" != x; then - $as_echo "#define HAVE_JAVA 1" >>confdefs.h - -fi - - -# Check whether --with-perl was given. -if test "${with_perl+set}" = set; then : - withval=$with_perl; CUPS_PERL="$withval" -else - CUPS_PERL="" -fi - - -if test "x$CUPS_PERL" = x; then - # Extract the first word of "perl", so it can be a program name with args. -set dummy perl; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PERL+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $PERL in - [\\/]* | ?:[\\/]*) - ac_cv_path_PERL="$PERL" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -PERL=$ac_cv_path_PERL -if test -n "$PERL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 -$as_echo "$PERL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - CUPS_PERL="$PERL" -fi - -cat >>confdefs.h <<_ACEOF -#define CUPS_PERL "$CUPS_PERL" -_ACEOF - - -if test "x$CUPS_PERL" != x; then - $as_echo "#define HAVE_PERL 1" >>confdefs.h - -fi - - -# Check whether --with-php was given. -if test "${with_php+set}" = set; then : - withval=$with_php; CUPS_PHP="$withval" -else - CUPS_PHP="" -fi - - -if test "x$CUPS_PHP" = x; then - # Extract the first word of "php-cgi", so it can be a program name with args. -set dummy php-cgi; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PHPCGI+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $PHPCGI in - [\\/]* | ?:[\\/]*) - ac_cv_path_PHPCGI="$PHPCGI" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_PHPCGI="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -PHPCGI=$ac_cv_path_PHPCGI -if test -n "$PHPCGI"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PHPCGI" >&5 -$as_echo "$PHPCGI" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - if test "x$PHPCGI" = x; then - # Extract the first word of "php", so it can be a program name with args. -set dummy php; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PHP+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $PHP in - [\\/]* | ?:[\\/]*) - ac_cv_path_PHP="$PHP" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_PHP="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -PHP=$ac_cv_path_PHP -if test -n "$PHP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PHP" >&5 -$as_echo "$PHP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - CUPS_PHP="$PHP" - else - CUPS_PHP="$PHPCGI" - fi -fi - -cat >>confdefs.h <<_ACEOF -#define CUPS_PHP "$CUPS_PHP" -_ACEOF - - -if test "x$CUPS_PHP" = x; then - CUPS_PHP="no" -else - $as_echo "#define HAVE_PHP 1" >>confdefs.h - -fi - - -# Check whether --with-python was given. -if test "${with_python+set}" = set; then : - withval=$with_python; CUPS_PYTHON="$withval" -else - CUPS_PYTHON="" -fi - - -if test "x$CUPS_PYTHON" = x; then - # Extract the first word of "python", so it can be a program name with args. -set dummy python; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PYTHON+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $PYTHON in - [\\/]* | ?:[\\/]*) - ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -PYTHON=$ac_cv_path_PYTHON -if test -n "$PYTHON"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 -$as_echo "$PYTHON" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - CUPS_PYTHON="$PYTHON" -fi - -cat >>confdefs.h <<_ACEOF -#define CUPS_PYTHON "$CUPS_PYTHON" -_ACEOF - - -if test "x$CUPS_PYTHON" != x; then - $as_echo "#define HAVE_PYTHON 1" >>confdefs.h - -fi - - - INSTALL_LANGUAGES="" UNINSTALL_LANGUAGES="" LANGFILES="" @@ -10108,7 +9885,7 @@ fi -ac_config_files="$ac_config_files Makedefs conf/cups-files.conf conf/cupsd.conf conf/mime.convs conf/pam.std conf/snmp.conf cups-config data/testprint desktop/cups.desktop doc/help/ref-cups-files-conf.html doc/help/ref-cupsd-conf.html doc/help/standard.html doc/index.html man/client.conf.man man/cups-deviced.man man/cups-driverd.man man/cups-files.conf.man man/cups-lpd.man man/cups-snmp.man man/cupsaddsmb.man man/cupsd.conf.man man/cupsd.man man/lpoptions.man scheduler/cups-lpd.xinetd scheduler/cups.sh scheduler/cups.xml scheduler/org.cups.cups-lpd.plist templates/header.tmpl packaging/cups.list $LANGFILES" +ac_config_files="$ac_config_files Makedefs conf/cups-files.conf conf/cupsd.conf conf/mime.convs conf/pam.std conf/snmp.conf cups-config desktop/cups.desktop doc/index.html scheduler/cups-lpd.xinetd scheduler/cups.sh scheduler/cups.xml scheduler/org.cups.cups-lpd.plist scheduler/org.cups.cups-lpdAT.service scheduler/org.cups.cupsd.path scheduler/org.cups.cupsd.service scheduler/org.cups.cupsd.socket templates/header.tmpl packaging/cups.list $LANGFILES" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -10616,7 +10393,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by $as_me, which was +This file was extended by CUPS $as_me 2.3.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -10672,13 +10449,14 @@ $config_files Configuration headers: $config_headers -Report bugs to the package provider." +Report bugs to . +CUPS home page: ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -config.status +CUPS config.status 2.3.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -10808,26 +10586,16 @@ do "conf/pam.std") CONFIG_FILES="$CONFIG_FILES conf/pam.std" ;; "conf/snmp.conf") CONFIG_FILES="$CONFIG_FILES conf/snmp.conf" ;; "cups-config") CONFIG_FILES="$CONFIG_FILES cups-config" ;; - "data/testprint") CONFIG_FILES="$CONFIG_FILES data/testprint" ;; "desktop/cups.desktop") CONFIG_FILES="$CONFIG_FILES desktop/cups.desktop" ;; - "doc/help/ref-cups-files-conf.html") CONFIG_FILES="$CONFIG_FILES doc/help/ref-cups-files-conf.html" ;; - "doc/help/ref-cupsd-conf.html") CONFIG_FILES="$CONFIG_FILES doc/help/ref-cupsd-conf.html" ;; - "doc/help/standard.html") CONFIG_FILES="$CONFIG_FILES doc/help/standard.html" ;; "doc/index.html") CONFIG_FILES="$CONFIG_FILES doc/index.html" ;; - "man/client.conf.man") CONFIG_FILES="$CONFIG_FILES man/client.conf.man" ;; - "man/cups-deviced.man") CONFIG_FILES="$CONFIG_FILES man/cups-deviced.man" ;; - "man/cups-driverd.man") CONFIG_FILES="$CONFIG_FILES man/cups-driverd.man" ;; - "man/cups-files.conf.man") CONFIG_FILES="$CONFIG_FILES man/cups-files.conf.man" ;; - "man/cups-lpd.man") CONFIG_FILES="$CONFIG_FILES man/cups-lpd.man" ;; - "man/cups-snmp.man") CONFIG_FILES="$CONFIG_FILES man/cups-snmp.man" ;; - "man/cupsaddsmb.man") CONFIG_FILES="$CONFIG_FILES man/cupsaddsmb.man" ;; - "man/cupsd.conf.man") CONFIG_FILES="$CONFIG_FILES man/cupsd.conf.man" ;; - "man/cupsd.man") CONFIG_FILES="$CONFIG_FILES man/cupsd.man" ;; - "man/lpoptions.man") CONFIG_FILES="$CONFIG_FILES man/lpoptions.man" ;; "scheduler/cups-lpd.xinetd") CONFIG_FILES="$CONFIG_FILES scheduler/cups-lpd.xinetd" ;; "scheduler/cups.sh") CONFIG_FILES="$CONFIG_FILES scheduler/cups.sh" ;; "scheduler/cups.xml") CONFIG_FILES="$CONFIG_FILES scheduler/cups.xml" ;; "scheduler/org.cups.cups-lpd.plist") CONFIG_FILES="$CONFIG_FILES scheduler/org.cups.cups-lpd.plist" ;; + "scheduler/org.cups.cups-lpdAT.service") CONFIG_FILES="$CONFIG_FILES scheduler/org.cups.cups-lpdAT.service" ;; + "scheduler/org.cups.cupsd.path") CONFIG_FILES="$CONFIG_FILES scheduler/org.cups.cupsd.path" ;; + "scheduler/org.cups.cupsd.service") CONFIG_FILES="$CONFIG_FILES scheduler/org.cups.cupsd.service" ;; + "scheduler/org.cups.cupsd.socket") CONFIG_FILES="$CONFIG_FILES scheduler/org.cups.cupsd.socket" ;; "templates/header.tmpl") CONFIG_FILES="$CONFIG_FILES templates/header.tmpl" ;; "packaging/cups.list") CONFIG_FILES="$CONFIG_FILES packaging/cups.list" ;; "$LANGFILES") CONFIG_FILES="$CONFIG_FILES $LANGFILES" ;; @@ -11414,4 +11182,3 @@ fi chmod +x cups-config - diff --git a/configure.in b/configure.ac similarity index 60% rename from configure.in rename to configure.ac index 3951e90..7eca9e3 100644 --- a/configure.in +++ b/configure.ac @@ -1,19 +1,18 @@ dnl -dnl "$Id: configure.in 7833 2008-08-04 20:55:13Z mike $" +dnl Configuration script for CUPS. dnl -dnl Configuration script for CUPS. +dnl Copyright © 2007-2019 by Apple Inc. +dnl Copyright © 1997-2007 by Easy Software Products, all rights reserved. dnl -dnl Copyright 2007-2013 by Apple Inc. -dnl Copyright 1997-2007 by Easy Software Products, all rights reserved. -dnl -dnl These coded instructions, statements, and computer programs are the -dnl property of Apple Inc. and are protected by Federal copyright -dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" -dnl which should have been included with this file. If this file is -dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl Licensed under Apache License v2.0. See the file "LICENSE" for more +dnl information. dnl -AC_INIT(cups/cups.h) +dnl We need at least autoconf 2.60... +AC_PREREQ(2.60) + +dnl Package name and version... +AC_INIT([CUPS], [2.3.0], [https://github.com/apple/cups/issues], [cups], [https://www.cups.org/]) sinclude(config-scripts/cups-opsys.m4) sinclude(config-scripts/cups-common.m4) @@ -32,9 +31,8 @@ sinclude(config-scripts/cups-ssl.m4) sinclude(config-scripts/cups-pam.m4) sinclude(config-scripts/cups-largefile.m4) sinclude(config-scripts/cups-dnssd.m4) -sinclude(config-scripts/cups-launchd.m4) +sinclude(config-scripts/cups-startup.m4) sinclude(config-scripts/cups-defaults.m4) -sinclude(config-scripts/cups-scripting.m4) INSTALL_LANGUAGES="" UNINSTALL_LANGUAGES="" @@ -66,32 +64,18 @@ AC_OUTPUT(Makedefs conf/pam.std conf/snmp.conf cups-config - data/testprint desktop/cups.desktop - doc/help/ref-cups-files-conf.html - doc/help/ref-cupsd-conf.html - doc/help/standard.html doc/index.html - man/client.conf.man - man/cups-deviced.man - man/cups-driverd.man - man/cups-files.conf.man - man/cups-lpd.man - man/cups-snmp.man - man/cupsaddsmb.man - man/cupsd.conf.man - man/cupsd.man - man/lpoptions.man scheduler/cups-lpd.xinetd scheduler/cups.sh scheduler/cups.xml scheduler/org.cups.cups-lpd.plist + scheduler/org.cups.cups-lpdAT.service + scheduler/org.cups.cupsd.path + scheduler/org.cups.cupsd.service + scheduler/org.cups.cupsd.socket templates/header.tmpl packaging/cups.list $LANGFILES) chmod +x cups-config - -dnl -dnl End of "$Id: configure.in 7833 2008-08-04 20:55:13Z mike $". -dnl diff --git a/cups-config.in b/cups-config.in index f0951d0..9dd094d 100755 --- a/cups-config.in +++ b/cups-config.in @@ -2,18 +2,15 @@ # # CUPS configuration utility. # -# Copyright 2007-2016 by Apple Inc. -# Copyright 2001-2006 by Easy Software Products, all rights reserved. +# Copyright © 2007-2019 by Apple Inc. +# Copyright © 2001-2006 by Easy Software Products, all rights reserved. # -# These coded instructions, statements, and computer programs are the -# property of Apple Inc. and are protected by Federal copyright -# law. Distribution and use rights are outlined in the file "LICENSE.txt" -# which should have been included with this file. If this file is -# file is missing or damaged, see the license at "http://www.cups.org/". +# Licensed under Apache License v2.0. See the file "LICENSE" for more +# information. # VERSION="@CUPS_VERSION@" -APIVERSION="2.2" +APIVERSION="2.3" BUILD="@CUPS_BUILD@" prefix=@prefix@ @@ -21,7 +18,6 @@ exec_prefix=@exec_prefix@ bindir=@bindir@ includedir=@includedir@ libdir=@libdir@ -imagelibdir=@libdir@ datarootdir=@datadir@ datadir=@datadir@ sysconfdir=@sysconfdir@ @@ -30,19 +26,18 @@ cups_serverbin=@CUPS_SERVERBIN@ cups_serverroot=@CUPS_SERVERROOT@ INSTALLSTATIC=@INSTALLSTATIC@ -# flags for C++ compiler: +# flags for compiler and linker... CFLAGS="" LDFLAGS="@EXPORT_LDFLAGS@" -LIBS="@LIBGSSAPI@ @EXPORT_SSLLIBS@ @LIBZ@ @LIBS@" +LIBS="@LIBGSSAPI@ @DNSSDLIBS@ @EXPORT_SSLLIBS@ @LIBZ@ @LIBS@" # Check for local invocation... selfdir=`dirname $0` if test -f "$selfdir/cups/cups.h"; then CFLAGS="-I$selfdir" - LDFLAGS="-L$selfdir/cups -L$selfdir/filter $LDFLAGS" + LDFLAGS="-L$selfdir/cups $LDFLAGS" libdir="$selfdir/cups" - imagelibdir="$selfdir/filter" else if test $includedir != /usr/include; then CFLAGS="$CFLAGS -I$includedir" @@ -76,7 +71,6 @@ fi # Parse command line options static=no -image=no while test $# -gt 0; do case $1 in @@ -96,22 +90,16 @@ while test $# -gt 0; do usage 0 ;; --image) - image=yes + # Do nothing ;; --ldflags) echo $LDFLAGS ;; --libs) if test $static = no; then - libs="@EXTLINKCUPS@ $LIBS"; - if test $image = yes; then - libs="@EXTLINKCUPSIMAGE@ $libs" - fi + libs="@EXTLINKCUPS@"; else libs="$libdir/libcups.a $LIBS"; - if test $image = yes; then - libs="$libdir/libcupsimage.a $libs" - fi fi echo $libs ;; @@ -123,7 +111,7 @@ while test $# -gt 0; do ;; --static) if test -z "$INSTALLSTATIC"; then - echo "WARNING: Static libraries not installed!" >&2 + echo "WARNING: Static libraries not installed." >&2 else static=yes fi diff --git a/cups/Dependencies b/cups/Dependencies index 11ec748..b30c769 100644 --- a/cups/Dependencies +++ b/cups/Dependencies @@ -1,316 +1,408 @@ -adminutil.o: adminutil.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h ppd.h raster.h \ - adminutil.h array.o: array.c ../cups/cups.h file.h versioning.h ipp.h http.h array.h \ - language.h pwg.h string-private.h ../config.h debug-private.h \ - array-private.h + language.h pwg.h string-private.h ../config.h ../cups/versioning.h \ + debug-internal.h debug-private.h array-private.h ../cups/array.h auth.o: auth.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +debug.o: debug.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +dest.o: dest.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +dest-job.o: dest-job.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +dest-localization.o: dest-localization.c cups-private.h string-private.h \ + ../config.h ../cups/versioning.h array-private.h ../cups/array.h \ + versioning.h ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h \ + language.h pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +dest-options.o: dest-options.c cups-private.h string-private.h \ + ../config.h ../cups/versioning.h array-private.h ../cups/array.h \ + versioning.h ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h \ + language.h pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +dir.o: dir.c string-private.h ../config.h ../cups/versioning.h \ + debug-internal.h debug-private.h dir.h versioning.h +encode.o: encode.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +file.o: file.c file-private.h cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +getputfile.o: getputfile.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +globals.o: globals.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h +hash.o: hash.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h +http.o: http.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +http-addr.o: http-addr.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +http-addrlist.o: http-addrlist.c cups-private.h string-private.h \ + ../config.h ../cups/versioning.h array-private.h ../cups/array.h \ + versioning.h ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h \ + language.h pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +http-support.o: http-support.c cups-private.h string-private.h \ + ../config.h ../cups/versioning.h array-private.h ../cups/array.h \ + versioning.h ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h \ + language.h pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +ipp.o: ipp.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +ipp-file.o: ipp-file.c ipp-private.h ../cups/cups.h file.h versioning.h \ + ipp.h http.h array.h language.h pwg.h string-private.h ../config.h \ + ../cups/versioning.h debug-internal.h debug-private.h +ipp-vars.o: ipp-vars.c ../cups/cups.h file.h versioning.h ipp.h http.h \ + array.h language.h pwg.h ipp-private.h string-private.h ../config.h \ + ../cups/versioning.h debug-internal.h debug-private.h +ipp-support.o: ipp-support.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +langprintf.o: langprintf.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +language.o: language.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +md5.o: md5.c md5-internal.h ../cups/versioning.h string-private.h \ + ../config.h +md5passwd.o: md5passwd.c ../cups/cups.h file.h versioning.h ipp.h http.h \ + array.h language.h pwg.h http-private.h ../config.h ../cups/language.h \ + ../cups/http.h ipp-private.h string-private.h ../cups/versioning.h +notify.o: notify.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +options.o: options.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +pwg-media.o: pwg-media.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +raster-error.o: raster-error.c cups-private.h string-private.h \ + ../config.h ../cups/versioning.h array-private.h ../cups/array.h \ + versioning.h ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h \ + language.h pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + raster-private.h raster.h cups.h ../cups/debug-private.h \ + ../cups/string-private.h debug-internal.h debug-private.h +raster-stream.o: raster-stream.c raster-private.h raster.h cups.h file.h \ + versioning.h ipp.h http.h array.h language.h pwg.h ../cups/cups.h \ + ../cups/debug-private.h ../cups/versioning.h ../cups/string-private.h \ + ../config.h debug-internal.h debug-private.h +raster-stubs.o: raster-stubs.c raster-private.h raster.h cups.h file.h \ + versioning.h ipp.h http.h array.h language.h pwg.h ../cups/cups.h \ + ../cups/debug-private.h ../cups/versioning.h ../cups/string-private.h \ + ../config.h +request.o: request.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +snprintf.o: snprintf.c string-private.h ../config.h ../cups/versioning.h +string.o: string.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +tempfile.o: tempfile.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +thread.o: thread.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h +tls.o: tls.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h tls-darwin.c +transcode.o: transcode.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +usersys.o: usersys.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +util.o: util.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h +adminutil.o: adminutil.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h ppd.h cups.h raster.h adminutil.h backchannel.o: backchannel.c cups.h file.h versioning.h ipp.h http.h \ array.h language.h pwg.h backend.o: backend.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h backend.h ppd.h raster.h -debug.o: debug.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -dest.o: dest.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -dest-job.o: dest-job.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -dest-localization.o: dest-localization.c cups-private.h string-private.h \ - ../config.h debug-private.h ../cups/versioning.h array-private.h \ - ../cups/array.h ipp-private.h ../cups/ipp.h http.h http-private.h \ - ../cups/language.h md5-private.h language-private.h \ - ../cups/transcode.h pwg-private.h ../cups/cups.h file.h pwg.h \ - thread-private.h -dest-options.o: dest-options.c cups-private.h string-private.h \ - ../config.h debug-private.h ../cups/versioning.h array-private.h \ - ../cups/array.h ipp-private.h ../cups/ipp.h http.h http-private.h \ - ../cups/language.h md5-private.h language-private.h \ - ../cups/transcode.h pwg-private.h ../cups/cups.h file.h pwg.h \ - thread-private.h -dir.o: dir.c string-private.h ../config.h debug-private.h \ - ../cups/versioning.h dir.h -encode.o: encode.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -file.o: file.c file-private.h cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + backend.h ppd.h cups.h raster.h getdevices.o: getdevices.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h adminutil.h -getifaddrs.o: getifaddrs.c http-private.h ../config.h ../cups/language.h \ - array.h versioning.h ../cups/http.h md5-private.h ipp-private.h \ - ../cups/ipp.h -getputfile.o: getputfile.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -globals.o: globals.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -hash.o: hash.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -http.o: http.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -http-addr.o: http-addr.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -http-addrlist.o: http-addrlist.c cups-private.h string-private.h \ - ../config.h debug-private.h ../cups/versioning.h array-private.h \ - ../cups/array.h ipp-private.h ../cups/ipp.h http.h http-private.h \ - ../cups/language.h md5-private.h language-private.h \ - ../cups/transcode.h pwg-private.h ../cups/cups.h file.h pwg.h \ - thread-private.h -http-support.o: http-support.c cups-private.h string-private.h \ - ../config.h debug-private.h ../cups/versioning.h array-private.h \ - ../cups/array.h ipp-private.h ../cups/ipp.h http.h http-private.h \ - ../cups/language.h md5-private.h language-private.h \ - ../cups/transcode.h pwg-private.h ../cups/cups.h file.h pwg.h \ - thread-private.h -ipp.o: ipp.c cups-private.h string-private.h ../config.h debug-private.h \ - ../cups/versioning.h array-private.h ../cups/array.h ipp-private.h \ - ../cups/ipp.h http.h http-private.h ../cups/language.h md5-private.h \ - language-private.h ../cups/transcode.h pwg-private.h ../cups/cups.h \ - file.h pwg.h thread-private.h -ipp-support.o: ipp-support.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -langprintf.o: langprintf.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -language.o: language.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -md5.o: md5.c md5-private.h string-private.h ../config.h -md5passwd.o: md5passwd.c http-private.h ../config.h ../cups/language.h \ - array.h versioning.h ../cups/http.h md5-private.h ipp-private.h \ - ../cups/ipp.h string-private.h -notify.o: notify.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -options.o: options.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -ppd.o: ppd.c cups-private.h string-private.h ../config.h debug-private.h \ - ../cups/versioning.h array-private.h ../cups/array.h ipp-private.h \ - ../cups/ipp.h http.h http-private.h ../cups/language.h md5-private.h \ - language-private.h ../cups/transcode.h pwg-private.h ../cups/cups.h \ - file.h pwg.h thread-private.h ppd-private.h ../cups/ppd.h raster.h + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h adminutil.h cups.h +getifaddrs.o: getifaddrs.c getifaddrs-internal.h ../config.h +ppd.o: ppd.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + ppd-private.h ../cups/ppd.h cups.h raster.h debug-internal.h \ + debug-private.h ppd-attr.o: ppd-attr.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h ppd-private.h \ - ../cups/ppd.h raster.h + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + ppd-private.h ../cups/ppd.h cups.h raster.h debug-internal.h \ + debug-private.h ppd-cache.o: ppd-cache.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h ppd-private.h \ - ../cups/ppd.h raster.h + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + ppd-private.h ../cups/ppd.h cups.h raster.h debug-internal.h \ + debug-private.h ppd-conflicts.o: ppd-conflicts.c cups-private.h string-private.h \ - ../config.h debug-private.h ../cups/versioning.h array-private.h \ - ../cups/array.h ipp-private.h ../cups/ipp.h http.h http-private.h \ - ../cups/language.h md5-private.h language-private.h \ - ../cups/transcode.h pwg-private.h ../cups/cups.h file.h pwg.h \ - thread-private.h ppd-private.h ../cups/ppd.h raster.h + ../config.h ../cups/versioning.h array-private.h ../cups/array.h \ + versioning.h ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h \ + language.h pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + ppd-private.h ../cups/ppd.h cups.h raster.h debug-internal.h \ + debug-private.h ppd-custom.o: ppd-custom.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h ppd-private.h \ - ../cups/ppd.h raster.h + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + ppd-private.h ../cups/ppd.h cups.h raster.h debug-internal.h \ + debug-private.h ppd-emit.o: ppd-emit.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h ppd.h raster.h + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + debug-internal.h debug-private.h ppd.h cups.h raster.h ppd-localize.o: ppd-localize.c cups-private.h string-private.h \ - ../config.h debug-private.h ../cups/versioning.h array-private.h \ - ../cups/array.h ipp-private.h ../cups/ipp.h http.h http-private.h \ - ../cups/language.h md5-private.h language-private.h \ - ../cups/transcode.h pwg-private.h ../cups/cups.h file.h pwg.h \ - thread-private.h ppd-private.h ../cups/ppd.h raster.h + ../config.h ../cups/versioning.h array-private.h ../cups/array.h \ + versioning.h ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h \ + language.h pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + ppd-private.h ../cups/ppd.h cups.h raster.h debug-internal.h \ + debug-private.h ppd-mark.o: ppd-mark.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h ppd-private.h \ - ../cups/ppd.h raster.h -ppd-page.o: ppd-page.c string-private.h ../config.h debug-private.h \ - ../cups/versioning.h ppd.h cups.h file.h ipp.h http.h array.h \ - language.h pwg.h raster.h + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + ppd-private.h ../cups/ppd.h cups.h raster.h debug-internal.h \ + debug-private.h +ppd-page.o: ppd-page.c string-private.h ../config.h ../cups/versioning.h \ + debug-internal.h debug-private.h ppd.h cups.h file.h versioning.h \ + ipp.h http.h array.h language.h pwg.h raster.h ppd-util.o: ppd-util.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h ppd-private.h \ - ../cups/ppd.h raster.h -pwg-media.o: pwg-media.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -request.o: request.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + ppd-private.h ../cups/ppd.h cups.h raster.h debug-internal.h \ + debug-private.h +raster-interpret.o: raster-interpret.c ../cups/raster-private.h raster.h \ + cups.h file.h versioning.h ipp.h http.h array.h language.h pwg.h \ + ../cups/cups.h ../cups/debug-private.h ../cups/versioning.h \ + ../cups/string-private.h ../config.h ../cups/ppd-private.h \ + ../cups/ppd.h pwg-private.h debug-internal.h debug-private.h +raster-interstub.o: raster-interstub.c ../cups/ppd-private.h \ + ../cups/cups.h file.h versioning.h ipp.h http.h array.h language.h \ + pwg.h ../cups/ppd.h cups.h raster.h pwg-private.h sidechannel.o: sidechannel.c sidechannel.h versioning.h cups-private.h \ - string-private.h ../config.h debug-private.h array-private.h \ - ../cups/array.h ipp-private.h ../cups/ipp.h http.h http-private.h \ - ../cups/language.h md5-private.h language-private.h \ - ../cups/transcode.h pwg-private.h ../cups/cups.h file.h pwg.h \ - thread-private.h + string-private.h ../config.h ../cups/versioning.h array-private.h \ + ../cups/array.h ipp-private.h ../cups/cups.h file.h ipp.h http.h \ + array.h language.h pwg.h http-private.h ../cups/language.h \ + ../cups/http.h language-private.h ../cups/transcode.h pwg-private.h \ + thread-private.h debug-internal.h debug-private.h snmp.o: snmp.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h snmp-private.h -snprintf.o: snprintf.c string-private.h ../config.h -string.o: string.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -tempfile.o: tempfile.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -thread.o: thread.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -tls.o: tls.c cups-private.h string-private.h ../config.h debug-private.h \ - ../cups/versioning.h array-private.h ../cups/array.h ipp-private.h \ - ../cups/ipp.h http.h http-private.h ../cups/language.h md5-private.h \ - language-private.h ../cups/transcode.h pwg-private.h ../cups/cups.h \ - file.h pwg.h thread-private.h tls-darwin.c -transcode.o: transcode.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -usersys.o: usersys.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -util.o: util.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + snmp-private.h debug-internal.h debug-private.h +raster-interstub.o: raster-interstub.c ../cups/ppd-private.h \ + ../cups/cups.h file.h versioning.h ipp.h http.h array.h language.h \ + pwg.h ../cups/ppd.h cups.h raster.h pwg-private.h +raster-stubs.o: raster-stubs.c raster-private.h raster.h cups.h file.h \ + versioning.h ipp.h http.h array.h language.h pwg.h ../cups/cups.h \ + ../cups/debug-private.h ../cups/versioning.h ../cups/string-private.h \ + ../config.h +rasterbench.o: rasterbench.c ../config.h ../cups/raster.h cups.h file.h \ + versioning.h ipp.h http.h array.h language.h pwg.h testadmin.o: testadmin.c adminutil.h cups.h file.h versioning.h ipp.h \ - http.h array.h language.h pwg.h string-private.h ../config.h -testarray.o: testarray.c string-private.h ../config.h debug-private.h \ - ../cups/versioning.h array-private.h ../cups/array.h dir.h + http.h array.h language.h pwg.h string-private.h ../config.h \ + ../cups/versioning.h +testarray.o: testarray.c string-private.h ../config.h \ + ../cups/versioning.h debug-private.h array-private.h ../cups/array.h \ + versioning.h dir.h testcache.o: testcache.c ppd-private.h ../cups/cups.h file.h versioning.h \ - ipp.h http.h array.h language.h pwg.h ../cups/ppd.h raster.h \ + ipp.h http.h array.h language.h pwg.h ../cups/ppd.h cups.h raster.h \ pwg-private.h file-private.h cups-private.h string-private.h \ - ../config.h debug-private.h array-private.h ipp-private.h \ - http-private.h md5-private.h language-private.h ../cups/transcode.h \ - thread-private.h + ../config.h ../cups/versioning.h array-private.h ../cups/array.h \ + ipp-private.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h thread-private.h +testclient.o: testclient.c ../config.h ../cups/cups.h file.h versioning.h \ + ipp.h http.h array.h language.h pwg.h ../cups/raster.h cups.h \ + ../cups/string-private.h ../cups/versioning.h ../cups/thread-private.h testconflicts.o: testconflicts.c cups.h file.h versioning.h ipp.h http.h \ - array.h language.h pwg.h ppd.h raster.h string-private.h ../config.h + array.h language.h pwg.h ppd.h raster.h string-private.h ../config.h \ + ../cups/versioning.h testcreds.o: testcreds.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -testcups.o: testcups.c string-private.h ../config.h cups.h file.h \ - versioning.h ipp.h http.h array.h language.h pwg.h ppd.h raster.h + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h +testcups.o: testcups.c cups-private.h string-private.h ../config.h \ + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + ppd.h cups.h raster.h testdest.o: testdest.c cups.h file.h versioning.h ipp.h http.h array.h \ language.h pwg.h -testfile.o: testfile.c string-private.h ../config.h debug-private.h \ - ../cups/versioning.h file.h +testfile.o: testfile.c string-private.h ../config.h ../cups/versioning.h \ + debug-private.h file.h versioning.h +testgetdests.o: testgetdests.c cups.h file.h versioning.h ipp.h http.h \ + array.h language.h pwg.h testhttp.o: testhttp.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h -testi18n.o: testi18n.c string-private.h ../config.h language-private.h \ - ../cups/transcode.h language.h array.h versioning.h + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h +testi18n.o: testi18n.c string-private.h ../config.h ../cups/versioning.h \ + language-private.h ../cups/transcode.h language.h array.h versioning.h testipp.o: testipp.c file.h versioning.h string-private.h ../config.h \ - ipp-private.h ../cups/ipp.h http.h array.h + ../cups/versioning.h ipp-private.h ../cups/cups.h ipp.h http.h array.h \ + language.h pwg.h testoptions.o: testoptions.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h testlang.o: testlang.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h ppd-private.h \ - ../cups/ppd.h raster.h + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + ppd-private.h ../cups/ppd.h cups.h raster.h testppd.o: testppd.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h ppd-private.h \ - ../cups/ppd.h raster.h + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + ppd-private.h ../cups/ppd.h cups.h raster.h raster-private.h \ + ../cups/debug-private.h ../cups/string-private.h testpwg.o: testpwg.c ppd-private.h ../cups/cups.h file.h versioning.h \ - ipp.h http.h array.h language.h pwg.h ../cups/ppd.h raster.h \ + ipp.h http.h array.h language.h pwg.h ../cups/ppd.h cups.h raster.h \ pwg-private.h file-private.h cups-private.h string-private.h \ - ../config.h debug-private.h array-private.h ipp-private.h \ - http-private.h md5-private.h language-private.h ../cups/transcode.h \ - thread-private.h + ../config.h ../cups/versioning.h array-private.h ../cups/array.h \ + ipp-private.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h thread-private.h +testraster.o: testraster.c ../cups/raster-private.h raster.h cups.h \ + file.h versioning.h ipp.h http.h array.h language.h pwg.h \ + ../cups/cups.h ../cups/debug-private.h ../cups/versioning.h \ + ../cups/string-private.h ../config.h testsnmp.o: testsnmp.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h snmp-private.h + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h \ + snmp-private.h tlscheck.o: tlscheck.c cups-private.h string-private.h ../config.h \ - debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ - ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ - md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ - ../cups/cups.h file.h pwg.h thread-private.h + ../cups/versioning.h array-private.h ../cups/array.h versioning.h \ + ipp-private.h ../cups/cups.h file.h ipp.h http.h array.h language.h \ + pwg.h http-private.h ../cups/language.h ../cups/http.h \ + language-private.h ../cups/transcode.h pwg-private.h thread-private.h diff --git a/cups/Makefile b/cups/Makefile index 962bee6..87d85ba 100644 --- a/cups/Makefile +++ b/cups/Makefile @@ -1,38 +1,23 @@ # -# API library Makefile for CUPS. +# Library Makefile for CUPS. # -# Copyright 2007-2016 by Apple Inc. -# Copyright 1997-2006 by Easy Software Products, all rights reserved. +# Copyright © 2007-2019 by Apple Inc. +# Copyright © 1997-2006 by Easy Software Products, all rights reserved. # -# These coded instructions, statements, and computer programs are the -# property of Apple Inc. and are protected by Federal copyright -# law. Distribution and use rights are outlined in the file "LICENSE.txt" -# which should have been included with this file. If this file is -# missing or damaged, see the license at "http://www.cups.org/". -# -# This file is subject to the Apple OS-Developed Software exception. +# Licensed under Apache License v2.0. See the file "LICENSE" for more +# information. # include ../Makedefs -# -# Options to build libcups without the use of deprecated APIs... -# - -OPTIONS = -D_CUPS_NO_DEPRECATED=1 -D_PPD_DEPRECATED="" - - # # Object files... # -LIBOBJS = \ - adminutil.o \ +COREOBJS = \ array.o \ auth.o \ - backchannel.o \ - backend.o \ debug.o \ dest.o \ dest-job.o \ @@ -41,8 +26,6 @@ LIBOBJS = \ dir.o \ encode.o \ file.o \ - getdevices.o \ - getifaddrs.o \ getputfile.o \ globals.o \ hash.o \ @@ -51,6 +34,8 @@ LIBOBJS = \ http-addrlist.o \ http-support.o \ ipp.o \ + ipp-file.o \ + ipp-vars.o \ ipp-support.o \ langprintf.o \ language.o \ @@ -58,6 +43,26 @@ LIBOBJS = \ md5passwd.o \ notify.o \ options.o \ + pwg-media.o \ + raster-error.o \ + raster-stream.o \ + raster-stubs.o \ + request.o \ + snprintf.o \ + string.o \ + tempfile.o \ + thread.o \ + tls.o \ + transcode.o \ + usersys.o \ + util.o + +DRIVEROBJS = \ + adminutil.o \ + backchannel.o \ + backend.o \ + getdevices.o \ + getifaddrs.o \ ppd.o \ ppd-attr.o \ ppd-cache.o \ @@ -68,27 +73,30 @@ LIBOBJS = \ ppd-mark.o \ ppd-page.o \ ppd-util.o \ - pwg-media.o \ - request.o \ + raster-interpret.o \ + raster-interstub.o \ sidechannel.o \ - snmp.o \ - snprintf.o \ - string.o \ - tempfile.o \ - thread.o \ - tls.o \ - transcode.o \ - usersys.o \ - util.o + snmp.o + +LIBOBJS = \ + $(LIBCUPSOBJS) + +IMAGEOBJS = \ + raster-interstub.o \ + raster-stubs.o + TESTOBJS = \ + rasterbench.o \ testadmin.o \ testarray.o \ testcache.o \ + testclient.o \ testconflicts.o \ testcreds.o \ testcups.o \ testdest.o \ testfile.o \ + testgetdests.o \ testhttp.o \ testi18n.o \ testipp.o \ @@ -96,10 +104,12 @@ TESTOBJS = \ testlang.o \ testppd.o \ testpwg.o \ + testraster.o \ testsnmp.o \ tlscheck.o OBJS = \ $(LIBOBJS) \ + $(IMAGEOBJS) \ $(TESTOBJS) @@ -107,24 +117,29 @@ OBJS = \ # Header files to install... # -HEADERS = \ - adminutil.h \ +COREHEADERS = \ array.h \ - backend.h \ cups.h \ dir.h \ file.h \ http.h \ ipp.h \ language.h \ - ppd.h \ pwg.h \ raster.h \ - sidechannel.h \ transcode.h \ versioning.h -HEADERSPRIV = \ +DRIVERHEADERS = \ + adminutil.h \ + backend.h \ + ppd.h \ + sidechannel.h + +HEADERS = \ + $(LIBHEADERS) + +COREHEADERSPRIV = \ array-private.h \ cups-private.h \ debug-private.h \ @@ -132,32 +147,41 @@ HEADERSPRIV = \ http-private.h \ ipp-private.h \ language-private.h \ - md5-private.h \ - ppd-private.h \ pwg-private.h \ raster-private.h \ - snmp-private.h \ string-private.h \ thread-private.h +DRIVERHEADERSPRIV = \ + ppd-private.h \ + snmp-private.h + +HEADERSPRIV = \ + $(LIBHEADERSPRIV) + # # Targets in this directory... # LIBTARGETS = \ + $(LIBCUPSIMAGE) \ $(LIBCUPSSTATIC) \ - $(LIBCUPS) + $(LIBCUPS) \ + libcupsimage.a UNITTARGETS = \ + rasterbench \ testadmin \ testarray \ testcache \ + testclient \ testconflicts \ testcreds \ testcups \ testdest \ testfile \ + testgetdests \ testhttp \ testi18n \ testipp \ @@ -165,6 +189,7 @@ UNITTARGETS = \ testoptions \ testppd \ testpwg \ + testraster \ testsnmp \ tlscheck @@ -200,6 +225,7 @@ unittests: $(UNITTARGETS) clean: $(RM) $(OBJS) $(TARGETS) $(UNITTARGETS) $(RM) libcups.so libcups.dylib + $(RM) libcupsimage.so libcupsimage.dylib # @@ -262,7 +288,7 @@ install-headers: # Install libraries... # -install-libs: $(INSTALLSTATIC) +install-libs: $(LIBTARGETS) $(INSTALLSTATIC) echo Installing libraries in $(LIBDIR)... $(INSTALL_DIR) -m 755 $(LIBDIR) $(INSTALL_LIB) $(LIBCUPS) $(LIBDIR) @@ -274,10 +300,25 @@ install-libs: $(INSTALLSTATIC) $(RM) $(LIBDIR)/libcups.dylib; \ $(LN) $(LIBCUPS) $(LIBDIR)/libcups.dylib; \ fi + -if test "x$(LIBCUPSIMAGE)" != x; then \ + $(INSTALL_LIB) $(LIBCUPSIMAGE) $(LIBDIR); \ + fi + -if test "x$(LIBCUPSIMAGE)" = "xlibcupsimage.so.2"; then \ + $(RM) $(LIBDIR)/`basename $(LIBCUPSIMAGE) .2`; \ + $(LN) $(LIBCUPSIMAGE) $(LIBDIR)/`basename $(LIBCUPSIMAGE) .2`; \ + fi + -if test "x$(LIBCUPSIMAGE)" = "xlibcupsimage.2.dylib"; then \ + $(RM) $(LIBDIR)/libcupsimage.dylib; \ + $(LN) $(LIBCUPSIMAGE) $(LIBDIR)/libcupsimage.dylib; \ + fi if test "x$(SYMROOT)" != "x"; then \ $(INSTALL_DIR) $(SYMROOT); \ cp $(LIBCUPS) $(SYMROOT); \ dsymutil $(SYMROOT)/$(LIBCUPS); \ + if test "x$(LIBCUPSIMAGE)" != x; then \ + cp $(LIBCUPSIMAGE) $(SYMROOT); \ + dsymutil $(SYMROOT)/$(LIBCUPSIMAGE); \ + fi; \ fi installstatic: @@ -285,6 +326,9 @@ installstatic: $(INSTALL_LIB) -m 755 $(LIBCUPSSTATIC) $(LIBDIR) $(RANLIB) $(LIBDIR)/$(LIBCUPSSTATIC) $(CHMOD) 555 $(LIBDIR)/$(LIBCUPSSTATIC) + $(INSTALL_LIB) -m 755 libcupsimage.a $(LIBDIR) + $(RANLIB) $(LIBDIR)/libcupsimage.a + $(CHMOD) 555 $(LIBDIR)/libcupsimage.a # @@ -293,15 +337,26 @@ installstatic: uninstall: $(RM) $(LIBDIR)/libcups.2.dylib - $(RM) $(LIBDIR)/$(LIBCUPSSTATIC) + $(RM) $(LIBDIR)/libcups.a $(RM) $(LIBDIR)/libcups.dylib $(RM) $(LIBDIR)/libcups.so $(RM) $(LIBDIR)/libcups.so.2 + $(RM) $(LIBDIR)/libcupsimage.2.dylib + $(RM) $(LIBDIR)/libcupsimage.a + $(RM) $(LIBDIR)/libcupsimage.dylib + $(RM) $(LIBDIR)/libcupsimage.so + $(RM) $(LIBDIR)/libcupsimage.so.2 -$(RMDIR) $(LIBDIR) for file in $(HEADERS); do \ $(RM) $(INCLUDEDIR)/cups/$$file; \ done -$(RMDIR) $(INCLUDEDIR)/cups + if test "x$(privateinclude)" != x; then \ + for file in $(HEADERSPRIV); do \ + $(RM) $(PRIVATEINCLUDE)/cups/$$file; \ + done + $(RMDIR) $(PRIVATEINCLUDE)/cups; \ + fi # @@ -310,8 +365,7 @@ uninstall: libcups.so.2: $(LIBOBJS) echo Linking $@... - $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS) $(LIBGSSAPI) \ - $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(DSO) $(ARCHFLAGS) $(ALL_DSOFLAGS) -o $@ $(LIBOBJS) $(LIBS) $(RM) `basename $@ .2` $(LN) $@ `basename $@ .2` @@ -320,21 +374,15 @@ libcups.so.2: $(LIBOBJS) # libcups.2.dylib # -libcups.2.dylib: $(LIBOBJS) $(LIBCUPSORDER) - echo Creating export list for $@... - nm -gm $(LIBOBJS) 2>/dev/null | grep "__text" | grep -v weak | \ - awk '{print $$NF}' | \ - grep -v -E -e '^(_cupsConnect|_cupsCharset|_cupsEncodingName|_cupsSetDefaults|_cupsSetHTTPError|_cupsUserDefault)$$' | \ - sort >t.exp +libcups.2.dylib: $(LIBOBJS) echo Linking $@... - $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ \ + $(DSO) $(ARCHFLAGS) $(ALL_DSOFLAGS) -o $@ \ -install_name $(libdir)/$@ \ - -current_version 2.12.0 \ + -current_version 2.14.0 \ -compatibility_version 2.0.0 \ - -exported_symbols_list t.exp \ - $(LIBOBJS) $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) \ - $(COMMONLIBS) $(LIBZ) - $(RM) libcups.dylib t.exp + $(LIBOBJS) $(LIBS) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ + $(RM) libcups.dylib $(LN) $@ libcups.dylib @@ -344,9 +392,8 @@ libcups.2.dylib: $(LIBOBJS) $(LIBCUPSORDER) libcups.la: $(LIBOBJS) echo Linking $@... - $(CC) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS:.o=.lo) \ - -rpath $(LIBDIR) -version-info 2:12 $(LIBGSSAPI) $(SSLLIBS) \ - $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(LD_CC) $(ARCHFLAGS) $(ALL_DSOFLAGS) -o $@ $(LIBOBJS:.o=.lo) \ + -rpath $(LIBDIR) -version-info 2:14 $(LIBS) # @@ -364,27 +411,86 @@ libcups.a: $(LIBOBJS) # libcups2.def (Windows DLL exports file...) # -libcups2.def: $(LIBOBJS) Makefile +libcups2.def: $(LIBOBJS) $(IMAGEOBJS) Makefile echo Generating $@... echo "LIBRARY libcups2" >libcups2.def - echo "VERSION 2.12" >>libcups2.def + echo "VERSION 2.14" >>libcups2.def echo "EXPORTS" >>libcups2.def - (nm $(LIBOBJS) 2>/dev/null | grep "T _" | awk '{print $$3}'; \ - echo __cups_strcpy; echo __cups_strlcat; echo __cups_strlcpy) | \ + (nm $(LIBOBJS) $(IMAGEOBJS) 2>/dev/null | grep "T _" | awk '{print $$3}'; \ + echo __cups_strcpy; echo __cups_strlcat; echo __cups_strlcpy; \ + echo __cups_snprintf; echo __cups_vsnprintf; echo __cups_gettimeofday) | \ grep -v -E \ - -e 'cups_debug|Apple|BackChannel|Backend|FileCheck|Filter|GSSService|SetNegotiate|SideChannel' \ + -e 'cups_debug|Apple|BackChannel|Backend|FileCheck|Filter|GSSService|SetNegotiate|SideChannel|SNMP' \ -e 'Block$$' | \ sed -e '1,$$s/^_//' | sort >>libcups2.def +# +# libcupsimage.so.2 +# + +libcupsimage.so.2: $(IMAGEOBJS) libcups.so.2 + echo Linking $@... + $(DSO) $(ARCHFLAGS) $(ALL_DSOFLAGS) -o $@ $(IMAGEOBJS) $(LINKCUPS) + $(RM) `basename $@ .2` + $(LN) $@ `basename $@ .2` + + +# +# libcupsimage.2.dylib +# + +libcupsimage.2.dylib: $(IMAGEOBJS) libcups.2.dylib + echo Linking $@... + $(DSO) $(ARCHFLAGS) $(ALL_DSOFLAGS) -o $@ \ + -install_name $(libdir)/$@ \ + -current_version 2.3.0 \ + -compatibility_version 2.0.0 \ + $(IMAGEOBJS) $(LINKCUPS) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ + $(RM) libcupsimage.dylib + $(LN) $@ libcupsimage.dylib + + +# +# libcupsimage.la +# + +libcupsimage.la: $(IMAGEOBJS) libcups.la + echo Linking $@... + $(DSO) $(ARCHFLAGS) $(ALL_DSOFLAGS) -o $@ $(IMAGEOBJS:.o=.lo) \ + $(LINKCUPS) -rpath $(LIBDIR) -version-info 2:3 + + +# +# libcupsimage.a +# + +libcupsimage.a: $(IMAGEOBJS) + echo Archiving $@... + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(IMAGEOBJS) + $(RANLIB) $@ + + +# +# rasterbench (dependency on static CUPS library is intentional) +# + +rasterbench: rasterbench.o $(LIBCUPSSTATIC) + echo Linking $@... + $(LD_CC) $(ALL_LDFLAGS) -o $@ rasterbench.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ + + # # testadmin (dependency on static CUPS library is intentional) # testadmin: testadmin.o $(LIBCUPSSTATIC) echo Linking $@... - $(CC) $(LDFLAGS) -o $@ testadmin.o $(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(LD_CC) $(ALL_LDFLAGS) -o $@ testadmin.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ # @@ -393,8 +499,8 @@ testadmin: testadmin.o $(LIBCUPSSTATIC) testarray: testarray.o $(LIBCUPSSTATIC) echo Linking $@... - $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testarray.o $(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(LD_CC) $(ARCHFLAGS) $(ALL_LDFLAGS) -o $@ testarray.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ echo Running array API tests... ./testarray @@ -405,8 +511,18 @@ testarray: testarray.o $(LIBCUPSSTATIC) testcache: testcache.o $(LIBCUPSSTATIC) echo Linking $@... - $(CC) $(LDFLAGS) -o $@ testcache.o $(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(LD_CC) $(ALL_LDFLAGS) -o $@ testcache.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ + + +# +# testclient (dependency on static libraries is intentional) +# + +testclient: testclient.o $(LIBCUPSSTATIC) + echo Linking $@... + $(LD_CC) $(ALL_LDFLAGS) -o $@ testclient.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ # @@ -415,8 +531,8 @@ testcache: testcache.o $(LIBCUPSSTATIC) testconflicts: testconflicts.o $(LIBCUPSSTATIC) echo Linking $@... - $(CC) $(LDFLAGS) -o $@ testconflicts.o $(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(LD_CC) $(ALL_LDFLAGS) -o $@ testconflicts.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ # @@ -425,8 +541,8 @@ testconflicts: testconflicts.o $(LIBCUPSSTATIC) testcreds: testcreds.o $(LIBCUPSSTATIC) echo Linking $@... - $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testcreds.o $(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(LD_CC) $(ARCHFLAGS) $(ALL_LDFLAGS) -o $@ testcreds.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ # @@ -435,8 +551,8 @@ testcreds: testcreds.o $(LIBCUPSSTATIC) testcups: testcups.o $(LIBCUPSSTATIC) echo Linking $@... - $(CC) $(LDFLAGS) -o $@ testcups.o $(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(LD_CC) $(ALL_LDFLAGS) -o $@ testcups.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ # @@ -445,8 +561,8 @@ testcups: testcups.o $(LIBCUPSSTATIC) testdest: testdest.o $(LIBCUPSSTATIC) echo Linking $@... - $(CC) $(LDFLAGS) -o $@ testdest.o $(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(LD_CC) $(ALL_LDFLAGS) -o $@ testdest.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ # @@ -455,20 +571,30 @@ testdest: testdest.o $(LIBCUPSSTATIC) testfile: testfile.o $(LIBCUPSSTATIC) echo Linking $@... - $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testfile.o $(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(LD_CC) $(ARCHFLAGS) $(ALL_LDFLAGS) -o $@ testfile.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ echo Running file API tests... ./testfile +# +# testgetdests (dependency on static CUPS library is intentional) +# + +testgetdests: testgetdests.o $(LIBCUPSSTATIC) + echo Linking $@... + $(LD_CC) $(ALL_LDFLAGS) -o $@ testgetdests.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ + + # # testhttp (dependency on static CUPS library is intentional) # testhttp: testhttp.o $(LIBCUPSSTATIC) echo Linking $@... - $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testhttp.o $(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(LD_CC) $(ARCHFLAGS) $(ALL_LDFLAGS) -o $@ testhttp.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ echo Running HTTP API tests... ./testhttp @@ -479,8 +605,8 @@ testhttp: testhttp.o $(LIBCUPSSTATIC) testipp: testipp.o $(LIBCUPSSTATIC) echo Linking $@... - $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testipp.o $(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(LD_CC) $(ARCHFLAGS) $(ALL_LDFLAGS) -o $@ testipp.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ echo Running IPP API tests... ./testipp @@ -491,8 +617,8 @@ testipp: testipp.o $(LIBCUPSSTATIC) testi18n: testi18n.o $(LIBCUPSSTATIC) echo Linking $@... - $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testi18n.o $(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(LD_CC) $(ARCHFLAGS) $(ALL_LDFLAGS) -o $@ testi18n.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ echo Running internationalization API tests... ./testi18n @@ -503,10 +629,17 @@ testi18n: testi18n.o $(LIBCUPSSTATIC) testlang: testlang.o $(LIBCUPSSTATIC) echo Linking $@... - $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testlang.o $(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(LD_CC) $(ARCHFLAGS) $(ALL_LDFLAGS) -o $@ testlang.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ + echo Creating locale directory structure... + $(RM) -r locale + for po in ../locale/cups_*.po; do \ + lang=`basename $$po .po | sed -e '1,$$s/^cups_//'`; \ + $(MKDIR) locale/$$lang; \ + $(LN) ../../$$po locale/$$lang; \ + done echo Running language API tests... - ./testlang + LOCALEDIR=locale ./testlang # @@ -515,8 +648,8 @@ testlang: testlang.o $(LIBCUPSSTATIC) testoptions: testoptions.o $(LIBCUPSSTATIC) echo Linking $@... - $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testoptions.o $(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(LD_CC) $(ARCHFLAGS) $(ALL_LDFLAGS) -o $@ testoptions.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ echo Running option API tests... ./testoptions @@ -527,8 +660,8 @@ testoptions: testoptions.o $(LIBCUPSSTATIC) testppd: testppd.o $(LIBCUPSSTATIC) test.ppd test2.ppd echo Linking $@... - $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testppd.o $(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(LD_CC) $(ARCHFLAGS) $(ALL_LDFLAGS) -o $@ testppd.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ echo Running PPD API tests... ./testppd @@ -539,20 +672,32 @@ testppd: testppd.o $(LIBCUPSSTATIC) test.ppd test2.ppd testpwg: testpwg.o $(LIBCUPSSTATIC) test.ppd echo Linking $@... - $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testpwg.o $(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(LD_CC) $(ARCHFLAGS) $(ALL_LDFLAGS) -o $@ testpwg.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ echo Running PWG API tests... ./testpwg test.ppd +# +# testraster (dependency on static CUPS library is intentional) +# + +testraster: testraster.o $(LIBCUPSSTATIC) + echo Linking $@... + $(LD_CC) $(ARCHFLAGS) $(ALL_LDFLAGS) -o $@ testraster.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ + echo Running raster API tests... + ./testraster + + # # testsnmp (dependency on static CUPS library is intentional) # testsnmp: testsnmp.o $(LIBCUPSSTATIC) echo Linking $@... - $(CC) $(LDFLAGS) -o $@ testsnmp.o $(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(LD_CC) $(ALL_LDFLAGS) -o $@ testsnmp.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ # @@ -561,8 +706,8 @@ testsnmp: testsnmp.o $(LIBCUPSSTATIC) tlscheck: tlscheck.o $(LIBCUPSSTATIC) echo Linking $@... - $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ tlscheck.o $(LIBCUPSSTATIC) \ - $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(LD_CC) $(ARCHFLAGS) $(ALL_LDFLAGS) -o $@ tlscheck.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ # @@ -572,34 +717,34 @@ tlscheck: tlscheck.o $(LIBCUPSSTATIC) apihelp: echo Generating CUPS API help files... $(RM) cupspm.xml - mxmldoc --section "Programming" --body cupspm.md \ + codedoc --section "Programming" --body cupspm.md \ cupspm.xml \ auth.c cups.h dest*.c encode.c http.h http*.c ipp.h ipp*.c \ options.c tls-darwin.c usersys.c util.c \ --coverimage cupspm.png \ --epub ../doc/help/cupspm.epub - mxmldoc --section "Programming" --body cupspm.md \ + codedoc --section "Programming" --body cupspm.md \ cupspm.xml > ../doc/help/cupspm.html $(RM) cupspm.xml - mxmldoc --section "Programming" --title "Administration APIs" \ + codedoc --section "Programming" --title "Administration APIs" \ --css ../doc/cups-printable.css \ - --header api-admin.header --intro api-admin.shtml \ - api-admin.xml \ + --header api-admin.header --body api-admin.shtml \ adminutil.c adminutil.h getdevices.c >../doc/help/api-admin.html - $(RM) api-admin.xml - mxmldoc --section "Programming" --title "PPD API (DEPRECATED)" \ + codedoc --section "Programming" --title "PPD API (DEPRECATED)" \ --css ../doc/cups-printable.css \ - --header api-ppd.header --intro api-ppd.shtml \ - api-ppd.xml ppd.h ppd-*.c >../doc/help/api-ppd.html - $(RM) api-ppd.xml - mxmldoc --section "Programming" \ + --header api-ppd.header --body api-ppd.shtml \ + ppd.h ppd-*.c raster-interstub.c >../doc/help/api-ppd.html + codedoc --section "Programming" --title "Raster API" \ + --css ../doc/cups-printable.css \ + --header api-raster.header --body api-raster.shtml \ + ../cups/raster.h raster-stubs.c \ + >../doc/help/api-raster.html + codedoc --section "Programming" \ --title "Filter and Backend Programming" \ --css ../doc/cups-printable.css \ - --header api-filter.header --intro api-filter.shtml \ - api-filter.xml \ + --header api-filter.header --body api-filter.shtml \ backchannel.c backend.h backend.c sidechannel.c sidechannel.h \ >../doc/help/api-filter.html - $(RM) api-filter.xml # @@ -609,6 +754,8 @@ apihelp: sloc: echo "libcups: \c" sloccount $(LIBOBJS:.o=.c) 2>/dev/null | grep "Total Physical" | awk '{print $$9}' + echo "libcupsimage: \c" + sloccount $(IMAGEOBJS:.o=.c) 2>/dev/null | grep "Total Physical" | awk '{print $$9}' # diff --git a/cups/adminutil.c b/cups/adminutil.c index adb1f7a..7ff5bf2 100644 --- a/cups/adminutil.c +++ b/cups/adminutil.c @@ -1,16 +1,11 @@ /* * Administration utility API definitions for CUPS. * - * Copyright 2007-2016 by Apple Inc. - * Copyright 2001-2007 by Easy Software Products. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 2001-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -18,36 +13,25 @@ */ #include "cups-private.h" +#include "debug-internal.h" #include "ppd.h" #include "adminutil.h" #include #include -#ifdef WIN32 -#else +#ifndef _WIN32 # include # include -#endif /* WIN32 */ +#endif /* !_WIN32 */ /* * Local functions... */ -static int do_samba_command(const char *command, - const char *address, - const char *subcommand, - const char *authfile, - FILE *logfile); static http_status_t get_cupsd_conf(http_t *http, _cups_globals_t *cg, time_t last_update, char *name, size_t namelen, int *remote); static void invalidate_cupsd_cache(_cups_globals_t *cg); -static void write_option(cups_file_t *dstfp, int order, - const char *name, const char *text, - const char *attrname, - ipp_attribute_t *suppattr, - ipp_attribute_t *defattr, int defval, - int valcount); /* @@ -63,318 +47,14 @@ cupsAdminCreateWindowsPPD( char *buffer, /* I - Filename buffer */ int bufsize) /* I - Size of filename buffer */ { - const char *src; /* Source PPD filename */ - cups_file_t *srcfp, /* Source PPD file */ - *dstfp; /* Destination PPD file */ - ipp_t *request, /* IPP request */ - *response; /* IPP response */ - ipp_attribute_t *suppattr, /* IPP -supported attribute */ - *defattr; /* IPP -default attribute */ - cups_lang_t *language; /* Current language */ - char line[256], /* Line from PPD file */ - junk[256], /* Extra junk to throw away */ - *ptr, /* Pointer into line */ - uri[1024], /* Printer URI */ - option[41], /* Option */ - choice[41]; /* Choice */ - int jcloption, /* In a JCL option? */ - jclorder, /* Next JCL order dependency */ - linenum; /* Current line number */ - time_t curtime; /* Current time */ - struct tm *curdate; /* Current date */ - static const char * const pattrs[] = /* Printer attributes we want */ - { - "job-hold-until-supported", - "job-hold-until-default", - "job-sheets-supported", - "job-sheets-default", - "job-priority-supported", - "job-priority-default" - }; - - - /* - * Range check the input... - */ + (void)http; + (void)dest; + (void)bufsize; if (buffer) *buffer = '\0'; - if (!http) - http = _cupsConnect(); - - if (!http || !dest || !buffer || bufsize < 2) - return (NULL); - - /* - * Get the PPD file... - */ - - if ((src = cupsGetPPD2(http, dest)) == NULL) - return (NULL); - - /* - * Get the supported banner pages, etc. for the printer... - */ - - request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES); - - httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, - "localhost", 0, "/printers/%s", dest); - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, - "printer-uri", NULL, uri); - - 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... - */ - - response = cupsDoRequest(http, request, "/"); - if (!response || cupsLastError() > IPP_STATUS_OK_CONFLICTING) - { - unlink(src); - return (NULL); - } - - /* - * Open the original PPD file... - */ - - if ((srcfp = cupsFileOpen(src, "rb")) == NULL) - return (NULL); - - /* - * Create a temporary output file using the destination buffer... - */ - - if ((dstfp = cupsTempFile2(buffer, bufsize)) == NULL) - { - cupsFileClose(srcfp); - - unlink(src); - - return (NULL); - } - - /* - * Write a new header explaining that this isn't the original PPD... - */ - - cupsFilePuts(dstfp, "*PPD-Adobe: \"4.3\"\n"); - - curtime = time(NULL); - curdate = gmtime(&curtime); - - cupsFilePrintf(dstfp, "*%% Modified on %04d%02d%02d%02d%02d%02d+0000 " - "for CUPS Windows Driver\n", - curdate->tm_year + 1900, curdate->tm_mon + 1, curdate->tm_mday, - curdate->tm_hour, curdate->tm_min, curdate->tm_sec); - - /* - * Read the existing PPD file, converting all PJL commands to CUPS - * job ticket comments... - */ - - jcloption = 0; - jclorder = 0; - linenum = 0; - language = cupsLangDefault(); - - while (cupsFileGets(srcfp, line, sizeof(line))) - { - linenum ++; - - if (!strncmp(line, "*PPD-Adobe:", 11)) - { - /* - * Already wrote the PPD header... - */ - - continue; - } - else if (!strncmp(line, "*JCLBegin:", 10) || - !strncmp(line, "*JCLToPSInterpreter:", 20) || - !strncmp(line, "*JCLEnd:", 8) || - !strncmp(line, "*Protocols:", 11)) - { - /* - * Don't use existing JCL keywords; we'll create our own, below... - */ - - cupsFilePrintf(dstfp, "*%% Commented out for CUPS Windows Driver...\n" - "*%%%s\n", line + 1); - continue; - } - else if (!strncmp(line, "*JCLOpenUI", 10)) - { - jcloption = 1; - cupsFilePrintf(dstfp, "%s\n", line); - } - else if (!strncmp(line, "*JCLCloseUI", 11)) - { - jcloption = 0; - cupsFilePrintf(dstfp, "%s\n", line); - } - else if (jcloption && !strncmp(line, "*OrderDependency:", 17)) - { - for (ptr = line + 17; _cups_isspace(*ptr); ptr ++); - - ptr = strchr(ptr, ' '); - - if (ptr) - { - cupsFilePrintf(dstfp, "*OrderDependency: %d%s\n", jclorder, ptr); - jclorder ++; - } - else - cupsFilePrintf(dstfp, "%s\n", line); - } - else if (jcloption && - strncmp(line, "*End", 4) && - strncmp(line, "*Default", 8)) - { - if ((ptr = strchr(line, ':')) == NULL) - { - snprintf(line, sizeof(line), - _cupsLangString(language, _("Missing value on line %d.")), - linenum); - _cupsSetError(IPP_STATUS_ERROR_DOCUMENT_FORMAT_ERROR, line, 0); - - cupsFileClose(srcfp); - cupsFileClose(dstfp); - - unlink(src); - unlink(buffer); - - *buffer = '\0'; - - return (NULL); - } - - if ((ptr = strchr(ptr, '\"')) == NULL) - { - snprintf(line, sizeof(line), - _cupsLangString(language, - _("Missing double quote on line %d.")), - linenum); - _cupsSetError(IPP_STATUS_ERROR_DOCUMENT_FORMAT_ERROR, line, 0); - - cupsFileClose(srcfp); - cupsFileClose(dstfp); - - unlink(src); - unlink(buffer); - - *buffer = '\0'; - - return (NULL); - } - - if (sscanf(line, "*%40s%*[ \t]%40[^:/]", option, choice) != 2) - { - snprintf(line, sizeof(line), - _cupsLangString(language, - _("Bad option + choice on line %d.")), - linenum); - _cupsSetError(IPP_STATUS_ERROR_DOCUMENT_FORMAT_ERROR, line, 0); - - cupsFileClose(srcfp); - cupsFileClose(dstfp); - - unlink(src); - unlink(buffer); - - *buffer = '\0'; - - return (NULL); - } - - if (strchr(ptr + 1, '\"') == NULL) - { - /* - * Skip remaining... - */ - - while (cupsFileGets(srcfp, junk, sizeof(junk)) != NULL) - { - linenum ++; - - if (!strncmp(junk, "*End", 4)) - break; - } - } - - snprintf(ptr + 1, sizeof(line) - (size_t)(ptr - line + 1), - "%%cupsJobTicket: %s=%s\n\"\n*End", option, choice); - - cupsFilePrintf(dstfp, "*%% Changed for CUPS Windows Driver...\n%s\n", - line); - } - else - cupsFilePrintf(dstfp, "%s\n", line); - } - - cupsFileClose(srcfp); - unlink(src); - - if (linenum == 0) - { - _cupsSetError(IPP_STATUS_ERROR_DOCUMENT_FORMAT_ERROR, _("Empty PPD file."), 1); - - cupsFileClose(dstfp); - unlink(buffer); - - *buffer = '\0'; - - return (NULL); - } - - /* - * Now add the CUPS-specific attributes and options... - */ - - cupsFilePuts(dstfp, "\n*% CUPS Job Ticket support and options...\n"); - cupsFilePuts(dstfp, "*Protocols: PJL\n"); - cupsFilePuts(dstfp, "*JCLBegin: \"%!PS-Adobe-3.0<0A>\"\n"); - cupsFilePuts(dstfp, "*JCLToPSInterpreter: \"\"\n"); - cupsFilePuts(dstfp, "*JCLEnd: \"\"\n"); - - cupsFilePuts(dstfp, "\n*OpenGroup: CUPS/CUPS Options\n\n"); - - if ((defattr = ippFindAttribute(response, "job-hold-until-default", - IPP_TAG_ZERO)) != NULL && - (suppattr = ippFindAttribute(response, "job-hold-until-supported", - IPP_TAG_ZERO)) != NULL) - write_option(dstfp, jclorder ++, "cupsJobHoldUntil", "Hold Until", - "job-hold-until", suppattr, defattr, 0, 1); - - if ((defattr = ippFindAttribute(response, "job-priority-default", - IPP_TAG_INTEGER)) != NULL && - (suppattr = ippFindAttribute(response, "job-priority-supported", - IPP_TAG_RANGE)) != NULL) - write_option(dstfp, jclorder ++, "cupsJobPriority", "Priority", - "job-priority", suppattr, defattr, 0, 1); - - if ((defattr = ippFindAttribute(response, "job-sheets-default", - IPP_TAG_ZERO)) != NULL && - (suppattr = ippFindAttribute(response, "job-sheets-supported", - IPP_TAG_ZERO)) != NULL) - { - write_option(dstfp, jclorder ++, "cupsJobSheetsStart", "Start Banner", - "job-sheets", suppattr, defattr, 0, 2); - write_option(dstfp, jclorder, "cupsJobSheetsEnd", "End Banner", - "job-sheets", suppattr, defattr, 1, 2); - } - - cupsFilePuts(dstfp, "*CloseGroup: CUPS\n"); - cupsFileClose(dstfp); - - ippDelete(response); - - return (buffer); + return (NULL); } @@ -393,435 +73,14 @@ cupsAdminExportSamba( const char *samba_password, /* I - Samba password */ FILE *logfile) /* I - Log file, if any */ { - int status; /* Status of Samba commands */ - int have_drivers; /* Have drivers? */ - char file[1024], /* File to test for */ - authfile[1024], /* Temporary authentication file */ - address[1024], /* Address for command */ - subcmd[1024], /* Sub-command */ - message[1024]; /* Error message */ - cups_file_t *fp; /* Authentication file */ - cups_lang_t *language; /* Current language */ - _cups_globals_t *cg = _cupsGlobals(); - /* Global data */ - - - /* - * Range check input... - */ - - if (!dest || !ppd || !samba_server || !samba_user || !samba_password) - { - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); - return (0); - } - - /* - * Create a temporary authentication file for Samba... - */ - - if ((fp = cupsTempFile2(authfile, sizeof(authfile))) == NULL) - { - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, NULL, 0); - return (0); - } - - cupsFilePrintf(fp, "username = %s\n", samba_user); - cupsFilePrintf(fp, "password = %s\n", samba_password); - cupsFileClose(fp); - - /* - * See which drivers are available; the new CUPS v6 and Adobe drivers - * depend on the Windows 2k PS driver, so copy that driver first: - * - * Files: - * - * ps5ui.dll - * pscript.hlp - * pscript.ntf - * pscript5.dll - */ - - have_drivers = 0; - language = cupsLangDefault(); - - snprintf(file, sizeof(file), "%s/drivers/pscript5.dll", cg->cups_datadir); - if (!access(file, 0)) - { - have_drivers |= 1; - - /* - * Windows 2k driver is installed; do the smbclient commands needed - * to copy the Win2k drivers over... - */ - - snprintf(address, sizeof(address), "//%s/print$", samba_server); - - snprintf(subcmd, sizeof(subcmd), - "mkdir W32X86;" - "put %s W32X86/%s.ppd;" - "put %s/drivers/ps5ui.dll W32X86/ps5ui.dll;" - "put %s/drivers/pscript.hlp W32X86/pscript.hlp;" - "put %s/drivers/pscript.ntf W32X86/pscript.ntf;" - "put %s/drivers/pscript5.dll W32X86/pscript5.dll", - ppd, dest, cg->cups_datadir, cg->cups_datadir, - cg->cups_datadir, cg->cups_datadir); - - if ((status = do_samba_command("smbclient", address, subcmd, - authfile, logfile)) != 0) - { - snprintf(message, sizeof(message), - _cupsLangString(language, - _("Unable to copy Windows 2000 printer " - "driver files (%d).")), status); - - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, message, 0); - - if (logfile) - _cupsLangPuts(logfile, message); - - unlink(authfile); - - return (0); - } - - /* - * See if we also have the CUPS driver files; if so, use them! - */ - - snprintf(file, sizeof(file), "%s/drivers/cupsps6.dll", cg->cups_datadir); - if (!access(file, 0)) - { - /* - * Copy the CUPS driver files over... - */ - - snprintf(subcmd, sizeof(subcmd), - "put %s/drivers/cups6.ini W32X86/cups6.ini;" - "put %s/drivers/cupsps6.dll W32X86/cupsps6.dll;" - "put %s/drivers/cupsui6.dll W32X86/cupsui6.dll", - cg->cups_datadir, cg->cups_datadir, cg->cups_datadir); - - if ((status = do_samba_command("smbclient", address, subcmd, - authfile, logfile)) != 0) - { - snprintf(message, sizeof(message), - _cupsLangString(language, - _("Unable to copy CUPS printer driver " - "files (%d).")), status); - - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, message, 0); - - if (logfile) - _cupsLangPuts(logfile, message); - - unlink(authfile); - - return (0); - } - - /* - * Do the rpcclient command needed for the CUPS drivers... - */ - - snprintf(subcmd, sizeof(subcmd), - "adddriver \"Windows NT x86\" \"%s:" - "pscript5.dll:%s.ppd:ps5ui.dll:pscript.hlp:NULL:RAW:" - "pscript5.dll,%s.ppd,ps5ui.dll,pscript.hlp,pscript.ntf," - "cups6.ini,cupsps6.dll,cupsui6.dll\"", - dest, dest, dest); - } - else - { - /* - * Don't have the CUPS drivers, so just use the standard Windows - * drivers... - */ - - snprintf(subcmd, sizeof(subcmd), - "adddriver \"Windows NT x86\" \"%s:" - "pscript5.dll:%s.ppd:ps5ui.dll:pscript.hlp:NULL:RAW:" - "pscript5.dll,%s.ppd,ps5ui.dll,pscript.hlp,pscript.ntf\"", - dest, dest, dest); - } - - if ((status = do_samba_command("rpcclient", samba_server, subcmd, - authfile, logfile)) != 0) - { - snprintf(message, sizeof(message), - _cupsLangString(language, - _("Unable to install Windows 2000 printer " - "driver files (%d).")), status); - - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, message, 0); - - if (logfile) - _cupsLangPuts(logfile, message); - - unlink(authfile); - - return (0); - } - } - - /* - * See if we have the Win9x PS driver... - */ - - snprintf(file, sizeof(file), "%s/drivers/ADOBEPS4.DRV", cg->cups_datadir); - if (!access(file, 0)) - { - have_drivers |= 2; - - /* - * Do the smbclient commands needed for the Adobe Win9x drivers... - */ - - snprintf(address, sizeof(address), "//%s/print$", samba_server); - - snprintf(subcmd, sizeof(subcmd), - "mkdir WIN40;" - "put %s WIN40/%s.PPD;" - "put %s/drivers/ADFONTS.MFM WIN40/ADFONTS.MFM;" - "put %s/drivers/ADOBEPS4.DRV WIN40/ADOBEPS4.DRV;" - "put %s/drivers/ADOBEPS4.HLP WIN40/ADOBEPS4.HLP;" - "put %s/drivers/ICONLIB.DLL WIN40/ICONLIB.DLL;" - "put %s/drivers/PSMON.DLL WIN40/PSMON.DLL;", - ppd, dest, cg->cups_datadir, cg->cups_datadir, - cg->cups_datadir, cg->cups_datadir, cg->cups_datadir); - - if ((status = do_samba_command("smbclient", address, subcmd, - authfile, logfile)) != 0) - { - snprintf(message, sizeof(message), - _cupsLangString(language, - _("Unable to copy Windows 9x printer " - "driver files (%d).")), status); - - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, message, 0); - - if (logfile) - _cupsLangPuts(logfile, message); - - unlink(authfile); - - return (0); - } - - /* - * Do the rpcclient commands needed for the Adobe Win9x drivers... - */ - - snprintf(subcmd, sizeof(subcmd), - "adddriver \"Windows 4.0\" \"%s:ADOBEPS4.DRV:%s.PPD:NULL:" - "ADOBEPS4.HLP:PSMON.DLL:RAW:" - "ADOBEPS4.DRV,%s.PPD,ADOBEPS4.HLP,PSMON.DLL,ADFONTS.MFM," - "ICONLIB.DLL\"", - dest, dest, dest); - - if ((status = do_samba_command("rpcclient", samba_server, subcmd, - authfile, logfile)) != 0) - { - snprintf(message, sizeof(message), - _cupsLangString(language, - _("Unable to install Windows 9x printer " - "driver files (%d).")), status); - - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, message, 0); - - if (logfile) - _cupsLangPuts(logfile, message); - - unlink(authfile); - - return (0); - } - } - - /* - * See if we have the 64-bit Windows PS driver... - * - * Files: - * - * x64/ps5ui.dll - * x64/pscript.hlp - * x64/pscript.ntf - * x64/pscript5.dll - */ - - snprintf(file, sizeof(file), "%s/drivers/x64/pscript5.dll", cg->cups_datadir); - if (!access(file, 0)) - { - have_drivers |= 4; - - /* - * 64-bit Windows driver is installed; do the smbclient commands needed - * to copy the Win64 drivers over... - */ - - snprintf(address, sizeof(address), "//%s/print$", samba_server); - - snprintf(subcmd, sizeof(subcmd), - "mkdir x64;" - "put %s x64/%s.ppd;" - "put %s/drivers/x64/ps5ui.dll x64/ps5ui.dll;" - "put %s/drivers/x64/pscript.hlp x64/pscript.hlp;" - "put %s/drivers/x64/pscript.ntf x64/pscript.ntf;" - "put %s/drivers/x64/pscript5.dll x64/pscript5.dll", - ppd, dest, cg->cups_datadir, cg->cups_datadir, - cg->cups_datadir, cg->cups_datadir); - - if ((status = do_samba_command("smbclient", address, subcmd, - authfile, logfile)) != 0) - { - snprintf(message, sizeof(message), - _cupsLangString(language, - _("Unable to copy 64-bit Windows printer " - "driver files (%d).")), status); - - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, message, 0); - - if (logfile) - _cupsLangPuts(logfile, message); - - unlink(authfile); - - return (0); - } - - /* - * See if we also have the CUPS driver files; if so, use them! - */ - - snprintf(file, sizeof(file), "%s/drivers/x64/cupsps6.dll", cg->cups_datadir); - if (!access(file, 0)) - { - /* - * Copy the CUPS driver files over... - */ - - snprintf(subcmd, sizeof(subcmd), - "put %s/drivers/x64/cups6.ini x64/cups6.ini;" - "put %s/drivers/x64/cupsps6.dll x64/cupsps6.dll;" - "put %s/drivers/x64/cupsui6.dll x64/cupsui6.dll", - cg->cups_datadir, cg->cups_datadir, cg->cups_datadir); - - if ((status = do_samba_command("smbclient", address, subcmd, - authfile, logfile)) != 0) - { - snprintf(message, sizeof(message), - _cupsLangString(language, - _("Unable to copy 64-bit CUPS printer driver " - "files (%d).")), status); - - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, message, 0); - - if (logfile) - _cupsLangPuts(logfile, message); - - unlink(authfile); - - return (0); - } - - /* - * Do the rpcclient command needed for the CUPS drivers... - */ - - snprintf(subcmd, sizeof(subcmd), - "adddriver \"Windows x64\" \"%s:" - "pscript5.dll:%s.ppd:ps5ui.dll:pscript.hlp:NULL:RAW:" - "pscript5.dll,%s.ppd,ps5ui.dll,pscript.hlp,pscript.ntf," - "cups6.ini,cupsps6.dll,cupsui6.dll\"", - dest, dest, dest); - } - else - { - /* - * Don't have the CUPS drivers, so just use the standard Windows - * drivers... - */ - - snprintf(subcmd, sizeof(subcmd), - "adddriver \"Windows x64\" \"%s:" - "pscript5.dll:%s.ppd:ps5ui.dll:pscript.hlp:NULL:RAW:" - "pscript5.dll,%s.ppd,ps5ui.dll,pscript.hlp,pscript.ntf\"", - dest, dest, dest); - } - - if ((status = do_samba_command("rpcclient", samba_server, subcmd, - authfile, logfile)) != 0) - { - snprintf(message, sizeof(message), - _cupsLangString(language, - _("Unable to install Windows 2000 printer " - "driver files (%d).")), status); - - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, message, 0); - - if (logfile) - _cupsLangPuts(logfile, message); - - unlink(authfile); - - return (0); - } - } - - if (logfile && !(have_drivers & 1)) - { - if (!have_drivers) - strlcpy(message, - _cupsLangString(language, - _("No Windows printer drivers are installed.")), - sizeof(message)); - else - strlcpy(message, - _cupsLangString(language, - _("Warning, no Windows 2000 printer drivers " - "are installed.")), - sizeof(message)); - - _cupsSetError(IPP_STATUS_ERROR_NOT_FOUND, message, 0); - _cupsLangPuts(logfile, message); - } - - if (have_drivers == 0) - { - _cupsSetError(IPP_STATUS_ERROR_NOT_FOUND, message, 0); - - unlink(authfile); - - return (0); - } - - /* - * Finally, associate the drivers we just added with the queue... - */ - - snprintf(subcmd, sizeof(subcmd), "setdriver %s %s", dest, dest); - - if ((status = do_samba_command("rpcclient", samba_server, subcmd, - authfile, logfile)) != 0) - { - snprintf(message, sizeof(message), - _cupsLangString(language, - _("Unable to set Windows printer driver (%d).")), - status); - - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, message, 0); - - if (logfile) - _cupsLangPuts(logfile, message); - - unlink(authfile); - - return (0); - } - - unlink(authfile); - - return (1); + (void)dest; + (void)ppd; + (void)samba_server; + (void)samba_user; + (void)samba_password; + (void)logfile; + + return (0); } @@ -2076,88 +1335,6 @@ cupsAdminSetServerSettings( } -/* - * 'do_samba_command()' - Do a SAMBA command. - */ - -static int /* O - Status of command */ -do_samba_command(const char *command, /* I - Command to run */ - const char *address, /* I - Address for command */ - const char *subcmd, /* I - Sub-command */ - const char *authfile, /* I - Samba authentication file */ - FILE *logfile) /* I - Optional log file */ -{ -#ifdef WIN32 - return (1); /* Always fail on Windows... */ - -#else - int status; /* Status of command */ - int pid; /* Process ID of child */ - - - if (logfile) - _cupsLangPrintf(logfile, - _("Running command: %s %s -N -A %s -c \'%s\'"), - command, address, authfile, subcmd); - - if ((pid = fork()) == 0) - { - /* - * Child goes here, redirect stdin/out/err and execute the command... - */ - - int fd = open("/dev/null", O_RDONLY); - - if (fd > 0) - { - dup2(fd, 0); - close(fd); - } - - if (logfile) - dup2(fileno(logfile), 1); - else if ((fd = open("/dev/null", O_WRONLY)) > 1) - { - dup2(fd, 1); - close(fd); - } - - dup2(1, 2); - - execlp(command, command, address, "-N", "-A", authfile, "-c", subcmd, - (char *)0); - exit(errno); - } - else if (pid < 0) - { - status = -1; - - if (logfile) - _cupsLangPrintf(logfile, _("Unable to run \"%s\": %s"), - command, strerror(errno)); - } - else - { - /* - * Wait for the process to complete... - */ - - while (wait(&status) != pid); - } - - if (logfile) - _cupsLangPuts(logfile, ""); - - DEBUG_printf(("9do_samba_command: status=%d", status)); - - if (WIFEXITED(status)) - return (WEXITSTATUS(status)); - else - return (-WTERMSIG(status)); -#endif /* WIN32 */ -} - - /* * 'get_cupsd_conf()' - Get the current cupsd.conf file. */ @@ -2172,9 +1349,9 @@ get_cupsd_conf( int *remote) /* O - Remote file? */ { int fd; /* Temporary file descriptor */ -#ifndef WIN32 +#ifndef _WIN32 struct stat info; /* cupsd.conf file information */ -#endif /* WIN32 */ +#endif /* _WIN32 */ http_status_t status; /* Status of getting cupsd.conf */ char host[HTTP_MAX_HOST]; /* Hostname for connection */ @@ -2191,7 +1368,7 @@ get_cupsd_conf( snprintf(name, namesize, "%s/cupsd.conf", cg->cups_serverroot); *remote = 0; -#ifndef WIN32 +#ifndef _WIN32 if (!_cups_strcasecmp(host, "localhost") && !access(name, R_OK)) { /* @@ -2218,7 +1395,7 @@ get_cupsd_conf( status = HTTP_STATUS_OK; } else -#endif /* !WIN32 */ +#endif /* !_WIN32 */ { /* * Read cupsd.conf via a HTTP GET request... @@ -2273,112 +1450,3 @@ invalidate_cupsd_cache( cg->cupsd_num_settings = 0; cg->cupsd_settings = NULL; } - - -/* - * 'write_option()' - Write a CUPS option to a PPD file. - */ - -static void -write_option(cups_file_t *dstfp, /* I - PPD file */ - int order, /* I - Order dependency */ - const char *name, /* I - Option name */ - const char *text, /* I - Option text */ - const char *attrname, /* I - Attribute name */ - ipp_attribute_t *suppattr, /* I - IPP -supported attribute */ - ipp_attribute_t *defattr, /* I - IPP -default attribute */ - int defval, /* I - Default value number */ - int valcount) /* I - Number of values */ -{ - int i; /* Looping var */ - - - cupsFilePrintf(dstfp, "*JCLOpenUI *%s/%s: PickOne\n" - "*OrderDependency: %d JCLSetup *%s\n", - name, text, order, name); - - if (defattr->value_tag == IPP_TAG_INTEGER) - { - /* - * Do numeric options with a range or list... - */ - - cupsFilePrintf(dstfp, "*Default%s: %d\n", name, - defattr->values[defval].integer); - - if (suppattr->value_tag == IPP_TAG_RANGE) - { - /* - * List each number in the range... - */ - - for (i = suppattr->values[0].range.lower; - i <= suppattr->values[0].range.upper; - i ++) - { - cupsFilePrintf(dstfp, "*%s %d: \"", name, i); - - if (valcount == 1) - cupsFilePrintf(dstfp, "%%cupsJobTicket: %s=%d\n\"\n*End\n", - attrname, i); - else if (defval == 0) - cupsFilePrintf(dstfp, "%%cupsJobTicket: %s=%d\"\n", attrname, i); - else if (defval < (valcount - 1)) - cupsFilePrintf(dstfp, ",%d\"\n", i); - else - cupsFilePrintf(dstfp, ",%d\n\"\n*End\n", i); - } - } - else - { - /* - * List explicit numbers... - */ - - for (i = 0; i < suppattr->num_values; i ++) - { - cupsFilePrintf(dstfp, "*%s %d: \"", name, suppattr->values[i].integer); - - if (valcount == 1) - cupsFilePrintf(dstfp, "%%cupsJobTicket: %s=%d\n\"\n*End\n", attrname, - suppattr->values[i].integer); - else if (defval == 0) - cupsFilePrintf(dstfp, "%%cupsJobTicket: %s=%d\"\n", attrname, - suppattr->values[i].integer); - else if (defval < (valcount - 1)) - cupsFilePrintf(dstfp, ",%d\"\n", suppattr->values[i].integer); - else - cupsFilePrintf(dstfp, ",%d\n\"\n*End\n", suppattr->values[i].integer); - } - } - } - else - { - /* - * Do text options with a list... - */ - - cupsFilePrintf(dstfp, "*Default%s: %s\n", name, - defattr->values[defval].string.text); - - for (i = 0; i < suppattr->num_values; i ++) - { - cupsFilePrintf(dstfp, "*%s %s: \"", name, - suppattr->values[i].string.text); - - if (valcount == 1) - cupsFilePrintf(dstfp, "%%cupsJobTicket: %s=%s\n\"\n*End\n", attrname, - suppattr->values[i].string.text); - else if (defval == 0) - cupsFilePrintf(dstfp, "%%cupsJobTicket: %s=%s\"\n", attrname, - suppattr->values[i].string.text); - else if (defval < (valcount - 1)) - cupsFilePrintf(dstfp, ",%s\"\n", suppattr->values[i].string.text); - else - cupsFilePrintf(dstfp, ",%s\n\"\n*End\n", - suppattr->values[i].string.text); - } - } - - cupsFilePrintf(dstfp, "*JCLCloseUI: *%s\n\n", name); -} diff --git a/cups/adminutil.h b/cups/adminutil.h index 23f7978..c3c0dc3 100644 --- a/cups/adminutil.h +++ b/cups/adminutil.h @@ -4,13 +4,7 @@ * Copyright 2007-2016 by Apple Inc. * Copyright 2001-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ #ifndef _CUPS_ADMINUTIL_H_ @@ -83,7 +77,7 @@ extern ipp_status_t cupsGetDevices(http_t *http, int timeout, const char *include_schemes, const char *exclude_schemes, cups_device_cb_t callback, - void *user_data) _CUPS_API_1_4; + void *user_data) _CUPS_DEPRECATED; # ifdef __cplusplus diff --git a/cups/api-admin.header b/cups/api-admin.header index a3ce3b1..73625c6 100644 --- a/cups/api-admin.header +++ b/cups/api-admin.header @@ -1,13 +1,10 @@

Administrative APIs

diff --git a/cups/api-admin.shtml b/cups/api-admin.shtml index 8928e47..ab00c9b 100644 --- a/cups/api-admin.shtml +++ b/cups/api-admin.shtml @@ -1,20 +1,17 @@

Overview

The administrative APIs provide convenience functions to perform certain administrative functions with the CUPS scheduler.

-
Note: +
Note:

Administrative functions normally require administrative privileges to execute and must not be used in ordinary user applications!

diff --git a/cups/api-array.header b/cups/api-array.header deleted file mode 100644 index 557833e..0000000 --- a/cups/api-array.header +++ /dev/null @@ -1,32 +0,0 @@ - - -

Array API

- -
- - - - - - - - - - - - - - - - -
Headercups/array.h
Library-lcups
See AlsoProgramming: Introduction to CUPS Programming
diff --git a/cups/api-array.shtml b/cups/api-array.shtml deleted file mode 100644 index 374ef5b..0000000 --- a/cups/api-array.shtml +++ /dev/null @@ -1,194 +0,0 @@ - - -

Overview

- -

The CUPS array API provides a high-performance generic array container. -The contents of the array container can be sorted and the container itself is -designed for optimal speed and memory usage under a wide variety of conditions. -Sorted arrays use a binary search algorithm from the last found or inserted -element to quickly find matching elements in the array. Arrays created with the -optional hash function can often find elements with a single lookup. The -cups_array_t type is used when -referring to a CUPS array.

- -

The CUPS scheduler (cupsd) and many of the CUPS API -functions use the array API to efficiently manage large lists of -data.

- -

Managing Arrays

- -

Arrays are created using either the -cupsArrayNew, -cupsArrayNew2, or -cupsArrayNew3 functions. The -first function creates a new array with the specified callback function -and user data pointer:

- -
-#include <cups/array.h>
-
-static int compare_func(void *first, void *second, void *user_data);
-
-void *user_data;
-cups_array_t *array = cupsArrayNew(compare_func, user_data);
-
- -

The comparison function (type -cups_arrayfunc_t) is called -whenever an element is added to the array and can be NULL to -create an unsorted array. The function returns -1 if the first element should -come before the second, 0 if the first and second elements should have the same -ordering, and 1 if the first element should come after the second.

- -

The "user_data" pointer is passed to your comparison function. Pass -NULL if you do not need to associate the elements in your array -with additional information.

- -

The cupsArrayNew2 function adds -two more arguments to support hashed lookups, which can potentially provide -instantaneous ("O(1)") lookups in your array:

- -
-#include <cups/array.h>
-
-#define HASH_SIZE 512 /* Size of hash table */
-
-static int compare_func(void *first, void *second, void *user_data);
-static int hash_func(void *element, void *user_data);
-
-void *user_data;
-cups_array_t *hash_array = cupsArrayNew2(compare_func, user_data, hash_func, HASH_SIZE);
-
- -

The hash function (type -cups_ahash_func_t) should return a -number from 0 to (hash_size-1) that (hopefully) uniquely identifies the -element and is called whenever you look up an element in the array with -cupsArrayFind. The hash size is -only limited by available memory, but generally should not be larger than -16384 to realize any performance improvement.

- -

The cupsArrayNew3 function adds -copy and free callbacks to support basic memory management of elements:

- -
-#include <cups/array.h>
-
-#define HASH_SIZE 512 /* Size of hash table */
-
-static int compare_func(void *first, void *second, void *user_data);
-static void *copy_func(void *element, void *user_data);
-static void free_func(void *element, void *user_data);
-static int hash_func(void *element, void *user_data);
-
-void *user_data;
-cups_array_t *array = cupsArrayNew3(compare_func, user_data, NULL, 0, copy_func, free_func);
-
-cups_array_t *hash_array = cupsArrayNew3(compare_func, user_data, hash_func, HASH_SIZE, copy_func, free_func);
-
- -

Once you have created the array, you add elements using the -cupsArrayAdd -cupsArrayInsert functions. -The first function adds an element to the array, adding the new element -after any elements that have the same order, while the second inserts the -element before others with the same order. For unsorted arrays, -cupsArrayAdd appends the element to -the end of the array while -cupsArrayInsert inserts the -element at the beginning of the array. For example, the following code -creates a sorted array of character strings:

- -
-#include <cups/array.h>
-
-/* Use strcmp() to compare strings - it will ignore the user_data pointer */
-cups_array_t *array = cupsArrayNew((cups_array_func_t)strcmp, NULL);
-
-/* Add four strings to the array */
-cupsArrayAdd(array, "One Fish");
-cupsArrayAdd(array, "Two Fish");
-cupsArrayAdd(array, "Red Fish");
-cupsArrayAdd(array, "Blue Fish");
-
- -

Elements are removed using the -cupsArrayRemove function, for -example:

- -
-#include <cups/array.h>
-
-/* Use strcmp() to compare strings - it will ignore the user_data pointer */
-cups_array_t *array = cupsArrayNew((cups_array_func_t)strcmp, NULL);
-
-/* Add four strings to the array */
-cupsArrayAdd(array, "One Fish");
-cupsArrayAdd(array, "Two Fish");
-cupsArrayAdd(array, "Red Fish");
-cupsArrayAdd(array, "Blue Fish");
-
-/* Remove "Red Fish" */
-cupsArrayRemove(array, "Red Fish");
-
- -

Finally, you free the memory used by the array using the -cupsArrayDelete function. All -of the memory for the array and hash table (if any) is freed, however CUPS -does not free the elements unless you provide copy and free functions.

- -

Finding and Enumerating Elements

- -

CUPS provides several functions to find and enumerate elements in an -array. Each one sets or updates a "current index" into the array, such that -future lookups will start where the last one left off:

- -
-
cupsArrayFind
-
Returns the first matching element.
-
cupsArrayFirst
-
Returns the first element in the array.
-
cupsArrayIndex
-
Returns the Nth element in the array, starting at 0.
-
cupsArrayLast
-
Returns the last element in the array.
-
cupsArrayNext
-
Returns the next element in the array.
-
cupsArrayPrev
-
Returns the previous element in the array.
-
- -

Each of these functions returns NULL when there is no -corresponding element. For example, a simple for loop using the -cupsArrayFirst and -cupsArrayNext functions will -enumerate all of the strings in our previous example:

- -
-#include <cups/array.h>
-
-/* Use strcmp() to compare strings - it will ignore the user_data pointer */
-cups_array_t *array = cupsArrayNew((cups_array_func_t)strcmp, NULL);
-
-/* Add four strings to the array */
-cupsArrayAdd(array, "One Fish");
-cupsArrayAdd(array, "Two Fish");
-cupsArrayAdd(array, "Red Fish");
-cupsArrayAdd(array, "Blue Fish");
-
-/* Show all of the strings in the array */
-char *s;
-for (s = (char *)cupsArrayFirst(array); s != NULL; s = (char *)cupsArrayNext(array))
-  puts(s);
-
diff --git a/cups/api-cups.header b/cups/api-cups.header deleted file mode 100644 index 23b3794..0000000 --- a/cups/api-cups.header +++ /dev/null @@ -1,38 +0,0 @@ - - -

CUPS API

- -
- - - - - - - - - - - - - - - - -
Headercups/cups.h
Library-lcups
See AlsoProgramming: Introduction to CUPS Programming
- Programming: Array API
- Programming: File and Directory APIs
- Programming: Filter and Backend Programming
- Programming: HTTP and IPP APIs
- Programming: PPD API
- Programming: Raster API
diff --git a/cups/api-cups.shtml b/cups/api-cups.shtml deleted file mode 100644 index 918efe7..0000000 --- a/cups/api-cups.shtml +++ /dev/null @@ -1,441 +0,0 @@ - - -

Overview

- -

The CUPS API provides the convenience functions needed to support -applications, filters, printer drivers, and backends that need to interface -with the CUPS scheduler.

- -

Clients and Servers

- -

CUPS is based on the Internet Printing Protocol ("IPP"), which allows -clients (applications) to communicate with a server (the scheduler) to get a -list of printers, send print jobs, and so forth. You identify which server -you want to communicate with using a pointer to the opaque structure -http_t. All of the examples in this document use the -CUPS_HTTP_DEFAULT constant, referring to the default connection -to the scheduler. The HTTP and IPP -APIs document provides more information on server connections.

- -

Printers and Classes

- -

Printers and classes (collections of printers) are accessed through -the cups_dest_t structure which -includes the name (name), instance (instance - -a way of selecting certain saved options/settings), and the options and -attributes associated with that destination (num_options and -options). Destinations are created using the -cupsGetDests function and freed -using the cupsFreeDests function. -The cupsGetDest function finds a -specific destination for printing:

- -
-#include <cups/cups.h>
-
-cups_dest_t *dests;
-int num_dests = cupsGetDests(&dests);
-cups_dest_t *dest = cupsGetDest("name", NULL, num_dests, dests);
-
-/* do something with dest */
-
-cupsFreeDests(num_dests, dests);
-
- -

Passing NULL to -cupsGetDest for the destination name -will return the default destination. Similarly, passing a NULL -instance will return the default instance for that destination.

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table 1: Printer Attributes
Attribute NameDescription
"auth-info-required"The type of authentication required for printing to this - destination: "none", "username,password", "domain,username,password", - or "negotiate" (Kerberos)
"printer-info"The human-readable description of the destination such as "My - Laser Printer".
"printer-is-accepting-jobs""true" if the destination is accepting new jobs, "false" if - not.
"printer-is-shared""true" if the destination is being shared with other computers, - "false" if not.
"printer-location"The human-readable location of the destination such as "Lab 4".
"printer-make-and-model"The human-readable make and model of the destination such as "HP - LaserJet 4000 Series".
"printer-state""3" if the destination is idle, "4" if the destination is printing - a job, and "5" if the destination is stopped.
"printer-state-change-time"The UNIX time when the destination entered the current state.
"printer-state-reasons"Additional comma-delimited state keywords for the destination - such as "media-tray-empty-error" and "toner-low-warning".
"printer-type"The cups_printer_t - value associated with the destination.
- -

Options

- -

Options are stored in arrays of -cups_option_t structures. Each -option has a name (name) and value (value) -associated with it. The cups_dest_t -num_options and options members contain the -default options for a particular destination, along with several informational -attributes about the destination as shown in Table 1. -The cupsGetOption function gets -the value for the named option. For example, the following code lists the -available destinations and their human-readable descriptions:

- -
-#include <cups/cups.h>
-
-cups_dest_t *dests;
-int num_dests = cupsGetDests(&dests);
-cups_dest_t *dest;
-int i;
-const char *value;
-
-for (i = num_dests, dest = dests; i > 0; i --, dest ++)
-  if (dest->instance == NULL)
-  {
-    value = cupsGetOption("printer-info", dest->num_options, dest->options);
-    printf("%s (%s)\n", dest->name, value ? value : "no description");
-  }
-
-cupsFreeDests(num_dests, dests);
-
- -

You can create your own option arrays using the -cupsAddOption function, which -adds a single named option to an array:

- -
-#include <cups/cups.h>
-
-int num_options = 0;
-cups_option_t *options = NULL;
-
-/* The returned num_options value is updated as needed */
-num_options = cupsAddOption("first", "value", num_options, &options);
-
-/* This adds a second option value */
-num_options = cupsAddOption("second", "value", num_options, &options);
-
-/* This replaces the first option we added */
-num_options = cupsAddOption("first", "new value", num_options, &options);
-
- -

Use a for loop to copy the options from a destination:

- -
-#include <cups/cups.h>
-
-int i;
-int num_options = 0;
-cups_option_t *options = NULL;
-cups_dest_t *dest;
-
-for (i = 0; i < dest->num_options; i ++)
-  num_options = cupsAddOption(dest->options[i].name, dest->options[i].value,
-                              num_options, &options);
-
- -

Use the cupsFreeOptions -function to free the options array when you are done using it:

- -
-cupsFreeOptions(num_options, options);
-
- -

Print Jobs

- -

Print jobs are identified by a locally-unique job ID number from 1 to -231-1 and have options and one or more files for printing to a -single destination. The cupsPrintFile -function creates a new job with one file. The following code prints the CUPS -test page file:

- -
-#include <cups/cups.h>
-
-cups_dest_t *dest;
-int num_options;
-cups_option_t *options;
-int job_id;
-
-/* Print a single file */
-job_id = cupsPrintFile(dest->name, "/usr/share/cups/data/testprint.ps",
-                        "Test Print", num_options, options);
-
- -

The cupsPrintFiles function -creates a job with multiple files. The files are provided in a -char * array:

- -
-#include <cups/cups.h>
-
-cups_dest_t *dest;
-int num_options;
-cups_option_t *options;
-int job_id;
-char *files[3] = { "file1.pdf", "file2.pdf", "file3.pdf" };
-
-/* Print three files */
-job_id = cupsPrintFiles(dest->name, 3, files, "Test Print", num_options, options);
-
- -

Finally, the cupsCreateJob -function creates a new job with no files in it. Files are added using the -cupsStartDocument, -cupsWriteRequestData, -and cupsFinishDocument functions. -The following example creates a job with 10 text files for printing:

- -
-#include <cups/cups.h>
-
-cups_dest_t *dest;
-int num_options;
-cups_option_t *options;
-int job_id;
-int i;
-char buffer[1024];
-
-/* Create the job */
-job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, dest->name, "10 Text Files",
-                       num_options, options);
-
-/* If the job is created, add 10 files */
-if (job_id > 0)
-{
-  for (i = 1; i <= 10; i ++)
-  {
-    snprintf(buffer, sizeof(buffer), "file%d.txt", i);
-
-    cupsStartDocument(CUPS_HTTP_DEFAULT, dest->name, job_id, buffer,
-                      CUPS_FORMAT_TEXT, i == 10);
-
-    snprintf(buffer, sizeof(buffer),
-             "File %d\n"
-             "\n"
-             "One fish,\n"
-             "Two fish,\n
-             "Red fish,\n
-             "Blue fish\n", i);
-
-    /* cupsWriteRequestData can be called as many times as needed */
-    cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, strlen(buffer));
-
-    cupsFinishDocument(CUPS_HTTP_DEFAULT, dest->name);
-  }
-}
-
- -

Once you have created a job, you can monitor its status using the -cupsGetJobs function, which returns -an array of cups_job_t structures. -Each contains the job ID (id), destination name -(dest), title (title), and other information -associated with the job. The job array is freed using the -cupsFreeJobs function. The following -example monitors a specific job ID, showing the current job state once every -5 seconds until the job is completed:

- -
-#include <cups/cups.h>
-
-cups_dest_t *dest;
-int job_id;
-int num_jobs;
-cups_job_t *jobs;
-int i;
-ipp_jstate_t job_state = IPP_JOB_PENDING;
-
-while (job_state < IPP_JOB_STOPPED)
-{
-  /* Get my jobs (1) with any state (-1) */
-  num_jobs = cupsGetJobs(&jobs, dest->name, 1, -1);
-
-  /* Loop to find my job */
-  job_state = IPP_JOB_COMPLETED;
-
-  for (i = 0; i < num_jobs; i ++)
-    if (jobs[i].id == job_id)
-    {
-      job_state = jobs[i].state;
-      break;
-    }
-
-  /* Free the job array */
-  cupsFreeJobs(num_jobs, jobs);
-
-  /* Show the current state */
-  switch (job_state)
-  {
-    case IPP_JOB_PENDING :
-        printf("Job %d is pending.\n", job_id);
-        break;
-    case IPP_JOB_HELD :
-        printf("Job %d is held.\n", job_id);
-        break;
-    case IPP_JOB_PROCESSING :
-        printf("Job %d is processing.\n", job_id);
-        break;
-    case IPP_JOB_STOPPED :
-        printf("Job %d is stopped.\n", job_id);
-        break;
-    case IPP_JOB_CANCELED :
-        printf("Job %d is canceled.\n", job_id);
-        break;
-    case IPP_JOB_ABORTED :
-        printf("Job %d is aborted.\n", job_id);
-        break;
-    case IPP_JOB_COMPLETED :
-        printf("Job %d is completed.\n", job_id);
-        break;
-  }
-
-  /* Sleep if the job is not finished */
-  if (job_state < IPP_JOB_STOPPED)
-    sleep(5);
-}
-
- -

To cancel a job, use the -cupsCancelJob function with the -job ID:

- -
-#include <cups/cups.h>
-
-cups_dest_t *dest;
-int job_id;
-
-cupsCancelJob(dest->name, job_id);
-
- -

Error Handling

- -

If any of the CUPS API printing functions returns an error, the reason for -that error can be found by calling the -cupsLastError and -cupsLastErrorString functions. -cupsLastError returns the last IPP -error code -(ipp_status_t) -that was encountered, while -cupsLastErrorString returns -a (localized) human-readable string that can be shown to the user. For example, -if any of the job creation functions returns a job ID of 0, you can use -cupsLastErrorString to show -the reason why the job could not be created:

- -
-#include <cups/cups.h>
-
-int job_id;
-
-if (job_id == 0)
-  puts(cupsLastErrorString());
-
- -

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:

- -
-#include <cups/cups.h>
-
-const char *
-my_password_cb(const char *prompt)
-{
-  char	user[65];
-
-
-  puts(prompt);
-
-  /* Get a username from the user */
-  printf("Username: ");
-  if (fgets(user, sizeof(user), stdin) == NULL)
-    return (NULL);
-
-  /* Strip the newline from the string and set the user */
-  user[strlen(user) - 1] = '\0';
-
-  cupsSetUser(user);
-
-  /* Use getpass() to ask for the password... */
-  return (getpass("Password: "));
-}
-
-cupsSetPasswordCB(my_password_cb);
-
- -

Similarly, a GUI could display the prompt string in a window with input -fields for the username and password. The username should default to the -string returned by the cupsUser -function.

diff --git a/cups/api-filedir.header b/cups/api-filedir.header deleted file mode 100644 index 87744ee..0000000 --- a/cups/api-filedir.header +++ /dev/null @@ -1,34 +0,0 @@ - - -

File and Directory APIs

- -
- - - - - - - - - - - - - - - - -
Headerscups/file.h
- cups/dir.h
Library-lcups
See AlsoProgramming: Introduction to CUPS Programming
- Programming: CUPS API
diff --git a/cups/api-filedir.shtml b/cups/api-filedir.shtml deleted file mode 100644 index 8fdbee6..0000000 --- a/cups/api-filedir.shtml +++ /dev/null @@ -1,29 +0,0 @@ - - -

Overview

- -

The CUPS file and directory APIs provide portable interfaces -for manipulating files and listing files and directories. Unlike -stdio FILE streams, the cupsFile functions -allow you to open more than 256 files at any given time. They -also manage the platform-specific details of locking, large file -support, line endings (CR, LF, or CR LF), and reading and writing -files using Flate ("gzip") compression. Finally, you can also -connect, read from, and write to network connections using the -cupsFile functions.

- -

The cupsDir functions manage the platform-specific -details of directory access/listing and provide a convenient way -to get both a list of files and the information (permissions, -size, timestamp, etc.) for each of those files.

diff --git a/cups/api-filter.header b/cups/api-filter.header index f08bc71..f64ef63 100644 --- a/cups/api-filter.header +++ b/cups/api-filter.header @@ -1,13 +1,10 @@

Filter and Backend Programming

diff --git a/cups/api-filter.shtml b/cups/api-filter.shtml index bd90333..e7ab510 100644 --- a/cups/api-filter.shtml +++ b/cups/api-filter.shtml @@ -1,14 +1,11 @@

Overview

@@ -871,4 +868,7 @@ void *my_data; -
Note: The sandbox profile used in CUPS 2.0 still allows some actions that are not listed above - these privileges will be removed over time until the profile matches the list above.
+
Note: + +

The sandbox profile used in CUPS still allows some actions that are not listed above - these privileges will be removed over time until the profile matches the list above.

+
diff --git a/cups/api-httpipp.header b/cups/api-httpipp.header deleted file mode 100644 index cbede8f..0000000 --- a/cups/api-httpipp.header +++ /dev/null @@ -1,37 +0,0 @@ - - -

HTTP and IPP APIs

- -
- - - - - - - - - - - - - - - - -
Headerscups/cups.h
- cups/http.h
- cups/ipp.h
Library-lcups
See AlsoProgramming: Introduction to CUPS Programming
- Programming: CUPS API
- References: CUPS Implementation of IPP
diff --git a/cups/api-httpipp.shtml b/cups/api-httpipp.shtml deleted file mode 100644 index 33bf5ad..0000000 --- a/cups/api-httpipp.shtml +++ /dev/null @@ -1,315 +0,0 @@ - - -

Overview

- -

The CUPS HTTP and IPP APIs provide low-level access to the HTTP and IPP -protocols and CUPS scheduler. They are typically used by monitoring and -administration programs to perform specific functions not supported by the -high-level CUPS API functions.

- -

The HTTP APIs use an opaque structure called -http_t to manage connections to -a particular HTTP or IPP server. The -httpConnectEncrypt function is -used to create an instance of this structure for a particular server. -The constant CUPS_HTTP_DEFAULT can be used with all of the -cups functions to refer to the default CUPS server - the functions -create a per-thread http_t as needed.

- -

The IPP APIs use two opaque structures for requests (messages sent to the CUPS scheduler) and responses (messages sent back to your application from the scheduler). The ipp_t type holds a complete request or response and is allocated using the ippNew or ippNewRequest functions and freed using the ippDelete function.

- -

The second opaque structure is called ipp_attribute_t and holds a single IPP attribute which consists of a group tag (ippGetGroupTag), a value type tag (ippGetValueTag), the attribute name (ippGetName), and 1 or more values (ippGetCount, ippGetBoolean, ippGetCollection, ippGetDate, ippGetInteger, ippGetRange, ippGetResolution, and ippGetString). Attributes are added to an ipp_t pointer using one of the ippAdd functions. For example, use ippAddString to add the "printer-uri" and "requesting-user-name" string attributes to a request:

- -
-ipp_t *request = ippNewRequest(IPP_GET_JOBS);
-
-ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
-             NULL, "ipp://localhost/printers/");
-ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
-             NULL, cupsUser());
-
- -

Once you have created an IPP request, use the cups functions to send the request to and read the response from the server. For example, the cupsDoRequest function can be used for simple query operations that do not involve files:

- -
-#include <cups/cups.h>
-
-
-ipp_t *get_jobs(void)
-{
-  ipp_t *request = ippNewRequest(IPP_GET_JOBS);
-
-  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
-               NULL, "ipp://localhost/printers/");
-  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
-               NULL, cupsUser());
-
-  return (cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/"));
-}
-
- -

The cupsDoRequest function frees the request and returns an IPP response or NULL pointer if the request could not be sent to the server. Once you have a response from the server, you can either use the ippFindAttribute and ippFindNextAttribute functions to find specific attributes, for example:

- -
-ipp_t *response;
-ipp_attribute_t *attr;
-
-attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM);
-
- -

You can also walk the list of attributes with a simple for loop like this:

- -
-ipp_t *response;
-ipp_attribute_t *attr;
-
-for (attr = ippFirstAttribute(response); attr != NULL; attr = ippNextAttribute(response))
-  if (ippGetName(attr) == NULL)
-    puts("--SEPARATOR--");
-  else
-    puts(ippGetName(attr));
-
- -

The for loop approach is normally used when collecting attributes for multiple objects (jobs, printers, etc.) in a response. Attributes with NULL names indicate a separator between the attributes of each object. For example, the following code will list the jobs returned from our previous get_jobs example code:

- -
-ipp_t *response = get_jobs();
-
-if (response != NULL)
-{
-  ipp_attribute_t *attr;
-  const char *attrname;
-  int job_id = 0;
-  const char *job_name = NULL;
-  const char *job_originating_user_name = NULL;
-
-  puts("Job ID  Owner             Title");
-  puts("------  ----------------  ---------------------------------");
-
-  for (attr = ippFirstAttribute(response); attr != NULL; attr = ippNextAttribute(response))
-  {
-   /* Attributes without names are separators between jobs */
-    attrname = ippGetName(attr);
-    if (attrname == NULL)
-    {
-      if (job_id > 0)
-      {
-        if (job_name == NULL)
-          job_name = "(withheld)";
-
-        if (job_originating_user_name == NULL)
-          job_originating_user_name = "(withheld)";
-
-        printf("%5d  %-16s  %s\n", job_id, job_originating_user_name, job_name);
-      }
-
-      job_id = 0;
-      job_name = NULL;
-      job_originating_user_name = NULL;
-      continue;
-    }
-    else if (!strcmp(attrname, "job-id") && ippGetValueTag(attr) == IPP_TAG_INTEGER)
-      job_id = ippGetInteger(attr, 0);
-    else if (!strcmp(attrname, "job-name") && ippGetValueTag(attr) == IPP_TAG_NAME)
-      job_name = ippGetString(attr, 0, NULL);
-    else if (!strcmp(attrname, "job-originating-user-name") &&
-             ippGetValueTag(attr) == IPP_TAG_NAME)
-      job_originating_user_name = ippGetString(attr, 0, NULL);
-  }
-
-  if (job_id > 0)
-  {
-    if (job_name == NULL)
-      job_name = "(withheld)";
-
-    if (job_originating_user_name == NULL)
-      job_originating_user_name = "(withheld)";
-
-    printf("%5d  %-16s  %s\n", job_id, job_originating_user_name, job_name);
-  }
-}
-
- -

Creating URI Strings

- -

To ensure proper encoding, the -httpAssembleURIf function must be -used to format a "printer-uri" string for all printer-based requests:

- -
-const char *name = "Foo";
-char uri[1024];
-ipp_t *request;
-
-httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, cupsServer(),
-                 ippPort(), "/printers/%s", name);
-ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
-
- -

Sending Requests with Files

- -

The cupsDoFileRequest and -cupsDoIORequest functions are -used for requests involving files. The -cupsDoFileRequest function -attaches the named file to a request and is typically used when sending a print -file or changing a printer's PPD file:

- -
-const char *filename = "/usr/share/cups/data/testprint.ps";
-const char *name = "Foo";
-char uri[1024];
-char resource[1024];
-ipp_t *request = ippNewRequest(IPP_PRINT_JOB);
-ipp_t *response;
-
-/* Use httpAssembleURIf for the printer-uri string */
-httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, cupsServer(),
-                 ippPort(), "/printers/%s", name);
-ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
-ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
-             NULL, cupsUser());
-ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
-             NULL, "testprint.ps");
-
-/* Use snprintf for the resource path */
-snprintf(resource, sizeof(resource), "/printers/%s", name);
-
-response = cupsDoFileRequest(CUPS_HTTP_DEFAULT, request, resource, filename);
-
- -

The cupsDoIORequest function -optionally attaches a file to the request and optionally saves a file in the -response from the server. It is used when using a pipe for the request -attachment or when using a request that returns a file, currently only -CUPS_GET_DOCUMENT and CUPS_GET_PPD. For example, -the following code will download the PPD file for the sample HP LaserJet -printer driver:

- -
-char tempfile[1024];
-int tempfd;
-ipp_t *request = ippNewRequest(CUPS_GET_PPD);
-ipp_t *response;
-
-ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
-             NULL, "laserjet.ppd");
-
-tempfd = cupsTempFd(tempfile, sizeof(tempfile));
-
-response = cupsDoIORequest(CUPS_HTTP_DEFAULT, request, "/", -1, tempfd);
-
- -

The example passes -1 for the input file descriptor to specify -that no file is to be attached to the request. The PPD file attached to the -response is written to the temporary file descriptor we created using the -cupsTempFd function.

- -

Asynchronous Request Processing

- -

The cupsSendRequest and -cupsGetResponse support -asynchronous communications with the server. Unlike the other request -functions, the IPP request is not automatically freed, so remember to -free your request with the ippDelete -function.

- -

File data is attached to the request using the -cupsWriteRequestData -function, while file data returned from the server is read using the -cupsReadResponseData -function. We can rewrite the previous CUPS_GET_PPD example -to use the asynchronous functions quite easily:

- -
-char tempfile[1024];
-int tempfd;
-ipp_t *request = ippNewRequest(CUPS_GET_PPD);
-ipp_t *response;
-
-ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
-             NULL, "laserjet.ppd");
-
-tempfd = cupsTempFd(tempfile, sizeof(tempfile));
-
-if (cupsSendRequest(CUPS_HTTP_DEFAULT, request, "/") == HTTP_CONTINUE)
-{
-  response = cupsGetResponse(CUPS_HTTP_DEFAULT, "/");
-
-  if (response != NULL)
-  {
-    ssize_t bytes;
-    char buffer[8192];
-
-    while ((bytes = cupsReadResponseData(CUPS_HTTP_DEFAULT, buffer, sizeof(buffer))) > 0)
-      write(tempfd, buffer, bytes);
-  }
-}
-
-/* Free the request! */
-ippDelete(request);
-
- -

The cupsSendRequest function -returns the initial HTTP request status, typically either -HTTP_CONTINUE or HTTP_UNAUTHORIZED. The latter status -is returned when the request requires authentication of some sort. The -cupsDoAuthentication function -must be called when your see HTTP_UNAUTHORIZED and the request -re-sent. We can add authentication support to our example code by using a -do ... while loop:

- -
-char tempfile[1024];
-int tempfd;
-ipp_t *request = ippNewRequest(CUPS_GET_PPD);
-ipp_t *response;
-http_status_t status;
-
-ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
-             NULL, "laserjet.ppd");
-
-tempfd = cupsTempFd(tempfile, sizeof(tempfile));
-
-/* Loop for authentication */
-do
-{
-  status = cupsSendRequest(CUPS_HTTP_DEFAULT, request, "/");
-
-  if (status == HTTP_UNAUTHORIZED)
-  {
-    /* Try to authenticate, break out of the loop if that fails */
-    if (cupsDoAuthentication(CUPS_HTTP_DEFAULT, "POST", "/"))
-      break;
-  }
-}
-while (status != HTTP_CONTINUE && status != HTTP_UNAUTHORIZED);
-
-if (status == HTTP_CONTINUE)
-{
-  response = cupsGetResponse(CUPS_HTTP_DEFAULT, "/");
-
-  if (response != NULL)
-  {
-    ssize_t bytes;
-    char buffer[8192];
-
-    while ((bytes = cupsReadResponseData(CUPS_HTTP_DEFAULT, buffer, sizeof(buffer))) > 0)
-      write(tempfd, buffer, bytes);
-  }
-}
-
-/* Free the request! */
-ippDelete(request);
-
diff --git a/cups/api-overview.header b/cups/api-overview.header deleted file mode 100644 index b96cd07..0000000 --- a/cups/api-overview.header +++ /dev/null @@ -1,54 +0,0 @@ - - -

Introduction to CUPS Programming

- -
- - - - - - - - - - - - - - - - -
Headerscups/cups.h
- cups/adminutil.h
- cups/array.h
- cups/dir.h
- cups/file.h
- cups/http.h
- cups/ipp.h
- cups/language.h
- cups/ppd.h
- cups/pwg.h
- cups/raster.h
Libraries-lcups
See AlsoProgramming: Developing Raster Printer Drivers
- Programming: Developing PostScript Printer Drivers
- Programming: Filter and Backend Programming
- Programming: Introduction to the PPD Compiler
- Programming: Administrative APIs
- Programming: Array API
- Programming: CUPS API
- Programming: File and Directory APIs
- Programming: HTTP and IPP APIs
- Programming: PPD API (DEPRECATED)
- Programming: Raster API
- References: PPD Compiler Driver Information File Reference
- Specifications: CUPS PPD Extensions
diff --git a/cups/api-overview.shtml b/cups/api-overview.shtml deleted file mode 100644 index 9903152..0000000 --- a/cups/api-overview.shtml +++ /dev/null @@ -1,92 +0,0 @@ - - -

Overview

- -

CUPS provides two libraries that interface with the different parts of the -printing system. The "cups" library provides all of the common application and -filter functions while the "cupsimage" library provides all of the imaging -functions used in raster printer drivers. The "cups" library functions are -accessed by including the <cups/cups.h> header, while -"cupsimage" functions are found in the <cups/raster.h> -header.

- -

Compiling Programs

- -

The CUPS libraries can be used from any C, C++, or Objective C program. -The method of compiling against the libraries varies depending on the -operating system and installation of CUPS. The following sections show how -to compile a simple program (shown below) in two common environments.

- -

The following simple program lists the available printers on the system:

- -
-#include <stdio.h>
-#include <cups/cups.h>
-
-int main(void)
-{
-  int i;
-  cups_dest_t *dests, *dest;
-  int num_dests = cupsGetDests(&dests);
-
-  for (i = num_dests, dest = dests; i > 0; i --, dest ++)
-  {
-    if (dest->instance)
-      printf("%s/%s\n", dest->name, dest->instance);
-    else
-      puts(dest->name);
-  }
-
-  return (0);
-}
-
- -

Compiling with Xcode

- -

In Xcode, choose New Project... from the File menu, -then select the Standard Tool project type under Command Line -Utility. Click Next and choose a project directory. Click -Next to create the project.

- -

In the project window, double-click on the Targets group and -control-click on the simple target to show the context menu. Choose -Existing Framework... from the Add submenu. When the file -chooser sheet appears, press the / key and enter "/usr/lib". Scroll -down the file list and select the libcups.dylib file. Click the -Add button in the file chooser and attributes sheets.

- -

In the project window, double-click on the main.c source file. -Replace the template source code with the listing above and save it. Click the -Build and Go button to build the sample program and run it.

- -

Compiling with GCC

- -

From the command-line, create a file called sample.c using your -favorite editor and then run the following command to compile it with GCC and -run it:

- -
-gcc -o simple `cups-config --cflags` simple.c `cups-config --libs`
-./simple
-
- -

The cups-config command provides the compiler flags -("cups-config --cflags") and libraries ("cups-config --libs") needed for the -local system.

- -

Where to Go Next

- -

If you are developing a print filter, driver, or backend, see the -Filter and Backend Programming -guide. Raster printer driver developers should also read the -Raster API reference.

diff --git a/cups/api-ppd.header b/cups/api-ppd.header index 2f7a4cd..bc555e6 100644 --- a/cups/api-ppd.header +++ b/cups/api-ppd.header @@ -1,18 +1,18 @@

PPD API (DEPRECATED)

-
The PPD API is deprecated starting in CUPS 1.6/macOS 10.8. Please use the new Job Ticket APIs in the CUPS API documentation. These functions will be removed in a future release of CUPS.
+
Note: + +

The PPD API was deprecated in CUPS 1.6/macOS 10.8. Please use the new Job Ticket APIs in the CUPS Programming Manual documentation. These functions will be removed in a future release of CUPS.

+
@@ -29,7 +29,7 @@ diff --git a/cups/api-ppd.shtml b/cups/api-ppd.shtml index 50c4850..d7a43f4 100644 --- a/cups/api-ppd.shtml +++ b/cups/api-ppd.shtml @@ -1,19 +1,19 @@

Overview

-
The PPD API is deprecated starting in CUPS 1.6/macOS 10.8. Please use the new Job Ticket APIs in the CUPS API documentation. These functions will be removed in a future release of CUPS.
+
Note: + +

The PPD API was deprecated in CUPS 1.6/macOS 10.8. Please use the new Job Ticket APIs in the CUPS Programming Manual documentation. These functions will be removed in a future release of CUPS.

+

The CUPS PPD API provides read-only access the data in PostScript Printer Description ("PPD") files which are used for all printers with a driver. With @@ -31,6 +31,7 @@ values as case-insensitive strings, so option "InputSlot" and choice "Upper" are equivalent to "inputslot" and "upper", respectively.

+

Loading a PPD File

The ppdOpenFile function "opens" a @@ -118,6 +119,7 @@ int num_options = cupsParseOptions(argv[5], 0, &options); cupsFreeOptions(num_options, options); +

Constraints

PPD files support specification of conflict conditions, called @@ -128,6 +130,7 @@ the options and choices that conflict with each other. The how many of the selected options are incompatible. Since constraints are normally specified in pairs, the returned value is typically an even number.

+

Page Sizes

Page sizes are special options which have physical dimensions and margins @@ -182,6 +185,7 @@ in points. Custom page size names can also be specified in inches ppdPageSize function will return NULL.

+

Attributes

Every PPD file is composed of one or more attributes. Most of these diff --git a/cups/api-raster.header b/cups/api-raster.header new file mode 100644 index 0000000..f5122d8 --- /dev/null +++ b/cups/api-raster.header @@ -0,0 +1,31 @@ + + +

Raster API

+ +
See Also Programming: Introduction to CUPS Programming
- Programming: CUPS API
+ Programming: CUPS Programming Manual
Specifications: CUPS PPD Extensions
+ + + + + + + + + + + + + + + + +
Headercups/raster.h
Library-lcups
See AlsoProgramming: CUPS Programming Manual
+ Programming: PPD API
+ References: CUPS PPD Specification
diff --git a/filter/api-raster.shtml b/cups/api-raster.shtml similarity index 90% rename from filter/api-raster.shtml rename to cups/api-raster.shtml index 6d458a2..44a6037 100644 --- a/filter/api-raster.shtml +++ b/cups/api-raster.shtml @@ -1,14 +1,11 @@

Overview

@@ -150,7 +147,7 @@ the memory used to read the raster file:

    -
  • cupsRasterInterpretPPD
  • +
  • cupsRasterInitPWGHeader
  • cupsRasterWriteHeader Deprecated in CUPS 1.2/macOS 10.5
  • cupsRasterWriteHeader2
  • cupsRasterWritePixels
  • diff --git a/cups/array-private.h b/cups/array-private.h index ff083e4..e4d7b8a 100644 --- a/cups/array-private.h +++ b/cups/array-private.h @@ -3,13 +3,7 @@ * * Copyright 2011-2012 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ #ifndef _CUPS_ARRAY_PRIVATE_H_ @@ -36,9 +30,9 @@ extern "C" { */ extern int _cupsArrayAddStrings(cups_array_t *a, const char *s, - char delim) _CUPS_API_1_5; + char delim) _CUPS_PRIVATE; extern cups_array_t *_cupsArrayNewStrings(const char *s, char delim) - _CUPS_API_1_5; + _CUPS_PRIVATE; # ifdef __cplusplus } diff --git a/cups/array.c b/cups/array.c index dee4f5e..860cb46 100644 --- a/cups/array.c +++ b/cups/array.c @@ -4,13 +4,7 @@ * Copyright 2007-2014 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -19,7 +13,7 @@ #include #include "string-private.h" -#include "debug-private.h" +#include "debug-internal.h" #include "array-private.h" diff --git a/cups/array.h b/cups/array.h index 189c6e1..e5468a3 100644 --- a/cups/array.h +++ b/cups/array.h @@ -4,13 +4,7 @@ * Copyright 2007-2010 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ #ifndef _CUPS_ARRAY_H_ diff --git a/cups/attr.c b/cups/attr.c deleted file mode 100644 index da7a725..0000000 --- a/cups/attr.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * "$Id: attr.c 7584 2008-05-16 22:55:53Z mike $" - * - * PPD model-specific attribute routines for CUPS. - * - * Copyright 2007-2012 by Apple Inc. - * Copyright 1997-2006 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * Contents: - * - * ppdFindAttr() - Find the first matching attribute. - * ppdFindNextAttr() - Find the next matching attribute. - * _ppdNormalizeMakeAndModel() - Normalize a product/make-and-model string. - */ - -/* - * Include necessary headers... - */ - -#include "cups-private.h" -#include "ppd-private.h" - - -/* - * 'ppdFindAttr()' - Find the first matching attribute. - * - * @since CUPS 1.1.19/OS X 10.3@ - */ - -ppd_attr_t * /* O - Attribute or @code NULL@ if not found */ -ppdFindAttr(ppd_file_t *ppd, /* I - PPD file data */ - const char *name, /* I - Attribute name */ - const char *spec) /* I - Specifier string or @code NULL@ */ -{ - ppd_attr_t key, /* Search key */ - *attr; /* Current attribute */ - - - DEBUG_printf(("2ppdFindAttr(ppd=%p, name=\"%s\", spec=\"%s\")", ppd, name, - spec)); - - /* - * Range check input... - */ - - if (!ppd || !name || ppd->num_attrs == 0) - return (NULL); - - /* - * Search for a matching attribute... - */ - - memset(&key, 0, sizeof(key)); - strlcpy(key.name, name, sizeof(key.name)); - - /* - * Return the first matching attribute, if any... - */ - - if ((attr = (ppd_attr_t *)cupsArrayFind(ppd->sorted_attrs, &key)) != NULL) - { - if (spec) - { - /* - * Loop until we find the first matching attribute for "spec"... - */ - - while (attr && _cups_strcasecmp(spec, attr->spec)) - { - if ((attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs)) != NULL && - _cups_strcasecmp(attr->name, name)) - attr = NULL; - } - } - } - - return (attr); -} - - -/* - * 'ppdFindNextAttr()' - Find the next matching attribute. - * - * @since CUPS 1.1.19/OS X 10.3@ - */ - -ppd_attr_t * /* O - Attribute or @code NULL@ if not found */ -ppdFindNextAttr(ppd_file_t *ppd, /* I - PPD file data */ - const char *name, /* I - Attribute name */ - const char *spec) /* I - Specifier string or @code NULL@ */ -{ - ppd_attr_t *attr; /* Current attribute */ - - - /* - * Range check input... - */ - - if (!ppd || !name || ppd->num_attrs == 0) - return (NULL); - - /* - * See if there are more attributes to return... - */ - - while ((attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs)) != NULL) - { - /* - * Check the next attribute to see if it is a match... - */ - - if (_cups_strcasecmp(attr->name, name)) - { - /* - * Nope, reset the current pointer to the end of the array... - */ - - cupsArrayIndex(ppd->sorted_attrs, cupsArrayCount(ppd->sorted_attrs)); - - return (NULL); - } - - if (!spec || !_cups_strcasecmp(attr->spec, spec)) - break; - } - - /* - * Return the next attribute's value... - */ - - return (attr); -} - - -/* - * '_ppdNormalizeMakeAndModel()' - Normalize a product/make-and-model string. - * - * This function tries to undo the mistakes made by many printer manufacturers - * to produce a clean make-and-model string we can use. - */ - -char * /* O - Normalized make-and-model string or NULL on error */ -_ppdNormalizeMakeAndModel( - const char *make_and_model, /* I - Original make-and-model string */ - char *buffer, /* I - String buffer */ - size_t bufsize) /* I - Size of string buffer */ -{ - char *bufptr; /* Pointer into buffer */ - - - if (!make_and_model || !buffer || bufsize < 1) - { - if (buffer) - *buffer = '\0'; - - return (NULL); - } - - /* - * Skip leading whitespace... - */ - - while (_cups_isspace(*make_and_model)) - make_and_model ++; - - /* - * Remove parenthesis and add manufacturers as needed... - */ - - if (make_and_model[0] == '(') - { - strlcpy(buffer, make_and_model + 1, bufsize); - - if ((bufptr = strrchr(buffer, ')')) != NULL) - *bufptr = '\0'; - } - else if (!_cups_strncasecmp(make_and_model, "XPrint", 6)) - { - /* - * Xerox XPrint... - */ - - snprintf(buffer, bufsize, "Xerox %s", make_and_model); - } - else if (!_cups_strncasecmp(make_and_model, "Eastman", 7)) - { - /* - * Kodak... - */ - - snprintf(buffer, bufsize, "Kodak %s", make_and_model + 7); - } - else if (!_cups_strncasecmp(make_and_model, "laserwriter", 11)) - { - /* - * Apple LaserWriter... - */ - - snprintf(buffer, bufsize, "Apple LaserWriter%s", make_and_model + 11); - } - else if (!_cups_strncasecmp(make_and_model, "colorpoint", 10)) - { - /* - * Seiko... - */ - - snprintf(buffer, bufsize, "Seiko %s", make_and_model); - } - else if (!_cups_strncasecmp(make_and_model, "fiery", 5)) - { - /* - * EFI... - */ - - snprintf(buffer, bufsize, "EFI %s", make_and_model); - } - else if (!_cups_strncasecmp(make_and_model, "ps ", 3) || - !_cups_strncasecmp(make_and_model, "colorpass", 9)) - { - /* - * Canon... - */ - - snprintf(buffer, bufsize, "Canon %s", make_and_model); - } - else if (!_cups_strncasecmp(make_and_model, "primera", 7)) - { - /* - * Fargo... - */ - - snprintf(buffer, bufsize, "Fargo %s", make_and_model); - } - else if (!_cups_strncasecmp(make_and_model, "designjet", 9) || - !_cups_strncasecmp(make_and_model, "deskjet", 7)) - { - /* - * HP... - */ - - snprintf(buffer, bufsize, "HP %s", make_and_model); - } - else - strlcpy(buffer, make_and_model, bufsize); - - /* - * Clean up the make... - */ - - if (!_cups_strncasecmp(buffer, "agfa", 4)) - { - /* - * Replace with AGFA (all uppercase)... - */ - - buffer[0] = 'A'; - buffer[1] = 'G'; - buffer[2] = 'F'; - buffer[3] = 'A'; - } - else if (!_cups_strncasecmp(buffer, "Hewlett-Packard hp ", 19)) - { - /* - * Just put "HP" on the front... - */ - - buffer[0] = 'H'; - buffer[1] = 'P'; - _cups_strcpy(buffer + 2, buffer + 18); - } - else if (!_cups_strncasecmp(buffer, "Hewlett-Packard ", 16)) - { - /* - * Just put "HP" on the front... - */ - - buffer[0] = 'H'; - buffer[1] = 'P'; - _cups_strcpy(buffer + 2, buffer + 15); - } - else if (!_cups_strncasecmp(buffer, "Lexmark International", 21)) - { - /* - * Strip "International"... - */ - - _cups_strcpy(buffer + 8, buffer + 21); - } - else if (!_cups_strncasecmp(buffer, "herk", 4)) - { - /* - * Replace with LHAG... - */ - - buffer[0] = 'L'; - buffer[1] = 'H'; - buffer[2] = 'A'; - buffer[3] = 'G'; - } - else if (!_cups_strncasecmp(buffer, "linotype", 8)) - { - /* - * Replace with LHAG... - */ - - buffer[0] = 'L'; - buffer[1] = 'H'; - buffer[2] = 'A'; - buffer[3] = 'G'; - _cups_strcpy(buffer + 4, buffer + 8); - } - - /* - * Remove trailing whitespace and return... - */ - - for (bufptr = buffer + strlen(buffer) - 1; - bufptr >= buffer && _cups_isspace(*bufptr); - bufptr --); - - bufptr[1] = '\0'; - - return (buffer[0] ? buffer : NULL); -} - - -/* - * End of "$Id: attr.c 7584 2008-05-16 22:55:53Z mike $". - */ diff --git a/cups/auth.c b/cups/auth.c index c051c86..634ed1f 100644 --- a/cups/auth.c +++ b/cups/auth.c @@ -1,19 +1,13 @@ /* * Authentication functions for CUPS. * - * Copyright 2007-2016 by Apple Inc. + * Copyright 2007-2019 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * * This file contains Kerberos support code, copyright 2006 by * Jelmer Vernooij. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -21,21 +15,17 @@ */ #include "cups-private.h" +#include "debug-internal.h" #include #include -#if defined(WIN32) || defined(__EMX__) +#if defined(_WIN32) || defined(__EMX__) # include #else # include -#endif /* WIN32 || __EMX__ */ +#endif /* _WIN32 || __EMX__ */ #if HAVE_AUTHORIZATION_H # include -# ifdef HAVE_SECBASEPRIV_H -# include -# else -extern const char *cssmErrorString(int error); -# endif /* HAVE_SECBASEPRIV_H */ #endif /* HAVE_AUTHORIZATION_H */ #if defined(SO_PEERCRED) && defined(AF_LOCAL) @@ -47,7 +37,14 @@ extern const char *cssmErrorString(int error); * Local functions... */ +static const char *cups_auth_find(const char *www_authenticate, const char *scheme); +static const char *cups_auth_param(const char *scheme, const char *name, char *value, size_t valsize); +static const char *cups_auth_scheme(const char *www_authenticate, char *scheme, size_t schemesize); + #ifdef HAVE_GSSAPI +# define CUPS_GSS_OK 0 /* Successfully set credentials */ +# define CUPS_GSS_NONE -1 /* No credentials */ +# define CUPS_GSS_FAIL -2 /* Failed credentials/authentication */ # ifdef HAVE_GSS_ACQUIRE_CRED_EX_F # ifdef HAVE_GSS_GSSAPI_SPI_H # include @@ -112,10 +109,10 @@ cupsDoAuthentication( const char *resource) /* I - Resource path */ { const char *password, /* Password string */ - *www_auth; /* WWW-Authenticate header */ - char prompt[1024], /* Prompt for user */ - realm[HTTP_MAX_VALUE], /* realm="xyz" string */ - nonce[HTTP_MAX_VALUE]; /* nonce="xyz" string */ + *www_auth, /* WWW-Authenticate header */ + *schemedata; /* Scheme-specific data */ + char scheme[256], /* Scheme name */ + prompt[1024]; /* Prompt for user */ int localauth; /* Local authentication result */ _cups_globals_t *cg; /* Global data */ @@ -163,122 +160,154 @@ cupsDoAuthentication( } /* - * Nope, see if we should retry the current username:password... + * Nope, loop through the authentication schemes to find the first we support. */ - www_auth = http->fields[HTTP_FIELD_WWW_AUTHENTICATE]; + www_auth = httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE); - if ((http->digest_tries > 1 || !http->userpass[0]) && - (!_cups_strncasecmp(www_auth, "Basic", 5) || - !_cups_strncasecmp(www_auth, "Digest", 6))) + for (schemedata = cups_auth_scheme(www_auth, scheme, sizeof(scheme)); schemedata; schemedata = cups_auth_scheme(schemedata + strlen(scheme), scheme, sizeof(scheme))) { /* - * Nope - get a new password from the user... + * Check the scheme name... */ - char default_username[HTTP_MAX_VALUE]; - /* Default username */ - - cg = _cupsGlobals(); - - if (!cg->lang_default) - cg->lang_default = cupsLangDefault(); - - if (httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "username", - default_username)) - cupsSetUser(default_username); - - snprintf(prompt, sizeof(prompt), - _cupsLangString(cg->lang_default, _("Password for %s on %s? ")), - cupsUser(), - http->hostname[0] == '/' ? "localhost" : http->hostname); - - http->digest_tries = _cups_strncasecmp(www_auth, "Digest", 6) != 0; - http->userpass[0] = '\0'; - - if ((password = cupsGetPassword2(prompt, http, method, resource)) == NULL) - { - http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; - return (-1); - } - - snprintf(http->userpass, sizeof(http->userpass), "%s:%s", cupsUser(), - password); - } - else if (http->status == HTTP_STATUS_UNAUTHORIZED) - http->digest_tries ++; - - if (http->status == HTTP_STATUS_UNAUTHORIZED && http->digest_tries >= 3) - { - DEBUG_printf(("1cupsDoAuthentication: Too many authentication tries (%d)", - http->digest_tries)); - - http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; - return (-1); - } - - /* - * Got a password; encode it for the server... - */ + DEBUG_printf(("2cupsDoAuthentication: Trying scheme \"%s\"...", scheme)); #ifdef HAVE_GSSAPI - if (!_cups_strncasecmp(www_auth, "Negotiate", 9)) - { + if (!_cups_strcasecmp(scheme, "Negotiate")) + { + /* + * Kerberos authentication... + */ + + int gss_status; /* Auth status */ + + if ((gss_status = _cupsSetNegotiateAuthString(http, method, resource)) == CUPS_GSS_FAIL) + { + DEBUG_puts("1cupsDoAuthentication: Negotiate failed."); + http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; + return (-1); + } + else if (gss_status == CUPS_GSS_NONE) + { + DEBUG_puts("2cupsDoAuthentication: No credentials for Negotiate."); + continue; + } + else + { + DEBUG_puts("2cupsDoAuthentication: Using Negotiate."); + break; + } + } + else +#endif /* HAVE_GSSAPI */ + if (_cups_strcasecmp(scheme, "Basic") && _cups_strcasecmp(scheme, "Digest")) + { + /* + * Other schemes not yet supported... + */ + + DEBUG_printf(("2cupsDoAuthentication: Scheme \"%s\" not yet supported.", scheme)); + continue; + } + /* - * Kerberos authentication... + * See if we should retry the current username:password... */ - if (_cupsSetNegotiateAuthString(http, method, resource)) + if ((http->digest_tries > 1 || !http->userpass[0]) && (!_cups_strcasecmp(scheme, "Basic") || (!_cups_strcasecmp(scheme, "Digest")))) { + /* + * Nope - get a new password from the user... + */ + + char default_username[HTTP_MAX_VALUE]; + /* Default username */ + + cg = _cupsGlobals(); + + if (!cg->lang_default) + cg->lang_default = cupsLangDefault(); + + if (cups_auth_param(schemedata, "username", default_username, sizeof(default_username))) + cupsSetUser(default_username); + + snprintf(prompt, sizeof(prompt), _cupsLangString(cg->lang_default, _("Password for %s on %s? ")), cupsUser(), http->hostname[0] == '/' ? "localhost" : http->hostname); + + http->digest_tries = _cups_strncasecmp(scheme, "Digest", 6) != 0; + http->userpass[0] = '\0'; + + if ((password = cupsGetPassword2(prompt, http, method, resource)) == NULL) + { + DEBUG_puts("1cupsDoAuthentication: User canceled password request."); + http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; + return (-1); + } + + snprintf(http->userpass, sizeof(http->userpass), "%s:%s", cupsUser(), password); + } + else if (http->status == HTTP_STATUS_UNAUTHORIZED) + http->digest_tries ++; + + if (http->status == HTTP_STATUS_UNAUTHORIZED && http->digest_tries >= 3) + { + DEBUG_printf(("1cupsDoAuthentication: Too many authentication tries (%d)", http->digest_tries)); + http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; return (-1); } - } - else -#endif /* HAVE_GSSAPI */ - if (!_cups_strncasecmp(www_auth, "Basic", 5)) - { + /* - * Basic authentication... + * Got a password; encode it for the server... */ - char encode[256]; /* Base64 buffer */ + if (!_cups_strcasecmp(scheme, "Basic")) + { + /* + * Basic authentication... + */ + char encode[256]; /* Base64 buffer */ - httpEncode64_2(encode, sizeof(encode), http->userpass, - (int)strlen(http->userpass)); - httpSetAuthString(http, "Basic", encode); + DEBUG_puts("2cupsDoAuthentication: Using Basic."); + httpEncode64_2(encode, sizeof(encode), http->userpass, (int)strlen(http->userpass)); + httpSetAuthString(http, "Basic", encode); + break; + } + else if (!_cups_strcasecmp(scheme, "Digest")) + { + /* + * Digest authentication... + */ + + char nonce[HTTP_MAX_VALUE]; /* nonce="xyz" string */ + + cups_auth_param(schemedata, "algorithm", http->algorithm, sizeof(http->algorithm)); + cups_auth_param(schemedata, "opaque", http->opaque, sizeof(http->opaque)); + cups_auth_param(schemedata, "nonce", nonce, sizeof(nonce)); + cups_auth_param(schemedata, "realm", http->realm, sizeof(http->realm)); + + if (_httpSetDigestAuthString(http, nonce, method, resource)) + { + DEBUG_puts("2cupsDoAuthentication: Using Basic."); + break; + } + } } - else if (!_cups_strncasecmp(www_auth, "Digest", 6)) + + if (http->authstring) { - /* - * Digest authentication... - */ + DEBUG_printf(("1cupsDoAuthentication: authstring=\"%s\".", http->authstring)); - char encode[33], /* MD5 buffer */ - digest[1024]; /* Digest auth data */ - - httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "realm", realm); - httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "nonce", nonce); - - httpMD5(cupsUser(), realm, strchr(http->userpass, ':') + 1, encode); - httpMD5Final(nonce, method, resource, encode); - snprintf(digest, sizeof(digest), - "username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", " - "response=\"%s\"", cupsUser(), realm, nonce, resource, encode); - httpSetAuthString(http, "Digest", digest); + return (0); } else { - DEBUG_printf(("1cupsDoAuthentication: Unknown auth type: \"%s\"", - www_auth)); + DEBUG_puts("1cupsDoAuthentication: No supported schemes."); http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; + return (-1); } - - DEBUG_printf(("1cupsDoAuthentication: authstring=\"%s\"", http->authstring)); - - return (0); } @@ -287,7 +316,7 @@ cupsDoAuthentication( * '_cupsSetNegotiateAuthString()' - Set the Kerberos authentication string. */ -int /* O - 0 on success, -1 on error */ +int /* O - 0 on success, negative on error */ _cupsSetNegotiateAuthString( http_t *http, /* I - Connection to server */ const char *method, /* I - Request method ("GET", "POST", "PUT") */ @@ -312,10 +341,16 @@ _cupsSetNegotiateAuthString( { DEBUG_puts("1_cupsSetNegotiateAuthString: Weak-linked GSSAPI/Kerberos " "framework is not present"); - return (-1); + return (CUPS_GSS_NONE); } # endif /* __APPLE__ */ + if (!strcmp(http->hostname, "localhost") || http->hostname[0] == '/' || isdigit(http->hostname[0] & 255) || !strchr(http->hostname, '.')) + { + DEBUG_printf(("1_cupsSetNegotiateAuthString: Kerberos not available for host \"%s\".", http->hostname)); + return (CUPS_GSS_NONE); + } + if (http->gssname == GSS_C_NO_NAME) { http->gssname = cups_gss_getname(http, _cupsGSSServiceName()); @@ -336,7 +371,7 @@ _cupsSetNegotiateAuthString( GSS_C_NO_BUFFER, &http->gssmech, &output_token, NULL, NULL); -#ifdef HAVE_GSS_ACQUIRE_CRED_EX_F +# ifdef HAVE_GSS_ACQUIRE_CRED_EX_F if (major_status == GSS_S_NO_CRED) { /* @@ -360,7 +395,7 @@ _cupsSetNegotiateAuthString( cupsUser(), http->gsshost); if ((password = cupsGetPassword2(prompt, http, method, resource)) == NULL) - return (-1); + return (CUPS_GSS_FAIL); /* * Try to acquire credentials... @@ -412,21 +447,23 @@ _cupsSetNegotiateAuthString( } } } -#endif /* HAVE_GSS_ACQUIRED_CRED_EX_F */ +# endif /* HAVE_GSS_ACQUIRED_CRED_EX_F */ - if (GSS_ERROR(major_status)) + if (major_status == GSS_S_NO_CRED) { - cups_gss_printf(major_status, minor_status, - "_cupsSetNegotiateAuthString: Unable to initialize " - "security context"); - return (-1); + cups_gss_printf(major_status, minor_status, "_cupsSetNegotiateAuthString: No credentials"); + return (CUPS_GSS_NONE); + } + else if (GSS_ERROR(major_status)) + { + cups_gss_printf(major_status, minor_status, "_cupsSetNegotiateAuthString: Unable to initialize security context"); + return (CUPS_GSS_FAIL); } -#ifdef DEBUG +# ifdef DEBUG else if (major_status == GSS_S_CONTINUE_NEEDED) - cups_gss_printf(major_status, minor_status, - "_cupsSetNegotiateAuthString: Continuation needed!"); -#endif /* DEBUG */ + cups_gss_printf(major_status, minor_status, "_cupsSetNegotiateAuthString: Continuation needed"); +# endif /* DEBUG */ if (output_token.length > 0 && output_token.length <= 65536) { @@ -436,7 +473,7 @@ _cupsSetNegotiateAuthString( */ int authsize = 10 + /* "Negotiate " */ - (int)output_token.length * 4 / 3 + 1 + 1; + (((int)output_token.length * 4 / 3 + 3) & ~3) + 1; /* Base64 + nul */ httpSetAuthString(http, NULL, NULL); @@ -459,13 +496,264 @@ _cupsSetNegotiateAuthString( "large - %d bytes!", (int)output_token.length)); gss_release_buffer(&minor_status, &output_token); - return (-1); + return (CUPS_GSS_FAIL); } - return (0); + return (CUPS_GSS_OK); +} +#endif /* HAVE_GSSAPI */ + + +/* + * 'cups_auth_find()' - Find the named WWW-Authenticate scheme. + * + * The "www_authenticate" parameter points to the current position in the header. + * + * Returns @code NULL@ if the auth scheme is not present. + */ + +static const char * /* O - Start of matching scheme or @code NULL@ if not found */ +cups_auth_find(const char *www_authenticate, /* I - Pointer into WWW-Authenticate header */ + const char *scheme) /* I - Authentication scheme */ +{ + size_t schemelen = strlen(scheme); /* Length of scheme */ + + + DEBUG_printf(("8cups_auth_find(www_authenticate=\"%s\", scheme=\"%s\"(%d))", www_authenticate, scheme, (int)schemelen)); + + while (*www_authenticate) + { + /* + * Skip leading whitespace and commas... + */ + + DEBUG_printf(("9cups_auth_find: Before whitespace: \"%s\"", www_authenticate)); + while (isspace(*www_authenticate & 255) || *www_authenticate == ',') + www_authenticate ++; + DEBUG_printf(("9cups_auth_find: After whitespace: \"%s\"", www_authenticate)); + + /* + * See if this is "Scheme" followed by whitespace or the end of the string. + */ + + if (!strncmp(www_authenticate, scheme, schemelen) && (isspace(www_authenticate[schemelen] & 255) || www_authenticate[schemelen] == ',' || !www_authenticate[schemelen])) + { + /* + * Yes, this is the start of the scheme-specific information... + */ + + DEBUG_printf(("9cups_auth_find: Returning \"%s\".", www_authenticate)); + + return (www_authenticate); + } + + /* + * Skip the scheme name or param="value" string... + */ + + while (!isspace(*www_authenticate & 255) && *www_authenticate) + { + if (*www_authenticate == '\"') + { + /* + * Skip quoted value... + */ + + www_authenticate ++; + while (*www_authenticate && *www_authenticate != '\"') + www_authenticate ++; + + DEBUG_printf(("9cups_auth_find: After quoted: \"%s\"", www_authenticate)); + } + + www_authenticate ++; + } + + DEBUG_printf(("9cups_auth_find: After skip: \"%s\"", www_authenticate)); + } + + DEBUG_puts("9cups_auth_find: Returning NULL."); + + return (NULL); } +/* + * 'cups_auth_param()' - Copy the value for the named authentication parameter, + * if present. + */ + +static const char * /* O - Parameter value or @code NULL@ if not present */ +cups_auth_param(const char *scheme, /* I - Pointer to auth data */ + const char *name, /* I - Name of parameter */ + char *value, /* I - Value buffer */ + size_t valsize) /* I - Size of value buffer */ +{ + char *valptr = value, /* Pointer into value buffer */ + *valend = value + valsize - 1; /* Pointer to end of buffer */ + size_t namelen = strlen(name); /* Name length */ + int param; /* Is this a parameter? */ + + + DEBUG_printf(("8cups_auth_param(scheme=\"%s\", name=\"%s\", value=%p, valsize=%d)", scheme, name, (void *)value, (int)valsize)); + + while (!isspace(*scheme & 255) && *scheme) + scheme ++; + + while (*scheme) + { + while (isspace(*scheme & 255) || *scheme == ',') + scheme ++; + + if (!strncmp(scheme, name, namelen) && scheme[namelen] == '=') + { + /* + * Found the parameter, copy the value... + */ + + scheme += namelen + 1; + if (*scheme == '\"') + { + scheme ++; + + while (*scheme && *scheme != '\"') + { + if (valptr < valend) + *valptr++ = *scheme; + + scheme ++; + } + } + else + { + while (*scheme && strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~+/=", *scheme)) + { + if (valptr < valend) + *valptr++ = *scheme; + + scheme ++; + } + } + + *valptr = '\0'; + + DEBUG_printf(("9cups_auth_param: Returning \"%s\".", value)); + + return (value); + } + + /* + * Skip the param=value string... + */ + + param = 0; + + while (!isspace(*scheme & 255) && *scheme) + { + if (*scheme == '=') + param = 1; + else if (*scheme == '\"') + { + /* + * Skip quoted value... + */ + + scheme ++; + while (*scheme && *scheme != '\"') + scheme ++; + } + + scheme ++; + } + + /* + * If this wasn't a parameter, we are at the end of this scheme's + * parameters... + */ + + if (!param) + break; + } + + *value = '\0'; + + DEBUG_puts("9cups_auth_param: Returning NULL."); + + return (NULL); +} + + +/* + * 'cups_auth_scheme()' - Get the (next) WWW-Authenticate scheme. + * + * The "www_authenticate" parameter points to the current position in the header. + * + * Returns @code NULL@ if there are no (more) auth schemes present. + */ + +static const char * /* O - Start of scheme or @code NULL@ if not found */ +cups_auth_scheme(const char *www_authenticate, /* I - Pointer into WWW-Authenticate header */ + char *scheme, /* I - Scheme name buffer */ + size_t schemesize) /* I - Size of buffer */ +{ + const char *start; /* Start of scheme data */ + char *sptr = scheme, /* Pointer into scheme buffer */ + *send = scheme + schemesize - 1;/* End of scheme buffer */ + int param; /* Is this a parameter? */ + + + DEBUG_printf(("8cups_auth_scheme(www_authenticate=\"%s\", scheme=%p, schemesize=%d)", www_authenticate, (void *)scheme, (int)schemesize)); + + while (*www_authenticate) + { + /* + * Skip leading whitespace and commas... + */ + + while (isspace(*www_authenticate & 255) || *www_authenticate == ',') + www_authenticate ++; + + /* + * Parse the scheme name or param="value" string... + */ + + for (sptr = scheme, start = www_authenticate, param = 0; *www_authenticate && *www_authenticate != ',' && !isspace(*www_authenticate & 255); www_authenticate ++) + { + if (*www_authenticate == '=') + param = 1; + else if (!param && sptr < send) + *sptr++ = *www_authenticate; + else if (*www_authenticate == '\"') + { + /* + * Skip quoted value... + */ + + www_authenticate ++; + while (*www_authenticate && *www_authenticate != '\"') + www_authenticate ++; + } + } + + if (sptr > scheme && !param) + { + *sptr = '\0'; + + DEBUG_printf(("9cups_auth_scheme: Returning \"%s\".", start)); + + return (start); + } + } + + *scheme = '\0'; + + DEBUG_puts("9cups_auth_scheme: Returning NULL."); + + return (NULL); +} + + +#ifdef HAVE_GSSAPI # ifdef HAVE_GSS_ACQUIRE_CRED_EX_F /* * 'cups_gss_acquire()' - Kerberos credentials callback. @@ -639,9 +927,9 @@ static int /* O - 0 if available */ /* -1 error */ cups_local_auth(http_t *http) /* I - HTTP connection to server */ { -#if defined(WIN32) || defined(__EMX__) +#if defined(_WIN32) || defined(__EMX__) /* - * Currently WIN32 and OS-2 do not support the CUPS server... + * Currently _WIN32 and OS-2 do not support the CUPS server... */ return (1); @@ -650,6 +938,8 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */ FILE *fp; /* Certificate file */ char trc[16], /* Try Root Certificate parameter */ filename[1024]; /* Certificate filename */ + const char *www_auth, /* WWW-Authenticate header */ + *schemedata; /* Data for the named auth scheme */ _cups_globals_t *cg = _cupsGlobals(); /* Global data */ # if defined(HAVE_AUTHORIZATION_H) OSStatus status; /* Status */ @@ -668,13 +958,14 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */ * See if we are accessing localhost... */ - if (!httpAddrLocalhost(http->hostaddr) && - _cups_strcasecmp(http->hostname, "localhost") != 0) + if (!httpAddrLocalhost(http->hostaddr) && _cups_strcasecmp(http->hostname, "localhost") != 0) { DEBUG_puts("8cups_local_auth: Not a local connection!"); return (1); } + www_auth = httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE); + # if defined(HAVE_AUTHORIZATION_H) /* * Delete any previous authorization reference... @@ -686,16 +977,13 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */ http->auth_ref = NULL; } - if (!getenv("GATEWAY_INTERFACE") && - httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "authkey", - auth_key, sizeof(auth_key))) + if (!getenv("GATEWAY_INTERFACE") && (schemedata = cups_auth_find(www_auth, "AuthRef")) != NULL && cups_auth_param(schemedata, "key", auth_key, sizeof(auth_key))) { - status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, - kAuthorizationFlagDefaults, &http->auth_ref); + status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &http->auth_ref); if (status != errAuthorizationSuccess) { - DEBUG_printf(("8cups_local_auth: AuthorizationCreate() returned %d (%s)", - (int)status, cssmErrorString(status))); + DEBUG_printf(("8cups_local_auth: AuthorizationCreate() returned %d", + (int)status)); return (-1); } @@ -736,8 +1024,7 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */ else if (status == errAuthorizationCanceled) return (-1); - DEBUG_printf(("9cups_local_auth: AuthorizationCopyRights() returned %d (%s)", - (int)status, cssmErrorString(status))); + DEBUG_printf(("9cups_local_auth: AuthorizationCopyRights() returned %d", (int)status)); /* * Fall through to try certificates... @@ -745,6 +1032,11 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */ } # endif /* HAVE_AUTHORIZATION_H */ +# ifdef HAVE_GSSAPI + if (cups_auth_find(www_auth, "Negotiate")) + return (1); +# endif /* HAVE_GSSAPI */ + # if defined(SO_PEERCRED) && defined(AF_LOCAL) /* * See if we can authenticate using the peer credentials provided over a @@ -752,16 +1044,9 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */ * information... */ - if ( -# ifdef HAVE_GSSAPI - _cups_strncasecmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Negotiate", 9) && -# endif /* HAVE_GSSAPI */ -# ifdef HAVE_AUTHORIZATION_H - !httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "authkey", - auth_key, sizeof(auth_key)) && -# endif /* HAVE_AUTHORIZATION_H */ - http->hostaddr->addr.sa_family == AF_LOCAL && - !getenv("GATEWAY_INTERFACE")) /* Not via CGI programs... */ + if (http->hostaddr->addr.sa_family == AF_LOCAL && + !getenv("GATEWAY_INTERFACE") && /* Not via CGI programs... */ + cups_auth_find(www_auth, "PeerCred")) { /* * Verify that the current cupsUser() matches the current UID... @@ -784,6 +1069,9 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */ } # endif /* SO_PEERCRED && AF_LOCAL */ + if ((schemedata = cups_auth_find(www_auth, "Local")) == NULL) + return (1); + /* * Try opening a certificate file for this PID. If that fails, * try the root certificate... @@ -797,33 +1085,9 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */ * No certificate for this PID; see if we can get the root certificate... */ - DEBUG_printf(("9cups_local_auth: Unable to open file %s: %s", - filename, strerror(errno))); + DEBUG_printf(("9cups_local_auth: Unable to open file \"%s\": %s", filename, strerror(errno))); -# ifdef HAVE_GSSAPI - if (!_cups_strncasecmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Negotiate", 9)) - { - /* - * Kerberos required, don't try the root certificate... - */ - - return (1); - } -# endif /* HAVE_GSSAPI */ - -# ifdef HAVE_AUTHORIZATION_H - if (httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "authkey", - auth_key, sizeof(auth_key))) - { - /* - * Don't use the root certificate as a replacement for an authkey... - */ - - return (1); - } -# endif /* HAVE_AUTHORIZATION_H */ - if (!httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "trc", trc, - sizeof(trc))) + if (!cups_auth_param(schemedata, "trc", trc, sizeof(trc))) { /* * Scheduler doesn't want us to use the root certificate... @@ -833,7 +1097,8 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */ } snprintf(filename, sizeof(filename), "%s/certs/0", cg->cups_statedir); - fp = fopen(filename, "r"); + if ((fp = fopen(filename, "r")) == NULL) + DEBUG_printf(("9cups_local_auth: Unable to open file \"%s\": %s", filename, strerror(errno))); } if (fp) @@ -864,5 +1129,5 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */ } return (1); -#endif /* WIN32 || __EMX__ */ +#endif /* _WIN32 || __EMX__ */ } diff --git a/cups/backchannel.c b/cups/backchannel.c index e804d45..916c314 100644 --- a/cups/backchannel.c +++ b/cups/backchannel.c @@ -4,13 +4,7 @@ * Copyright 2007-2014 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -18,13 +12,14 @@ */ #include "cups.h" +#include "sidechannel.h" #include -#ifdef WIN32 +#ifdef _WIN32 # include # include #else # include -#endif /* WIN32 */ +#endif /* _WIN32 */ /* @@ -77,11 +72,11 @@ cupsBackChannelRead(char *buffer, /* I - Buffer to read into */ * Read bytes from the pipe... */ -#ifdef WIN32 +#ifdef _WIN32 return ((ssize_t)_read(3, buffer, (unsigned)bytes)); #else return (read(3, buffer, bytes)); -#endif /* WIN32 */ +#endif /* _WIN32 */ } @@ -139,11 +134,11 @@ cupsBackChannelWrite( * Write bytes to the pipe... */ -#ifdef WIN32 +#ifdef _WIN32 count = (ssize_t)_write(3, buffer, (unsigned)(bytes - total)); #else count = write(3, buffer, bytes - total); -#endif /* WIN32 */ +#endif /* _WIN32 */ if (count < 0) { diff --git a/cups/backend.c b/cups/backend.c index f164617..4f5099b 100644 --- a/cups/backend.c +++ b/cups/backend.c @@ -4,13 +4,7 @@ * Copyright 2007-2015 by Apple Inc. * Copyright 2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* diff --git a/cups/backend.h b/cups/backend.h index 274bcd4..a8c5ec1 100644 --- a/cups/backend.h +++ b/cups/backend.h @@ -4,13 +4,7 @@ * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2005 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ #ifndef _CUPS_BACKEND_H_ diff --git a/cups/conflicts.c b/cups/conflicts.c deleted file mode 100644 index f0d01b0..0000000 --- a/cups/conflicts.c +++ /dev/null @@ -1,1214 +0,0 @@ -/* - * "$Id: conflicts.c 3794 2012-04-23 22:44:16Z msweet $" - * - * Option marking routines for CUPS. - * - * Copyright 2007-2012 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * PostScript is a trademark of Adobe Systems, Inc. - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * cupsGetConflicts() - Get a list of conflicting options in a marked - * PPD. - * cupsResolveConflicts() - Resolve conflicts in a marked PPD. - * ppdConflicts() - Check to see if there are any conflicts among - * the marked option choices. - * ppdInstallableConflict() - Test whether an option choice conflicts with an - * installable option. - * ppd_is_installable() - Determine whether an option is in the - * InstallableOptions group. - * ppd_load_constraints() - Load constraints from a PPD file. - * ppd_test_constraints() - See if any constraints are active. - */ - -/* - * Include necessary headers... - */ - -#include "cups-private.h" -#include "ppd-private.h" - - -/* - * Local constants... - */ - -enum -{ - _PPD_NORMAL_CONSTRAINTS, - _PPD_OPTION_CONSTRAINTS, - _PPD_INSTALLABLE_CONSTRAINTS, - _PPD_ALL_CONSTRAINTS -}; - - -/* - * Local functions... - */ - -static int ppd_is_installable(ppd_group_t *installable, - const char *option); -static void ppd_load_constraints(ppd_file_t *ppd); -static cups_array_t *ppd_test_constraints(ppd_file_t *ppd, - const char *option, - const char *choice, - int num_options, - cups_option_t *options, - int which); - - -/* - * 'cupsGetConflicts()' - Get a list of conflicting options in a marked PPD. - * - * This function gets a list of options that would conflict if "option" and - * "choice" were marked in the PPD. You would typically call this function - * after marking the currently selected options in the PPD in order to - * determine whether a new option selection would cause a conflict. - * - * The number of conflicting options are returned with "options" pointing to - * the conflicting options. The returned option array must be freed using - * @link cupsFreeOptions@. - * - * @since CUPS 1.4/OS X 10.6@ - */ - -int /* O - Number of conflicting options */ -cupsGetConflicts( - ppd_file_t *ppd, /* I - PPD file */ - const char *option, /* I - Option to test */ - const char *choice, /* I - Choice to test */ - cups_option_t **options) /* O - Conflicting options */ -{ - int i, /* Looping var */ - num_options; /* Number of conflicting options */ - cups_array_t *active; /* Active conflicts */ - _ppd_cups_uiconsts_t *c; /* Current constraints */ - _ppd_cups_uiconst_t *cptr; /* Current constraint */ - ppd_choice_t *marked; /* Marked choice */ - - - /* - * Range check input... - */ - - if (options) - *options = NULL; - - if (!ppd || !option || !choice || !options) - return (0); - - /* - * Test for conflicts... - */ - - active = ppd_test_constraints(ppd, option, choice, 0, NULL, - _PPD_ALL_CONSTRAINTS); - - /* - * Loop through all of the UI constraints and add any options that conflict... - */ - - for (num_options = 0, c = (_ppd_cups_uiconsts_t *)cupsArrayFirst(active); - c; - c = (_ppd_cups_uiconsts_t *)cupsArrayNext(active)) - { - for (i = c->num_constraints, cptr = c->constraints; - i > 0; - i --, cptr ++) - if (_cups_strcasecmp(cptr->option->keyword, option)) - { - if (cptr->choice) - num_options = cupsAddOption(cptr->option->keyword, - cptr->choice->choice, num_options, - options); - else if ((marked = ppdFindMarkedChoice(ppd, - cptr->option->keyword)) != NULL) - num_options = cupsAddOption(cptr->option->keyword, marked->choice, - num_options, options); - } - } - - cupsArrayDelete(active); - - return (num_options); -} - - -/* - * 'cupsResolveConflicts()' - Resolve conflicts in a marked PPD. - * - * This function attempts to resolve any conflicts in a marked PPD, returning - * a list of option changes that are required to resolve them. On input, - * "num_options" and "options" contain any pending option changes that have - * not yet been marked, while "option" and "choice" contain the most recent - * selection which may or may not be in "num_options" or "options". - * - * On successful return, "num_options" and "options" are updated to contain - * "option" and "choice" along with any changes required to resolve conflicts - * specified in the PPD file and 1 is returned. - * - * If option conflicts cannot be resolved, "num_options" and "options" are not - * changed and 0 is returned. - * - * When resolving conflicts, @code cupsResolveConflicts@ does not consider - * changes to the current page size (@code media@, @code PageSize@, and - * @code PageRegion@) or to the most recent option specified in "option". - * Thus, if the only way to resolve a conflict is to change the page size - * or the option the user most recently changed, @code cupsResolveConflicts@ - * will return 0 to indicate it was unable to resolve the conflicts. - * - * The @code cupsResolveConflicts@ function uses one of two sources of option - * constraint information. The preferred constraint information is defined by - * @code cupsUIConstraints@ and @code cupsUIResolver@ attributes - in this - * case, the PPD file provides constraint resolution actions. - * - * The backup constraint information is defined by the - * @code UIConstraints@ and @code NonUIConstraints@ attributes. These - * constraints are resolved algorithmically by first selecting the default - * choice for the conflicting option, then iterating over all possible choices - * until a non-conflicting option choice is found. - * - * @since CUPS 1.4/OS X 10.6@ - */ - -int /* O - 1 on success, 0 on failure */ -cupsResolveConflicts( - ppd_file_t *ppd, /* I - PPD file */ - const char *option, /* I - Newly selected option or @code NULL@ for none */ - const char *choice, /* I - Newly selected choice or @code NULL@ for none */ - int *num_options, /* IO - Number of additional selected options */ - cups_option_t **options) /* IO - Additional selected options */ -{ - int i, /* Looping var */ - tries, /* Number of tries */ - num_newopts; /* Number of new options */ - cups_option_t *newopts; /* New options */ - cups_array_t *active, /* Active constraints */ - *pass, /* Resolvers for this pass */ - *resolvers, /* Resolvers we have used */ - *test; /* Test array for conflicts */ - _ppd_cups_uiconsts_t *consts; /* Current constraints */ - _ppd_cups_uiconst_t *constptr; /* Current constraint */ - ppd_attr_t *resolver; /* Current resolver */ - const char *resval; /* Pointer into resolver value */ - char resoption[PPD_MAX_NAME], - /* Current resolver option */ - reschoice[PPD_MAX_NAME], - /* Current resolver choice */ - *resptr, /* Pointer into option/choice */ - firstpage[255]; /* AP_FIRSTPAGE_Keyword string */ - const char *value; /* Selected option value */ - int changed; /* Did we change anything? */ - ppd_choice_t *marked; /* Marked choice */ - - - /* - * Range check input... - */ - - if (!ppd || !num_options || !options || (option == NULL) != (choice == NULL)) - return (0); - - /* - * Build a shadow option array... - */ - - num_newopts = 0; - newopts = NULL; - - for (i = 0; i < *num_options; i ++) - num_newopts = cupsAddOption((*options)[i].name, (*options)[i].value, - num_newopts, &newopts); - if (option && _cups_strcasecmp(option, "Collate")) - num_newopts = cupsAddOption(option, choice, num_newopts, &newopts); - - /* - * Loop until we have no conflicts... - */ - - cupsArraySave(ppd->sorted_attrs); - - resolvers = NULL; - pass = cupsArrayNew((cups_array_func_t)_cups_strcasecmp, NULL); - tries = 0; - - while (tries < 100 && - (active = ppd_test_constraints(ppd, NULL, NULL, num_newopts, newopts, - _PPD_ALL_CONSTRAINTS)) != NULL) - { - tries ++; - - if (!resolvers) - resolvers = cupsArrayNew((cups_array_func_t)_cups_strcasecmp, NULL); - - for (consts = (_ppd_cups_uiconsts_t *)cupsArrayFirst(active), changed = 0; - consts; - consts = (_ppd_cups_uiconsts_t *)cupsArrayNext(active)) - { - if (consts->resolver[0]) - { - /* - * Look up the resolver... - */ - - if (cupsArrayFind(pass, consts->resolver)) - continue; /* Already applied this resolver... */ - - if (cupsArrayFind(resolvers, consts->resolver)) - { - /* - * Resolver loop! - */ - - DEBUG_printf(("1cupsResolveConflicts: Resolver loop with %s!", - consts->resolver)); - goto error; - } - - if ((resolver = ppdFindAttr(ppd, "cupsUIResolver", - consts->resolver)) == NULL) - { - DEBUG_printf(("1cupsResolveConflicts: Resolver %s not found!", - consts->resolver)); - goto error; - } - - if (!resolver->value) - { - DEBUG_printf(("1cupsResolveConflicts: Resolver %s has no value!", - consts->resolver)); - goto error; - } - - /* - * Add the options from the resolver... - */ - - cupsArrayAdd(pass, consts->resolver); - cupsArrayAdd(resolvers, consts->resolver); - - for (resval = resolver->value; *resval && !changed;) - { - while (_cups_isspace(*resval)) - resval ++; - - if (*resval != '*') - break; - - for (resval ++, resptr = resoption; - *resval && !_cups_isspace(*resval); - resval ++) - if (resptr < (resoption + sizeof(resoption) - 1)) - *resptr++ = *resval; - - *resptr = '\0'; - - while (_cups_isspace(*resval)) - resval ++; - - for (resptr = reschoice; - *resval && !_cups_isspace(*resval); - resval ++) - if (resptr < (reschoice + sizeof(reschoice) - 1)) - *resptr++ = *resval; - - *resptr = '\0'; - - if (!resoption[0] || !reschoice[0]) - break; - - /* - * Is this the option we are changing? - */ - - snprintf(firstpage, sizeof(firstpage), "AP_FIRSTPAGE_%s", resoption); - - if (option && - (!_cups_strcasecmp(resoption, option) || - !_cups_strcasecmp(firstpage, option) || - (!_cups_strcasecmp(option, "PageSize") && - !_cups_strcasecmp(resoption, "PageRegion")) || - (!_cups_strcasecmp(option, "AP_FIRSTPAGE_PageSize") && - !_cups_strcasecmp(resoption, "PageSize")) || - (!_cups_strcasecmp(option, "AP_FIRSTPAGE_PageSize") && - !_cups_strcasecmp(resoption, "PageRegion")) || - (!_cups_strcasecmp(option, "PageRegion") && - !_cups_strcasecmp(resoption, "PageSize")) || - (!_cups_strcasecmp(option, "AP_FIRSTPAGE_PageRegion") && - !_cups_strcasecmp(resoption, "PageSize")) || - (!_cups_strcasecmp(option, "AP_FIRSTPAGE_PageRegion") && - !_cups_strcasecmp(resoption, "PageRegion")))) - continue; - - /* - * Try this choice... - */ - - if ((test = ppd_test_constraints(ppd, resoption, reschoice, - num_newopts, newopts, - _PPD_ALL_CONSTRAINTS)) == NULL) - { - /* - * That worked... - */ - - changed = 1; - } - else - cupsArrayDelete(test); - - /* - * Add the option/choice from the resolver regardless of whether it - * worked; this makes sure that we can cascade several changes to - * make things resolve... - */ - - num_newopts = cupsAddOption(resoption, reschoice, num_newopts, - &newopts); - } - } - else - { - /* - * Try resolving by choosing the default values for non-installable - * options, then by iterating through the possible choices... - */ - - int j; /* Looping var */ - ppd_choice_t *cptr; /* Current choice */ - ppd_size_t *size; /* Current page size */ - - - for (i = consts->num_constraints, constptr = consts->constraints; - i > 0 && !changed; - i --, constptr ++) - { - /* - * Can't resolve by changing an installable option... - */ - - if (constptr->installable) - continue; - - /* - * Is this the option we are changing? - */ - - if (option && - (!_cups_strcasecmp(constptr->option->keyword, option) || - (!_cups_strcasecmp(option, "PageSize") && - !_cups_strcasecmp(constptr->option->keyword, "PageRegion")) || - (!_cups_strcasecmp(option, "PageRegion") && - !_cups_strcasecmp(constptr->option->keyword, "PageSize")))) - continue; - - /* - * Get the current option choice... - */ - - if ((value = cupsGetOption(constptr->option->keyword, num_newopts, - newopts)) == NULL) - { - if (!_cups_strcasecmp(constptr->option->keyword, "PageSize") || - !_cups_strcasecmp(constptr->option->keyword, "PageRegion")) - { - if ((value = cupsGetOption("PageSize", num_newopts, - newopts)) == NULL) - value = cupsGetOption("PageRegion", num_newopts, newopts); - - if (!value) - { - if ((size = ppdPageSize(ppd, NULL)) != NULL) - value = size->name; - else - value = ""; - } - } - else - { - marked = ppdFindMarkedChoice(ppd, constptr->option->keyword); - value = marked ? marked->choice : ""; - } - } - - if (!_cups_strncasecmp(value, "Custom.", 7)) - value = "Custom"; - - /* - * Try the default choice... - */ - - test = NULL; - - if (_cups_strcasecmp(value, constptr->option->defchoice) && - (test = ppd_test_constraints(ppd, constptr->option->keyword, - constptr->option->defchoice, - num_newopts, newopts, - _PPD_OPTION_CONSTRAINTS)) == NULL) - { - /* - * That worked... - */ - - num_newopts = cupsAddOption(constptr->option->keyword, - constptr->option->defchoice, - num_newopts, &newopts); - changed = 1; - } - else - { - /* - * Try each choice instead... - */ - - for (j = constptr->option->num_choices, - cptr = constptr->option->choices; - j > 0; - j --, cptr ++) - { - cupsArrayDelete(test); - test = NULL; - - if (_cups_strcasecmp(value, cptr->choice) && - _cups_strcasecmp(constptr->option->defchoice, cptr->choice) && - _cups_strcasecmp("Custom", cptr->choice) && - (test = ppd_test_constraints(ppd, constptr->option->keyword, - cptr->choice, num_newopts, - newopts, - _PPD_OPTION_CONSTRAINTS)) == NULL) - { - /* - * This choice works... - */ - - num_newopts = cupsAddOption(constptr->option->keyword, - cptr->choice, num_newopts, - &newopts); - changed = 1; - break; - } - } - - cupsArrayDelete(test); - } - } - } - } - - if (!changed) - { - DEBUG_puts("1cupsResolveConflicts: Unable to automatically resolve " - "constraint!"); - goto error; - } - - cupsArrayClear(pass); - cupsArrayDelete(active); - active = NULL; - } - - if (tries >= 100) - goto error; - - /* - * Free the caller's option array... - */ - - cupsFreeOptions(*num_options, *options); - - /* - * If Collate is the option we are testing, add it here. Otherwise, remove - * any Collate option from the resolve list since the filters automatically - * handle manual collation... - */ - - if (option && !_cups_strcasecmp(option, "Collate")) - num_newopts = cupsAddOption(option, choice, num_newopts, &newopts); - else - num_newopts = cupsRemoveOption("Collate", num_newopts, &newopts); - - /* - * Return the new list of options to the caller... - */ - - *num_options = num_newopts; - *options = newopts; - - cupsArrayDelete(pass); - cupsArrayDelete(resolvers); - - cupsArrayRestore(ppd->sorted_attrs); - - DEBUG_printf(("1cupsResolveConflicts: Returning %d options:", num_newopts)); -#ifdef DEBUG - for (i = 0; i < num_newopts; i ++) - DEBUG_printf(("1cupsResolveConflicts: options[%d]: %s=%s", i, - newopts[i].name, newopts[i].value)); -#endif /* DEBUG */ - - return (1); - - /* - * If we get here, we failed to resolve... - */ - - error: - - cupsFreeOptions(num_newopts, newopts); - - cupsArrayDelete(active); - cupsArrayDelete(pass); - cupsArrayDelete(resolvers); - - cupsArrayRestore(ppd->sorted_attrs); - - DEBUG_puts("1cupsResolveConflicts: Unable to resolve conflicts!"); - - return (0); -} - - -/* - * 'ppdConflicts()' - Check to see if there are any conflicts among the - * marked option choices. - * - * The returned value is the same as returned by @link ppdMarkOption@. - */ - -int /* O - Number of conflicts found */ -ppdConflicts(ppd_file_t *ppd) /* I - PPD to check */ -{ - int i, /* Looping variable */ - conflicts; /* Number of conflicts */ - cups_array_t *active; /* Active conflicts */ - _ppd_cups_uiconsts_t *c; /* Current constraints */ - _ppd_cups_uiconst_t *cptr; /* Current constraint */ - ppd_option_t *o; /* Current option */ - - - if (!ppd) - return (0); - - /* - * Clear all conflicts... - */ - - cupsArraySave(ppd->options); - - for (o = ppdFirstOption(ppd); o; o = ppdNextOption(ppd)) - o->conflicted = 0; - - cupsArrayRestore(ppd->options); - - /* - * Test for conflicts... - */ - - active = ppd_test_constraints(ppd, NULL, NULL, 0, NULL, - _PPD_ALL_CONSTRAINTS); - conflicts = cupsArrayCount(active); - - /* - * Loop through all of the UI constraints and flag any options - * that conflict... - */ - - for (c = (_ppd_cups_uiconsts_t *)cupsArrayFirst(active); - c; - c = (_ppd_cups_uiconsts_t *)cupsArrayNext(active)) - { - for (i = c->num_constraints, cptr = c->constraints; - i > 0; - i --, cptr ++) - cptr->option->conflicted = 1; - } - - cupsArrayDelete(active); - - /* - * Return the number of conflicts found... - */ - - return (conflicts); -} - - -/* - * 'ppdInstallableConflict()' - Test whether an option choice conflicts with - * an installable option. - * - * This function tests whether a particular option choice is available based - * on constraints against options in the "InstallableOptions" group. - * - * @since CUPS 1.4/OS X 10.6@ - */ - -int /* O - 1 if conflicting, 0 if not conflicting */ -ppdInstallableConflict( - ppd_file_t *ppd, /* I - PPD file */ - const char *option, /* I - Option */ - const char *choice) /* I - Choice */ -{ - cups_array_t *active; /* Active conflicts */ - - - DEBUG_printf(("2ppdInstallableConflict(ppd=%p, option=\"%s\", choice=\"%s\")", - ppd, option, choice)); - - /* - * Range check input... - */ - - if (!ppd || !option || !choice) - return (0); - - /* - * Test constraints using the new option... - */ - - active = ppd_test_constraints(ppd, option, choice, 0, NULL, - _PPD_INSTALLABLE_CONSTRAINTS); - - cupsArrayDelete(active); - - return (active != NULL); -} - - -/* - * 'ppd_is_installable()' - Determine whether an option is in the - * InstallableOptions group. - */ - -static int /* O - 1 if installable, 0 if normal */ -ppd_is_installable( - ppd_group_t *installable, /* I - InstallableOptions group */ - const char *name) /* I - Option name */ -{ - if (installable) - { - int i; /* Looping var */ - ppd_option_t *option; /* Current option */ - - - for (i = installable->num_options, option = installable->options; - i > 0; - i --, option ++) - if (!_cups_strcasecmp(option->keyword, name)) - return (1); - } - - return (0); -} - - -/* - * 'ppd_load_constraints()' - Load constraints from a PPD file. - */ - -static void -ppd_load_constraints(ppd_file_t *ppd) /* I - PPD file */ -{ - int i; /* Looping var */ - ppd_const_t *oldconst; /* Current UIConstraints data */ - ppd_attr_t *constattr; /* Current cupsUIConstraints attribute */ - _ppd_cups_uiconsts_t *consts; /* Current cupsUIConstraints data */ - _ppd_cups_uiconst_t *constptr; /* Current constraint */ - ppd_group_t *installable; /* Installable options group */ - const char *vptr; /* Pointer into constraint value */ - char option[PPD_MAX_NAME], /* Option name/MainKeyword */ - choice[PPD_MAX_NAME], /* Choice/OptionKeyword */ - *ptr; /* Pointer into option or choice */ - - - DEBUG_printf(("7ppd_load_constraints(ppd=%p)", ppd)); - - /* - * Create an array to hold the constraint data... - */ - - ppd->cups_uiconstraints = cupsArrayNew(NULL, NULL); - - /* - * Find the installable options group if it exists... - */ - - for (i = ppd->num_groups, installable = ppd->groups; - i > 0; - i --, installable ++) - if (!_cups_strcasecmp(installable->name, "InstallableOptions")) - break; - - if (i <= 0) - installable = NULL; - - /* - * Load old-style [Non]UIConstraints data... - */ - - for (i = ppd->num_consts, oldconst = ppd->consts; i > 0; i --, oldconst ++) - { - /* - * Weed out nearby duplicates, since the PPD spec requires that you - * define both "*Foo foo *Bar bar" and "*Bar bar *Foo foo"... - */ - - if (i > 1 && - !_cups_strcasecmp(oldconst[0].option1, oldconst[1].option2) && - !_cups_strcasecmp(oldconst[0].choice1, oldconst[1].choice2) && - !_cups_strcasecmp(oldconst[0].option2, oldconst[1].option1) && - !_cups_strcasecmp(oldconst[0].choice2, oldconst[1].choice1)) - continue; - - /* - * Allocate memory... - */ - - if ((consts = calloc(1, sizeof(_ppd_cups_uiconsts_t))) == NULL) - { - DEBUG_puts("8ppd_load_constraints: Unable to allocate memory for " - "UIConstraints!"); - return; - } - - if ((constptr = calloc(2, sizeof(_ppd_cups_uiconst_t))) == NULL) - { - free(consts); - DEBUG_puts("8ppd_load_constraints: Unable to allocate memory for " - "UIConstraints!"); - return; - } - - /* - * Fill in the information... - */ - - consts->num_constraints = 2; - consts->constraints = constptr; - - if (!_cups_strncasecmp(oldconst->option1, "Custom", 6) && - !_cups_strcasecmp(oldconst->choice1, "True")) - { - constptr[0].option = ppdFindOption(ppd, oldconst->option1 + 6); - constptr[0].choice = ppdFindChoice(constptr[0].option, "Custom"); - constptr[0].installable = 0; - } - else - { - constptr[0].option = ppdFindOption(ppd, oldconst->option1); - constptr[0].choice = ppdFindChoice(constptr[0].option, - oldconst->choice1); - constptr[0].installable = ppd_is_installable(installable, - oldconst->option1); - } - - if (!constptr[0].option || (!constptr[0].choice && oldconst->choice1[0])) - { - DEBUG_printf(("8ppd_load_constraints: Unknown option *%s %s!", - oldconst->option1, oldconst->choice1)); - free(consts->constraints); - free(consts); - continue; - } - - if (!_cups_strncasecmp(oldconst->option2, "Custom", 6) && - !_cups_strcasecmp(oldconst->choice2, "True")) - { - constptr[1].option = ppdFindOption(ppd, oldconst->option2 + 6); - constptr[1].choice = ppdFindChoice(constptr[1].option, "Custom"); - constptr[1].installable = 0; - } - else - { - constptr[1].option = ppdFindOption(ppd, oldconst->option2); - constptr[1].choice = ppdFindChoice(constptr[1].option, - oldconst->choice2); - constptr[1].installable = ppd_is_installable(installable, - oldconst->option2); - } - - if (!constptr[1].option || (!constptr[1].choice && oldconst->choice2[0])) - { - DEBUG_printf(("8ppd_load_constraints: Unknown option *%s %s!", - oldconst->option2, oldconst->choice2)); - free(consts->constraints); - free(consts); - continue; - } - - consts->installable = constptr[0].installable || constptr[1].installable; - - /* - * Add it to the constraints array... - */ - - cupsArrayAdd(ppd->cups_uiconstraints, consts); - } - - /* - * Then load new-style constraints... - */ - - for (constattr = ppdFindAttr(ppd, "cupsUIConstraints", NULL); - constattr; - constattr = ppdFindNextAttr(ppd, "cupsUIConstraints", NULL)) - { - if (!constattr->value) - { - DEBUG_puts("8ppd_load_constraints: Bad cupsUIConstraints value!"); - continue; - } - - for (i = 0, vptr = strchr(constattr->value, '*'); - vptr; - i ++, vptr = strchr(vptr + 1, '*')); - - if (i == 0) - { - DEBUG_puts("8ppd_load_constraints: Bad cupsUIConstraints value!"); - continue; - } - - if ((consts = calloc(1, sizeof(_ppd_cups_uiconsts_t))) == NULL) - { - DEBUG_puts("8ppd_load_constraints: Unable to allocate memory for " - "cupsUIConstraints!"); - return; - } - - if ((constptr = calloc(i, sizeof(_ppd_cups_uiconst_t))) == NULL) - { - free(consts); - DEBUG_puts("8ppd_load_constraints: Unable to allocate memory for " - "cupsUIConstraints!"); - return; - } - - consts->num_constraints = i; - consts->constraints = constptr; - - strlcpy(consts->resolver, constattr->spec, sizeof(consts->resolver)); - - for (i = 0, vptr = strchr(constattr->value, '*'); - vptr; - i ++, vptr = strchr(vptr, '*'), constptr ++) - { - /* - * Extract "*Option Choice" or just "*Option"... - */ - - for (vptr ++, ptr = option; *vptr && !_cups_isspace(*vptr); vptr ++) - if (ptr < (option + sizeof(option) - 1)) - *ptr++ = *vptr; - - *ptr = '\0'; - - while (_cups_isspace(*vptr)) - vptr ++; - - if (*vptr == '*') - choice[0] = '\0'; - else - { - for (ptr = choice; *vptr && !_cups_isspace(*vptr); vptr ++) - if (ptr < (choice + sizeof(choice) - 1)) - *ptr++ = *vptr; - - *ptr = '\0'; - } - - if (!_cups_strncasecmp(option, "Custom", 6) && !_cups_strcasecmp(choice, "True")) - { - _cups_strcpy(option, option + 6); - strcpy(choice, "Custom"); - } - - constptr->option = ppdFindOption(ppd, option); - constptr->choice = ppdFindChoice(constptr->option, choice); - constptr->installable = ppd_is_installable(installable, option); - consts->installable |= constptr->installable; - - if (!constptr->option || (!constptr->choice && choice[0])) - { - DEBUG_printf(("8ppd_load_constraints: Unknown option *%s %s!", - option, choice)); - break; - } - } - - if (!vptr) - cupsArrayAdd(ppd->cups_uiconstraints, consts); - else - { - free(consts->constraints); - free(consts); - } - } -} - - -/* - * 'ppd_test_constraints()' - See if any constraints are active. - */ - -static cups_array_t * /* O - Array of active constraints */ -ppd_test_constraints( - ppd_file_t *ppd, /* I - PPD file */ - const char *option, /* I - Current option */ - const char *choice, /* I - Current choice */ - int num_options, /* I - Number of additional options */ - cups_option_t *options, /* I - Additional options */ - int which) /* I - Which constraints to test */ -{ - int i; /* Looping var */ - _ppd_cups_uiconsts_t *consts; /* Current constraints */ - _ppd_cups_uiconst_t *constptr; /* Current constraint */ - ppd_choice_t key, /* Search key */ - *marked; /* Marked choice */ - cups_array_t *active = NULL; /* Active constraints */ - const char *value, /* Current value */ - *firstvalue; /* AP_FIRSTPAGE_Keyword value */ - char firstpage[255]; /* AP_FIRSTPAGE_Keyword string */ - - - DEBUG_printf(("7ppd_test_constraints(ppd=%p, option=\"%s\", choice=\"%s\", " - "num_options=%d, options=%p, which=%d)", ppd, option, choice, - num_options, options, which)); - - if (!ppd->cups_uiconstraints) - ppd_load_constraints(ppd); - - DEBUG_printf(("9ppd_test_constraints: %d constraints!", - cupsArrayCount(ppd->cups_uiconstraints))); - - cupsArraySave(ppd->marked); - - for (consts = (_ppd_cups_uiconsts_t *)cupsArrayFirst(ppd->cups_uiconstraints); - consts; - consts = (_ppd_cups_uiconsts_t *)cupsArrayNext(ppd->cups_uiconstraints)) - { - DEBUG_printf(("9ppd_test_constraints: installable=%d, resolver=\"%s\", " - "num_constraints=%d option1=\"%s\", choice1=\"%s\", " - "option2=\"%s\", choice2=\"%s\", ...", - consts->installable, consts->resolver, consts->num_constraints, - consts->constraints[0].option->keyword, - consts->constraints[0].choice ? - consts->constraints[0].choice->choice : "", - consts->constraints[1].option->keyword, - consts->constraints[1].choice ? - consts->constraints[1].choice->choice : "")); - - if (consts->installable && which < _PPD_INSTALLABLE_CONSTRAINTS) - continue; /* Skip installable option constraint */ - - if (!consts->installable && which == _PPD_INSTALLABLE_CONSTRAINTS) - continue; /* Skip non-installable option constraint */ - - if (which == _PPD_OPTION_CONSTRAINTS && option) - { - /* - * Skip constraints that do not involve the current option... - */ - - for (i = consts->num_constraints, constptr = consts->constraints; - i > 0; - i --, constptr ++) - { - if (!_cups_strcasecmp(constptr->option->keyword, option)) - break; - - if (!_cups_strncasecmp(option, "AP_FIRSTPAGE_", 13) && - !_cups_strcasecmp(constptr->option->keyword, option + 13)) - break; - } - - if (!i) - continue; - } - - DEBUG_puts("9ppd_test_constraints: Testing..."); - - for (i = consts->num_constraints, constptr = consts->constraints; - i > 0; - i --, constptr ++) - { - DEBUG_printf(("9ppd_test_constraints: %s=%s?", constptr->option->keyword, - constptr->choice ? constptr->choice->choice : "")); - - if (constptr->choice && - (!_cups_strcasecmp(constptr->option->keyword, "PageSize") || - !_cups_strcasecmp(constptr->option->keyword, "PageRegion"))) - { - /* - * PageSize and PageRegion are used depending on the selected input slot - * and manual feed mode. Validate against the selected page size instead - * of an individual option... - */ - - if (option && choice && - (!_cups_strcasecmp(option, "PageSize") || - !_cups_strcasecmp(option, "PageRegion"))) - { - value = choice; - } - else if ((value = cupsGetOption("PageSize", num_options, - options)) == NULL) - if ((value = cupsGetOption("PageRegion", num_options, - options)) == NULL) - if ((value = cupsGetOption("media", num_options, options)) == NULL) - { - ppd_size_t *size = ppdPageSize(ppd, NULL); - - if (size) - value = size->name; - } - - if (value && !_cups_strncasecmp(value, "Custom.", 7)) - value = "Custom"; - - if (option && choice && - (!_cups_strcasecmp(option, "AP_FIRSTPAGE_PageSize") || - !_cups_strcasecmp(option, "AP_FIRSTPAGE_PageRegion"))) - { - firstvalue = choice; - } - else if ((firstvalue = cupsGetOption("AP_FIRSTPAGE_PageSize", - num_options, options)) == NULL) - firstvalue = cupsGetOption("AP_FIRSTPAGE_PageRegion", num_options, - options); - - if (firstvalue && !_cups_strncasecmp(firstvalue, "Custom.", 7)) - firstvalue = "Custom"; - - if ((!value || _cups_strcasecmp(value, constptr->choice->choice)) && - (!firstvalue || _cups_strcasecmp(firstvalue, constptr->choice->choice))) - { - DEBUG_puts("9ppd_test_constraints: NO"); - break; - } - } - else if (constptr->choice) - { - /* - * Compare against the constrained choice... - */ - - if (option && choice && !_cups_strcasecmp(option, constptr->option->keyword)) - { - if (!_cups_strncasecmp(choice, "Custom.", 7)) - value = "Custom"; - else - value = choice; - } - else if ((value = cupsGetOption(constptr->option->keyword, num_options, - options)) != NULL) - { - if (!_cups_strncasecmp(value, "Custom.", 7)) - value = "Custom"; - } - else if (constptr->choice->marked) - value = constptr->choice->choice; - else - value = NULL; - - /* - * Now check AP_FIRSTPAGE_option... - */ - - snprintf(firstpage, sizeof(firstpage), "AP_FIRSTPAGE_%s", - constptr->option->keyword); - - if (option && choice && !_cups_strcasecmp(option, firstpage)) - { - if (!_cups_strncasecmp(choice, "Custom.", 7)) - firstvalue = "Custom"; - else - firstvalue = choice; - } - else if ((firstvalue = cupsGetOption(firstpage, num_options, - options)) != NULL) - { - if (!_cups_strncasecmp(firstvalue, "Custom.", 7)) - firstvalue = "Custom"; - } - else - firstvalue = NULL; - - DEBUG_printf(("9ppd_test_constraints: value=%s, firstvalue=%s", value, - firstvalue)); - - if ((!value || _cups_strcasecmp(value, constptr->choice->choice)) && - (!firstvalue || _cups_strcasecmp(firstvalue, constptr->choice->choice))) - { - DEBUG_puts("9ppd_test_constraints: NO"); - break; - } - } - else if (option && choice && - !_cups_strcasecmp(option, constptr->option->keyword)) - { - if (!_cups_strcasecmp(choice, "None") || !_cups_strcasecmp(choice, "Off") || - !_cups_strcasecmp(choice, "False")) - { - DEBUG_puts("9ppd_test_constraints: NO"); - break; - } - } - else if ((value = cupsGetOption(constptr->option->keyword, num_options, - options)) != NULL) - { - if (!_cups_strcasecmp(value, "None") || !_cups_strcasecmp(value, "Off") || - !_cups_strcasecmp(value, "False")) - { - DEBUG_puts("9ppd_test_constraints: NO"); - break; - } - } - else - { - key.option = constptr->option; - - if ((marked = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) - == NULL || - (!_cups_strcasecmp(marked->choice, "None") || - !_cups_strcasecmp(marked->choice, "Off") || - !_cups_strcasecmp(marked->choice, "False"))) - { - DEBUG_puts("9ppd_test_constraints: NO"); - break; - } - } - } - - if (i <= 0) - { - if (!active) - active = cupsArrayNew(NULL, NULL); - - cupsArrayAdd(active, consts); - DEBUG_puts("9ppd_test_constraints: Added..."); - } - } - - cupsArrayRestore(ppd->marked); - - DEBUG_printf(("8ppd_test_constraints: Found %d active constraints!", - cupsArrayCount(active))); - - return (active); -} - - -/* - * End of "$Id: conflicts.c 3794 2012-04-23 22:44:16Z msweet $". - */ diff --git a/cups/cups-private.h b/cups/cups-private.h index 6fd66a9..f1b052a 100644 --- a/cups/cups-private.h +++ b/cups/cups-private.h @@ -1,16 +1,11 @@ /* * Private definitions for CUPS. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ #ifndef _CUPS_CUPS_PRIVATE_H_ @@ -21,7 +16,6 @@ */ # include "string-private.h" -# include "debug-private.h" # include "array-private.h" # include "ipp-private.h" # include "http-private.h" @@ -56,6 +50,24 @@ typedef struct _cups_buffer_s /**** Read/write buffer ****/ d[1]; /* Data buffer */ } _cups_buffer_t; +typedef struct _cups_raster_error_s /**** Error buffer structure ****/ +{ + char *start, /* Start of buffer */ + *current, /* Current position in buffer */ + *end; /* End of buffer */ +} _cups_raster_error_t; + +typedef enum _cups_uatokens_e /**** UserAgentTokens values */ +{ + _CUPS_UATOKENS_NONE, /* Do not send User-Agent */ + _CUPS_UATOKENS_PRODUCT_ONLY, /* CUPS IPP */ + _CUPS_UATOKENS_MAJOR, /* CUPS/major IPP/2 */ + _CUPS_UATOKENS_MINOR, /* CUPS/major.minor IPP/2.1 */ + _CUPS_UATOKENS_MINIMAL, /* CUPS/major.minor.patch IPP/2.1 */ + _CUPS_UATOKENS_OS, /* CUPS/major.minor.patch (osname osversion) IPP/2.1 */ + _CUPS_UATOKENS_FULL /* CUPS/major.minor.patch (osname osversion; architecture) IPP/2.1 */ +} _cups_uatokens_t; + typedef struct _cups_globals_s /**** CUPS global state data ****/ { /* Multiple places... */ @@ -127,6 +139,9 @@ typedef struct _cups_globals_s /**** CUPS global state data ****/ char pwg_name[65], /* PWG media name for custom size */ ppd_name[41]; /* PPD media name for custom size */ + /* raster-error.c */ + _cups_raster_error_t raster_error; /* Raster error information */ + /* request.c */ http_t *http; /* Current server connection */ ipp_status_t last_error; /* Last IPP error */ @@ -142,6 +157,7 @@ typedef struct _cups_globals_s /**** CUPS global state data ****/ char tempfile[1024]; /* cupsTempFd/File buffer */ /* usersys.c */ + _cups_uatokens_t uatokens; /* UserAgentTokens setting */ http_encryption_t encryption; /* Encryption setting */ char user[65], /* User name */ user_agent[256],/* User-Agent string */ @@ -224,44 +240,38 @@ struct _cups_dinfo_s /* Destination capability and status */ # ifdef __APPLE__ -extern CFStringRef _cupsAppleCopyDefaultPaperID(void); -extern CFStringRef _cupsAppleCopyDefaultPrinter(void); -extern int _cupsAppleGetUseLastPrinter(void); -extern void _cupsAppleSetDefaultPaperID(CFStringRef name); -extern void _cupsAppleSetDefaultPrinter(CFStringRef name); -extern void _cupsAppleSetUseLastPrinter(int uselast); +extern CFStringRef _cupsAppleCopyDefaultPaperID(void) _CUPS_PRIVATE; +extern CFStringRef _cupsAppleCopyDefaultPrinter(void) _CUPS_PRIVATE; +extern int _cupsAppleGetUseLastPrinter(void) _CUPS_PRIVATE; +extern void _cupsAppleSetDefaultPaperID(CFStringRef name) _CUPS_PRIVATE; +extern void _cupsAppleSetDefaultPrinter(CFStringRef name) _CUPS_PRIVATE; +extern void _cupsAppleSetUseLastPrinter(int uselast) _CUPS_PRIVATE; # endif /* __APPLE__ */ -extern char *_cupsBufferGet(size_t size); -extern void _cupsBufferRelease(char *b); +extern char *_cupsBufferGet(size_t size) _CUPS_PRIVATE; +extern void _cupsBufferRelease(char *b) _CUPS_PRIVATE; -extern http_t *_cupsConnect(void); -extern char *_cupsCreateDest(const char *name, const char *info, const char *device_id, const char *device_uri, char *uri, size_t urisize); -extern int _cupsGet1284Values(const char *device_id, - cups_option_t **values); -extern const char *_cupsGetDestResource(cups_dest_t *dest, char *resource, - size_t resourcesize); -extern int _cupsGetDests(http_t *http, ipp_op_t op, - const char *name, cups_dest_t **dests, - cups_ptype_t type, cups_ptype_t mask); -extern const char *_cupsGetPassword(const char *prompt); -extern void _cupsGlobalLock(void); -extern _cups_globals_t *_cupsGlobals(void); -extern void _cupsGlobalUnlock(void); +extern http_t *_cupsConnect(void) _CUPS_PRIVATE; +extern char *_cupsCreateDest(const char *name, const char *info, const char *device_id, const char *device_uri, char *uri, size_t urisize) _CUPS_PRIVATE; +extern ipp_attribute_t *_cupsEncodeOption(ipp_t *ipp, ipp_tag_t group_tag, _ipp_option_t *map, const char *name, const char *value) _CUPS_PRIVATE; +extern int _cupsGet1284Values(const char *device_id, cups_option_t **values) _CUPS_PRIVATE; +extern const char *_cupsGetDestResource(cups_dest_t *dest, unsigned flags, char *resource, size_t resourcesize) _CUPS_PRIVATE; +extern int _cupsGetDests(http_t *http, ipp_op_t op, const char *name, cups_dest_t **dests, cups_ptype_t type, cups_ptype_t mask) _CUPS_PRIVATE; +extern const char *_cupsGetPassword(const char *prompt) _CUPS_PRIVATE; +extern void _cupsGlobalLock(void) _CUPS_PRIVATE; +extern _cups_globals_t *_cupsGlobals(void) _CUPS_PRIVATE; +extern void _cupsGlobalUnlock(void) _CUPS_PRIVATE; # ifdef HAVE_GSSAPI -extern const char *_cupsGSSServiceName(void); +extern const char *_cupsGSSServiceName(void) _CUPS_PRIVATE; # endif /* HAVE_GSSAPI */ -extern int _cupsNextDelay(int current, int *previous); -extern void _cupsSetDefaults(void); -extern void _cupsSetError(ipp_status_t status, const char *message, - int localize); -extern void _cupsSetHTTPError(http_status_t status); +extern int _cupsNextDelay(int current, int *previous) _CUPS_PRIVATE; +extern void _cupsSetDefaults(void) _CUPS_INTERNAL; +extern void _cupsSetError(ipp_status_t status, const char *message, int localize) _CUPS_PRIVATE; +extern void _cupsSetHTTPError(http_status_t status) _CUPS_INTERNAL; # ifdef HAVE_GSSAPI -extern int _cupsSetNegotiateAuthString(http_t *http, - const char *method, - const char *resource); +extern int _cupsSetNegotiateAuthString(http_t *http, const char *method, const char *resource) _CUPS_PRIVATE; # endif /* HAVE_GSSAPI */ -extern char *_cupsUserDefault(char *name, size_t namesize); +extern char *_cupsUserDefault(char *name, size_t namesize) _CUPS_INTERNAL; /* diff --git a/cups/cups.h b/cups/cups.h index a73cf7a..e64fdcc 100644 --- a/cups/cups.h +++ b/cups/cups.h @@ -1,16 +1,11 @@ /* * API definitions for CUPS. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ #ifndef _CUPS_CUPS_H_ @@ -21,12 +16,12 @@ */ # include -# if defined(WIN32) && !defined(__CUPS_SSIZE_T_DEFINED) +# if defined(_WIN32) && !defined(__CUPS_SSIZE_T_DEFINED) # define __CUPS_SSIZE_T_DEFINED # include /* Windows does not support the ssize_t type, so map it to long... */ typedef long ssize_t; /* @private@ */ -# endif /* WIN32 && !__CUPS_SSIZE_T_DEFINED */ +# endif /* _WIN32 && !__CUPS_SSIZE_T_DEFINED */ # include "file.h" # include "ipp.h" @@ -47,10 +42,10 @@ extern "C" { * Constants... */ -# define CUPS_VERSION 2.0204 +# define CUPS_VERSION 2.0300 # define CUPS_VERSION_MAJOR 2 -# define CUPS_VERSION_MINOR 2 -# define CUPS_VERSION_PATCH 4 +# define CUPS_VERSION_MINOR 3 +# define CUPS_VERSION_PATCH 0 # define CUPS_BC_FD 3 /* Back-channel file descriptor for @@ -334,55 +329,55 @@ typedef int (*cups_server_cert_cb_t)(http_t *http, void *tls, * Functions... */ -extern int cupsCancelJob(const char *name, int job_id); +extern int cupsCancelJob(const char *name, int job_id) _CUPS_PUBLIC; extern ipp_t *cupsDoFileRequest(http_t *http, ipp_t *request, const char *resource, - const char *filename); + const char *filename) _CUPS_PUBLIC; extern ipp_t *cupsDoRequest(http_t *http, ipp_t *request, - const char *resource); + const char *resource) _CUPS_PUBLIC; extern http_encryption_t cupsEncryption(void); -extern void cupsFreeJobs(int num_jobs, cups_job_t *jobs); +extern void cupsFreeJobs(int num_jobs, cups_job_t *jobs) _CUPS_PUBLIC; extern int cupsGetClasses(char ***classes) _CUPS_DEPRECATED_MSG("Use cupsEnumDests instead."); -extern const char *cupsGetDefault(void); +extern const char *cupsGetDefault(void) _CUPS_PUBLIC; extern int cupsGetJobs(cups_job_t **jobs, const char *name, - int myjobs, int whichjobs); + int myjobs, int whichjobs) _CUPS_PUBLIC; extern int cupsGetPrinters(char ***printers) _CUPS_DEPRECATED_MSG("Use cupsEnumDests instead."); -extern ipp_status_t cupsLastError(void); +extern ipp_status_t cupsLastError(void) _CUPS_PUBLIC; extern int cupsPrintFile(const char *name, const char *filename, const char *title, int num_options, - cups_option_t *options); + cups_option_t *options) _CUPS_PUBLIC; extern int cupsPrintFiles(const char *name, int num_files, const char **files, const char *title, - int num_options, cups_option_t *options); + int num_options, cups_option_t *options) _CUPS_PUBLIC; extern char *cupsTempFile(char *filename, int len) _CUPS_DEPRECATED_MSG("Use cupsTempFd or cupsTempFile2 instead."); -extern int cupsTempFd(char *filename, int len); +extern int cupsTempFd(char *filename, int len) _CUPS_PUBLIC; extern int cupsAddDest(const char *name, const char *instance, - int num_dests, cups_dest_t **dests); -extern void cupsFreeDests(int num_dests, cups_dest_t *dests); + int num_dests, cups_dest_t **dests) _CUPS_PUBLIC; +extern void cupsFreeDests(int num_dests, cups_dest_t *dests) _CUPS_PUBLIC; extern cups_dest_t *cupsGetDest(const char *name, const char *instance, - int num_dests, cups_dest_t *dests); -extern int cupsGetDests(cups_dest_t **dests); -extern void cupsSetDests(int num_dests, cups_dest_t *dests); + int num_dests, cups_dest_t *dests) _CUPS_PUBLIC; +extern int cupsGetDests(cups_dest_t **dests) _CUPS_PUBLIC; +extern void cupsSetDests(int num_dests, cups_dest_t *dests) _CUPS_PUBLIC; extern int cupsAddOption(const char *name, const char *value, - int num_options, cups_option_t **options); + int num_options, cups_option_t **options) _CUPS_PUBLIC; extern void cupsEncodeOptions(ipp_t *ipp, int num_options, - cups_option_t *options); + cups_option_t *options) _CUPS_PUBLIC; extern void cupsFreeOptions(int num_options, - cups_option_t *options); + cups_option_t *options) _CUPS_PUBLIC; extern const char *cupsGetOption(const char *name, int num_options, - cups_option_t *options); + cups_option_t *options) _CUPS_PUBLIC; extern int cupsParseOptions(const char *arg, int num_options, - cups_option_t **options); + cups_option_t **options) _CUPS_PUBLIC; -extern const char *cupsGetPassword(const char *prompt); -extern const char *cupsServer(void); -extern void cupsSetEncryption(http_encryption_t e); -extern void cupsSetPasswordCB(cups_password_cb_t cb); -extern void cupsSetServer(const char *server); -extern void cupsSetUser(const char *user); -extern const char *cupsUser(void); +extern const char *cupsGetPassword(const char *prompt) _CUPS_PUBLIC; +extern const char *cupsServer(void) _CUPS_PUBLIC; +extern void cupsSetEncryption(http_encryption_t e) _CUPS_PUBLIC; +extern void cupsSetPasswordCB(cups_password_cb_t cb) _CUPS_PUBLIC; +extern void cupsSetServer(const char *server) _CUPS_PUBLIC; +extern void cupsSetUser(const char *user) _CUPS_PUBLIC; +extern const char *cupsUser(void) _CUPS_PUBLIC; /**** New in CUPS 1.1.20 ****/ extern int cupsDoAuthentication(http_t *http, const char *method, @@ -390,7 +385,7 @@ extern int cupsDoAuthentication(http_t *http, const char *method, _CUPS_API_1_1_20; extern http_status_t cupsGetFile(http_t *http, const char *resource, const char *filename) _CUPS_API_1_1_20; -extern http_status_t cupsGetFd(http_t *http, const char *resource, int fd); +extern http_status_t cupsGetFd(http_t *http, const char *resource, int fd) _CUPS_API_1_1_20; extern http_status_t cupsPutFile(http_t *http, const char *resource, const char *filename) _CUPS_API_1_1_20; extern http_status_t cupsPutFd(http_t *http, const char *resource, int fd) @@ -416,10 +411,6 @@ extern int cupsSetDests2(http_t *http, int num_dests, cups_dest_t *dests) _CUPS_API_1_1_21; /**** New in CUPS 1.2/macOS 10.5 ****/ -extern ssize_t cupsBackChannelRead(char *buffer, size_t bytes, - double timeout) _CUPS_API_1_2; -extern ssize_t cupsBackChannelWrite(const char *buffer, size_t bytes, - double timeout) _CUPS_API_1_2; extern void cupsEncodeOptions2(ipp_t *ipp, int num_options, cups_option_t *options, ipp_tag_t group_tag) _CUPS_API_1_2; @@ -606,6 +597,13 @@ extern ssize_t cupsHashData(const char *algorithm, const void *data, size_t dat extern int cupsAddIntegerOption(const char *name, int value, int num_options, cups_option_t **options) _CUPS_API_2_2_4; extern int cupsGetIntegerOption(const char *name, int num_options, cups_option_t *options) _CUPS_API_2_2_4; +/* New in CUPS 2.2.7 */ +extern const char *cupsHashString(const unsigned char *hash, size_t hashsize, char *buffer, size_t bufsize) _CUPS_API_2_2_7; + +/* New in CUPS 2.3 */ +extern int cupsAddDestMediaOptions(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, unsigned flags, cups_size_t *size, int num_options, cups_option_t **options) _CUPS_API_2_3; +extern ipp_attribute_t *cupsEncodeOption(ipp_t *ipp, ipp_tag_t group_tag, const char *name, const char *value) _CUPS_API_2_3; + # ifdef __cplusplus } # endif /* __cplusplus */ diff --git a/cups/cupspm-icon.png b/cups/cupspm-icon.png new file mode 100644 index 0000000..8050934 Binary files /dev/null and b/cups/cupspm-icon.png differ diff --git a/cups/cupspm.md b/cups/cupspm.md new file mode 100644 index 0000000..260b261 --- /dev/null +++ b/cups/cupspm.md @@ -0,0 +1,1005 @@ +--- +title: CUPS Programming Manual +author: Michael R Sweet +copyright: Copyright © 2007-2019 by Apple Inc. All Rights Reserved. +version: 2.3.0 +... + +> Please [file issues on Github](https://github.com/apple/cups/issues) to +> provide feedback on this document. + + +# Introduction + +CUPS provides the "cups" library to talk to the different parts of CUPS and with +Internet Printing Protocol (IPP) printers. The "cups" library functions are +accessed by including the `` header. + +CUPS is based on the Internet Printing Protocol ("IPP"), which allows clients +(applications) to communicate with a server (the scheduler, printers, etc.) to +get a list of destinations, send print jobs, and so forth. You identify which +server you want to communicate with using a pointer to the opaque structure +`http_t`. The `CUPS_HTTP_DEFAULT` constant can be used when you want to talk to +the CUPS scheduler. + + +## Guidelines + +When writing software (other than printer drivers) that uses the "cups" library: + +- Do not use undocumented or deprecated APIs, +- Do not rely on pre-configured printers, +- Do not assume that printers support specific features or formats, and +- Do not rely on implementation details (PPDs, etc.) + +CUPS is designed to insulate users and developers from the implementation +details of printers and file formats. The goal is to allow an application to +supply a print file in a standard format with the user intent ("print four +copies, two-sided on A4 media, and staple each copy") and have the printing +system manage the printer communication and format conversion needed. + +Similarly, printer and job management applications can use standard query +operations to obtain the status information in a common, generic form and use +standard management operations to control the state of those printers and jobs. + +> **Note:** +> +> CUPS printer drivers necessarily depend on specific file formats and certain +> implementation details of the CUPS software. Please consult the Postscript +> and raster printer driver developer documentation on +> [CUPS.org](https://www.cups.org/documentation.html) for more information. + + +## Terms Used in This Document + +A *Destination* is a printer or print queue that accepts print jobs. A +*Print Job* is a collection of one or more documents that are processed by a +destination using options supplied when creating the job. A *Document* is a +file (JPEG image, PDF file, etc.) suitable for printing. An *Option* controls +some aspect of printing, such as the media used. *Media* is the sheets or roll +that is printed on. An *Attribute* is an option encoded for an Internet +Printing Protocol (IPP) request. + + +## Compiling Programs That Use the CUPS API + +The CUPS libraries can be used from any C, C++, or Objective C program. +The method of compiling against the libraries varies depending on the +operating system and installation of CUPS. The following sections show how +to compile a simple program (shown below) in two common environments. + +The following simple program lists the available destinations: + + #include + #include + + int print_dest(void *user_data, unsigned flags, cups_dest_t *dest) + { + if (dest->instance) + printf("%s/%s\n", dest->name, dest->instance); + else + puts(dest->name); + + return (1); + } + + int main(void) + { + cupsEnumDests(CUPS_DEST_FLAGS_NONE, 1000, NULL, 0, 0, print_dest, NULL); + + return (0); + } + + +### Compiling with Xcode + +In Xcode, choose *New Project...* from the *File* menu (or press SHIFT+CMD+N), +then select the *Command Line Tool* under the macOS Application project type. +Click *Next* and enter a name for the project, for example "firstcups". Click +*Next* and choose a project directory. The click *Next* to create the project. + +In the project window, click on the *Build Phases* group and expand the +*Link Binary with Libraries* section. Click *+*, type "libcups" to show the +library, and then double-click on `libcups.tbd`. + +Finally, click on the `main.c` file in the sidebar and copy the example program +to the file. Build and run (CMD+R) to see the list of destinations. + + +### Compiling with GCC + +From the command-line, create a file called `sample.c` using your favorite +editor, copy the example to this file, and save. Then run the following command +to compile it with GCC and run it: + + gcc -o simple `cups-config --cflags` simple.c `cups-config --libs` + ./simple + +The `cups-config` command provides the compiler flags (`cups-config --cflags`) +and libraries (`cups-config --libs`) needed for the local system. + + +# Working with Destinations + +Destinations, which in CUPS represent individual printers or classes +(collections or pools) of printers, are represented by the `cups_dest_t` +structure which includes the name \(`name`), instance \(`instance`, saved +options/settings), whether the destination is the default for the user +\(`is_default`), and the options and basic information associated with that +destination \(`num_options` and `options`). + +Historically destinations have been manually maintained by the administrator of +a system or network, but CUPS also supports dynamic discovery of destinations on +the current network. + + +## Finding Available Destinations + +The `cupsEnumDests` function finds all of the available destinations: + + int + cupsEnumDests(unsigned flags, int msec, int *cancel, + cups_ptype_t type, cups_ptype_t mask, + cups_dest_cb_t cb, void *user_data) + +The `flags` argument specifies enumeration options, which at present must be +`CUPS_DEST_FLAGS_NONE`. + +The `msec` argument specifies the maximum amount of time that should be used for +enumeration in milliseconds - interactive applications should keep this value to +5000 or less when run on the main thread. + +The `cancel` argument points to an integer variable that, when set to a non-zero +value, will cause enumeration to stop as soon as possible. It can be `NULL` if +not needed. + +The `type` and `mask` arguments are bitfields that allow the caller to filter +the destinations based on categories and/or capabilities. The destination's +"printer-type" value is masked by the `mask` value and compared to the `type` +value when filtering. For example, to only enumerate destinations that are +hosted on the local system, pass `CUPS_PRINTER_LOCAL` for the `type` argument +and `CUPS_PRINTER_DISCOVERED` for the `mask` argument. The following constants +can be used for filtering: + +- `CUPS_PRINTER_CLASS`: A collection of destinations. +- `CUPS_PRINTER_FAX`: A facsimile device. +- `CUPS_PRINTER_LOCAL`: A local printer or class. This constant has the value 0 + (no bits set) and is only used for the `type` argument and is paired with the + `CUPS_PRINTER_REMOTE` or `CUPS_PRINTER_DISCOVERED` constant passed in the + `mask` argument. +- `CUPS_PRINTER_REMOTE`: A remote (shared) printer or class. +- `CUPS_PRINTER_DISCOVERED`: An available network printer or class. +- `CUPS_PRINTER_BW`: Can do B&W printing. +- `CUPS_PRINTER_COLOR`: Can do color printing. +- `CUPS_PRINTER_DUPLEX`: Can do two-sided printing. +- `CUPS_PRINTER_STAPLE`: Can staple output. +- `CUPS_PRINTER_COLLATE`: Can quickly collate copies. +- `CUPS_PRINTER_PUNCH`: Can punch output. +- `CUPS_PRINTER_COVER`: Can cover output. +- `CUPS_PRINTER_BIND`: Can bind output. +- `CUPS_PRINTER_SORT`: Can sort output (mailboxes, etc.) +- `CUPS_PRINTER_SMALL`: Can print on Letter/Legal/A4-size media. +- `CUPS_PRINTER_MEDIUM`: Can print on Tabloid/B/C/A3/A2-size media. +- `CUPS_PRINTER_LARGE`: Can print on D/E/A1/A0-size media. +- `CUPS_PRINTER_VARIABLE`: Can print on rolls and custom-size media. + +The `cb` argument specifies a function to call for every destination that is +found: + + typedef int (*cups_dest_cb_t)(void *user_data, + unsigned flags, + cups_dest_t *dest); + +The callback function receives a copy of the `user_data` argument along with a +bitfield \(`flags`) and the destination that was found. The `flags` argument +can have any of the following constant (bit) values set: + +- `CUPS_DEST_FLAGS_MORE`: There are more destinations coming. +- `CUPS_DEST_FLAGS_REMOVED`: The destination has gone away and should be removed + from the list of destinations a user can select. +- `CUPS_DEST_FLAGS_ERROR`: An error occurred. The reason for the error can be + found by calling the `cupsLastError` and/or `cupsLastErrorString` functions. + +The callback function returns 0 to stop enumeration or 1 to continue. + +> **Note:** +> +> The callback function will likely be called multiple times for the +> same destination, so it is up to the caller to suppress any duplicate +> destinations. + +The following example shows how to use `cupsEnumDests` to get a filtered array +of destinations: + + typedef struct + { + int num_dests; + cups_dest_t *dests; + } my_user_data_t; + + int + my_dest_cb(my_user_data_t *user_data, unsigned flags, + cups_dest_t *dest) + { + if (flags & CUPS_DEST_FLAGS_REMOVED) + { + /* + * Remove destination from array... + */ + + user_data->num_dests = + cupsRemoveDest(dest->name, dest->instance, + user_data->num_dests, + &(user_data->dests)); + } + else + { + /* + * Add destination to array... + */ + + user_data->num_dests = + cupsCopyDest(dest, user_data->num_dests, + &(user_data->dests)); + } + + return (1); + } + + int + my_get_dests(cups_ptype_t type, cups_ptype_t mask, + cups_dest_t **dests) + { + my_user_data_t user_data = { 0, NULL }; + + if (!cupsEnumDests(CUPS_DEST_FLAGS_NONE, 1000, NULL, type, + mask, (cups_dest_cb_t)my_dest_cb, + &user_data)) + { + /* + * An error occurred, free all of the destinations and + * return... + */ + + cupsFreeDests(user_data.num_dests, user_dasta.dests); + + *dests = NULL; + + return (0); + } + + /* + * Return the destination array... + */ + + *dests = user_data.dests; + + return (user_data.num_dests); + } + + +## Basic Destination Information + +The `num_options` and `options` members of the `cups_dest_t` structure provide +basic attributes about the destination in addition to the user default options +and values for that destination. The following names are predefined for various +destination attributes: + +- "auth-info-required": The type of authentication required for printing to this + destination: "none", "username,password", "domain,username,password", or + "negotiate" (Kerberos). +- "printer-info": The human-readable description of the destination such as "My + Laser Printer". +- "printer-is-accepting-jobs": "true" if the destination is accepting new jobs, + "false" otherwise. +- "printer-is-shared": "true" if the destination is being shared with other + computers, "false" otherwise. +- "printer-location": The human-readable location of the destination such as + "Lab 4". +- "printer-make-and-model": The human-readable make and model of the destination + such as "ExampleCorp LaserPrinter 4000 Series". +- "printer-state": "3" if the destination is idle, "4" if the destination is + printing a job, and "5" if the destination is stopped. +- "printer-state-change-time": The UNIX time when the destination entered the + current state. +- "printer-state-reasons": Additional comma-delimited state keywords for the + destination such as "media-tray-empty-error" and "toner-low-warning". +- "printer-type": The `cups_ptype_t` value associated with the destination. +- "printer-uri-supported": The URI associated with the destination; if not set, + this destination was discovered but is not yet setup as a local printer. + +Use the `cupsGetOption` function to retrieve the value. For example, the +following code gets the make and model of a destination: + + const char *model = cupsGetOption("printer-make-and-model", + dest->num_options, + dest->options); + + +## Detailed Destination Information + +Once a destination has been chosen, the `cupsCopyDestInfo` function can be used +to gather detailed information about the destination: + + cups_dinfo_t * + cupsCopyDestInfo(http_t *http, cups_dest_t *dest); + +The `http` argument specifies a connection to the CUPS scheduler and is +typically the constant `CUPS_HTTP_DEFAULT`. The `dest` argument specifies the +destination to query. + +The `cups_dinfo_t` structure that is returned contains a snapshot of the +supported options and their supported, ready, and default values. It also can +report constraints between different options and values, and recommend changes +to resolve those constraints. + + +### Getting Supported Options and Values + +The `cupsCheckDestSupported` function can be used to test whether a particular +option or option and value is supported: + + int + cupsCheckDestSupported(http_t *http, cups_dest_t *dest, + cups_dinfo_t *info, + const char *option, + const char *value); + +The `option` argument specifies the name of the option to check. The following +constants can be used to check the various standard options: + +- `CUPS_COPIES`: Controls the number of copies that are produced. +- `CUPS_FINISHINGS`: A comma-delimited list of integer constants that control + the finishing processes that are applied to the job, including stapling, + punching, and folding. +- `CUPS_MEDIA`: Controls the media size that is used, typically one of the + following: `CUPS_MEDIA_3X5`, `CUPS_MEDIA_4X6`, `CUPS_MEDIA_5X7`, + `CUPS_MEDIA_8X10`, `CUPS_MEDIA_A3`, `CUPS_MEDIA_A4`, `CUPS_MEDIA_A5`, + `CUPS_MEDIA_A6`, `CUPS_MEDIA_ENV10`, `CUPS_MEDIA_ENVDL`, `CUPS_MEDIA_LEGAL`, + `CUPS_MEDIA_LETTER`, `CUPS_MEDIA_PHOTO_L`, `CUPS_MEDIA_SUPERBA3`, or + `CUPS_MEDIA_TABLOID`. +- `CUPS_MEDIA_SOURCE`: Controls where the media is pulled from, typically either + `CUPS_MEDIA_SOURCE_AUTO` or `CUPS_MEDIA_SOURCE_MANUAL`. +- `CUPS_MEDIA_TYPE`: Controls the type of media that is used, typically one of + the following: `CUPS_MEDIA_TYPE_AUTO`, `CUPS_MEDIA_TYPE_ENVELOPE`, + `CUPS_MEDIA_TYPE_LABELS`, `CUPS_MEDIA_TYPE_LETTERHEAD`, + `CUPS_MEDIA_TYPE_PHOTO`, `CUPS_MEDIA_TYPE_PHOTO_GLOSSY`, + `CUPS_MEDIA_TYPE_PHOTO_MATTE`, `CUPS_MEDIA_TYPE_PLAIN`, or + `CUPS_MEDIA_TYPE_TRANSPARENCY`. +- `CUPS_NUMBER_UP`: Controls the number of document pages that are placed on + each media side. +- `CUPS_ORIENTATION`: Controls the orientation of document pages placed on the + media: `CUPS_ORIENTATION_PORTRAIT` or `CUPS_ORIENTATION_LANDSCAPE`. +- `CUPS_PRINT_COLOR_MODE`: Controls whether the output is in color + \(`CUPS_PRINT_COLOR_MODE_COLOR`), grayscale + \(`CUPS_PRINT_COLOR_MODE_MONOCHROME`), or either + \(`CUPS_PRINT_COLOR_MODE_AUTO`). +- `CUPS_PRINT_QUALITY`: Controls the generate quality of the output: + `CUPS_PRINT_QUALITY_DRAFT`, `CUPS_PRINT_QUALITY_NORMAL`, or + `CUPS_PRINT_QUALITY_HIGH`. +- `CUPS_SIDES`: Controls whether prints are placed on one or both sides of the + media: `CUPS_SIDES_ONE_SIDED`, `CUPS_SIDES_TWO_SIDED_PORTRAIT`, or + `CUPS_SIDES_TWO_SIDED_LANDSCAPE`. + +If the `value` argument is `NULL`, the `cupsCheckDestSupported` function returns +whether the option is supported by the destination. Otherwise, the function +returns whether the specified value of the option is supported. + +The `cupsFindDestSupported` function returns the IPP attribute containing the +supported values for a given option: + + ipp_attribute_t * + cupsFindDestSupported(http_t *http, cups_dest_t *dest, + cups_dinfo_t *dinfo, + const char *option); + +For example, the following code prints the supported finishing processes for a +destination, if any, to the standard output: + + cups_dinfo_t *info = cupsCopyDestInfo(CUPS_HTTP_DEFAULT, + dest); + + if (cupsCheckDestSupported(CUPS_HTTP_DEFAULT, dest, info, + CUPS_FINISHINGS, NULL)) + { + ipp_attribute_t *finishings = + cupsFindDestSupported(CUPS_HTTP_DEFAULT, dest, info, + CUPS_FINISHINGS); + int i, count = ippGetCount(finishings); + + puts("finishings supported:"); + for (i = 0; i < count; i ++) + printf(" %d\n", ippGetInteger(finishings, i)); + } + else + puts("finishings not supported."); + +The "job-creation-attributes" option can be queried to get a list of supported +options. For example, the following code prints the list of supported options +to the standard output: + + ipp_attribute_t *attrs = + cupsFindDestSupported(CUPS_HTTP_DEFAULT, dest, info, + "job-creation-attributes"); + int i, count = ippGetCount(attrs); + + for (i = 0; i < count; i ++) + puts(ippGetString(attrs, i, NULL)); + + +### Getting Default Values + +There are two sets of default values - user defaults that are available via the +`num_options` and `options` members of the `cups_dest_t` structure, and +destination defaults that available via the `cups_dinfo_t` structure and the +`cupsFindDestDefault` function which returns the IPP attribute containing the +default value(s) for a given option: + + ipp_attribute_t * + cupsFindDestDefault(http_t *http, cups_dest_t *dest, + cups_dinfo_t *dinfo, + const char *option); + +The user defaults from `cupsGetOption` should always take preference over the +destination defaults. For example, the following code prints the default +finishings value(s) to the standard output: + + const char *def_value = + cupsGetOption(CUPS_FINISHINGS, dest->num_options, + dest->options); + ipp_attribute_t *def_attr = + cupsFindDestDefault(CUPS_HTTP_DEFAULT, dest, info, + CUPS_FINISHINGS); + + if (def_value != NULL) + { + printf("Default finishings: %s\n", def_value); + } + else + { + int i, count = ippGetCount(def_attr); + + printf("Default finishings: %d", + ippGetInteger(def_attr, 0)); + for (i = 1; i < count; i ++) + printf(",%d", ippGetInteger(def_attr, i)); + putchar('\n'); + } + + +### Getting Ready (Loaded) Values + +The finishings and media options also support queries for the ready, or loaded, +values. For example, a printer may have punch and staple finishers installed +but be out of staples - the supported values will list both punch and staple +finishing processes but the ready values will only list the punch processes. +Similarly, a printer may support hundreds of different sizes of media but only +have a single size loaded at any given time - the ready values are limited to +the media that is actually in the printer. + +The `cupsFindDestReady` function finds the IPP attribute containing the ready +values for a given option: + + ipp_attribute_t * + cupsFindDestReady(http_t *http, cups_dest_t *dest, + cups_dinfo_t *dinfo, const char *option); + +For example, the following code lists the ready finishing processes: + + ipp_attribute_t *ready_finishings = + cupsFindDestReady(CUPS_HTTP_DEFAULT, dest, info, + CUPS_FINISHINGS); + + if (ready_finishings != NULL) + { + int i, count = ippGetCount(ready_finishings); + + puts("finishings ready:"); + for (i = 0; i < count; i ++) + printf(" %d\n", ippGetInteger(ready_finishings, i)); + } + else + puts("no finishings are ready."); + + +### Media Size Options + +CUPS provides functions for querying the dimensions and margins for each of the +supported media size options. The `cups_size_t` structure is used to describe a +media size: + + typedef struct cups_size_s + { + char media[128]; + int width, length; + int bottom, left, right, top; + } cups_size_t; + +The `width` and `length` members specify the dimensions of the media in +hundredths of millimeters (1/2540th of an inch). The `bottom`, `left`, `right`, +and `top` members specify the margins of the printable area, also in hundredths +of millimeters. + +The `cupsGetDestMediaByName` and `cupsGetDestMediaBySize` functions lookup the +media size information using a standard media size name or dimensions in +hundredths of millimeters: + + int + cupsGetDestMediaByName(http_t *http, cups_dest_t *dest, + cups_dinfo_t *dinfo, + const char *media, + unsigned flags, cups_size_t *size); + + int + cupsGetDestMediaBySize(http_t *http, cups_dest_t *dest, + cups_dinfo_t *dinfo, + int width, int length, + unsigned flags, cups_size_t *size); + +The `media`, `width`, and `length` arguments specify the size to lookup. The +`flags` argument specifies a bitfield controlling various lookup options: + +- `CUPS_MEDIA_FLAGS_DEFAULT`: Find the closest size supported by the printer. +- `CUPS_MEDIA_FLAGS_BORDERLESS`: Find a borderless size. +- `CUPS_MEDIA_FLAGS_DUPLEX`: Find a size compatible with two-sided printing. +- `CUPS_MEDIA_FLAGS_EXACT`: Find an exact match for the size. +- `CUPS_MEDIA_FLAGS_READY`: If the printer supports media sensing or + configuration of the media in each tray/source, find the size amongst the + "ready" media. + +If a matching size is found for the destination, the size information is stored +in the structure pointed to by the `size` argument and 1 is returned. Otherwise +0 is returned. + +For example, the following code prints the margins for two-sided printing on US +Letter media: + + cups_size_t size; + + if (cupsGetDestMediaByName(CUPS_HTTP_DEFAULT, dest, info, + CUPS_MEDIA_LETTER, + CUPS_MEDIA_FLAGS_DUPLEX, &size)) + { + puts("Margins for duplex US Letter:"); + printf(" Bottom: %.2fin\n", size.bottom / 2540.0); + printf(" Left: %.2fin\n", size.left / 2540.0); + printf(" Right: %.2fin\n", size.right / 2540.0); + printf(" Top: %.2fin\n", size.top / 2540.0); + } + else + puts("Margins for duplex US Letter are not available."); + +You can also enumerate all of the sizes that match a given `flags` value using +the `cupsGetDestMediaByIndex` and `cupsGetDestMediaCount` functions: + + int + cupsGetDestMediaByIndex(http_t *http, cups_dest_t *dest, + cups_dinfo_t *dinfo, int n, + unsigned flags, cups_size_t *size); + + int + cupsGetDestMediaCount(http_t *http, cups_dest_t *dest, + cups_dinfo_t *dinfo, unsigned flags); + +For example, the following code prints the list of ready media and corresponding +margins: + + cups_size_t size; + int i; + int count = cupsGetDestMediaCount(CUPS_HTTP_DEFAULT, + dest, info, + CUPS_MEDIA_FLAGS_READY); + + for (i = 0; i < count; i ++) + { + if (cupsGetDestMediaByIndex(CUPS_HTTP_DEFAULT, dest, info, + i, CUPS_MEDIA_FLAGS_READY, + &size)) + { + printf("%s:\n", size.name); + printf(" Width: %.2fin\n", size.width / 2540.0); + printf(" Length: %.2fin\n", size.length / 2540.0); + printf(" Bottom: %.2fin\n", size.bottom / 2540.0); + printf(" Left: %.2fin\n", size.left / 2540.0); + printf(" Right: %.2fin\n", size.right / 2540.0); + printf(" Top: %.2fin\n", size.top / 2540.0); + } + } + +Finally, the `cupsGetDestMediaDefault` function returns the default media size: + + int + cupsGetDestMediaDefault(http_t *http, cups_dest_t *dest, + cups_dinfo_t *dinfo, unsigned flags, + cups_size_t *size); + + +### Localizing Options and Values + +CUPS provides three functions to get localized, human-readable strings in the +user's current locale for options and values: `cupsLocalizeDestMedia`, +`cupsLocalizeDestOption`, and `cupsLocalizeDestValue`: + + const char * + cupsLocalizeDestMedia(http_t *http, cups_dest_t *dest, + cups_dinfo_t *info, unsigned flags, + cups_size_t *size); + + const char * + cupsLocalizeDestOption(http_t *http, cups_dest_t *dest, + cups_dinfo_t *info, + const char *option); + + const char * + cupsLocalizeDestValue(http_t *http, cups_dest_t *dest, + cups_dinfo_t *info, + const char *option, const char *value); + + +## Submitting a Print Job + +Once you are ready to submit a print job, you create a job using the +`cupsCreateDestJob` function: + + ipp_status_t + cupsCreateDestJob(http_t *http, cups_dest_t *dest, + cups_dinfo_t *info, int *job_id, + const char *title, int num_options, + cups_option_t *options); + +The `title` argument specifies a name for the print job such as "My Document". +The `num_options` and `options` arguments specify the options for the print +job which are allocated using the `cupsAddOption` function. + +When successful, the job's numeric identifier is stored in the integer pointed +to by the `job_id` argument and `IPP_STATUS_OK` is returned. Otherwise, an IPP +error status is returned. + +For example, the following code creates a new job that will print 42 copies of a +two-sided US Letter document: + + int job_id = 0; + int num_options = 0; + cups_option_t *options = NULL; + + num_options = cupsAddOption(CUPS_COPIES, "42", + num_options, &options); + num_options = cupsAddOption(CUPS_MEDIA, CUPS_MEDIA_LETTER, + num_options, &options); + num_options = cupsAddOption(CUPS_SIDES, + CUPS_SIDES_TWO_SIDED_PORTRAIT, + num_options, &options); + + if (cupsCreateDestJob(CUPS_HTTP_DEFAULT, dest, info, + &job_id, "My Document", num_options, + options) == IPP_STATUS_OK) + printf("Created job: %d\n", job_id); + else + printf("Unable to create job: %s\n", + cupsLastErrorString()); + +Once the job is created, you submit documents for the job using the +`cupsStartDestDocument`, `cupsWriteRequestData`, and `cupsFinishDestDocument` +functions: + + http_status_t + cupsStartDestDocument(http_t *http, cups_dest_t *dest, + cups_dinfo_t *info, int job_id, + const char *docname, + const char *format, + int num_options, + cups_option_t *options, + int last_document); + + http_status_t + cupsWriteRequestData(http_t *http, const char *buffer, + size_t length); + + ipp_status_t + cupsFinishDestDocument(http_t *http, cups_dest_t *dest, + cups_dinfo_t *info); + +The `docname` argument specifies the name of the document, typically the +original filename. The `format` argument specifies the MIME media type of the +document, including the following constants: + +- `CUPS_FORMAT_JPEG`: "image/jpeg" +- `CUPS_FORMAT_PDF`: "application/pdf" +- `CUPS_FORMAT_POSTSCRIPT`: "application/postscript" +- `CUPS_FORMAT_TEXT`: "text/plain" + +The `num_options` and `options` arguments specify per-document print options, +which at present must be 0 and `NULL`. The `last_document` argument specifies +whether this is the last document in the job. + +For example, the following code submits a PDF file to the job that was just +created: + + FILE *fp = fopen("filename.pdf", "rb"); + size_t bytes; + char buffer[65536]; + + if (cupsStartDestDocument(CUPS_HTTP_DEFAULT, dest, info, + job_id, "filename.pdf", 0, NULL, + 1) == HTTP_STATUS_CONTINUE) + { + while ((bytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) + if (cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, + bytes) != HTTP_STATUS_CONTINUE) + break; + + if (cupsFinishDestDocument(CUPS_HTTP_DEFAULT, dest, + info) == IPP_STATUS_OK) + puts("Document send succeeded."); + else + printf("Document send failed: %s\n", + cupsLastErrorString()); + } + + fclose(fp); + + +# Sending IPP Requests + +CUPS provides a rich API for sending IPP requests to the scheduler or printers, +typically from management or utility applications whose primary purpose is not +to send print jobs. + + +## Connecting to the Scheduler or Printer + +The connection to the scheduler or printer is represented by the HTTP connection +type `http_t`. The `cupsConnectDest` function connects to the scheduler or +printer associated with the destination: + + http_t * + cupsConnectDest(cups_dest_t *dest, unsigned flags, int msec, + int *cancel, char *resource, + size_t resourcesize, cups_dest_cb_t cb, + void *user_data); + +The `dest` argument specifies the destination to connect to. + +The `flags` argument specifies whether you want to connect to the scheduler +(`CUPS_DEST_FLAGS_NONE`) or device/printer (`CUPS_DEST_FLAGS_DEVICE`) associated +with the destination. + +The `msec` argument specifies how long you are willing to wait for the +connection to be established in milliseconds. Specify a value of `-1` to wait +indefinitely. + +The `cancel` argument specifies the address of an integer variable that can be +set to a non-zero value to cancel the connection. Specify a value of `NULL` +to not provide a cancel variable. + +The `resource` and `resourcesize` arguments specify the address and size of a +character string array to hold the path to use when sending an IPP request. + +The `cb` and `user_data` arguments specify a destination callback function that +returns 1 to continue connecting or 0 to stop. The destination callback work +the same way as the one used for the `cupsEnumDests` function. + +On success, a HTTP connection is returned that can be used to send IPP requests +and get IPP responses. + +For example, the following code connects to the printer associated with a +destination with a 30 second timeout: + + char resource[256]; + http_t *http = cupsConnectDest(dest, CUPS_DEST_FLAGS_DEVICE, + 30000, NULL, resource, + sizeof(resource), NULL, NULL); + + +## Creating an IPP Request + +IPP requests are represented by the IPP message type `ipp_t` and each IPP +attribute in the request is representing using the type `ipp_attribute_t`. Each +IPP request includes an operation code (`IPP_OP_CREATE_JOB`, +`IPP_OP_GET_PRINTER_ATTRIBUTES`, etc.) and a 32-bit integer identifier. + +The `ippNewRequest` function creates a new IPP request: + + ipp_t * + ippNewRequest(ipp_op_t op); + +The `op` argument specifies the IPP operation code for the request. For +example, the following code creates an IPP Get-Printer-Attributes request: + + ipp_t *request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES); + +The request identifier is automatically set to a unique value for the current +process. + +Each IPP request starts with two IPP attributes, "attributes-charset" and +"attributes-natural-language", followed by IPP attribute(s) that specify the +target of the operation. The `ippNewRequest` automatically adds the correct +"attributes-charset" and "attributes-natural-language" attributes, but you must +add the target attribute(s). For example, the following code adds the +"printer-uri" attribute to the IPP Get-Printer-Attributes request to specify +which printer is being queried: + + const char *printer_uri = cupsGetOption("device-uri", + dest->num_options, + dest->options); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, + "printer-uri", NULL, printer_uri); + +> **Note:** +> +> If we wanted to query the scheduler instead of the device, we would look +> up the "printer-uri-supported" option instead of the "device-uri" value. + +The `ippAddString` function adds the "printer-uri" attribute the the IPP +request. The `IPP_TAG_OPERATION` argument specifies that the attribute is part +of the operation. The `IPP_TAG_URI` argument specifies that the value is a +Universal Resource Identifier (URI) string. The `NULL` argument specifies there +is no language (English, French, Japanese, etc.) associated with the string, and +the `printer_uri` argument specifies the string value. + +The IPP Get-Printer-Attributes request also supports an IPP attribute called +"requested-attributes" that lists the attributes and values you are interested +in. For example, the following code requests the printer state attributes: + + static const char * const requested_attributes[] = + { + "printer-state", + "printer-state-message", + "printer-state-reasons" + }; + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", 3, NULL, + requested_attributes); + +The `ippAddStrings` function adds an attribute with one or more strings, in this +case three. The `IPP_TAG_KEYWORD` argument specifies that the strings are +keyword values, which are used for attribute names. All strings use the same +language (`NULL`), and the attribute will contain the three strings in the +array `requested_attributes`. + +CUPS provides many functions to adding attributes of different types: + +- `ippAddBoolean` adds a boolean (`IPP_TAG_BOOLEAN`) attribute with one value. +- `ippAddInteger` adds an enum (`IPP_TAG_ENUM`) or integer (`IPP_TAG_INTEGER`) + attribute with one value. +- `ippAddIntegers` adds an enum or integer attribute with one or more values. +- `ippAddOctetString` adds an octetString attribute with one value. +- `ippAddOutOfBand` adds a admin-defined (`IPP_TAG_ADMINDEFINE`), default + (`IPP_TAG_DEFAULT`), delete-attribute (`IPP_TAG_DELETEATTR`), no-value + (`IPP_TAG_NOVALUE`), not-settable (`IPP_TAG_NOTSETTABLE`), unknown + (`IPP_TAG_UNKNOWN`), or unsupported (`IPP_TAG_UNSUPPORTED_VALUE`) out-of-band + attribute. +- `ippAddRange` adds a rangeOfInteger attribute with one range. +- `ippAddRanges` adds a rangeOfInteger attribute with one or more ranges. +- `ippAddResolution` adds a resolution attribute with one resolution. +- `ippAddResolutions` adds a resolution attribute with one or more resolutions. +- `ippAddString` adds a charset (`IPP_TAG_CHARSET`), keyword (`IPP_TAG_KEYWORD`), + mimeMediaType (`IPP_TAG_MIMETYPE`), name (`IPP_TAG_NAME` and + `IPP_TAG_NAMELANG`), naturalLanguage (`IPP_TAG_NATURAL_LANGUAGE`), text + (`IPP_TAG_TEXT` and `IPP_TAG_TEXTLANG`), uri (`IPP_TAG_URI`), or uriScheme + (`IPP_TAG_URISCHEME`) attribute with one value. +- `ippAddStrings` adds a charset, keyword, mimeMediaType, name, naturalLanguage, + text, uri, or uriScheme attribute with one or more values. + + +## Sending the IPP Request + +Once you have created the IPP request, you can send it using the +`cupsDoRequest` function. For example, the following code sends the IPP +Get-Printer-Attributes request to the destination and saves the response: + + ipp_t *response = cupsDoRequest(http, request, resource); + +For requests like Send-Document that include a file, the `cupsDoFileRequest` +function should be used: + + ipp_t *response = cupsDoFileRequest(http, request, resource, + filename); + +Both `cupsDoRequest` and `cupsDoFileRequest` free the IPP request. If a valid +IPP response is received, it is stored in a new IPP message (`ipp_t`) and +returned to the caller. Otherwise `NULL` is returned. + +The status from the most recent request can be queried using the `cupsLastError` +function, for example: + + if (cupsLastError() >= IPP_STATUS_ERROR_BAD_REQUEST) + { + /* request failed */ + } + +A human-readable error message is also available using the `cupsLastErrorString` +function: + + if (cupsLastError() >= IPP_STATUS_ERROR_BAD_REQUEST) + { + /* request failed */ + printf("Request failed: %s\n", cupsLastErrorString()); + } + + +## Processing the IPP Response + +Each response to an IPP request is also an IPP message (`ipp_t`) with its own +IPP attributes (`ipp_attribute_t`) that includes a status code (`IPP_STATUS_OK`, +`IPP_STATUS_ERROR_BAD_REQUEST`, etc.) and the corresponding 32-bit integer +identifier from the request. + +For example, the following code finds the printer state attributes and prints +their values: + + ipp_attribute_t *attr; + + if ((attr = ippFindAttribute(response, "printer-state", + IPP_TAG_ENUM)) != NULL) + { + printf("printer-state=%s\n", + ippEnumString("printer-state", ippGetInteger(attr, 0))); + } + else + puts("printer-state=unknown"); + + if ((attr = ippFindAttribute(response, "printer-state-message", + IPP_TAG_TEXT)) != NULL) + { + printf("printer-state-message=\"%s\"\n", + ippGetString(attr, 0, NULL))); + } + + if ((attr = ippFindAttribute(response, "printer-state-reasons", + IPP_TAG_KEYWORD)) != NULL) + { + int i, count = ippGetCount(attr); + + puts("printer-state-reasons="); + for (i = 0; i < count; i ++) + printf(" %s\n", ippGetString(attr, i, NULL))); + } + +The `ippGetCount` function returns the number of values in an attribute. + +The `ippGetInteger` and `ippGetString` functions return a single integer or +string value from an attribute. + +The `ippEnumString` function converts a enum value to its keyword (string) +equivalent. + +Once you are done using the IPP response message, free it using the `ippDelete` +function: + + ippDelete(response); + + +## Authentication + +CUPS normally handles authentication through the console. GUI applications +should set a password callback using the `cupsSetPasswordCB2` function: + + void + cupsSetPasswordCB2(cups_password_cb2_t cb, void *user_data); + +The password callback will be called when needed and is responsible for setting +the current user name using `cupsSetUser` and returning a string: + + const char * + cups_password_cb2(const char *prompt, http_t *http, + const char *method, const char *resource, + void *user_data); + +The `prompt` argument is a string from CUPS that should be displayed to the +user. + +The `http` argument is the connection hosting the request that is being +authenticated. The password callback can call the `httpGetField` and +`httpGetSubField` functions to look for additional details concerning the +authentication challenge. + +The `method` argument specifies the HTTP method used for the request and is +typically "POST". + +The `resource` argument specifies the path used for the request. + +The `user_data` argument provides the user data pointer from the +`cupsSetPasswordCB2` call. diff --git a/cups/cupspm.opacity b/cups/cupspm.opacity new file mode 100644 index 0000000..261626f Binary files /dev/null and b/cups/cupspm.opacity differ diff --git a/cups/cupspm.png b/cups/cupspm.png new file mode 100644 index 0000000..d9ac067 Binary files /dev/null and b/cups/cupspm.png differ diff --git a/cups/custom.c b/cups/custom.c deleted file mode 100644 index 4c4cc8a..0000000 --- a/cups/custom.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * "$Id: custom.c 6649 2007-07-11 21:46:42Z mike $" - * - * PPD custom option routines for CUPS. - * - * Copyright 2007-2012 by Apple Inc. - * Copyright 1997-2006 by Easy Software Products, all rights reserved. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * PostScript is a trademark of Adobe Systems, Inc. - * - * This code and any derivative of it may be used and distributed - * freely under the terms of the GNU General Public License when - * used with GNU Ghostscript or its derivatives. Use of the code - * (or any derivative of it) with software other than GNU - * GhostScript (or its derivatives) is governed by the CUPS license - * agreement. - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * ppdFindCustomOption() - Find a custom option. - * ppdFindCustomParam() - Find a parameter for a custom option. - * ppdFirstCustomParam() - Return the first parameter for a custom option. - * ppdNextCustomParam() - Return the next parameter for a custom option. - */ - -/* - * Include necessary headers. - */ - -#include "cups-private.h" - - -/* - * 'ppdFindCustomOption()' - Find a custom option. - * - * @since CUPS 1.2/OS X 10.5@ - */ - -ppd_coption_t * /* O - Custom option or NULL */ -ppdFindCustomOption(ppd_file_t *ppd, /* I - PPD file */ - const char *keyword)/* I - Custom option name */ -{ - ppd_coption_t key; /* Custom option search key */ - - - if (!ppd) - return (NULL); - - strlcpy(key.keyword, keyword, sizeof(key.keyword)); - return ((ppd_coption_t *)cupsArrayFind(ppd->coptions, &key)); -} - - -/* - * 'ppdFindCustomParam()' - Find a parameter for a custom option. - * - * @since CUPS 1.2/OS X 10.5@ - */ - -ppd_cparam_t * /* O - Custom parameter or NULL */ -ppdFindCustomParam(ppd_coption_t *opt, /* I - Custom option */ - const char *name) /* I - Parameter name */ -{ - ppd_cparam_t *param; /* Current custom parameter */ - - - if (!opt) - return (NULL); - - for (param = (ppd_cparam_t *)cupsArrayFirst(opt->params); - param; - param = (ppd_cparam_t *)cupsArrayNext(opt->params)) - if (!_cups_strcasecmp(param->name, name)) - break; - - return (param); -} - - -/* - * 'ppdFirstCustomParam()' - Return the first parameter for a custom option. - * - * @since CUPS 1.2/OS X 10.5@ - */ - -ppd_cparam_t * /* O - Custom parameter or NULL */ -ppdFirstCustomParam(ppd_coption_t *opt) /* I - Custom option */ -{ - if (!opt) - return (NULL); - - return ((ppd_cparam_t *)cupsArrayFirst(opt->params)); -} - - -/* - * 'ppdNextCustomParam()' - Return the next parameter for a custom option. - * - * @since CUPS 1.2/OS X 10.5@ - */ - -ppd_cparam_t * /* O - Custom parameter or NULL */ -ppdNextCustomParam(ppd_coption_t *opt) /* I - Custom option */ -{ - if (!opt) - return (NULL); - - return ((ppd_cparam_t *)cupsArrayNext(opt->params)); -} - - -/* - * End of "$Id: custom.c 6649 2007-07-11 21:46:42Z mike $". - */ diff --git a/cups/debug-internal.h b/cups/debug-internal.h new file mode 100644 index 0000000..2b57854 --- /dev/null +++ b/cups/debug-internal.h @@ -0,0 +1,84 @@ +/* + * Internal debugging macros for CUPS. + * + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2005 by Easy Software Products. + * + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. + */ + +#ifndef _CUPS_DEBUG_INTERNAL_H_ +# define _CUPS_DEBUG_INTERNAL_H_ + + +/* + * Include necessary headers... + */ + +# include "debug-private.h" + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * The debug macros are used if you compile with DEBUG defined. + * + * Usage: + * + * DEBUG_puts("string") + * DEBUG_printf(("format string", arg, arg, ...)); + * + * Note the extra parenthesis around the DEBUG_printf macro... + * + * Newlines are not required on the end of messages, as both add one when + * writing the output. + * + * If the first character is a digit, then it represents the "log level" of the + * message from 0 to 9. The default level is 1. The following defines the + * current levels we use: + * + * 0 = public APIs, other than value accessor functions + * 1 = return values for public APIs + * 2 = public value accessor APIs, progress for public APIs + * 3 = return values for value accessor APIs + * 4 = private APIs, progress for value accessor APIs + * 5 = return values for private APIs + * 6 = progress for private APIs + * 7 = static functions + * 8 = return values for static functions + * 9 = progress for static functions + */ + +# ifdef DEBUG +# define DEBUG_puts(x) _cups_debug_puts(x) +# define DEBUG_printf(x) _cups_debug_printf x +# else +# define DEBUG_puts(x) +# define DEBUG_printf(x) +# endif /* DEBUG */ + + +/* + * Prototypes... + */ + +# ifdef DEBUG +extern int _cups_debug_fd _CUPS_INTERNAL; +extern int _cups_debug_level _CUPS_INTERNAL; +extern void _cups_debug_printf(const char *format, ...) _CUPS_FORMAT(1,2) _CUPS_INTERNAL; +extern void _cups_debug_puts(const char *s) _CUPS_INTERNAL; +# endif /* DEBUG */ + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_DEBUG_INTERNAL_H_ */ diff --git a/cups/debug-private.h b/cups/debug-private.h index 23a0ae1..fb84a2f 100644 --- a/cups/debug-private.h +++ b/cups/debug-private.h @@ -1,16 +1,11 @@ /* - * Private debugging macros for CUPS. + * Private debugging APIs for CUPS. * - * Copyright 2007-2012 by Apple Inc. - * Copyright 1997-2005 by Easy Software Products. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2005 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ #ifndef _CUPS_DEBUG_PRIVATE_H_ @@ -38,51 +33,17 @@ extern "C" { * * Usage: * - * DEBUG_puts("string") - * DEBUG_printf(("format string", arg, arg, ...)); - * - * Note the extra parenthesis around the DEBUG_printf macro... - * - * Newlines are not required on the end of messages, as both add one when - * writing the output. - * - * If the first character is a digit, then it represents the "log level" of the - * message from 0 to 9. The default level is 1. The following defines the - * current levels we use: - * - * 0 = public APIs, other than value accessor functions - * 1 = return values for public APIs - * 2 = public value accessor APIs, progress for public APIs - * 3 = return values for value accessor APIs - * 4 = private APIs, progress for value accessor APIs - * 5 = return values for private APIs - * 6 = progress for private APIs - * 7 = static functions - * 8 = return values for static functions - * 9 = progress for static functions + * DEBUG_set("logfile", "level", "filter", 1) * * The DEBUG_set macro allows an application to programmatically enable (or * disable) debug logging. The arguments correspond to the CUPS_DEBUG_LOG, - * CUPS_DEBUG_LEVEL, and CUPS_DEBUG_FILTER environment variables. + * CUPS_DEBUG_LEVEL, and CUPS_DEBUG_FILTER environment variables. The 1 on the + * end forces the values to override the environment. */ # ifdef DEBUG -# ifdef WIN32 -# ifdef LIBCUPS2_EXPORTS -# define DLLExport __declspec(dllexport) -# else -# define DLLExport -# endif /* LIBCUPS2_EXPORTS */ -# else -# define DLLExport -# endif /* WIN32 */ -# define DEBUG_puts(x) _cups_debug_puts(x) -# define DEBUG_printf(x) _cups_debug_printf x # define DEBUG_set(logfile,level,filter) _cups_debug_set(logfile,level,filter,1) # else -# define DLLExport -# define DEBUG_puts(x) -# define DEBUG_printf(x) # define DEBUG_set(logfile,level,filter) # endif /* DEBUG */ @@ -91,18 +52,11 @@ extern "C" { * Prototypes... */ -extern int _cups_debug_fd; -extern int _cups_debug_level; -extern void DLLExport _cups_debug_printf(const char *format, ...) - __attribute__ ((__format__ (__printf__, 1, 2))); -extern void DLLExport _cups_debug_puts(const char *s); -extern void DLLExport _cups_debug_set(const char *logfile, - const char *level, const char *filter, - int force); -# ifdef WIN32 -extern int _cups_gettimeofday(struct timeval *tv, void *tz); +extern void _cups_debug_set(const char *logfile, const char *level, const char *filter, int force) _CUPS_PRIVATE; +# ifdef _WIN32 +extern int _cups_gettimeofday(struct timeval *tv, void *tz) _CUPS_PRIVATE; # define gettimeofday(a,b) _cups_gettimeofday(a, b) -# endif /* WIN32 */ +# endif /* _WIN32 */ # ifdef __cplusplus } diff --git a/cups/debug.c b/cups/debug.c index bd244fe..6b3914e 100644 --- a/cups/debug.c +++ b/cups/debug.c @@ -1,15 +1,10 @@ /* * Debugging functions for CUPS. * - * Copyright 2008-2015 by Apple Inc. + * Copyright © 2008-2018 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -17,8 +12,9 @@ */ #include "cups-private.h" +#include "debug-internal.h" #include "thread-private.h" -#ifdef WIN32 +#ifdef _WIN32 # include # include # include @@ -36,11 +32,12 @@ _cups_gettimeofday(struct timeval *tv, /* I - Timeval struct */ #else # include # include -#endif /* WIN32 */ +#endif /* _WIN32 */ #include #include +#ifdef DEBUG /* * Globals... */ @@ -51,7 +48,6 @@ int _cups_debug_level = 1; /* Log level (0 to 9) */ -#ifdef DEBUG /* * Local globals... */ @@ -83,7 +79,7 @@ debug_thread_id(void) * '_cups_debug_printf()' - Write a formatted line to the log. */ -void DLLExport +void _cups_debug_printf(const char *format, /* I - Printf-style format string */ ...) /* I - Additional arguments as needed */ { @@ -168,7 +164,7 @@ _cups_debug_printf(const char *format, /* I - Printf-style format string */ * '_cups_debug_puts()' - Write a single line to the log. */ -void DLLExport +void _cups_debug_puts(const char *s) /* I - String to output */ { struct timeval curtime; /* Current time */ @@ -248,7 +244,7 @@ _cups_debug_puts(const char *s) /* I - String to output */ * '_cups_debug_set()' - Enable or disable debug logging. */ -void DLLExport +void _cups_debug_set(const char *logfile, /* I - Log file or NULL */ const char *level, /* I - Log level or NULL */ const char *filter, /* I - Filter string or NULL */ @@ -318,6 +314,24 @@ _cups_debug_set(const char *logfile, /* I - Log file or NULL */ _cupsMutexUnlock(&debug_init_mutex); } + + +#else +/* + * '_cups_debug_set()' - Enable or disable debug logging. + */ + +void +_cups_debug_set(const char *logfile, /* I - Log file or NULL */ + const char *level, /* I - Log level or NULL */ + const char *filter, /* I - Filter string or NULL */ + int force) /* I - Force initialization */ +{ + (void)logfile; + (void)level; + (void)filter; + (void)force; +} #endif /* DEBUG */ diff --git a/cups/dest-job.c b/cups/dest-job.c index f12b1dc..f4e5b33 100644 --- a/cups/dest-job.c +++ b/cups/dest-job.c @@ -3,13 +3,7 @@ * * Copyright 2012-2017 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -17,6 +11,7 @@ */ #include "cups-private.h" +#include "debug-internal.h" /* diff --git a/cups/dest-localization.c b/cups/dest-localization.c index 6d75a97..67d01f4 100644 --- a/cups/dest-localization.c +++ b/cups/dest-localization.c @@ -1,15 +1,9 @@ /* * Destination localization support for CUPS. * - * Copyright 2012-2014 by Apple Inc. + * Copyright 2012-2017 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -17,6 +11,7 @@ */ #include "cups-private.h" +#include "debug-internal.h" /* @@ -24,9 +19,6 @@ */ static void cups_create_localizations(http_t *http, cups_dinfo_t *dinfo); -static int cups_read_strings(cups_file_t *fp, char *buffer, size_t bufsize, - char **id, char **str); -static char *cups_scan_strings(char *buffer); /* @@ -53,68 +45,30 @@ cupsLocalizeDestMedia( pwg_media_t *pwg; /* PWG media information */ cups_array_t *db; /* Media database */ _cups_media_db_t *mdb; /* Media database entry */ - char name[1024], /* Size name */ + char lstr[1024], /* Localized size name */ temp[256]; /* Temporary string */ const char *lsize, /* Localized media size */ *lsource, /* Localized media source */ *ltype; /* Localized media type */ + DEBUG_printf(("cupsLocalizeDestMedia(http=%p, dest=%p, dinfo=%p, flags=%x, size=%p(\"%s\"))", (void *)http, (void *)dest, (void *)dinfo, flags, (void *)size, size ? size->media : "(null)")); + /* * Range check input... */ if (!http || !dest || !dinfo || !size) { + DEBUG_puts("1cupsLocalizeDestMedia: Returning NULL."); _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); return (NULL); } /* - * See if the localization is cached... + * Find the matching media database entry... */ - if (!dinfo->localizations) - cups_create_localizations(http, dinfo); - - key.id = size->media; - if ((match = (_cups_message_t *)cupsArrayFind(dinfo->localizations, &key)) != NULL) - return (match->str); - - /* - * If not, get the localized size, source, and type strings... - */ - - lang = cupsLangDefault(); - pwg = pwgMediaForSize(size->width, size->length); - - if (pwg->ppd) - lsize = _cupsLangString(lang, pwg->ppd); - else - lsize = NULL; - - if (!lsize) - { - if ((size->width % 635) == 0 && (size->length % 635) == 0) - { - /* - * Use inches since the size is a multiple of 1/4 inch. - */ - - snprintf(temp, sizeof(temp), _cupsLangString(lang, _("%g x %g")), size->width / 2540.0, size->length / 2540.0); - } - else - { - /* - * Use millimeters since the size is not a multiple of 1/4 inch. - */ - - snprintf(temp, sizeof(temp), _cupsLangString(lang, _("%d x %d mm")), (size->width + 50) / 100, (size->length + 50) / 100); - } - - lsize = temp; - } - if (flags & CUPS_MEDIA_FLAGS_READY) db = dinfo->ready_db; else @@ -139,12 +93,80 @@ cupsLocalizeDestMedia( } } + /* + * See if the localization is cached... + */ + + lang = cupsLangDefault(); + + if (!dinfo->localizations) + cups_create_localizations(http, dinfo); + + snprintf(temp, sizeof(temp), "media.%s", size->media); + key.msg = temp; + + if ((match = (_cups_message_t *)cupsArrayFind(dinfo->localizations, &key)) != NULL) + { + lsize = match->str; + } + else + { + /* + * Not a media name, try a media-key name... + */ + + snprintf(temp, sizeof(temp), "media-key.%s", size->media); + if ((match = (_cups_message_t *)cupsArrayFind(dinfo->localizations, &key)) != NULL) + lsize = match->str; + else + lsize = NULL; + } + + if (!lsize && (pwg = pwgMediaForSize(size->width, size->length)) != NULL && pwg->ppd) + { + /* + * Get a standard localization... + */ + + snprintf(temp, sizeof(temp), "media.%s", pwg->pwg); + if ((lsize = _cupsLangString(lang, temp)) == temp) + lsize = NULL; + } + + if (!lsize) + { + /* + * Make a dimensional localization... + */ + + if ((size->width % 635) == 0 && (size->length % 635) == 0) + { + /* + * Use inches since the size is a multiple of 1/4 inch. + */ + + snprintf(temp, sizeof(temp), _cupsLangString(lang, _("%g x %g \"")), size->width / 2540.0, size->length / 2540.0); + } + else + { + /* + * Use millimeters since the size is not a multiple of 1/4 inch. + */ + + snprintf(temp, sizeof(temp), _cupsLangString(lang, _("%d x %d mm")), (size->width + 50) / 100, (size->length + 50) / 100); + } + + lsize = temp; + } + if (mdb) { DEBUG_printf(("1cupsLocalizeDestMedia: MATCH mdb%p [key=\"%s\" size_name=\"%s\" source=\"%s\" type=\"%s\" width=%d length=%d B%d L%d R%d T%d]", (void *)mdb, mdb->key, mdb->size_name, mdb->source, mdb->type, mdb->width, mdb->length, mdb->bottom, mdb->left, mdb->right, mdb->top)); - lsource = cupsLocalizeDestValue(http, dest, dinfo, "media-source", mdb->source); - ltype = cupsLocalizeDestValue(http, dest, dinfo, "media-type", mdb->type); + if ((lsource = cupsLocalizeDestValue(http, dest, dinfo, "media-source", mdb->source)) == mdb->source && mdb->source) + lsource = _cupsLangString(lang, _("Other Tray")); + if ((ltype = cupsLocalizeDestValue(http, dest, dinfo, "media-type", mdb->type)) == mdb->type && mdb->type) + ltype = _cupsLangString(lang, _("Other Media")); } else { @@ -154,41 +176,43 @@ cupsLocalizeDestMedia( if (!lsource && !ltype) { - if (size->bottom || size->left || size->right || size->top) - snprintf(name, sizeof(name), _cupsLangString(lang, _("%s (Borderless)")), lsize); + if (!size->bottom && !size->left && !size->right && !size->top) + snprintf(lstr, sizeof(lstr), _cupsLangString(lang, _("%s (Borderless)")), lsize); else - strlcpy(name, lsize, sizeof(name)); + strlcpy(lstr, lsize, sizeof(lstr)); } else if (!lsource) { - if (size->bottom || size->left || size->right || size->top) - snprintf(name, sizeof(name), _cupsLangString(lang, _("%s (Borderless, %s)")), lsize, ltype); + if (!size->bottom && !size->left && !size->right && !size->top) + snprintf(lstr, sizeof(lstr), _cupsLangString(lang, _("%s (Borderless, %s)")), lsize, ltype); else - snprintf(name, sizeof(name), _cupsLangString(lang, _("%s (%s)")), lsize, ltype); + snprintf(lstr, sizeof(lstr), _cupsLangString(lang, _("%s (%s)")), lsize, ltype); } else if (!ltype) { - if (size->bottom || size->left || size->right || size->top) - snprintf(name, sizeof(name), _cupsLangString(lang, _("%s (Borderless, %s)")), lsize, lsource); + if (!size->bottom && !size->left && !size->right && !size->top) + snprintf(lstr, sizeof(lstr), _cupsLangString(lang, _("%s (Borderless, %s)")), lsize, lsource); else - snprintf(name, sizeof(name), _cupsLangString(lang, _("%s (%s)")), lsize, lsource); + snprintf(lstr, sizeof(lstr), _cupsLangString(lang, _("%s (%s)")), lsize, lsource); } else { - if (size->bottom || size->left || size->right || size->top) - snprintf(name, sizeof(name), _cupsLangString(lang, _("%s (Borderless, %s, %s)")), lsize, ltype, lsource); + if (!size->bottom && !size->left && !size->right && !size->top) + snprintf(lstr, sizeof(lstr), _cupsLangString(lang, _("%s (Borderless, %s, %s)")), lsize, ltype, lsource); else - snprintf(name, sizeof(name), _cupsLangString(lang, _("%s (%s, %s)")), lsize, ltype, lsource); + snprintf(lstr, sizeof(lstr), _cupsLangString(lang, _("%s (%s, %s)")), lsize, ltype, lsource); } if ((match = (_cups_message_t *)calloc(1, sizeof(_cups_message_t))) == NULL) return (NULL); - match->id = strdup(size->media); - match->str = strdup(name); + match->msg = strdup(size->media); + match->str = strdup(lstr); cupsArrayAdd(dinfo->localizations, match); + DEBUG_printf(("1cupsLocalizeDestMedia: Returning \"%s\".", match->str)); + return (match->str); } @@ -212,21 +236,22 @@ cupsLocalizeDestOption( { _cups_message_t key, /* Search key */ *match; /* Matching entry */ + const char *localized; /* Localized string */ + DEBUG_printf(("cupsLocalizeDestOption(http=%p, dest=%p, dinfo=%p, option=\"%s\")", (void *)http, (void *)dest, (void *)dinfo, option)); + if (!http || !dest || !dinfo) return (option); if (!dinfo->localizations) cups_create_localizations(http, dinfo); - if (cupsArrayCount(dinfo->localizations) == 0) - return (option); - - key.id = (char *)option; - if ((match = (_cups_message_t *)cupsArrayFind(dinfo->localizations, - &key)) != NULL) + key.msg = (char *)option; + if ((match = (_cups_message_t *)cupsArrayFind(dinfo->localizations, &key)) != NULL) return (match->str); + else if ((localized = _cupsLangString(cupsLangDefault(), option)) != NULL) + return (localized); else return (option); } @@ -253,22 +278,39 @@ cupsLocalizeDestValue( _cups_message_t key, /* Search key */ *match; /* Matching entry */ char pair[256]; /* option.value pair */ + const char *localized; /* Localized string */ + DEBUG_printf(("cupsLocalizeDestValue(http=%p, dest=%p, dinfo=%p, option=\"%s\", value=\"%s\")", (void *)http, (void *)dest, (void *)dinfo, option, value)); + if (!http || !dest || !dinfo) return (value); + if (!strcmp(option, "media")) + { + pwg_media_t *media = pwgMediaForPWG(value); + cups_size_t size; + + strlcpy(size.media, value, sizeof(size.media)); + size.width = media ? media->width : 0; + size.length = media ? media->length : 0; + size.left = 0; + size.right = 0; + size.bottom = 0; + size.top = 0; + + return (cupsLocalizeDestMedia(http, dest, dinfo, CUPS_MEDIA_FLAGS_DEFAULT, &size)); + } + if (!dinfo->localizations) cups_create_localizations(http, dinfo); - if (cupsArrayCount(dinfo->localizations) == 0) - return (value); - snprintf(pair, sizeof(pair), "%s.%s", option, value); - key.id = pair; - if ((match = (_cups_message_t *)cupsArrayFind(dinfo->localizations, - &key)) != NULL) + key.msg = pair; + if ((match = (_cups_message_t *)cupsArrayFind(dinfo->localizations, &key)) != NULL) return (match->str); + else if ((localized = _cupsLangString(cupsLangDefault(), pair)) != NULL && strcmp(localized, pair)) + return (localized); else return (value); } @@ -299,12 +341,6 @@ cups_create_localizations( cups_file_t *temp; /* Temporary file */ - /* - * Create an empty message catalog... - */ - - dinfo->localizations = _cupsMessageNew(NULL); - /* * See if there are any localizations... */ @@ -313,12 +349,12 @@ cups_create_localizations( IPP_TAG_URI)) == NULL) { /* - * Nope... + * Nope, create an empty message catalog... */ - DEBUG_puts("4cups_create_localizations: No printer-strings-uri (uri) " - "value."); - return; /* Nope */ + dinfo->localizations = _cupsMessageNew(NULL); + DEBUG_puts("4cups_create_localizations: No printer-strings-uri (uri) value."); + return; } /* @@ -331,8 +367,8 @@ cups_create_localizations( hostname, sizeof(hostname), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK) { - DEBUG_printf(("4cups_create_localizations: Bad printer-strings-uri value " - "\"%s\".", attr->values[0].string.text)); + dinfo->localizations = _cupsMessageNew(NULL); + DEBUG_printf(("4cups_create_localizations: Bad printer-strings-uri value \"%s\".", attr->values[0].string.text)); return; } @@ -381,9 +417,9 @@ cups_create_localizations( } status = cupsGetFd(http2, resource, cupsFileNumber(temp)); + cupsFileClose(temp); - DEBUG_printf(("4cups_create_localizations: GET %s = %s", resource, - httpStatus(status))); + DEBUG_printf(("4cups_create_localizations: GET %s = %s", resource, httpStatus(status))); if (status == HTTP_STATUS_OK) { @@ -391,35 +427,7 @@ cups_create_localizations( * Got the file, read it... */ - char buffer[8192], /* Message buffer */ - *id, /* ID string */ - *str; /* Translated message */ - _cups_message_t *m; /* Current message */ - - lseek(cupsFileNumber(temp), 0, SEEK_SET); - - while (cups_read_strings(temp, buffer, sizeof(buffer), &id, &str)) - { - if ((m = malloc(sizeof(_cups_message_t))) == NULL) - break; - - m->id = strdup(id); - m->str = strdup(str); - - if (m->id && m->str) - cupsArrayAdd(dinfo->localizations, m); - else - { - if (m->id) - free(m->id); - - if (m->str) - free(m->str); - - free(m); - break; - } - } + dinfo->localizations = _cupsMessageLoad(tempfile, _CUPS_MESSAGE_STRINGS); } DEBUG_printf(("4cups_create_localizations: %d messages loaded.", @@ -430,102 +438,8 @@ cups_create_localizations( */ unlink(tempfile); - cupsFileClose(temp); if (http2 != http) httpClose(http2); } - -/* - * 'cups_read_strings()' - Read a pair of strings from a .strings file. - */ - -static int /* O - 1 on success, 0 on failure */ -cups_read_strings(cups_file_t *strings, /* I - .strings file */ - char *buffer, /* I - Line buffer */ - size_t bufsize, /* I - Size of line buffer */ - char **id, /* O - Pointer to ID string */ - char **str) /* O - Pointer to translation string */ -{ - char *bufptr; /* Pointer into buffer */ - - - while (cupsFileGets(strings, buffer, bufsize)) - { - if (buffer[0] != '\"') - continue; - - *id = buffer + 1; - bufptr = cups_scan_strings(buffer); - - if (*bufptr != '\"') - continue; - - *bufptr++ = '\0'; - - while (*bufptr && *bufptr != '\"') - bufptr ++; - - if (!*bufptr) - continue; - - *str = bufptr + 1; - bufptr = cups_scan_strings(bufptr); - - if (*bufptr != '\"') - continue; - - *bufptr = '\0'; - - return (1); - } - - return (0); -} - - -/* - * 'cups_scan_strings()' - Scan a quoted string. - */ - -static char * /* O - End of string */ -cups_scan_strings(char *buffer) /* I - Start of string */ -{ - char *bufptr; /* Pointer into string */ - - - for (bufptr = buffer + 1; *bufptr && *bufptr != '\"'; bufptr ++) - { - if (*bufptr == '\\') - { - if (bufptr[1] >= '0' && bufptr[1] <= '3' && - bufptr[2] >= '0' && bufptr[2] <= '7' && - bufptr[3] >= '0' && bufptr[3] <= '7') - { - /* - * Decode \nnn octal escape... - */ - - *bufptr = (char)(((((bufptr[1] - '0') << 3) | (bufptr[2] - '0')) << 3) | (bufptr[3] - '0')); - _cups_strcpy(bufptr + 1, bufptr + 4); - } - else - { - /* - * Decode \C escape... - */ - - _cups_strcpy(bufptr, bufptr + 1); - if (*bufptr == 'n') - *bufptr = '\n'; - else if (*bufptr == 'r') - *bufptr = '\r'; - else if (*bufptr == 't') - *bufptr = '\t'; - } - } - } - - return (bufptr); -} diff --git a/cups/dest-options.c b/cups/dest-options.c index 51705a5..8c5fe66 100644 --- a/cups/dest-options.c +++ b/cups/dest-options.c @@ -1,15 +1,10 @@ /* * Destination option/media support for CUPS. * - * Copyright 2012-2017 by Apple Inc. + * Copyright © 2012-2019 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -17,6 +12,7 @@ */ #include "cups-private.h" +#include "debug-internal.h" /* @@ -31,6 +27,8 @@ */ static void cups_add_dconstres(cups_array_t *a, ipp_t *collection); +static int cups_collection_contains(ipp_t *test, ipp_t *match); +static size_t cups_collection_string(ipp_attribute_t *attr, char *buffer, size_t bufsize) _CUPS_NONNULL((1,2)); static int cups_compare_dconstres(_cups_dconstres_t *a, _cups_dconstres_t *b); static int cups_compare_media_db(_cups_media_db_t *a, @@ -58,6 +56,104 @@ static cups_array_t *cups_test_constraints(cups_dinfo_t *dinfo, static void cups_update_ready(http_t *http, cups_dinfo_t *dinfo); +/* + * 'cupsAddDestMediaOptions()' - Add the option corresponding to the specified media size. + * + * @since CUPS 2.3/macOS 10.14@ + */ + +int /* O - New number of options */ +cupsAddDestMediaOptions( + http_t *http, /* I - Connection to destination */ + cups_dest_t *dest, /* I - Destination */ + cups_dinfo_t *dinfo, /* I - Destination information */ + unsigned flags, /* I - Media matching flags */ + cups_size_t *size, /* I - Media size */ + int num_options, /* I - Current number of options */ + cups_option_t **options) /* IO - Options */ +{ + cups_array_t *db; /* Media database */ + _cups_media_db_t *mdb; /* Media database entry */ + char value[2048]; /* Option value */ + + + /* + * Range check input... + */ + + if (!http || !dest || !dinfo || !size || !options) + { + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); + return (num_options); + } + + /* + * Find the matching media size... + */ + + if (flags & CUPS_MEDIA_FLAGS_READY) + db = dinfo->ready_db; + else + db = dinfo->media_db; + + DEBUG_printf(("1cupsAddDestMediaOptions: size->media=\"%s\"", size->media)); + + for (mdb = (_cups_media_db_t *)cupsArrayFirst(db); mdb; mdb = (_cups_media_db_t *)cupsArrayNext(db)) + { + if (mdb->key && !strcmp(mdb->key, size->media)) + break; + else if (mdb->size_name && !strcmp(mdb->size_name, size->media)) + break; + } + + if (!mdb) + { + for (mdb = (_cups_media_db_t *)cupsArrayFirst(db); mdb; mdb = (_cups_media_db_t *)cupsArrayNext(db)) + { + if (mdb->width == size->width && mdb->length == size->length && mdb->bottom == size->bottom && mdb->left == size->left && mdb->right == size->right && mdb->top == size->top) + break; + } + } + + if (!mdb) + { + for (mdb = (_cups_media_db_t *)cupsArrayFirst(db); mdb; mdb = (_cups_media_db_t *)cupsArrayNext(db)) + { + if (mdb->width == size->width && mdb->length == size->length) + break; + } + } + + if (!mdb) + { + DEBUG_puts("1cupsAddDestMediaOptions: Unable to find matching size."); + return (num_options); + } + + DEBUG_printf(("1cupsAddDestMediaOptions: MATCH mdb%p [key=\"%s\" size_name=\"%s\" source=\"%s\" type=\"%s\" width=%d length=%d B%d L%d R%d T%d]", (void *)mdb, mdb->key, mdb->size_name, mdb->source, mdb->type, mdb->width, mdb->length, mdb->bottom, mdb->left, mdb->right, mdb->top)); + + if (mdb->source) + { + if (mdb->type) + snprintf(value, sizeof(value), "{media-size={x-dimension=%d y-dimension=%d} media-bottom-margin=%d media-left-margin=%d media-right-margin=%d media-top-margin=%d media-source=\"%s\" media-type=\"%s\"}", mdb->width, mdb->length, mdb->bottom, mdb->left, mdb->right, mdb->top, mdb->source, mdb->type); + else + snprintf(value, sizeof(value), "{media-size={x-dimension=%d y-dimension=%d} media-bottom-margin=%d media-left-margin=%d media-right-margin=%d media-top-margin=%d media-source=\"%s\"}", mdb->width, mdb->length, mdb->bottom, mdb->left, mdb->right, mdb->top, mdb->source); + } + else if (mdb->type) + { + snprintf(value, sizeof(value), "{media-size={x-dimension=%d y-dimension=%d} media-bottom-margin=%d media-left-margin=%d media-right-margin=%d media-top-margin=%d media-type=\"%s\"}", mdb->width, mdb->length, mdb->bottom, mdb->left, mdb->right, mdb->top, mdb->type); + } + else + { + snprintf(value, sizeof(value), "{media-size={x-dimension=%d y-dimension=%d} media-bottom-margin=%d media-left-margin=%d media-right-margin=%d media-top-margin=%d}", mdb->width, mdb->length, mdb->bottom, mdb->left, mdb->right, mdb->top); + } + + num_options = cupsAddOption("media-col", value, num_options, options); + + return (num_options); +} + + /* * 'cupsCheckDestSupported()' - Check that the option and value are supported * by the destination. @@ -83,6 +179,7 @@ cupsCheckDestSupported( ipp_res_t units_value; /* Resolution units */ ipp_attribute_t *attr; /* Attribute */ _ipp_value_t *attrval; /* Current attribute value */ + _ipp_option_t *map; /* Option mapping information */ /* @@ -128,10 +225,10 @@ cupsCheckDestSupported( */ pwg_media_t *pwg; /* Current PWG media size info */ - int min_width, /* Minimum width */ - min_length, /* Minimum length */ - max_width, /* Maximum width */ - max_length; /* Maximum length */ + int min_width, /* Minimum width */ + min_length, /* Minimum length */ + max_width, /* Maximum width */ + max_length; /* Maximum length */ /* * Get the minimum and maximum size... @@ -174,9 +271,14 @@ cupsCheckDestSupported( * Check literal values... */ + map = _ippFindOption(option); + switch (attr->value_tag) { case IPP_TAG_INTEGER : + if (map && map->value_tag == IPP_TAG_STRING) + return (strlen(value) <= (size_t)attr->values[0].integer); + case IPP_TAG_ENUM : int_value = atoi(value); @@ -189,7 +291,10 @@ cupsCheckDestSupported( return (attr->values[0].boolean); case IPP_TAG_RANGE : - int_value = atoi(value); + if (map && map->value_tag == IPP_TAG_STRING) + int_value = (int)strlen(value); + else + int_value = atoi(value); for (i = 0; i < attr->num_values; i ++) if (int_value >= attr->values[i].range.lower && @@ -572,6 +677,7 @@ cupsCopyDestInfo( cups_dest_t *dest) /* I - Destination */ { cups_dinfo_t *dinfo; /* Destination information */ + unsigned dflags; /* Destination flags */ ipp_t *request, /* Get-Printer-Attributes request */ *response; /* Supported attributes */ int tries, /* Number of tries so far */ @@ -581,6 +687,7 @@ cupsCopyDestInfo( char resource[1024]; /* Resource path */ int version; /* IPP version */ ipp_status_t status; /* Status of request */ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ static const char * const requested_attrs[] = { /* Requested attributes */ "job-template", @@ -589,14 +696,35 @@ cupsCopyDestInfo( }; - DEBUG_printf(("cupsCopyDestSupported(http=%p, dest=%p(%s))", (void *)http, (void *)dest, dest ? dest->name : "")); + DEBUG_printf(("cupsCopyDestInfo(http=%p, dest=%p(%s))", (void *)http, (void *)dest, dest ? dest->name : "")); /* * Get the default connection as needed... */ if (!http) - http = _cupsConnect(); + { + DEBUG_puts("1cupsCopyDestInfo: Default server connection."); + http = _cupsConnect(); + dflags = CUPS_DEST_FLAGS_NONE; + } +#ifdef AF_LOCAL + else if (httpAddrFamily(http->hostaddr) == AF_LOCAL) + { + DEBUG_puts("1cupsCopyDestInfo: Connection to server (domain socket)."); + dflags = CUPS_DEST_FLAGS_NONE; + } +#endif /* AF_LOCAL */ + else if ((strcmp(http->hostname, cg->server) && cg->server[0] != '/') || cg->ipp_port != httpAddrPort(http->hostaddr)) + { + DEBUG_printf(("1cupsCopyDestInfo: Connection to device (%s).", http->hostname)); + dflags = CUPS_DEST_FLAGS_DEVICE; + } + else + { + DEBUG_printf(("1cupsCopyDestInfo: Connection to server (%s).", http->hostname)); + dflags = CUPS_DEST_FLAGS_NONE; + } /* * Range check input... @@ -609,8 +737,11 @@ cupsCopyDestInfo( * Get the printer URI and resource path... */ - if ((uri = _cupsGetDestResource(dest, resource, sizeof(resource))) == NULL) + if ((uri = _cupsGetDestResource(dest, dflags, resource, sizeof(resource))) == NULL) + { + DEBUG_puts("1cupsCopyDestInfo: Unable to get resource."); return (NULL); + } /* * Get the supported attributes... @@ -628,28 +759,25 @@ cupsCopyDestInfo( */ request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES); - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, - uri); - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, - "requesting-user-name", NULL, cupsUser()); - ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, - "requested-attributes", - (int)(sizeof(requested_attrs) / sizeof(requested_attrs[0])), - NULL, requested_attrs); + + ippSetVersion(request, version / 10, version % 10); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (int)(sizeof(requested_attrs) / sizeof(requested_attrs[0])), NULL, requested_attrs); response = cupsDoRequest(http, request, resource); status = cupsLastError(); if (status > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED) { - DEBUG_printf(("cupsCopyDestSupported: Get-Printer-Attributes for '%s' " - "returned %s (%s)", dest->name, ippErrorString(status), - cupsLastErrorString())); + DEBUG_printf(("1cupsCopyDestInfo: Get-Printer-Attributes for '%s' returned %s (%s)", dest->name, ippErrorString(status), cupsLastErrorString())); ippDelete(response); response = NULL; - if (status == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED && version > 11) + if ((status == IPP_STATUS_ERROR_BAD_REQUEST || status == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED) && version > 11) + { version = 11; + } else if (status == IPP_STATUS_ERROR_BUSY) { sleep((unsigned)delay); @@ -665,7 +793,10 @@ cupsCopyDestInfo( while (!response && tries < 10); if (!response) + { + DEBUG_puts("1cupsCopyDestInfo: Unable to get printer attributes."); return (NULL); + } /* * Allocate a cups_dinfo_t structure and return it... @@ -678,6 +809,8 @@ cupsCopyDestInfo( return (NULL); } + DEBUG_printf(("1cupsCopyDestInfo: version=%d, uri=\"%s\", resource=\"%s\".", version, uri, resource)); + dinfo->version = version; dinfo->uri = uri; dinfo->resource = _cupsStrAlloc(resource); @@ -938,10 +1071,10 @@ cupsGetDestMediaByIndex( return (0); } - if (nsize->size_name) - strlcpy(size->media, nsize->size_name, sizeof(size->media)); - else if (nsize->key) + if (nsize->key) strlcpy(size->media, nsize->key, sizeof(size->media)); + else if (nsize->size_name) + strlcpy(size->media, nsize->size_name, sizeof(size->media)); else if ((pwg = pwgMediaForSize(nsize->width, nsize->length)) != NULL) strlcpy(size->media, pwg->pwg, sizeof(size->media)); else @@ -1202,25 +1335,19 @@ cupsGetDestMediaDefault( * Get the default media size, if any... */ - if ((media = cupsGetOption("media", dest->num_options, - dest->options)) == NULL) + if ((media = cupsGetOption("media", dest->num_options, dest->options)) == NULL) media = "na_letter_8.5x11in"; if (cupsGetDestMediaByName(http, dest, dinfo, media, flags, size)) return (1); - if (strcmp(media, "na_letter_8.5x11in") && - cupsGetDestMediaByName(http, dest, dinfo, "iso_a4_210x297mm", flags, - size)) + if (strcmp(media, "na_letter_8.5x11in") && cupsGetDestMediaByName(http, dest, dinfo, "iso_a4_210x297mm", flags, size)) return (1); - if (strcmp(media, "iso_a4_210x297mm") && - cupsGetDestMediaByName(http, dest, dinfo, "na_letter_8.5x11in", flags, - size)) + if (strcmp(media, "iso_a4_210x297mm") && cupsGetDestMediaByName(http, dest, dinfo, "na_letter_8.5x11in", flags, size)) return (1); - if ((flags & CUPS_MEDIA_FLAGS_BORDERLESS) && - cupsGetDestMediaByName(http, dest, dinfo, "na_index_4x6in", flags, size)) + if ((flags & CUPS_MEDIA_FLAGS_BORDERLESS) && cupsGetDestMediaByName(http, dest, dinfo, "na_index_4x6in", flags, size)) return (1); /* @@ -1258,6 +1385,346 @@ cups_add_dconstres( } +/* + * 'cups_collection_contains()' - Check whether test collection is contained in the matching collection. + */ + +static int /* O - 1 on a match, 0 on a non-match */ +cups_collection_contains(ipp_t *test, /* I - Collection to test */ + ipp_t *match) /* I - Matching values */ +{ + int i, j, /* Looping vars */ + mcount, /* Number of match values */ + tcount; /* Number of test values */ + ipp_attribute_t *tattr, /* Testing attribute */ + *mattr; /* Matching attribute */ + const char *tval; /* Testing string value */ + + + for (mattr = ippFirstAttribute(match); mattr; mattr = ippNextAttribute(match)) + { + if ((tattr = ippFindAttribute(test, ippGetName(mattr), IPP_TAG_ZERO)) == NULL) + return (0); + + tcount = ippGetCount(tattr); + + switch (ippGetValueTag(mattr)) + { + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + if (ippGetValueTag(tattr) != ippGetValueTag(mattr)) + return (0); + + for (i = 0; i < tcount; i ++) + { + if (!ippContainsInteger(mattr, ippGetInteger(tattr, i))) + return (0); + } + break; + + case IPP_TAG_RANGE : + if (ippGetValueTag(tattr) != IPP_TAG_INTEGER) + return (0); + + for (i = 0; i < tcount; i ++) + { + if (!ippContainsInteger(mattr, ippGetInteger(tattr, i))) + return (0); + } + break; + + case IPP_TAG_BOOLEAN : + if (ippGetValueTag(tattr) != IPP_TAG_BOOLEAN || ippGetBoolean(tattr, 0) != ippGetBoolean(mattr, 0)) + return (0); + break; + + case IPP_TAG_TEXTLANG : + case IPP_TAG_NAMELANG : + case IPP_TAG_TEXT : + case IPP_TAG_NAME : + case IPP_TAG_KEYWORD : + case IPP_TAG_URI : + case IPP_TAG_URISCHEME : + case IPP_TAG_CHARSET : + case IPP_TAG_LANGUAGE : + case IPP_TAG_MIMETYPE : + for (i = 0; i < tcount; i ++) + { + if ((tval = ippGetString(tattr, i, NULL)) == NULL || !ippContainsString(mattr, tval)) + return (0); + } + break; + + case IPP_TAG_BEGIN_COLLECTION : + for (i = 0; i < tcount; i ++) + { + ipp_t *tcol = ippGetCollection(tattr, i); + /* Testing collection */ + + for (j = 0, mcount = ippGetCount(mattr); j < mcount; j ++) + if (!cups_collection_contains(tcol, ippGetCollection(mattr, j))) + return (0); + } + break; + + default : + return (0); + } + } + + return (1); +} + + +/* + * 'cups_collection_string()' - Convert an IPP collection to an option string. + */ + +static size_t /* O - Number of bytes needed */ +cups_collection_string( + ipp_attribute_t *attr, /* I - Collection attribute */ + char *buffer, /* I - String buffer */ + size_t bufsize) /* I - Size of buffer */ +{ + int i, j, /* Looping vars */ + count, /* Number of collection values */ + mcount; /* Number of member values */ + ipp_t *col; /* Collection */ + ipp_attribute_t *first, /* First member attribute */ + *member; /* Member attribute */ + char *bufptr, /* Pointer into buffer */ + *bufend, /* End of buffer */ + temp[100]; /* Temporary string */ + const char *mptr; /* Pointer into member value */ + int mlen; /* Length of octetString */ + + + bufptr = buffer; + bufend = buffer + bufsize - 1; + + for (i = 0, count = ippGetCount(attr); i < count; i ++) + { + col = ippGetCollection(attr, i); + + if (i) + { + if (bufptr < bufend) + *bufptr++ = ','; + else + bufptr ++; + } + + if (bufptr < bufend) + *bufptr++ = '{'; + else + bufptr ++; + + for (member = first = ippFirstAttribute(col); member; member = ippNextAttribute(col)) + { + const char *mname = ippGetName(member); + + if (member != first) + { + if (bufptr < bufend) + *bufptr++ = ' '; + else + bufptr ++; + } + + if (ippGetValueTag(member) == IPP_TAG_BOOLEAN) + { + if (!ippGetBoolean(member, 0)) + { + if (bufptr < bufend) + strlcpy(bufptr, "no", (size_t)(bufend - bufptr + 1)); + bufptr += 2; + } + + if (bufptr < bufend) + strlcpy(bufptr, mname, (size_t)(bufend - bufptr + 1)); + bufptr += strlen(mname); + continue; + } + + if (bufptr < bufend) + strlcpy(bufptr, mname, (size_t)(bufend - bufptr + 1)); + bufptr += strlen(mname); + + if (bufptr < bufend) + *bufptr++ = '='; + else + bufptr ++; + + if (ippGetValueTag(member) == IPP_TAG_BEGIN_COLLECTION) + { + /* + * Convert sub-collection... + */ + + bufptr += cups_collection_string(member, bufptr, bufptr < bufend ? (size_t)(bufend - bufptr + 1) : 0); + } + else + { + /* + * Convert simple type... + */ + + for (j = 0, mcount = ippGetCount(member); j < mcount; j ++) + { + if (j) + { + if (bufptr < bufend) + *bufptr++ = ','; + else + bufptr ++; + } + + switch (ippGetValueTag(member)) + { + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + bufptr += snprintf(bufptr, bufptr < bufend ? (size_t)(bufend - bufptr + 1) : 0, "%d", ippGetInteger(member, j)); + break; + + case IPP_TAG_STRING : + if (bufptr < bufend) + *bufptr++ = '\"'; + else + bufptr ++; + + for (mptr = (const char *)ippGetOctetString(member, j, &mlen); mlen > 0; mlen --, mptr ++) + { + if (*mptr == '\"' || *mptr == '\\') + { + if (bufptr < bufend) + *bufptr++ = '\\'; + else + bufptr ++; + } + + if (bufptr < bufend) + *bufptr++ = *mptr; + else + bufptr ++; + } + + if (bufptr < bufend) + *bufptr++ = '\"'; + else + bufptr ++; + break; + + case IPP_TAG_DATE : + { + unsigned year; /* Year */ + const ipp_uchar_t *date = ippGetDate(member, j); + /* Date value */ + + year = ((unsigned)date[0] << 8) + (unsigned)date[1]; + + if (date[9] == 0 && date[10] == 0) + snprintf(temp, sizeof(temp), "%04u-%02u-%02uT%02u:%02u:%02uZ", year, date[2], date[3], date[4], date[5], date[6]); + else + snprintf(temp, sizeof(temp), "%04u-%02u-%02uT%02u:%02u:%02u%c%02u%02u", year, date[2], date[3], date[4], date[5], date[6], date[8], date[9], date[10]); + + if (bufptr < bufend) + strlcpy(bufptr, temp, (size_t)(bufend - bufptr + 1)); + + bufptr += strlen(temp); + } + break; + + case IPP_TAG_RESOLUTION : + { + int xres, /* Horizontal resolution */ + yres; /* Vertical resolution */ + ipp_res_t units; /* Resolution units */ + + xres = ippGetResolution(member, j, &yres, &units); + + if (xres == yres) + snprintf(temp, sizeof(temp), "%d%s", xres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm"); + else + snprintf(temp, sizeof(temp), "%dx%d%s", xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm"); + + if (bufptr < bufend) + strlcpy(bufptr, temp, (size_t)(bufend - bufptr + 1)); + + bufptr += strlen(temp); + } + break; + + case IPP_TAG_RANGE : + { + int lower, /* Lower bound */ + upper; /* Upper bound */ + + lower = ippGetRange(member, j, &upper); + + snprintf(temp, sizeof(temp), "%d-%d", lower, upper); + + if (bufptr < bufend) + strlcpy(bufptr, temp, (size_t)(bufend - bufptr + 1)); + + bufptr += strlen(temp); + } + break; + + case IPP_TAG_TEXTLANG : + case IPP_TAG_NAMELANG : + case IPP_TAG_TEXT : + case IPP_TAG_NAME : + case IPP_TAG_KEYWORD : + case IPP_TAG_URI : + case IPP_TAG_URISCHEME : + case IPP_TAG_CHARSET : + case IPP_TAG_LANGUAGE : + case IPP_TAG_MIMETYPE : + if (bufptr < bufend) + *bufptr++ = '\"'; + else + bufptr ++; + + for (mptr = ippGetString(member, j, NULL); *mptr; mptr ++) + { + if (*mptr == '\"' || *mptr == '\\') + { + if (bufptr < bufend) + *bufptr++ = '\\'; + else + bufptr ++; + } + + if (bufptr < bufend) + *bufptr++ = *mptr; + else + bufptr ++; + } + + if (bufptr < bufend) + *bufptr++ = '\"'; + else + bufptr ++; + break; + + default : + break; + } + } + } + } + + if (bufptr < bufend) + *bufptr++ = '}'; + else + bufptr ++; + } + + *bufptr = '\0'; + return ((size_t)(bufptr - buffer + 1)); +} + + /* * 'cups_compare_dconstres()' - Compare to resolver entries. */ @@ -1445,8 +1912,6 @@ cups_create_constraints( /* * 'cups_create_defaults()' - Create the -default option array. - * - * TODO: Need to support collection defaults... */ static void @@ -1465,32 +1930,26 @@ cups_create_defaults( * xxx=value to the defaults option array. */ - for (attr = ippFirstAttribute(dinfo->attrs); - attr; - attr = ippNextAttribute(dinfo->attrs)) + for (attr = ippFirstAttribute(dinfo->attrs); attr; attr = ippNextAttribute(dinfo->attrs)) { - if (!attr->name || attr->group_tag != IPP_TAG_PRINTER) + if (!ippGetName(attr) || ippGetGroupTag(attr) != IPP_TAG_PRINTER) continue; - if (attr->value_tag == IPP_TAG_BEGIN_COLLECTION) - continue; /* TODO: STR #4096 */ - - if ((nameptr = attr->name + strlen(attr->name) - 8) <= attr->name || - strcmp(nameptr, "-default")) - continue; - - strlcpy(name, attr->name, sizeof(name)); - if ((nameptr = name + strlen(name) - 8) <= name || - strcmp(nameptr, "-default")) + strlcpy(name, ippGetName(attr), sizeof(name)); + if ((nameptr = name + strlen(name) - 8) <= name || strcmp(nameptr, "-default")) continue; *nameptr = '\0'; - if (ippAttributeString(attr, value, sizeof(value)) >= sizeof(value)) + if (ippGetValueTag(attr) == IPP_TAG_BEGIN_COLLECTION) + { + if (cups_collection_string(attr, value, sizeof(value)) >= sizeof(value)) + continue; + } + else if (ippAttributeString(attr, value, sizeof(value)) >= sizeof(value)) continue; - dinfo->num_defaults = cupsAddOption(name, value, dinfo->num_defaults, - &dinfo->defaults); + dinfo->num_defaults = cupsAddOption(name, value, dinfo->num_defaults, &dinfo->defaults); } } @@ -1513,6 +1972,7 @@ cups_create_media_db( pwg_media_t *pwg; /* PWG media info */ cups_array_t *db; /* New media database array */ _cups_media_db_t mdb; /* Media entry */ + char media_key[256]; /* Synthesized media-key value */ db = cupsArrayNew3((cups_array_func_t)cups_compare_media_db, @@ -1613,61 +2073,92 @@ cups_create_media_db( } } - if ((media_attr = ippFindAttribute(val->collection, "media-color", - IPP_TAG_ZERO)) != NULL && - (media_attr->value_tag == IPP_TAG_NAME || - media_attr->value_tag == IPP_TAG_NAMELANG || - media_attr->value_tag == IPP_TAG_KEYWORD)) + if ((media_attr = ippFindAttribute(val->collection, "media-color", IPP_TAG_ZERO)) != NULL && (media_attr->value_tag == IPP_TAG_NAME || media_attr->value_tag == IPP_TAG_NAMELANG || media_attr->value_tag == IPP_TAG_KEYWORD)) mdb.color = media_attr->values[0].string.text; - if ((media_attr = ippFindAttribute(val->collection, "media-info", - IPP_TAG_TEXT)) != NULL) + if ((media_attr = ippFindAttribute(val->collection, "media-info", IPP_TAG_TEXT)) != NULL) mdb.info = media_attr->values[0].string.text; - if ((media_attr = ippFindAttribute(val->collection, "media-key", - IPP_TAG_ZERO)) != NULL && - (media_attr->value_tag == IPP_TAG_NAME || - media_attr->value_tag == IPP_TAG_NAMELANG || - media_attr->value_tag == IPP_TAG_KEYWORD)) + if ((media_attr = ippFindAttribute(val->collection, "media-key", IPP_TAG_ZERO)) != NULL && (media_attr->value_tag == IPP_TAG_NAME || media_attr->value_tag == IPP_TAG_NAMELANG || media_attr->value_tag == IPP_TAG_KEYWORD)) mdb.key = media_attr->values[0].string.text; - if ((media_attr = ippFindAttribute(val->collection, "media-size-name", - IPP_TAG_ZERO)) != NULL && - (media_attr->value_tag == IPP_TAG_NAME || - media_attr->value_tag == IPP_TAG_NAMELANG || - media_attr->value_tag == IPP_TAG_KEYWORD)) + if ((media_attr = ippFindAttribute(val->collection, "media-size-name", IPP_TAG_ZERO)) != NULL && (media_attr->value_tag == IPP_TAG_NAME || media_attr->value_tag == IPP_TAG_NAMELANG || media_attr->value_tag == IPP_TAG_KEYWORD)) mdb.size_name = media_attr->values[0].string.text; - if ((media_attr = ippFindAttribute(val->collection, "media-source", - IPP_TAG_ZERO)) != NULL && - (media_attr->value_tag == IPP_TAG_NAME || - media_attr->value_tag == IPP_TAG_NAMELANG || - media_attr->value_tag == IPP_TAG_KEYWORD)) + if ((media_attr = ippFindAttribute(val->collection, "media-source", IPP_TAG_ZERO)) != NULL && (media_attr->value_tag == IPP_TAG_NAME || media_attr->value_tag == IPP_TAG_NAMELANG || media_attr->value_tag == IPP_TAG_KEYWORD)) mdb.source = media_attr->values[0].string.text; - if ((media_attr = ippFindAttribute(val->collection, "media-type", - IPP_TAG_ZERO)) != NULL && - (media_attr->value_tag == IPP_TAG_NAME || - media_attr->value_tag == IPP_TAG_NAMELANG || - media_attr->value_tag == IPP_TAG_KEYWORD)) + if ((media_attr = ippFindAttribute(val->collection, "media-type", IPP_TAG_ZERO)) != NULL && (media_attr->value_tag == IPP_TAG_NAME || media_attr->value_tag == IPP_TAG_NAMELANG || media_attr->value_tag == IPP_TAG_KEYWORD)) mdb.type = media_attr->values[0].string.text; - if ((media_attr = ippFindAttribute(val->collection, "media-bottom-margin", - IPP_TAG_INTEGER)) != NULL) + if ((media_attr = ippFindAttribute(val->collection, "media-bottom-margin", IPP_TAG_INTEGER)) != NULL) mdb.bottom = media_attr->values[0].integer; - if ((media_attr = ippFindAttribute(val->collection, "media-left-margin", - IPP_TAG_INTEGER)) != NULL) + if ((media_attr = ippFindAttribute(val->collection, "media-left-margin", IPP_TAG_INTEGER)) != NULL) mdb.left = media_attr->values[0].integer; - if ((media_attr = ippFindAttribute(val->collection, "media-right-margin", - IPP_TAG_INTEGER)) != NULL) + if ((media_attr = ippFindAttribute(val->collection, "media-right-margin", IPP_TAG_INTEGER)) != NULL) mdb.right = media_attr->values[0].integer; - if ((media_attr = ippFindAttribute(val->collection, "media-top-margin", - IPP_TAG_INTEGER)) != NULL) + if ((media_attr = ippFindAttribute(val->collection, "media-top-margin", IPP_TAG_INTEGER)) != NULL) mdb.top = media_attr->values[0].integer; + if (!mdb.key) + { + if (!mdb.size_name && (pwg = pwgMediaForSize(mdb.width, mdb.length)) != NULL) + mdb.size_name = (char *)pwg->pwg; + + if (!mdb.size_name) + { + /* + * Use a CUPS-specific identifier if we don't have a size name... + */ + + if (flags & CUPS_MEDIA_FLAGS_READY) + snprintf(media_key, sizeof(media_key), "cups-media-ready-%d", i + 1); + else + snprintf(media_key, sizeof(media_key), "cups-media-%d", i + 1); + } + else if (mdb.source) + { + /* + * Generate key using size name, source, and type (if set)... + */ + + if (mdb.type) + snprintf(media_key, sizeof(media_key), "%s_%s_%s", mdb.size_name, mdb.source, mdb.type); + else + snprintf(media_key, sizeof(media_key), "%s_%s", mdb.size_name, mdb.source); + } + else if (mdb.type) + { + /* + * Generate key using size name and type... + */ + + snprintf(media_key, sizeof(media_key), "%s_%s", mdb.size_name, mdb.type); + } + else + { + /* + * Key is just the size name... + */ + + strlcpy(media_key, mdb.size_name, sizeof(media_key)); + } + + /* + * Append "_borderless" for borderless media... + */ + + if (!mdb.bottom && !mdb.left && !mdb.right && !mdb.top) + strlcat(media_key, "_borderless", sizeof(media_key)); + + mdb.key = media_key; + } + + DEBUG_printf(("1cups_create_media_db: Adding media: key=\"%s\", width=%d, length=%d, source=\"%s\", type=\"%s\".", mdb.key, mdb.width, mdb.length, mdb.source, mdb.type)); + cupsArrayAdd(db, &mdb); } @@ -2027,12 +2518,14 @@ cups_get_media_db(http_t *http, /* I - Connection to destination */ * Return the matching size... */ - if (best->size_name) - strlcpy(size->media, best->size_name, sizeof(size->media)); - else if (best->key) + if (best->key) strlcpy(size->media, best->key, sizeof(size->media)); - else + else if (best->size_name) + strlcpy(size->media, best->size_name, sizeof(size->media)); + else if (pwg && pwg->pwg) strlcpy(size->media, pwg->pwg, sizeof(size->media)); + else + strlcpy(size->media, "unknown", sizeof(size->media)); size->width = best->width; size->length = best->length; @@ -2074,8 +2567,6 @@ cups_is_close_media_db( /* * 'cups_test_constraints()' - Test constraints. - * - * TODO: STR #4096 - Need to properly support media-col contraints... */ static cups_array_t * /* O - Active constraints */ @@ -2089,11 +2580,13 @@ cups_test_constraints( cups_option_t **conflicts) /* O - Conflicting options */ { int i, /* Looping var */ + count, /* Number of values */ match; /* Value matches? */ int num_matching; /* Number of matching options */ cups_option_t *matching; /* Matching options */ _cups_dconstres_t *c; /* Current constraint */ cups_array_t *active = NULL; /* Active constraints */ + ipp_t *col; /* Collection value */ ipp_attribute_t *attr; /* Current attribute */ _ipp_value_t *attrval; /* Current attribute value */ const char *value; /* Current value */ @@ -2115,17 +2608,13 @@ cups_test_constraints( attr; attr = ippNextAttribute(c->collection)) { - if (attr->value_tag == IPP_TAG_BEGIN_COLLECTION) - break; /* TODO: STR #4096 */ - /* * Get the value for the current attribute in the constraint... */ if (new_option && new_value && !strcmp(attr->name, new_option)) value = new_value; - else if ((value = cupsGetOption(attr->name, num_options, - options)) == NULL) + else if ((value = cupsGetOption(attr->name, num_options, options)) == NULL) value = cupsGetOption(attr->name, dinfo->num_defaults, dinfo->defaults); if (!value) @@ -2240,6 +2729,22 @@ cups_test_constraints( } break; + case IPP_TAG_BEGIN_COLLECTION : + col = ippNew(); + _cupsEncodeOption(col, IPP_TAG_ZERO, NULL, ippGetName(attr), value); + + for (i = 0, count = ippGetCount(attr); i < count; i ++) + { + if (cups_collection_contains(col, ippGetCollection(attr, i))) + { + match = 1; + break; + } + } + + ippDelete(col); + break; + default : break; } @@ -2262,8 +2767,7 @@ cups_test_constraints( cups_option_t *moption; /* Matching option */ for (i = num_matching, moption = matching; i > 0; i --, moption ++) - *num_conflicts = cupsAddOption(moption->name, moption->value, - *num_conflicts, conflicts); + *num_conflicts = cupsAddOption(moption->name, moption->value, *num_conflicts, conflicts); } } diff --git a/cups/dest.c b/cups/dest.c index fc57ed3..17d96fe 100644 --- a/cups/dest.c +++ b/cups/dest.c @@ -1,16 +1,11 @@ /* * User-defined destination (and option) support for CUPS. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -18,6 +13,7 @@ */ #include "cups-private.h" +#include "debug-internal.h" #include #ifdef HAVE_NOTIFY_H @@ -48,10 +44,10 @@ */ #ifdef __APPLE__ -# if !TARGET_OS_IOS +# if HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME # include # define _CUPS_LOCATION_DEFAULTS 1 -# endif /* !TARGET_OS_IOS */ +# endif /* HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME */ # define kCUPSPrintingPrefs CFSTR("org.cups.PrintingPrefs") # define kDefaultPaperIDKey CFSTR("DefaultPaperID") # define kLastUsedPrintersKey CFSTR("LastUsedPrinters") @@ -61,7 +57,10 @@ #endif /* __APPLE__ */ #if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) -# define _CUPS_DNSSD_MAXTIME 500 /* Milliseconds for maximum quantum of time */ +# define _CUPS_DNSSD_GET_DESTS 250 /* Milliseconds for cupsGetDests */ +# define _CUPS_DNSSD_MAXTIME 50 /* Milliseconds for maximum quantum of time */ +#else +# define _CUPS_DNSSD_GET_DESTS 0 /* Milliseconds for cupsGetDests */ #endif /* HAVE_DNSSD || HAVE_AVAHI */ @@ -76,7 +75,6 @@ typedef enum _cups_dnssd_state_e /* Enumerated device state */ _CUPS_DNSSD_QUERY, _CUPS_DNSSD_PENDING, _CUPS_DNSSD_ACTIVE, - _CUPS_DNSSD_LOCAL, _CUPS_DNSSD_INCOMPATIBLE, _CUPS_DNSSD_ERROR } _cups_dnssd_state_t; @@ -96,6 +94,10 @@ typedef struct _cups_dnssd_data_s /* Enumeration data */ cups_ptype_t type, /* Printer type filter */ mask; /* Printer type mask */ cups_array_t *devices; /* Devices found so far */ + int num_dests; /* Number of lpoptions destinations */ + cups_dest_t *dests; /* lpoptions destinations */ + char def_name[1024], /* Default printer name, if any */ + *def_instance; /* Default printer instance, if any */ } _cups_dnssd_data_t; typedef struct _cups_dnssd_device_s /* Enumerated device */ @@ -122,8 +124,10 @@ typedef struct _cups_dnssd_resolve_s /* Data for resolving URI */ typedef struct _cups_getdata_s { - int num_dests; /* Number of destinations */ - cups_dest_t *dests; /* Destinations */ + int num_dests; /* Number of destinations */ + cups_dest_t *dests; /* Destinations */ + char def_name[1024], /* Default printer name, if any */ + *def_instance; /* Default printer instance, if any */ } _cups_getdata_t; typedef struct _cups_namedata_s @@ -189,14 +193,6 @@ static _cups_dnssd_device_t * const char *regtype, const char *replyDomain); # ifdef HAVE_DNSSD -static void cups_dnssd_local_cb(DNSServiceRef sdRef, - DNSServiceFlags flags, - uint32_t interfaceIndex, - DNSServiceErrorType errorCode, - const char *serviceName, - const char *regtype, - const char *replyDomain, - void *context); static void cups_dnssd_query_cb(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, @@ -227,15 +223,14 @@ static void cups_dnssd_unquote(char *dst, const char *src, size_t dstsize); static int cups_elapsed(struct timeval *t); #endif /* HAVE_DNSSD || HAVE_AVAHI */ +static int cups_enum_dests(http_t *http, unsigned flags, int msec, int *cancel, cups_ptype_t type, cups_ptype_t mask, cups_dest_cb_t cb, void *user_data); static int cups_find_dest(const char *name, const char *instance, int num_dests, cups_dest_t *dests, int prev, int *rdiff); static int cups_get_cb(_cups_getdata_t *data, unsigned flags, cups_dest_t *dest); static char *cups_get_default(const char *filename, char *namebuf, size_t namesize, const char **instance); -static int cups_get_dests(const char *filename, const char *match_name, - const char *match_inst, int user_default_set, - int num_dests, cups_dest_t **dests); +static int cups_get_dests(const char *filename, const char *match_name, const char *match_inst, int load_all, int user_default_set, int num_dests, cups_dest_t **dests); static char *cups_make_string(ipp_attribute_t *attr, char *buffer, size_t bufsize); static int cups_name_cb(_cups_namedata_t *data, unsigned flags, cups_dest_t *dest); @@ -570,7 +565,7 @@ _cupsAppleSetUseLastPrinter( /* - * 'cupsConnectDest()' - Open a conection to the destination. + * 'cupsConnectDest()' - Open a connection to the destination. * * Connect to the destination, returning a new @code http_t@ connection object * and optionally the resource path to use for the destination. These calls @@ -579,7 +574,7 @@ _cupsAppleSetUseLastPrinter( * returns 0. The caller is responsible for calling @link httpClose@ on the * returned connection. * - * Starting with CUPS 2.2.4, the caller can pass @code CUPS_DEST_FLAGS_DEVICE@ + * Starting with CUPS 2.2.4, the caller can pass @code CUPS_DEST_FLAGS_DEVICE@ * for the "flags" argument to connect directly to the device associated with * the destination. Otherwise, the connection is made to the CUPS scheduler * associated with the destination. @@ -847,6 +842,8 @@ cupsCopyDest(cups_dest_t *dest, /* I - Destination to copy */ if (new_dest) { + new_dest->is_default = dest->is_default; + if ((new_dest->options = calloc(sizeof(cups_option_t), (size_t)dest->num_options)) == NULL) return (cupsRemoveDest(dest->name, dest->instance, num_dests, dests)); @@ -975,406 +972,7 @@ cupsEnumDests( cups_dest_cb_t cb, /* I - Callback function */ void *user_data) /* I - User data */ { - int i, /* Looping var */ - num_dests; /* Number of destinations */ - cups_dest_t *dests = NULL, /* Destinations */ - *dest; /* Current destination */ - const char *defprinter; /* Default printer */ - char name[1024], /* Copy of printer name */ - *instance, /* Pointer to instance name */ - *user_default; /* User default printer */ -#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) - int count, /* Number of queries started */ - completed, /* Number of completed queries */ - remaining; /* Remainder of timeout */ - struct timeval curtime; /* Current time */ - _cups_dnssd_data_t data; /* Data for callback */ - _cups_dnssd_device_t *device; /* Current device */ -# ifdef HAVE_DNSSD - int nfds, /* Number of files responded */ - main_fd; /* File descriptor for lookups */ - DNSServiceRef ipp_ref = NULL, /* IPP browser */ - local_ipp_ref = NULL; /* Local IPP browser */ -# ifdef HAVE_SSL - DNSServiceRef ipps_ref = NULL,/* IPPS browser */ - local_ipps_ref = NULL; /* Local IPPS browser */ -# endif /* HAVE_SSL */ -# ifdef HAVE_POLL - struct pollfd pfd; /* Polling data */ -# else - fd_set input; /* Input set for select() */ - struct timeval timeout; /* Timeout for select() */ -# endif /* HAVE_POLL */ -# else /* HAVE_AVAHI */ - int error; /* Error value */ - AvahiServiceBrowser *ipp_ref = NULL;/* IPP browser */ -# ifdef HAVE_SSL - AvahiServiceBrowser *ipps_ref = NULL; /* IPPS browser */ -# endif /* HAVE_SSL */ -# endif /* HAVE_DNSSD */ -#endif /* HAVE_DNSSD || HAVE_AVAHI */ - - - /* - * Range check input... - */ - - (void)flags; - - if (!cb) - return (0); - - /* - * Get ready to enumerate... - */ - -#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) - memset(&data, 0, sizeof(data)); - - data.type = type; - data.mask = mask; - data.cb = cb; - data.user_data = user_data; - data.devices = cupsArrayNew3((cups_array_func_t)cups_dnssd_compare_devices, NULL, NULL, 0, NULL, (cups_afree_func_t)cups_dnssd_free_device); -#endif /* HAVE_DNSSD || HAVE_AVAHI */ - - if (!(mask & CUPS_PRINTER_DISCOVERED) || !(type & CUPS_PRINTER_DISCOVERED)) - { - /* - * Get the list of local printers and pass them to the callback function... - */ - - num_dests = _cupsGetDests(CUPS_HTTP_DEFAULT, IPP_OP_CUPS_GET_PRINTERS, NULL, - &dests, type, mask); - - if ((user_default = _cupsUserDefault(name, sizeof(name))) != NULL) - defprinter = name; - else if ((defprinter = cupsGetDefault2(CUPS_HTTP_DEFAULT)) != NULL) - { - strlcpy(name, defprinter, sizeof(name)); - defprinter = name; - } - - if (defprinter) - { - /* - * Separate printer and instance name... - */ - - if ((instance = strchr(name, '/')) != NULL) - *instance++ = '\0'; - - /* - * Lookup the printer and instance and make it the default... - */ - - if ((dest = cupsGetDest(name, instance, num_dests, dests)) != NULL) - dest->is_default = 1; - } - - for (i = num_dests, dest = dests; - i > 0 && (!cancel || !*cancel); - i --, dest ++) - { -#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) - const char *device_uri; /* Device URI */ -#endif /* HAVE_DNSSD || HAVE_AVAHI */ - - if (!(*cb)(user_data, i > 1 ? CUPS_DEST_FLAGS_MORE : CUPS_DEST_FLAGS_NONE, - dest)) - break; - -#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) - if (!dest->instance && (device_uri = cupsGetOption("device-uri", dest->num_options, dest->options)) != NULL && !strncmp(device_uri, "dnssd://", 8)) - { - /* - * Add existing queue using service name, etc. so we don't list it again... - */ - - char scheme[32], /* URI scheme */ - userpass[32], /* Username:password */ - serviceName[256], /* Service name (host field) */ - resource[256], /* Resource (options) */ - *regtype, /* Registration type */ - *replyDomain; /* Registration domain */ - int port; /* Port number (not used) */ - - if (httpSeparateURI(HTTP_URI_CODING_ALL, device_uri, scheme, sizeof(scheme), userpass, sizeof(userpass), serviceName, sizeof(serviceName), &port, resource, sizeof(resource)) >= HTTP_URI_STATUS_OK) - { - if ((regtype = strstr(serviceName, "._ipp")) != NULL) - { - *regtype++ = '\0'; - - if ((replyDomain = strstr(regtype, "._tcp.")) != NULL) - { - replyDomain[5] = '\0'; - replyDomain += 6; - - if ((device = cups_dnssd_get_device(&data, serviceName, regtype, replyDomain)) != NULL) - device->state = _CUPS_DNSSD_ACTIVE; - } - } - } - } -#endif /* HAVE_DNSSD || HAVE_AVAHI */ - } - - cupsFreeDests(num_dests, dests); - - if (i > 0 || msec == 0) - goto enum_finished; - } - - /* - * Return early if the caller doesn't want to do discovery... - */ - - if ((mask & CUPS_PRINTER_DISCOVERED) && !(type & CUPS_PRINTER_DISCOVERED)) - goto enum_finished; - -#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) - /* - * Get Bonjour-shared printers... - */ - - gettimeofday(&curtime, NULL); - -# ifdef HAVE_DNSSD - if (DNSServiceCreateConnection(&data.main_ref) != kDNSServiceErr_NoError) - return (0); - - main_fd = DNSServiceRefSockFD(data.main_ref); - - ipp_ref = data.main_ref; - DNSServiceBrowse(&ipp_ref, kDNSServiceFlagsShareConnection, 0, - "_ipp._tcp", NULL, - (DNSServiceBrowseReply)cups_dnssd_browse_cb, &data); - - local_ipp_ref = data.main_ref; - DNSServiceBrowse(&local_ipp_ref, kDNSServiceFlagsShareConnection, - kDNSServiceInterfaceIndexLocalOnly, - "_ipp._tcp", NULL, - (DNSServiceBrowseReply)cups_dnssd_local_cb, &data); - -# ifdef HAVE_SSL - ipps_ref = data.main_ref; - DNSServiceBrowse(&ipps_ref, kDNSServiceFlagsShareConnection, 0, - "_ipps._tcp", NULL, - (DNSServiceBrowseReply)cups_dnssd_browse_cb, &data); - - local_ipps_ref = data.main_ref; - DNSServiceBrowse(&local_ipps_ref, kDNSServiceFlagsShareConnection, - kDNSServiceInterfaceIndexLocalOnly, - "_ipps._tcp", NULL, - (DNSServiceBrowseReply)cups_dnssd_local_cb, &data); -# endif /* HAVE_SSL */ - -# else /* HAVE_AVAHI */ - if ((data.simple_poll = avahi_simple_poll_new()) == NULL) - { - DEBUG_puts("cupsEnumDests: Unable to create Avahi simple poll object."); - return (1); - } - - avahi_simple_poll_set_func(data.simple_poll, cups_dnssd_poll_cb, &data); - - data.client = avahi_client_new(avahi_simple_poll_get(data.simple_poll), - 0, cups_dnssd_client_cb, &data, - &error); - if (!data.client) - { - DEBUG_puts("cupsEnumDests: Unable to create Avahi client."); - avahi_simple_poll_free(data.simple_poll); - return (1); - } - - data.browsers = 1; - ipp_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipp._tcp", NULL, 0, cups_dnssd_browse_cb, &data); - -# ifdef HAVE_SSL - data.browsers ++; - ipps_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipps._tcp", NULL, 0, cups_dnssd_browse_cb, &data); -# endif /* HAVE_SSL */ -# endif /* HAVE_DNSSD */ - - if (msec < 0) - remaining = INT_MAX; - else - remaining = msec; - - while (remaining > 0 && (!cancel || !*cancel)) - { - /* - * Check for input... - */ - - DEBUG_printf(("1cupsEnumDests: remaining=%d", remaining)); - - cups_elapsed(&curtime); - -# ifdef HAVE_DNSSD -# ifdef HAVE_POLL - pfd.fd = main_fd; - pfd.events = POLLIN; - - nfds = poll(&pfd, 1, remaining > _CUPS_DNSSD_MAXTIME ? _CUPS_DNSSD_MAXTIME : remaining); - -# else - FD_ZERO(&input); - FD_SET(main_fd, &input); - - timeout.tv_sec = 0; - timeout.tv_usec = 1000 * (remaining > _CUPS_DNSSD_MAXTIME ? _CUPS_DNSSD_MAXTIME : remaining); - - nfds = select(main_fd + 1, &input, NULL, NULL, &timeout); -# endif /* HAVE_POLL */ - - if (nfds > 0) - DNSServiceProcessResult(data.main_ref); - -# else /* HAVE_AVAHI */ - data.got_data = 0; - - if ((error = avahi_simple_poll_iterate(data.simple_poll, _CUPS_DNSSD_MAXTIME)) > 0) - { - /* - * We've been told to exit the loop. Perhaps the connection to - * Avahi failed. - */ - - break; - } - - DEBUG_printf(("1cupsEnumDests: got_data=%d", data.got_data)); -# endif /* HAVE_DNSSD */ - - remaining -= cups_elapsed(&curtime); - - for (device = (_cups_dnssd_device_t *)cupsArrayFirst(data.devices), - count = 0, completed = 0; - device; - device = (_cups_dnssd_device_t *)cupsArrayNext(data.devices)) - { - if (device->ref) - count ++; - - if (device->state == _CUPS_DNSSD_ACTIVE) - completed ++; - - if (!device->ref && device->state == _CUPS_DNSSD_NEW) - { - DEBUG_printf(("1cupsEnumDests: Querying '%s'.", device->fullName)); - -# ifdef HAVE_DNSSD - device->ref = data.main_ref; - - if (DNSServiceQueryRecord(&(device->ref), - kDNSServiceFlagsShareConnection, - 0, device->fullName, - kDNSServiceType_TXT, - kDNSServiceClass_IN, - (DNSServiceQueryRecordReply)cups_dnssd_query_cb, - &data) == kDNSServiceErr_NoError) - { - count ++; - } - else - { - device->ref = 0; - device->state = _CUPS_DNSSD_ERROR; - - DEBUG_puts("1cupsEnumDests: Query failed."); - } - -# else /* HAVE_AVAHI */ - if ((device->ref = avahi_record_browser_new(data.client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, device->fullName, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_TXT, 0, cups_dnssd_query_cb, &data)) != NULL) - { - DEBUG_printf(("1cupsEnumDests: Query ref=%p", device->ref)); - count ++; - } - else - { - device->state = _CUPS_DNSSD_ERROR; - - DEBUG_printf(("1cupsEnumDests: Query failed: %s", avahi_strerror(avahi_client_errno(data.client)))); - } -# endif /* HAVE_DNSSD */ - } - else if (device->ref && device->state == _CUPS_DNSSD_PENDING) - { - completed ++; - - DEBUG_printf(("1cupsEnumDests: Query for \"%s\" is complete.", device->fullName)); - - if ((device->type & mask) == type) - { - DEBUG_printf(("1cupsEnumDests: Add callback for \"%s\".", device->dest.name)); - if (!(*cb)(user_data, CUPS_DEST_FLAGS_NONE, &device->dest)) - { - remaining = -1; - break; - } - } - - device->state = _CUPS_DNSSD_ACTIVE; - } - } - -# ifdef HAVE_AVAHI - DEBUG_printf(("1cupsEnumDests: remaining=%d, browsers=%d, completed=%d, count=%d, devices count=%d", remaining, data.browsers, completed, count, cupsArrayCount(data.devices))); - - if (data.browsers == 0 && completed == cupsArrayCount(data.devices)) - break; -# else - DEBUG_printf(("1cupsEnumDests: remaining=%d, completed=%d, count=%d, devices count=%d", remaining, completed, count, cupsArrayCount(data.devices))); - - if (completed == cupsArrayCount(data.devices)) - break; -# endif /* HAVE_AVAHI */ - } -#endif /* HAVE_DNSSD || HAVE_AVAHI */ - - /* - * Return... - */ - - enum_finished: - -#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) - cupsArrayDelete(data.devices); - -# ifdef HAVE_DNSSD - if (ipp_ref) - DNSServiceRefDeallocate(ipp_ref); - if (local_ipp_ref) - DNSServiceRefDeallocate(local_ipp_ref); - -# ifdef HAVE_SSL - if (ipps_ref) - DNSServiceRefDeallocate(ipps_ref); - if (local_ipps_ref) - DNSServiceRefDeallocate(local_ipps_ref); -# endif /* HAVE_SSL */ - - if (data.main_ref) - DNSServiceRefDeallocate(data.main_ref); - -# else /* HAVE_AVAHI */ - if (ipp_ref) - avahi_service_browser_free(ipp_ref); -# ifdef HAVE_SSL - if (ipps_ref) - avahi_service_browser_free(ipps_ref); -# endif /* HAVE_SSL */ - - if (data.client) - avahi_client_free(data.client); - if (data.simple_poll) - avahi_simple_poll_free(data.simple_poll); -# endif /* HAVE_DNSSD */ -#endif /* HAVE_DNSSD || HAVE_AVAHI */ - - return (1); + return (cups_enum_dests(CUPS_HTTP_DEFAULT, flags, msec, cancel, type, mask, cb, user_data)); } @@ -1498,20 +1096,23 @@ cupsGetDest(const char *name, /* I - Destination name or @code NULL@ for the d * '_cupsGetDestResource()' - Get the resource path and URI for a destination. */ -const char * /* O - Printer URI */ +const char * /* O - URI */ _cupsGetDestResource( cups_dest_t *dest, /* I - Destination */ + unsigned flags, /* I - Destination flags */ char *resource, /* I - Resource buffer */ size_t resourcesize) /* I - Size of resource buffer */ { - const char *uri; /* Printer URI */ + const char *uri, /* URI */ + *device_uri, /* Device URI */ + *printer_uri; /* Printer URI */ char scheme[32], /* URI scheme */ userpass[256], /* Username and password (unused) */ hostname[256]; /* Hostname */ int port; /* Port number */ - DEBUG_printf(("_cupsGetDestResource(dest=%p(%s), resource=%p, resourcesize=%d)", (void *)dest, dest->name, (void *)resource, (int)resourcesize)); + DEBUG_printf(("_cupsGetDestResource(dest=%p(%s), flags=%u, resource=%p, resourcesize=%d)", (void *)dest, dest->name, flags, (void *)resource, (int)resourcesize)); /* * Range check input... @@ -1527,25 +1128,46 @@ _cupsGetDestResource( } /* - * Grab the printer URI... + * Grab the printer and device URIs... */ - if ((uri = cupsGetOption("printer-uri-supported", dest->num_options, dest->options)) == NULL) - { - if ((uri = cupsGetOption("device-uri", dest->num_options, dest->options)) != NULL) - { + device_uri = cupsGetOption("device-uri", dest->num_options, dest->options); + printer_uri = cupsGetOption("printer-uri-supported", dest->num_options, dest->options); + + DEBUG_printf(("1_cupsGetDestResource: device-uri=\"%s\", printer-uri-supported=\"%s\".", device_uri, printer_uri)); + #if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) - if (strstr(uri, "._tcp")) - uri = cups_dnssd_resolve(dest, uri, 5000, NULL, NULL, NULL); -#endif /* HAVE_DNSSD || HAVE_AVAHI */ - } - - if (uri) + if (((flags & CUPS_DEST_FLAGS_DEVICE) || !printer_uri) && strstr(device_uri, "._tcp")) + { + if ((device_uri = cups_dnssd_resolve(dest, device_uri, 5000, NULL, NULL, NULL)) != NULL) { - DEBUG_printf(("1_cupsGetDestResource: Resolved printer-uri-supported=\"%s\"", uri)); - - uri = _cupsCreateDest(dest->name, cupsGetOption("printer-info", dest->num_options, dest->options), NULL, uri, resource, resourcesize); + DEBUG_printf(("1_cupsGetDestResource: Resolved device-uri=\"%s\".", device_uri)); } + else + { + DEBUG_puts("1_cupsGetDestResource: Unable to resolve device."); + + if (resource) + *resource = '\0'; + + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0); + + return (NULL); + } + } +#endif /* HAVE_DNSSD || HAVE_AVAHI */ + + if (flags & CUPS_DEST_FLAGS_DEVICE) + { + uri = device_uri; + } + else if (printer_uri) + { + uri = printer_uri; + } + else + { + uri = _cupsCreateDest(dest->name, cupsGetOption("printer-info", dest->num_options, dest->options), NULL, device_uri, resource, resourcesize); if (uri) { @@ -1555,30 +1177,24 @@ _cupsGetDestResource( uri = cupsGetOption("printer-uri-supported", dest->num_options, dest->options); } - else - { - DEBUG_puts("1_cupsGetDestResource: No printer-uri-supported found."); - - if (resource) - *resource = '\0'; - - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0); - - return (NULL); - } } - else + + if (!uri) { - DEBUG_printf(("1_cupsGetDestResource: printer-uri-supported=\"%s\"", uri)); + DEBUG_puts("1_cupsGetDestResource: No printer-uri-supported or device-uri found."); - if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), - userpass, sizeof(userpass), hostname, sizeof(hostname), - &port, resource, (int)resourcesize) < HTTP_URI_STATUS_OK) - { - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad printer-uri."), 1); + if (resource) + *resource = '\0'; - return (NULL); - } + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0); + + return (NULL); + } + else if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), userpass, sizeof(userpass), hostname, sizeof(hostname), &port, resource, (int)resourcesize) < HTTP_URI_STATUS_OK) + { + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad URI."), 1); + + return (NULL); } DEBUG_printf(("1_cupsGetDestResource: resource=\"%s\"", resource)); @@ -1666,6 +1282,12 @@ cupsGetDestWithURI(const char *name, /* I - Desired printer name or @code NULL@ name = resource + 10; info = temp; } + else if (!strncmp(resource, "/ipp/print/", 11)) + { + snprintf(temp, sizeof(temp), "%s @ %s", resource + 11, hostname); + name = resource + 11; + info = temp; + } else { name = hostname; @@ -1780,6 +1402,7 @@ _cupsGetDests(http_t *http, /* I - Connection to server or */ appleGetPaperSize(media_default, sizeof(media_default)); + DEBUG_printf(("1_cupsGetDests: Default media is '%s'.", media_default)); #endif /* __APPLE__ */ /* @@ -1888,7 +1511,7 @@ _cupsGetDests(http_t *http, /* I - Connection to server or num_options, &options); } #ifdef __APPLE__ - else if (!strcmp(attr->name, "media-supported")) + else if (!strcmp(attr->name, "media-supported") && media_default[0]) { /* * See if we can set a default media size... @@ -1899,8 +1522,8 @@ _cupsGetDests(http_t *http, /* I - Connection to server or for (i = 0; i < attr->num_values; i ++) if (!_cups_strcasecmp(media_default, attr->values[i].string.text)) { - num_options = cupsAddOption("media", media_default, num_options, - &options); + DEBUG_printf(("1_cupsGetDests: Setting media to '%s'.", media_default)); + num_options = cupsAddOption("media", media_default, num_options, &options); break; } } @@ -1909,7 +1532,8 @@ _cupsGetDests(http_t *http, /* I - Connection to server or attr->value_tag == IPP_TAG_NAME) printer_name = attr->values[0].string.text; else if (strncmp(attr->name, "notify-", 7) && - (attr->value_tag == IPP_TAG_BOOLEAN || + strncmp(attr->name, "print-quality-", 14) && + (attr->value_tag == IPP_TAG_BOOLEAN || attr->value_tag == IPP_TAG_ENUM || attr->value_tag == IPP_TAG_INTEGER || attr->value_tag == IPP_TAG_KEYWORD || @@ -1924,12 +1548,8 @@ _cupsGetDests(http_t *http, /* I - Connection to server or strlcpy(optname, attr->name, sizeof(optname)); optname[ptr - attr->name] = '\0'; - if (_cups_strcasecmp(optname, "media") || - !cupsGetOption("media", num_options, options)) - num_options = cupsAddOption(optname, - cups_make_string(attr, value, - sizeof(value)), - num_options, &options); + if (_cups_strcasecmp(optname, "media") || !cupsGetOption("media", num_options, options)) + num_options = cupsAddOption(optname, cups_make_string(attr, value, sizeof(value)), num_options, &options); } } @@ -2028,28 +1648,35 @@ cupsGetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_ cups_dest_t **dests) /* O - Destinations */ { _cups_getdata_t data; /* Enumeration data */ - cups_dest_t *dest; /* Current destination */ - const char *home; /* HOME environment variable */ - char filename[1024]; /* Local ~/.cups/lpoptions file */ - const char *defprinter; /* Default printer */ - char name[1024], /* Copy of printer name */ - *instance, /* Pointer to instance name */ - *user_default; /* User default printer */ - int num_reals; /* Number of real queues */ - cups_dest_t *reals; /* Real queues */ - _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ - /* + DEBUG_printf(("cupsGetDests2(http=%p, dests=%p)", (void *)http, (void *)dests)); + +/* * Range check the input... */ if (!dests) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad NULL dests pointer"), 1); + DEBUG_puts("1cupsGetDests2: NULL dests pointer, returning 0."); return (0); } + /* + * Connect to the server as needed... + */ + + if (!http) + { + if ((http = _cupsConnect()) == NULL) + { + *dests = NULL; + + return (0); + } + } + /* * Grab the printers and classes... */ @@ -2057,116 +1684,23 @@ cupsGetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_ data.num_dests = 0; data.dests = NULL; - cupsEnumDests(0, 1000, NULL, 0, 0, (cups_dest_cb_t)cups_get_cb, &data); - - if (cupsLastError() >= IPP_STATUS_REDIRECTION_OTHER_SITE) + if (!httpAddrLocalhost(httpGetAddress(http))) { - cupsFreeDests(data.num_dests, data.dests); + /* + * When talking to a remote cupsd, just enumerate printers on the remote + * cupsd. + */ - *dests = (cups_dest_t *)0; - - return (0); - } - - /* - * Make a copy of the "real" queues for a later sanity check... - */ - - if (data.num_dests > 0) - { - num_reals = data.num_dests; - reals = calloc((size_t)num_reals, sizeof(cups_dest_t)); - - if (reals) - memcpy(reals, data.dests, (size_t)num_reals * sizeof(cups_dest_t)); - else - num_reals = 0; + cups_enum_dests(http, 0, _CUPS_DNSSD_GET_DESTS, NULL, 0, CUPS_PRINTER_DISCOVERED, (cups_dest_cb_t)cups_get_cb, &data); } else - { - num_reals = 0; - reals = NULL; - } - - /* - * Grab the default destination... - */ - - if ((user_default = _cupsUserDefault(name, sizeof(name))) != NULL) - defprinter = name; - else if ((defprinter = cupsGetDefault2(http)) != NULL) - { - strlcpy(name, defprinter, sizeof(name)); - defprinter = name; - } - - if (defprinter) { /* - * Separate printer and instance name... + * When talking to a local cupsd, enumerate both local printers and ones we + * can find on the network... */ - if ((instance = strchr(name, '/')) != NULL) - *instance++ = '\0'; - - /* - * Lookup the printer and instance and make it the default... - */ - - if ((dest = cupsGetDest(name, instance, data.num_dests, data.dests)) != NULL) - dest->is_default = 1; - } - else - instance = NULL; - - /* - * Load the /etc/cups/lpoptions and ~/.cups/lpoptions files... - */ - - snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot); - data.num_dests = cups_get_dests(filename, NULL, NULL, user_default != NULL, data.num_dests, &data.dests); - - if ((home = getenv("HOME")) != NULL) - { - snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home); - - data.num_dests = cups_get_dests(filename, NULL, NULL, user_default != NULL, data.num_dests, &data.dests); - } - - /* - * Validate the current default destination - this prevents old - * Default lines in /etc/cups/lpoptions and ~/.cups/lpoptions from - * pointing to a non-existent printer or class... - */ - - if (num_reals) - { - /* - * See if we have a default printer... - */ - - if ((dest = cupsGetDest(NULL, NULL, data.num_dests, data.dests)) != NULL) - { - /* - * Have a default; see if it is real... - */ - - if (!cupsGetDest(dest->name, NULL, num_reals, reals)) - { - /* - * Remove the non-real printer from the list, since we don't want jobs - * going to an unexpected printer... () - */ - - data.num_dests = cupsRemoveDest(dest->name, dest->instance, data.num_dests, &data.dests); - } - } - - /* - * Free memory... - */ - - free(reals); + cups_enum_dests(http, 0, _CUPS_DNSSD_GET_DESTS, NULL, 0, 0, (cups_dest_cb_t)cups_get_cb, &data); } /* @@ -2178,6 +1712,8 @@ cupsGetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_ if (data.num_dests > 0) _cupsSetError(IPP_STATUS_OK, NULL, 0); + DEBUG_printf(("1cupsGetDests2: Returning %d destinations.", data.num_dests)); + return (data.num_dests); } @@ -2253,9 +1789,12 @@ cupsGetNamedDest(http_t *http, /* I - Connection to server or @code CUPS_HTT snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home); dest_name = cups_get_default(filename, defname, sizeof(defname), &instance); + + if (dest_name) + set_as_default = 2; } - if (!name) + if (!dest_name) { /* * Still not there? Try the system lpoptions file... @@ -2263,6 +1802,9 @@ cupsGetNamedDest(http_t *http, /* I - Connection to server or @code CUPS_HTT snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot); dest_name = cups_get_default(filename, defname, sizeof(defname), &instance); + + if (dest_name) + set_as_default = 3; } if (!dest_name) @@ -2271,7 +1813,8 @@ cupsGetNamedDest(http_t *http, /* I - Connection to server or @code CUPS_HTT * No locally-set default destination, ask the server... */ - op = IPP_OP_CUPS_GET_DEFAULT; + op = IPP_OP_CUPS_GET_DEFAULT; + set_as_default = 4; DEBUG_puts("1cupsGetNamedDest: Asking server for default printer..."); } @@ -2302,7 +1845,36 @@ cupsGetNamedDest(http_t *http, /* I - Connection to server or @code CUPS_HTT dest = data.dest; } else + { + switch (set_as_default) + { + default : + break; + + case 1 : /* Set from env vars */ + if (getenv("LPDEST")) + _cupsSetError(IPP_STATUS_ERROR_NOT_FOUND, _("LPDEST environment variable names default destination that does not exist."), 1); + else if (getenv("PRINTER")) + _cupsSetError(IPP_STATUS_ERROR_NOT_FOUND, _("PRINTER environment variable names default destination that does not exist."), 1); + else + _cupsSetError(IPP_STATUS_ERROR_NOT_FOUND, _("No default destination."), 1); + break; + + case 2 : /* Set from ~/.cups/lpoptions */ + _cupsSetError(IPP_STATUS_ERROR_NOT_FOUND, _("~/.cups/lpoptions file names default destination that does not exist."), 1); + break; + + case 3 : /* Set from /etc/cups/lpoptions */ + _cupsSetError(IPP_STATUS_ERROR_NOT_FOUND, _("/etc/cups/lpoptions file names default destination that does not exist."), 1); + break; + + case 4 : /* Set from server */ + _cupsSetError(IPP_STATUS_ERROR_NOT_FOUND, _("No default destination."), 1); + break; + } + return (NULL); + } } DEBUG_printf(("1cupsGetNamedDest: Got dest=%p", (void *)dest)); @@ -2318,13 +1890,13 @@ cupsGetNamedDest(http_t *http, /* I - Connection to server or @code CUPS_HTT */ snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot); - cups_get_dests(filename, dest_name, instance, 1, 1, &dest); + cups_get_dests(filename, dest_name, instance, 0, 1, 1, &dest); if (home) { snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home); - cups_get_dests(filename, dest_name, instance, 1, 1, &dest); + cups_get_dests(filename, dest_name, instance, 0, 1, 1, &dest); } /* @@ -2460,9 +2032,9 @@ cupsSetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_ cups_option_t *option; /* Current option */ _ipp_option_t *match; /* Matching attribute for option */ FILE *fp; /* File pointer */ -#ifndef WIN32 +#ifndef _WIN32 const char *home; /* HOME environment variable */ -#endif /* WIN32 */ +#endif /* _WIN32 */ char filename[1024]; /* lpoptions file */ int num_temps; /* Number of temporary destinations */ cups_dest_t *temps = NULL, /* Temporary destinations */ @@ -2496,15 +2068,9 @@ cupsSetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_ snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot); -#ifndef WIN32 +#ifndef _WIN32 if (getuid()) { - /* - * Merge in server defaults... - */ - - num_temps = cups_get_dests(filename, NULL, NULL, 0, num_temps, &temps); - /* * Point to user defaults... */ @@ -2522,7 +2088,7 @@ cupsSetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_ snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home); } } -#endif /* !WIN32 */ +#endif /* !_WIN32 */ /* * Try to open the file... @@ -2534,7 +2100,7 @@ cupsSetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_ return (-1); } -#ifndef WIN32 +#ifndef _WIN32 /* * Set the permissions to 0644 when saving to the /etc/cups/lpoptions * file... @@ -2542,7 +2108,7 @@ cupsSetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_ if (!getuid()) fchmod(fileno(fp), 0644); -#endif /* !WIN32 */ +#endif /* !_WIN32 */ /* * Write each printer; each line looks like: @@ -2565,8 +2131,7 @@ cupsSetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_ else wrote = 0; - if ((temp = cupsGetDest(dest->name, dest->instance, num_temps, temps)) == NULL) - temp = cupsGetDest(dest->name, NULL, num_temps, temps); + temp = cupsGetDest(dest->name, NULL, num_temps, temps); for (j = dest->num_options, option = dest->options; j > 0; j --, option ++) { @@ -2574,19 +2139,14 @@ cupsSetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_ * See if this option is a printer attribute; if so, skip it... */ - if ((match = _ippFindOption(option->name)) != NULL && - match->group_tag == IPP_TAG_PRINTER) + if ((match = _ippFindOption(option->name)) != NULL && match->group_tag == IPP_TAG_PRINTER) continue; /* - * See if the server/global options match these; if so, don't - * write 'em. + * See if the server options match these; if so, don't write 'em. */ - if (temp && - (val = cupsGetOption(option->name, temp->num_options, - temp->options)) != NULL && - !_cups_strcasecmp(val, option->value)) + if (temp && (val = cupsGetOption(option->name, temp->num_options, temp->options)) != NULL && !_cups_strcasecmp(val, option->value)) continue; /* @@ -2603,10 +2163,7 @@ cupsSetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_ if (option->value[0]) { - if (strchr(option->value, ' ') || - strchr(option->value, '\\') || - strchr(option->value, '\"') || - strchr(option->value, '\'')) + if (strchr(option->value, ' ') || strchr(option->value, '\\') || strchr(option->value, '\"') || strchr(option->value, '\'')) { /* * Quote the value... @@ -2657,9 +2214,7 @@ cupsSetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_ if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) != NULL) { - CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, - dest->name, - kCFStringEncodingUTF8); + CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, dest->name, kCFStringEncodingUTF8); /* Default printer name */ if (name) @@ -3090,22 +2645,7 @@ cups_dnssd_browse_cb( * This object is new on the network. */ - if (flags & AVAHI_LOOKUP_RESULT_LOCAL) - { - /* - * This comes from the local machine so ignore it. - */ - - DEBUG_printf(("cups_dnssd_browse_cb: Ignoring local service \"%s\".", name)); - } - else - { - /* - * Create a device entry for it if it doesn't yet exist. - */ - - cups_dnssd_get_device(data, name, type, domain); - } + cups_dnssd_get_device(data, name, type, domain); break; case AVAHI_BROWSER_REMOVE : @@ -3326,66 +2866,6 @@ cups_dnssd_get_device( } -# ifdef HAVE_DNSSD -/* - * 'cups_dnssd_local_cb()' - Browse for local printers. - */ - -static void -cups_dnssd_local_cb( - DNSServiceRef sdRef, /* I - Service reference */ - DNSServiceFlags flags, /* I - Option flags */ - uint32_t interfaceIndex, /* I - Interface number */ - DNSServiceErrorType errorCode, /* I - Error, if any */ - const char *serviceName, /* I - Name of service/device */ - const char *regtype, /* I - Type of service */ - const char *replyDomain, /* I - Service domain */ - void *context) /* I - Devices array */ -{ - _cups_dnssd_data_t *data = (_cups_dnssd_data_t *)context; - /* Enumeration data */ - _cups_dnssd_device_t *device; /* Device */ - - - DEBUG_printf(("5cups_dnssd_local_cb(sdRef=%p, flags=%x, interfaceIndex=%d, errorCode=%d, serviceName=\"%s\", regtype=\"%s\", replyDomain=\"%s\", context=%p)", (void *)sdRef, flags, interfaceIndex, errorCode, serviceName, regtype, replyDomain, context)); - - /* - * Only process "add" data... - */ - - if (errorCode != kDNSServiceErr_NoError || !(flags & kDNSServiceFlagsAdd)) - return; - - /* - * Get the device... - */ - - device = cups_dnssd_get_device(data, serviceName, regtype, replyDomain); - - /* - * Hide locally-registered devices... - */ - - DEBUG_printf(("6cups_dnssd_local_cb: Hiding local printer '%s'.", - serviceName)); - - if (device->ref) - { - DNSServiceRefDeallocate(device->ref); - device->ref = 0; - } - - if (device->state == _CUPS_DNSSD_ACTIVE) - { - DEBUG_printf(("6cups_dnssd_local_cb: Remove callback for \"%s\".", device->dest.name)); - (*data->cb)(data->user_data, CUPS_DEST_FLAGS_REMOVED, &device->dest); - } - - device->state = _CUPS_DNSSD_LOCAL; -} -# endif /* HAVE_DNSSD */ - - # ifdef HAVE_AVAHI /* * 'cups_dnssd_poll_cb()' - Wait for input on the specified file descriptors. @@ -3435,9 +2915,9 @@ cups_dnssd_poll_cb( * 'cups_dnssd_query_cb()' - Process query data. */ -# ifdef HAVE_DNSSD static void cups_dnssd_query_cb( +# ifdef HAVE_DNSSD DNSServiceRef sdRef, /* I - Service reference */ DNSServiceFlags flags, /* I - Data flags */ uint32_t interfaceIndex, /* I - Interface */ @@ -3448,11 +2928,7 @@ cups_dnssd_query_cb( uint16_t rdlen, /* I - Length of record data */ const void *rdata, /* I - Record data */ uint32_t ttl, /* I - Time-to-live */ - void *context) /* I - Enumeration data */ -{ # else /* HAVE_AVAHI */ -static void -cups_dnssd_query_cb( AvahiRecordBrowser *browser, /* I - Record browser */ AvahiIfIndex interfaceIndex, /* I - Interface index (unused) */ @@ -3464,13 +2940,13 @@ cups_dnssd_query_cb( const void *rdata, /* I - TXT record */ size_t rdlen, /* I - Length of TXT record */ AvahiLookupResultFlags flags, /* I - Flags */ - void *context) /* I - Enumeration data */ +# endif /* HAVE_DNSSD */ + void *context) /* I - Enumeration data */ { -# ifdef DEBUG +# if defined(DEBUG) && defined(HAVE_AVAHI) AvahiClient *client = avahi_record_browser_get_client(browser); /* Client information */ -# endif /* DEBUG */ -# endif /* HAVE_DNSSD */ +# endif /* DEBUG && HAVE_AVAHI */ _cups_dnssd_data_t *data = (_cups_dnssd_data_t *)context; /* Enumeration data */ char serviceName[256],/* Service name */ @@ -3898,6 +3374,509 @@ cups_elapsed(struct timeval *t) /* IO - Previous time */ #endif /* HAVE_AVAHI || HAVE_DNSSD */ +/* + * 'cups_enum_dests()' - Enumerate destinations from a specific server. + */ + +static int /* O - 1 on success, 0 on failure */ +cups_enum_dests( + http_t *http, /* I - Connection to scheduler */ + unsigned flags, /* I - Enumeration flags */ + int msec, /* I - Timeout in milliseconds, -1 for indefinite */ + int *cancel, /* I - Pointer to "cancel" variable */ + cups_ptype_t type, /* I - Printer type bits */ + cups_ptype_t mask, /* I - Mask for printer type bits */ + cups_dest_cb_t cb, /* I - Callback function */ + void *user_data) /* I - User data */ +{ + int i, j, /* Looping vars */ + num_dests; /* Number of destinations */ + cups_dest_t *dests = NULL, /* Destinations */ + *dest, /* Current destination */ + *user_dest; /* User destination */ + cups_option_t *option; /* Current option */ + char *user_default; /* User default printer */ +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) + int count, /* Number of queries started */ + completed, /* Number of completed queries */ + remaining; /* Remainder of timeout */ + struct timeval curtime; /* Current time */ + _cups_dnssd_data_t data; /* Data for callback */ + _cups_dnssd_device_t *device; /* Current device */ +# ifdef HAVE_DNSSD + int nfds, /* Number of files responded */ + main_fd; /* File descriptor for lookups */ + DNSServiceRef ipp_ref = NULL; /* IPP browser */ +# ifdef HAVE_SSL + DNSServiceRef ipps_ref = NULL; /* IPPS browser */ +# endif /* HAVE_SSL */ +# ifdef HAVE_POLL + struct pollfd pfd; /* Polling data */ +# else + fd_set input; /* Input set for select() */ + struct timeval timeout; /* Timeout for select() */ +# endif /* HAVE_POLL */ +# else /* HAVE_AVAHI */ + int error; /* Error value */ + AvahiServiceBrowser *ipp_ref = NULL; /* IPP browser */ +# ifdef HAVE_SSL + AvahiServiceBrowser *ipps_ref = NULL; /* IPPS browser */ +# endif /* HAVE_SSL */ +# endif /* HAVE_DNSSD */ +#else + _cups_getdata_t data; /* Data for callback */ +#endif /* HAVE_DNSSD || HAVE_AVAHI */ + const char *home; /* HOME environment variable */ + char filename[1024]; /* Local lpoptions file */ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + DEBUG_printf(("cups_enum_dests(flags=%x, msec=%d, cancel=%p, type=%x, mask=%x, cb=%p, user_data=%p)", flags, msec, (void *)cancel, type, mask, (void *)cb, (void *)user_data)); + + /* + * Range check input... + */ + + (void)flags; + + if (!cb) + { + DEBUG_puts("1cups_enum_dests: No callback, returning 0."); + return (0); + } + + /* + * Load the /etc/cups/lpoptions and ~/.cups/lpoptions files... + */ + + memset(&data, 0, sizeof(data)); + + if ((user_default = _cupsUserDefault(data.def_name, sizeof(data.def_name))) == NULL) + { + const char *defprinter = cupsGetDefault2(http); + /* Server default, if any */ + + if (defprinter) + strlcpy(data.def_name, defprinter, sizeof(data.def_name)); + } + + if (data.def_name[0]) + { + /* + * Separate printer and instance name... + */ + + if ((data.def_instance = strchr(data.def_name, '/')) != NULL) + *data.def_instance++ = '\0'; + } + + DEBUG_printf(("1cups_enum_dests: def_name=\"%s\", def_instance=\"%s\"", data.def_name, data.def_instance)); + + snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot); + data.num_dests = cups_get_dests(filename, NULL, NULL, 1, user_default != NULL, data.num_dests, &data.dests); + + if ((home = getenv("HOME")) != NULL) + { + snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home); + + data.num_dests = cups_get_dests(filename, NULL, NULL, 1, user_default != NULL, data.num_dests, &data.dests); + } + + /* + * Get ready to enumerate... + */ + +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) + data.type = type; + data.mask = mask; + data.cb = cb; + data.user_data = user_data; + data.devices = cupsArrayNew3((cups_array_func_t)cups_dnssd_compare_devices, NULL, NULL, 0, NULL, (cups_afree_func_t)cups_dnssd_free_device); +#endif /* HAVE_DNSSD || HAVE_AVAHI */ + + if (!(mask & CUPS_PRINTER_DISCOVERED) || !(type & CUPS_PRINTER_DISCOVERED)) + { + /* + * Get the list of local printers and pass them to the callback function... + */ + + num_dests = _cupsGetDests(http, IPP_OP_CUPS_GET_PRINTERS, NULL, &dests, type, mask); + + if (data.def_name[0]) + { + /* + * Lookup the named default printer and instance and make it the default... + */ + + if ((dest = cupsGetDest(data.def_name, data.def_instance, num_dests, dests)) != NULL) + { + DEBUG_printf(("1cups_enum_dests: Setting is_default on \"%s/%s\".", dest->name, dest->instance)); + dest->is_default = 1; + } + } + + for (i = num_dests, dest = dests; + i > 0 && (!cancel || !*cancel); + i --, dest ++) + { +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) + const char *device_uri; /* Device URI */ +#endif /* HAVE_DNSSD || HAVE_AVAHI */ + + if ((user_dest = cupsGetDest(dest->name, dest->instance, data.num_dests, data.dests)) != NULL) + { + /* + * Apply user defaults to this destination... + */ + + for (j = user_dest->num_options, option = user_dest->options; j > 0; j --, option ++) + dest->num_options = cupsAddOption(option->name, option->value, dest->num_options, &dest->options); + } + + if (!(*cb)(user_data, i > 1 ? CUPS_DEST_FLAGS_MORE : CUPS_DEST_FLAGS_NONE, dest)) + break; + +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) + if (!dest->instance && (device_uri = cupsGetOption("device-uri", dest->num_options, dest->options)) != NULL && !strncmp(device_uri, "dnssd://", 8)) + { + /* + * Add existing queue using service name, etc. so we don't list it again... + */ + + char scheme[32], /* URI scheme */ + userpass[32], /* Username:password */ + serviceName[256], /* Service name (host field) */ + resource[256], /* Resource (options) */ + *regtype, /* Registration type */ + *replyDomain; /* Registration domain */ + int port; /* Port number (not used) */ + + if (httpSeparateURI(HTTP_URI_CODING_ALL, device_uri, scheme, sizeof(scheme), userpass, sizeof(userpass), serviceName, sizeof(serviceName), &port, resource, sizeof(resource)) >= HTTP_URI_STATUS_OK) + { + if ((regtype = strstr(serviceName, "._ipp")) != NULL) + { + *regtype++ = '\0'; + + if ((replyDomain = strstr(regtype, "._tcp.")) != NULL) + { + replyDomain[5] = '\0'; + replyDomain += 6; + + if ((device = cups_dnssd_get_device(&data, serviceName, regtype, replyDomain)) != NULL) + device->state = _CUPS_DNSSD_ACTIVE; + } + } + } + } +#endif /* HAVE_DNSSD || HAVE_AVAHI */ + } + + cupsFreeDests(num_dests, dests); + + if (i > 0 || msec == 0) + goto enum_finished; + } + + /* + * Return early if the caller doesn't want to do discovery... + */ + + if ((mask & CUPS_PRINTER_DISCOVERED) && !(type & CUPS_PRINTER_DISCOVERED)) + goto enum_finished; + +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) + /* + * Get Bonjour-shared printers... + */ + + gettimeofday(&curtime, NULL); + +# ifdef HAVE_DNSSD + if (DNSServiceCreateConnection(&data.main_ref) != kDNSServiceErr_NoError) + { + DEBUG_puts("1cups_enum_dests: Unable to create service browser, returning 0."); + + cupsFreeDests(data.num_dests, data.dests); + + return (0); + } + + main_fd = DNSServiceRefSockFD(data.main_ref); + + ipp_ref = data.main_ref; + if (DNSServiceBrowse(&ipp_ref, kDNSServiceFlagsShareConnection, 0, "_ipp._tcp", NULL, (DNSServiceBrowseReply)cups_dnssd_browse_cb, &data) != kDNSServiceErr_NoError) + { + DEBUG_puts("1cups_enum_dests: Unable to create IPP browser, returning 0."); + DNSServiceRefDeallocate(data.main_ref); + + cupsFreeDests(data.num_dests, data.dests); + + return (0); + } + +# ifdef HAVE_SSL + ipps_ref = data.main_ref; + if (DNSServiceBrowse(&ipps_ref, kDNSServiceFlagsShareConnection, 0, "_ipps._tcp", NULL, (DNSServiceBrowseReply)cups_dnssd_browse_cb, &data) != kDNSServiceErr_NoError) + { + DEBUG_puts("1cups_enum_dests: Unable to create IPPS browser, returning 0."); + DNSServiceRefDeallocate(data.main_ref); + + cupsFreeDests(data.num_dests, data.dests); + + return (0); + } +# endif /* HAVE_SSL */ + +# else /* HAVE_AVAHI */ + if ((data.simple_poll = avahi_simple_poll_new()) == NULL) + { + DEBUG_puts("1cups_enum_dests: Unable to create Avahi poll, returning 0."); + + cupsFreeDests(data.num_dests, data.dests); + + return (0); + } + + avahi_simple_poll_set_func(data.simple_poll, cups_dnssd_poll_cb, &data); + + data.client = avahi_client_new(avahi_simple_poll_get(data.simple_poll), + 0, cups_dnssd_client_cb, &data, + &error); + if (!data.client) + { + DEBUG_puts("1cups_enum_dests: Unable to create Avahi client, returning 0."); + avahi_simple_poll_free(data.simple_poll); + + cupsFreeDests(data.num_dests, data.dests); + + return (0); + } + + data.browsers = 1; + if ((ipp_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipp._tcp", NULL, 0, cups_dnssd_browse_cb, &data)) == NULL) + { + DEBUG_puts("1cups_enum_dests: Unable to create Avahi IPP browser, returning 0."); + + avahi_client_free(data.client); + avahi_simple_poll_free(data.simple_poll); + + cupsFreeDests(data.num_dests, data.dests); + + return (0); + } + +# ifdef HAVE_SSL + data.browsers ++; + if ((ipps_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipps._tcp", NULL, 0, cups_dnssd_browse_cb, &data)) == NULL) + { + DEBUG_puts("1cups_enum_dests: Unable to create Avahi IPPS browser, returning 0."); + + avahi_service_browser_free(ipp_ref); + avahi_client_free(data.client); + avahi_simple_poll_free(data.simple_poll); + + cupsFreeDests(data.num_dests, data.dests); + + return (0); + } +# endif /* HAVE_SSL */ +# endif /* HAVE_DNSSD */ + + if (msec < 0) + remaining = INT_MAX; + else + remaining = msec; + + while (remaining > 0 && (!cancel || !*cancel)) + { + /* + * Check for input... + */ + + DEBUG_printf(("1cups_enum_dests: remaining=%d", remaining)); + + cups_elapsed(&curtime); + +# ifdef HAVE_DNSSD +# ifdef HAVE_POLL + pfd.fd = main_fd; + pfd.events = POLLIN; + + nfds = poll(&pfd, 1, remaining > _CUPS_DNSSD_MAXTIME ? _CUPS_DNSSD_MAXTIME : remaining); + +# else + FD_ZERO(&input); + FD_SET(main_fd, &input); + + timeout.tv_sec = 0; + timeout.tv_usec = 1000 * (remaining > _CUPS_DNSSD_MAXTIME ? _CUPS_DNSSD_MAXTIME : remaining); + + nfds = select(main_fd + 1, &input, NULL, NULL, &timeout); +# endif /* HAVE_POLL */ + + if (nfds > 0) + DNSServiceProcessResult(data.main_ref); + else if (nfds < 0 && errno != EINTR && errno != EAGAIN) + break; + +# else /* HAVE_AVAHI */ + data.got_data = 0; + + if ((error = avahi_simple_poll_iterate(data.simple_poll, _CUPS_DNSSD_MAXTIME)) > 0) + { + /* + * We've been told to exit the loop. Perhaps the connection to + * Avahi failed. + */ + + break; + } + + DEBUG_printf(("1cups_enum_dests: got_data=%d", data.got_data)); +# endif /* HAVE_DNSSD */ + + remaining -= cups_elapsed(&curtime); + + for (device = (_cups_dnssd_device_t *)cupsArrayFirst(data.devices), + count = 0, completed = 0; + device; + device = (_cups_dnssd_device_t *)cupsArrayNext(data.devices)) + { + if (device->ref) + count ++; + + if (device->state == _CUPS_DNSSD_ACTIVE) + completed ++; + + if (!device->ref && device->state == _CUPS_DNSSD_NEW) + { + DEBUG_printf(("1cups_enum_dests: Querying '%s'.", device->fullName)); + +# ifdef HAVE_DNSSD + device->ref = data.main_ref; + + if (DNSServiceQueryRecord(&(device->ref), kDNSServiceFlagsShareConnection, 0, device->fullName, kDNSServiceType_TXT, kDNSServiceClass_IN, (DNSServiceQueryRecordReply)cups_dnssd_query_cb, &data) == kDNSServiceErr_NoError) + { + count ++; + } + else + { + device->ref = 0; + device->state = _CUPS_DNSSD_ERROR; + + DEBUG_puts("1cups_enum_dests: Query failed."); + } + +# else /* HAVE_AVAHI */ + if ((device->ref = avahi_record_browser_new(data.client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, device->fullName, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_TXT, 0, cups_dnssd_query_cb, &data)) != NULL) + { + DEBUG_printf(("1cups_enum_dests: Query ref=%p", device->ref)); + count ++; + } + else + { + device->state = _CUPS_DNSSD_ERROR; + + DEBUG_printf(("1cups_enum_dests: Query failed: %s", avahi_strerror(avahi_client_errno(data.client)))); + } +# endif /* HAVE_DNSSD */ + } + else if (device->ref && device->state == _CUPS_DNSSD_PENDING) + { + completed ++; + + DEBUG_printf(("1cups_enum_dests: Query for \"%s\" is complete.", device->fullName)); + + if ((device->type & mask) == type) + { + dest = &device->dest; + + if ((user_dest = cupsGetDest(dest->name, dest->instance, data.num_dests, data.dests)) != NULL) + { + /* + * Apply user defaults to this destination... + */ + + for (j = user_dest->num_options, option = user_dest->options; j > 0; j --, option ++) + dest->num_options = cupsAddOption(option->name, option->value, dest->num_options, &dest->options); + } + + if (!strcasecmp(dest->name, data.def_name) && !data.def_instance) + { + DEBUG_printf(("1cups_enum_dests: Setting is_default on discovered \"%s\".", dest->name)); + dest->is_default = 1; + } + + DEBUG_printf(("1cups_enum_dests: Add callback for \"%s\".", device->dest.name)); + if (!(*cb)(user_data, CUPS_DEST_FLAGS_NONE, dest)) + { + remaining = -1; + break; + } + } + + device->state = _CUPS_DNSSD_ACTIVE; + } + } + +# ifdef HAVE_AVAHI + DEBUG_printf(("1cups_enum_dests: remaining=%d, browsers=%d, completed=%d, count=%d, devices count=%d", remaining, data.browsers, completed, count, cupsArrayCount(data.devices))); + + if (data.browsers == 0 && completed == cupsArrayCount(data.devices)) + break; +# else + DEBUG_printf(("1cups_enum_dests: remaining=%d, completed=%d, count=%d, devices count=%d", remaining, completed, count, cupsArrayCount(data.devices))); + + if (completed == cupsArrayCount(data.devices)) + break; +# endif /* HAVE_AVAHI */ + } +#endif /* HAVE_DNSSD || HAVE_AVAHI */ + + /* + * Return... + */ + + enum_finished: + + cupsFreeDests(data.num_dests, data.dests); + +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) + cupsArrayDelete(data.devices); + +# ifdef HAVE_DNSSD + if (ipp_ref) + DNSServiceRefDeallocate(ipp_ref); + +# ifdef HAVE_SSL + if (ipps_ref) + DNSServiceRefDeallocate(ipps_ref); +# endif /* HAVE_SSL */ + + if (data.main_ref) + DNSServiceRefDeallocate(data.main_ref); + +# else /* HAVE_AVAHI */ + if (ipp_ref) + avahi_service_browser_free(ipp_ref); +# ifdef HAVE_SSL + if (ipps_ref) + avahi_service_browser_free(ipps_ref); +# endif /* HAVE_SSL */ + + if (data.client) + avahi_client_free(data.client); + if (data.simple_poll) + avahi_simple_poll_free(data.simple_poll); +# endif /* HAVE_DNSSD */ +#endif /* HAVE_DNSSD || HAVE_AVAHI */ + + DEBUG_puts("1cups_enum_dests: Returning 1."); + + return (1); +} + + /* * 'cups_find_dest()' - Find a destination using a binary search. */ @@ -4089,6 +4068,7 @@ cups_get_dests( const char *filename, /* I - File to read from */ const char *match_name, /* I - Destination name we want */ const char *match_inst, /* I - Instance name we want */ + int load_all, /* I - Load all saved destinations? */ int user_default_set, /* I - User default printer set? */ int num_dests, /* I - Number of destinations */ cups_dest_t **dests) /* IO - Destinations */ @@ -4103,7 +4083,7 @@ cups_get_dests( int linenum; /* Current line number */ - DEBUG_printf(("7cups_get_dests(filename=\"%s\", match_name=\"%s\", match_inst=\"%s\", user_default_set=%d, num_dests=%d, dests=%p)", filename, match_name, match_inst, user_default_set, num_dests, (void *)dests)); + DEBUG_printf(("7cups_get_dests(filename=\"%s\", match_name=\"%s\", match_inst=\"%s\", load_all=%d, user_default_set=%d, num_dests=%d, dests=%p)", filename, match_name, match_inst, load_all, user_default_set, num_dests, (void *)dests)); /* * Try to open the file... @@ -4171,8 +4151,7 @@ cups_get_dests( instance)); /* - * See if the primary instance of the destination exists; if not, - * ignore this entry and move on... + * Match and/or ignore missing destinations... */ if (match_name) @@ -4185,7 +4164,7 @@ cups_get_dests( dest = *dests; } - else if (cupsGetDest(name, NULL, num_dests, *dests) == NULL) + else if (!load_all && cupsGetDest(name, NULL, num_dests, *dests) == NULL) { DEBUG_puts("9cups_get_dests: Not found!"); continue; @@ -4213,8 +4192,7 @@ cups_get_dests( * Add options until we hit the end of the line... */ - dest->num_options = cupsParseOptions(lineptr, dest->num_options, - &(dest->options)); + dest->num_options = cupsParseOptions(lineptr, dest->num_options, &(dest->options)); /* * If we found what we were looking for, stop now... diff --git a/cups/dir.c b/cups/dir.c index b7cd400..184aa7c 100644 --- a/cups/dir.c +++ b/cups/dir.c @@ -6,11 +6,7 @@ * Copyright 2007-2017 by Apple Inc. * Copyright 1997-2005 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -18,7 +14,7 @@ */ #include "string-private.h" -#include "debug-private.h" +#include "debug-internal.h" #include "dir.h" @@ -26,7 +22,7 @@ * Windows implementation... */ -#ifdef WIN32 +#ifdef _WIN32 # include /* @@ -145,7 +141,7 @@ cupsDirOpen(const char *directory) /* I - Directory name */ cups_dentry_t * /* O - Directory entry or @code NULL@ if there are no more */ cupsDirRead(cups_dir_t *dp) /* I - Directory pointer */ { - WIN32_FIND_DATA entry; /* Directory entry data */ + WIN32_FIND_DATAA entry; /* Directory entry data */ /* @@ -165,11 +161,11 @@ cupsDirRead(cups_dir_t *dp) /* I - Directory pointer */ * No, find the first file... */ - dp->dir = FindFirstFile(dp->directory, &entry); + dp->dir = FindFirstFileA(dp->directory, &entry); if (dp->dir == INVALID_HANDLE_VALUE) return (NULL); } - else if (!FindNextFile(dp->dir, &entry)) + else if (!FindNextFileA(dp->dir, &entry)) return (NULL); /* @@ -422,4 +418,4 @@ cupsDirRewind(cups_dir_t *dp) /* I - Directory pointer */ rewinddir(dp->dir); } -#endif /* WIN32 */ +#endif /* _WIN32 */ diff --git a/cups/dir.h b/cups/dir.h index d010544..f6878cb 100644 --- a/cups/dir.h +++ b/cups/dir.h @@ -6,11 +6,7 @@ * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2006 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ #ifndef _CUPS_DIR_H_ diff --git a/cups/emit.c b/cups/emit.c deleted file mode 100644 index 650e847..0000000 --- a/cups/emit.c +++ /dev/null @@ -1,1229 +0,0 @@ -/* - * "$Id: emit.c 7863 2008-08-26 03:39:59Z mike $" - * - * PPD code emission routines for CUPS. - * - * Copyright 2007-2012 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * PostScript is a trademark of Adobe Systems, Inc. - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * ppdCollect() - Collect all marked options that reside in the - * specified section. - * ppdCollect2() - Collect all marked options that reside in the - * specified section and minimum order. - * ppdEmit() - Emit code for marked options to a file. - * ppdEmitAfterOrder() - Emit a subset of the code for marked options to a - * file. - * ppdEmitFd() - Emit code for marked options to a file. - * ppdEmitJCL() - Emit code for JCL options to a file. - * ppdEmitJCLEnd() - Emit JCLEnd code to a file. - * ppdEmitString() - Get a string containing the code for marked - * options. - * ppd_compare_cparams() - Compare the order of two custom parameters. - * ppd_handle_media() - Handle media selection... - */ - -/* - * Include necessary headers... - */ - -#include "cups-private.h" -#if defined(WIN32) || defined(__EMX__) -# include -#else -# include -#endif /* WIN32 || __EMX__ */ - - -/* - * Local functions... - */ - -static int ppd_compare_cparams(ppd_cparam_t *a, ppd_cparam_t *b); -static void ppd_handle_media(ppd_file_t *ppd); - - -/* - * Local globals... - */ - -static const char ppd_custom_code[] = - "pop pop pop\n" - "<>setpagedevice\n"; - - -/* - * 'ppdCollect()' - Collect all marked options that reside in the specified - * section. - * - * The choices array should be freed using @code free@ when you are - * finished with it. - */ - -int /* O - Number of options marked */ -ppdCollect(ppd_file_t *ppd, /* I - PPD file data */ - ppd_section_t section, /* I - Section to collect */ - ppd_choice_t ***choices) /* O - Pointers to choices */ -{ - return (ppdCollect2(ppd, section, 0.0, choices)); -} - - -/* - * 'ppdCollect2()' - Collect all marked options that reside in the - * specified section and minimum order. - * - * The choices array should be freed using @code free@ when you are - * finished with it. - * - * @since CUPS 1.2/OS X 10.5@ - */ - -int /* O - Number of options marked */ -ppdCollect2(ppd_file_t *ppd, /* I - PPD file data */ - ppd_section_t section, /* I - Section to collect */ - float min_order, /* I - Minimum OrderDependency value */ - ppd_choice_t ***choices) /* O - Pointers to choices */ -{ - ppd_choice_t *c; /* Current choice */ - ppd_section_t csection; /* Current section */ - float corder; /* Current OrderDependency value */ - int count; /* Number of choices collected */ - ppd_choice_t **collect; /* Collected choices */ - float *orders; /* Collected order values */ - - - DEBUG_printf(("ppdCollect2(ppd=%p, section=%d, min_order=%f, choices=%p)", - ppd, section, min_order, choices)); - - if (!ppd || !choices) - { - if (choices) - *choices = NULL; - - return (0); - } - - /* - * Allocate memory for up to N selected choices... - */ - - count = 0; - if ((collect = calloc(sizeof(ppd_choice_t *), - cupsArrayCount(ppd->marked))) == NULL) - { - *choices = NULL; - return (0); - } - - if ((orders = calloc(sizeof(float), cupsArrayCount(ppd->marked))) == NULL) - { - *choices = NULL; - free(collect); - return (0); - } - - /* - * Loop through all options and add choices as needed... - */ - - for (c = (ppd_choice_t *)cupsArrayFirst(ppd->marked); - c; - c = (ppd_choice_t *)cupsArrayNext(ppd->marked)) - { - csection = c->option->section; - corder = c->option->order; - - if (!strcmp(c->choice, "Custom")) - { - ppd_attr_t *attr; /* NonUIOrderDependency value */ - float aorder; /* Order value */ - char asection[17], /* Section name */ - amain[PPD_MAX_NAME + 1], - aoption[PPD_MAX_NAME]; - /* *CustomFoo and True */ - - - for (attr = ppdFindAttr(ppd, "NonUIOrderDependency", NULL); - attr; - attr = ppdFindNextAttr(ppd, "NonUIOrderDependency", NULL)) - if (attr->value && - sscanf(attr->value, "%f%16s%41s%40s", &aorder, asection, amain, - aoption) == 4 && - !strncmp(amain, "*Custom", 7) && - !strcmp(amain + 7, c->option->keyword) && !strcmp(aoption, "True")) - { - /* - * Use this NonUIOrderDependency... - */ - - corder = aorder; - - if (!strcmp(asection, "DocumentSetup")) - csection = PPD_ORDER_DOCUMENT; - else if (!strcmp(asection, "ExitServer")) - csection = PPD_ORDER_EXIT; - else if (!strcmp(asection, "JCLSetup")) - csection = PPD_ORDER_JCL; - else if (!strcmp(asection, "PageSetup")) - csection = PPD_ORDER_PAGE; - else if (!strcmp(asection, "Prolog")) - csection = PPD_ORDER_PROLOG; - else - csection = PPD_ORDER_ANY; - - break; - } - } - - if (csection == section && corder >= min_order) - { - collect[count] = c; - orders[count] = corder; - count ++; - } - } - - /* - * If we have more than 1 marked choice, sort them... - */ - - if (count > 1) - { - int i, j; /* Looping vars */ - - for (i = 0; i < (count - 1); i ++) - for (j = i + 1; j < count; j ++) - if (orders[i] > orders[j]) - { - c = collect[i]; - corder = orders[i]; - collect[i] = collect[j]; - orders[i] = orders[j]; - collect[j] = c; - orders[j] = corder; - } - } - - free(orders); - - DEBUG_printf(("2ppdCollect2: %d marked choices...", count)); - - /* - * Return the array and number of choices; if 0, free the array since - * it isn't needed. - */ - - if (count > 0) - { - *choices = collect; - return (count); - } - else - { - *choices = NULL; - free(collect); - return (0); - } -} - - -/* - * 'ppdEmit()' - Emit code for marked options to a file. - */ - -int /* O - 0 on success, -1 on failure */ -ppdEmit(ppd_file_t *ppd, /* I - PPD file record */ - FILE *fp, /* I - File to write to */ - ppd_section_t section) /* I - Section to write */ -{ - return (ppdEmitAfterOrder(ppd, fp, section, 0, 0.0)); -} - - -/* - * 'ppdEmitAfterOrder()' - Emit a subset of the code for marked options to a file. - * - * When "limit" is non-zero, this function only emits options whose - * OrderDependency value is greater than or equal to "min_order". - * - * When "limit" is zero, this function is identical to ppdEmit(). - * - * @since CUPS 1.2/OS X 10.5@ - */ - -int /* O - 0 on success, -1 on failure */ -ppdEmitAfterOrder( - ppd_file_t *ppd, /* I - PPD file record */ - FILE *fp, /* I - File to write to */ - ppd_section_t section, /* I - Section to write */ - int limit, /* I - Non-zero to use min_order */ - float min_order) /* I - Lowest OrderDependency */ -{ - char *buffer; /* Option code */ - int status; /* Return status */ - - - /* - * Range check input... - */ - - if (!ppd || !fp) - return (-1); - - /* - * Get the string... - */ - - buffer = ppdEmitString(ppd, section, limit ? min_order : 0.0f); - - /* - * Write it as needed and return... - */ - - if (buffer) - { - status = fputs(buffer, fp) < 0 ? -1 : 0; - - free(buffer); - } - else - status = 0; - - return (status); -} - - -/* - * 'ppdEmitFd()' - Emit code for marked options to a file. - */ - -int /* O - 0 on success, -1 on failure */ -ppdEmitFd(ppd_file_t *ppd, /* I - PPD file record */ - int fd, /* I - File to write to */ - ppd_section_t section) /* I - Section to write */ -{ - char *buffer, /* Option code */ - *bufptr; /* Pointer into code */ - size_t buflength; /* Length of option code */ - ssize_t bytes; /* Bytes written */ - int status; /* Return status */ - - - /* - * Range check input... - */ - - if (!ppd || fd < 0) - return (-1); - - /* - * Get the string... - */ - - buffer = ppdEmitString(ppd, section, 0.0); - - /* - * Write it as needed and return... - */ - - if (buffer) - { - buflength = strlen(buffer); - bufptr = buffer; - bytes = 0; - - while (buflength > 0) - { -#ifdef WIN32 - if ((bytes = (ssize_t)write(fd, bufptr, (unsigned)buflength)) < 0) -#else - if ((bytes = write(fd, bufptr, buflength)) < 0) -#endif /* WIN32 */ - { - if (errno == EAGAIN || errno == EINTR) - continue; - - break; - } - - buflength -= bytes; - bufptr += bytes; - } - - status = bytes < 0 ? -1 : 0; - - free(buffer); - } - else - status = 0; - - return (status); -} - - -/* - * 'ppdEmitJCL()' - Emit code for JCL options to a file. - */ - -int /* O - 0 on success, -1 on failure */ -ppdEmitJCL(ppd_file_t *ppd, /* I - PPD file record */ - FILE *fp, /* I - File to write to */ - int job_id, /* I - Job ID */ - const char *user, /* I - Username */ - const char *title) /* I - Title */ -{ - char *ptr; /* Pointer into JCL string */ - char temp[65], /* Local title string */ - displaymsg[33]; /* Local display string */ - - - /* - * Range check the input... - */ - - if (!ppd || !ppd->jcl_begin || !ppd->jcl_ps) - return (0); - - /* - * See if the printer supports HP PJL... - */ - - if (!strncmp(ppd->jcl_begin, "\033%-12345X@", 10)) - { - /* - * This printer uses HP PJL commands for output; filter the output - * so that we only have a single "@PJL JOB" command in the header... - * - * To avoid bugs in the PJL implementation of certain vendors' products - * (Xerox in particular), we add a dummy "@PJL" command at the beginning - * of the PJL commands to initialize PJL processing. - */ - - ppd_attr_t *charset; /* PJL charset */ - ppd_attr_t *display; /* PJL display command */ - - - if ((charset = ppdFindAttr(ppd, "cupsPJLCharset", NULL)) != NULL) - { - if (!charset->value || _cups_strcasecmp(charset->value, "UTF-8")) - charset = NULL; - } - - if ((display = ppdFindAttr(ppd, "cupsPJLDisplay", NULL)) != NULL) - { - if (!display->value) - display = NULL; - } - - fputs("\033%-12345X@PJL\n", fp); - for (ptr = ppd->jcl_begin + 9; *ptr;) - if (!strncmp(ptr, "@PJL JOB", 8)) - { - /* - * Skip job command... - */ - - for (;*ptr; ptr ++) - if (*ptr == '\n') - break; - - if (*ptr) - ptr ++; - } - else - { - /* - * Copy line... - */ - - for (;*ptr; ptr ++) - { - putc(*ptr, fp); - if (*ptr == '\n') - break; - } - - if (*ptr) - ptr ++; - } - - /* - * Clean up the job title... - */ - - if ((ptr = strrchr(title, '/')) != NULL) - { - /* - * Only show basename of file path... - */ - - title = ptr + 1; - } - - if (!strncmp(title, "smbprn.", 7)) - { - /* - * Skip leading smbprn.######## from Samba jobs... - */ - - for (title += 7; *title && isdigit(*title & 255); title ++); - while (_cups_isspace(*title)) - title ++; - - if ((ptr = strstr(title, " - ")) != NULL) - { - /* - * Skip application name in "Some Application - Title of job"... - */ - - title = ptr + 3; - } - } - - /* - * Replace double quotes with single quotes and UTF-8 characters with - * question marks so that the title does not cause a PJL syntax error. - */ - - strlcpy(temp, title, sizeof(temp)); - - for (ptr = temp; *ptr; ptr ++) - if (*ptr == '\"') - *ptr = '\''; - else if (!charset && (*ptr & 128)) - *ptr = '?'; - - /* - * CUPS STR #3125: Long PJL JOB NAME causes problems with some printers - * - * Generate the display message, truncating at 32 characters + nul to avoid - * issues with some printer's PJL implementations... - */ - - snprintf(displaymsg, sizeof(displaymsg), "%d %s %s", job_id, user, temp); - - /* - * Send PJL JOB and PJL RDYMSG commands before we enter PostScript mode... - */ - - if (display && strcmp(display->value, "job")) - fprintf(fp, "@PJL JOB NAME = \"%s\"\n", temp); - else if (display && !strcmp(display->value, "rdymsg")) - fprintf(fp, "@PJL RDYMSG DISPLAY = \"%s\"\n", displaymsg); - else - fprintf(fp, "@PJL JOB NAME = \"%s\" DISPLAY = \"%s\"\n", temp, - displaymsg); - - /* - * Replace double quotes with single quotes and UTF-8 characters with - * question marks so that the user does not cause a PJL syntax error. - */ - - strlcpy(temp, user, sizeof(temp)); - - for (ptr = temp; *ptr; ptr ++) - if (*ptr == '\"') - *ptr = '\''; - else if (!charset && (*ptr & 128)) - *ptr = '?'; - - fprintf(fp, "@PJL SET USERNAME = \"%s\"\n", temp); - } - else - fputs(ppd->jcl_begin, fp); - - ppdEmit(ppd, fp, PPD_ORDER_JCL); - fputs(ppd->jcl_ps, fp); - - return (0); -} - - -/* - * 'ppdEmitJCLEnd()' - Emit JCLEnd code to a file. - * - * @since CUPS 1.2/OS X 10.5@ - */ - -int /* O - 0 on success, -1 on failure */ -ppdEmitJCLEnd(ppd_file_t *ppd, /* I - PPD file record */ - FILE *fp) /* I - File to write to */ -{ - /* - * Range check the input... - */ - - if (!ppd) - return (0); - - if (!ppd->jcl_end) - { - if (ppd->num_filters == 0) - putc(0x04, fp); - - return (0); - } - - /* - * See if the printer supports HP PJL... - */ - - if (!strncmp(ppd->jcl_end, "\033%-12345X@", 10)) - { - /* - * This printer uses HP PJL commands for output; filter the output - * so that we only have a single "@PJL JOB" command in the header... - * - * To avoid bugs in the PJL implementation of certain vendors' products - * (Xerox in particular), we add a dummy "@PJL" command at the beginning - * of the PJL commands to initialize PJL processing. - */ - - fputs("\033%-12345X@PJL\n", fp); - fputs("@PJL RDYMSG DISPLAY = \"\"\n", fp); - fputs(ppd->jcl_end + 9, fp); - } - else - fputs(ppd->jcl_end, fp); - - return (0); -} - - -/* - * 'ppdEmitString()' - Get a string containing the code for marked options. - * - * When "min_order" is greater than zero, this function only includes options - * whose OrderDependency value is greater than or equal to "min_order". - * Otherwise, all options in the specified section are included in the - * returned string. - * - * The return string is allocated on the heap and should be freed using - * @code free@ when you are done with it. - * - * @since CUPS 1.2/OS X 10.5@ - */ - -char * /* O - String containing option code or @code NULL@ if there is no option code */ -ppdEmitString(ppd_file_t *ppd, /* I - PPD file record */ - ppd_section_t section, /* I - Section to write */ - float min_order) /* I - Lowest OrderDependency */ -{ - int i, j, /* Looping vars */ - count; /* Number of choices */ - ppd_choice_t **choices; /* Choices */ - ppd_size_t *size; /* Custom page size */ - ppd_coption_t *coption; /* Custom option */ - ppd_cparam_t *cparam; /* Custom parameter */ - size_t bufsize; /* Size of string buffer needed */ - char *buffer, /* String buffer */ - *bufptr, /* Pointer into buffer */ - *bufend; /* End of buffer */ - struct lconv *loc; /* Locale data */ - - - DEBUG_printf(("ppdEmitString(ppd=%p, section=%d, min_order=%f)", - ppd, section, min_order)); - - /* - * Range check input... - */ - - if (!ppd) - return (NULL); - - /* - * Use PageSize or PageRegion as required... - */ - - ppd_handle_media(ppd); - - /* - * Collect the options we need to emit... - */ - - if ((count = ppdCollect2(ppd, section, min_order, &choices)) == 0) - return (NULL); - - /* - * Count the number of bytes that are required to hold all of the - * option code... - */ - - for (i = 0, bufsize = 1; i < count; i ++) - { - if (section == PPD_ORDER_JCL) - { - if (!_cups_strcasecmp(choices[i]->choice, "Custom") && - (coption = ppdFindCustomOption(ppd, choices[i]->option->keyword)) - != NULL) - { - /* - * Add space to account for custom parameter substitution... - */ - - for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params); - cparam; - cparam = (ppd_cparam_t *)cupsArrayNext(coption->params)) - { - switch (cparam->type) - { - case PPD_CUSTOM_CURVE : - case PPD_CUSTOM_INVCURVE : - case PPD_CUSTOM_POINTS : - case PPD_CUSTOM_REAL : - case PPD_CUSTOM_INT : - bufsize += 10; - break; - - case PPD_CUSTOM_PASSCODE : - case PPD_CUSTOM_PASSWORD : - case PPD_CUSTOM_STRING : - if (cparam->current.custom_string) - bufsize += strlen(cparam->current.custom_string); - break; - } - } - } - } - else if (section != PPD_ORDER_EXIT) - { - bufsize += 3; /* [{\n */ - - if ((!_cups_strcasecmp(choices[i]->option->keyword, "PageSize") || - !_cups_strcasecmp(choices[i]->option->keyword, "PageRegion")) && - !_cups_strcasecmp(choices[i]->choice, "Custom")) - { - DEBUG_puts("2ppdEmitString: Custom size set!"); - - bufsize += 37; /* %%BeginFeature: *CustomPageSize True\n */ - bufsize += 50; /* Five 9-digit numbers + newline */ - } - else if (!_cups_strcasecmp(choices[i]->choice, "Custom") && - (coption = ppdFindCustomOption(ppd, - choices[i]->option->keyword)) - != NULL) - { - bufsize += 23 + strlen(choices[i]->option->keyword) + 6; - /* %%BeginFeature: *Customkeyword True\n */ - - - for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params); - cparam; - cparam = (ppd_cparam_t *)cupsArrayNext(coption->params)) - { - switch (cparam->type) - { - case PPD_CUSTOM_CURVE : - case PPD_CUSTOM_INVCURVE : - case PPD_CUSTOM_POINTS : - case PPD_CUSTOM_REAL : - case PPD_CUSTOM_INT : - bufsize += 10; - break; - - case PPD_CUSTOM_PASSCODE : - case PPD_CUSTOM_PASSWORD : - case PPD_CUSTOM_STRING : - bufsize += 3; - if (cparam->current.custom_string) - bufsize += 4 * strlen(cparam->current.custom_string); - break; - } - } - } - else - bufsize += 17 + strlen(choices[i]->option->keyword) + 1 + - strlen(choices[i]->choice) + 1; - /* %%BeginFeature: *keyword choice\n */ - - bufsize += 13; /* %%EndFeature\n */ - bufsize += 22; /* } stopped cleartomark\n */ - } - - if (choices[i]->code) - bufsize += strlen(choices[i]->code) + 1; - else - bufsize += strlen(ppd_custom_code); - } - - /* - * Allocate memory... - */ - - DEBUG_printf(("2ppdEmitString: Allocating %d bytes for string...", - (int)bufsize)); - - if ((buffer = calloc(1, bufsize)) == NULL) - { - free(choices); - return (NULL); - } - - bufend = buffer + bufsize - 1; - loc = localeconv(); - - /* - * Copy the option code to the buffer... - */ - - for (i = 0, bufptr = buffer; i < count; i ++, bufptr += strlen(bufptr)) - if (section == PPD_ORDER_JCL) - { - if (!_cups_strcasecmp(choices[i]->choice, "Custom") && - choices[i]->code && - (coption = ppdFindCustomOption(ppd, choices[i]->option->keyword)) - != NULL) - { - /* - * Handle substitutions in custom JCL options... - */ - - char *cptr; /* Pointer into code */ - int pnum; /* Parameter number */ - - - for (cptr = choices[i]->code; *cptr && bufptr < bufend;) - { - if (*cptr == '\\') - { - cptr ++; - - if (isdigit(*cptr & 255)) - { - /* - * Substitute parameter... - */ - - pnum = *cptr++ - '0'; - while (isdigit(*cptr & 255)) - pnum = pnum * 10 + *cptr++ - '0'; - - for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params); - cparam; - cparam = (ppd_cparam_t *)cupsArrayNext(coption->params)) - if (cparam->order == pnum) - break; - - if (cparam) - { - switch (cparam->type) - { - case PPD_CUSTOM_CURVE : - case PPD_CUSTOM_INVCURVE : - case PPD_CUSTOM_POINTS : - case PPD_CUSTOM_REAL : - bufptr = _cupsStrFormatd(bufptr, bufend, - cparam->current.custom_real, - loc); - break; - - case PPD_CUSTOM_INT : - snprintf(bufptr, bufend - bufptr, "%d", - cparam->current.custom_int); - bufptr += strlen(bufptr); - break; - - case PPD_CUSTOM_PASSCODE : - case PPD_CUSTOM_PASSWORD : - case PPD_CUSTOM_STRING : - if (cparam->current.custom_string) - { - strlcpy(bufptr, cparam->current.custom_string, - bufend - bufptr); - bufptr += strlen(bufptr); - } - break; - } - } - } - else if (*cptr) - *bufptr++ = *cptr++; - } - else - *bufptr++ = *cptr++; - } - } - else - { - /* - * Otherwise just copy the option code directly... - */ - - strlcpy(bufptr, choices[i]->code, bufend - bufptr + 1); - bufptr += strlen(bufptr); - } - } - else if (section != PPD_ORDER_EXIT) - { - /* - * Add wrapper commands to prevent printer errors for unsupported - * options... - */ - - strlcpy(bufptr, "[{\n", bufend - bufptr + 1); - bufptr += 3; - - /* - * Send DSC comments with option... - */ - - DEBUG_printf(("2ppdEmitString: Adding code for %s=%s...", - choices[i]->option->keyword, choices[i]->choice)); - - if ((!_cups_strcasecmp(choices[i]->option->keyword, "PageSize") || - !_cups_strcasecmp(choices[i]->option->keyword, "PageRegion")) && - !_cups_strcasecmp(choices[i]->choice, "Custom")) - { - /* - * Variable size; write out standard size options, using the - * parameter positions defined in the PPD file... - */ - - ppd_attr_t *attr; /* PPD attribute */ - int pos, /* Position of custom value */ - orientation; /* Orientation to use */ - float values[5]; /* Values for custom command */ - - - strlcpy(bufptr, "%%BeginFeature: *CustomPageSize True\n", - bufend - bufptr + 1); - bufptr += 37; - - size = ppdPageSize(ppd, "Custom"); - - memset(values, 0, sizeof(values)); - - if ((attr = ppdFindAttr(ppd, "ParamCustomPageSize", "Width")) != NULL) - { - pos = atoi(attr->value) - 1; - - if (pos < 0 || pos > 4) - pos = 0; - } - else - pos = 0; - - values[pos] = size->width; - - if ((attr = ppdFindAttr(ppd, "ParamCustomPageSize", "Height")) != NULL) - { - pos = atoi(attr->value) - 1; - - if (pos < 0 || pos > 4) - pos = 1; - } - else - pos = 1; - - values[pos] = size->length; - - /* - * According to the Adobe PPD specification, an orientation of 1 - * will produce a print that comes out upside-down with the X - * axis perpendicular to the direction of feed, which is exactly - * what we want to be consistent with non-PS printers. - * - * We could also use an orientation of 3 to produce output that - * comes out rightside-up (this is the default for many large format - * printer PPDs), however for consistency we will stick with the - * value 1. - * - * If we wanted to get fancy, we could use orientations of 0 or - * 2 and swap the width and length, however we don't want to get - * fancy, we just want it to work consistently. - * - * The orientation value is range limited by the Orientation - * parameter definition, so certain non-PS printer drivers that - * only support an Orientation of 0 will get the value 0 as - * expected. - */ - - orientation = 1; - - if ((attr = ppdFindAttr(ppd, "ParamCustomPageSize", - "Orientation")) != NULL) - { - int min_orient, max_orient; /* Minimum and maximum orientations */ - - - if (sscanf(attr->value, "%d%*s%d%d", &pos, &min_orient, - &max_orient) != 3) - pos = 4; - else - { - pos --; - - if (pos < 0 || pos > 4) - pos = 4; - - if (orientation > max_orient) - orientation = max_orient; - else if (orientation < min_orient) - orientation = min_orient; - } - } - else - pos = 4; - - values[pos] = (float)orientation; - - for (pos = 0; pos < 5; pos ++) - { - bufptr = _cupsStrFormatd(bufptr, bufend, values[pos], loc); - *bufptr++ = '\n'; - } - - if (!choices[i]->code) - { - /* - * This can happen with certain buggy PPD files that don't include - * a CustomPageSize command sequence... We just use a generic - * Level 2 command sequence... - */ - - strlcpy(bufptr, ppd_custom_code, bufend - bufptr + 1); - bufptr += strlen(bufptr); - } - } - else if (!_cups_strcasecmp(choices[i]->choice, "Custom") && - (coption = ppdFindCustomOption(ppd, choices[i]->option->keyword)) - != NULL) - { - /* - * Custom option... - */ - - const char *s; /* Pointer into string value */ - cups_array_t *params; /* Parameters in the correct output order */ - - - params = cupsArrayNew((cups_array_func_t)ppd_compare_cparams, NULL); - - for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params); - cparam; - cparam = (ppd_cparam_t *)cupsArrayNext(coption->params)) - cupsArrayAdd(params, cparam); - - snprintf(bufptr, bufend - bufptr + 1, - "%%%%BeginFeature: *Custom%s True\n", coption->keyword); - bufptr += strlen(bufptr); - - for (cparam = (ppd_cparam_t *)cupsArrayFirst(params); - cparam; - cparam = (ppd_cparam_t *)cupsArrayNext(params)) - { - switch (cparam->type) - { - case PPD_CUSTOM_CURVE : - case PPD_CUSTOM_INVCURVE : - case PPD_CUSTOM_POINTS : - case PPD_CUSTOM_REAL : - bufptr = _cupsStrFormatd(bufptr, bufend, - cparam->current.custom_real, loc); - *bufptr++ = '\n'; - break; - - case PPD_CUSTOM_INT : - snprintf(bufptr, bufend - bufptr + 1, "%d\n", - cparam->current.custom_int); - bufptr += strlen(bufptr); - break; - - case PPD_CUSTOM_PASSCODE : - case PPD_CUSTOM_PASSWORD : - case PPD_CUSTOM_STRING : - *bufptr++ = '('; - - if (cparam->current.custom_string) - { - for (s = cparam->current.custom_string; *s; s ++) - { - if (*s < ' ' || *s == '(' || *s == ')' || *s >= 127) - { - snprintf(bufptr, bufend - bufptr + 1, "\\%03o", *s & 255); - bufptr += strlen(bufptr); - } - else - *bufptr++ = *s; - } - } - - *bufptr++ = ')'; - *bufptr++ = '\n'; - break; - } - } - - cupsArrayDelete(params); - } - else - { - snprintf(bufptr, bufend - bufptr + 1, "%%%%BeginFeature: *%s %s\n", - choices[i]->option->keyword, choices[i]->choice); - bufptr += strlen(bufptr); - } - - if (choices[i]->code && choices[i]->code[0]) - { - j = (int)strlen(choices[i]->code); - memcpy(bufptr, choices[i]->code, j); - bufptr += j; - - if (choices[i]->code[j - 1] != '\n') - *bufptr++ = '\n'; - } - - strlcpy(bufptr, "%%EndFeature\n" - "} stopped cleartomark\n", bufend - bufptr + 1); - bufptr += strlen(bufptr); - - DEBUG_printf(("2ppdEmitString: Offset in string is %d...", - (int)(bufptr - buffer))); - } - else - { - strlcpy(bufptr, choices[i]->code, bufend - bufptr + 1); - bufptr += strlen(bufptr); - } - - /* - * Nul-terminate, free, and return... - */ - - *bufptr = '\0'; - - free(choices); - - return (buffer); -} - - -/* - * 'ppd_compare_cparams()' - Compare the order of two custom parameters. - */ - -static int /* O - Result of comparison */ -ppd_compare_cparams(ppd_cparam_t *a, /* I - First parameter */ - ppd_cparam_t *b) /* I - Second parameter */ -{ - return (a->order - b->order); -} - - -/* - * 'ppd_handle_media()' - Handle media selection... - */ - -static void -ppd_handle_media(ppd_file_t *ppd) /* I - PPD file */ -{ - ppd_choice_t *manual_feed, /* ManualFeed choice, if any */ - *input_slot; /* InputSlot choice, if any */ - ppd_size_t *size; /* Current media size */ - ppd_attr_t *rpr; /* RequiresPageRegion value */ - - - /* - * This function determines what page size code to use, if any, for the - * current media size, InputSlot, and ManualFeed selections. - * - * We use the PageSize code if: - * - * 1. A custom media size is selected. - * 2. ManualFeed and InputSlot are not selected (or do not exist). - * 3. ManualFeed is selected but is False and InputSlot is not selected or - * the selection has no code - the latter check done to support "auto" or - * "printer default" InputSlot options. - * - * We use the PageRegion code if: - * - * 4. RequiresPageRegion does not exist and the PPD contains cupsFilter - * keywords, indicating this is a CUPS-based driver. - * 5. RequiresPageRegion exists for the selected InputSlot (or "All" for any - * InputSlot or ManualFeed selection) and is True. - * - * If none of the 5 conditions are true, no page size code is used and we - * unmark any existing PageSize or PageRegion choices. - */ - - if ((size = ppdPageSize(ppd, NULL)) == NULL) - return; - - manual_feed = ppdFindMarkedChoice(ppd, "ManualFeed"); - input_slot = ppdFindMarkedChoice(ppd, "InputSlot"); - - if (input_slot != NULL) - rpr = ppdFindAttr(ppd, "RequiresPageRegion", input_slot->choice); - else - rpr = NULL; - - if (!rpr) - rpr = ppdFindAttr(ppd, "RequiresPageRegion", "All"); - - if (!_cups_strcasecmp(size->name, "Custom") || - (!manual_feed && !input_slot) || - (manual_feed && !_cups_strcasecmp(manual_feed->choice, "False") && - (!input_slot || (input_slot->code && !input_slot->code[0]))) || - (!rpr && ppd->num_filters > 0)) - { - /* - * Use PageSize code... - */ - - ppdMarkOption(ppd, "PageSize", size->name); - } - else if (rpr && rpr->value && !_cups_strcasecmp(rpr->value, "True")) - { - /* - * Use PageRegion code... - */ - - ppdMarkOption(ppd, "PageRegion", size->name); - } - else - { - /* - * Do not use PageSize or PageRegion code... - */ - - ppd_choice_t *page; /* PageSize/Region choice, if any */ - - if ((page = ppdFindMarkedChoice(ppd, "PageSize")) != NULL) - { - /* - * Unmark PageSize... - */ - - page->marked = 0; - cupsArrayRemove(ppd->marked, page); - } - - if ((page = ppdFindMarkedChoice(ppd, "PageRegion")) != NULL) - { - /* - * Unmark PageRegion... - */ - - page->marked = 0; - cupsArrayRemove(ppd->marked, page); - } - } -} - - -/* - * End of "$Id: emit.c 7863 2008-08-26 03:39:59Z mike $". - */ diff --git a/cups/encode.c b/cups/encode.c index 94695d0..2469406 100644 --- a/cups/encode.c +++ b/cups/encode.c @@ -1,16 +1,11 @@ /* * Option encoding routines for CUPS. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -18,6 +13,7 @@ */ #include "cups-private.h" +#include "debug-internal.h" /* @@ -134,6 +130,9 @@ static const _ipp_option_t ipp_options[] = cups_schemes }, { 1, "finishings", IPP_TAG_ENUM, IPP_TAG_JOB, IPP_TAG_DOCUMENT }, + { 1, "finishings-col", IPP_TAG_BEGIN_COLLECTION, IPP_TAG_JOB, + IPP_TAG_DOCUMENT }, + { 1, "finishings-col-default", IPP_TAG_BEGIN_COLLECTION, IPP_TAG_PRINTER }, { 1, "finishings-default", IPP_TAG_ENUM, IPP_TAG_PRINTER }, { 0, "fit-to-page", IPP_TAG_BOOLEAN, IPP_TAG_JOB, IPP_TAG_DOCUMENT }, @@ -147,6 +146,7 @@ static const _ipp_option_t ipp_options[] = { 1, "include-schemes", IPP_TAG_NAME, IPP_TAG_OPERATION, IPP_TAG_ZERO, cups_schemes }, + { 0, "ipp-attribute-fidelity", IPP_TAG_BOOLEAN, IPP_TAG_OPERATION }, { 0, "job-account-id", IPP_TAG_NAME, IPP_TAG_JOB }, { 0, "job-account-id-default",IPP_TAG_NAME, IPP_TAG_PRINTER }, { 0, "job-accounting-user-id", IPP_TAG_NAME, IPP_TAG_JOB }, @@ -155,15 +155,20 @@ static const _ipp_option_t ipp_options[] = { 0, "job-cancel-after", IPP_TAG_INTEGER, IPP_TAG_JOB }, { 0, "job-cancel-after-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { 0, "job-hold-until", IPP_TAG_KEYWORD, IPP_TAG_JOB }, + { 0, "job-hold-until-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, { 0, "job-id", IPP_TAG_INTEGER, IPP_TAG_ZERO }, /* never send as option */ - { 0, "job-impressions", IPP_TAG_INTEGER, IPP_TAG_ZERO }, /* never send as option */ + { 0, "job-impressions", IPP_TAG_INTEGER, IPP_TAG_OPERATION }, { 0, "job-impressions-completed", IPP_TAG_INTEGER, IPP_TAG_ZERO }, /* never send as option */ { 0, "job-k-limit", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, - { 0, "job-k-octets", IPP_TAG_INTEGER, IPP_TAG_ZERO }, /* never send as option */ + { 0, "job-k-octets", IPP_TAG_INTEGER, IPP_TAG_OPERATION }, { 0, "job-k-octets-completed",IPP_TAG_INTEGER, IPP_TAG_ZERO }, /* never send as option */ - { 0, "job-media-sheets", IPP_TAG_INTEGER, IPP_TAG_ZERO }, /* never send as option */ + { 0, "job-media-sheets", IPP_TAG_INTEGER, IPP_TAG_OPERATION }, { 0, "job-media-sheets-completed", IPP_TAG_INTEGER, IPP_TAG_ZERO }, /* never send as option */ + { 0, "job-name", IPP_TAG_NAME, IPP_TAG_OPERATION, + IPP_TAG_JOB }, { 0, "job-page-limit", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "job-pages", IPP_TAG_INTEGER, IPP_TAG_OPERATION }, + { 0, "job-pages-completed", IPP_TAG_INTEGER, IPP_TAG_ZERO }, /* never send as option */ { 0, "job-password", IPP_TAG_STRING, IPP_TAG_OPERATION, IPP_TAG_ZERO, ipp_job_creation }, @@ -171,6 +176,7 @@ static const _ipp_option_t ipp_options[] = IPP_TAG_ZERO, ipp_job_creation }, { 0, "job-priority", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { 0, "job-priority-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { 0, "job-quota-period", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { 1, "job-sheets", IPP_TAG_NAME, IPP_TAG_JOB }, { 1, "job-sheets-default", IPP_TAG_NAME, IPP_TAG_PRINTER }, @@ -189,6 +195,8 @@ static const _ipp_option_t ipp_options[] = { 1, "marker-types", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, { 1, "media", IPP_TAG_KEYWORD, IPP_TAG_JOB, IPP_TAG_DOCUMENT }, + { 0, "media-bottom-margin", IPP_TAG_INTEGER, IPP_TAG_JOB, + IPP_TAG_DOCUMENT }, { 0, "media-col", IPP_TAG_BEGIN_COLLECTION, IPP_TAG_JOB, IPP_TAG_DOCUMENT }, { 0, "media-col-default", IPP_TAG_BEGIN_COLLECTION, IPP_TAG_PRINTER }, @@ -197,12 +205,25 @@ static const _ipp_option_t ipp_options[] = { 1, "media-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, { 0, "media-key", IPP_TAG_KEYWORD, IPP_TAG_JOB, IPP_TAG_DOCUMENT }, + { 0, "media-left-margin", IPP_TAG_INTEGER, IPP_TAG_JOB, + IPP_TAG_DOCUMENT }, + { 0, "media-right-margin", IPP_TAG_INTEGER, IPP_TAG_JOB, + IPP_TAG_DOCUMENT }, { 0, "media-size", IPP_TAG_BEGIN_COLLECTION, IPP_TAG_JOB, IPP_TAG_DOCUMENT }, + { 0, "media-size-name", IPP_TAG_KEYWORD, IPP_TAG_JOB, + IPP_TAG_DOCUMENT }, + { 0, "media-source", IPP_TAG_KEYWORD, IPP_TAG_JOB, + IPP_TAG_DOCUMENT }, + { 0, "media-top-margin", IPP_TAG_INTEGER, IPP_TAG_JOB, + IPP_TAG_DOCUMENT }, { 0, "media-type", IPP_TAG_KEYWORD, IPP_TAG_JOB, IPP_TAG_DOCUMENT }, { 0, "mirror", IPP_TAG_BOOLEAN, IPP_TAG_JOB }, { 0, "mirror-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, + { 0, "multiple-document-handling", IPP_TAG_KEYWORD, IPP_TAG_JOB, + IPP_TAG_DOCUMENT }, + { 0, "multiple-document-handling-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, { 0, "natural-scaling", IPP_TAG_INTEGER, IPP_TAG_JOB }, { 0, "natural-scaling-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { 0, "notify-charset", IPP_TAG_CHARSET, IPP_TAG_SUBSCRIPTION }, @@ -218,18 +239,26 @@ static const _ipp_option_t ipp_options[] = { 0, "number-up", IPP_TAG_INTEGER, IPP_TAG_JOB, IPP_TAG_DOCUMENT }, { 0, "number-up-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "number-up-layout", IPP_TAG_KEYWORD, IPP_TAG_JOB, + IPP_TAG_DOCUMENT }, + { 0, "number-up-layout-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, { 0, "orientation-requested", IPP_TAG_ENUM, IPP_TAG_JOB, IPP_TAG_DOCUMENT }, { 0, "orientation-requested-default", IPP_TAG_ENUM, IPP_TAG_PRINTER }, + { 0, "output-bin", IPP_TAG_KEYWORD, IPP_TAG_JOB, + IPP_TAG_DOCUMENT }, + { 0, "output-bin-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, { 1, "overrides", IPP_TAG_BEGIN_COLLECTION, IPP_TAG_JOB, IPP_TAG_DOCUMENT }, { 0, "page-bottom", IPP_TAG_INTEGER, IPP_TAG_JOB }, { 0, "page-bottom-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "page-delivery", IPP_TAG_KEYWORD, IPP_TAG_JOB, + IPP_TAG_DOCUMENT }, + { 0, "page-delivery-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, { 0, "page-left", IPP_TAG_INTEGER, IPP_TAG_JOB }, { 0, "page-left-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { 1, "page-ranges", IPP_TAG_RANGE, IPP_TAG_JOB, IPP_TAG_DOCUMENT }, - { 1, "page-ranges-default", IPP_TAG_RANGE, IPP_TAG_PRINTER }, { 0, "page-right", IPP_TAG_INTEGER, IPP_TAG_JOB }, { 0, "page-right-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { 0, "page-top", IPP_TAG_INTEGER, IPP_TAG_JOB }, @@ -270,13 +299,32 @@ static const _ipp_option_t ipp_options[] = { 0, "ppi-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { 0, "prettyprint", IPP_TAG_BOOLEAN, IPP_TAG_JOB }, { 0, "prettyprint-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, + { 0, "print-color-mode", IPP_TAG_KEYWORD, IPP_TAG_JOB, + IPP_TAG_DOCUMENT }, + { 0, "print-color-mode-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, + { 0, "print-content-optimize", IPP_TAG_KEYWORD, IPP_TAG_JOB, + IPP_TAG_DOCUMENT }, + { 0, "print-content-optimize-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, { 0, "print-quality", IPP_TAG_ENUM, IPP_TAG_JOB, IPP_TAG_DOCUMENT }, { 0, "print-quality-default", IPP_TAG_ENUM, IPP_TAG_PRINTER }, + { 0, "print-rendering-intent", IPP_TAG_KEYWORD, IPP_TAG_JOB, + IPP_TAG_DOCUMENT }, + { 0, "print-rendering-intent-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, + { 0, "print-scaling", IPP_TAG_KEYWORD, IPP_TAG_JOB, + IPP_TAG_DOCUMENT }, + { 0, "print-scaling-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, + { 1, "printer-alert", IPP_TAG_STRING, IPP_TAG_PRINTER }, + { 1, "printer-alert-description", IPP_TAG_TEXT, IPP_TAG_PRINTER }, { 1, "printer-commands", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, { 0, "printer-error-policy", IPP_TAG_NAME, IPP_TAG_PRINTER }, + { 1, "printer-finisher", IPP_TAG_STRING, IPP_TAG_PRINTER }, + { 1, "printer-finisher-description", IPP_TAG_TEXT, IPP_TAG_PRINTER }, + { 1, "printer-finisher-supplies", IPP_TAG_STRING, IPP_TAG_PRINTER }, + { 1, "printer-finisher-supplies-description", IPP_TAG_TEXT, IPP_TAG_PRINTER }, { 0, "printer-geo-location", IPP_TAG_URI, IPP_TAG_PRINTER }, { 0, "printer-info", IPP_TAG_TEXT, IPP_TAG_PRINTER }, + { 1, "printer-input-tray", IPP_TAG_STRING, IPP_TAG_PRINTER }, { 0, "printer-is-accepting-jobs", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, { 0, "printer-is-shared", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, { 0, "printer-is-temporary", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, @@ -284,11 +332,15 @@ static const _ipp_option_t ipp_options[] = { 0, "printer-make-and-model", IPP_TAG_TEXT, IPP_TAG_PRINTER }, { 0, "printer-more-info", IPP_TAG_URI, IPP_TAG_PRINTER }, { 0, "printer-op-policy", IPP_TAG_NAME, IPP_TAG_PRINTER }, + { 1, "printer-output-tray", IPP_TAG_STRING, IPP_TAG_PRINTER }, { 0, "printer-resolution", IPP_TAG_RESOLUTION, IPP_TAG_JOB, IPP_TAG_DOCUMENT }, + { 0, "printer-resolution-default", IPP_TAG_RESOLUTION, IPP_TAG_PRINTER }, { 0, "printer-state", IPP_TAG_ENUM, IPP_TAG_PRINTER }, { 0, "printer-state-change-time", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, { 1, "printer-state-reasons", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, + { 1, "printer-supply", IPP_TAG_STRING, IPP_TAG_PRINTER }, + { 1, "printer-supply-description", IPP_TAG_TEXT, IPP_TAG_PRINTER }, { 0, "printer-type", IPP_TAG_ENUM, IPP_TAG_PRINTER }, { 0, "printer-uri", IPP_TAG_URI, IPP_TAG_OPERATION }, { 1, "printer-uri-supported", IPP_TAG_URI, IPP_TAG_PRINTER }, @@ -325,6 +377,315 @@ static const _ipp_option_t ipp_options[] = static int compare_ipp_options(_ipp_option_t *a, _ipp_option_t *b); +/* + * '_cupsEncodeOption()' - Encode a single option as an IPP attribute. + */ + +ipp_attribute_t * /* O - New attribute or @code NULL@ on error */ +_cupsEncodeOption( + ipp_t *ipp, /* I - IPP request/response/collection */ + ipp_tag_t group_tag, /* I - Group tag */ + _ipp_option_t *map, /* I - Option mapping, if any */ + const char *name, /* I - Attribute name */ + const char *value) /* I - Value */ +{ + int i, /* Looping var */ + count; /* Number of values */ + char *s, /* Pointer into option value */ + *val, /* Pointer to option value */ + *copy, /* Copy of option value */ + *sep, /* Option separator */ + quote; /* Quote character */ + ipp_attribute_t *attr; /* IPP attribute */ + ipp_tag_t value_tag; /* IPP value tag */ + ipp_t *collection; /* Collection value */ + int num_cols; /* Number of collection values */ + cups_option_t *cols; /* Collection values */ + + + DEBUG_printf(("_cupsEncodeOption(ipp=%p(%s), group=%s, map=%p, name=\"%s\", value=\"%s\")", (void *)ipp, ipp ? ippOpString(ippGetOperation(ipp)) : "", ippTagString(group_tag), (void *)map, name, value)); + + /* + * Figure out the attribute syntax for encoding... + */ + + if (!map) + map = _ippFindOption(name); + + if (map) + value_tag = map->value_tag; + else if (!_cups_strcasecmp(value, "true") || !_cups_strcasecmp(value, "false")) + value_tag = IPP_TAG_BOOLEAN; + else if (value[0] == '{') + value_tag = IPP_TAG_BEGIN_COLLECTION; + else + value_tag = IPP_TAG_NAME; + + /* + * Count the number of values... + */ + + if (map && map->multivalue) + { + for (count = 1, sep = (char *)value, quote = 0; *sep; sep ++) + { + if (*sep == quote) + quote = 0; + else if (!quote && (*sep == '\'' || *sep == '\"')) + { + /* + * Skip quoted option value... + */ + + quote = *sep; + } + else if (*sep == ',' && !quote) + count ++; + else if (*sep == '\\' && sep[1]) + sep ++; + } + } + else + count = 1; + + DEBUG_printf(("2_cupsEncodeOption: value_tag=%s, count=%d", ippTagString(value_tag), count)); + + /* + * Allocate memory for the attribute values... + */ + + if ((attr = ippAddStrings(ipp, group_tag, value_tag, name, count, NULL, NULL)) == NULL) + { + /* + * Ran out of memory! + */ + + DEBUG_puts("1_cupsEncodeOption: Ran out of memory for attributes."); + return (NULL); + } + + if (count > 1) + { + /* + * Make a copy of the value we can fiddle with... + */ + + if ((copy = strdup(value)) == NULL) + { + /* + * Ran out of memory! + */ + + DEBUG_puts("1_cupsEncodeOption: Ran out of memory for value copy."); + ippDeleteAttribute(ipp, attr); + return (NULL); + } + + val = copy; + } + else + { + /* + * Since we have a single value, use the value directly... + */ + + val = (char *)value; + copy = NULL; + } + + /* + * Scan the value string for values... + */ + + for (i = 0, sep = val; i < count; val = sep, i ++) + { + /* + * Find the end of this value and mark it if needed... + */ + + if (count > 1) + { + for (quote = 0; *sep; sep ++) + { + if (*sep == quote) + { + /* + * Finish quoted value... + */ + + quote = 0; + } + else if (!quote && (*sep == '\'' || *sep == '\"')) + { + /* + * Handle quoted option value... + */ + + quote = *sep; + } + else if (*sep == ',' && count > 1) + break; + else if (*sep == '\\' && sep[1]) + { + /* + * Skip quoted character... + */ + + memmove(sep, sep + 1, strlen(sep)); + } + } + + if (*sep == ',') + *sep++ = '\0'; + } + + /* + * Copy the option value(s) over as needed by the type... + */ + + switch (attr->value_tag) + { + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + /* + * Integer/enumeration value... + */ + + ippSetInteger(ipp, &attr, i, (int)strtol(val, &s, 10)); + break; + + case IPP_TAG_BOOLEAN : + if (!_cups_strcasecmp(val, "true") || !_cups_strcasecmp(val, "on") || !_cups_strcasecmp(val, "yes")) + { + /* + * Boolean value - true... + */ + + ippSetBoolean(ipp, &attr, i, 1); + } + else + { + /* + * Boolean value - false... + */ + + ippSetBoolean(ipp, &attr, i, 0); + } + break; + + case IPP_TAG_RANGE : + { + /* + * Range... + */ + + int lower, upper; /* Lower and upper ranges... */ + + if (*val == '-') + { + lower = 1; + s = val; + } + else + lower = (int)strtol(val, &s, 10); + + if (*s == '-') + { + if (s[1]) + upper = (int)strtol(s + 1, NULL, 10); + else + upper = 2147483647; + } + else + upper = lower; + + ippSetRange(ipp, &attr, i, lower, upper); + } + break; + + case IPP_TAG_RESOLUTION : + { + /* + * Resolution... + */ + int xres, yres; /* Resolution values */ + ipp_res_t units; /* Resolution units */ + + xres = (int)strtol(val, &s, 10); + + if (*s == 'x') + yres = (int)strtol(s + 1, &s, 10); + else + yres = xres; + + if (!_cups_strcasecmp(s, "dpc") || !_cups_strcasecmp(s, "dpcm")) + units = IPP_RES_PER_CM; + else + units = IPP_RES_PER_INCH; + + ippSetResolution(ipp, &attr, i, units, xres, yres); + } + break; + + case IPP_TAG_STRING : + /* + * octetString + */ + + ippSetOctetString(ipp, &attr, i, val, (int)strlen(val)); + break; + + case IPP_TAG_BEGIN_COLLECTION : + /* + * Collection value + */ + + num_cols = cupsParseOptions(val, 0, &cols); + if ((collection = ippNew()) == NULL) + { + cupsFreeOptions(num_cols, cols); + + if (copy) + free(copy); + + ippDeleteAttribute(ipp, attr); + return (NULL); + } + + ippSetCollection(ipp, &attr, i, collection); + cupsEncodeOptions2(collection, num_cols, cols, IPP_TAG_JOB); + cupsFreeOptions(num_cols, cols); + break; + + default : + ippSetString(ipp, &attr, i, val); + break; + } + } + + if (copy) + free(copy); + + return (attr); +} + + +/* + * 'cupsEncodeOption()' - Encode a single option into an IPP attribute. + * + * @since CUPS 2.3/macOS 10.14@ + */ + +ipp_attribute_t * /* O - New attribute or @code NULL@ on error */ +cupsEncodeOption(ipp_t *ipp, /* I - IPP request/response */ + ipp_tag_t group_tag, /* I - Attribute group */ + const char *name, /* I - Option name */ + const char *value) /* I - Option string value */ +{ + return (_cupsEncodeOption(ipp, group_tag, _ippFindOption(name), name, value)); +} + + /* * 'cupsEncodeOptions()' - Encode printer options into IPP attributes. * @@ -334,7 +695,7 @@ static int compare_ipp_options(_ipp_option_t *a, _ipp_option_t *b); */ void -cupsEncodeOptions(ipp_t *ipp, /* I - Request to add to */ +cupsEncodeOptions(ipp_t *ipp, /* I - IPP request/response */ int num_options, /* I - Number of options */ cups_option_t *options) /* I - Options */ { @@ -362,24 +723,14 @@ cupsEncodeOptions(ipp_t *ipp, /* I - Request to add to */ void cupsEncodeOptions2( - ipp_t *ipp, /* I - Request to add to */ + ipp_t *ipp, /* I - IPP request/response */ int num_options, /* I - Number of options */ cups_option_t *options, /* I - Options */ ipp_tag_t group_tag) /* I - Group to encode */ { - int i, j; /* Looping vars */ - int count; /* Number of values */ - char *s, /* Pointer into option value */ - *val, /* Pointer to option value */ - *copy, /* Copy of option value */ - *sep, /* Option separator */ - quote; /* Quote character */ - ipp_attribute_t *attr; /* IPP attribute */ - ipp_tag_t value_tag; /* IPP value tag */ + int i; /* Looping var */ + char *val; /* Pointer to option value */ cups_option_t *option; /* Current option */ - ipp_t *collection; /* Collection value */ - int num_cols; /* Number of collection values */ - cups_option_t *cols; /* Collection values */ ipp_op_t op; /* Operation for this request */ const ipp_op_t *ops; /* List of allowed operations */ @@ -399,24 +750,18 @@ cupsEncodeOptions2( op = ippGetOperation(ipp); - if (group_tag == IPP_TAG_OPERATION && - (op == IPP_OP_PRINT_JOB || op == IPP_OP_PRINT_URI || - op == IPP_OP_SEND_DOCUMENT || op == IPP_OP_SEND_URI)) + if (group_tag == IPP_TAG_OPERATION && (op == IPP_OP_PRINT_JOB || op == IPP_OP_PRINT_URI || op == IPP_OP_SEND_DOCUMENT || op == IPP_OP_SEND_URI)) { /* * Handle the document format stuff first... */ - if ((val = (char *)cupsGetOption("document-format", num_options, - options)) != NULL) - ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", - NULL, val); + if ((val = (char *)cupsGetOption("document-format", num_options, options)) != NULL) + ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", NULL, val); else if (cupsGetOption("raw", num_options, options)) - ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", - NULL, "application/vnd.cups-raw"); + ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", NULL, "application/vnd.cups-raw"); else - ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", - NULL, "application/octet-stream"); + ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", NULL, "application/octet-stream"); } /* @@ -427,14 +772,11 @@ cupsEncodeOptions2( { _ipp_option_t *match; /* Matching attribute */ - /* * Skip document format options that are handled above... */ - if (!_cups_strcasecmp(option->name, "raw") || - !_cups_strcasecmp(option->name, "document-format") || - !option->name[0]) + if (!_cups_strcasecmp(option->name, "raw") || !_cups_strcasecmp(option->name, "document-format") || !option->name[0]) continue; /* @@ -446,8 +788,6 @@ cupsEncodeOptions2( if (match->group_tag != group_tag && match->alt_group_tag != group_tag) continue; - value_tag = match->value_tag; - if (match->operations) ops = match->operations; else if (group_tag == IPP_TAG_JOB) @@ -468,12 +808,9 @@ cupsEncodeOptions2( { int namelen; /* Length of name */ - namelen = (int)strlen(option->name); - if (namelen < 10 || - (strcmp(option->name + namelen - 8, "-default") && - strcmp(option->name + namelen - 10, "-supported"))) + if (namelen < 10 || (strcmp(option->name + namelen - 8, "-default") && strcmp(option->name + namelen - 10, "-supported"))) { if (group_tag != IPP_TAG_JOB && group_tag != IPP_TAG_DOCUMENT) { @@ -493,12 +830,6 @@ cupsEncodeOptions2( ops = ipp_doc_creation; else ops = ipp_set_printer; - - if (!_cups_strcasecmp(option->value, "true") || - !_cups_strcasecmp(option->value, "false")) - value_tag = IPP_TAG_BOOLEAN; - else - value_tag = IPP_TAG_NAME; } /* @@ -517,277 +848,7 @@ cupsEncodeOptions2( continue; } - /* - * Count the number of values... - */ - - if (match && match->multivalue) - { - for (count = 1, sep = option->value, quote = 0; *sep; sep ++) - { - if (*sep == quote) - quote = 0; - else if (!quote && (*sep == '\'' || *sep == '\"')) - { - /* - * Skip quoted option value... - */ - - quote = *sep++; - } - else if (*sep == ',' && !quote) - count ++; - else if (*sep == '\\' && sep[1]) - sep += 2; - } - } - else - count = 1; - - DEBUG_printf(("2cupsEncodeOptions2: option=\"%s\", value=\"%s\", count=%d", option->name, option->value, count)); - - /* - * Allocate memory for the attribute values... - */ - - if ((attr = ippAddStrings(ipp, group_tag, value_tag, option->name, count, - NULL, NULL)) == NULL) - { - /* - * Ran out of memory! - */ - - DEBUG_puts("1cupsEncodeOptions2: Ran out of memory for attributes!"); - return; - } - - if (count > 1) - { - /* - * Make a copy of the value we can fiddle with... - */ - - if ((copy = strdup(option->value)) == NULL) - { - /* - * Ran out of memory! - */ - - DEBUG_puts("1cupsEncodeOptions2: Ran out of memory for value copy!"); - ippDeleteAttribute(ipp, attr); - return; - } - - val = copy; - } - else - { - /* - * Since we have a single value, use the value directly... - */ - - val = option->value; - copy = NULL; - } - - /* - * Scan the value string for values... - */ - - for (j = 0, sep = val; j < count; val = sep, j ++) - { - /* - * Find the end of this value and mark it if needed... - */ - - if (count > 1) - { - for (quote = 0; *sep; sep ++) - { - if (*sep == quote) - { - /* - * Finish quoted value... - */ - - quote = 0; - } - else if (!quote && (*sep == '\'' || *sep == '\"')) - { - /* - * Handle quoted option value... - */ - - quote = *sep; - } - else if (*sep == ',' && count > 1) - break; - else if (*sep == '\\' && sep[1]) - { - /* - * Skip quoted character... - */ - - memmove(sep, sep + 1, strlen(sep)); - sep ++; - } - } - - if (*sep == ',') - *sep++ = '\0'; - } - - /* - * Copy the option value(s) over as needed by the type... - */ - - switch (attr->value_tag) - { - case IPP_TAG_INTEGER : - case IPP_TAG_ENUM : - /* - * Integer/enumeration value... - */ - - attr->values[j].integer = (int)strtol(val, &s, 10); - - DEBUG_printf(("2cupsEncodeOptions2: Added integer option value " - "%d...", attr->values[j].integer)); - break; - - case IPP_TAG_BOOLEAN : - if (!_cups_strcasecmp(val, "true") || - !_cups_strcasecmp(val, "on") || - !_cups_strcasecmp(val, "yes")) - { - /* - * Boolean value - true... - */ - - attr->values[j].boolean = 1; - - DEBUG_puts("2cupsEncodeOptions2: Added boolean true value..."); - } - else - { - /* - * Boolean value - false... - */ - - attr->values[j].boolean = 0; - - DEBUG_puts("2cupsEncodeOptions2: Added boolean false value..."); - } - break; - - case IPP_TAG_RANGE : - /* - * Range... - */ - - if (*val == '-') - { - attr->values[j].range.lower = 1; - s = val; - } - else - attr->values[j].range.lower = (int)strtol(val, &s, 10); - - if (*s == '-') - { - if (s[1]) - attr->values[j].range.upper = (int)strtol(s + 1, NULL, 10); - else - attr->values[j].range.upper = 2147483647; - } - else - attr->values[j].range.upper = attr->values[j].range.lower; - - DEBUG_printf(("2cupsEncodeOptions2: Added range option value " - "%d-%d...", attr->values[j].range.lower, - attr->values[j].range.upper)); - break; - - case IPP_TAG_RESOLUTION : - /* - * Resolution... - */ - - attr->values[j].resolution.xres = (int)strtol(val, &s, 10); - - if (*s == 'x') - attr->values[j].resolution.yres = (int)strtol(s + 1, &s, 10); - else - attr->values[j].resolution.yres = attr->values[j].resolution.xres; - - if (!_cups_strcasecmp(s, "dpc") || - !_cups_strcasecmp(s, "dpcm")) - attr->values[j].resolution.units = IPP_RES_PER_CM; - else - attr->values[j].resolution.units = IPP_RES_PER_INCH; - - DEBUG_printf(("2cupsEncodeOptions2: Added resolution option value " - "%s...", val)); - break; - - case IPP_TAG_STRING : - /* - * octet-string - */ - - attr->values[j].unknown.length = (int)strlen(val); - attr->values[j].unknown.data = strdup(val); - - DEBUG_printf(("2cupsEncodeOptions2: Added octet-string value " - "\"%s\"...", (char *)attr->values[j].unknown.data)); - break; - - case IPP_TAG_BEGIN_COLLECTION : - /* - * Collection value - */ - - num_cols = cupsParseOptions(val, 0, &cols); - if ((collection = ippNew()) == NULL) - { - cupsFreeOptions(num_cols, cols); - - if (copy) - free(copy); - - ippDeleteAttribute(ipp, attr); - return; - } - - attr->values[j].collection = collection; - cupsEncodeOptions2(collection, num_cols, cols, IPP_TAG_JOB); - cupsFreeOptions(num_cols, cols); - break; - - default : - if ((attr->values[j].string.text = _cupsStrAlloc(val)) == NULL) - { - /* - * Ran out of memory! - */ - - DEBUG_puts("1cupsEncodeOptions2: Ran out of memory for string!"); - - if (copy) - free(copy); - - ippDeleteAttribute(ipp, attr); - return; - } - - DEBUG_printf(("2cupsEncodeOptions2: Added string value \"%s\"...", - val)); - break; - } - } - - if (copy) - free(copy); + _cupsEncodeOption(ipp, group_tag, match, option->name, option->value); } } diff --git a/cups/file-private.h b/cups/file-private.h index 1f4db79..bb6f213 100644 --- a/cups/file-private.h +++ b/cups/file-private.h @@ -6,16 +6,11 @@ * our own file functions allows us to provide transparent support of * different line endings, gzip'd print files, PPD files, etc. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ #ifndef _CUPS_FILE_PRIVATE_H_ @@ -31,13 +26,10 @@ # include # include -# ifdef HAVE_LIBZ -# include -# endif /* HAVE_LIBZ */ -# ifdef WIN32 +# ifdef _WIN32 # include # include -# endif /* WIN32 */ +# endif /* _WIN32 */ /* @@ -88,43 +80,13 @@ typedef enum /**** _cupsFileCheck file type values ****/ typedef void (*_cups_fc_func_t)(void *context, _cups_fc_result_t result, const char *message); -struct _cups_file_s /**** CUPS file structure... ****/ - -{ - int fd; /* File descriptor */ - char mode, /* Mode ('r' or 'w') */ - compressed, /* Compression used? */ - is_stdio, /* stdin/out/err? */ - eof, /* End of file? */ - buf[4096], /* Buffer */ - *ptr, /* Pointer into buffer */ - *end; /* End of buffer data */ - off_t pos, /* Position in file */ - bufpos; /* File position for start of buffer */ - -#ifdef HAVE_LIBZ - z_stream stream; /* (De)compression stream */ - Bytef cbuf[4096]; /* (De)compression buffer */ - uLong crc; /* (De)compression CRC */ -#endif /* HAVE_LIBZ */ - - char *printf_buffer; /* cupsFilePrintf buffer */ - size_t printf_size; /* Size of cupsFilePrintf buffer */ -}; - - /* * Prototypes... */ -extern _cups_fc_result_t _cupsFileCheck(const char *filename, - _cups_fc_filetype_t filetype, - int dorootchecks, - _cups_fc_func_t cb, - void *context); -extern void _cupsFileCheckFilter(void *context, - _cups_fc_result_t result, - const char *message); +extern _cups_fc_result_t _cupsFileCheck(const char *filename, _cups_fc_filetype_t filetype, int dorootchecks, _cups_fc_func_t cb, void *context) _CUPS_PRIVATE; +extern void _cupsFileCheckFilter(void *context, _cups_fc_result_t result, const char *message) _CUPS_PRIVATE; +extern int _cupsFilePeekAhead(cups_file_t *fp, int ch); # ifdef __cplusplus } diff --git a/cups/file.c b/cups/file.c index 8cdf036..e6e1f5b 100644 --- a/cups/file.c +++ b/cups/file.c @@ -6,16 +6,11 @@ * our own file functions allows us to provide transparent support of * different line endings, gzip'd print files, PPD files, etc. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -23,9 +18,43 @@ */ #include "file-private.h" +#include "debug-internal.h" #include #include +# ifdef HAVE_LIBZ +# include +# endif /* HAVE_LIBZ */ + + +/* + * Internal structures... + */ + +struct _cups_file_s /**** CUPS file structure... ****/ + +{ + int fd; /* File descriptor */ + char mode, /* Mode ('r' or 'w') */ + compressed, /* Compression used? */ + is_stdio, /* stdin/out/err? */ + eof, /* End of file? */ + buf[4096], /* Buffer */ + *ptr, /* Pointer into buffer */ + *end; /* End of buffer data */ + off_t pos, /* Position in file */ + bufpos; /* File position for start of buffer */ + +#ifdef HAVE_LIBZ + z_stream stream; /* (De)compression stream */ + Bytef cbuf[4096]; /* (De)compression buffer */ + uLong crc; /* (De)compression CRC */ +#endif /* HAVE_LIBZ */ + + char *printf_buffer; /* cupsFilePrintf buffer */ + size_t printf_size; /* Size of cupsFilePrintf buffer */ +}; + /* * Local functions... @@ -40,7 +69,7 @@ static ssize_t cups_read(cups_file_t *fp, char *buf, size_t bytes); static ssize_t cups_write(cups_file_t *fp, const char *buf, size_t bytes); -#ifndef WIN32 +#ifndef _WIN32 /* * '_cupsFileCheck()' - Check the permissions of the given filename. */ @@ -306,7 +335,7 @@ _cupsFileCheckFilter( fprintf(stderr, "%s: %s\n", prefix, message); } -#endif /* !WIN32 */ +#endif /* !_WIN32 */ /* @@ -526,22 +555,22 @@ cupsFileFind(const char *filename, /* I - File to find */ while (*path) { -#ifdef WIN32 +#ifdef _WIN32 if (*path == ';' || (*path == ':' && ((bufptr - buffer) > 1 || !isalpha(buffer[0] & 255)))) #else if (*path == ';' || *path == ':') -#endif /* WIN32 */ +#endif /* _WIN32 */ { if (bufptr > buffer && bufptr[-1] != '/' && bufptr < bufend) *bufptr++ = '/'; strlcpy(bufptr, filename, (size_t)(bufend - bufptr)); -#ifdef WIN32 +#ifdef _WIN32 if (!access(buffer, 0)) #else if (!access(buffer, executable ? X_OK : 0)) -#endif /* WIN32 */ +#endif /* _WIN32 */ { DEBUG_printf(("1cupsFileFind: Returning \"%s\"", buffer)); return (buffer); @@ -646,6 +675,12 @@ cupsFileGetChar(cups_file_t *fp) /* I - CUPS file */ return (-1); } + if (fp->eof) + { + DEBUG_puts("5cupsFileGetChar: End-of-file!"); + return (-1); + } + /* * If the input buffer is empty, try to read more data... */ @@ -992,11 +1027,11 @@ cupsFileLock(cups_file_t *fp, /* I - CUPS file */ * Try the lock... */ -#ifdef WIN32 +#ifdef _WIN32 return (_locking(fp->fd, block ? _LK_LOCK : _LK_NBLCK, 0)); #else return (lockf(fp->fd, block ? F_LOCK : F_TLOCK, 0)); -#endif /* WIN32 */ +#endif /* _WIN32 */ } @@ -1084,11 +1119,11 @@ cupsFileOpen(const char *filename, /* I - Name of file */ } if (fd >= 0) -#ifdef WIN32 +#ifdef _WIN32 _chsize(fd, 0); #else ftruncate(fd, 0); -#endif /* WIN32 */ +#endif /* _WIN32 */ break; case 's' : /* Read/write socket */ @@ -1255,14 +1290,26 @@ cupsFileOpenFd(int fd, /* I - File descriptor */ * Don't pass this file to child processes... */ -#ifndef WIN32 +#ifndef _WIN32 fcntl(fp->fd, F_SETFD, fcntl(fp->fd, F_GETFD) | FD_CLOEXEC); -#endif /* !WIN32 */ +#endif /* !_WIN32 */ return (fp); } +/* + * '_cupsFilePeekAhead()' - See if the requested character is buffered up. + */ + +int /* O - 1 if present, 0 otherwise */ +_cupsFilePeekAhead(cups_file_t *fp, /* I - CUPS file */ + int ch) /* I - Character */ +{ + return (fp && fp->ptr && memchr(fp->ptr, ch, (size_t)(fp->end - fp->ptr))); +} + + /* * 'cupsFilePeekChar()' - Peek at the next character from a file. * @@ -1606,6 +1653,12 @@ cupsFileRead(cups_file_t *fp, /* I - CUPS file */ if (bytes == 0) return (0); + if (fp->eof) + { + DEBUG_puts("5cupsFileRead: End-of-file!"); + return (-1); + } + /* * Loop until all bytes are read... */ @@ -2019,11 +2072,11 @@ cupsFileUnlock(cups_file_t *fp) /* I - CUPS file */ * Unlock... */ -#ifdef WIN32 +#ifdef _WIN32 return (_locking(fp->fd, _LK_UNLCK, 0)); #else return (lockf(fp->fd, F_ULOCK, 0)); -#endif /* WIN32 */ +#endif /* _WIN32 */ } @@ -2477,6 +2530,8 @@ cups_fill(cups_file_t *fp) /* I - CUPS file */ * file header... */ + inflateEnd(&fp->stream); + fp->compressed = 0; } else if (status < Z_OK) @@ -2551,9 +2606,9 @@ cups_open(const char *filename, /* I - Filename */ { int fd; /* File descriptor */ struct stat fileinfo; /* File information */ -#ifndef WIN32 +#ifndef _WIN32 struct stat linkinfo; /* Link information */ -#endif /* !WIN32 */ +#endif /* !_WIN32 */ /* @@ -2581,18 +2636,18 @@ cups_open(const char *filename, /* I - Filename */ return (-1); } -#ifdef WIN32 +#ifdef _WIN32 if (fileinfo.st_mode & _S_IFDIR) #else if (S_ISDIR(fileinfo.st_mode)) -#endif /* WIN32 */ +#endif /* _WIN32 */ { close(fd); errno = EISDIR; return (-1); } -#ifndef WIN32 +#ifndef _WIN32 /* * Then use lstat to determine whether the filename is a symlink... */ @@ -2620,7 +2675,7 @@ cups_open(const char *filename, /* I - Filename */ errno = EPERM; return (-1); } -#endif /* !WIN32 */ +#endif /* !_WIN32 */ return (fd); } @@ -2646,7 +2701,7 @@ cups_read(cups_file_t *fp, /* I - CUPS file */ for (;;) { -#ifdef WIN32 +#ifdef _WIN32 if (fp->mode == 's') total = (ssize_t)recv(fp->fd, buf, (unsigned)bytes, 0); else @@ -2656,7 +2711,7 @@ cups_read(cups_file_t *fp, /* I - CUPS file */ total = recv(fp->fd, buf, bytes, 0); else total = read(fp->fd, buf, bytes); -#endif /* WIN32 */ +#endif /* _WIN32 */ DEBUG_printf(("9cups_read: total=" CUPS_LLFMT, CUPS_LLCAST total)); @@ -2703,7 +2758,7 @@ cups_write(cups_file_t *fp, /* I - CUPS file */ total = 0; while (bytes > 0) { -#ifdef WIN32 +#ifdef _WIN32 if (fp->mode == 's') count = (ssize_t)send(fp->fd, buf, (unsigned)bytes, 0); else @@ -2713,7 +2768,7 @@ cups_write(cups_file_t *fp, /* I - CUPS file */ count = send(fp->fd, buf, bytes, 0); else count = write(fp->fd, buf, bytes); -#endif /* WIN32 */ +#endif /* _WIN32 */ DEBUG_printf(("9cups_write: count=" CUPS_LLFMT, CUPS_LLCAST count)); diff --git a/cups/file.h b/cups/file.h index 42abe20..49ca58a 100644 --- a/cups/file.h +++ b/cups/file.h @@ -6,16 +6,11 @@ * our own file functions allows us to provide transparent support of * different line endings, gzip'd print files, PPD files, etc. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ #ifndef _CUPS_FILE_H_ @@ -29,11 +24,11 @@ # include "versioning.h" # include # include -# if defined(WIN32) && !defined(__CUPS_SSIZE_T_DEFINED) +# if defined(_WIN32) && !defined(__CUPS_SSIZE_T_DEFINED) # define __CUPS_SSIZE_T_DEFINED /* Windows does not support the ssize_t type, so map it to off_t... */ typedef off_t ssize_t; /* @private@ */ -# endif /* WIN32 && !__CUPS_SSIZE_T_DEFINED */ +# endif /* _WIN32 && !__CUPS_SSIZE_T_DEFINED */ /* @@ -67,34 +62,22 @@ typedef struct _cups_file_s cups_file_t;/**** CUPS file type ****/ extern int cupsFileClose(cups_file_t *fp) _CUPS_API_1_2; extern int cupsFileCompression(cups_file_t *fp) _CUPS_API_1_2; extern int cupsFileEOF(cups_file_t *fp) _CUPS_API_1_2; -extern const char *cupsFileFind(const char *filename, const char *path, - int executable, char *buffer, - int bufsize) _CUPS_API_1_2; +extern const char *cupsFileFind(const char *filename, const char *path, int executable, char *buffer, int bufsize) _CUPS_API_1_2; extern int cupsFileFlush(cups_file_t *fp) _CUPS_API_1_2; extern int cupsFileGetChar(cups_file_t *fp) _CUPS_API_1_2; -extern char *cupsFileGetConf(cups_file_t *fp, char *buf, - size_t buflen, char **value, - int *linenum) _CUPS_API_1_2; -extern size_t cupsFileGetLine(cups_file_t *fp, char *buf, - size_t buflen) _CUPS_API_1_2; -extern char *cupsFileGets(cups_file_t *fp, char *buf, size_t buflen) - _CUPS_API_1_2; +extern char *cupsFileGetConf(cups_file_t *fp, char *buf, size_t buflen, char **value, int *linenum) _CUPS_API_1_2; +extern size_t cupsFileGetLine(cups_file_t *fp, char *buf, size_t buflen) _CUPS_API_1_2; +extern char *cupsFileGets(cups_file_t *fp, char *buf, size_t buflen) _CUPS_API_1_2; extern int cupsFileLock(cups_file_t *fp, int block) _CUPS_API_1_2; extern int cupsFileNumber(cups_file_t *fp) _CUPS_API_1_2; -extern cups_file_t *cupsFileOpen(const char *filename, const char *mode) - _CUPS_API_1_2; +extern cups_file_t *cupsFileOpen(const char *filename, const char *mode) _CUPS_API_1_2; extern cups_file_t *cupsFileOpenFd(int fd, const char *mode) _CUPS_API_1_2; extern int cupsFilePeekChar(cups_file_t *fp) _CUPS_API_1_2; -extern int cupsFilePrintf(cups_file_t *fp, const char *format, ...) - __attribute__((__format__ (__printf__, 2, 3))) - _CUPS_API_1_2; +extern int cupsFilePrintf(cups_file_t *fp, const char *format, ...) _CUPS_FORMAT(2, 3) _CUPS_API_1_2; extern int cupsFilePutChar(cups_file_t *fp, int c) _CUPS_API_1_2; -extern ssize_t cupsFilePutConf(cups_file_t *fp, const char *directive, - const char *value) _CUPS_API_1_4; -extern int cupsFilePuts(cups_file_t *fp, const char *s) - _CUPS_API_1_2; -extern ssize_t cupsFileRead(cups_file_t *fp, char *buf, size_t bytes) - _CUPS_API_1_2; +extern ssize_t cupsFilePutConf(cups_file_t *fp, const char *directive, const char *value) _CUPS_API_1_4; +extern int cupsFilePuts(cups_file_t *fp, const char *s) _CUPS_API_1_2; +extern ssize_t cupsFileRead(cups_file_t *fp, char *buf, size_t bytes) _CUPS_API_1_2; extern off_t cupsFileRewind(cups_file_t *fp) _CUPS_API_1_2; extern off_t cupsFileSeek(cups_file_t *fp, off_t pos) _CUPS_API_1_2; extern cups_file_t *cupsFileStderr(void) _CUPS_API_1_2; @@ -102,8 +85,7 @@ extern cups_file_t *cupsFileStdin(void) _CUPS_API_1_2; extern cups_file_t *cupsFileStdout(void) _CUPS_API_1_2; extern off_t cupsFileTell(cups_file_t *fp) _CUPS_API_1_2; extern int cupsFileUnlock(cups_file_t *fp) _CUPS_API_1_2; -extern ssize_t cupsFileWrite(cups_file_t *fp, const char *buf, - size_t bytes) _CUPS_API_1_2; +extern ssize_t cupsFileWrite(cups_file_t *fp, const char *buf, size_t bytes) _CUPS_API_1_2; # ifdef __cplusplus diff --git a/cups/getdevices.c b/cups/getdevices.c index 0f303ba..de2186f 100644 --- a/cups/getdevices.c +++ b/cups/getdevices.c @@ -3,13 +3,7 @@ * * Copyright 2008-2016 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -17,6 +11,7 @@ */ #include "cups-private.h" +#include "debug-internal.h" #include "adminutil.h" @@ -29,7 +24,10 @@ * parameters provide comma-delimited lists of backends to include or omit from * the request respectively. * - * @since CUPS 1.4/macOS 10.6@ + * This function is deprecated with the IPP printer discovery functionality + * being provided by the @link cupsEnumDests@ and @cupsGetDests@ functions. + * + * @deprecated@ */ ipp_status_t /* O - Request status - @code IPP_OK@ on success. */ diff --git a/cups/getifaddrs-internal.h b/cups/getifaddrs-internal.h new file mode 100644 index 0000000..35e98be --- /dev/null +++ b/cups/getifaddrs-internal.h @@ -0,0 +1,113 @@ +/* + * getifaddrs definitions for CUPS. + * + * Copyright 2007-2018 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. + */ + +#ifndef _CUPS_GETIFADDRS_INTERNAL_H_ +# define _CUPS_GETIFADDRS_INTERNAL_H_ + +/* + * Include necessary headers... + */ + +# include "config.h" +# ifdef _WIN32 +# define _WINSOCK_DEPRECATED_NO_WARNINGS 1 +# include +# include +# define CUPS_SOCAST (const char *) +# else +# include +# include +# include +# define CUPS_SOCAST +# endif /* _WIN32 */ + +# if defined(__APPLE__) && !defined(_SOCKLEN_T) +/* + * macOS 10.2.x does not define socklen_t, and in fact uses an int instead of + * unsigned type for length values... + */ + +typedef int socklen_t; +# endif /* __APPLE__ && !_SOCKLEN_T */ + +# ifndef _WIN32 +# include +# include +# ifdef HAVE_GETIFADDRS +# include +# else +# include +# ifdef HAVE_SYS_SOCKIO_H +# include +# endif /* HAVE_SYS_SOCKIO_H */ +# endif /* HAVE_GETIFADDRS */ +# endif /* !_WIN32 */ + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * Some OS's don't have getifaddrs() and freeifaddrs()... + */ + +# if !defined(_WIN32) && !defined(HAVE_GETIFADDRS) +# ifdef ifa_dstaddr +# undef ifa_dstaddr +# endif /* ifa_dstaddr */ +# ifndef ifr_netmask +# define ifr_netmask ifr_addr +# endif /* !ifr_netmask */ + +struct ifaddrs /**** Interface Structure ****/ +{ + struct ifaddrs *ifa_next; /* Next interface in list */ + char *ifa_name; /* Name of interface */ + unsigned int ifa_flags; /* Flags (up, point-to-point, etc.) */ + struct sockaddr *ifa_addr, /* Network address */ + *ifa_netmask; /* Address mask */ + union + { + struct sockaddr *ifu_broadaddr; /* Broadcast address of this interface. */ + struct sockaddr *ifu_dstaddr; /* Point-to-point destination address. */ + } ifa_ifu; + + void *ifa_data; /* Interface statistics */ +}; + +# ifndef ifa_broadaddr +# define ifa_broadaddr ifa_ifu.ifu_broadaddr +# endif /* !ifa_broadaddr */ +# ifndef ifa_dstaddr +# define ifa_dstaddr ifa_ifu.ifu_dstaddr +# endif /* !ifa_dstaddr */ + +extern int _cups_getifaddrs(struct ifaddrs **addrs) _CUPS_PRIVATE; +# define getifaddrs _cups_getifaddrs +extern void _cups_freeifaddrs(struct ifaddrs *addrs) _CUPS_PRIVATE; +# define freeifaddrs _cups_freeifaddrs +# endif /* !_WIN32 && !HAVE_GETIFADDRS */ + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_GETIFADDRS_INTERNAL_H_ */ diff --git a/cups/getifaddrs.c b/cups/getifaddrs.c index 82653a9..f751aa8 100644 --- a/cups/getifaddrs.c +++ b/cups/getifaddrs.c @@ -1,21 +1,18 @@ /* * Network interface functions for CUPS. * - * Copyright 2007-2010 by Apple Inc. - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2006 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * "LICENSE" which should have been included with this file. If this - * file is missing or damaged, see the license at "http://www.cups.org/". + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* * Include necessary headers. */ -#include "http-private.h" +#include "getifaddrs-internal.h" #ifndef HAVE_GETIFADDRS diff --git a/cups/getputfile.c b/cups/getputfile.c index ae33bc5..818d5e9 100644 --- a/cups/getputfile.c +++ b/cups/getputfile.c @@ -1,16 +1,11 @@ /* * Get/put file functions for CUPS. * - * Copyright 2007-2014 by Apple Inc. + * Copyright 2007-2018 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -18,13 +13,14 @@ */ #include "cups-private.h" +#include "debug-internal.h" #include #include -#if defined(WIN32) || defined(__EMX__) +#if defined(_WIN32) || defined(__EMX__) # include #else # include -#endif /* WIN32 || __EMX__ */ +#endif /* _WIN32 || __EMX__ */ /* @@ -45,6 +41,8 @@ cupsGetFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA http_status_t status; /* HTTP status from server */ char if_modified_since[HTTP_MAX_VALUE]; /* If-Modified-Since header */ + int new_auth = 0; /* Using new auth information? */ + int digest; /* Are we using Digest authentication? */ /* @@ -85,9 +83,33 @@ cupsGetFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA } httpClearFields(http); - httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring); httpSetField(http, HTTP_FIELD_IF_MODIFIED_SINCE, if_modified_since); + digest = http->authstring && !strncmp(http->authstring, "Digest ", 7); + + if (digest && !new_auth) + { + /* + * Update the Digest authentication string... + */ + + _httpSetDigestAuthString(http, http->nextnonce, "GET", resource); + } + +#ifdef HAVE_GSSAPI + if (http->authstring && !strncmp(http->authstring, "Negotiate", 9) && !new_auth) + { + /* + * Do not use cached Kerberos credentials since they will look like a + * "replay" attack... + */ + + _cupsSetNegotiateAuthString(http, "GET", resource); + } +#endif /* HAVE_GSSAPI */ + + httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring); + if (httpGet(http, resource)) { if (httpReconnect2(http, 30000, NULL)) @@ -102,6 +124,8 @@ cupsGetFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA } } + new_auth = 0; + while ((status = httpUpdate(http)) == HTTP_STATUS_CONTINUE); if (status == HTTP_STATUS_UNAUTHORIZED) @@ -116,6 +140,8 @@ cupsGetFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA * See if we can do authentication... */ + new_auth = 1; + if (cupsDoAuthentication(http, "GET", resource)) { status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; @@ -267,6 +293,8 @@ cupsPutFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA int retries; /* Number of retries */ char buffer[8192]; /* Buffer for file */ http_status_t status; /* HTTP status from server */ + int new_auth = 0; /* Using new auth information? */ + int digest; /* Are we using Digest authentication? */ /* @@ -309,10 +337,34 @@ cupsPutFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA http->authstring)); httpClearFields(http); - httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring); httpSetField(http, HTTP_FIELD_TRANSFER_ENCODING, "chunked"); httpSetExpect(http, HTTP_STATUS_CONTINUE); + digest = http->authstring && !strncmp(http->authstring, "Digest ", 7); + + if (digest && !new_auth) + { + /* + * Update the Digest authentication string... + */ + + _httpSetDigestAuthString(http, http->nextnonce, "PUT", resource); + } + +#ifdef HAVE_GSSAPI + if (http->authstring && !strncmp(http->authstring, "Negotiate", 9) && !new_auth) + { + /* + * Do not use cached Kerberos credentials since they will look like a + * "replay" attack... + */ + + _cupsSetNegotiateAuthString(http, "PUT", resource); + } +#endif /* HAVE_GSSAPI */ + + httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring); + if (httpPut(http, resource)) { if (httpReconnect2(http, 30000, NULL)) @@ -383,6 +435,8 @@ cupsPutFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA DEBUG_printf(("2cupsPutFd: status=%d", status)); + new_auth = 0; + if (status == HTTP_STATUS_UNAUTHORIZED) { /* @@ -395,6 +449,8 @@ cupsPutFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA * See if we can do authentication... */ + new_auth = 1; + if (cupsDoAuthentication(http, "PUT", resource)) { status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; diff --git a/cups/globals.c b/cups/globals.c index 8a05c3e..b75434f 100644 --- a/cups/globals.c +++ b/cups/globals.c @@ -4,13 +4,7 @@ * Copyright 2007-2015 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -34,23 +28,23 @@ static _cups_threadkey_t cups_globals_key = _CUPS_THREADKEY_INITIALIZER; static pthread_once_t cups_globals_key_once = PTHREAD_ONCE_INIT; /* One-time initialization object */ #endif /* HAVE_PTHREAD_H */ -#if defined(HAVE_PTHREAD_H) || defined(WIN32) +#if defined(HAVE_PTHREAD_H) || defined(_WIN32) static _cups_mutex_t cups_global_mutex = _CUPS_MUTEX_INITIALIZER; /* Global critical section */ -#endif /* HAVE_PTHREAD_H || WIN32 */ +#endif /* HAVE_PTHREAD_H || _WIN32 */ /* * Local functions... */ -#ifdef WIN32 +#ifdef _WIN32 static void cups_fix_path(char *path); -#endif /* WIN32 */ +#endif /* _WIN32 */ static _cups_globals_t *cups_globals_alloc(void); -#if defined(HAVE_PTHREAD_H) || defined(WIN32) +#if defined(HAVE_PTHREAD_H) || defined(_WIN32) static void cups_globals_free(_cups_globals_t *g); -#endif /* HAVE_PTHREAD_H || WIN32 */ +#endif /* HAVE_PTHREAD_H || _WIN32 */ #ifdef HAVE_PTHREAD_H static void cups_globals_init(void); #endif /* HAVE_PTHREAD_H */ @@ -65,7 +59,7 @@ _cupsGlobalLock(void) { #ifdef HAVE_PTHREAD_H pthread_mutex_lock(&cups_global_mutex); -#elif defined(WIN32) +#elif defined(_WIN32) EnterCriticalSection(&cups_global_mutex.m_criticalSection); #endif /* HAVE_PTHREAD_H */ } @@ -120,13 +114,13 @@ _cupsGlobalUnlock(void) { #ifdef HAVE_PTHREAD_H pthread_mutex_unlock(&cups_global_mutex); -#elif defined(WIN32) +#elif defined(_WIN32) LeaveCriticalSection(&cups_global_mutex.m_criticalSection); #endif /* HAVE_PTHREAD_H */ } -#ifdef WIN32 +#ifdef _WIN32 /* * 'DllMain()' - Main entry for library. */ @@ -170,7 +164,7 @@ DllMain(HINSTANCE hinst, /* I - DLL module handle */ return (TRUE); } -#endif /* WIN32 */ +#endif /* _WIN32 */ /* @@ -182,13 +176,13 @@ cups_globals_alloc(void) { _cups_globals_t *cg = malloc(sizeof(_cups_globals_t)); /* Pointer to global data */ -#ifdef WIN32 +#ifdef _WIN32 HKEY key; /* Registry key */ DWORD size; /* Size of string */ static char installdir[1024] = "", /* Install directory */ confdir[1024] = "", /* Server root directory */ localedir[1024] = ""; /* Locale directory */ -#endif /* WIN32 */ +#endif /* _WIN32 */ if (!cg) @@ -219,7 +213,7 @@ cups_globals_alloc(void) * Then set directories as appropriate... */ -#ifdef WIN32 +#ifdef _WIN32 if (!installdir[0]) { /* @@ -228,8 +222,7 @@ cups_globals_alloc(void) strlcpy(installdir, "C:/Program Files/cups.org", sizeof(installdir)); - if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\cups.org", 0, KEY_READ, - &key)) + if (!RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\cups.org", 0, KEY_READ, &key)) { /* * Grab the installation directory... @@ -238,7 +231,7 @@ cups_globals_alloc(void) char *ptr; /* Pointer into installdir */ size = sizeof(installdir); - RegQueryValueEx(key, "installdir", NULL, NULL, installdir, &size); + RegQueryValueExA(key, "installdir", NULL, NULL, installdir, &size); RegCloseKey(key); for (ptr = installdir; *ptr;) @@ -315,7 +308,7 @@ cups_globals_alloc(void) if ((cg->localedir = getenv("LOCALEDIR")) == NULL) cg->localedir = CUPS_LOCALEDIR; } -#endif /* WIN32 */ +#endif /* _WIN32 */ return (cg); } @@ -325,7 +318,7 @@ cups_globals_alloc(void) * 'cups_globals_free()' - Free global data. */ -#if defined(HAVE_PTHREAD_H) || defined(WIN32) +#if defined(HAVE_PTHREAD_H) || defined(_WIN32) static void cups_globals_free(_cups_globals_t *cg) /* I - Pointer to global data */ { @@ -358,9 +351,12 @@ cups_globals_free(_cups_globals_t *cg) /* I - Pointer to global data */ cupsFreeOptions(cg->cupsd_num_settings, cg->cupsd_settings); + if (cg->raster_error.start) + free(cg->raster_error.start); + free(cg); } -#endif /* HAVE_PTHREAD_H || WIN32 */ +#endif /* HAVE_PTHREAD_H || _WIN32 */ #ifdef HAVE_PTHREAD_H diff --git a/cups/hash.c b/cups/hash.c index ede5461..7b3ea81 100644 --- a/cups/hash.c +++ b/cups/hash.c @@ -1,15 +1,10 @@ /* * Hashing function for CUPS. * - * Copyright 2015-2016 by Apple Inc. + * Copyright © 2015-2019 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -21,6 +16,8 @@ # include #elif defined(HAVE_GNUTLS) # include +#else +# include "md5-internal.h" #endif /* __APPLE__ */ @@ -53,7 +50,24 @@ cupsHashData(const char *algorithm, /* I - Algorithm name */ } #ifdef __APPLE__ - if (!strcmp(algorithm, "sha")) + if (!strcmp(algorithm, "md5")) + { + /* + * MD5 (deprecated but widely used...) + */ + + CC_MD5_CTX ctx; /* MD5 context */ + + if (hashsize < CC_MD5_DIGEST_LENGTH) + goto too_small; + + CC_MD5_Init(&ctx); + CC_MD5_Update(&ctx, data, (CC_LONG)datalen); + CC_MD5_Final(hash, &ctx); + + return (CC_MD5_DIGEST_LENGTH); + } + else if (!strcmp(algorithm, "sha")) { /* * SHA-1... @@ -171,7 +185,16 @@ cupsHashData(const char *algorithm, /* I - Algorithm name */ unsigned char temp[64]; /* Temporary hash buffer */ size_t tempsize = 0; /* Truncate to this size? */ - if (!strcmp(algorithm, "sha")) + +# ifdef HAVE_GNUTLS_FIPS140_SET_MODE + unsigned oldmode = gnutls_fips140_mode_enabled(); + + gnutls_fips140_set_mode(GNUTLS_FIPS140_LAX, GNUTLS_FIPS140_SET_MODE_THREAD); +# endif /* HAVE_GNUTLS_FIPS140_SET_MODE */ + + if (!strcmp(algorithm, "md5")) + alg = GNUTLS_DIG_MD5; + else if (!strcmp(algorithm, "sha")) alg = GNUTLS_DIG_SHA1; else if (!strcmp(algorithm, "sha2-224")) alg = GNUTLS_DIG_SHA224; @@ -206,6 +229,10 @@ cupsHashData(const char *algorithm, /* I - Algorithm name */ gnutls_hash_fast(alg, data, datalen, temp); memcpy(hash, temp, tempsize); +# ifdef HAVE_GNUTLS_FIPS140_SET_MODE + gnutls_fips140_set_mode(oldmode, GNUTLS_FIPS140_SET_MODE_THREAD); +# endif /* HAVE_GNUTLS_FIPS140_SET_MODE */ + return ((ssize_t)tempsize); } @@ -214,15 +241,33 @@ cupsHashData(const char *algorithm, /* I - Algorithm name */ gnutls_hash_fast(alg, data, datalen, hash); - return (gnutls_hash_get_len(alg)); +# ifdef HAVE_GNUTLS_FIPS140_SET_MODE + gnutls_fips140_set_mode(oldmode, GNUTLS_FIPS140_SET_MODE_THREAD); +# endif /* HAVE_GNUTLS_FIPS140_SET_MODE */ + + return ((ssize_t)gnutls_hash_get_len(alg)); } +# ifdef HAVE_GNUTLS_FIPS140_SET_MODE + gnutls_fips140_set_mode(oldmode, GNUTLS_FIPS140_SET_MODE_THREAD); +# endif /* HAVE_GNUTLS_FIPS140_SET_MODE */ + #else /* - * No hash support without CommonCrypto or GNU TLS... + * No hash support beyond MD5 without CommonCrypto or GNU TLS... */ - if (hashsize < 64) + if (!strcmp(algorithm, "md5")) + { + _cups_md5_state_t state; /* MD5 state info */ + + _cupsMD5Init(&state); + _cupsMD5Append(&state, data, datalen); + _cupsMD5Finish(&state, hash); + + return (16); + } + else if (hashsize < 64) goto too_small; #endif /* __APPLE__ */ @@ -240,6 +285,60 @@ cupsHashData(const char *algorithm, /* I - Algorithm name */ too_small: +#ifdef HAVE_GNUTLS_FIPS140_SET_MODE + gnutls_fips140_set_mode(oldmode, GNUTLS_FIPS140_SET_MODE_THREAD); +#endif /* HAVE_GNUTLS_FIPS140_SET_MODE */ + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Hash buffer too small."), 1); return (-1); } + + +/* + * 'cupsHashString()' - Format a hash value as a hexadecimal string. + * + * The passed buffer must be at least 2 * hashsize + 1 characters in length. + * + * @since CUPS 2.2.7@ + */ + +const char * /* O - Formatted string */ +cupsHashString( + const unsigned char *hash, /* I - Hash */ + size_t hashsize, /* I - Size of hash */ + char *buffer, /* I - String buffer */ + size_t bufsize) /* I - Size of string buffer */ +{ + char *bufptr = buffer; /* Pointer into buffer */ + static const char *hex = "0123456789abcdef"; + /* Hex characters (lowercase!) */ + + + /* + * Range check input... + */ + + if (!hash || hashsize < 1 || !buffer || bufsize < (2 * hashsize + 1)) + { + if (buffer) + *buffer = '\0'; + return (NULL); + } + + /* + * Loop until we've converted the whole hash... + */ + + while (hashsize > 0) + { + *bufptr++ = hex[*hash >> 4]; + *bufptr++ = hex[*hash & 15]; + + hash ++; + hashsize --; + } + + *bufptr = '\0'; + + return (buffer); +} diff --git a/cups/http-addr.c b/cups/http-addr.c index 61c8638..86749c8 100644 --- a/cups/http-addr.c +++ b/cups/http-addr.c @@ -1,16 +1,11 @@ /* * HTTP address routines for CUPS. * - * Copyright 2007-2014 by Apple Inc. + * Copyright 2007-2019 by Apple Inc. * Copyright 1997-2006 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -18,13 +13,16 @@ */ #include "cups-private.h" +#include "debug-internal.h" #include #ifdef HAVE_RESOLV_H # include #endif /* HAVE_RESOLV_H */ #ifdef __APPLE__ # include -# include +# ifdef HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME +# include +# endif /* HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME */ #endif /* __APPLE__ */ @@ -69,11 +67,11 @@ int /* O - 0 on success, -1 on failure */ httpAddrClose(http_addr_t *addr, /* I - Listen address or @code NULL@ */ int fd) /* I - Socket file descriptor */ { -#ifdef WIN32 +#ifdef _WIN32 if (closesocket(fd)) #else if (close(fd)) -#endif /* WIN32 */ +#endif /* _WIN32 */ return (-1); #ifdef AF_LOCAL @@ -258,9 +256,9 @@ httpAddrListen(http_addr_t *addr, /* I - Address to bind to */ * Close on exec... */ -#ifndef WIN32 +#ifndef _WIN32 fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); -#endif /* !WIN32 */ +#endif /* !_WIN32 */ #ifdef SO_NOSIGPIPE /* diff --git a/cups/http-addrlist.c b/cups/http-addrlist.c index 22bd5a7..485c6f4 100644 --- a/cups/http-addrlist.c +++ b/cups/http-addrlist.c @@ -1,16 +1,11 @@ /* * HTTP address list routines for CUPS. * - * Copyright 2007-2017 by Apple Inc. + * Copyright 2007-2018 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -18,15 +13,16 @@ */ #include "cups-private.h" +#include "debug-internal.h" #ifdef HAVE_RESOLV_H # include #endif /* HAVE_RESOLV_H */ #ifdef HAVE_POLL # include #endif /* HAVE_POLL */ -#ifndef WIN32 +#ifndef _WIN32 # include -#endif /* WIN32 */ +#endif /* _WIN32 */ /* @@ -61,14 +57,14 @@ httpAddrConnect2( int *cancel) /* I - Pointer to "cancel" variable */ { int val; /* Socket option value */ -#ifndef WIN32 - int flags; /* Socket flags */ -#endif /* !WIN32 */ - int remaining; /* Remaining timeout */ - int i, /* Looping var */ - nfds, /* Number of file descriptors */ - fds[100], /* Socket file descriptors */ +#ifndef _WIN32 + int i, j, /* Looping vars */ + flags, /* Socket flags */ result; /* Result from select() or poll() */ +#endif /* !_WIN32 */ + int remaining; /* Remaining timeout */ + int nfds, /* Number of file descriptors */ + fds[100]; /* Socket file descriptors */ http_addrlist_t *addrs[100]; /* Addresses */ #ifndef HAVE_POLL int max_fd = -1; /* Highest file descriptor */ @@ -84,8 +80,10 @@ httpAddrConnect2( # endif /* HAVE_POLL */ #endif /* O_NONBLOCK */ #ifdef DEBUG +# ifndef _WIN32 socklen_t len; /* Length of value */ http_addr_t peer; /* Peer address */ +# endif /* !_WIN32 */ char temp[256]; /* Temporary address string */ #endif /* DEBUG */ @@ -213,11 +211,11 @@ httpAddrConnect2( return (addrlist); } -#ifdef WIN32 +#ifdef _WIN32 if (WSAGetLastError() != WSAEINPROGRESS && WSAGetLastError() != WSAEWOULDBLOCK) #else if (errno != EINPROGRESS && errno != EWOULDBLOCK) -#endif /* WIN32 */ +#endif /* _WIN32 */ { DEBUG_printf(("1httpAddrConnect2: Unable to connect to %s:%d: %s", httpAddrString(&(addrlist->addr), temp, sizeof(temp)), httpAddrPort(&(addrlist->addr)), strerror(errno))); httpAddrClose(NULL, fds[nfds]); @@ -225,9 +223,9 @@ httpAddrConnect2( continue; } -#ifndef WIN32 +#ifndef _WIN32 fcntl(fds[nfds], F_SETFL, flags); -#endif /* !WIN32 */ +#endif /* !_WIN32 */ #ifndef HAVE_POLL if (fds[nfds] > max_fd) @@ -296,11 +294,11 @@ httpAddrConnect2( DEBUG_printf(("1httpAddrConnect2: select() returned %d (%d)", result, errno)); # endif /* HAVE_POLL */ } -# ifdef WIN32 +# ifdef _WIN32 while (result < 0 && (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEWOULDBLOCK)); # else while (result < 0 && (errno == EINTR || errno == EAGAIN)); -# endif /* WIN32 */ +# endif /* _WIN32 */ if (result > 0) { @@ -323,6 +321,8 @@ httpAddrConnect2( if (!getpeername(fds[i], (struct sockaddr *)&peer, &len)) DEBUG_printf(("1httpAddrConnect2: Connected to %s:%d...", httpAddrString(&peer, temp, sizeof(temp)), httpAddrPort(&peer))); # endif /* DEBUG */ + + break; } # ifdef HAVE_POLL else if (pfds[i].revents & (POLLERR | POLLHUP)) @@ -346,7 +346,20 @@ httpAddrConnect2( } if (connaddr) + { + /* + * Connected on one address, close all of the other sockets we have so + * far and return... + */ + + for (j = 0; j < i; j ++) + httpAddrClose(NULL, fds[j]); + + for (j ++; j < nfds; j ++) + httpAddrClose(NULL, fds[j]); + return (connaddr); + } } #endif /* O_NONBLOCK */ @@ -362,11 +375,11 @@ httpAddrConnect2( httpAddrClose(NULL, fds[nfds]); } -#ifdef WIN32 +#ifdef _WIN32 _cupsSetError(IPP_STATUS_ERROR_SERVICE_UNAVAILABLE, "Connection failed", 0); #else _cupsSetError(IPP_STATUS_ERROR_SERVICE_UNAVAILABLE, strerror(errno), 0); -#endif /* WIN32 */ +#endif /* _WIN32 */ return (NULL); } @@ -603,6 +616,7 @@ httpAddrGetList(const char *hostname, /* I - Hostname, IP address, or NULL for p if (!temp) { httpAddrFreeList(first); + freeaddrinfo(results); _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0); return (NULL); } @@ -638,7 +652,11 @@ httpAddrGetList(const char *hostname, /* I - Hostname, IP address, or NULL for p if (error == EAI_FAIL) cg->need_res_init = 1; +# ifdef _WIN32 /* Really, Microsoft?!? */ + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gai_strerrorA(error), 0); +# else _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gai_strerror(error), 0); +# endif /* _WIN32 */ } #else @@ -833,11 +851,11 @@ httpAddrGetList(const char *hostname, /* I - Hostname, IP address, or NULL for p temp->addr.ipv6.sin6_family = AF_INET6; temp->addr.ipv6.sin6_port = htons(portnum); -# ifdef WIN32 +# ifdef _WIN32 temp->addr.ipv6.sin6_addr.u.Byte[15] = 1; # else temp->addr.ipv6.sin6_addr.s6_addr32[3] = htonl(1); -# endif /* WIN32 */ +# endif /* _WIN32 */ if (!first) first = temp; diff --git a/cups/http-private.h b/cups/http-private.h index 7c39c04..212fea7 100644 --- a/cups/http-private.h +++ b/cups/http-private.h @@ -1,16 +1,11 @@ /* * Private HTTP definitions for CUPS. * - * Copyright 2007-2017 by Apple Inc. + * Copyright 2007-2018 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ #ifndef _CUPS_HTTP_PRIVATE_H_ @@ -30,7 +25,8 @@ # endif /* __sun */ # include -# ifdef WIN32 +# ifdef _WIN32 +# define _WINSOCK_DEPRECATED_NO_WARNINGS 1 # include # include # define CUPS_SOCAST (const char *) @@ -39,7 +35,7 @@ # include # include # define CUPS_SOCAST -# endif /* WIN32 */ +# endif /* _WIN32 */ # ifdef HAVE_GSSAPI # ifdef HAVE_GSS_GSSAPI_H @@ -68,7 +64,6 @@ typedef int socklen_t; # endif /* __APPLE__ && !_SOCKLEN_T */ # include -# include "md5-private.h" # include "ipp-private.h" # ifdef HAVE_GNUTLS @@ -78,60 +73,13 @@ typedef int socklen_t; # include # include # include -# ifdef HAVE_SECURETRANSPORTPRIV_H -# include -# endif /* HAVE_SECURETRANSPORTPRIV_H */ # ifdef HAVE_SECITEM_H # include # endif /* HAVE_SECITEM_H */ -# ifdef HAVE_SECBASEPRIV_H -# include -# endif /* HAVE_SECBASEPRIV_H */ # ifdef HAVE_SECCERTIFICATE_H # include # include # endif /* HAVE_SECCERTIFICATE_H */ -# ifdef HAVE_SECCERTIFICATEPRIV_H -# include -# else -# ifdef __cplusplus -extern "C" { -# endif /* __cplusplus */ -# ifndef _SECURITY_VERSION_GREATER_THAN_57610_ -typedef CF_OPTIONS(uint32_t, SecKeyUsage) { - kSecKeyUsageAll = 0x7FFFFFFF -}; -# endif /* !_SECURITY_VERSION_GREATER_THAN_57610_ */ -extern const void * kSecCSRChallengePassword; -extern const void * kSecSubjectAltName; -extern const void * kSecCertificateKeyUsage; -extern const void * kSecCSRBasicContraintsPathLen; -extern const void * kSecCertificateExtensions; -extern const void * kSecCertificateExtensionsEncoded; -extern const void * kSecOidCommonName; -extern const void * kSecOidCountryName; -extern const void * kSecOidStateProvinceName; -extern const void * kSecOidLocalityName; -extern const void * kSecOidOrganization; -extern const void * kSecOidOrganizationalUnit; -extern SecCertificateRef SecCertificateCreateWithBytes(CFAllocatorRef allocator, const UInt8 *bytes, CFIndex length); -extern bool SecCertificateIsValid(SecCertificateRef certificate, CFAbsoluteTime verifyTime); -extern CFAbsoluteTime SecCertificateNotValidAfter(SecCertificateRef certificate); -extern SecCertificateRef SecGenerateSelfSignedCertificate(CFArrayRef subject, CFDictionaryRef parameters, SecKeyRef publicKey, SecKeyRef privateKey); -extern SecIdentityRef SecIdentityCreate(CFAllocatorRef allocator, SecCertificateRef certificate, SecKeyRef privateKey); -# ifdef __cplusplus -} -# endif /* __cplusplus */ -# endif /* HAVE_SECCERTIFICATEPRIV_H */ -# ifdef HAVE_SECITEMPRIV_H -# include -# endif /* HAVE_SECITEMPRIV_H */ -# ifdef HAVE_SECIDENTITYSEARCHPRIV_H -# include -# endif /* HAVE_SECIDENTITYSEARCHPRIV_H */ -# ifdef HAVE_SECPOLICYPRIV_H -# include -# endif /* HAVE_SECPOLICYPRIV_H */ # elif defined(HAVE_SSPISSL) # include # include @@ -141,7 +89,7 @@ extern SecIdentityRef SecIdentityCreate(CFAllocatorRef allocator, SecCertificate # include # endif /* HAVE_GNUTLS */ -# ifndef WIN32 +# ifndef _WIN32 # include # include # ifdef HAVE_GETIFADDRS @@ -152,11 +100,7 @@ extern SecIdentityRef SecIdentityCreate(CFAllocatorRef allocator, SecCertificate # include # endif /* HAVE_SYS_SOCKIO_H */ # endif /* HAVE_GETIFADDRS */ -# endif /* !WIN32 */ - -# ifdef HAVE_LIBZ -# include -# endif /* HAVE_LIBZ */ +# endif /* !_WIN32 */ /* @@ -172,19 +116,24 @@ extern "C" { * Constants... */ +# define _HTTP_MAX_SBUFFER 65536 /* Size of (de)compression buffer */ +# define _HTTP_RESOLVE_DEFAULT 0 /* Just resolve with default options */ +# define _HTTP_RESOLVE_STDERR 1 /* Log resolve progress to stderr */ +# define _HTTP_RESOLVE_FQDN 2 /* Resolve to a FQDN */ +# define _HTTP_RESOLVE_FAXOUT 4 /* Resolve FaxOut service? */ -#define _HTTP_MAX_SBUFFER 65536 /* Size of (de)compression buffer */ -#define _HTTP_RESOLVE_DEFAULT 0 /* Just resolve with default options */ -#define _HTTP_RESOLVE_STDERR 1 /* Log resolve progress to stderr */ -#define _HTTP_RESOLVE_FQDN 2 /* Resolve to a FQDN */ -#define _HTTP_RESOLVE_FAXOUT 4 /* Resolve FaxOut service? */ +# define _HTTP_TLS_NONE 0 /* No TLS options */ +# define _HTTP_TLS_ALLOW_RC4 1 /* Allow RC4 cipher suites */ +# define _HTTP_TLS_ALLOW_DH 2 /* Allow DH/DHE key negotiation */ +# define _HTTP_TLS_DENY_CBC 4 /* Deny CBC cipher suites */ +# define _HTTP_TLS_SET_DEFAULT 128 /* Setting the default TLS options */ -#define _HTTP_TLS_NONE 0 /* No TLS options */ -#define _HTTP_TLS_ALLOW_RC4 1 /* Allow RC4 cipher suites */ -#define _HTTP_TLS_ALLOW_SSL3 2 /* Allow SSL 3.0 */ -#define _HTTP_TLS_ALLOW_DH 4 /* Allow DH/DHE key negotiation */ -#define _HTTP_TLS_DENY_TLS10 16 /* Deny TLS 1.0 */ -#define _HTTP_TLS_DENY_CBC 32 /* Deny CBC cipher suites */ +# define _HTTP_TLS_SSL3 0 /* Min/max version is SSL/3.0 */ +# define _HTTP_TLS_1_0 1 /* Min/max version is TLS/1.0 */ +# define _HTTP_TLS_1_1 2 /* Min/max version is TLS/1.1 */ +# define _HTTP_TLS_1_2 3 /* Min/max version is TLS/1.2 */ +# define _HTTP_TLS_1_3 4 /* Min/max version is TLS/1.3 */ +# define _HTTP_TLS_MAX 5 /* Highest known TLS version */ /* @@ -205,21 +154,6 @@ typedef gnutls_certificate_credentials_t *http_tls_credentials_t; * for its IO and protocol management... */ -# if !defined(HAVE_SECBASEPRIV_H) && defined(HAVE_CSSMERRORSTRING) /* Declare prototype for function in that header... */ -extern const char *cssmErrorString(int error); -# endif /* !HAVE_SECBASEPRIV_H && HAVE_CSSMERRORSTRING */ -# if !defined(HAVE_SECIDENTITYSEARCHPRIV_H) && defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY) /* Declare prototype for function in that header... */ -extern OSStatus SecIdentitySearchCreateWithPolicy(SecPolicyRef policy, - CFStringRef idString, CSSM_KEYUSE keyUsage, - CFTypeRef keychainOrArray, - Boolean returnOnlyValidIdentities, - SecIdentitySearchRef* searchRef); -# endif /* !HAVE_SECIDENTITYSEARCHPRIV_H && HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY */ -# if !defined(HAVE_SECPOLICYPRIV_H) && defined(HAVE_SECPOLICYSETVALUE) /* Declare prototype for function in that header... */ -extern OSStatus SecPolicySetValue(SecPolicyRef policyRef, - const CSSM_DATA *value); -# endif /* !HAVE_SECPOLICYPRIV_H && HAVE_SECPOLICYSETVALUE */ - typedef SSLContextRef http_tls_t; typedef CFArrayRef http_tls_credentials_t; @@ -287,8 +221,8 @@ struct _http_s /**** HTTP connection structure ****/ struct sockaddr_in _hostaddr; /* Address of connected host (deprecated) */ char hostname[HTTP_MAX_HOST], /* Name of connected host */ - fields[HTTP_FIELD_ACCEPT_ENCODING][HTTP_MAX_VALUE]; - /* Field values up to Accept-Encoding */ + _fields[HTTP_FIELD_ACCEPT_ENCODING][HTTP_MAX_VALUE]; + /* Field values up to Accept-Encoding (deprecated) */ char *data; /* Pointer to data buffer */ http_encoding_t data_encoding; /* Chunked or not */ int _data_remaining;/* Number of bytes left (deprecated) */ @@ -296,10 +230,10 @@ struct _http_s /**** HTTP connection structure ****/ char buffer[HTTP_MAX_BUFFER]; /* Buffer for incoming data */ int _auth_type; /* Authentication in use (deprecated) */ - _cups_md5_state_t md5_state; /* MD5 state */ + unsigned char _md5_state[88]; /* MD5 state (deprecated) */ char nonce[HTTP_MAX_VALUE]; /* Nonce value */ - int nonce_count; /* Nonce count */ + unsigned nonce_count; /* Nonce count */ http_tls_t tls; /* TLS state information */ http_encryption_t encryption; /* Encryption requirements */ @@ -324,8 +258,6 @@ struct _http_s /**** HTTP connection structure ****/ int wused; /* Write buffer bytes used */ /**** New in CUPS 1.3 ****/ - char *field_authorization; - /* Authorization field */ char *authstring; /* Current Authorization field */ # ifdef HAVE_GSSAPI gss_OID gssmech; /* Authentication mechanism */ @@ -350,19 +282,26 @@ struct _http_s /**** HTTP connection structure ****/ /**** New in CUPS 1.7 ****/ int tls_upgrade; /* Non-zero if we are doing an upgrade */ _http_mode_t mode; /* _HTTP_MODE_CLIENT or _HTTP_MODE_SERVER */ - char *accept_encoding, - /* Accept-Encoding field */ - *allow, /* Allow field */ - *server, /* Server field */ - *default_accept_encoding, - *default_server, - *default_user_agent; - /* Default field values */ # ifdef HAVE_LIBZ _http_coding_t coding; /* _HTTP_CODING_xxx */ - z_stream stream; /* (De)compression stream */ - Bytef *sbuffer; /* (De)compression buffer */ + void *stream; /* (De)compression stream */ + unsigned char *sbuffer; /* (De)compression buffer */ # endif /* HAVE_LIBZ */ + + /**** New in CUPS 2.2.9 ****/ + char algorithm[65], /* Algorithm from WWW-Authenticate */ + nextnonce[HTTP_MAX_VALUE], + /* Next nonce value from Authentication-Info */ + opaque[HTTP_MAX_VALUE], + /* Opaque value from WWW-Authenticate */ + realm[HTTP_MAX_VALUE]; + /* Realm from WWW-Authenticate */ + + /**** New in CUPS 2.3 ****/ + char *fields[HTTP_FIELD_MAX], + /* Allocated field values */ + *default_fields[HTTP_FIELD_MAX]; + /* Default field values, if any */ }; # endif /* !_HTTP_NO_PRIVATE */ @@ -377,76 +316,34 @@ extern const char *_cups_hstrerror(int error); # endif /* !HAVE_HSTRERROR */ -/* - * Some OS's don't have getifaddrs() and freeifaddrs()... - */ - -# if !defined(WIN32) && !defined(HAVE_GETIFADDRS) -# ifdef ifa_dstaddr -# undef ifa_dstaddr -# endif /* ifa_dstaddr */ -# ifndef ifr_netmask -# define ifr_netmask ifr_addr -# endif /* !ifr_netmask */ - -struct ifaddrs /**** Interface Structure ****/ -{ - struct ifaddrs *ifa_next; /* Next interface in list */ - char *ifa_name; /* Name of interface */ - unsigned int ifa_flags; /* Flags (up, point-to-point, etc.) */ - struct sockaddr *ifa_addr, /* Network address */ - *ifa_netmask; /* Address mask */ - union - { - struct sockaddr *ifu_broadaddr; /* Broadcast address of this interface. */ - struct sockaddr *ifu_dstaddr; /* Point-to-point destination address. */ - } ifa_ifu; - - void *ifa_data; /* Interface statistics */ -}; - -# ifndef ifa_broadaddr -# define ifa_broadaddr ifa_ifu.ifu_broadaddr -# endif /* !ifa_broadaddr */ -# ifndef ifa_dstaddr -# define ifa_dstaddr ifa_ifu.ifu_dstaddr -# endif /* !ifa_dstaddr */ - -extern int _cups_getifaddrs(struct ifaddrs **addrs); -# define getifaddrs _cups_getifaddrs -extern void _cups_freeifaddrs(struct ifaddrs *addrs); -# define freeifaddrs _cups_freeifaddrs -# endif /* !WIN32 && !HAVE_GETIFADDRS */ - - /* * Prototypes... */ -extern void _httpAddrSetPort(http_addr_t *addr, int port); +extern void _httpAddrSetPort(http_addr_t *addr, int port) _CUPS_PRIVATE; extern http_tls_credentials_t - _httpCreateCredentials(cups_array_t *credentials); + _httpCreateCredentials(cups_array_t *credentials) _CUPS_PRIVATE; extern char *_httpDecodeURI(char *dst, const char *src, - size_t dstsize); -extern void _httpDisconnect(http_t *http); + size_t dstsize) _CUPS_PRIVATE; +extern void _httpDisconnect(http_t *http) _CUPS_PRIVATE; extern char *_httpEncodeURI(char *dst, const char *src, - size_t dstsize); -extern void _httpFreeCredentials(http_tls_credentials_t credentials); + size_t dstsize) _CUPS_PRIVATE; +extern void _httpFreeCredentials(http_tls_credentials_t credentials) _CUPS_PRIVATE; extern const char *_httpResolveURI(const char *uri, char *resolved_uri, size_t resolved_size, int options, int (*cb)(void *context), - void *context); -extern const char *_httpStatus(cups_lang_t *lang, http_status_t status); -extern void _httpTLSInitialize(void); -extern size_t _httpTLSPending(http_t *http); -extern int _httpTLSRead(http_t *http, char *buf, int len); -extern int _httpTLSSetCredentials(http_t *http); -extern void _httpTLSSetOptions(int options); -extern int _httpTLSStart(http_t *http); -extern void _httpTLSStop(http_t *http); -extern int _httpTLSWrite(http_t *http, const char *buf, int len); -extern int _httpUpdate(http_t *http, http_status_t *status); -extern int _httpWait(http_t *http, int msec, int usessl); + void *context) _CUPS_PRIVATE; +extern int _httpSetDigestAuthString(http_t *http, const char *nonce, const char *method, const char *resource) _CUPS_PRIVATE; +extern const char *_httpStatus(cups_lang_t *lang, http_status_t status) _CUPS_PRIVATE; +extern void _httpTLSInitialize(void) _CUPS_PRIVATE; +extern size_t _httpTLSPending(http_t *http) _CUPS_PRIVATE; +extern int _httpTLSRead(http_t *http, char *buf, int len) _CUPS_PRIVATE; +extern void _httpTLSSetOptions(int options, int min_version, int max_version) _CUPS_PRIVATE; +extern int _httpTLSStart(http_t *http) _CUPS_PRIVATE; +extern void _httpTLSStop(http_t *http) _CUPS_PRIVATE; +extern int _httpTLSWrite(http_t *http, const char *buf, int len) _CUPS_PRIVATE; +extern int _httpUpdate(http_t *http, http_status_t *status) _CUPS_PRIVATE; +extern int _httpWait(http_t *http, int msec, int usessl) _CUPS_PRIVATE; /* diff --git a/cups/http-support.c b/cups/http-support.c index 76dbb7d..6d86071 100644 --- a/cups/http-support.c +++ b/cups/http-support.c @@ -1,16 +1,11 @@ /* * HTTP support routines for CUPS. * - * Copyright 2007-2017 by Apple Inc. + * Copyright 2007-2018 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -18,15 +13,16 @@ */ #include "cups-private.h" +#include "debug-internal.h" #ifdef HAVE_DNSSD # include -# ifdef WIN32 +# ifdef _WIN32 # include # elif defined(HAVE_POLL) # include # else # include -# endif /* WIN32 */ +# endif /* _WIN32 */ #elif defined(HAVE_AVAHI) # include # include @@ -502,7 +498,6 @@ httpAssembleUUID(const char *server, /* I - Server name */ size_t bufsize) /* I - Size of buffer */ { char data[1024]; /* Source string for MD5 */ - _cups_md5_state_t md5state; /* MD5 state */ unsigned char md5sum[16]; /* MD5 digest/sum */ @@ -517,9 +512,7 @@ httpAssembleUUID(const char *server, /* I - Server name */ port, name ? name : server, number, (unsigned)CUPS_RAND() & 0xffff, (unsigned)CUPS_RAND() & 0xffff); - _cupsMD5Init(&md5state); - _cupsMD5Append(&md5state, (unsigned char *)data, (int)strlen(data)); - _cupsMD5Finish(&md5state, md5sum); + cupsHashData("md5", (unsigned char *)data, strlen(data), md5sum, sizeof(md5sum)); /* * Generate the UUID from the MD5... @@ -1035,7 +1028,7 @@ httpSeparateURI( *ptr = '\0'; - if (*uri != ':') + if (*uri != ':' || *scheme == '.' || !*scheme) { *scheme = '\0'; return (HTTP_URI_STATUS_BAD_SCHEME); @@ -1305,6 +1298,152 @@ httpSeparateURI( } +/* + * '_httpSetDigestAuthString()' - Calculate a Digest authentication response + * using the appropriate RFC 2068/2617/7616 + * algorithm. + */ + +int /* O - 1 on success, 0 on failure */ +_httpSetDigestAuthString( + http_t *http, /* I - HTTP connection */ + const char *nonce, /* I - Nonce value */ + const char *method, /* I - HTTP method */ + const char *resource) /* I - HTTP resource path */ +{ + char kd[65], /* Final MD5/SHA-256 digest */ + ha1[65], /* Hash of username:realm:password */ + ha2[65], /* Hash of method:request-uri */ + username[HTTP_MAX_VALUE], + /* username:password */ + *password, /* Pointer to password */ + temp[1024], /* Temporary string */ + digest[1024]; /* Digest auth data */ + unsigned char hash[32]; /* Hash buffer */ + size_t hashsize; /* Size of hash */ + + + DEBUG_printf(("2_httpSetDigestAuthString(http=%p, nonce=\"%s\", method=\"%s\", resource=\"%s\")", (void *)http, nonce, method, resource)); + + if (nonce && *nonce && strcmp(nonce, http->nonce)) + { + strlcpy(http->nonce, nonce, sizeof(http->nonce)); + + if (nonce == http->nextnonce) + http->nextnonce[0] = '\0'; + + http->nonce_count = 1; + } + else + http->nonce_count ++; + + strlcpy(username, http->userpass, sizeof(username)); + if ((password = strchr(username, ':')) != NULL) + *password++ = '\0'; + else + return (0); + + if (http->algorithm[0]) + { + /* + * Follow RFC 2617/7616... + */ + + int i; /* Looping var */ + char cnonce[65]; /* cnonce value */ + const char *hashalg; /* Hashing algorithm */ + + for (i = 0; i < 64; i ++) + cnonce[i] = "0123456789ABCDEF"[CUPS_RAND() & 15]; + cnonce[64] = '\0'; + + if (!_cups_strcasecmp(http->algorithm, "MD5")) + { + /* + * RFC 2617 Digest with MD5 + */ + + hashalg = "md5"; + } + else if (!_cups_strcasecmp(http->algorithm, "SHA-256")) + { + /* + * RFC 7616 Digest with SHA-256 + */ + + hashalg = "sha2-256"; + } + else + { + /* + * Some other algorithm we don't support, skip this one... + */ + + return (0); + } + + /* + * Calculate digest value... + */ + + /* H(A1) = H(username:realm:password) */ + snprintf(temp, sizeof(temp), "%s:%s:%s", username, http->realm, password); + hashsize = (size_t)cupsHashData(hashalg, (unsigned char *)temp, strlen(temp), hash, sizeof(hash)); + cupsHashString(hash, hashsize, ha1, sizeof(ha1)); + + /* H(A2) = H(method:uri) */ + snprintf(temp, sizeof(temp), "%s:%s", method, resource); + hashsize = (size_t)cupsHashData(hashalg, (unsigned char *)temp, strlen(temp), hash, sizeof(hash)); + cupsHashString(hash, hashsize, ha2, sizeof(ha2)); + + /* KD = H(H(A1):nonce:nc:cnonce:qop:H(A2)) */ + snprintf(temp, sizeof(temp), "%s:%s:%08x:%s:%s:%s", ha1, http->nonce, http->nonce_count, cnonce, "auth", ha2); + hashsize = (size_t)cupsHashData(hashalg, (unsigned char *)temp, strlen(temp), hash, sizeof(hash)); + cupsHashString(hash, hashsize, kd, sizeof(kd)); + + /* + * Pass the RFC 2617/7616 WWW-Authenticate header... + */ + + if (http->opaque[0]) + snprintf(digest, sizeof(digest), "username=\"%s\", realm=\"%s\", nonce=\"%s\", algorithm=%s, qop=auth, opaque=\"%s\", cnonce=\"%s\", nc=%08x, uri=\"%s\", response=\"%s\"", cupsUser(), http->realm, http->nonce, http->algorithm, http->opaque, cnonce, http->nonce_count, resource, kd); + else + snprintf(digest, sizeof(digest), "username=\"%s\", realm=\"%s\", nonce=\"%s\", algorithm=%s, qop=auth, cnonce=\"%s\", nc=%08x, uri=\"%s\", response=\"%s\"", username, http->realm, http->nonce, http->algorithm, cnonce, http->nonce_count, resource, kd); + } + else + { + /* + * Use old RFC 2069 Digest method... + */ + + /* H(A1) = H(username:realm:password) */ + snprintf(temp, sizeof(temp), "%s:%s:%s", username, http->realm, password); + hashsize = (size_t)cupsHashData("md5", (unsigned char *)temp, strlen(temp), hash, sizeof(hash)); + cupsHashString(hash, hashsize, ha1, sizeof(ha1)); + + /* H(A2) = H(method:uri) */ + snprintf(temp, sizeof(temp), "%s:%s", method, resource); + hashsize = (size_t)cupsHashData("md5", (unsigned char *)temp, strlen(temp), hash, sizeof(hash)); + cupsHashString(hash, hashsize, ha2, sizeof(ha2)); + + /* KD = H(H(A1):nonce:H(A2)) */ + snprintf(temp, sizeof(temp), "%s:%s:%s", ha1, http->nonce, ha2); + hashsize = (size_t)cupsHashData("md5", (unsigned char *)temp, strlen(temp), hash, sizeof(hash)); + cupsHashString(hash, hashsize, kd, sizeof(kd)); + + /* + * Pass the old RFC 2069 WWW-Authenticate header... + */ + + snprintf(digest, sizeof(digest), "username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"", username, http->realm, http->nonce, resource, kd); + } + + httpSetAuthString(http, "Digest", digest); + + return (1); +} + + /* * 'httpStateString()' - Return the string describing a HTTP state value. * @@ -1360,6 +1499,9 @@ _httpStatus(cups_lang_t *lang, /* I - Language */ case HTTP_STATUS_MOVED_PERMANENTLY : s = _("Moved Permanently"); break; + case HTTP_STATUS_FOUND : + s = _("Found"); + break; case HTTP_STATUS_SEE_OTHER : s = _("See Other"); break; @@ -1622,9 +1764,6 @@ _httpResolveURI( _http_uribuf_t uribuf; /* URI buffer */ int offline = 0; /* offline-report state set? */ # ifdef HAVE_DNSSD -# ifdef WIN32 -# pragma comment(lib, "dnssd.lib") -# endif /* WIN32 */ DNSServiceRef ref, /* DNS-SD master service reference */ domainref = NULL,/* DNS-SD service reference for domain */ ippref = NULL, /* DNS-SD service reference for network IPP */ @@ -1753,11 +1892,11 @@ _httpResolveURI( FD_ZERO(&input_set); FD_SET(DNSServiceRefSockFD(ref), &input_set); -# ifdef WIN32 +# ifdef _WIN32 stimeout.tv_sec = (long)timeout; # else stimeout.tv_sec = timeout; -# endif /* WIN32 */ +# endif /* _WIN32 */ stimeout.tv_usec = 0; fds = select(DNSServiceRefSockFD(ref)+1, &input_set, NULL, NULL, diff --git a/cups/http.c b/cups/http.c index 61b88c9..fbb1bf1 100644 --- a/cups/http.c +++ b/cups/http.c @@ -1,19 +1,14 @@ /* * HTTP routines for CUPS. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products, all rights reserved. * * This file contains Kerberos support code, copyright 2006 by * Jelmer Vernooij. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -21,24 +16,29 @@ */ #include "cups-private.h" +#include "debug-internal.h" #include #include -#ifdef WIN32 +#ifdef _WIN32 # include #else # include # include # include -#endif /* WIN32 */ +#endif /* _WIN32 */ #ifdef HAVE_POLL # include #endif /* HAVE_POLL */ +# ifdef HAVE_LIBZ +# include +# endif /* HAVE_LIBZ */ /* * Local functions... */ +static void http_add_field(http_t *http, http_field_t field, const char *value, int append); #ifdef HAVE_LIBZ static void http_content_coding_finish(http_t *http); static void http_content_coding_start(http_t *http, @@ -105,7 +105,8 @@ static const char * const http_fields[] = "WWW-Authenticate", "Accept-Encoding", "Allow", - "Server" + "Server", + "Authentication-Info" }; @@ -287,11 +288,22 @@ httpClearCookie(http_t *http) /* I - HTTP connection */ void httpClearFields(http_t *http) /* I - HTTP connection */ { + http_field_t field; /* Current field */ + + DEBUG_printf(("httpClearFields(http=%p)", (void *)http)); if (http) { - memset(http->fields, 0, sizeof(http->fields)); + memset(http->_fields, 0, sizeof(http->fields)); + + for (field = HTTP_FIELD_ACCEPT_LANGUAGE; field < HTTP_FIELD_MAX; field ++) + { + if (http->fields[field] && http->fields[field] != http->_fields[field]) + free(http->fields[field]); + + http->fields[field] = NULL; + } if (http->mode == _HTTP_MODE_CLIENT) { @@ -301,30 +313,6 @@ httpClearFields(http_t *http) /* I - HTTP connection */ httpSetField(http, HTTP_FIELD_HOST, http->hostname); } - if (http->field_authorization) - { - free(http->field_authorization); - http->field_authorization = NULL; - } - - if (http->accept_encoding) - { - _cupsStrFree(http->accept_encoding); - http->accept_encoding = NULL; - } - - if (http->allow) - { - _cupsStrFree(http->allow); - http->allow = NULL; - } - - if (http->server) - { - _cupsStrFree(http->server); - http->server = NULL; - } - http->expect = (http_status_t)0; } } @@ -815,7 +803,7 @@ const char * /* O - Content-Coding value or httpGetContentEncoding(http_t *http) /* I - HTTP connection */ { #ifdef HAVE_LIBZ - if (http && http->accept_encoding) + if (http && http->fields[HTTP_FIELD_ACCEPT_ENCODING]) { int i; /* Looping var */ char temp[HTTP_MAX_VALUE], /* Copy of Accepts-Encoding value */ @@ -831,7 +819,7 @@ httpGetContentEncoding(http_t *http) /* I - HTTP connection */ "x-gzip" }; - strlcpy(temp, http->accept_encoding, sizeof(temp)); + strlcpy(temp, http->fields[HTTP_FIELD_ACCEPT_ENCODING], sizeof(temp)); for (start = temp; *start; start = end) { @@ -957,32 +945,10 @@ httpGetField(http_t *http, /* I - HTTP connection */ { if (!http || field <= HTTP_FIELD_UNKNOWN || field >= HTTP_FIELD_MAX) return (NULL); - - switch (field) - { - case HTTP_FIELD_ACCEPT_ENCODING : - return (http->accept_encoding); - - case HTTP_FIELD_ALLOW : - return (http->allow); - - case HTTP_FIELD_SERVER : - return (http->server); - - case HTTP_FIELD_AUTHORIZATION : - if (http->field_authorization) - { - /* - * Special case for WWW-Authenticate: as its contents can be - * longer than HTTP_MAX_VALUE... - */ - - return (http->field_authorization); - } - - default : - return (http->fields[field]); - } + else if (http->fields[field]) + return (http->fields[field]); + else + return (""); } @@ -1048,7 +1014,7 @@ httpGetLength2(http_t *http) /* I - HTTP connection */ if (!http) return (-1); - if (!_cups_strcasecmp(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked")) + if (http->fields[HTTP_FIELD_TRANSFER_ENCODING] && !_cups_strcasecmp(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked")) { DEBUG_puts("4httpGetLength2: chunked request!"); remaining = 0; @@ -1063,7 +1029,7 @@ httpGetLength2(http_t *http) /* I - HTTP connection */ * after the transfer is complete... */ - if (!http->fields[HTTP_FIELD_CONTENT_LENGTH][0]) + if (!http->fields[HTTP_FIELD_CONTENT_LENGTH] || !http->fields[HTTP_FIELD_CONTENT_LENGTH][0]) { /* * Default content length is 0 for errors and certain types of operations, @@ -1183,11 +1149,11 @@ httpGets(char *line, /* I - Line to read into */ * Pre-load the buffer as needed... */ -#ifdef WIN32 +#ifdef _WIN32 WSASetLastError(0); #else errno = 0; -#endif /* WIN32 */ +#endif /* _WIN32 */ while (http->used == 0) { @@ -1201,11 +1167,11 @@ httpGets(char *line, /* I - Line to read into */ continue; DEBUG_puts("3httpGets: Timed out!"); -#ifdef WIN32 +#ifdef _WIN32 http->error = WSAETIMEDOUT; #else http->error = ETIMEDOUT; -#endif /* WIN32 */ +#endif /* _WIN32 */ return (NULL); } @@ -1219,7 +1185,7 @@ httpGets(char *line, /* I - Line to read into */ * Nope, can't get a line this time... */ -#ifdef WIN32 +#ifdef _WIN32 DEBUG_printf(("3httpGets: recv() error %d!", WSAGetLastError())); if (WSAGetLastError() == WSAEINTR) @@ -1256,7 +1222,7 @@ httpGets(char *line, /* I - Line to read into */ http->error = errno; continue; } -#endif /* WIN32 */ +#endif /* _WIN32 */ return (NULL); } @@ -1379,8 +1345,11 @@ httpGetSubField2(http_t *http, /* I - HTTP connection */ DEBUG_printf(("2httpGetSubField2(http=%p, field=%d, name=\"%s\", value=%p, valuelen=%d)", (void *)http, field, name, (void *)value, valuelen)); + if (value) + *value = '\0'; + if (!http || !name || !value || valuelen < 2 || - field <= HTTP_FIELD_UNKNOWN || field >= HTTP_FIELD_MAX) + field <= HTTP_FIELD_UNKNOWN || field >= HTTP_FIELD_MAX || !http->fields[field]) return (NULL); end = value + valuelen - 1; @@ -1523,9 +1492,9 @@ void httpInitialize(void) { static int initialized = 0; /* Have we been called before? */ -#ifdef WIN32 +#ifdef _WIN32 WSADATA winsockdata; /* WinSock data */ -#endif /* WIN32 */ +#endif /* _WIN32 */ _cupsGlobalLock(); @@ -1535,7 +1504,7 @@ httpInitialize(void) return; } -#ifdef WIN32 +#ifdef _WIN32 WSAStartup(MAKEWORD(2,2), &winsockdata); #elif !defined(SO_NOSIGPIPE) @@ -1557,7 +1526,7 @@ httpInitialize(void) # else signal(SIGPIPE, SIG_IGN); # endif /* !SO_NOSIGPIPE */ -#endif /* WIN32 */ +#endif /* _WIN32 */ # ifdef HAVE_SSL _httpTLSInitialize(); @@ -1713,7 +1682,7 @@ httpPeek(http_t *http, /* I - HTTP connection */ #ifdef HAVE_LIBZ if (http->used == 0 && (http->coding == _HTTP_CODING_IDENTITY || - (http->coding >= _HTTP_CODING_GUNZIP && http->stream.avail_in == 0))) + (http->coding >= _HTTP_CODING_GUNZIP && ((z_stream *)http->stream)->avail_in == 0))) #else if (http->used == 0) #endif /* HAVE_LIBZ */ @@ -1762,16 +1731,16 @@ httpPeek(http_t *http, /* I - HTTP connection */ int zerr; /* Decompressor error */ z_stream stream; /* Copy of decompressor stream */ - if (http->used > 0 && http->stream.avail_in < HTTP_MAX_BUFFER) + if (http->used > 0 && ((z_stream *)http->stream)->avail_in < HTTP_MAX_BUFFER) { - size_t buflen = buflen = HTTP_MAX_BUFFER - http->stream.avail_in; + size_t buflen = buflen = HTTP_MAX_BUFFER - ((z_stream *)http->stream)->avail_in; /* Number of bytes to copy */ - if (http->stream.avail_in > 0 && - http->stream.next_in > http->sbuffer) - memmove(http->sbuffer, http->stream.next_in, http->stream.avail_in); + if (((z_stream *)http->stream)->avail_in > 0 && + ((z_stream *)http->stream)->next_in > http->sbuffer) + memmove(http->sbuffer, ((z_stream *)http->stream)->next_in, ((z_stream *)http->stream)->avail_in); - http->stream.next_in = http->sbuffer; + ((z_stream *)http->stream)->next_in = http->sbuffer; if (buflen > (size_t)http->data_remaining) buflen = (size_t)http->data_remaining; @@ -1782,8 +1751,8 @@ httpPeek(http_t *http, /* I - HTTP connection */ DEBUG_printf(("1httpPeek: Copying %d more bytes of data into " "decompression buffer.", (int)buflen)); - memcpy(http->sbuffer + http->stream.avail_in, http->buffer, buflen); - http->stream.avail_in += buflen; + memcpy(http->sbuffer + ((z_stream *)http->stream)->avail_in, http->buffer, buflen); + ((z_stream *)http->stream)->avail_in += buflen; http->used -= (int)buflen; http->data_remaining -= (off_t)buflen; @@ -1792,9 +1761,9 @@ httpPeek(http_t *http, /* I - HTTP connection */ } DEBUG_printf(("2httpPeek: length=%d, avail_in=%d", (int)length, - (int)http->stream.avail_in)); + (int)((z_stream *)http->stream)->avail_in)); - if (inflateCopy(&stream, &(http->stream)) != Z_OK) + if (inflateCopy(&stream, (z_stream *)http->stream) != Z_OK) { DEBUG_puts("2httpPeek: Unable to copy decompressor stream."); http->error = ENOMEM; @@ -1811,14 +1780,14 @@ httpPeek(http_t *http, /* I - HTTP connection */ { DEBUG_printf(("2httpPeek: zerr=%d", zerr)); #ifdef DEBUG - http_debug_hex("2httpPeek", (char *)http->sbuffer, (int)http->stream.avail_in); + http_debug_hex("2httpPeek", (char *)http->sbuffer, (int)((z_stream *)http->stream)->avail_in); #endif /* DEBUG */ http->error = EIO; return (-1); } - bytes = (ssize_t)(length - http->stream.avail_out); + bytes = (ssize_t)(length - ((z_stream *)http->stream)->avail_out); # else DEBUG_puts("2httpPeek: No inflateCopy on this platform, httpPeek does not " @@ -1845,7 +1814,7 @@ httpPeek(http_t *http, /* I - HTTP connection */ if (bytes < 0) { -#ifdef WIN32 +#ifdef _WIN32 if (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEWOULDBLOCK) bytes = 0; else @@ -1855,7 +1824,7 @@ httpPeek(http_t *http, /* I - HTTP connection */ bytes = 0; else http->error = errno; -#endif /* WIN32 */ +#endif /* _WIN32 */ } else if (bytes == 0) { @@ -1891,7 +1860,7 @@ httpPrintf(http_t *http, /* I - HTTP connection */ ...) /* I - Additional args as needed */ { ssize_t bytes; /* Number of bytes to write */ - char buf[16384]; /* Buffer for formatted string */ + char buf[65536]; /* Buffer for formatted string */ va_list ap; /* Variable argument pointer */ @@ -1903,7 +1872,12 @@ httpPrintf(http_t *http, /* I - HTTP connection */ DEBUG_printf(("3httpPrintf: (" CUPS_LLFMT " bytes) %s", CUPS_LLCAST bytes, buf)); - if (http->data_encoding == HTTP_ENCODING_FIELDS) + if (bytes > (ssize_t)(sizeof(buf) - 1)) + { + http->error = ENOMEM; + return (-1); + } + else if (http->data_encoding == HTTP_ENCODING_FIELDS) return ((int)httpWrite2(http, buf, (size_t)bytes)); else { @@ -1985,31 +1959,31 @@ httpRead2(http_t *http, /* I - HTTP connection */ { do { - if (http->stream.avail_in > 0) + if (((z_stream *)http->stream)->avail_in > 0) { int zerr; /* Decompressor error */ DEBUG_printf(("2httpRead2: avail_in=%d, avail_out=%d", - (int)http->stream.avail_in, (int)length)); + (int)((z_stream *)http->stream)->avail_in, (int)length)); - http->stream.next_out = (Bytef *)buffer; - http->stream.avail_out = (uInt)length; + ((z_stream *)http->stream)->next_out = (Bytef *)buffer; + ((z_stream *)http->stream)->avail_out = (uInt)length; - if ((zerr = inflate(&(http->stream), Z_SYNC_FLUSH)) < Z_OK) + if ((zerr = inflate((z_stream *)http->stream, Z_SYNC_FLUSH)) < Z_OK) { DEBUG_printf(("2httpRead2: zerr=%d", zerr)); #ifdef DEBUG - http_debug_hex("2httpRead2", (char *)http->sbuffer, (int)http->stream.avail_in); + http_debug_hex("2httpRead2", (char *)http->sbuffer, (int)((z_stream *)http->stream)->avail_in); #endif /* DEBUG */ http->error = EIO; return (-1); } - bytes = (ssize_t)(length - http->stream.avail_out); + bytes = (ssize_t)(length - ((z_stream *)http->stream)->avail_out); DEBUG_printf(("2httpRead2: avail_in=%d, avail_out=%d, bytes=%d", - http->stream.avail_in, http->stream.avail_out, + ((z_stream *)http->stream)->avail_in, ((z_stream *)http->stream)->avail_out, (int)bytes)); } else @@ -2017,16 +1991,16 @@ httpRead2(http_t *http, /* I - HTTP connection */ if (bytes == 0) { - ssize_t buflen = HTTP_MAX_BUFFER - (ssize_t)http->stream.avail_in; + ssize_t buflen = HTTP_MAX_BUFFER - (ssize_t)((z_stream *)http->stream)->avail_in; /* Additional bytes for buffer */ if (buflen > 0) { - if (http->stream.avail_in > 0 && - http->stream.next_in > http->sbuffer) - memmove(http->sbuffer, http->stream.next_in, http->stream.avail_in); + if (((z_stream *)http->stream)->avail_in > 0 && + ((z_stream *)http->stream)->next_in > http->sbuffer) + memmove(http->sbuffer, ((z_stream *)http->stream)->next_in, ((z_stream *)http->stream)->avail_in); - http->stream.next_in = http->sbuffer; + ((z_stream *)http->stream)->next_in = http->sbuffer; DEBUG_printf(("1httpRead2: Reading up to %d more bytes of data into " "decompression buffer.", (int)buflen)); @@ -2036,10 +2010,10 @@ httpRead2(http_t *http, /* I - HTTP connection */ if (buflen > http->data_remaining) buflen = (ssize_t)http->data_remaining; - bytes = http_read_buffered(http, (char *)http->sbuffer + http->stream.avail_in, (size_t)buflen); + bytes = http_read_buffered(http, (char *)http->sbuffer + ((z_stream *)http->stream)->avail_in, (size_t)buflen); } else if (http->data_encoding == HTTP_ENCODING_CHUNKED) - bytes = http_read_chunk(http, (char *)http->sbuffer + http->stream.avail_in, (size_t)buflen); + bytes = http_read_chunk(http, (char *)http->sbuffer + ((z_stream *)http->stream)->avail_in, (size_t)buflen); else bytes = 0; @@ -2052,7 +2026,7 @@ httpRead2(http_t *http, /* I - HTTP connection */ "decompression buffer.", CUPS_LLCAST bytes)); http->data_remaining -= bytes; - http->stream.avail_in += (uInt)bytes; + ((z_stream *)http->stream)->avail_in += (uInt)bytes; if (http->data_remaining <= 0 && http->data_encoding == HTTP_ENCODING_CHUNKED) @@ -2131,7 +2105,7 @@ httpRead2(http_t *http, /* I - HTTP connection */ if ( #ifdef HAVE_LIBZ (http->coding == _HTTP_CODING_IDENTITY || - (http->coding >= _HTTP_CODING_GUNZIP && http->stream.avail_in == 0)) && + (http->coding >= _HTTP_CODING_GUNZIP && ((z_stream *)http->stream)->avail_in == 0)) && #endif /* HAVE_LIBZ */ ((http->data_remaining <= 0 && http->data_encoding == HTTP_ENCODING_LENGTH) || @@ -2416,11 +2390,11 @@ httpReconnect2(http_t *http, /* I - HTTP connection */ * Unable to connect... */ -#ifdef WIN32 +#ifdef _WIN32 http->error = WSAGetLastError(); #else http->error = errno; -#endif /* WIN32 */ +#endif /* _WIN32 */ http->status = HTTP_STATUS_ERROR; DEBUG_printf(("1httpReconnect2: httpAddrConnect failed: %s", @@ -2588,36 +2562,13 @@ httpSetDefaultField(http_t *http, /* I - HTTP connection */ { DEBUG_printf(("httpSetDefaultField(http=%p, field=%d(%s), value=\"%s\")", (void *)http, field, http_fields[field], value)); - if (!http) + if (!http || field <= HTTP_FIELD_UNKNOWN || field >= HTTP_FIELD_MAX) return; - switch (field) - { - case HTTP_FIELD_ACCEPT_ENCODING : - if (http->default_accept_encoding) - _cupsStrFree(http->default_accept_encoding); + if (http->default_fields[field]) + free(http->default_fields[field]); - http->default_accept_encoding = value ? _cupsStrAlloc(value) : NULL; - break; - - case HTTP_FIELD_SERVER : - if (http->default_server) - _cupsStrFree(http->default_server); - - http->default_server = value ? _cupsStrAlloc(value) : NULL; - break; - - case HTTP_FIELD_USER_AGENT : - if (http->default_user_agent) - _cupsStrFree(http->default_user_agent); - - http->default_user_agent = value ? _cupsStrAlloc(value) : NULL; - break; - - default : - DEBUG_puts("1httpSetDefaultField: Ignored."); - break; - } + http->default_fields[field] = value ? strdup(value) : NULL; } @@ -2653,111 +2604,10 @@ httpSetField(http_t *http, /* I - HTTP connection */ { DEBUG_printf(("httpSetField(http=%p, field=%d(%s), value=\"%s\")", (void *)http, field, http_fields[field], value)); - if (http == NULL || - field < HTTP_FIELD_ACCEPT_LANGUAGE || - field >= HTTP_FIELD_MAX || - value == NULL) + if (!http || field <= HTTP_FIELD_UNKNOWN || field >= HTTP_FIELD_MAX || !value) return; - switch (field) - { - case HTTP_FIELD_ACCEPT_ENCODING : - if (http->accept_encoding) - _cupsStrFree(http->accept_encoding); - - http->accept_encoding = _cupsStrAlloc(value); - break; - - case HTTP_FIELD_ALLOW : - if (http->allow) - _cupsStrFree(http->allow); - - http->allow = _cupsStrAlloc(value); - break; - - case HTTP_FIELD_SERVER : - if (http->server) - _cupsStrFree(http->server); - - http->server = _cupsStrAlloc(value); - break; - - case HTTP_FIELD_WWW_AUTHENTICATE : - /* CUPS STR #4503 - don't override WWW-Authenticate for unknown auth schemes */ - if (http->fields[HTTP_FIELD_WWW_AUTHENTICATE][0] && - _cups_strncasecmp(value, "Basic ", 6) && - _cups_strncasecmp(value, "Digest ", 7) && - _cups_strncasecmp(value, "Negotiate ", 10)) - { - DEBUG_printf(("1httpSetField: Ignoring unknown auth scheme in \"%s\".", value)); - return; - } - - /* Fall through to copy */ - - default : - strlcpy(http->fields[field], value, HTTP_MAX_VALUE); - break; - } - - if (field == HTTP_FIELD_AUTHORIZATION) - { - /* - * Special case for Authorization: as its contents can be - * longer than HTTP_MAX_VALUE - */ - - if (http->field_authorization) - free(http->field_authorization); - - http->field_authorization = strdup(value); - } - else if (field == HTTP_FIELD_HOST) - { - /* - * Special-case for Host: as we don't want a trailing "." on the hostname and - * need to bracket IPv6 numeric addresses. - */ - - char *ptr = strchr(value, ':'); - - if (value[0] != '[' && ptr && strchr(ptr + 1, ':')) - { - /* - * Bracket IPv6 numeric addresses... - * - * This is slightly inefficient (basically copying twice), but is an edge - * case and not worth optimizing... - */ - - snprintf(http->fields[HTTP_FIELD_HOST], - sizeof(http->fields[HTTP_FIELD_HOST]), "[%s]", value); - } - else - { - /* - * Check for a trailing dot on the hostname... - */ - - ptr = http->fields[HTTP_FIELD_HOST]; - - if (*ptr) - { - ptr += strlen(ptr) - 1; - - if (*ptr == '.') - *ptr = '\0'; - } - } - } -#ifdef HAVE_LIBZ - else if (field == HTTP_FIELD_CONTENT_ENCODING && - http->data_encoding != HTTP_ENCODING_FIELDS) - { - DEBUG_puts("1httpSetField: Calling http_content_coding_start."); - http_content_coding_start(http, value); - } -#endif /* HAVE_LIBZ */ + http_add_field(http, field, value, 0); } @@ -2794,15 +2644,17 @@ httpSetLength(http_t *http, /* I - HTTP connection */ if (!length) { - strlcpy(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked", - HTTP_MAX_VALUE); - http->fields[HTTP_FIELD_CONTENT_LENGTH][0] = '\0'; + httpSetField(http, HTTP_FIELD_TRANSFER_ENCODING, "chunked"); + httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, ""); } else { - http->fields[HTTP_FIELD_TRANSFER_ENCODING][0] = '\0'; - snprintf(http->fields[HTTP_FIELD_CONTENT_LENGTH], HTTP_MAX_VALUE, - CUPS_LLFMT, CUPS_LLCAST length); + char len[32]; /* Length string */ + + + snprintf(len, sizeof(len), CUPS_LLFMT, CUPS_LLCAST length); + httpSetField(http, HTTP_FIELD_TRANSFER_ENCODING, ""); + httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, len); } } @@ -2855,11 +2707,11 @@ httpShutdown(http_t *http) /* I - HTTP connection */ _httpTLSStop(http); #endif /* HAVE_SSL */ -#ifdef WIN32 +#ifdef _WIN32 shutdown(http->fd, SD_RECEIVE); /* Microsoft-ism... */ #else shutdown(http->fd, SHUT_RD); -#endif /* WIN32 */ +#endif /* _WIN32 */ } @@ -3035,7 +2887,12 @@ _httpUpdate(http_t *http, /* I - HTTP connection */ httpSetCookie(http, value); } else if ((field = httpFieldValue(line)) != HTTP_FIELD_UNKNOWN) - httpSetField(http, field, value); + { + http_add_field(http, field, value, 1); + + if (field == HTTP_FIELD_AUTHENTICATION_INFO) + httpGetSubField2(http, HTTP_FIELD_AUTHENTICATION_INFO, "nextnonce", http->nextnonce, (int)sizeof(http->nextnonce)); + } #ifdef DEBUG else DEBUG_printf(("1_httpUpdate: unknown field %s seen!", line)); @@ -3188,12 +3045,12 @@ _httpWait(http_t *http, /* I - HTTP connection */ DEBUG_printf(("6_httpWait: select() returned %d...", nfds)); } -# ifdef WIN32 +# ifdef _WIN32 while (nfds < 0 && (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEWOULDBLOCK)); # else while (nfds < 0 && (errno == EINTR || errno == EAGAIN)); -# endif /* WIN32 */ +# endif /* _WIN32 */ #endif /* HAVE_POLL */ DEBUG_printf(("5_httpWait: returning with nfds=%d, errno=%d...", nfds, @@ -3229,7 +3086,7 @@ httpWait(http_t *http, /* I - HTTP connection */ } #ifdef HAVE_LIBZ - if (http->coding >= _HTTP_CODING_GUNZIP && http->stream.avail_in > 0) + if (http->coding >= _HTTP_CODING_GUNZIP && ((z_stream *)http->stream)->avail_in > 0) { DEBUG_puts("3httpWait: Returning 1 since there is buffered data ready."); return (1); @@ -3325,17 +3182,17 @@ httpWrite2(http_t *http, /* I - HTTP connection */ size_t slen; /* Bytes to write */ ssize_t sret; /* Bytes written */ - http->stream.next_in = (Bytef *)buffer; - http->stream.avail_in = (uInt)length; + ((z_stream *)http->stream)->next_in = (Bytef *)buffer; + ((z_stream *)http->stream)->avail_in = (uInt)length; - while (deflate(&(http->stream), Z_NO_FLUSH) == Z_OK) + while (deflate((z_stream *)http->stream, Z_NO_FLUSH) == Z_OK) { - DEBUG_printf(("1httpWrite2: avail_out=%d", http->stream.avail_out)); + DEBUG_printf(("1httpWrite2: avail_out=%d", ((z_stream *)http->stream)->avail_out)); - if (http->stream.avail_out > 0) + if (((z_stream *)http->stream)->avail_out > 0) continue; - slen = _HTTP_MAX_SBUFFER - http->stream.avail_out; + slen = _HTTP_MAX_SBUFFER - ((z_stream *)http->stream)->avail_out; DEBUG_printf(("1httpWrite2: Writing intermediate chunk, len=%d", (int)slen)); @@ -3352,8 +3209,8 @@ httpWrite2(http_t *http, /* I - HTTP connection */ return (-1); } - http->stream.next_out = (Bytef *)http->sbuffer; - http->stream.avail_out = (uInt)_HTTP_MAX_SBUFFER; + ((z_stream *)http->stream)->next_out = (Bytef *)http->sbuffer; + ((z_stream *)http->stream)->avail_out = (uInt)_HTTP_MAX_SBUFFER; } bytes = (ssize_t)length; @@ -3495,7 +3352,7 @@ httpWriteResponse(http_t *http, /* I - HTTP connection */ * Set the various standard fields if they aren't already... */ - if (!http->fields[HTTP_FIELD_DATE][0]) + if (!http->fields[HTTP_FIELD_DATE]) httpSetField(http, HTTP_FIELD_DATE, httpGetDateString(time(NULL))); if (status >= HTTP_STATUS_BAD_REQUEST && http->keep_alive) @@ -3506,7 +3363,7 @@ httpWriteResponse(http_t *http, /* I - HTTP connection */ if (http->version == HTTP_VERSION_1_1) { - if (!http->fields[HTTP_FIELD_CONNECTION][0]) + if (!http->fields[HTTP_FIELD_CONNECTION]) { if (http->keep_alive) httpSetField(http, HTTP_FIELD_CONNECTION, "Keep-Alive"); @@ -3514,7 +3371,7 @@ httpWriteResponse(http_t *http, /* I - HTTP connection */ httpSetField(http, HTTP_FIELD_CONNECTION, "close"); } - if (http->keep_alive && !http->fields[HTTP_FIELD_KEEP_ALIVE][0]) + if (http->keep_alive && !http->fields[HTTP_FIELD_KEEP_ALIVE]) httpSetField(http, HTTP_FIELD_KEEP_ALIVE, "timeout=10"); } @@ -3522,28 +3379,26 @@ httpWriteResponse(http_t *http, /* I - HTTP connection */ if (status == HTTP_STATUS_UPGRADE_REQUIRED || status == HTTP_STATUS_SWITCHING_PROTOCOLS) { - if (!http->fields[HTTP_FIELD_CONNECTION][0]) + if (!http->fields[HTTP_FIELD_CONNECTION]) httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade"); - if (!http->fields[HTTP_FIELD_UPGRADE][0]) + if (!http->fields[HTTP_FIELD_UPGRADE]) httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2,TLS/1.1,TLS/1.0"); - if (!http->fields[HTTP_FIELD_CONTENT_LENGTH][0]) + if (!http->fields[HTTP_FIELD_CONTENT_LENGTH]) httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, "0"); } #endif /* HAVE_SSL */ - if (!http->server) - httpSetField(http, HTTP_FIELD_SERVER, - http->default_server ? http->default_server : CUPS_MINIMAL); + if (!http->fields[HTTP_FIELD_SERVER]) + httpSetField(http, HTTP_FIELD_SERVER, http->default_fields[HTTP_FIELD_SERVER] ? http->default_fields[HTTP_FIELD_SERVER] : CUPS_MINIMAL); /* * Set the Accept-Encoding field if it isn't already... */ - if (!http->accept_encoding) - httpSetField(http, HTTP_FIELD_ACCEPT_ENCODING, - http->default_accept_encoding ? http->default_accept_encoding : + if (!http->fields[HTTP_FIELD_ACCEPT_ENCODING]) + httpSetField(http, HTTP_FIELD_ACCEPT_ENCODING, http->default_fields[HTTP_FIELD_ACCEPT_ENCODING] ? http->default_fields[HTTP_FIELD_ACCEPT_ENCODING] : #ifdef HAVE_LIBZ "gzip, deflate, identity"); #else @@ -3558,8 +3413,7 @@ httpWriteResponse(http_t *http, /* I - HTTP connection */ old_remaining = http->data_remaining; http->data_encoding = HTTP_ENCODING_FIELDS; - if (httpPrintf(http, "HTTP/%d.%d %d %s\r\n", http->version / 100, - http->version % 100, (int)status, httpStatus(status)) < 0) + if (httpPrintf(http, "HTTP/%d.%d %d %s\r\n", http->version / 100, http->version % 100, (int)status, httpStatus(status)) < 0) { http->status = HTTP_STATUS_ERROR; return (-1); @@ -3689,6 +3543,149 @@ httpWriteResponse(http_t *http, /* I - HTTP connection */ } +/* + * 'http_add_field()' - Add a value for a HTTP field, appending if needed. + */ + +static void +http_add_field(http_t *http, /* I - HTTP connection */ + http_field_t field, /* I - HTTP field */ + const char *value, /* I - Value string */ + int append) /* I - Append value? */ +{ + char temp[1024]; /* Temporary value string */ + size_t fieldlen, /* Length of existing value */ + valuelen, /* Length of value string */ + total; /* Total length of string */ + + + if (field == HTTP_FIELD_HOST) + { + /* + * Special-case for Host: as we don't want a trailing "." on the hostname and + * need to bracket IPv6 numeric addresses. + */ + + char *ptr = strchr(value, ':'); + + if (value[0] != '[' && ptr && strchr(ptr + 1, ':')) + { + /* + * Bracket IPv6 numeric addresses... + * + * This is slightly inefficient (basically copying twice), but is an edge + * case and not worth optimizing... + */ + + snprintf(temp, sizeof(temp), "[%s]", value); + value = temp; + } + else if (*value) + { + /* + * Check for a trailing dot on the hostname... + */ + + strlcpy(temp, value, sizeof(temp)); + value = temp; + ptr = temp + strlen(temp) - 1; + + if (*ptr == '.') + *ptr = '\0'; + } + } + + if (append && field != HTTP_FIELD_ACCEPT_ENCODING && field != HTTP_FIELD_ACCEPT_LANGUAGE && field != HTTP_FIELD_ACCEPT_RANGES && field != HTTP_FIELD_ALLOW && field != HTTP_FIELD_LINK && field != HTTP_FIELD_TRANSFER_ENCODING && field != HTTP_FIELD_UPGRADE && field != HTTP_FIELD_WWW_AUTHENTICATE) + append = 0; + + if (!append && http->fields[field]) + { + if (http->fields[field] != http->_fields[field]) + free(http->fields[field]); + + http->fields[field] = NULL; + } + + valuelen = strlen(value); + + if (!valuelen) + { + http->_fields[field][0] = '\0'; + return; + } + + if (http->fields[field]) + { + fieldlen = strlen(http->fields[field]); + total = fieldlen + 2 + valuelen; + } + else + { + fieldlen = 0; + total = valuelen; + } + + if (total < HTTP_MAX_VALUE && field < HTTP_FIELD_ACCEPT_ENCODING) + { + /* + * Copy short values to legacy char arrays (maintained for binary + * compatibility with CUPS 1.2.x and earlier applications...) + */ + + if (fieldlen) + { + char combined[HTTP_MAX_VALUE]; + /* Combined value string */ + + snprintf(combined, sizeof(combined), "%s, %s", http->_fields[field], value); + value = combined; + } + + strlcpy(http->_fields[field], value, sizeof(http->_fields[field])); + http->fields[field] = http->_fields[field]; + } + else if (fieldlen) + { + /* + * Expand the field value... + */ + + char *combined; /* New value string */ + + if (http->fields[field] == http->_fields[field]) + { + if ((combined = malloc(total + 1)) != NULL) + { + http->fields[field] = combined; + snprintf(combined, total + 1, "%s, %s", http->_fields[field], value); + } + } + else if ((combined = realloc(http->fields[field], total + 1)) != NULL) + { + http->fields[field] = combined; + strlcat(combined, ", ", total + 1); + strlcat(combined, value, total + 1); + } + } + else + { + /* + * Allocate the field value... + */ + + http->fields[field] = strdup(value); + } + +#ifdef HAVE_LIBZ + if (field == HTTP_FIELD_CONTENT_ENCODING && http->data_encoding != HTTP_ENCODING_FIELDS) + { + DEBUG_puts("1httpSetField: Calling http_content_coding_start."); + http_content_coding_start(http, value); + } +#endif /* HAVE_LIBZ */ +} + + #ifdef HAVE_LIBZ /* * 'http_content_coding_finish()' - Finish doing any content encoding. @@ -3710,13 +3707,13 @@ http_content_coding_finish( { case _HTTP_CODING_DEFLATE : case _HTTP_CODING_GZIP : - http->stream.next_in = dummy; - http->stream.avail_in = 0; + ((z_stream *)http->stream)->next_in = dummy; + ((z_stream *)http->stream)->avail_in = 0; do { - zerr = deflate(&(http->stream), Z_FINISH); - bytes = _HTTP_MAX_SBUFFER - http->stream.avail_out; + zerr = deflate((z_stream *)http->stream, Z_FINISH); + bytes = _HTTP_MAX_SBUFFER - ((z_stream *)http->stream)->avail_out; if (bytes > 0) { @@ -3728,15 +3725,18 @@ http_content_coding_finish( http_write(http, (char *)http->sbuffer, bytes); } - http->stream.next_out = (Bytef *)http->sbuffer; - http->stream.avail_out = (uInt)_HTTP_MAX_SBUFFER; + ((z_stream *)http->stream)->next_out = (Bytef *)http->sbuffer; + ((z_stream *)http->stream)->avail_out = (uInt)_HTTP_MAX_SBUFFER; } while (zerr == Z_OK); - deflateEnd(&(http->stream)); + deflateEnd((z_stream *)http->stream); free(http->sbuffer); + free(http->stream); + http->sbuffer = NULL; + http->stream = NULL; if (http->wused) httpFlushWrite(http); @@ -3744,9 +3744,13 @@ http_content_coding_finish( case _HTTP_CODING_INFLATE : case _HTTP_CODING_GUNZIP : - inflateEnd(&(http->stream)); + inflateEnd((z_stream *)http->stream); + free(http->sbuffer); + free(http->stream); + http->sbuffer = NULL; + http->stream = NULL; break; default : @@ -3816,8 +3820,6 @@ http_content_coding_start( return; } - memset(&(http->stream), 0, sizeof(http->stream)); - switch (coding) { case _HTTP_CODING_DEFLATE : @@ -3838,18 +3840,30 @@ http_content_coding_start( * documentation. */ - if ((zerr = deflateInit2(&(http->stream), Z_DEFAULT_COMPRESSION, - Z_DEFLATED, - coding == _HTTP_CODING_DEFLATE ? -11 : 27, 7, - Z_DEFAULT_STRATEGY)) < Z_OK) + if ((http->stream = calloc(1, sizeof(z_stream))) == NULL) + { + free(http->sbuffer); + + http->sbuffer = NULL; + http->status = HTTP_STATUS_ERROR; + http->error = errno; + return; + } + + if ((zerr = deflateInit2((z_stream *)http->stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, coding == _HTTP_CODING_DEFLATE ? -11 : 27, 7, Z_DEFAULT_STRATEGY)) < Z_OK) { - http->status = HTTP_STATUS_ERROR; - http->error = zerr == Z_MEM_ERROR ? ENOMEM : EINVAL; + free(http->sbuffer); + free(http->stream); + + http->sbuffer = NULL; + http->stream = NULL; + http->status = HTTP_STATUS_ERROR; + http->error = zerr == Z_MEM_ERROR ? ENOMEM : EINVAL; return; } - http->stream.next_out = (Bytef *)http->sbuffer; - http->stream.avail_out = (uInt)_HTTP_MAX_SBUFFER; + ((z_stream *)http->stream)->next_out = (Bytef *)http->sbuffer; + ((z_stream *)http->stream)->avail_out = (uInt)_HTTP_MAX_SBUFFER; break; case _HTTP_CODING_INFLATE : @@ -3866,19 +3880,30 @@ http_content_coding_start( * -15 is raw inflate, 31 is gunzip, per ZLIB documentation. */ - if ((zerr = inflateInit2(&(http->stream), - coding == _HTTP_CODING_INFLATE ? -15 : 31)) - < Z_OK) + if ((http->stream = calloc(1, sizeof(z_stream))) == NULL) + { + free(http->sbuffer); + + http->sbuffer = NULL; + http->status = HTTP_STATUS_ERROR; + http->error = errno; + return; + } + + if ((zerr = inflateInit2((z_stream *)http->stream, coding == _HTTP_CODING_INFLATE ? -15 : 31)) < Z_OK) { free(http->sbuffer); + free(http->stream); + http->sbuffer = NULL; + http->stream = NULL; http->status = HTTP_STATUS_ERROR; http->error = zerr == Z_MEM_ERROR ? ENOMEM : EINVAL; return; } - http->stream.avail_in = 0; - http->stream.next_in = http->sbuffer; + ((z_stream *)http->stream)->avail_in = 0; + ((z_stream *)http->stream)->next_in = http->sbuffer; break; default : @@ -3944,7 +3969,7 @@ http_create( if ((http = calloc(sizeof(http_t), 1)) == NULL) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0); - httpAddrFreeList(addrlist); + httpAddrFreeList(myaddrlist); return (NULL); } @@ -4056,7 +4081,7 @@ http_read(http_t *http, /* I - HTTP connection */ DEBUG_printf(("http_read(http=%p, buffer=%p, length=" CUPS_LLFMT ")", (void *)http, (void *)buffer, CUPS_LLCAST length)); - if (!http->blocking) + if (!http->blocking || http->timeout_value > 0.0) { while (!httpWait(http, http->wait_value)) { @@ -4081,7 +4106,7 @@ http_read(http_t *http, /* I - HTTP connection */ if (bytes < 0) { -#ifdef WIN32 +#ifdef _WIN32 if (WSAGetLastError() != WSAEINTR) { http->error = WSAGetLastError(); @@ -4117,7 +4142,7 @@ http_read(http_t *http, /* I - HTTP connection */ http->error = errno; return (-1); } -#endif /* WIN32 */ +#endif /* _WIN32 */ } } while (bytes < 0); @@ -4131,7 +4156,7 @@ http_read(http_t *http, /* I - HTTP connection */ if (bytes < 0) { -#ifdef WIN32 +#ifdef _WIN32 if (WSAGetLastError() == WSAEINTR) bytes = 0; else @@ -4141,7 +4166,7 @@ http_read(http_t *http, /* I - HTTP connection */ bytes = 0; else http->error = errno; -#endif /* WIN32 */ +#endif /* _WIN32 */ } else if (bytes == 0) { @@ -4301,10 +4326,10 @@ http_send(http_t *http, /* I - HTTP connection */ * Set the User-Agent field if it isn't already... */ - if (!http->fields[HTTP_FIELD_USER_AGENT][0]) + if (!http->fields[HTTP_FIELD_USER_AGENT]) { - if (http->default_user_agent) - httpSetField(http, HTTP_FIELD_USER_AGENT, http->default_user_agent); + if (http->default_fields[HTTP_FIELD_USER_AGENT]) + httpSetField(http, HTTP_FIELD_USER_AGENT, http->default_fields[HTTP_FIELD_USER_AGENT]); else httpSetField(http, HTTP_FIELD_USER_AGENT, cupsUserAgent()); } @@ -4313,9 +4338,8 @@ http_send(http_t *http, /* I - HTTP connection */ * Set the Accept-Encoding field if it isn't already... */ - if (!http->accept_encoding && http->default_accept_encoding) - httpSetField(http, HTTP_FIELD_ACCEPT_ENCODING, - http->default_accept_encoding); + if (!http->fields[HTTP_FIELD_ACCEPT_ENCODING] && http->default_fields[HTTP_FIELD_ACCEPT_ENCODING]) + httpSetField(http, HTTP_FIELD_ACCEPT_ENCODING, http->default_fields[HTTP_FIELD_ACCEPT_ENCODING]); /* * Encode the URI as needed... @@ -4430,7 +4454,7 @@ http_send(http_t *http, /* I - HTTP connection */ * The Kerberos and AuthRef authentication strings can only be used once... */ - if (http->field_authorization && http->authstring && + if (http->fields[HTTP_FIELD_AUTHORIZATION] && http->authstring && (!strncmp(http->authstring, "Negotiate", 9) || !strncmp(http->authstring, "AuthRef", 7))) { @@ -4470,8 +4494,7 @@ http_set_length(http_t *http) /* I - Connection */ return (remaining); } - if (!_cups_strcasecmp(http->fields[HTTP_FIELD_TRANSFER_ENCODING], - "chunked")) + if (!_cups_strcasecmp(httpGetField(http, HTTP_FIELD_TRANSFER_ENCODING), "chunked")) { DEBUG_puts("1http_set_length: Setting data_encoding to " "HTTP_ENCODING_CHUNKED."); @@ -4505,7 +4528,7 @@ static void http_set_timeout(int fd, /* I - File descriptor */ double timeout) /* I - Timeout in seconds */ { -#ifdef WIN32 +#ifdef _WIN32 DWORD tv = (DWORD)(timeout * 1000); /* Timeout in milliseconds */ @@ -4520,7 +4543,7 @@ http_set_timeout(int fd, /* I - File descriptor */ setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, CUPS_SOCAST &tv, sizeof(tv)); setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, CUPS_SOCAST &tv, sizeof(tv)); -#endif /* WIN32 */ +#endif /* _WIN32 */ } @@ -4576,10 +4599,15 @@ http_tls_upgrade(http_t *http) /* I - HTTP connection */ * encryption on the link... */ - http->tls_upgrade = 1; - http->field_authorization = NULL; /* Don't free the auth string */ + http->tls_upgrade = 1; + memset(http->fields, 0, sizeof(http->fields)); + http->expect = (http_status_t)0; + + if (http->hostname[0] == '/') + httpSetField(http, HTTP_FIELD_HOST, "localhost"); + else + httpSetField(http, HTTP_FIELD_HOST, http->hostname); - httpClearFields(http); httpSetField(http, HTTP_FIELD_CONNECTION, "upgrade"); httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.2,TLS/1.1,TLS/1.0"); @@ -4596,14 +4624,15 @@ http_tls_upgrade(http_t *http) /* I - HTTP connection */ * Restore the HTTP request data... */ + memcpy(http->_fields, myhttp._fields, sizeof(http->_fields)); memcpy(http->fields, myhttp.fields, sizeof(http->fields)); - http->data_encoding = myhttp.data_encoding; - http->data_remaining = myhttp.data_remaining; - http->_data_remaining = myhttp._data_remaining; - http->expect = myhttp.expect; - http->field_authorization = myhttp.field_authorization; - http->digest_tries = myhttp.digest_tries; - http->tls_upgrade = 0; + + http->data_encoding = myhttp.data_encoding; + http->data_remaining = myhttp.data_remaining; + http->_data_remaining = myhttp._data_remaining; + http->expect = myhttp.expect; + http->digest_tries = myhttp.digest_tries; + http->tls_upgrade = 0; /* * See if we actually went secure... @@ -4651,7 +4680,7 @@ http_write(http_t *http, /* I - HTTP connection */ { DEBUG_printf(("3http_write: About to write %d bytes.", (int)length)); - if (http->timeout_cb) + if (http->timeout_value > 0.0) { #ifdef HAVE_POLL struct pollfd pfd; /* Polled file descriptor */ @@ -4682,12 +4711,12 @@ http_write(http_t *http, /* I - HTTP connection */ nfds = select(http->fd + 1, NULL, &output_set, NULL, &timeout); } -# ifdef WIN32 +# ifdef _WIN32 while (nfds < 0 && (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEWOULDBLOCK)); # else while (nfds < 0 && (errno == EINTR || errno == EAGAIN)); -# endif /* WIN32 */ +# endif /* _WIN32 */ #endif /* HAVE_POLL */ if (nfds < 0) @@ -4695,13 +4724,13 @@ http_write(http_t *http, /* I - HTTP connection */ http->error = errno; return (-1); } - else if (nfds == 0 && !(*http->timeout_cb)(http, http->timeout_data)) + else if (nfds == 0 && (!http->timeout_cb || !(*http->timeout_cb)(http, http->timeout_data))) { -#ifdef WIN32 +#ifdef _WIN32 http->error = WSAEWOULDBLOCK; #else http->error = EWOULDBLOCK; -#endif /* WIN32 */ +#endif /* _WIN32 */ return (-1); } } @@ -4720,7 +4749,7 @@ http_write(http_t *http, /* I - HTTP connection */ if (bytes < 0) { -#ifdef WIN32 +#ifdef _WIN32 if (WSAGetLastError() == WSAEINTR) continue; else if (WSAGetLastError() == WSAEWOULDBLOCK) @@ -4754,7 +4783,7 @@ http_write(http_t *http, /* I - HTTP connection */ http->error = errno; continue; } -#endif /* WIN32 */ +#endif /* _WIN32 */ DEBUG_printf(("3http_write: error writing data (%s).", strerror(http->error))); diff --git a/cups/http.h b/cups/http.h index c61a79e..01a0321 100644 --- a/cups/http.h +++ b/cups/http.h @@ -1,16 +1,11 @@ /* * Hyper-Text Transport Protocol definitions for CUPS. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ #ifndef _CUPS_HTTP_H_ @@ -25,7 +20,7 @@ # include # include # include -# ifdef WIN32 +# ifdef _WIN32 # ifndef __CUPS_SSIZE_T_DEFINED # define __CUPS_SSIZE_T_DEFINED /* Windows does not support the ssize_t type, so map it to off_t... */ @@ -54,7 +49,7 @@ typedef off_t ssize_t; /* @private@ */ # if defined(LOCAL_PEERCRED) && !defined(SO_PEERCRED) # define SO_PEERCRED LOCAL_PEERCRED # endif /* LOCAL_PEERCRED && !SO_PEERCRED */ -# endif /* WIN32 */ +# endif /* _WIN32 */ /* @@ -85,7 +80,7 @@ extern "C" { # define s6_addr32 _S6_un._S6_u32 # elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)|| defined(__DragonFly__) # define s6_addr32 __u6_addr.__u6_addr32 -# elif defined(WIN32) +# elif defined(_WIN32) /* * Windows only defines byte and 16-bit word members of the union and * requires special casing of all raw address code... @@ -181,6 +176,7 @@ typedef enum http_field_e /**** HTTP field names ****/ HTTP_FIELD_ACCEPT_ENCODING, /* Accepting-Encoding field @since CUPS 1.7/macOS 10.9@ */ HTTP_FIELD_ALLOW, /* Allow field @since CUPS 1.7/macOS 10.9@ */ HTTP_FIELD_SERVER, /* Server field @since CUPS 1.7/macOS 10.9@ */ + HTTP_FIELD_AUTHENTICATION_INFO, /* Authentication-Info field (@since CUPS 2.2.9) */ HTTP_FIELD_MAX /* Maximum field index */ } http_field_t; @@ -248,10 +244,11 @@ typedef enum http_status_e /**** HTTP status codes ****/ HTTP_STATUS_MULTIPLE_CHOICES = 300, /* Multiple files match request */ HTTP_STATUS_MOVED_PERMANENTLY, /* Document has moved permanently */ - HTTP_STATUS_MOVED_TEMPORARILY, /* Document has moved temporarily */ - HTTP_STATUS_SEE_OTHER, /* See this other link... */ + HTTP_STATUS_FOUND, /* Document was found at a different URI */ + HTTP_STATUS_SEE_OTHER, /* See this other link */ HTTP_STATUS_NOT_MODIFIED, /* File not modified */ HTTP_STATUS_USE_PROXY, /* Must use a proxy to access this URI */ + HTTP_STATUS_TEMPORARY_REDIRECT = 307, /* Temporary redirection */ HTTP_STATUS_BAD_REQUEST = 400, /* Bad request */ HTTP_STATUS_UNAUTHORIZED, /* Unauthorized to access host */ @@ -285,6 +282,8 @@ typedef enum http_status_e /**** HTTP status codes ****/ HTTP_STATUS_CUPS_PKI_ERROR, /* Error negotiating a secure connection @since CUPS 1.5/macOS 10.7@ */ HTTP_STATUS_CUPS_WEBIF_DISABLED /* Web interface is disabled @private@ */ +# define HTTP_STATUS_MOVED_TEMPORARILY HTTP_STATUS_FOUND /* Renamed in RFC 7231 */ + # ifndef _CUPS_NO_DEPRECATED /* Old names for this enumeration */ # define HTTP_ERROR HTTP_STATUS_ERROR @@ -451,53 +450,43 @@ typedef int (*http_timeout_cb_t)(http_t *http, void *user_data); * Prototypes... */ -extern void httpBlocking(http_t *http, int b); -extern int httpCheck(http_t *http); -extern void httpClearFields(http_t *http); -extern void httpClose(http_t *http); -extern http_t *httpConnect(const char *host, int port) - _CUPS_DEPRECATED_1_7_MSG("Use httpConnect2 instead."); -extern http_t *httpConnectEncrypt(const char *host, int port, - http_encryption_t encryption) - _CUPS_DEPRECATED_1_7_MSG("Use httpConnect2 instead."); -extern int httpDelete(http_t *http, const char *uri); -extern int httpEncryption(http_t *http, http_encryption_t e); -extern int httpError(http_t *http); -extern void httpFlush(http_t *http); -extern int httpGet(http_t *http, const char *uri); -extern char *httpGets(char *line, int length, http_t *http); -extern const char *httpGetDateString(time_t t); -extern time_t httpGetDateTime(const char *s); -extern const char *httpGetField(http_t *http, http_field_t 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); -extern void httpInitialize(void); -extern int httpOptions(http_t *http, const char *uri); -extern int httpPost(http_t *http, const char *uri); -extern int httpPrintf(http_t *http, const char *format, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); -extern int httpPut(http_t *http, const char *uri); +extern void httpBlocking(http_t *http, int b) _CUPS_PUBLIC; +extern int httpCheck(http_t *http) _CUPS_PUBLIC; +extern void httpClearFields(http_t *http) _CUPS_PUBLIC; +extern void httpClose(http_t *http) _CUPS_PUBLIC; +extern http_t *httpConnect(const char *host, int port) _CUPS_DEPRECATED_1_7_MSG("Use httpConnect2 instead."); +extern http_t *httpConnectEncrypt(const char *host, int port, http_encryption_t encryption) _CUPS_DEPRECATED_1_7_MSG("Use httpConnect2 instead."); +extern int httpDelete(http_t *http, const char *uri) _CUPS_PUBLIC; +extern int httpEncryption(http_t *http, http_encryption_t e) _CUPS_PUBLIC; +extern int httpError(http_t *http) _CUPS_PUBLIC; +extern void httpFlush(http_t *http) _CUPS_PUBLIC; +extern int httpGet(http_t *http, const char *uri) _CUPS_PUBLIC; +extern char *httpGets(char *line, int length, http_t *http) _CUPS_PUBLIC; +extern const char *httpGetDateString(time_t t) _CUPS_PUBLIC; +extern time_t httpGetDateTime(const char *s) _CUPS_PUBLIC; +extern const char *httpGetField(http_t *http, http_field_t field) _CUPS_PUBLIC; +extern struct hostent *httpGetHostByName(const char *name) _CUPS_PUBLIC; +extern char *httpGetSubField(http_t *http, http_field_t field, const char *name, char *value) _CUPS_PUBLIC; +extern int httpHead(http_t *http, const char *uri) _CUPS_PUBLIC; +extern void httpInitialize(void) _CUPS_PUBLIC; +extern int httpOptions(http_t *http, const char *uri) _CUPS_PUBLIC; +extern int httpPost(http_t *http, const char *uri) _CUPS_PUBLIC; +extern int httpPrintf(http_t *http, const char *format, ...) _CUPS_FORMAT(2, 3) _CUPS_PUBLIC; +extern int httpPut(http_t *http, const char *uri) _CUPS_PUBLIC; extern int httpRead(http_t *http, char *buffer, int length) _CUPS_DEPRECATED_MSG("Use httpRead2 instead."); extern int httpReconnect(http_t *http) _CUPS_DEPRECATED_1_6_MSG("Use httpReconnect2 instead."); -extern void httpSeparate(const char *uri, char *method, - char *username, char *host, int *port, - char *resource) _CUPS_DEPRECATED_MSG("Use httpSeparateURI instead."); -extern void httpSetField(http_t *http, http_field_t field, - const char *value); -extern const char *httpStatus(http_status_t status); -extern int httpTrace(http_t *http, const char *uri); -extern http_status_t httpUpdate(http_t *http); +extern void httpSeparate(const char *uri, char *method, char *username, char *host, int *port, char *resource) _CUPS_DEPRECATED_1_2_MSG("Use httpSeparateURI instead."); +extern void httpSetField(http_t *http, http_field_t field, const char *value) _CUPS_PUBLIC; +extern const char *httpStatus(http_status_t status) _CUPS_PUBLIC; +extern int httpTrace(http_t *http, const char *uri) _CUPS_PUBLIC; +extern http_status_t httpUpdate(http_t *http) _CUPS_PUBLIC; extern int httpWrite(http_t *http, const char *buffer, int length) _CUPS_DEPRECATED_MSG("Use httpWrite2 instead."); extern char *httpEncode64(char *out, const char *in) _CUPS_DEPRECATED_MSG("Use httpEncode64_2 instead."); extern char *httpDecode64(char *out, const char *in) _CUPS_DEPRECATED_MSG("Use httpDecode64_2 instead."); -extern int httpGetLength(http_t *http) _CUPS_DEPRECATED_MSG("Use httpGetLength2 instead."); -extern char *httpMD5(const char *, const char *, const char *, - char [33]); -extern char *httpMD5Final(const char *, const char *, const char *, - char [33]); -extern char *httpMD5String(const unsigned char *, char [33]); +extern int httpGetLength(http_t *http) _CUPS_DEPRECATED_1_2_MSG("Use httpGetLength2 instead."); +extern char *httpMD5(const char *, const char *, const char *, char [33]) _CUPS_DEPRECATED_MSG("Use cupsDoAuth or cupsHashData instead."); +extern char *httpMD5Final(const char *, const char *, const char *, char [33]) _CUPS_DEPRECATED_2_2_MSG("Use cupsDoAuth or cupsHashData instead."); +extern char *httpMD5String(const unsigned char *, char [33]) _CUPS_DEPRECATED_2_2_MSG("Use cupsHashString instead."); /**** New in CUPS 1.1.19 ****/ extern void httpClearCookie(http_t *http) _CUPS_API_1_1_19; @@ -507,40 +496,21 @@ extern int httpWait(http_t *http, int msec) _CUPS_API_1_1_19; /**** New in CUPS 1.1.21 ****/ extern char *httpDecode64_2(char *out, int *outlen, const char *in) _CUPS_API_1_1_21; -extern char *httpEncode64_2(char *out, int outlen, const char *in, - int inlen) _CUPS_API_1_1_21; -extern void httpSeparate2(const char *uri, - char *method, int methodlen, - char *username, int usernamelen, - char *host, int hostlen, int *port, - char *resource, int resourcelen) _CUPS_DEPRECATED_MSG("Use httpSeparateURI instead."); +extern char *httpEncode64_2(char *out, int outlen, const char *in, int inlen) _CUPS_API_1_1_21; +extern void httpSeparate2(const char *uri, char *method, int methodlen, char *username, int usernamelen, char *host, int hostlen, int *port, char *resource, int resourcelen) _CUPS_DEPRECATED_1_2_MSG("Use httpSeparateURI instead."); /**** New in CUPS 1.2/macOS 10.5 ****/ extern int httpAddrAny(const http_addr_t *addr) _CUPS_API_1_2; extern http_addrlist_t *httpAddrConnect(http_addrlist_t *addrlist, int *sock) _CUPS_API_1_2; -extern int httpAddrEqual(const http_addr_t *addr1, - const http_addr_t *addr2) _CUPS_API_1_2; +extern int httpAddrEqual(const http_addr_t *addr1, const http_addr_t *addr2) _CUPS_API_1_2; extern void httpAddrFreeList(http_addrlist_t *addrlist) _CUPS_API_1_2; -extern http_addrlist_t *httpAddrGetList(const char *hostname, int family, - const char *service) _CUPS_API_1_2; +extern http_addrlist_t *httpAddrGetList(const char *hostname, int family, const char *service) _CUPS_API_1_2; extern int httpAddrLength(const http_addr_t *addr) _CUPS_API_1_2; extern int httpAddrLocalhost(const http_addr_t *addr) _CUPS_API_1_2; -extern char *httpAddrLookup(const http_addr_t *addr, - char *name, int namelen) _CUPS_API_1_2; -extern char *httpAddrString(const http_addr_t *addr, - char *s, int slen) _CUPS_API_1_2; -extern http_uri_status_t httpAssembleURI(http_uri_coding_t encoding, - char *uri, int urilen, - const char *scheme, - const char *username, - const char *host, int port, - const char *resource) _CUPS_API_1_2; -extern http_uri_status_t httpAssembleURIf(http_uri_coding_t encoding, - char *uri, int urilen, - const char *scheme, - const char *username, - const char *host, int port, - const char *resourcef, ...) _CUPS_API_1_2; +extern char *httpAddrLookup(const http_addr_t *addr, char *name, int namelen) _CUPS_API_1_2; +extern char *httpAddrString(const http_addr_t *addr, char *s, int slen) _CUPS_API_1_2; +extern http_uri_status_t httpAssembleURI(http_uri_coding_t encoding, char *uri, int urilen, const char *scheme, const char *username, const char *host, int port, const char *resource) _CUPS_API_1_2; +extern http_uri_status_t httpAssembleURIf(http_uri_coding_t encoding, char *uri, int urilen, const char *scheme, const char *username, const char *host, int port, const char *resourcef, ...) _CUPS_FORMAT(8, 9) _CUPS_API_1_2; extern int httpFlushWrite(http_t *http) _CUPS_API_1_2; extern int httpGetBlocking(http_t *http) _CUPS_API_1_2; extern const char *httpGetDateString2(time_t t, char *s, int slen) _CUPS_API_1_2; @@ -548,76 +518,44 @@ extern int httpGetFd(http_t *http) _CUPS_API_1_2; extern const char *httpGetHostname(http_t *http, char *s, int slen) _CUPS_API_1_2; extern off_t httpGetLength2(http_t *http) _CUPS_API_1_2; extern http_status_t httpGetStatus(http_t *http) _CUPS_API_1_2; -extern char *httpGetSubField2(http_t *http, http_field_t field, - const char *name, char *value, - int valuelen) _CUPS_API_1_2; +extern char *httpGetSubField2(http_t *http, http_field_t field, const char *name, char *value, int valuelen) _CUPS_API_1_2; extern ssize_t httpRead2(http_t *http, char *buffer, size_t length) _CUPS_API_1_2; -extern http_uri_status_t httpSeparateURI(http_uri_coding_t decoding, - const char *uri, - char *scheme, int schemelen, - char *username, int usernamelen, - char *host, int hostlen, int *port, - char *resource, int resourcelen) _CUPS_API_1_2; +extern http_uri_status_t httpSeparateURI(http_uri_coding_t decoding, const char *uri, char *scheme, int schemelen, char *username, int usernamelen, char *host, int hostlen, int *port, char *resource, int resourcelen) _CUPS_API_1_2; extern void httpSetExpect(http_t *http, http_status_t expect) _CUPS_API_1_2; extern void httpSetLength(http_t *http, size_t length) _CUPS_API_1_2; -extern ssize_t httpWrite2(http_t *http, const char *buffer, - size_t length) _CUPS_API_1_2; +extern ssize_t httpWrite2(http_t *http, const char *buffer, size_t length) _CUPS_API_1_2; /**** New in CUPS 1.3/macOS 10.5 ****/ extern char *httpGetAuthString(http_t *http) _CUPS_API_1_3; -extern void httpSetAuthString(http_t *http, const char *scheme, - const char *data) _CUPS_API_1_3; +extern void httpSetAuthString(http_t *http, const char *scheme, const char *data) _CUPS_API_1_3; /**** New in CUPS 1.5/macOS 10.7 ****/ -extern int httpAddCredential(cups_array_t *credentials, - const void *data, size_t datalen) - _CUPS_API_1_5; -extern int httpCopyCredentials(http_t *http, - cups_array_t **credentials) - _CUPS_API_1_5; +extern int httpAddCredential(cups_array_t *credentials, const void *data, size_t datalen) _CUPS_API_1_5; +extern int httpCopyCredentials(http_t *http, cups_array_t **credentials) _CUPS_API_1_5; extern void httpFreeCredentials(cups_array_t *certs) _CUPS_API_1_5; -extern int httpSetCredentials(http_t *http, cups_array_t *certs) - _CUPS_API_1_5; -extern void httpSetTimeout(http_t *http, double timeout, - http_timeout_cb_t cb, void *user_data) - _CUPS_API_1_5; +extern int httpSetCredentials(http_t *http, cups_array_t *certs) _CUPS_API_1_5; +extern void httpSetTimeout(http_t *http, double timeout, http_timeout_cb_t cb, void *user_data) _CUPS_API_1_5; /**** New in CUPS 1.6/macOS 10.8 ****/ -extern http_addrlist_t *httpAddrConnect2(http_addrlist_t *addrlist, int *sock, - int msec, int *cancel) - _CUPS_API_1_6; +extern http_addrlist_t *httpAddrConnect2(http_addrlist_t *addrlist, int *sock, int msec, int *cancel) _CUPS_API_1_6; extern http_state_t httpGetState(http_t *http) _CUPS_API_1_6; extern http_version_t httpGetVersion(http_t *http) _CUPS_API_1_6; -extern int httpReconnect2(http_t *http, int msec, int *cancel) - _CUPS_API_1_6; +extern int httpReconnect2(http_t *http, int msec, int *cancel) _CUPS_API_1_6; /**** New in CUPS 1.7/macOS 10.9 ****/ -extern http_t *httpAcceptConnection(int fd, int blocking) - _CUPS_API_1_7; +extern http_t *httpAcceptConnection(int fd, int blocking) _CUPS_API_1_7; extern http_addrlist_t *httpAddrCopyList(http_addrlist_t *src) _CUPS_API_1_7; -extern int httpAddrListen(http_addr_t *addr, int port) - _CUPS_API_1_7; +extern int httpAddrListen(http_addr_t *addr, int port) _CUPS_API_1_7; extern int httpAddrPort(http_addr_t *addr) _CUPS_API_1_7; -extern char *httpAssembleUUID(const char *server, int port, - const char *name, int number, - char *buffer, size_t bufsize) - _CUPS_API_1_7; -extern http_t *httpConnect2(const char *host, int port, - http_addrlist_t *addrlist, - int family, http_encryption_t encryption, - int blocking, int msec, int *cancel) - _CUPS_API_1_7; +extern char *httpAssembleUUID(const char *server, int port, const char *name, int number, char *buffer, size_t bufsize) _CUPS_API_1_7; +extern http_t *httpConnect2(const char *host, int port, http_addrlist_t *addrlist, int family, http_encryption_t encryption, int blocking, int msec, int *cancel) _CUPS_API_1_7; extern const char *httpGetContentEncoding(http_t *http) _CUPS_API_1_7; extern http_status_t httpGetExpect(http_t *http) _CUPS_API_1_7; -extern ssize_t httpPeek(http_t *http, char *buffer, size_t length) - _CUPS_API_1_7; -extern http_state_t httpReadRequest(http_t *http, char *resource, - size_t resourcelen) _CUPS_API_1_7; -extern void httpSetDefaultField(http_t *http, http_field_t field, - const char *value) _CUPS_API_1_7; -extern http_state_t httpWriteResponse(http_t *http, - http_status_t status) _CUPS_API_1_7; +extern ssize_t httpPeek(http_t *http, char *buffer, size_t length) _CUPS_API_1_7; +extern http_state_t httpReadRequest(http_t *http, char *resource, size_t resourcelen) _CUPS_API_1_7; +extern void httpSetDefaultField(http_t *http, http_field_t field, const char *value) _CUPS_API_1_7; +extern http_state_t httpWriteResponse(http_t *http, http_status_t status) _CUPS_API_1_7; /* New in CUPS 2.0/macOS 10.10 */ extern int httpAddrClose(http_addr_t *addr, int fd) _CUPS_API_2_0; diff --git a/cups/ipp-file.c b/cups/ipp-file.c new file mode 100644 index 0000000..5db5932 --- /dev/null +++ b/cups/ipp-file.c @@ -0,0 +1,846 @@ +/* + * IPP data file parsing functions. + * + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products. + * + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. + */ + +/* + * Include necessary headers... + */ + +#include "ipp-private.h" +#include "string-private.h" +#include "debug-internal.h" + + +/* + * Local functions... + */ + +static ipp_t *parse_collection(_ipp_file_t *f, _ipp_vars_t *v, void *user_data); +static int parse_value(_ipp_file_t *f, _ipp_vars_t *v, void *user_data, ipp_t *ipp, ipp_attribute_t **attr, int element); +static void report_error(_ipp_file_t *f, _ipp_vars_t *v, void *user_data, const char *message, ...) _CUPS_FORMAT(4, 5); + + +/* + * '_ippFileParse()' - Parse an IPP data file. + */ + +ipp_t * /* O - IPP attributes or @code NULL@ on failure */ +_ippFileParse( + _ipp_vars_t *v, /* I - Variables */ + const char *filename, /* I - Name of file to parse */ + void *user_data) /* I - User data pointer */ +{ + _ipp_file_t f; /* IPP data file information */ + ipp_t *attrs = NULL; /* Active IPP message */ + ipp_attribute_t *attr = NULL; /* Current attribute */ + char token[1024]; /* Token string */ + ipp_t *ignored = NULL; /* Ignored attributes */ + + + DEBUG_printf(("_ippFileParse(v=%p, filename=\"%s\", user_data=%p)", (void *)v, filename, user_data)); + + /* + * Initialize file info... + */ + + memset(&f, 0, sizeof(f)); + f.filename = filename; + f.linenum = 1; + + if ((f.fp = cupsFileOpen(filename, "r")) == NULL) + { + DEBUG_printf(("1_ippFileParse: Unable to open \"%s\": %s", filename, strerror(errno))); + return (0); + } + + /* + * Do the callback with a NULL token to setup any initial state... + */ + + (*v->tokencb)(&f, v, user_data, NULL); + + /* + * Read data file, using the callback function as needed... + */ + + while (_ippFileReadToken(&f, token, sizeof(token))) + { + if (!_cups_strcasecmp(token, "DEFINE") || !_cups_strcasecmp(token, "DEFINE-DEFAULT")) + { + char name[128], /* Variable name */ + value[1024], /* Variable value */ + temp[1024]; /* Temporary string */ + + attr = NULL; + + if (_ippFileReadToken(&f, name, sizeof(name)) && _ippFileReadToken(&f, temp, sizeof(temp))) + { + if (_cups_strcasecmp(token, "DEFINE-DEFAULT") || !_ippVarsGet(v, name)) + { + _ippVarsExpand(v, value, temp, sizeof(value)); + _ippVarsSet(v, name, value); + } + } + else + { + report_error(&f, v, user_data, "Missing %s name and/or value on line %d of \"%s\".", token, f.linenum, f.filename); + break; + } + } + else if (f.attrs && !_cups_strcasecmp(token, "ATTR")) + { + /* + * Attribute definition... + */ + + char syntax[128], /* Attribute syntax (value tag) */ + name[128]; /* Attribute name */ + ipp_tag_t value_tag; /* Value tag */ + + attr = NULL; + + if (!_ippFileReadToken(&f, syntax, sizeof(syntax))) + { + report_error(&f, v, user_data, "Missing ATTR syntax on line %d of \"%s\".", f.linenum, f.filename); + break; + } + else if ((value_tag = ippTagValue(syntax)) < IPP_TAG_UNSUPPORTED_VALUE) + { + report_error(&f, v, user_data, "Bad ATTR syntax \"%s\" on line %d of \"%s\".", syntax, f.linenum, f.filename); + break; + } + + if (!_ippFileReadToken(&f, name, sizeof(name)) || !name[0]) + { + report_error(&f, v, user_data, "Missing ATTR name on line %d of \"%s\".", f.linenum, f.filename); + break; + } + + if (!v->attrcb || (*v->attrcb)(&f, user_data, name)) + { + /* + * Add this attribute... + */ + + attrs = f.attrs; + } + else + { + /* + * Ignore this attribute... + */ + + if (!ignored) + ignored = ippNew(); + + attrs = ignored; + } + + if (value_tag < IPP_TAG_INTEGER) + { + /* + * Add out-of-band attribute - no value string needed... + */ + + ippAddOutOfBand(attrs, f.group_tag, value_tag, name); + } + else + { + /* + * Add attribute with one or more values... + */ + + attr = ippAddString(attrs, f.group_tag, value_tag, name, NULL, NULL); + + if (!parse_value(&f, v, user_data, attrs, &attr, 0)) + break; + } + + } + else if (attr && !_cups_strcasecmp(token, ",")) + { + /* + * Additional value... + */ + + if (!parse_value(&f, v, user_data, attrs, &attr, ippGetCount(attr))) + break; + } + else + { + /* + * Something else... + */ + + attr = NULL; + attrs = NULL; + + if (!(*v->tokencb)(&f, v, user_data, token)) + break; + } + } + + /* + * Close the file and free ignored attributes, then return any attributes we + * kept... + */ + + cupsFileClose(f.fp); + ippDelete(ignored); + + return (f.attrs); +} + + +/* + * '_ippFileReadToken()' - Read a token from an IPP data file. + */ + +int /* O - 1 on success, 0 on failure */ +_ippFileReadToken(_ipp_file_t *f, /* I - File to read from */ + char *token, /* I - Token string buffer */ + size_t tokensize)/* I - Size of token string buffer */ +{ + int ch, /* Character from file */ + quote = 0; /* Quoting character */ + char *tokptr = token, /* Pointer into token buffer */ + *tokend = token + tokensize - 1;/* End of token buffer */ + + + /* + * Skip whitespace and comments... + */ + + DEBUG_printf(("1_ippFileReadToken: linenum=%d, pos=%ld", f->linenum, (long)cupsFileTell(f->fp))); + + while ((ch = cupsFileGetChar(f->fp)) != EOF) + { + if (_cups_isspace(ch)) + { + /* + * Whitespace... + */ + + if (ch == '\n') + { + f->linenum ++; + DEBUG_printf(("1_ippFileReadToken: LF in leading whitespace, linenum=%d, pos=%ld", f->linenum, (long)cupsFileTell(f->fp))); + } + } + else if (ch == '#') + { + /* + * Comment... + */ + + DEBUG_puts("1_ippFileReadToken: Skipping comment in leading whitespace..."); + + while ((ch = cupsFileGetChar(f->fp)) != EOF) + { + if (ch == '\n') + break; + } + + if (ch == '\n') + { + f->linenum ++; + DEBUG_printf(("1_ippFileReadToken: LF at end of comment, linenum=%d, pos=%ld", f->linenum, (long)cupsFileTell(f->fp))); + } + else + break; + } + else + break; + } + + if (ch == EOF) + { + DEBUG_puts("1_ippFileReadToken: EOF"); + return (0); + } + + /* + * Read a token... + */ + + while (ch != EOF) + { + if (ch == '\n') + { + f->linenum ++; + DEBUG_printf(("1_ippFileReadToken: LF in token, linenum=%d, pos=%ld", f->linenum, (long)cupsFileTell(f->fp))); + } + + if (ch == quote) + { + /* + * End of quoted text... + */ + + *tokptr = '\0'; + DEBUG_printf(("1_ippFileReadToken: Returning \"%s\" at closing quote.", token)); + return (1); + } + else if (!quote && _cups_isspace(ch)) + { + /* + * End of unquoted text... + */ + + *tokptr = '\0'; + DEBUG_printf(("1_ippFileReadToken: Returning \"%s\" before whitespace.", token)); + return (1); + } + else if (!quote && (ch == '\'' || ch == '\"')) + { + /* + * Start of quoted text or regular expression... + */ + + if (ch == '<') + quote = '>'; + else + quote = ch; + + DEBUG_printf(("1_ippFileReadToken: Start of quoted string, quote=%c, pos=%ld", quote, (long)cupsFileTell(f->fp))); + } + else if (!quote && ch == '#') + { + /* + * Start of comment... + */ + + cupsFileSeek(f->fp, cupsFileTell(f->fp) - 1); + *tokptr = '\0'; + DEBUG_printf(("1_ippFileReadToken: Returning \"%s\" before comment.", token)); + return (1); + } + else if (!quote && (ch == '{' || ch == '}' || ch == ',')) + { + /* + * Delimiter... + */ + + if (tokptr > token) + { + /* + * Return the preceding token first... + */ + + cupsFileSeek(f->fp, cupsFileTell(f->fp) - 1); + } + else + { + /* + * Return this delimiter by itself... + */ + + *tokptr++ = (char)ch; + } + + *tokptr = '\0'; + DEBUG_printf(("1_ippFileReadToken: Returning \"%s\".", token)); + return (1); + } + else + { + if (ch == '\\') + { + /* + * Quoted character... + */ + + DEBUG_printf(("1_ippFileReadToken: Quoted character at pos=%ld", (long)cupsFileTell(f->fp))); + + if ((ch = cupsFileGetChar(f->fp)) == EOF) + { + *token = '\0'; + DEBUG_puts("1_ippFileReadToken: EOF"); + return (0); + } + else if (ch == '\n') + { + f->linenum ++; + DEBUG_printf(("1_ippFileReadToken: quoted LF, linenum=%d, pos=%ld", f->linenum, (long)cupsFileTell(f->fp))); + } + else if (ch == 'a') + ch = '\a'; + else if (ch == 'b') + ch = '\b'; + else if (ch == 'f') + ch = '\f'; + else if (ch == 'n') + ch = '\n'; + else if (ch == 'r') + ch = '\r'; + else if (ch == 't') + ch = '\t'; + else if (ch == 'v') + ch = '\v'; + } + + if (tokptr < tokend) + { + /* + * Add to current token... + */ + + *tokptr++ = (char)ch; + } + else + { + /* + * Token too long... + */ + + *tokptr = '\0'; + DEBUG_printf(("1_ippFileReadToken: Too long: \"%s\".", token)); + return (0); + } + } + + /* + * Get the next character... + */ + + ch = cupsFileGetChar(f->fp); + } + + *tokptr = '\0'; + DEBUG_printf(("1_ippFileReadToken: Returning \"%s\" at EOF.", token)); + + return (tokptr > token); +} + + +/* + * 'parse_collection()' - Parse an IPP collection value. + */ + +static ipp_t * /* O - Collection value or @code NULL@ on error */ +parse_collection( + _ipp_file_t *f, /* I - IPP data file */ + _ipp_vars_t *v, /* I - IPP variables */ + void *user_data) /* I - User data pointer */ +{ + ipp_t *col = ippNew(); /* Collection value */ + ipp_attribute_t *attr = NULL; /* Current member attribute */ + char token[1024]; /* Token string */ + + + /* + * Parse the collection value... + */ + + while (_ippFileReadToken(f, token, sizeof(token))) + { + if (!_cups_strcasecmp(token, "}")) + { + /* + * End of collection value... + */ + + break; + } + else if (!_cups_strcasecmp(token, "MEMBER")) + { + /* + * Member attribute definition... + */ + + char syntax[128], /* Attribute syntax (value tag) */ + name[128]; /* Attribute name */ + ipp_tag_t value_tag; /* Value tag */ + + attr = NULL; + + if (!_ippFileReadToken(f, syntax, sizeof(syntax))) + { + report_error(f, v, user_data, "Missing MEMBER syntax on line %d of \"%s\".", f->linenum, f->filename); + ippDelete(col); + col = NULL; + break; + } + else if ((value_tag = ippTagValue(syntax)) < IPP_TAG_UNSUPPORTED_VALUE) + { + report_error(f, v, user_data, "Bad MEMBER syntax \"%s\" on line %d of \"%s\".", syntax, f->linenum, f->filename); + ippDelete(col); + col = NULL; + break; + } + + if (!_ippFileReadToken(f, name, sizeof(name)) || !name[0]) + { + report_error(f, v, user_data, "Missing MEMBER name on line %d of \"%s\".", f->linenum, f->filename); + ippDelete(col); + col = NULL; + break; + } + + if (value_tag < IPP_TAG_INTEGER) + { + /* + * Add out-of-band attribute - no value string needed... + */ + + ippAddOutOfBand(col, IPP_TAG_ZERO, value_tag, name); + } + else + { + /* + * Add attribute with one or more values... + */ + + attr = ippAddString(col, IPP_TAG_ZERO, value_tag, name, NULL, NULL); + + if (!parse_value(f, v, user_data, col, &attr, 0)) + { + ippDelete(col); + col = NULL; + break; + } + } + + } + else if (attr && !_cups_strcasecmp(token, ",")) + { + /* + * Additional value... + */ + + if (!parse_value(f, v, user_data, col, &attr, ippGetCount(attr))) + { + ippDelete(col); + col = NULL; + break; + } + } + else + { + /* + * Something else... + */ + + report_error(f, v, user_data, "Unknown directive \"%s\" on line %d of \"%s\".", token, f->linenum, f->filename); + ippDelete(col); + col = NULL; + attr = NULL; + break; + + } + } + + return (col); +} + + +/* + * 'parse_value()' - Parse an IPP value. + */ + +static int /* O - 1 on success or 0 on error */ +parse_value(_ipp_file_t *f, /* I - IPP data file */ + _ipp_vars_t *v, /* I - IPP variables */ + void *user_data,/* I - User data pointer */ + ipp_t *ipp, /* I - IPP message */ + ipp_attribute_t **attr, /* IO - IPP attribute */ + int element) /* I - Element number */ +{ + char value[2049], /* Value string */ + *valueptr, /* Pointer into value string */ + temp[2049], /* Temporary string */ + *tempptr; /* Pointer into temporary string */ + size_t valuelen; /* Length of value */ + + + if (!_ippFileReadToken(f, temp, sizeof(temp))) + { + report_error(f, v, user_data, "Missing value on line %d of \"%s\".", f->linenum, f->filename); + return (0); + } + + _ippVarsExpand(v, value, temp, sizeof(value)); + + switch (ippGetValueTag(*attr)) + { + case IPP_TAG_BOOLEAN : + return (ippSetBoolean(ipp, attr, element, !_cups_strcasecmp(value, "true"))); + break; + + case IPP_TAG_ENUM : + case IPP_TAG_INTEGER : + return (ippSetInteger(ipp, attr, element, (int)strtol(value, NULL, 0))); + break; + + case IPP_TAG_DATE : + { + int year, /* Year */ + month, /* Month */ + day, /* Day of month */ + hour, /* Hour */ + minute, /* Minute */ + second, /* Second */ + utc_offset = 0; /* Timezone offset from UTC */ + ipp_uchar_t date[11]; /* dateTime value */ + + if (*value == 'P') + { + /* + * Time period... + */ + + time_t curtime; /* Current time in seconds */ + int period = 0, /* Current period value */ + saw_T = 0; /* Saw time separator */ + + curtime = time(NULL); + + for (valueptr = value + 1; *valueptr; valueptr ++) + { + if (isdigit(*valueptr & 255)) + { + period = (int)strtol(valueptr, &valueptr, 10); + + if (!valueptr || period < 0) + { + report_error(f, v, user_data, "Bad dateTime value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename); + return (0); + } + } + + if (*valueptr == 'Y') + { + curtime += 365 * 86400 * period; + period = 0; + } + else if (*valueptr == 'M') + { + if (saw_T) + curtime += 60 * period; + else + curtime += 30 * 86400 * period; + + period = 0; + } + else if (*valueptr == 'D') + { + curtime += 86400 * period; + period = 0; + } + else if (*valueptr == 'H') + { + curtime += 3600 * period; + period = 0; + } + else if (*valueptr == 'S') + { + curtime += period; + period = 0; + } + else if (*valueptr == 'T') + { + saw_T = 1; + period = 0; + } + else + { + report_error(f, v, user_data, "Bad dateTime value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename); + return (0); + } + } + + return (ippSetDate(ipp, attr, element, ippTimeToDate(curtime))); + } + else if (sscanf(value, "%d-%d-%dT%d:%d:%d%d", &year, &month, &day, &hour, &minute, &second, &utc_offset) < 6) + { + /* + * Date/time value did not parse... + */ + + report_error(f, v, user_data, "Bad dateTime value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename); + return (0); + } + + date[0] = (ipp_uchar_t)(year >> 8); + date[1] = (ipp_uchar_t)(year & 255); + date[2] = (ipp_uchar_t)month; + date[3] = (ipp_uchar_t)day; + date[4] = (ipp_uchar_t)hour; + date[5] = (ipp_uchar_t)minute; + date[6] = (ipp_uchar_t)second; + date[7] = 0; + if (utc_offset < 0) + { + utc_offset = -utc_offset; + date[8] = (ipp_uchar_t)'-'; + } + else + { + date[8] = (ipp_uchar_t)'+'; + } + + date[9] = (ipp_uchar_t)(utc_offset / 100); + date[10] = (ipp_uchar_t)(utc_offset % 100); + + return (ippSetDate(ipp, attr, element, date)); + } + break; + + case IPP_TAG_RESOLUTION : + { + int xres, /* X resolution */ + yres; /* Y resolution */ + char *ptr; /* Pointer into value */ + + xres = yres = (int)strtol(value, (char **)&ptr, 10); + if (ptr > value && xres > 0) + { + if (*ptr == 'x') + yres = (int)strtol(ptr + 1, (char **)&ptr, 10); + } + + if (ptr <= value || xres <= 0 || yres <= 0 || !ptr || (_cups_strcasecmp(ptr, "dpi") && _cups_strcasecmp(ptr, "dpc") && _cups_strcasecmp(ptr, "dpcm") && _cups_strcasecmp(ptr, "other"))) + { + report_error(f, v, user_data, "Bad resolution value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename); + return (0); + } + + if (!_cups_strcasecmp(ptr, "dpi")) + return (ippSetResolution(ipp, attr, element, IPP_RES_PER_INCH, xres, yres)); + else if (!_cups_strcasecmp(ptr, "dpc") || !_cups_strcasecmp(ptr, "dpcm")) + return (ippSetResolution(ipp, attr, element, IPP_RES_PER_CM, xres, yres)); + else + return (ippSetResolution(ipp, attr, element, (ipp_res_t)0, xres, yres)); + } + break; + + case IPP_TAG_RANGE : + { + int lower, /* Lower value */ + upper; /* Upper value */ + + if (sscanf(value, "%d-%d", &lower, &upper) != 2) + { + report_error(f, v, user_data, "Bad rangeOfInteger value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename); + return (0); + } + + return (ippSetRange(ipp, attr, element, lower, upper)); + } + break; + + case IPP_TAG_STRING : + valuelen = strlen(value); + + if (value[0] == '<' && value[strlen(value) - 1] == '>') + { + if (valuelen & 1) + { + report_error(f, v, user_data, "Bad octetString value on line %d of \"%s\".", f->linenum, f->filename); + return (0); + } + + valueptr = value + 1; + tempptr = temp; + + while (*valueptr && *valueptr != '>') + { + if (!isxdigit(valueptr[0] & 255) || !isxdigit(valueptr[1] & 255)) + { + report_error(f, v, user_data, "Bad octetString value on line %d of \"%s\".", f->linenum, f->filename); + return (0); + } + + if (valueptr[0] >= '0' && valueptr[0] <= '9') + *tempptr = (char)((valueptr[0] - '0') << 4); + else + *tempptr = (char)((tolower(valueptr[0]) - 'a' + 10) << 4); + + if (valueptr[1] >= '0' && valueptr[1] <= '9') + *tempptr |= (valueptr[1] - '0'); + else + *tempptr |= (tolower(valueptr[1]) - 'a' + 10); + + tempptr ++; + } + + return (ippSetOctetString(ipp, attr, element, temp, (int)(tempptr - temp))); + } + else + return (ippSetOctetString(ipp, attr, element, value, (int)valuelen)); + break; + + case IPP_TAG_TEXTLANG : + case IPP_TAG_NAMELANG : + case IPP_TAG_TEXT : + case IPP_TAG_NAME : + case IPP_TAG_KEYWORD : + case IPP_TAG_URI : + case IPP_TAG_URISCHEME : + case IPP_TAG_CHARSET : + case IPP_TAG_LANGUAGE : + case IPP_TAG_MIMETYPE : + return (ippSetString(ipp, attr, element, value)); + break; + + case IPP_TAG_BEGIN_COLLECTION : + { + int status; /* Add status */ + ipp_t *col; /* Collection value */ + + if (strcmp(value, "{")) + { + report_error(f, v, user_data, "Bad collection value on line %d of \"%s\".", f->linenum, f->filename); + return (0); + } + + if ((col = parse_collection(f, v, user_data)) == NULL) + return (0); + + status = ippSetCollection(ipp, attr, element, col); + ippDelete(col); + + return (status); + } + break; + + default : + report_error(f, v, user_data, "Unsupported value on line %d of \"%s\".", f->linenum, f->filename); + return (0); + } + + return (1); +} + + +/* + * 'report_error()' - Report an error. + */ + +static void +report_error( + _ipp_file_t *f, /* I - IPP data file */ + _ipp_vars_t *v, /* I - Error callback function, if any */ + void *user_data, /* I - User data pointer */ + const char *message, /* I - Printf-style message */ + ...) /* I - Additional arguments as needed */ +{ + char buffer[8192]; /* Formatted string */ + va_list ap; /* Argument pointer */ + + + va_start(ap, message); + vsnprintf(buffer, sizeof(buffer), message, ap); + va_end(ap); + + if (v->errorcb) + (*v->errorcb)(f, user_data, buffer); + else + fprintf(stderr, "%s\n", buffer); +} diff --git a/cups/ipp-private.h b/cups/ipp-private.h index 4b1947c..fa5e435 100644 --- a/cups/ipp-private.h +++ b/cups/ipp-private.h @@ -1,16 +1,11 @@ /* * Private IPP definitions for CUPS. * - * Copyright 2007-2014 by Apple Inc. - * Copyright 1997-2006 by Easy Software Products. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ #ifndef _CUPS_IPP_PRIVATE_H_ @@ -20,7 +15,7 @@ * Include necessary headers... */ -# include +# include /* @@ -44,7 +39,105 @@ extern "C" { * Structures... */ -typedef struct /**** Attribute mapping data ****/ +typedef union _ipp_request_u /**** Request Header ****/ +{ + struct /* Any Header */ + { + ipp_uchar_t version[2]; /* Protocol version number */ + int op_status; /* Operation ID or status code*/ + int request_id; /* Request ID */ + } any; + + struct /* Operation Header */ + { + ipp_uchar_t version[2]; /* Protocol version number */ + ipp_op_t operation_id; /* Operation ID */ + int request_id; /* Request ID */ + } op; + + struct /* Status Header */ + { + ipp_uchar_t version[2]; /* Protocol version number */ + ipp_status_t status_code; /* Status code */ + int request_id; /* Request ID */ + } status; + + /**** New in CUPS 1.1.19 ****/ + struct /* Event Header @since CUPS 1.1.19/macOS 10.3@ */ + { + ipp_uchar_t version[2]; /* Protocol version number */ + ipp_status_t status_code; /* Status code */ + int request_id; /* Request ID */ + } event; +} _ipp_request_t; + +typedef union _ipp_value_u /**** Attribute Value ****/ +{ + int integer; /* Integer/enumerated value */ + + char boolean; /* Boolean value */ + + ipp_uchar_t date[11]; /* Date/time value */ + + struct + { + int xres, /* Horizontal resolution */ + yres; /* Vertical resolution */ + ipp_res_t units; /* Resolution units */ + } resolution; /* Resolution value */ + + struct + { + int lower, /* Lower value */ + upper; /* Upper value */ + } range; /* Range of integers value */ + + struct + { + char *language; /* Language code */ + char *text; /* String */ + } string; /* String with language value */ + + struct + { + int length; /* Length of attribute */ + void *data; /* Data in attribute */ + } unknown; /* Unknown attribute type */ + +/**** New in CUPS 1.1.19 ****/ + ipp_t *collection; /* Collection value @since CUPS 1.1.19/macOS 10.3@ */ +} _ipp_value_t; + +struct _ipp_attribute_s /**** IPP attribute ****/ +{ + ipp_attribute_t *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 */ + int num_values; /* Number of values */ + _ipp_value_t values[1]; /* Values */ +}; + +struct _ipp_s /**** IPP Request/Response/Notification ****/ +{ + ipp_state_t state; /* State of request */ + _ipp_request_t request; /* Request header */ + ipp_attribute_t *attrs; /* Attributes */ + ipp_attribute_t *last; /* Last attribute in list */ + ipp_attribute_t *current; /* Current attribute (for read/write) */ + ipp_tag_t curtag; /* Current attribute group tag */ + +/**** New in CUPS 1.2 ****/ + ipp_attribute_t *prev; /* Previous attribute (for read) @since CUPS 1.2/macOS 10.5@ */ + +/**** New in CUPS 1.4.4 ****/ + int use; /* Use count @since CUPS 1.4.4/macOS 10.6.?@ */ +/**** New in CUPS 2.0 ****/ + int atend, /* At end of list? */ + curindex; /* Current attribute index for hierarchical search */ +}; + +typedef struct _ipp_option_s /**** Attribute mapping data ****/ { int multivalue; /* Option has multiple values? */ const char *name; /* Option/attribute name */ @@ -55,15 +148,66 @@ typedef struct /**** Attribute mapping data ****/ const ipp_op_t *operations; /* Allowed operations for this attr */ } _ipp_option_t; +typedef struct _ipp_file_s _ipp_file_t;/**** File Parser ****/ +typedef struct _ipp_vars_s _ipp_vars_t;/**** Variables ****/ + +typedef int (*_ipp_fattr_cb_t)(_ipp_file_t *f, void *user_data, const char *attr); + /**** File Attribute (Filter) Callback ****/ +typedef int (*_ipp_ferror_cb_t)(_ipp_file_t *f, void *user_data, const char *error); + /**** File Parser Error Callback ****/ +typedef int (*_ipp_ftoken_cb_t)(_ipp_file_t *f, _ipp_vars_t *v, void *user_data, const char *token); + /**** File Parser Token Callback ****/ + +struct _ipp_vars_s /**** Variables ****/ +{ + char *uri, /* URI for printer */ + scheme[64], /* Scheme from URI */ + username[256], /* Username from URI */ + *password, /* Password from URI (if any) */ + host[256], /* Hostname from URI */ + portstr[32], /* Port number string */ + resource[1024]; /* Resource path from URI */ + int port; /* Port number from URI */ + int num_vars; /* Number of variables */ + cups_option_t *vars; /* Array of variables */ + int password_tries; /* Number of retries for password */ + _ipp_fattr_cb_t attrcb; /* Attribute (filter) callback */ + _ipp_ferror_cb_t errorcb; /* Error callback */ + _ipp_ftoken_cb_t tokencb; /* Token callback */ +}; + +struct _ipp_file_s /**** File Parser */ +{ + const char *filename; /* Filename */ + cups_file_t *fp; /* File pointer */ + int linenum; /* Current line number */ + ipp_t *attrs; /* Attributes */ + ipp_tag_t group_tag; /* Current group for new attributes */ +}; + /* * Prototypes for private functions... */ +/* encode.c */ #ifdef DEBUG -extern const char *_ippCheckOptions(void); +extern const char *_ippCheckOptions(void) _CUPS_PRIVATE; #endif /* DEBUG */ -extern _ipp_option_t *_ippFindOption(const char *name); +extern _ipp_option_t *_ippFindOption(const char *name) _CUPS_PRIVATE; + +/* ipp-file.c */ +extern ipp_t *_ippFileParse(_ipp_vars_t *v, const char *filename, void *user_data) _CUPS_PRIVATE; +extern int _ippFileReadToken(_ipp_file_t *f, char *token, size_t tokensize) _CUPS_PRIVATE; + +/* ipp-vars.c */ +extern void _ippVarsDeinit(_ipp_vars_t *v) _CUPS_PRIVATE; +extern void _ippVarsExpand(_ipp_vars_t *v, char *dst, const char *src, size_t dstsize) _CUPS_NONNULL(1,2,3) _CUPS_PRIVATE; +extern const char *_ippVarsGet(_ipp_vars_t *v, const char *name) _CUPS_PRIVATE; +extern void _ippVarsInit(_ipp_vars_t *v, _ipp_fattr_cb_t attrcb, _ipp_ferror_cb_t errorcb, _ipp_ftoken_cb_t tokencb) _CUPS_PRIVATE; +extern const char *_ippVarsPasswordCB(const char *prompt, http_t *http, const char *method, const char *resource, void *user_data) _CUPS_PRIVATE; +extern int _ippVarsSet(_ipp_vars_t *v, const char *name, const char *value) _CUPS_PRIVATE; + /* * C++ magic... diff --git a/cups/ipp-support.c b/cups/ipp-support.c index 675e5f3..7d028b4 100644 --- a/cups/ipp-support.c +++ b/cups/ipp-support.c @@ -1,16 +1,11 @@ /* * Internet Printing Protocol support functions for CUPS. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -18,6 +13,7 @@ */ #include "cups-private.h" +#include "debug-internal.h" /* @@ -143,87 +139,117 @@ static const char * const ipp_std_ops[] = /* 0x0000 - 0x000f */ "0x0000", "0x0001", - "Print-Job", - "Print-URI", - "Validate-Job", - "Create-Job", - "Send-Document", - "Send-URI", - "Cancel-Job", - "Get-Job-Attributes", - "Get-Jobs", - "Get-Printer-Attributes", - "Hold-Job", - "Release-Job", - "Restart-Job", + "Print-Job", /* RFC 8011 */ + "Print-URI", /* RFC 8011 */ + "Validate-Job", /* RFC 8011 */ + "Create-Job", /* RFC 8011 */ + "Send-Document", /* RFC 8011 */ + "Send-URI", /* RFC 8011 */ + "Cancel-Job", /* RFC 8011 */ + "Get-Job-Attributes", /* RFC 8011 */ + "Get-Jobs", /* RFC 8011 */ + "Get-Printer-Attributes", /* RFC 8011 */ + "Hold-Job", /* RFC 8011 */ + "Release-Job", /* RFC 8011 */ + "Restart-Job", /* RFC 8011 */ "0x000f", /* 0x0010 - 0x001f */ - "Pause-Printer", - "Resume-Printer", - "Purge-Jobs", - "Set-Printer-Attributes", - "Set-Job-Attributes", - "Get-Printer-Supported-Values", - "Create-Printer-Subscriptions", - "Create-Job-Subscriptions", - "Get-Subscription-Attributes", - "Get-Subscriptions", - "Renew-Subscription", - "Cancel-Subscription", - "Get-Notifications", + "Pause-Printer", /* RFC 8011 */ + "Resume-Printer", /* RFC 8011 */ + "Purge-Jobs", /* RFC 8011 */ + "Set-Printer-Attributes", /* RFC 3380 */ + "Set-Job-Attributes", /* RFC 3380 */ + "Get-Printer-Supported-Values", /* RFC 3380 */ + "Create-Printer-Subscriptions", /* RFC 3995 */ + "Create-Job-Subscriptions", /* RFC 3995 */ + "Get-Subscription-Attributes", /* RFC 3995 */ + "Get-Subscriptions", /* RFC 3995 */ + "Renew-Subscription", /* RFC 3995 */ + "Cancel-Subscription", /* RFC 3995 */ + "Get-Notifications", /* RFC 3996 */ "(Send-Notifications)", - "(Get-Resource-Attributes)", + "Get-Resource-Attributes", /* IPP System */ "(Get-Resource-Data)", /* 0x0020 - 0x002f */ - "(Get-Resources)", + "Get-Resources", /* IPP System */ "(Get-Printer-Support-Files)", - "Enable-Printer", - "Disable-Printer", - "Pause-Printer-After-Current-Job", - "Hold-New-Jobs", - "Release-Held-New-Jobs", - "Deactivate-Printer", - "Activate-Printer", - "Restart-Printer", - "Shutdown-Printer", - "Startup-Printer", - "Reprocess-Job", - "Cancel-Current-Job", - "Suspend-Current-Job", - "Resume-Job", + "Enable-Printer", /* RFC 3998 */ + "Disable-Printer", /* RFC 3998 */ + "Pause-Printer-After-Current-Job", /* RFC 3998 */ + "Hold-New-Jobs", /* RFC 3998 */ + "Release-Held-New-Jobs", /* RFC 3998 */ + "Deactivate-Printer", /* RFC 3998 */ + "Activate-Printer", /* RFC 3998 */ + "Restart-Printer", /* RFC 3998 */ + "Shutdown-Printer", /* RFC 3998 */ + "Startup-Printer", /* RFC 3998 */ + "Reprocess-Job", /* RFC 3998 */ + "Cancel-Current-Job", /* RFC 3998 */ + "Suspend-Current-Job", /* RFC 3998 */ + "Resume-Job", /* RFC 3998 */ /* 0x0030 - 0x003f */ - "Promote-Job", - "Schedule-Job-After", + "Promote-Job", /* RFC 3998 */ + "Schedule-Job-After", /* RFC 3998 */ "0x0032", - "Cancel-Document", - "Get-Document-Attributes", - "Get-Documents", - "Delete-Document", - "Set-Document-Attributes", - "Cancel-Jobs", - "Cancel-My-Jobs", - "Resubmit-Job", - "Close-Job", - "Identify-Printer", - "Validate-Document", - "Add-Document-Images", - "Acknowledge-Document", + "Cancel-Document", /* IPP DocObject */ + "Get-Document-Attributes", /* IPP DocObject */ + "Get-Documents", /* IPP DocObject */ + "Delete-Document", /* IPP DocObject */ + "Set-Document-Attributes", /* IPP DocObject */ + "Cancel-Jobs", /* IPP JPS2 */ + "Cancel-My-Jobs", /* IPP JPS2 */ + "Resubmit-Job", /* IPP JPS2 */ + "Close-Job", /* IPP JPS2 */ + "Identify-Printer", /* IPP JPS3 */ + "Validate-Document", /* IPP JPS3 */ + "Add-Document-Images", /* IPP Scan */ + "Acknowledge-Document", /* IPP INFRA */ - /* 0x0040 - 0x004a */ - "Acknowledge-Identify-Printer", - "Acknowledge-Job", - "Fetch-Document", - "Fetch-Job", - "Get-Output-Device-Attributes", - "Update-Active-Jobs", - "Deregister-Output-Device", - "Update-Document-Status", - "Update-Job-Status", - "Update-Output-Device-Attributes", - "Get-Next-Document-Data" + /* 0x0040 - 0x004f */ + "Acknowledge-Identify-Printer", /* IPP INFRA */ + "Acknowledge-Job", /* IPP INFRA */ + "Fetch-Document", /* IPP INFRA */ + "Fetch-Job", /* IPP INFRA */ + "Get-Output-Device-Attributes", /* IPP INFRA */ + "Update-Active-Jobs", /* IPP INFRA */ + "Deregister-Output-Device", /* IPP INFRA */ + "Update-Document-Status", /* IPP INFRA */ + "Update-Job-Status", /* IPP INFRA */ + "Update-Output-Device-Attributes", /* IPP INFRA */ + "Get-Next-Document-Data", /* IPP Scan */ + "Allocate-Printer-Resources", /* IPP System */ + "Create-Printer", /* IPP System */ + "Deallocate-Printer-Resources", /* IPP System */ + "Delete-Printer", /* IPP System */ + "Get-Printers", /* IPP System */ + + /* 0x0050 - 0x005f */ + "Shutdown-One-Printer", /* IPP System */ + "Startup-One-Printer", /* IPP System */ + "Cancel-Resource", /* IPP System */ + "Create-Resource", /* IPP System */ + "Install-Resource", /* IPP System */ + "Send-Resource-Data", /* IPP System */ + "Set-Resource-Attributes", /* IPP System */ + "Create-Resource-Subscriptions", /* IPP System */ + "Create-System-Subscriptions", /* IPP System */ + "Disable-All-Printers", /* IPP System */ + "Enable-All-Printers", /* IPP System */ + "Get-System-Attributes", /* IPP System */ + "Get-System-Supported-Values", /* IPP System */ + "Pause-All-Printers", /* IPP System */ + "Pause-All-Printers-After-Current-Job", /* IPP System */ + "Register-Output-Device", /* IPP System */ + + /* 0x0060 - 0x0064 */ + "Restart-System", /* IPP System */ + "Resume-All-Printers", /* IPP System */ + "Set-System-Attributes", /* IPP System */ + "Shutdown-All-Printers", /* IPP System */ + "Startup-All-Printers" /* IPP System */ }, * const ipp_cups_ops[] = { @@ -261,14 +287,15 @@ static const char * const ipp_std_ops[] = "unsupported-attributes-tag", /* 0x05 */ "subscription-attributes-tag", - /* 0x06 */ + /* 0x06 - RFC 3995 */ "event-notification-attributes-tag", - /* 0x07 */ - "(resource-attributes-tag)", - /* 0x08 */ + /* 0x07 - RFC 3995 */ + "resource-attributes-tag", + /* 0x08 - IPP System */ "document-attributes-tag", - /* 0x09 */ - "0x0a", /* 0x0a */ + /* 0x09 - IPP DocObject */ + "system-attributes-tag", + /* 0x0a - IPP System */ "0x0b", /* 0x0b */ "0x0c", /* 0x0c */ "0x0d", /* 0x0d */ @@ -279,9 +306,9 @@ static const char * const ipp_std_ops[] = "unknown", /* 0x12 */ "no-value", /* 0x13 */ "0x14", /* 0x14 */ - "not-settable", /* 0x15 */ - "delete-attribute", /* 0x16 */ - "admin-define", /* 0x17 */ + "not-settable", /* 0x15 - RFC 3380 */ + "delete-attribute", /* 0x16 - RFC 3380 */ + "admin-define", /* 0x17 - RFC 3380 */ "0x18", /* 0x18 */ "0x19", /* 0x19 */ "0x1a", /* 0x1a */ @@ -339,7 +366,7 @@ static const char * const ipp_document_states[] = "pending", "4", "processing", - "processing-stopped", /* IPPSIX */ + "processing-stopped", /* IPP INFRA */ "canceled", "aborted", "completed" @@ -358,8 +385,8 @@ static const char * const ipp_document_states[] = "bale", "booklet-maker", "jog-offset", - "coat", /* Finishings 2.0 */ - "laminate", /* Finishings 2.0 */ + "coat", /* IPP Finishings 2.0 */ + "laminate", /* IPP Finishings 2.0 */ "17", "18", "19", @@ -375,10 +402,10 @@ static const char * const ipp_document_states[] = "staple-dual-top", "staple-dual-right", "staple-dual-bottom", - "staple-triple-left", /* Finishings 2.0 */ - "staple-triple-top", /* Finishings 2.0 */ - "staple-triple-right",/* Finishings 2.0 */ - "staple-triple-bottom",/* Finishings 2.0 */ + "staple-triple-left", /* IPP Finishings 2.0 */ + "staple-triple-top", /* IPP Finishings 2.0 */ + "staple-triple-right",/* IPP Finishings 2.0 */ + "staple-triple-bottom",/* IPP Finishings 2.0 */ "36", "37", "38", @@ -413,38 +440,38 @@ static const char * const ipp_document_states[] = "67", "68", "69", - "punch-top-left", /* Finishings 2.0 */ - "punch-bottom-left", /* Finishings 2.0 */ - "punch-top-right", /* Finishings 2.0 */ - "punch-bottom-right", /* Finishings 2.0 */ - "punch-dual-left", /* Finishings 2.0 */ - "punch-dual-top", /* Finishings 2.0 */ - "punch-dual-right", /* Finishings 2.0 */ - "punch-dual-bottom", /* Finishings 2.0 */ - "punch-triple-left", /* Finishings 2.0 */ - "punch-triple-top", /* Finishings 2.0 */ - "punch-triple-right", /* Finishings 2.0 */ - "punch-triple-bottom",/* Finishings 2.0 */ - "punch-quad-left", /* Finishings 2.0 */ - "punch-quad-top", /* Finishings 2.0 */ - "punch-quad-right", /* Finishings 2.0 */ - "punch-quad-bottom", /* Finishings 2.0 */ - "punch-multiple-left",/* Finishings 2.1/Canon */ - "punch-multiple-top", /* Finishings 2.1/Canon */ - "punch-multiple-right",/* Finishings 2.1/Canon */ - "punch-multiple-bottom",/* Finishings 2.1/Canon */ - "fold-accordian", /* Finishings 2.0 */ - "fold-double-gate", /* Finishings 2.0 */ - "fold-gate", /* Finishings 2.0 */ - "fold-half", /* Finishings 2.0 */ - "fold-half-z", /* Finishings 2.0 */ - "fold-left-gate", /* Finishings 2.0 */ - "fold-letter", /* Finishings 2.0 */ - "fold-parallel", /* Finishings 2.0 */ - "fold-poster", /* Finishings 2.0 */ - "fold-right-gate", /* Finishings 2.0 */ - "fold-z", /* Finishings 2.0 */ - "fold-engineering-z" /* Finishings 2.1 */ + "punch-top-left", /* IPP Finishings 2.0 */ + "punch-bottom-left", /* IPP Finishings 2.0 */ + "punch-top-right", /* IPP Finishings 2.0 */ + "punch-bottom-right", /* IPP Finishings 2.0 */ + "punch-dual-left", /* IPP Finishings 2.0 */ + "punch-dual-top", /* IPP Finishings 2.0 */ + "punch-dual-right", /* IPP Finishings 2.0 */ + "punch-dual-bottom", /* IPP Finishings 2.0 */ + "punch-triple-left", /* IPP Finishings 2.0 */ + "punch-triple-top", /* IPP Finishings 2.0 */ + "punch-triple-right", /* IPP Finishings 2.0 */ + "punch-triple-bottom",/* IPP Finishings 2.0 */ + "punch-quad-left", /* IPP Finishings 2.0 */ + "punch-quad-top", /* IPP Finishings 2.0 */ + "punch-quad-right", /* IPP Finishings 2.0 */ + "punch-quad-bottom", /* IPP Finishings 2.0 */ + "punch-multiple-left",/* IPP Finishings 2.1/Canon */ + "punch-multiple-top", /* IPP Finishings 2.1/Canon */ + "punch-multiple-right",/* IPP Finishings 2.1/Canon */ + "punch-multiple-bottom",/* IPP Finishings 2.1/Canon */ + "fold-accordian", /* IPP Finishings 2.0 */ + "fold-double-gate", /* IPP Finishings 2.0 */ + "fold-gate", /* IPP Finishings 2.0 */ + "fold-half", /* IPP Finishings 2.0 */ + "fold-half-z", /* IPP Finishings 2.0 */ + "fold-left-gate", /* IPP Finishings 2.0 */ + "fold-letter", /* IPP Finishings 2.0 */ + "fold-parallel", /* IPP Finishings 2.0 */ + "fold-poster", /* IPP Finishings 2.0 */ + "fold-right-gate", /* IPP Finishings 2.0 */ + "fold-z", /* IPP Finishings 2.0 */ + "fold-engineering-z" /* IPP Finishings 2.1 */ }, * const ipp_finishings_vendor[] = { @@ -591,7 +618,21 @@ static const char * const ipp_document_states[] = { /* printer-state enums */ "idle", "processing", - "stopped", + "stopped" + }, + * const ipp_resource_states[] = + { /* resource-state enums */ + "pending", + "available", + "installed", + "canceled", + "aborted" + }, + * const ipp_system_states[] = + { /* system-state enums */ + "idle", + "processing", + "stopped" }; @@ -849,6 +890,7 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ int i, j, /* Looping vars */ count, /* Number of values */ added; /* Was name added? */ + ipp_op_t op; /* IPP operation code */ ipp_attribute_t *requested; /* requested-attributes attribute */ cups_array_t *ra; /* Requested attributes array */ const char *value; /* Current value */ @@ -884,14 +926,16 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "document-state-message", "document-state-reasons", "document-uri", - "document-uuid", + "document-uuid", /* IPP JPS3 */ "errors-count", "finishings-actual", "finishings-col-actual", "force-front-side-actual", "imposition-template-actual", "impressions", + "impressions-col", "impressions-completed", + "impressions-completed-col", "impressions-completed-current-copy", "insert-sheet-actual", "k-octets", @@ -902,7 +946,9 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "media-col-actual", "media-input-tray-check-actual", "media-sheets", + "media-sheets-col", "media-sheets-completed", + "media-sheets-completed-col", "more-info", "multiple-object-handling-actual", /* IPP 3D */ "number-up-actual", @@ -914,7 +960,9 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "page-order-received-actual", "page-ranges-actual", "pages", + "pages-col", "pages-completed", + "pages-completed-col", "pages-completed-current-copy", "platform-temperature-actual", /* IPP 3D */ "presentation-direction-number-up-actual", @@ -946,6 +994,12 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ }; static const char * const document_template[] = { /* document-template group */ + "chamber-humidity", /* IPP 3D */ + "chamber-humidity-default", /* IPP 3D */ + "chamber-humidity-supported", /* IPP 3D */ + "chamber-temperature", /* IPP 3D */ + "chamber-temperature-default", /* IPP 3D */ + "chamber-temperature-supported", /* IPP 3D */ "copies", "copies-default", "copies-supported", @@ -960,9 +1014,12 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "feed-orientation-supported", "finishings", "finishings-col", + "finishings-col-database", "finishings-col-default", + "finishings-col-ready", "finishings-col-supported", "finishings-default", + "finishings-ready", "finishings-supported", "font-name-requested", "font-name-requested-default", @@ -1001,6 +1058,7 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "media-bottom-margin-supported", "media-col", "media-col-default", + "media-col-ready", "media-col-supported", "media-color-supported", "media-default", @@ -1015,6 +1073,7 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "media-left-margin-supported", "media-order-count-supported", "media-pre-printed-supported", + "media-ready", "media-recycled-supported", "media-right-margin-supported", "media-size-supported", @@ -1132,6 +1191,8 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ }; static const char * const job_description[] = { /* job-description group */ + "chamber-humidity-actual", /* IPP 3D */ + "chamber-temperature-actual", /* IPP 3D */ "compression-supplied", "copies-actual", "cover-back-actual", @@ -1175,27 +1236,34 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "job-hold-until-actual", "job-id", "job-impressions", + "job-impressions-col", "job-impressions-completed", + "job-impressions-completed-col", "job-k-octets", "job-k-octets-processed", "job-mandatory-attributes", "job-media-progress", /* CUPS extension */ "job-media-sheets", + "job-media-sheets-col", "job-media-sheets-completed", + "job-media-sheets-completed-col", "job-message-from-operator", "job-more-info", "job-name", "job-originating-host-name", /* CUPS extension */ "job-originating-user-name", - "job-originating-user-uri", + "job-originating-user-uri", /* IPP JPS3 */ "job-pages", + "job-pages-col", "job-pages-completed", + "job-pages-completed-col", "job-pages-completed-current-copy", "job-printer-state-message", /* CUPS extension */ "job-printer-state-reasons", /* CUPS extension */ "job-printer-up-time", "job-printer-uri", "job-priority-actual", + "job-resource-ids", /* IPP System */ "job-save-printer-make-and-model", "job-sheet-message-actual", "job-sheets-actual", @@ -1204,7 +1272,7 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "job-state-message", "job-state-reasons", "job-uri", - "job-uuid", + "job-uuid", /* IPP JPS3 */ "materials-col-actual", /* IPP 3D */ "media-actual", "media-col-actual", @@ -1218,6 +1286,10 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "original-requesting-user-name", "output-bin-actual", "output-device-assigned", + "output-device-job-state", /* IPP INFRA */ + "output-device-job-state-message", /* IPP INFRA */ + "output-device-job-state-reasons", /* IPP INFRA */ + "output-device-uuid-assigned", /* IPP INFRA */ "overrides-actual", "page-delivery-actual", "page-order-received-actual", @@ -1255,6 +1327,12 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ static const char * const job_template[] = { /* job-template group */ "accuracy-units-supported", /* IPP 3D */ + "chamber-humidity", /* IPP 3D */ + "chamber-humidity-default", /* IPP 3D */ + "chamber-humidity-supported", /* IPP 3D */ + "chamber-temperature", /* IPP 3D */ + "chamber-temperature-default", /* IPP 3D */ + "chamber-temperature-supported", /* IPP 3D */ "confirmation-sheet-print", /* IPP FaxOut */ "confirmation-sheet-print-default", "copies", @@ -1277,9 +1355,12 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "feed-orientation-supported", "finishings", "finishings-col", + "finishings-col-database", "finishings-col-default", + "finishings-col-ready", "finishings-col-supported", "finishings-default", + "finishings-ready", "finishings-supported", "font-name-requested", "font-name-requested-default", @@ -1383,6 +1464,7 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "media-bottom-margin-supported", "media-col", "media-col-default", + "media-col-ready", "media-col-supported", "media-color-supported", "media-default", @@ -1397,6 +1479,7 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "media-left-margin-supported", "media-order-count-supported", "media-pre-printed-supported", + "media-ready", "media-recycled-supported", "media-right-margin-supported", "media-size-supported", @@ -1425,8 +1508,8 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "output-bin-default", "output-bin-supported", "output-device", - "output-device-default", "output-device-supported", + "output-device-uuid-supported", /* IPP INFRA */ "output-mode", /* CUPS extension */ "output-mode-default", /* CUPS extension */ "output-mode-supported", /* CUPS extension */ @@ -1540,6 +1623,8 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ static const char * const printer_description[] = { /* printer-description group */ "auth-info-required", /* CUPS extension */ + "chamber-humidity-current", /* IPP 3D */ + "chamber-temperature-current", /* IPP 3D */ "charset-configured", "charset-supported", "color-supported", @@ -1562,6 +1647,8 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "document-natural-language-default", "document-natural-language-supported", "document-password-supported", + "document-privacy-attributes", /* IPP Privacy Attributes */ + "document-privacy-scope", /* IPP Privacy Attributes */ "generated-natural-language-supported", "identify-actions-default", "identify-actions-supported", @@ -1582,10 +1669,14 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "job-page-limit", /* CUPS extension */ "job-password-encryption-supported", "job-password-supported", + "job-presets-supported", /* IPP Presets */ + "job-privacy-attributes", /* IPP Privacy Attributes */ + "job-privacy-scope", /* IPP Privacy Attributes */ "job-quota-period", /* CUPS extension */ "job-resolvers-supported", "job-settable-attributes-supported", "job-spooling-supported", + "job-triggers-supported", /* IPP Presets */ "jpeg-k-octets-supported", /* CUPS extension */ "jpeg-x-dimension-supported", /* CUPS extension */ "jpeg-y-dimension-supported", /* CUPS extension */ @@ -1599,8 +1690,6 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "marker-message", /* CUPS extension */ "marker-names", /* CUPS extension */ "marker-types", /* CUPS extension */ - "media-col-ready", - "media-ready", "member-names", /* CUPS extension */ "member-uris", /* CUPS extension */ "multiple-destination-uris-supported",/* IPP FaxOut */ @@ -1615,14 +1704,20 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "pdf-features-supported", /* IPP 3D */ "pdf-versions-supported", /* CUPS extension */ "pdl-override-supported", + "platform-shape", /* IPP 3D */ "port-monitor", /* CUPS extension */ "port-monitor-supported", /* CUPS extension */ "preferred-attributes-supported", "printer-alert", "printer-alert-description", + "printer-camera-image-uri", /* IPP 3D */ "printer-charge-info", "printer-charge-info-uri", "printer-commands", /* CUPS extension */ + "printer-config-change-date-time", + "printer-config-change-time", + "printer-config-changes", /* IPP System */ + "printer-contact-col", /* IPP System */ "printer-current-time", "printer-detailed-status-messages", "printer-device-id", @@ -1640,7 +1735,7 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "printer-get-attributes-supported", "printer-icc-profiles", "printer-icons", - "printer-id", /* CUPS extension */ + "printer-id", /* IPP System */ "printer-info", "printer-input-tray", /* IPP JPS3 */ "printer-is-accepting-jobs", @@ -1660,7 +1755,7 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "printer-organization", "printer-organizational-unit", "printer-output-tray", /* IPP JPS3 */ - "printer-queue-id", /* CUPS extension */ + "printer-service-type", /* IPP System */ "printer-settable-attributes-supported", "printer-state", "printer-state-change-date-time", @@ -1684,7 +1779,15 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "requesting-user-name-allowed", /* CUPS extension */ "requesting-user-name-denied", /* CUPS extension */ "requesting-user-uri-supported", + "smi2699-auth-print-group", /* PWG ippserver extension */ + "smi2699-auth-proxy-group", /* PWG ippserver extension */ + "smi2699-device-command", /* PWG ippserver extension */ + "smi2699-device-format", /* PWG ippserver extension */ + "smi2699-device-name", /* PWG ippserver extension */ + "smi2699-device-uri", /* PWG ippserver extension */ "subordinate-printers-supported", + "subscription-privacy-attributes", /* IPP Privacy Attributes */ + "subscription-privacy-scope", /* IPP Privacy Attributes */ "urf-supported", /* CUPS extension */ "uri-authentication-supported", "uri-security-supported", @@ -1694,17 +1797,54 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "xri-security-supported", "xri-uri-scheme-supported" }; + static const char * const resource_description[] = + { /* resource-description group - IPP System */ + "resource-info", + "resource-name" + }; + static const char * const resource_status[] = + { /* resource-status group - IPP System */ + "date-time-at-canceled", + "date-time-at-creation", + "date-time-at-installed", + "resource-data-uri", + "resource-format", + "resource-id", + "resource-k-octets", + "resource-state", + "resource-state-message", + "resource-state-reasons", + "resource-string-version", + "resource-type", + "resource-use-count", + "resource-uuid", + "resource-version", + "time-at-canceled", + "time-at-creation", + "time-at-installed" + }; + static const char * const resource_template[] = + { /* resource-template group - IPP System */ + "resource-format", + "resource-format-supported", + "resource-info", + "resource-name", + "resource-type", + "resource-type-supported" + }; static const char * const subscription_description[] = { /* subscription-description group */ "notify-job-id", "notify-lease-expiration-time", "notify-printer-up-time", "notify-printer-uri", + "notify-resource-id", /* IPP System */ + "notify-system-uri", /* IPP System */ "notify-sequence-number", "notify-subscriber-user-name", "notify-subscriber-user-uri", "notify-subscription-id", - "subscriptions-uuid" + "notify-subscription-uuid" /* IPP JPS3 */ }; static const char * const subscription_template[] = { /* subscription-template group */ @@ -1726,21 +1866,78 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ "notify-time-interval", "notify-user-data" }; + static const char * const system_description[] = + { /* system-description group - IPP System */ + "charset-configured", + "charset-supported", + "generated-natural-language-supported", + "ipp-features-supported", + "ipp-versions-supported", + "natural-language-configured", + "operations-supported", + "power-calendar-policy-col", + "power-event-policy-col", + "power-timeout-policy-col", + "printer-creation-attributes-supported", + "resource-settable-attributes-supported", + "smi2699-auth-group-supported", /* PWG ippserver extension */ + "smi2699-device-command-supported", /* PWG ippserver extension */ + "smi2699-device-format-format", /* PWG ippserver extension */ + "smi2699-device-uri-schemes-supported", + /* PWG ippserver extension */ + "system-contact-col", + "system-current-time", + "system-default-printer-id", + "system-device-id", + "system-geo-location", + "system-info", + "system-location", + "system-mandatory-printer-attributes", + "system-make-and-model", + "system-message-from-operator", + "system-name", + "system-settable-attributes-supported", + "system-strings-languages-supported", + "system-strings-uri", + "system-xri-supported" + }; + static const char * const system_status[] = + { /* system-status group - IPP System */ + "power-log-col", + "power-state-capabilities-col", + "power-state-counters-col", + "power-state-monitor-col", + "power-state-transitions-col", + "system-config-change-date-time", + "system-config-change-time", + "system-config-changes", + "system-configured-printers", + "system-configured-resources", + "system-serial-number", + "system-state", + "system-state-change-date-time", + "system-state-change-time", + "system-state-message", + "system-state-reasons", + "system-up-time", + "system-uuid" + }; /* * Get the requested-attributes attribute... */ - if ((requested = ippFindAttribute(request, "requested-attributes", - IPP_TAG_KEYWORD)) == NULL) + op = ippGetOperation(request); + + if ((requested = ippFindAttribute(request, "requested-attributes", IPP_TAG_KEYWORD)) == NULL) { /* * The Get-Jobs operation defaults to "job-id" and "job-uri", all others * default to "all"... */ - if (ippGetOperation(request) == IPP_OP_GET_JOBS) + if (op == IPP_OP_GET_JOBS) { ra = cupsArrayNew((cups_array_func_t)strcmp, NULL); cupsArrayAdd(ra, "job-id"); @@ -1771,12 +1968,9 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ added = 0; value = ippGetString(requested, i, NULL); - if (!strcmp(value, "document-description") || !strcmp(value, "all")) + if (!strcmp(value, "document-description") || (!strcmp(value, "all") && (op == IPP_OP_GET_JOB_ATTRIBUTES || op == IPP_OP_GET_JOBS || op == IPP_OP_GET_DOCUMENT_ATTRIBUTES || op == IPP_OP_GET_DOCUMENTS))) { - for (j = 0; - j < (int)(sizeof(document_description) / - sizeof(document_description[0])); - j ++) + for (j = 0; j < (int)(sizeof(document_description) / sizeof(document_description[0])); j ++) cupsArrayAdd(ra, (void *)document_description[j]); added = 1; @@ -1784,67 +1978,92 @@ ippCreateRequestedArray(ipp_t *request) /* I - IPP request */ if (!strcmp(value, "document-template") || !strcmp(value, "all")) { - for (j = 0; - j < (int)(sizeof(document_template) / sizeof(document_template[0])); - j ++) + for (j = 0; j < (int)(sizeof(document_template) / sizeof(document_template[0])); j ++) cupsArrayAdd(ra, (void *)document_template[j]); added = 1; } - if (!strcmp(value, "job-description") || !strcmp(value, "all")) + if (!strcmp(value, "job-description") || (!strcmp(value, "all") && (op == IPP_OP_GET_JOB_ATTRIBUTES || op == IPP_OP_GET_JOBS))) { - for (j = 0; - j < (int)(sizeof(job_description) / sizeof(job_description[0])); - j ++) + for (j = 0; j < (int)(sizeof(job_description) / sizeof(job_description[0])); j ++) cupsArrayAdd(ra, (void *)job_description[j]); added = 1; } - if (!strcmp(value, "job-template") || !strcmp(value, "all")) + if (!strcmp(value, "job-template") || (!strcmp(value, "all") && (op == IPP_OP_GET_JOB_ATTRIBUTES || op == IPP_OP_GET_JOBS || op == IPP_OP_GET_PRINTER_ATTRIBUTES))) { - for (j = 0; - j < (int)(sizeof(job_template) / sizeof(job_template[0])); - j ++) + for (j = 0; j < (int)(sizeof(job_template) / sizeof(job_template[0])); j ++) cupsArrayAdd(ra, (void *)job_template[j]); added = 1; } - if (!strcmp(value, "printer-description") || !strcmp(value, "all")) + if (!strcmp(value, "printer-description") || (!strcmp(value, "all") && (op == IPP_OP_GET_PRINTER_ATTRIBUTES || op == IPP_OP_GET_PRINTERS || op == IPP_OP_CUPS_GET_DEFAULT || op == IPP_OP_CUPS_GET_PRINTERS || op == IPP_OP_CUPS_GET_CLASSES))) { - for (j = 0; - j < (int)(sizeof(printer_description) / - sizeof(printer_description[0])); - j ++) + for (j = 0; j < (int)(sizeof(printer_description) / sizeof(printer_description[0])); j ++) cupsArrayAdd(ra, (void *)printer_description[j]); added = 1; } - if (!strcmp(value, "subscription-description") || !strcmp(value, "all")) + if (!strcmp(value, "resource-description") || (!strcmp(value, "all") && (op == IPP_OP_GET_RESOURCE_ATTRIBUTES || op == IPP_OP_GET_RESOURCES))) { - for (j = 0; - j < (int)(sizeof(subscription_description) / - sizeof(subscription_description[0])); - j ++) + for (j = 0; j < (int)(sizeof(resource_description) / sizeof(resource_description[0])); j ++) + cupsArrayAdd(ra, (void *)resource_description[j]); + + added = 1; + } + + if (!strcmp(value, "resource-status") || (!strcmp(value, "all") && (op == IPP_OP_GET_RESOURCE_ATTRIBUTES || op == IPP_OP_GET_RESOURCES))) + { + for (j = 0; j < (int)(sizeof(resource_status) / sizeof(resource_status[0])); j ++) + cupsArrayAdd(ra, (void *)resource_status[j]); + + added = 1; + } + + if (!strcmp(value, "resource-template") || (!strcmp(value, "all") && (op == IPP_OP_GET_RESOURCE_ATTRIBUTES || op == IPP_OP_GET_RESOURCES || op == IPP_OP_GET_SYSTEM_ATTRIBUTES))) + { + for (j = 0; j < (int)(sizeof(resource_template) / sizeof(resource_template[0])); j ++) + cupsArrayAdd(ra, (void *)resource_template[j]); + + added = 1; + } + + if (!strcmp(value, "subscription-description") || (!strcmp(value, "all") && (op == IPP_OP_GET_SUBSCRIPTION_ATTRIBUTES || op == IPP_OP_GET_SUBSCRIPTIONS))) + { + for (j = 0; j < (int)(sizeof(subscription_description) / sizeof(subscription_description[0])); j ++) cupsArrayAdd(ra, (void *)subscription_description[j]); added = 1; } - if (!strcmp(value, "subscription-template") || !strcmp(value, "all")) + if (!strcmp(value, "subscription-template") || (!strcmp(value, "all") && (op == IPP_OP_GET_SUBSCRIPTION_ATTRIBUTES || op == IPP_OP_GET_SUBSCRIPTIONS))) { - for (j = 0; - j < (int)(sizeof(subscription_template) / - sizeof(subscription_template[0])); - j ++) + for (j = 0; j < (int)(sizeof(subscription_template) / sizeof(subscription_template[0])); j ++) cupsArrayAdd(ra, (void *)subscription_template[j]); added = 1; } + if (!strcmp(value, "system-description") || (!strcmp(value, "all") && op == IPP_OP_GET_SYSTEM_ATTRIBUTES)) + { + for (j = 0; j < (int)(sizeof(system_description) / sizeof(system_description[0])); j ++) + cupsArrayAdd(ra, (void *)system_description[j]); + + added = 1; + } + + if (!strcmp(value, "system-status") || (!strcmp(value, "all") && op == IPP_OP_GET_SYSTEM_ATTRIBUTES)) + { + for (j = 0; j < (int)(sizeof(system_status) / sizeof(system_status[0])); j ++) + cupsArrayAdd(ra, (void *)system_status[j]); + + added = 1; + } + if (!added) cupsArrayAdd(ra, (void *)value); } @@ -1868,59 +2087,31 @@ ippEnumString(const char *attrname, /* I - Attribute name */ * Check for standard enum values... */ - if (!strcmp(attrname, "document-state") && - enumvalue >= 3 && - enumvalue < (3 + (int)(sizeof(ipp_document_states) / - sizeof(ipp_document_states[0])))) + if (!strcmp(attrname, "document-state") && enumvalue >= 3 && enumvalue < (3 + (int)(sizeof(ipp_document_states) / sizeof(ipp_document_states[0])))) return (ipp_document_states[enumvalue - 3]); - else if (!strcmp(attrname, "finishings") || - !strcmp(attrname, "finishings-actual") || - !strcmp(attrname, "finishings-default") || - !strcmp(attrname, "finishings-ready") || - !strcmp(attrname, "finishings-supported") || - !strcmp(attrname, "job-finishings") || - !strcmp(attrname, "job-finishings-default") || - !strcmp(attrname, "job-finishings-supported")) + else if (!strcmp(attrname, "finishings") || !strcmp(attrname, "finishings-actual") || !strcmp(attrname, "finishings-default") || !strcmp(attrname, "finishings-ready") || !strcmp(attrname, "finishings-supported") || !strcmp(attrname, "job-finishings") || !strcmp(attrname, "job-finishings-default") || !strcmp(attrname, "job-finishings-supported")) { - if (enumvalue >= 3 && - enumvalue < (3 + (int)(sizeof(ipp_finishings) / - sizeof(ipp_finishings[0])))) + if (enumvalue >= 3 && enumvalue < (3 + (int)(sizeof(ipp_finishings) / sizeof(ipp_finishings[0])))) return (ipp_finishings[enumvalue - 3]); - else if (enumvalue >= 0x40000000 && - enumvalue <= (0x40000000 + (int)(sizeof(ipp_finishings_vendor) / - sizeof(ipp_finishings_vendor[0])))) + else if (enumvalue >= 0x40000000 && enumvalue <= (0x40000000 + (int)(sizeof(ipp_finishings_vendor) / sizeof(ipp_finishings_vendor[0])))) return (ipp_finishings_vendor[enumvalue - 0x40000000]); } - else if ((!strcmp(attrname, "job-collation-type") || - !strcmp(attrname, "job-collation-type-actual")) && - enumvalue >= 3 && - enumvalue < (3 + (int)(sizeof(ipp_job_collation_types) / - sizeof(ipp_job_collation_types[0])))) + else if ((!strcmp(attrname, "job-collation-type") || !strcmp(attrname, "job-collation-type-actual")) && enumvalue >= 3 && enumvalue < (3 + (int)(sizeof(ipp_job_collation_types) / sizeof(ipp_job_collation_types[0])))) return (ipp_job_collation_types[enumvalue - 3]); - else if (!strcmp(attrname, "job-state") && - enumvalue >= IPP_JSTATE_PENDING && enumvalue <= IPP_JSTATE_COMPLETED) + else if (!strcmp(attrname, "job-state") && enumvalue >= IPP_JSTATE_PENDING && enumvalue <= IPP_JSTATE_COMPLETED) return (ipp_job_states[enumvalue - IPP_JSTATE_PENDING]); else if (!strcmp(attrname, "operations-supported")) return (ippOpString((ipp_op_t)enumvalue)); - else if ((!strcmp(attrname, "orientation-requested") || - !strcmp(attrname, "orientation-requested-actual") || - !strcmp(attrname, "orientation-requested-default") || - !strcmp(attrname, "orientation-requested-supported")) && - enumvalue >= 3 && - enumvalue < (3 + (int)(sizeof(ipp_orientation_requesteds) / - sizeof(ipp_orientation_requesteds[0])))) + else if ((!strcmp(attrname, "orientation-requested") || !strcmp(attrname, "orientation-requested-actual") || !strcmp(attrname, "orientation-requested-default") || !strcmp(attrname, "orientation-requested-supported")) && enumvalue >= 3 && enumvalue < (3 + (int)(sizeof(ipp_orientation_requesteds) / sizeof(ipp_orientation_requesteds[0])))) return (ipp_orientation_requesteds[enumvalue - 3]); - else if ((!strcmp(attrname, "print-quality") || - !strcmp(attrname, "print-quality-actual") || - !strcmp(attrname, "print-quality-default") || - !strcmp(attrname, "print-quality-supported")) && - enumvalue >= 3 && - enumvalue < (3 + (int)(sizeof(ipp_print_qualities) / - sizeof(ipp_print_qualities[0])))) + else if ((!strcmp(attrname, "print-quality") || !strcmp(attrname, "print-quality-actual") || !strcmp(attrname, "print-quality-default") || !strcmp(attrname, "print-quality-supported")) && enumvalue >= 3 && enumvalue < (3 + (int)(sizeof(ipp_print_qualities) / sizeof(ipp_print_qualities[0])))) return (ipp_print_qualities[enumvalue - 3]); - else if (!strcmp(attrname, "printer-state") && - enumvalue >= IPP_PSTATE_IDLE && enumvalue <= IPP_PSTATE_STOPPED) + else if (!strcmp(attrname, "printer-state") && enumvalue >= IPP_PSTATE_IDLE && enumvalue <= IPP_PSTATE_STOPPED) return (ipp_printer_states[enumvalue - IPP_PSTATE_IDLE]); + else if (!strcmp(attrname, "resource-state") && enumvalue >= IPP_RSTATE_PENDING && enumvalue <= IPP_RSTATE_ABORTED) + return (ipp_resource_states[enumvalue - IPP_RSTATE_PENDING]); + else if (!strcmp(attrname, "system-state") && enumvalue >= IPP_SSTATE_IDLE && enumvalue <= IPP_SSTATE_STOPPED) + return (ipp_system_states[enumvalue - IPP_SSTATE_IDLE]); /* * Not a standard enum value, just return the decimal equivalent... @@ -2012,6 +2203,16 @@ ippEnumValue(const char *attrname, /* I - Attribute name */ num_strings = (int)(sizeof(ipp_printer_states) / sizeof(ipp_printer_states[0])); strings = ipp_printer_states; } + else if (!strcmp(attrname, "resource-state")) + { + num_strings = (int)(sizeof(ipp_resource_states) / sizeof(ipp_resource_states[0])); + strings = ipp_resource_states; + } + else if (!strcmp(attrname, "system-state")) + { + num_strings = (int)(sizeof(ipp_system_states) / sizeof(ipp_system_states[0])); + strings = ipp_system_states; + } else return (-1); diff --git a/cups/ipp-vars.c b/cups/ipp-vars.c new file mode 100644 index 0000000..395b0eb --- /dev/null +++ b/cups/ipp-vars.c @@ -0,0 +1,250 @@ +/* + * IPP data file parsing functions. + * + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products. + * + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. + */ + +/* + * Include necessary headers... + */ + +#include +#include "ipp-private.h" +#include "string-private.h" +#include "debug-internal.h" + + +/* + * '_ippVarsDeinit()' - Free all memory associated with the IPP variables. + */ + +void +_ippVarsDeinit(_ipp_vars_t *v) /* I - IPP variables */ +{ + if (v->uri) + { + free(v->uri); + v->uri = NULL; + } + + cupsFreeOptions(v->num_vars, v->vars); + v->num_vars = 0; + v->vars = NULL; +} + + +/* + * '_ippVarsExpand()' - Expand variables in the source string. + */ + +void +_ippVarsExpand(_ipp_vars_t *v, /* I - IPP variables */ + char *dst, /* I - Destination buffer */ + const char *src, /* I - Source string */ + size_t dstsize) /* I - Destination buffer size */ +{ + char *dstptr, /* Pointer into destination */ + *dstend, /* End of destination */ + temp[256], /* Temporary string */ + *tempptr; /* Pointer into temporary string */ + const char *value; /* Value to substitute */ + + + dstptr = dst; + dstend = dst + dstsize - 1; + + while (*src && dstptr < dstend) + { + if (*src == '$') + { + /* + * Substitute a string/number... + */ + + if (!strncmp(src, "$$", 2)) + { + value = "$"; + src += 2; + } + else if (!strncmp(src, "$ENV[", 5)) + { + strlcpy(temp, src + 5, sizeof(temp)); + + for (tempptr = temp; *tempptr; tempptr ++) + if (*tempptr == ']') + break; + + if (*tempptr) + *tempptr++ = '\0'; + + value = getenv(temp); + src += tempptr - temp + 5; + } + else + { + if (src[1] == '{') + { + src += 2; + strlcpy(temp, src, sizeof(temp)); + if ((tempptr = strchr(temp, '}')) != NULL) + *tempptr = '\0'; + else + tempptr = temp + strlen(temp); + } + else + { + strlcpy(temp, src + 1, sizeof(temp)); + + for (tempptr = temp; *tempptr; tempptr ++) + if (!isalnum(*tempptr & 255) && *tempptr != '-' && *tempptr != '_') + break; + + if (*tempptr) + *tempptr = '\0'; + } + + value = _ippVarsGet(v, temp); + + src += tempptr - temp + 1; + } + + if (value) + { + strlcpy(dstptr, value, (size_t)(dstend - dstptr + 1)); + dstptr += strlen(dstptr); + } + } + else + *dstptr++ = *src++; + } + + *dstptr = '\0'; +} + + +/* + * '_ippVarsGet()' - Get a variable string. + */ + +const char * /* O - Value or @code NULL@ if not set */ +_ippVarsGet(_ipp_vars_t *v, /* I - IPP variables */ + const char *name) /* I - Variable name */ +{ + if (!v) + return (NULL); + else if (!strcmp(name, "uri")) + return (v->uri); + else if (!strcmp(name, "uriuser") || !strcmp(name, "username")) + return (v->username[0] ? v->username : NULL); + else if (!strcmp(name, "scheme") || !strcmp(name, "method")) + return (v->scheme); + else if (!strcmp(name, "hostname")) + return (v->host); + else if (!strcmp(name, "port")) + return (v->portstr); + else if (!strcmp(name, "resource")) + return (v->resource); + else if (!strcmp(name, "user")) + return (cupsUser()); + else + return (cupsGetOption(name, v->num_vars, v->vars)); +} + + +/* + * '_ippVarsInit()' - Initialize . + */ + +void +_ippVarsInit(_ipp_vars_t *v, /* I - IPP variables */ + _ipp_fattr_cb_t attrcb, /* I - Attribute (filter) callback */ + _ipp_ferror_cb_t errorcb, /* I - Error callback */ + _ipp_ftoken_cb_t tokencb) /* I - Token callback */ +{ + memset(v, 0, sizeof(_ipp_vars_t)); + + v->attrcb = attrcb; + v->errorcb = errorcb; + v->tokencb = tokencb; +} + + +/* + * '_ippVarsPasswordCB()' - Password callback using the IPP variables. + */ + +const char * /* O - Password string or @code NULL@ */ +_ippVarsPasswordCB( + const char *prompt, /* I - Prompt string (not used) */ + http_t *http, /* I - HTTP connection (not used) */ + const char *method, /* I - HTTP method (not used) */ + const char *resource, /* I - Resource path (not used) */ + void *user_data) /* I - IPP variables */ +{ + _ipp_vars_t *v = (_ipp_vars_t *)user_data; + /* I - IPP variables */ + + + (void)prompt; + (void)http; + (void)method; + (void)resource; + + if (v->username[0] && v->password && v->password_tries < 3) + { + v->password_tries ++; + + cupsSetUser(v->username); + + return (v->password); + } + else + { + return (NULL); + } +} + + +/* + * '_ippVarsSet()' - Set an IPP variable. + */ + +int /* O - 1 on success, 0 on failure */ +_ippVarsSet(_ipp_vars_t *v, /* I - IPP variables */ + const char *name, /* I - Variable name */ + const char *value) /* I - Variable value */ +{ + if (!strcmp(name, "uri")) + { + char uri[1024]; /* New printer URI */ + http_uri_status_t uri_status; /* URI status */ + + if ((uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, value, v->scheme, sizeof(v->scheme), v->username, sizeof(v->username), v->host, sizeof(v->host), &(v->port), v->resource, sizeof(v->resource))) < HTTP_URI_STATUS_OK) + return (0); + + if (v->username[0]) + { + if ((v->password = strchr(v->username, ':')) != NULL) + *(v->password)++ = '\0'; + } + + snprintf(v->portstr, sizeof(v->portstr), "%d", v->port); + + if (v->uri) + free(v->uri); + + httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), v->scheme, NULL, v->host, v->port, v->resource); + v->uri = strdup(uri); + + return (v->uri != NULL); + } + else + { + v->num_vars = cupsAddOption(name, value, v->num_vars, &v->vars); + return (1); + } +} diff --git a/cups/ipp.c b/cups/ipp.c index 429a05e..1bd59ce 100644 --- a/cups/ipp.c +++ b/cups/ipp.c @@ -1,16 +1,11 @@ /* * Internet Printing Protocol functions for CUPS. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -18,10 +13,11 @@ */ #include "cups-private.h" +#include "debug-internal.h" #include -#ifdef WIN32 +#ifdef _WIN32 # include -#endif /* WIN32 */ +#endif /* _WIN32 */ /* @@ -33,12 +29,8 @@ static ipp_attribute_t *ipp_add_attr(ipp_t *ipp, const char *name, int num_values); static void ipp_free_values(ipp_attribute_t *attr, int element, int count); -static char *ipp_get_code(const char *locale, char *buffer, - size_t bufsize) - __attribute__((nonnull(1,2))); -static char *ipp_lang_code(const char *locale, char *buffer, - size_t bufsize) - __attribute__((nonnull(1,2))); +static char *ipp_get_code(const char *locale, char *buffer, size_t bufsize) _CUPS_NONNULL(1,2); +static char *ipp_lang_code(const char *locale, char *buffer, size_t bufsize) _CUPS_NONNULL(1,2); static size_t ipp_length(ipp_t *ipp, int collection); static ssize_t ipp_read_http(http_t *http, ipp_uchar_t *buffer, size_t length); @@ -1483,6 +1475,7 @@ ippCopyAttribute( int quickcopy) /* I - 1 for a referenced copy, 0 for normal */ { int i; /* Looping var */ + ipp_tag_t srctag; /* Source value tag */ ipp_attribute_t *dstattr; /* Destination attribute */ _ipp_value_t *srcval, /* Source value */ *dstval; /* Destination value */ @@ -1501,144 +1494,86 @@ ippCopyAttribute( * Copy it... */ - quickcopy = quickcopy ? IPP_TAG_CUPS_CONST : 0; + quickcopy = (quickcopy && (srcattr->value_tag & IPP_TAG_CUPS_CONST)) ? IPP_TAG_CUPS_CONST : 0; + srctag = srcattr->value_tag & IPP_TAG_CUPS_MASK; - switch (srcattr->value_tag & ~IPP_TAG_CUPS_CONST) + switch (srctag) { case IPP_TAG_ZERO : dstattr = ippAddSeparator(dst); break; - case IPP_TAG_INTEGER : - case IPP_TAG_ENUM : - dstattr = ippAddIntegers(dst, srcattr->group_tag, srcattr->value_tag, - srcattr->name, srcattr->num_values, NULL); - if (!dstattr) - break; - - for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) - dstval->integer = srcval->integer; + case IPP_TAG_UNSUPPORTED_VALUE : + case IPP_TAG_DEFAULT : + case IPP_TAG_UNKNOWN : + case IPP_TAG_NOVALUE : + case IPP_TAG_NOTSETTABLE : + case IPP_TAG_DELETEATTR : + case IPP_TAG_ADMINDEFINE : + dstattr = ippAddOutOfBand(dst, srcattr->group_tag, srctag, srcattr->name); break; + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : case IPP_TAG_BOOLEAN : - dstattr = ippAddBooleans(dst, srcattr->group_tag, srcattr->name, - srcattr->num_values, NULL); - if (!dstattr) - break; - - for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) - dstval->boolean = srcval->boolean; + case IPP_TAG_DATE : + case IPP_TAG_RESOLUTION : + case IPP_TAG_RANGE : + if ((dstattr = ipp_add_attr(dst, srcattr->name, srcattr->group_tag, srctag, srcattr->num_values)) != NULL) + memcpy(dstattr->values, srcattr->values, (size_t)srcattr->num_values * sizeof(_ipp_value_t)); break; case IPP_TAG_TEXT : case IPP_TAG_NAME : + case IPP_TAG_RESERVED_STRING : case IPP_TAG_KEYWORD : case IPP_TAG_URI : case IPP_TAG_URISCHEME : case IPP_TAG_CHARSET : case IPP_TAG_LANGUAGE : case IPP_TAG_MIMETYPE : - dstattr = ippAddStrings(dst, srcattr->group_tag, - (ipp_tag_t)(srcattr->value_tag | quickcopy), - srcattr->name, srcattr->num_values, NULL, NULL); - if (!dstattr) + if ((dstattr = ippAddStrings(dst, srcattr->group_tag, (ipp_tag_t)(srctag | quickcopy), srcattr->name, srcattr->num_values, NULL, NULL)) == NULL) break; if (quickcopy) { - for (i = srcattr->num_values, srcval = srcattr->values, - dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) - dstval->string.text = srcval->string.text; + /* + * Can safely quick-copy these string values... + */ + + memcpy(dstattr->values, srcattr->values, (size_t)srcattr->num_values * sizeof(_ipp_value_t)); } - else if (srcattr->value_tag & IPP_TAG_CUPS_CONST) - { - for (i = srcattr->num_values, srcval = srcattr->values, - dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) - dstval->string.text = _cupsStrAlloc(srcval->string.text); - } else { - for (i = srcattr->num_values, srcval = srcattr->values, - dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) - dstval->string.text = _cupsStrRetain(srcval->string.text); - } - break; + /* + * Otherwise do a normal reference counted copy... + */ - case IPP_TAG_DATE : - if (srcattr->num_values != 1) - return (NULL); - - dstattr = ippAddDate(dst, srcattr->group_tag, srcattr->name, - srcattr->values[0].date); - break; - - case IPP_TAG_RESOLUTION : - dstattr = ippAddResolutions(dst, srcattr->group_tag, srcattr->name, - srcattr->num_values, IPP_RES_PER_INCH, - NULL, NULL); - if (!dstattr) - break; - - for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) - { - dstval->resolution.xres = srcval->resolution.xres; - dstval->resolution.yres = srcval->resolution.yres; - dstval->resolution.units = srcval->resolution.units; - } - break; - - case IPP_TAG_RANGE : - dstattr = ippAddRanges(dst, srcattr->group_tag, srcattr->name, - srcattr->num_values, NULL, NULL); - if (!dstattr) - break; - - for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) - { - dstval->range.lower = srcval->range.lower; - dstval->range.upper = srcval->range.upper; + for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; i > 0; i --, srcval ++, dstval ++) + dstval->string.text = _cupsStrAlloc(srcval->string.text); } break; case IPP_TAG_TEXTLANG : case IPP_TAG_NAMELANG : - dstattr = ippAddStrings(dst, srcattr->group_tag, - (ipp_tag_t)(srcattr->value_tag | quickcopy), - srcattr->name, srcattr->num_values, NULL, NULL); - if (!dstattr) + if ((dstattr = ippAddStrings(dst, srcattr->group_tag, (ipp_tag_t)(srctag | quickcopy), srcattr->name, srcattr->num_values, NULL, NULL)) == NULL) break; if (quickcopy) { - for (i = srcattr->num_values, srcval = srcattr->values, - dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) - { - dstval->string.language = srcval->string.language; - dstval->string.text = srcval->string.text; - } + /* + * Can safely quick-copy these string values... + */ + + memcpy(dstattr->values, srcattr->values, (size_t)srcattr->num_values * sizeof(_ipp_value_t)); } else if (srcattr->value_tag & IPP_TAG_CUPS_CONST) { - for (i = srcattr->num_values, srcval = srcattr->values, - dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) + /* + * Otherwise do a normal reference counted copy... + */ + + for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; i > 0; i --, srcval ++, dstval ++) { if (srcval == srcattr->values) dstval->string.language = _cupsStrAlloc(srcval->string.language); @@ -1648,32 +1583,13 @@ ippCopyAttribute( dstval->string.text = _cupsStrAlloc(srcval->string.text); } } - else - { - for (i = srcattr->num_values, srcval = srcattr->values, - dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) - { - if (srcval == srcattr->values) - dstval->string.language = _cupsStrRetain(srcval->string.language); - else - dstval->string.language = dstattr->values[0].string.language; - - dstval->string.text = _cupsStrRetain(srcval->string.text); - } - } break; case IPP_TAG_BEGIN_COLLECTION : - dstattr = ippAddCollections(dst, srcattr->group_tag, srcattr->name, - srcattr->num_values, NULL); - if (!dstattr) + if ((dstattr = ippAddCollections(dst, srcattr->group_tag, srcattr->name, srcattr->num_values, NULL)) == NULL) break; - for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) + for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; i > 0; i --, srcval ++, dstval ++) { dstval->collection = srcval->collection; srcval->collection->use ++; @@ -1682,15 +1598,10 @@ ippCopyAttribute( case IPP_TAG_STRING : default : - /* TODO: Implement quick copy for unknown/octetString values */ - dstattr = ippAddIntegers(dst, srcattr->group_tag, srcattr->value_tag, - srcattr->name, srcattr->num_values, NULL); - if (!dstattr) + if ((dstattr = ipp_add_attr(dst, srcattr->name, srcattr->group_tag, srctag, srcattr->num_values)) == NULL) break; - for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) + for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; i > 0; i --, srcval ++, dstval ++) { dstval->unknown.length = srcval->unknown.length; @@ -1828,12 +1739,19 @@ ippDelete(ipp_t *ipp) /* I - IPP message */ ipp->use --; if (ipp->use > 0) + { + DEBUG_printf(("4debug_retain: %p IPP message (use=%d)", (void *)ipp, ipp->use)); return; + } + + DEBUG_printf(("4debug_free: %p IPP message", (void *)ipp)); for (attr = ipp->attrs; attr != NULL; attr = next) { next = attr->next; + DEBUG_printf(("4debug_free: %p %s %s%s (%d values)", (void *)attr, attr->name, attr->num_values > 1 ? "1setOf " : "", ippTagString(attr->value_tag), attr->num_values)); + ipp_free_values(attr, 0, attr->num_values); if (attr->name) @@ -1870,6 +1788,8 @@ ippDeleteAttribute( if (!attr) return; + DEBUG_printf(("4debug_free: %p %s %s%s (%d values)", (void *)attr, attr->name, attr->num_values > 1 ? "1setOf " : "", ippTagString(attr->value_tag), attr->num_values)); + /* * Find the attribute in the list... */ @@ -2705,6 +2625,8 @@ ippNew(void) * Set default version - usually 2.0... */ + DEBUG_printf(("4debug_alloc: %p IPP message", (void *)temp)); + if (cg->server_version == 0) _cupsSetDefaults(); @@ -3068,6 +2990,13 @@ ippReadIO(void *src, /* I - Data source */ ipp->state = IPP_STATE_DATA; break; } + else if (tag == IPP_TAG_ZERO || (tag == IPP_TAG_OPERATION && ipp->curtag != IPP_TAG_ZERO)) + { + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Invalid group tag."), 1); + DEBUG_printf(("1ippReadIO: bad tag 0x%02x.", tag)); + _cupsBufferRelease((char *)buffer); + return (IPP_STATE_ERROR); + } else if (tag < IPP_TAG_UNSUPPORTED_VALUE) { /* @@ -3111,8 +3040,13 @@ ippReadIO(void *src, /* I - Data source */ DEBUG_printf(("2ippReadIO: name length=%d", n)); - if (n == 0 && tag != IPP_TAG_MEMBERNAME && - tag != IPP_TAG_END_COLLECTION) + if (n && parent) + { + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Invalid named IPP attribute in collection."), 1); + DEBUG_puts("1ippReadIO: bad attribute name in collection."); + return (IPP_STATE_ERROR); + } + else if (n == 0 && tag != IPP_TAG_MEMBERNAME && tag != IPP_TAG_END_COLLECTION) { /* * More values for current attribute... @@ -3365,7 +3299,10 @@ ippReadIO(void *src, /* I - Data source */ value->boolean = (char)buffer[0]; break; - case IPP_TAG_NOVALUE : + case IPP_TAG_UNSUPPORTED_VALUE : + case IPP_TAG_DEFAULT : + case IPP_TAG_UNKNOWN : + case IPP_TAG_NOVALUE : case IPP_TAG_NOTSETTABLE : case IPP_TAG_DELETEATTR : case IPP_TAG_ADMINDEFINE : @@ -3385,6 +3322,7 @@ ippReadIO(void *src, /* I - Data source */ case IPP_TAG_TEXT : case IPP_TAG_NAME : + case IPP_TAG_RESERVED_STRING : case IPP_TAG_KEYWORD : case IPP_TAG_URI : case IPP_TAG_URISCHEME : @@ -3639,6 +3577,7 @@ ippReadIO(void *src, /* I - Data source */ DEBUG_printf(("2ippReadIO: member name=\"%s\"", attr->name)); break; + case IPP_TAG_STRING : default : /* Other unsupported values */ if (tag == IPP_TAG_STRING && n > IPP_MAX_LENGTH) { @@ -3815,8 +3754,7 @@ ippSetDate(ipp_t *ipp, /* I - IPP message */ * Range check input... */ - if (!ipp || !attr || !*attr || (*attr)->value_tag != IPP_TAG_DATE || - element < 0 || element > (*attr)->num_values || !datevalue) + if (!ipp || !attr || !*attr || ((*attr)->value_tag != IPP_TAG_DATE && (*attr)->value_tag != IPP_TAG_NOVALUE && (*attr)->value_tag != IPP_TAG_UNKNOWN) || element < 0 || element > (*attr)->num_values || !datevalue) return (0); /* @@ -3899,9 +3837,7 @@ ippSetInteger(ipp_t *ipp, /* I - IPP message */ * Range check input... */ - if (!ipp || !attr || !*attr || - ((*attr)->value_tag != IPP_TAG_INTEGER && (*attr)->value_tag != IPP_TAG_ENUM) || - element < 0 || element > (*attr)->num_values) + if (!ipp || !attr || !*attr || ((*attr)->value_tag != IPP_TAG_INTEGER && (*attr)->value_tag != IPP_TAG_ENUM && (*attr)->value_tag != IPP_TAG_NOVALUE && (*attr)->value_tag != IPP_TAG_UNKNOWN) || element < 0 || element > (*attr)->num_values) return (0); /* @@ -3909,7 +3845,12 @@ ippSetInteger(ipp_t *ipp, /* I - IPP message */ */ if ((value = ipp_set_value(ipp, attr, element)) != NULL) + { + if ((*attr)->value_tag != IPP_TAG_ENUM) + (*attr)->value_tag = IPP_TAG_INTEGER; + value->integer = intvalue; + } return (value != NULL); } @@ -3986,9 +3927,7 @@ ippSetOctetString( * Range check input... */ - if (!ipp || !attr || !*attr || (*attr)->value_tag != IPP_TAG_STRING || - element < 0 || element > (*attr)->num_values || - datalen < 0 || datalen > IPP_MAX_LENGTH) + if (!ipp || !attr || !*attr || ((*attr)->value_tag != IPP_TAG_STRING && (*attr)->value_tag != IPP_TAG_NOVALUE && (*attr)->value_tag != IPP_TAG_UNKNOWN) || element < 0 || element > (*attr)->num_values || datalen < 0 || datalen > IPP_MAX_LENGTH) return (0); /* @@ -4012,6 +3951,8 @@ ippSetOctetString( * Copy the data... */ + (*attr)->value_tag = IPP_TAG_STRING; + if (value->unknown.data) { /* @@ -4103,8 +4044,7 @@ ippSetRange(ipp_t *ipp, /* I - IPP message */ * Range check input... */ - if (!ipp || !attr || !*attr || (*attr)->value_tag != IPP_TAG_RANGE || - element < 0 || element > (*attr)->num_values || lowervalue > uppervalue) + if (!ipp || !attr || !*attr || ((*attr)->value_tag != IPP_TAG_RANGE && (*attr)->value_tag != IPP_TAG_NOVALUE && (*attr)->value_tag != IPP_TAG_UNKNOWN) || element < 0 || element > (*attr)->num_values || lowervalue > uppervalue) return (0); /* @@ -4113,6 +4053,7 @@ ippSetRange(ipp_t *ipp, /* I - IPP message */ if ((value = ipp_set_value(ipp, attr, element)) != NULL) { + (*attr)->value_tag = IPP_TAG_RANGE; value->range.lower = lowervalue; value->range.upper = uppervalue; } @@ -4185,9 +4126,7 @@ ippSetResolution( * Range check input... */ - if (!ipp || !attr || !*attr || (*attr)->value_tag != IPP_TAG_RESOLUTION || - element < 0 || element > (*attr)->num_values || xresvalue <= 0 || yresvalue <= 0 || - unitsvalue < IPP_RES_PER_INCH || unitsvalue > IPP_RES_PER_CM) + if (!ipp || !attr || !*attr || ((*attr)->value_tag != IPP_TAG_RESOLUTION && (*attr)->value_tag != IPP_TAG_NOVALUE && (*attr)->value_tag != IPP_TAG_UNKNOWN) || element < 0 || element > (*attr)->num_values || xresvalue <= 0 || yresvalue <= 0 || unitsvalue < IPP_RES_PER_INCH || unitsvalue > IPP_RES_PER_CM) return (0); /* @@ -4196,6 +4135,7 @@ ippSetResolution( if ((value = ipp_set_value(ipp, attr, element)) != NULL) { + (*attr)->value_tag = IPP_TAG_RESOLUTION; value->resolution.units = unitsvalue; value->resolution.xres = xresvalue; value->resolution.yres = yresvalue; @@ -4285,18 +4225,19 @@ ippSetString(ipp_t *ipp, /* I - IPP message */ { char *temp; /* Temporary string */ _ipp_value_t *value; /* Current value */ + ipp_tag_t value_tag; /* Value tag */ /* * Range check input... */ - if (!ipp || !attr || !*attr || - ((*attr)->value_tag != IPP_TAG_TEXTLANG && - (*attr)->value_tag != IPP_TAG_NAMELANG && - ((*attr)->value_tag < IPP_TAG_TEXT || - (*attr)->value_tag > IPP_TAG_MIMETYPE)) || - element < 0 || element > (*attr)->num_values || !strvalue) + if (attr && *attr) + value_tag = (*attr)->value_tag & IPP_TAG_CUPS_MASK; + else + value_tag = IPP_TAG_ZERO; + + if (!ipp || !attr || !*attr || (value_tag < IPP_TAG_TEXT && value_tag != IPP_TAG_TEXTLANG && value_tag != IPP_TAG_NAMELANG && value_tag != IPP_TAG_NOVALUE && value_tag != IPP_TAG_UNKNOWN) || value_tag > IPP_TAG_MIMETYPE || element < 0 || element > (*attr)->num_values || !strvalue) return (0); /* @@ -4305,6 +4246,9 @@ ippSetString(ipp_t *ipp, /* I - IPP message */ if ((value = ipp_set_value(ipp, attr, element)) != NULL) { + if (value_tag == IPP_TAG_NOVALUE || value_tag == IPP_TAG_UNKNOWN) + (*attr)->value_tag = IPP_TAG_KEYWORD; + if (element > 0) value->string.language = (*attr)->values[0].string.language; @@ -4405,10 +4349,7 @@ ippSetStringfv(ipp_t *ipp, /* I - IPP message */ else value_tag = IPP_TAG_ZERO; - if (!ipp || !attr || !*attr || - (value_tag < IPP_TAG_TEXT && value_tag != IPP_TAG_TEXTLANG && - value_tag != IPP_TAG_NAMELANG) || value_tag > IPP_TAG_MIMETYPE || - !format) + if (!ipp || !attr || !*attr || (value_tag < IPP_TAG_TEXT && value_tag != IPP_TAG_TEXTLANG && value_tag != IPP_TAG_NAMELANG && value_tag != IPP_TAG_NOVALUE && value_tag != IPP_TAG_UNKNOWN) || value_tag > IPP_TAG_MIMETYPE || !format) return (0); /* @@ -4460,6 +4401,8 @@ ippSetStringfv(ipp_t *ipp, /* I - IPP message */ max_bytes = IPP_MAX_CHARSET; break; + case IPP_TAG_NOVALUE : + case IPP_TAG_UNKNOWN : case IPP_TAG_KEYWORD : max_bytes = IPP_MAX_KEYWORD; break; @@ -4607,9 +4550,7 @@ ippSetValueTag( break; case IPP_TAG_NAME : - if (temp_tag != IPP_TAG_KEYWORD && temp_tag != IPP_TAG_URI && - temp_tag != IPP_TAG_URISCHEME && temp_tag != IPP_TAG_LANGUAGE && - temp_tag != IPP_TAG_MIMETYPE) + if (temp_tag != IPP_TAG_KEYWORD) return (0); (*attr)->value_tag = (ipp_tag_t)(IPP_TAG_NAME | ((*attr)->value_tag & IPP_TAG_CUPS_CONST)); @@ -4617,10 +4558,7 @@ ippSetValueTag( case IPP_TAG_NAMELANG : case IPP_TAG_TEXTLANG : - if (value_tag == IPP_TAG_NAMELANG && - (temp_tag != IPP_TAG_NAME && temp_tag != IPP_TAG_KEYWORD && - temp_tag != IPP_TAG_URI && temp_tag != IPP_TAG_URISCHEME && - temp_tag != IPP_TAG_LANGUAGE && temp_tag != IPP_TAG_MIMETYPE)) + if (value_tag == IPP_TAG_NAMELANG && (temp_tag != IPP_TAG_NAME && temp_tag != IPP_TAG_KEYWORD)) return (0); if (value_tag == IPP_TAG_TEXTLANG && temp_tag != IPP_TAG_TEXT) @@ -4787,21 +4725,6 @@ ippValidateAttribute( ipp_attribute_t *colattr; /* Collection attribute */ regex_t re; /* Regular expression */ ipp_uchar_t *date; /* Current date value */ - static const char * const uri_status_strings[] = - { /* URI status strings */ - "URI too large", - "Bad arguments to function", - "Bad resource in URI", - "Bad port number in URI", - "Bad hostname/address in URI", - "Bad username in URI", - "Bad scheme in URI", - "Bad/empty URI", - "OK", - "Missing scheme in URI", - "Unknown scheme in URI", - "Missing resource in URI" - }; /* @@ -4821,18 +4744,13 @@ ippValidateAttribute( if (*ptr || ptr == attr->name) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad attribute name - invalid character " - "(RFC 8011 section 5.1.4)."), attr->name); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad attribute name - invalid character (RFC 8011 section 5.1.4)."), attr->name); return (0); } if ((ptr - attr->name) > 255) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad attribute name - bad length %d " - "(RFC 8011 section 5.1.4)."), attr->name, - (int)(ptr - attr->name)); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad attribute name - bad length %d (RFC 8011 section 5.1.4)."), attr->name, (int)(ptr - attr->name)); return (0); } @@ -4847,10 +4765,7 @@ ippValidateAttribute( if (attr->values[i].boolean != 0 && attr->values[i].boolean != 1) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad boolen value %d " - "(RFC 8011 section 5.1.21)."), attr->name, - attr->values[i].boolean); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad boolean value %d (RFC 8011 section 5.1.21)."), attr->name, attr->values[i].boolean); return (0); } } @@ -4861,10 +4776,7 @@ ippValidateAttribute( { if (attr->values[i].integer < 1) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad enum value %d - out of range " - "(RFC 8011 section 5.1.5)."), attr->name, - attr->values[i].integer); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad enum value %d - out of range (RFC 8011 section 5.1.5)."), attr->name, attr->values[i].integer); return (0); } } @@ -4875,10 +4787,7 @@ ippValidateAttribute( { if (attr->values[i].unknown.length > IPP_MAX_OCTETSTRING) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad octetString value - bad length %d " - "(RFC 8011 section 5.1.20)."), attr->name, - attr->values[i].unknown.length); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad octetString value - bad length %d (RFC 8011 section 5.1.20)."), attr->name, attr->values[i].unknown.length); return (0); } } @@ -4891,73 +4800,55 @@ ippValidateAttribute( if (date[2] < 1 || date[2] > 12) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad dateTime month %u " - "(RFC 8011 section 5.1.15)."), attr->name, date[2]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime month %u (RFC 8011 section 5.1.15)."), attr->name, date[2]); return (0); } if (date[3] < 1 || date[3] > 31) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad dateTime day %u " - "(RFC 8011 section 5.1.15)."), attr->name, date[3]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime day %u (RFC 8011 section 5.1.15)."), attr->name, date[3]); return (0); } if (date[4] > 23) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad dateTime hours %u " - "(RFC 8011 section 5.1.15)."), attr->name, date[4]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime hours %u (RFC 8011 section 5.1.15)."), attr->name, date[4]); return (0); } if (date[5] > 59) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad dateTime minutes %u " - "(RFC 8011 section 5.1.15)."), attr->name, date[5]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime minutes %u (RFC 8011 section 5.1.15)."), attr->name, date[5]); return (0); } if (date[6] > 60) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad dateTime seconds %u " - "(RFC 8011 section 5.1.15)."), attr->name, date[6]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime seconds %u (RFC 8011 section 5.1.15)."), attr->name, date[6]); return (0); } if (date[7] > 9) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad dateTime deciseconds %u " - "(RFC 8011 section 5.1.15)."), attr->name, date[7]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime deciseconds %u (RFC 8011 section 5.1.15)."), attr->name, date[7]); return (0); } if (date[8] != '-' && date[8] != '+') { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad dateTime UTC sign '%c' " - "(RFC 8011 section 5.1.15)."), attr->name, date[8]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime UTC sign '%c' (RFC 8011 section 5.1.15)."), attr->name, date[8]); return (0); } if (date[9] > 11) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad dateTime UTC hours %u " - "(RFC 8011 section 5.1.15)."), attr->name, date[9]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime UTC hours %u (RFC 8011 section 5.1.15)."), attr->name, date[9]); return (0); } if (date[10] > 59) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad dateTime UTC minutes %u " - "(RFC 8011 section 5.1.15)."), attr->name, date[10]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime UTC minutes %u (RFC 8011 section 5.1.15)."), attr->name, date[10]); return (0); } } @@ -4968,46 +4859,19 @@ ippValidateAttribute( { if (attr->values[i].resolution.xres <= 0) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad resolution value %dx%d%s - cross " - "feed resolution must be positive " - "(RFC 8011 section 5.1.16)."), attr->name, - attr->values[i].resolution.xres, - attr->values[i].resolution.yres, - attr->values[i].resolution.units == - IPP_RES_PER_INCH ? "dpi" : - attr->values[i].resolution.units == - IPP_RES_PER_CM ? "dpcm" : "unknown"); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad resolution value %dx%d%s - cross feed resolution must be positive (RFC 8011 section 5.1.16)."), attr->name, attr->values[i].resolution.xres, attr->values[i].resolution.yres, attr->values[i].resolution.units == IPP_RES_PER_INCH ? "dpi" : attr->values[i].resolution.units == IPP_RES_PER_CM ? "dpcm" : "unknown"); return (0); } if (attr->values[i].resolution.yres <= 0) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad resolution value %dx%d%s - feed " - "resolution must be positive " - "(RFC 8011 section 5.1.16)."), attr->name, - attr->values[i].resolution.xres, - attr->values[i].resolution.yres, - attr->values[i].resolution.units == - IPP_RES_PER_INCH ? "dpi" : - attr->values[i].resolution.units == - IPP_RES_PER_CM ? "dpcm" : "unknown"); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad resolution value %dx%d%s - feed resolution must be positive (RFC 8011 section 5.1.16)."), attr->name, attr->values[i].resolution.xres, attr->values[i].resolution.yres, attr->values[i].resolution.units == IPP_RES_PER_INCH ? "dpi" : attr->values[i].resolution.units == IPP_RES_PER_CM ? "dpcm" : "unknown"); return (0); } - if (attr->values[i].resolution.units != IPP_RES_PER_INCH && - attr->values[i].resolution.units != IPP_RES_PER_CM) + if (attr->values[i].resolution.units != IPP_RES_PER_INCH && attr->values[i].resolution.units != IPP_RES_PER_CM) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad resolution value %dx%d%s - bad " - "units value (RFC 8011 section 5.1.16)."), - attr->name, attr->values[i].resolution.xres, - attr->values[i].resolution.yres, - attr->values[i].resolution.units == - IPP_RES_PER_INCH ? "dpi" : - attr->values[i].resolution.units == - IPP_RES_PER_CM ? "dpcm" : "unknown"); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad resolution value %dx%d%s - bad units value (RFC 8011 section 5.1.16)."), attr->name, attr->values[i].resolution.xres, attr->values[i].resolution.yres, attr->values[i].resolution.units == IPP_RES_PER_INCH ? "dpi" : attr->values[i].resolution.units == IPP_RES_PER_CM ? "dpcm" : "unknown"); return (0); } } @@ -5018,11 +4882,7 @@ ippValidateAttribute( { if (attr->values[i].range.lower > attr->values[i].range.upper) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad rangeOfInteger value %d-%d - lower " - "greater than upper (RFC 8011 section 5.1.14)."), - attr->name, attr->values[i].range.lower, - attr->values[i].range.upper); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad rangeOfInteger value %d-%d - lower greater than upper (RFC 8011 section 5.1.14)."), attr->name, attr->values[i].range.lower, attr->values[i].range.upper); return (0); } } @@ -5049,51 +4909,48 @@ ippValidateAttribute( { if ((*ptr & 0xe0) == 0xc0) { - ptr ++; - if ((*ptr & 0xc0) != 0x80) + if ((ptr[1] & 0xc0) != 0x80) break; + + ptr ++; } else if ((*ptr & 0xf0) == 0xe0) { - ptr ++; - if ((*ptr & 0xc0) != 0x80) - break; - ptr ++; - if ((*ptr & 0xc0) != 0x80) + if ((ptr[1] & 0xc0) != 0x80 || (ptr[2] & 0xc0) != 0x80) break; + + ptr += 2; } else if ((*ptr & 0xf8) == 0xf0) { - ptr ++; - if ((*ptr & 0xc0) != 0x80) - break; - ptr ++; - if ((*ptr & 0xc0) != 0x80) - break; - ptr ++; - if ((*ptr & 0xc0) != 0x80) + if ((ptr[1] & 0xc0) != 0x80 || (ptr[2] & 0xc0) != 0x80 || (ptr[3] & 0xc0) != 0x80) break; + + ptr += 3; } else if (*ptr & 0x80) break; + else if ((*ptr < ' ' && *ptr != '\n' && *ptr != '\r' && *ptr != '\t') || *ptr == 0x7f) + break; } - if (*ptr) - { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad text value \"%s\" - bad UTF-8 " - "sequence (RFC 8011 section 5.1.2)."), attr->name, - attr->values[i].string.text); - return (0); - } + if (*ptr) + { + if (*ptr < ' ' || *ptr == 0x7f) + { + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad text value \"%s\" - bad control character (PWG 5100.14 section 8.3)."), attr->name, attr->values[i].string.text); + return (0); + } + else + { + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad text value \"%s\" - bad UTF-8 sequence (RFC 8011 section 5.1.2)."), attr->name, attr->values[i].string.text); + return (0); + } + } if ((ptr - attr->values[i].string.text) > (IPP_MAX_TEXT - 1)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad text value \"%s\" - bad length %d " - "(RFC 8011 section 5.1.2)."), attr->name, - attr->values[i].string.text, - (int)(ptr - attr->values[i].string.text)); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad text value \"%s\" - bad length %d (RFC 8011 section 5.1.2)."), attr->name, attr->values[i].string.text, (int)(ptr - attr->values[i].string.text)); return (0); } } @@ -5107,51 +4964,48 @@ ippValidateAttribute( { if ((*ptr & 0xe0) == 0xc0) { - ptr ++; - if ((*ptr & 0xc0) != 0x80) + if ((ptr[1] & 0xc0) != 0x80) break; + + ptr ++; } else if ((*ptr & 0xf0) == 0xe0) { - ptr ++; - if ((*ptr & 0xc0) != 0x80) - break; - ptr ++; - if ((*ptr & 0xc0) != 0x80) + if ((ptr[1] & 0xc0) != 0x80 || (ptr[2] & 0xc0) != 0x80) break; + + ptr += 2; } else if ((*ptr & 0xf8) == 0xf0) { - ptr ++; - if ((*ptr & 0xc0) != 0x80) - break; - ptr ++; - if ((*ptr & 0xc0) != 0x80) - break; - ptr ++; - if ((*ptr & 0xc0) != 0x80) + if ((ptr[1] & 0xc0) != 0x80 || (ptr[2] & 0xc0) != 0x80 || (ptr[3] & 0xc0) != 0x80) break; + + ptr += 3; } else if (*ptr & 0x80) break; + else if (*ptr < ' ' || *ptr == 0x7f) + break; } if (*ptr) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad name value \"%s\" - bad UTF-8 " - "sequence (RFC 8011 section 5.1.3)."), attr->name, - attr->values[i].string.text); - return (0); - } + if (*ptr < ' ' || *ptr == 0x7f) + { + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad name value \"%s\" - bad control character (PWG 5100.14 section 8.1)."), attr->name, attr->values[i].string.text); + return (0); + } + else + { + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad name value \"%s\" - bad UTF-8 sequence (RFC 8011 section 5.1.3)."), attr->name, attr->values[i].string.text); + return (0); + } + } if ((ptr - attr->values[i].string.text) > (IPP_MAX_NAME - 1)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad name value \"%s\" - bad length %d " - "(RFC 8011 section 5.1.3)."), attr->name, - attr->values[i].string.text, - (int)(ptr - attr->values[i].string.text)); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad name value \"%s\" - bad length %d (RFC 8011 section 5.1.3)."), attr->name, attr->values[i].string.text, (int)(ptr - attr->values[i].string.text)); return (0); } } @@ -5161,26 +5015,21 @@ ippValidateAttribute( for (i = 0; i < attr->num_values; i ++) { for (ptr = attr->values[i].string.text; *ptr; ptr ++) + { if (!isalnum(*ptr & 255) && *ptr != '-' && *ptr != '.' && *ptr != '_') break; + } if (*ptr || ptr == attr->values[i].string.text) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad keyword value \"%s\" - invalid " - "character (RFC 8011 section 5.1.4)."), - attr->name, attr->values[i].string.text); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad keyword value \"%s\" - invalid character (RFC 8011 section 5.1.4)."), attr->name, attr->values[i].string.text); return (0); } if ((ptr - attr->values[i].string.text) > (IPP_MAX_KEYWORD - 1)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad keyword value \"%s\" - bad " - "length %d (RFC 8011 section 5.1.4)."), - attr->name, attr->values[i].string.text, - (int)(ptr - attr->values[i].string.text)); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad keyword value \"%s\" - bad length %d (RFC 8011 section 5.1.4)."), attr->name, attr->values[i].string.text, (int)(ptr - attr->values[i].string.text)); return (0); } } @@ -5189,31 +5038,17 @@ ippValidateAttribute( case IPP_TAG_URI : for (i = 0; i < attr->num_values; i ++) { - uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, - attr->values[i].string.text, - scheme, sizeof(scheme), - userpass, sizeof(userpass), - hostname, sizeof(hostname), - &port, resource, sizeof(resource)); + uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[i].string.text, scheme, sizeof(scheme), userpass, sizeof(userpass), hostname, sizeof(hostname), &port, resource, sizeof(resource)); if (uri_status < HTTP_URI_STATUS_OK) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad URI value \"%s\" - %s " - "(RFC 8011 section 5.1.6)."), attr->name, - attr->values[i].string.text, - uri_status_strings[uri_status - - HTTP_URI_STATUS_OVERFLOW]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad URI value \"%s\" - %s (RFC 8011 section 5.1.6)."), attr->name, attr->values[i].string.text, httpURIStatusString(uri_status)); return (0); } if (strlen(attr->values[i].string.text) > (IPP_MAX_URI - 1)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad URI value \"%s\" - bad length %d " - "(RFC 8011 section 5.1.6)."), attr->name, - attr->values[i].string.text, - (int)strlen(attr->values[i].string.text)); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad URI value \"%s\" - bad length %d (RFC 8011 section 5.1.6)."), attr->name, attr->values[i].string.text, (int)strlen(attr->values[i].string.text)); } } break; @@ -5225,27 +5060,22 @@ ippValidateAttribute( if (islower(*ptr & 255)) { for (ptr ++; *ptr; ptr ++) + { if (!islower(*ptr & 255) && !isdigit(*ptr & 255) && *ptr != '+' && *ptr != '-' && *ptr != '.') break; + } } if (*ptr || ptr == attr->values[i].string.text) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad uriScheme value \"%s\" - bad " - "characters (RFC 8011 section 5.1.7)."), - attr->name, attr->values[i].string.text); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad uriScheme value \"%s\" - bad characters (RFC 8011 section 5.1.7)."), attr->name, attr->values[i].string.text); return (0); } if ((ptr - attr->values[i].string.text) > (IPP_MAX_URISCHEME - 1)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad uriScheme value \"%s\" - bad " - "length %d (RFC 8011 section 5.1.7)."), - attr->name, attr->values[i].string.text, - (int)(ptr - attr->values[i].string.text)); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad uriScheme value \"%s\" - bad length %d (RFC 8011 section 5.1.7)."), attr->name, attr->values[i].string.text, (int)(ptr - attr->values[i].string.text)); return (0); } } @@ -5255,26 +5085,21 @@ ippValidateAttribute( for (i = 0; i < attr->num_values; i ++) { for (ptr = attr->values[i].string.text; *ptr; ptr ++) + { if (!isprint(*ptr & 255) || isupper(*ptr & 255) || isspace(*ptr & 255)) break; + } if (*ptr || ptr == attr->values[i].string.text) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad charset value \"%s\" - bad " - "characters (RFC 8011 section 5.1.8)."), - attr->name, attr->values[i].string.text); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad charset value \"%s\" - bad characters (RFC 8011 section 5.1.8)."), attr->name, attr->values[i].string.text); return (0); } if ((ptr - attr->values[i].string.text) > (IPP_MAX_CHARSET - 1)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad charset value \"%s\" - bad " - "length %d (RFC 8011 section 5.1.8)."), - attr->name, attr->values[i].string.text, - (int)(ptr - attr->values[i].string.text)); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad charset value \"%s\" - bad length %d (RFC 8011 section 5.1.8)."), attr->name, attr->values[i].string.text, (int)(ptr - attr->values[i].string.text)); return (0); } } @@ -5306,9 +5131,7 @@ ippValidateAttribute( char temp[256]; /* Temporary error string */ regerror(i, &re, temp, sizeof(temp)); - ipp_set_error(IPP_STATUS_ERROR_INTERNAL, - _("Unable to compile naturalLanguage regular " - "expression: %s."), temp); + ipp_set_error(IPP_STATUS_ERROR_INTERNAL, _("Unable to compile naturalLanguage regular expression: %s."), temp); return (0); } @@ -5316,21 +5139,14 @@ ippValidateAttribute( { if (regexec(&re, attr->values[i].string.text, 0, NULL, 0)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad naturalLanguage value \"%s\" - bad " - "characters (RFC 8011 section 5.1.9)."), - attr->name, attr->values[i].string.text); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad naturalLanguage value \"%s\" - bad characters (RFC 8011 section 5.1.9)."), attr->name, attr->values[i].string.text); regfree(&re); return (0); } if (strlen(attr->values[i].string.text) > (IPP_MAX_LANGUAGE - 1)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad naturalLanguage value \"%s\" - bad " - "length %d (RFC 8011 section 5.1.9)."), - attr->name, attr->values[i].string.text, - (int)strlen(attr->values[i].string.text)); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad naturalLanguage value \"%s\" - bad length %d (RFC 8011 section 5.1.9)."), attr->name, attr->values[i].string.text, (int)strlen(attr->values[i].string.text)); regfree(&re); return (0); } @@ -5360,9 +5176,7 @@ ippValidateAttribute( char temp[256]; /* Temporary error string */ regerror(i, &re, temp, sizeof(temp)); - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("Unable to compile mimeMediaType regular " - "expression: %s."), temp); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("Unable to compile mimeMediaType regular expression: %s."), temp); return (0); } @@ -5370,21 +5184,14 @@ ippValidateAttribute( { if (regexec(&re, attr->values[i].string.text, 0, NULL, 0)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad mimeMediaType value \"%s\" - bad " - "characters (RFC 8011 section 5.1.10)."), - attr->name, attr->values[i].string.text); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad mimeMediaType value \"%s\" - bad characters (RFC 8011 section 5.1.10)."), attr->name, attr->values[i].string.text); regfree(&re); return (0); } if (strlen(attr->values[i].string.text) > (IPP_MAX_MIMETYPE - 1)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad mimeMediaType value \"%s\" - bad " - "length %d (RFC 8011 section 5.1.10)."), - attr->name, attr->values[i].string.text, - (int)strlen(attr->values[i].string.text)); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad mimeMediaType value \"%s\" - bad length %d (RFC 8011 section 5.1.10)."), attr->name, attr->values[i].string.text, (int)strlen(attr->values[i].string.text)); regfree(&re); return (0); } @@ -6402,6 +6209,8 @@ ipp_add_attr(ipp_t *ipp, /* I - IPP message */ * Initialize attribute... */ + DEBUG_printf(("4debug_alloc: %p %s %s%s (%d values)", (void *)attr, name, num_values > 1 ? "1setOf " : "", ippTagString(value_tag), num_values)); + if (name) attr->name = _cupsStrAlloc(name); @@ -6479,6 +6288,7 @@ ipp_free_values(ipp_attribute_t *attr, /* I - Attribute to free values from */ } break; + case IPP_TAG_UNSUPPORTED_VALUE : case IPP_TAG_DEFAULT : case IPP_TAG_UNKNOWN : case IPP_TAG_NOVALUE : @@ -6820,14 +6630,14 @@ ipp_read_http(http_t *http, /* I - Client connection */ if ((bytes = httpRead2(http, (char *)buffer, length - (size_t)tbytes)) < 0) { -#ifdef WIN32 +#ifdef _WIN32 break; #else if (errno != EAGAIN && errno != EINTR) break; bytes = 0; -#endif /* WIN32 */ +#endif /* _WIN32 */ } else if (bytes == 0) break; @@ -6855,11 +6665,11 @@ ipp_read_file(int *fd, /* I - File descriptor */ ipp_uchar_t *buffer, /* O - Read buffer */ size_t length) /* I - Number of bytes to read */ { -#ifdef WIN32 +#ifdef _WIN32 return ((ssize_t)read(*fd, buffer, (unsigned)length)); #else return (read(*fd, buffer, length)); -#endif /* WIN32 */ +#endif /* _WIN32 */ } @@ -6958,6 +6768,11 @@ ipp_set_value(ipp_t *ipp, /* IO - IPP message */ * Reset pointers in the list... */ +#ifndef __clang_analyzer__ + DEBUG_printf(("4debug_free: %p %s", (void *)*attr, temp->name)); +#endif /* !__clang_analyzer__ */ + DEBUG_printf(("4debug_alloc: %p %s %s%s (%d)", (void *)temp, temp->name, temp->num_values > 1 ? "1setOf " : "", ippTagString(temp->value_tag), temp->num_values)); + if (ipp->current == *attr && ipp->prev) { /* @@ -7024,9 +6839,9 @@ ipp_write_file(int *fd, /* I - File descriptor */ ipp_uchar_t *buffer, /* I - Data to write */ size_t length) /* I - Number of bytes to write */ { -#ifdef WIN32 +#ifdef _WIN32 return ((ssize_t)write(*fd, buffer, (unsigned)length)); #else return (write(*fd, buffer, length)); -#endif /* WIN32 */ +#endif /* _WIN32 */ } diff --git a/cups/ipp.h b/cups/ipp.h index 2a4f546..6402855 100644 --- a/cups/ipp.h +++ b/cups/ipp.h @@ -1,16 +1,11 @@ /* * Internet Printing Protocol definitions for CUPS. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2006 by Easy Software Products. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ #ifndef _CUPS_IPP_H_ @@ -79,11 +74,11 @@ extern "C" { typedef enum ipp_dstate_e /**** Document states @exclude all@ ****/ { - IPP_DOCUMENT_PENDING = 3, /* Document is pending */ - IPP_DOCUMENT_PROCESSING = 5, /* Document is processing */ - IPP_DOCUMENT_CANCELED = 7, /* Document is canceled */ - IPP_DOCUMENT_ABORTED, /* Document is aborted */ - IPP_DOCUMENT_COMPLETED /* Document is completed */ + IPP_DSTATE_PENDING = 3, /* Document is pending */ + IPP_DSTATE_PROCESSING = 5, /* Document is processing */ + IPP_DSTATE_CANCELED = 7, /* Document is canceled */ + IPP_DSTATE_ABORTED, /* Document is aborted */ + IPP_DSTATE_COMPLETED /* Document is completed */ # ifndef _CUPS_NO_DEPRECATED # define IPP_DOCUMENT_PENDING IPP_DSTATE_PENDING @@ -321,6 +316,33 @@ typedef enum ipp_op_e /**** IPP operations ****/ IPP_OP_UPDATE_OUTPUT_DEVICE_ATTRIBUTES, /* Update-Output-Device-Attributes: Update output device values @exclude all@ */ IPP_OP_GET_NEXT_DOCUMENT_DATA, /* Get-Next-Document-Data: Scan more document data @exclude all@ */ + IPP_OP_ALLOCATE_PRINTER_RESOURCES, /* Allocate-Printer-Resources: Use resources for a printer. */ + IPP_OP_CREATE_PRINTER, /* Create-Printer: Create a new service. */ + IPP_OP_DEALLOCATE_PRINTER_RESOURCES, /* Deallocate-Printer-Resources: Stop using resources for a printer. */ + IPP_OP_DELETE_PRINTER, /* Delete-Printer: Delete an existing service. */ + IPP_OP_GET_PRINTERS, /* Get-Printers: Get a list of services. */ + IPP_OP_SHUTDOWN_ONE_PRINTER, /* Shutdown-One-Printer: Shutdown a service. */ + IPP_OP_STARTUP_ONE_PRINTER, /* Startup-One-Printer: Start a service. */ + IPP_OP_CANCEL_RESOURCE, /* Cancel-Resource: Uninstall a resource. */ + IPP_OP_CREATE_RESOURCE, /* Create-Resource: Create a new (empty) resource. */ + IPP_OP_INSTALL_RESOURCE, /* Install-Resource: Install a resource. */ + IPP_OP_SEND_RESOURCE_DATA, /* Send-Resource-Data: Upload the data for a resource. */ + IPP_OP_SET_RESOURCE_ATTRIBUTES, /* Set-Resource-Attributes: Set resource object attributes. */ + IPP_OP_CREATE_RESOURCE_SUBSCRIPTIONS, /* Create-Resource-Subscriptions: Create event subscriptions for a resource. */ + IPP_OP_CREATE_SYSTEM_SUBSCRIPTIONS, /* Create-System-Subscriptions: Create event subscriptions for a system. */ + IPP_OP_DISABLE_ALL_PRINTERS, /* Disable-All-Printers: Stop accepting new jobs on all services. */ + IPP_OP_ENABLE_ALL_PRINTERS, /* Enable-All-Printers: Start accepting new jobs on all services. */ + IPP_OP_GET_SYSTEM_ATTRIBUTES, /* Get-System-Attributes: Get system object attributes. */ + IPP_OP_GET_SYSTEM_SUPPORTED_VALUES, /* Get-System-Supported-Values: Get supported values for system object attributes. */ + IPP_OP_PAUSE_ALL_PRINTERS, /* Pause-All-Printers: Stop all services immediately. */ + IPP_OP_PAUSE_ALL_PRINTERS_AFTER_CURRENT_JOB, + /* Pause-All-Printers-After-Current-Job: Stop all services after processing the current jobs. */ + IPP_OP_REGISTER_OUTPUT_DEVICE, /* Register-Output-Device: Register a remote service. */ + IPP_OP_RESTART_SYSTEM, /* Restart-System: Restart all services. */ + IPP_OP_RESUME_ALL_PRINTERS, /* Resume-All-Printers: Start job processing on all services. */ + IPP_OP_SET_SYSTEM_ATTRIBUTES, /* Set-System-Attributes: Set system object attributes. */ + IPP_OP_SHUTDOWN_ALL_PRINTERS, /* Shutdown-All-Printers: Shutdown all services. */ + IPP_OP_STARTUP_ALL_PRINTERS, /* Startup-All-Printers: Startup all services. */ IPP_OP_PRIVATE = 0x4000, /* Reserved @private@ */ IPP_OP_CUPS_GET_DEFAULT, /* CUPS-Get-Default: Get the default printer */ @@ -468,6 +490,22 @@ typedef enum ipp_res_e /**** Resolution units ****/ IPP_RES_PER_CM /* Pixels per centimeter */ } ipp_res_t; +typedef enum ipp_rstate_e /**** resource-state values ****/ +{ + IPP_RSTATE_PENDING = 3, /* Resource is created but has no data yet. */ + IPP_RSTATE_AVAILABLE, /* Resource is available for installation. */ + IPP_RSTATE_INSTALLED, /* Resource is installed. */ + IPP_RSTATE_CANCELED, /* Resource has been canceled and is pending deletion. */ + IPP_RSTATE_ABORTED /* Resource has been aborted and is pending deletion. */ +} ipp_rstate_t; + +typedef enum ipp_sstate_e /**** system-state values ****/ +{ + IPP_SSTATE_IDLE = 3, /* At least one printer is idle and none are processing a job. */ + IPP_SSTATE_PROCESSING, /* At least one printer is processing a job. */ + IPP_SSTATE_STOPPED /* All printers are stopped. */ +} ipp_sstate_t; + typedef enum ipp_state_e /**** ipp_t state values ****/ { IPP_STATE_ERROR = -1, /* An error occurred */ @@ -647,8 +685,9 @@ typedef enum ipp_tag_e /**** Value and group tag values for attributes ****/ IPP_TAG_UNSUPPORTED_GROUP, /* Unsupported attributes group */ IPP_TAG_SUBSCRIPTION, /* Subscription group */ IPP_TAG_EVENT_NOTIFICATION, /* Event group */ - IPP_TAG_RESOURCE, /* Resource group @private@ */ - IPP_TAG_DOCUMENT, /* Document group @exclude all@ */ + IPP_TAG_RESOURCE, /* Resource group */ + IPP_TAG_DOCUMENT, /* Document group */ + IPP_TAG_SYSTEM, /* System group */ IPP_TAG_UNSUPPORTED_VALUE = 0x10, /* Unsupported value */ IPP_TAG_DEFAULT, /* Default value */ IPP_TAG_UNKNOWN, /* Unknown value */ @@ -702,192 +741,57 @@ typedef int (*ipp_copycb_t)(void *context, ipp_t *dst, ipp_attribute_t *attr); /**** ippCopyAttributes callback function @since CUPS 1.6/macOS 10.8 ****/ -/* - * The following structures are PRIVATE starting with CUPS 1.6/macOS 10.8. - * Please use the new accessor functions available in CUPS 1.6 and later, as - * these definitions will be moved to a private header file in a future release. - * - * Define _IPP_PRIVATE_STRUCTURES to 1 to cause the private IPP structures to be - * exposed in CUPS 1.6. This happens automatically on macOS when compiling for - * a deployment target of 10.7 or earlier. - * - * Define _IPP_PRIVATE_STRUCTURES to 0 to prevent the private IPP structures - * from being exposed. This is useful when migrating existing code to the new - * accessors. - */ - -# ifdef _IPP_PRIVATE_STRUCTURES - /* Somebody has overridden the value */ -# elif defined(_CUPS_SOURCE) || defined(_CUPS_IPP_PRIVATE_H_) - /* Building CUPS */ -# define _IPP_PRIVATE_STRUCTURES 1 -# elif defined(__APPLE__) -# if defined(MAC_OS_X_VERSION_10_8) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_8 - /* Building for 10.7 and earlier */ -# define _IPP_PRIVATE_STRUCTURES 1 -# elif !defined(MAC_OS_X_VERSION_10_8) - /* Building for 10.7 and earlier */ -# define _IPP_PRIVATE_STRUCTURES 1 -# endif /* MAC_OS_X_VERSION_10_8 && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_8 */ -# else -# define _IPP_PRIVATE_STRUCTURES 0 -# endif /* _CUPS_SOURCE || _CUPS_IPP_PRIVATE_H_ */ - -# if _IPP_PRIVATE_STRUCTURES -typedef union _ipp_request_u /**** Request Header ****/ -{ - struct /* Any Header */ - { - ipp_uchar_t version[2]; /* Protocol version number */ - int op_status; /* Operation ID or status code*/ - int request_id; /* Request ID */ - } any; - - struct /* Operation Header */ - { - ipp_uchar_t version[2]; /* Protocol version number */ - ipp_op_t operation_id; /* Operation ID */ - int request_id; /* Request ID */ - } op; - - struct /* Status Header */ - { - ipp_uchar_t version[2]; /* Protocol version number */ - ipp_status_t status_code; /* Status code */ - int request_id; /* Request ID */ - } status; - - /**** New in CUPS 1.1.19 ****/ - struct /* Event Header @since CUPS 1.1.19/macOS 10.3@ */ - { - ipp_uchar_t version[2]; /* Protocol version number */ - ipp_status_t status_code; /* Status code */ - int request_id; /* Request ID */ - } event; -} _ipp_request_t; - -/**** New in CUPS 1.1.19 ****/ - -typedef union _ipp_value_u /**** Attribute Value ****/ -{ - int integer; /* Integer/enumerated value */ - - char boolean; /* Boolean value */ - - ipp_uchar_t date[11]; /* Date/time value */ - - struct - { - int xres, /* Horizontal resolution */ - yres; /* Vertical resolution */ - ipp_res_t units; /* Resolution units */ - } resolution; /* Resolution value */ - - struct - { - int lower, /* Lower value */ - upper; /* Upper value */ - } range; /* Range of integers value */ - - struct - { - char *language; /* Language code */ - char *text; /* String */ - } string; /* String with language value */ - - struct - { - int length; /* Length of attribute */ - void *data; /* Data in attribute */ - } unknown; /* Unknown attribute type */ - -/**** New in CUPS 1.1.19 ****/ - ipp_t *collection; /* Collection value @since CUPS 1.1.19/macOS 10.3@ */ -} _ipp_value_t; -typedef _ipp_value_t ipp_value_t; /**** Convenience typedef that will be removed @private@ ****/ - -struct _ipp_attribute_s /**** IPP attribute ****/ -{ - ipp_attribute_t *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 */ - int num_values; /* Number of values */ - _ipp_value_t values[1]; /* Values */ -}; - -struct _ipp_s /**** IPP Request/Response/Notification ****/ -{ - ipp_state_t state; /* State of request */ - _ipp_request_t request; /* Request header */ - ipp_attribute_t *attrs; /* Attributes */ - ipp_attribute_t *last; /* Last attribute in list */ - ipp_attribute_t *current; /* Current attribute (for read/write) */ - ipp_tag_t curtag; /* Current attribute group tag */ - -/**** New in CUPS 1.2 ****/ - ipp_attribute_t *prev; /* Previous attribute (for read) @since CUPS 1.2/macOS 10.5@ */ - -/**** New in CUPS 1.4.4 ****/ - int use; /* Use count @since CUPS 1.4.4/macOS 10.6.?@ */ -/**** New in CUPS 2.0 ****/ - int atend, /* At end of list? */ - curindex; /* Current attribute index for hierarchical search */ -}; -# endif /* _IPP_PRIVATE_STRUCTURES */ - - /* * Prototypes... */ extern ipp_attribute_t *ippAddBoolean(ipp_t *ipp, ipp_tag_t group, - const char *name, char value); + const char *name, char value) _CUPS_PUBLIC; extern ipp_attribute_t *ippAddBooleans(ipp_t *ipp, ipp_tag_t group, const char *name, int num_values, - const char *values); + const char *values) _CUPS_PUBLIC; extern ipp_attribute_t *ippAddDate(ipp_t *ipp, ipp_tag_t group, - const char *name, const ipp_uchar_t *value); + const char *name, const ipp_uchar_t *value) _CUPS_PUBLIC; extern ipp_attribute_t *ippAddInteger(ipp_t *ipp, ipp_tag_t group, ipp_tag_t value_tag, const char *name, - int value); + int value) _CUPS_PUBLIC; extern ipp_attribute_t *ippAddIntegers(ipp_t *ipp, ipp_tag_t group, ipp_tag_t value_tag, const char *name, - int num_values, const int *values); + int num_values, const int *values) _CUPS_PUBLIC; extern ipp_attribute_t *ippAddRange(ipp_t *ipp, ipp_tag_t group, - const char *name, int lower, int upper); + const char *name, int lower, int upper) _CUPS_PUBLIC; extern ipp_attribute_t *ippAddRanges(ipp_t *ipp, ipp_tag_t group, const char *name, int num_values, - const int *lower, const int *upper); + const int *lower, const int *upper) _CUPS_PUBLIC; extern ipp_attribute_t *ippAddResolution(ipp_t *ipp, ipp_tag_t group, const char *name, ipp_res_t units, - int xres, int yres); + int xres, int yres) _CUPS_PUBLIC; extern ipp_attribute_t *ippAddResolutions(ipp_t *ipp, ipp_tag_t group, const char *name, int num_values, ipp_res_t units, const int *xres, - const int *yres); -extern ipp_attribute_t *ippAddSeparator(ipp_t *ipp); + const int *yres) _CUPS_PUBLIC; +extern ipp_attribute_t *ippAddSeparator(ipp_t *ipp) _CUPS_PUBLIC; extern ipp_attribute_t *ippAddString(ipp_t *ipp, ipp_tag_t group, ipp_tag_t value_tag, const char *name, - const char *language, const char *value); + const char *language, const char *value) _CUPS_PUBLIC; extern ipp_attribute_t *ippAddStrings(ipp_t *ipp, ipp_tag_t group, ipp_tag_t value_tag, const char *name, int num_values, const char *language, - const char * const *values); -extern time_t ippDateToTime(const ipp_uchar_t *date); -extern void ippDelete(ipp_t *ipp); -extern const char *ippErrorString(ipp_status_t error); + const char * const *values) _CUPS_PUBLIC; +extern time_t ippDateToTime(const ipp_uchar_t *date) _CUPS_PUBLIC; +extern void ippDelete(ipp_t *ipp) _CUPS_PUBLIC; +extern const char *ippErrorString(ipp_status_t error) _CUPS_PUBLIC; extern ipp_attribute_t *ippFindAttribute(ipp_t *ipp, const char *name, - ipp_tag_t value_tag); + ipp_tag_t value_tag) _CUPS_PUBLIC; extern ipp_attribute_t *ippFindNextAttribute(ipp_t *ipp, const char *name, - ipp_tag_t value_tag); -extern size_t ippLength(ipp_t *ipp); -extern ipp_t *ippNew(void); -extern ipp_state_t ippRead(http_t *http, ipp_t *ipp); -extern const ipp_uchar_t *ippTimeToDate(time_t t); -extern ipp_state_t ippWrite(http_t *http, ipp_t *ipp); -extern int ippPort(void); -extern void ippSetPort(int p); + ipp_tag_t value_tag) _CUPS_PUBLIC; +extern size_t ippLength(ipp_t *ipp) _CUPS_PUBLIC; +extern ipp_t *ippNew(void) _CUPS_PUBLIC; +extern ipp_state_t ippRead(http_t *http, ipp_t *ipp) _CUPS_PUBLIC; +extern const ipp_uchar_t *ippTimeToDate(time_t t) _CUPS_PUBLIC; +extern ipp_state_t ippWrite(http_t *http, ipp_t *ipp) _CUPS_PUBLIC; +extern int ippPort(void) _CUPS_PUBLIC; +extern void ippSetPort(int p) _CUPS_PUBLIC; /**** New in CUPS 1.1.19 ****/ extern ipp_attribute_t *ippAddCollection(ipp_t *ipp, ipp_tag_t group, diff --git a/cups/langprintf.c b/cups/langprintf.c index 46b6be5..bbcbb89 100644 --- a/cups/langprintf.c +++ b/cups/langprintf.c @@ -4,13 +4,7 @@ * Copyright 2007-2014 by Apple Inc. * Copyright 2002-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -18,6 +12,7 @@ */ #include "cups-private.h" +#include "debug-internal.h" /* diff --git a/cups/language-private.h b/cups/language-private.h index 49e4b71..7c304df 100644 --- a/cups/language-private.h +++ b/cups/language-private.h @@ -1,16 +1,11 @@ /* * Private localization support for CUPS. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2006 by Easy Software Products. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ #ifndef _CUPS_LANGUAGE_PRIVATE_H_ @@ -20,6 +15,7 @@ * Include necessary headers... */ +# include "config.h" # include # include # ifdef __APPLE__ @@ -38,13 +34,23 @@ extern "C" { # define _(x) x +/* + * Constants... + */ + +# define _CUPS_MESSAGE_PO 0 /* Message file is in GNU .po format */ +# define _CUPS_MESSAGE_UNQUOTE 1 /* Unescape \foo in strings? */ +# define _CUPS_MESSAGE_STRINGS 2 /* Message file is in Apple .strings format */ +# define _CUPS_MESSAGE_EMPTY 4 /* Allow empty localized strings */ + + /* * Types... */ typedef struct _cups_message_s /**** Message catalog entry ****/ { - char *id, /* Original string */ + char *msg, /* Original string */ *str; /* Localized string */ } _cups_message_t; @@ -54,26 +60,22 @@ typedef struct _cups_message_s /**** Message catalog entry ****/ */ # ifdef __APPLE__ -extern const char *_cupsAppleLanguage(const char *locale, char *language, size_t langsize); -extern const char *_cupsAppleLocale(CFStringRef languageName, char *locale, size_t localesize); +extern const char *_cupsAppleLanguage(const char *locale, char *language, size_t langsize) _CUPS_PRIVATE; +extern const char *_cupsAppleLocale(CFStringRef languageName, char *locale, size_t localesize) _CUPS_PRIVATE; # endif /* __APPLE__ */ -extern void _cupsCharmapFlush(void); -extern const char *_cupsEncodingName(cups_encoding_t encoding); -extern void _cupsLangPrintError(const char *prefix, - const char *message); -extern int _cupsLangPrintFilter(FILE *fp, const char *prefix, - const char *message, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); -extern int _cupsLangPrintf(FILE *fp, const char *message, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); -extern int _cupsLangPuts(FILE *fp, const char *message); -extern const char *_cupsLangString(cups_lang_t *lang, - const char *message); -extern void _cupsMessageFree(cups_array_t *a); -extern cups_array_t *_cupsMessageLoad(const char *filename, int unquote); -extern const char *_cupsMessageLookup(cups_array_t *a, const char *m); -extern cups_array_t *_cupsMessageNew(void *context); -extern void _cupsSetLocale(char *argv[]); +extern void _cupsCharmapFlush(void) _CUPS_INTERNAL; +extern const char *_cupsEncodingName(cups_encoding_t encoding) _CUPS_PRIVATE; +extern void _cupsLangPrintError(const char *prefix, const char *message) _CUPS_PRIVATE; +extern int _cupsLangPrintFilter(FILE *fp, const char *prefix, const char *message, ...) _CUPS_FORMAT(3, 4) _CUPS_PRIVATE; +extern int _cupsLangPrintf(FILE *fp, const char *message, ...) _CUPS_FORMAT(2, 3) _CUPS_PRIVATE; +extern int _cupsLangPuts(FILE *fp, const char *message) _CUPS_PRIVATE; +extern const char *_cupsLangString(cups_lang_t *lang, const char *message) _CUPS_PRIVATE; +extern void _cupsMessageFree(cups_array_t *a) _CUPS_PRIVATE; +extern cups_array_t *_cupsMessageLoad(const char *filename, int flags) _CUPS_PRIVATE; +extern const char *_cupsMessageLookup(cups_array_t *a, const char *m) _CUPS_PRIVATE; +extern cups_array_t *_cupsMessageNew(void *context) _CUPS_PRIVATE; +extern int _cupsMessageSave(const char *filename, int flags, cups_array_t *a) _CUPS_PRIVATE; +extern void _cupsSetLocale(char *argv[]) _CUPS_PRIVATE; # ifdef __cplusplus diff --git a/cups/language.c b/cups/language.c index f3a3496..e064169 100644 --- a/cups/language.c +++ b/cups/language.c @@ -4,13 +4,7 @@ * Copyright 2007-2017 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -18,14 +12,15 @@ */ #include "cups-private.h" +#include "debug-internal.h" #ifdef HAVE_LANGINFO_H # include #endif /* HAVE_LANGINFO_H */ -#ifdef WIN32 +#ifdef _WIN32 # include #else # include -#endif /* WIN32 */ +#endif /* _WIN32 */ #ifdef HAVE_COREFOUNDATION_H # include #endif /* HAVE_COREFOUNDATION_H */ @@ -123,7 +118,9 @@ static const _apple_language_locale_t apple_language_locale[] = { "nb", "no" }, { "nb_NO", "no" }, { "zh-Hans", "zh_CN" }, + { "zh_HANS", "zh_CN" }, { "zh-Hant", "zh_TW" }, + { "zh_HANT", "zh_TW" }, { "zh-Hant_CN", "zh_TW" } }; #endif /* __APPLE__ */ @@ -144,16 +141,15 @@ static const char *appleLangDefault(void); # define CF_RETURNS_RETAINED # endif /* __has_feature(attribute_cf_returns_retained) */ # endif /* !CF_RETURNED_RETAINED */ -static cups_array_t *appleMessageLoad(const char *locale) - CF_RETURNS_RETAINED; +static cups_array_t *appleMessageLoad(const char *locale) CF_RETURNS_RETAINED; # endif /* CUPS_BUNDLEDIR */ #endif /* __APPLE__ */ -static cups_lang_t *cups_cache_lookup(const char *name, - cups_encoding_t encoding); -static int cups_message_compare(_cups_message_t *m1, - _cups_message_t *m2); +static cups_lang_t *cups_cache_lookup(const char *name, cups_encoding_t encoding); +static int cups_message_compare(_cups_message_t *m1, _cups_message_t *m2); static void cups_message_free(_cups_message_t *m); static void cups_message_load(cups_lang_t *lang); +static void cups_message_puts(cups_file_t *fp, const char *s); +static int cups_read_strings(cups_file_t *fp, int flags, cups_array_t *a); static void cups_unquote(char *d, const char *s); @@ -254,8 +250,16 @@ _cupsAppleLocale(CFStringRef languageName, /* I - Apple language ID */ { int i; /* Looping var */ CFStringRef localeName; /* Locale as a CF string */ +#ifdef DEBUG + char temp[1024]; /* Temporary string */ + if (!CFStringGetCString(languageName, temp, (CFIndex)sizeof(temp), kCFStringEncodingASCII)) + temp[0] = '\0'; + + DEBUG_printf(("_cupsAppleLocale(languageName=%p(%s), locale=%p, localsize=%d)", (void *)languageName, temp, (void *)locale, (int)localesize)); +#endif /* DEBUG */ + localeName = CFLocaleCreateCanonicalLocaleIdentifierFromString(kCFAllocatorDefault, languageName); if (localeName) @@ -267,6 +271,8 @@ _cupsAppleLocale(CFStringRef languageName, /* I - Apple language ID */ if (!CFStringGetCString(localeName, locale, (CFIndex)localesize, kCFStringEncodingASCII)) *locale = '\0'; + DEBUG_printf(("_cupsAppleLocale: locale=\"%s\"", locale)); + CFRelease(localeName); /* @@ -278,8 +284,12 @@ _cupsAppleLocale(CFStringRef languageName, /* I - Apple language ID */ sizeof(apple_language_locale[0])); i ++) { - if (!strcmp(locale, apple_language_locale[i].language)) + size_t len = strlen(apple_language_locale[i].language); + + if (!strcmp(locale, apple_language_locale[i].language) || + (!strncmp(locale, apple_language_locale[i].language, len) && (locale[len] == '_' || locale[len] == '-'))) { + DEBUG_printf(("_cupsAppleLocale: Updating locale to \"%s\".", apple_language_locale[i].locale)); strlcpy(locale, apple_language_locale[i].locale, localesize); break; } @@ -296,7 +306,10 @@ _cupsAppleLocale(CFStringRef languageName, /* I - Apple language ID */ } if (!*locale) + { + DEBUG_puts("_cupsAppleLocale: Returning NULL."); return (NULL); + } /* * Convert language subtag into region subtag... @@ -304,10 +317,14 @@ _cupsAppleLocale(CFStringRef languageName, /* I - Apple language ID */ if (locale[2] == '-') locale[2] = '_'; + else if (locale[3] == '-') + locale[3] = '_'; if (!strchr(locale, '.')) strlcat(locale, ".UTF-8", localesize); + DEBUG_printf(("_cupsAppleLocale: Returning \"%s\".", locale)); + return (locale); } #endif /* __APPLE__ */ @@ -669,6 +686,15 @@ cupsLangGet(const char *language) /* I - Language or locale */ *ptr++ = (char)toupper(*language & 255); *ptr = '\0'; + + /* + * Map Chinese region codes to legacy country codes. + */ + + if (!strcmp(language, "zh") && !strcmp(country, "HANS")) + strlcpy(country, "CN", sizeof(country)); + if (!strcmp(language, "zh") && !strcmp(country, "HANT")) + strlcpy(country, "TW", sizeof(country)); } if (*language == '.' && !charset[0]) @@ -688,7 +714,7 @@ cupsLangGet(const char *language) /* I - Language or locale */ * Force a POSIX locale for an invalid language name... */ - if (strlen(langname) != 2) + if (strlen(langname) != 2 && strlen(langname) != 3) { strlcpy(langname, "C", sizeof(langname)); country[0] = '\0'; @@ -828,6 +854,9 @@ _cupsLangString(cups_lang_t *lang, /* I - Language */ { const char *s; /* Localized message */ + + DEBUG_printf(("_cupsLangString(lang=%p, message=\"%s\")", (void *)lang, message)); + /* * Range check input... */ @@ -877,12 +906,12 @@ _cupsMessageFree(cups_array_t *a) /* I - Message array */ /* - * '_cupsMessageLoad()' - Load a .po file into a messages array. + * '_cupsMessageLoad()' - Load a .po or .strings file into a messages array. */ cups_array_t * /* O - New message array */ _cupsMessageLoad(const char *filename, /* I - Message catalog to load */ - int unquote) /* I - Unescape \foo in strings? */ + int flags) /* I - Load flags */ { cups_file_t *fp; /* Message file */ cups_array_t *a; /* Message array */ @@ -917,188 +946,190 @@ _cupsMessageLoad(const char *filename, /* I - Message catalog to load */ return (a); } - /* - * Read messages from the catalog file until EOF... - * - * The format is the GNU gettext .po format, which is fairly simple: - * - * msgid "some text" - * msgstr "localized text" - * - * The ID and localized text can span multiple lines using the form: - * - * msgid "" - * "some long text" - * msgstr "" - * "localized text spanning " - * "multiple lines" - */ - - m = NULL; - - while (cupsFileGets(fp, s, sizeof(s)) != NULL) + if (flags & _CUPS_MESSAGE_STRINGS) + { + while (cups_read_strings(fp, flags, a)); + } + else { /* - * Skip blank and comment lines... + * Read messages from the catalog file until EOF... + * + * The format is the GNU gettext .po format, which is fairly simple: + * + * msgid "some text" + * msgstr "localized text" + * + * The ID and localized text can span multiple lines using the form: + * + * msgid "" + * "some long text" + * msgstr "" + * "localized text spanning " + * "multiple lines" */ - if (s[0] == '#' || !s[0]) - continue; + m = NULL; - /* - * Strip the trailing quote... - */ - - if ((ptr = strrchr(s, '\"')) == NULL) - continue; - - *ptr = '\0'; - - /* - * Find start of value... - */ - - if ((ptr = strchr(s, '\"')) == NULL) - continue; - - ptr ++; - - /* - * Unquote the text... - */ - - if (unquote) - cups_unquote(ptr, ptr); - - /* - * Create or add to a message... - */ - - if (!strncmp(s, "msgid", 5)) + while (cupsFileGets(fp, s, sizeof(s)) != NULL) { /* - * Add previous message as needed... + * Skip blank and comment lines... */ - if (m) - { - if (m->str && m->str[0]) - { - cupsArrayAdd(a, m); - } - else - { - /* - * Translation is empty, don't add it... (STR #4033) - */ - - free(m->id); - if (m->str) - free(m->str); - free(m); - } - } + if (s[0] == '#' || !s[0]) + continue; /* - * Create a new message with the given msgid string... + * Strip the trailing quote... */ - if ((m = (_cups_message_t *)calloc(1, sizeof(_cups_message_t))) == NULL) - { - cupsFileClose(fp); - return (a); - } + if ((ptr = strrchr(s, '\"')) == NULL) + continue; + + *ptr = '\0'; - if ((m->id = strdup(ptr)) == NULL) - { - free(m); - cupsFileClose(fp); - return (a); - } - } - else if (s[0] == '\"' && m) - { /* - * Append to current string... + * Find start of value... */ - length = strlen(m->str ? m->str : m->id); - ptrlen = strlen(ptr); + if ((ptr = strchr(s, '\"')) == NULL) + continue; - if ((temp = realloc(m->str ? m->str : m->id, length + ptrlen + 1)) == NULL) - { - if (m->str) - free(m->str); - free(m->id); - free(m); + ptr ++; - cupsFileClose(fp); - return (a); - } + /* + * Unquote the text... + */ - if (m->str) + if (flags & _CUPS_MESSAGE_UNQUOTE) + cups_unquote(ptr, ptr); + + /* + * Create or add to a message... + */ + + if (!strncmp(s, "msgid", 5)) { /* - * Copy the new portion to the end of the msgstr string - safe - * to use memcpy because the buffer is allocated to the correct - * size... + * Add previous message as needed... */ - m->str = temp; + if (m) + { + if (m->str && (m->str[0] || (flags & _CUPS_MESSAGE_EMPTY))) + { + cupsArrayAdd(a, m); + } + else + { + /* + * Translation is empty, don't add it... (STR #4033) + */ - memcpy(m->str + length, ptr, ptrlen + 1); + free(m->msg); + if (m->str) + free(m->str); + free(m); + } + } + + /* + * Create a new message with the given msgid string... + */ + + if ((m = (_cups_message_t *)calloc(1, sizeof(_cups_message_t))) == NULL) + break; + + if ((m->msg = strdup(ptr)) == NULL) + { + free(m); + m = NULL; + break; + } + } + else if (s[0] == '\"' && m) + { + /* + * Append to current string... + */ + + length = strlen(m->str ? m->str : m->msg); + ptrlen = strlen(ptr); + + if ((temp = realloc(m->str ? m->str : m->msg, length + ptrlen + 1)) == NULL) + { + if (m->str) + free(m->str); + free(m->msg); + free(m); + m = NULL; + break; + } + + if (m->str) + { + /* + * Copy the new portion to the end of the msgstr string - safe + * to use memcpy because the buffer is allocated to the correct + * size... + */ + + m->str = temp; + + memcpy(m->str + length, ptr, ptrlen + 1); + } + else + { + /* + * Copy the new portion to the end of the msgid string - safe + * to use memcpy because the buffer is allocated to the correct + * size... + */ + + m->msg = temp; + + memcpy(m->msg + length, ptr, ptrlen + 1); + } + } + else if (!strncmp(s, "msgstr", 6) && m) + { + /* + * Set the string... + */ + + if ((m->str = strdup(ptr)) == NULL) + { + free(m->msg); + free(m); + m = NULL; + break; + } + } + } + + /* + * Add the last message string to the array as needed... + */ + + if (m) + { + if (m->str && (m->str[0] || (flags & _CUPS_MESSAGE_EMPTY))) + { + cupsArrayAdd(a, m); } else { /* - * Copy the new portion to the end of the msgid string - safe - * to use memcpy because the buffer is allocated to the correct - * size... + * Translation is empty, don't add it... (STR #4033) */ - m->id = temp; - - memcpy(m->id + length, ptr, ptrlen + 1); + free(m->msg); + if (m->str) + free(m->str); + free(m); } } - else if (!strncmp(s, "msgstr", 6) && m) - { - /* - * Set the string... - */ - - if ((m->str = strdup(ptr)) == NULL) - { - free(m->id); - free(m); - - cupsFileClose(fp); - return (a); - } - } - } - - /* - * Add the last message string to the array as needed... - */ - - if (m) - { - if (m->str && m->str[0]) - { - cupsArrayAdd(a, m); - } - else - { - /* - * Translation is empty, don't add it... (STR #4033) - */ - - free(m->id); - if (m->str) - free(m->str); - free(m); - } } /* @@ -1107,8 +1138,7 @@ _cupsMessageLoad(const char *filename, /* I - Message catalog to load */ cupsFileClose(fp); - DEBUG_printf(("5_cupsMessageLoad: Returning %d messages...", - cupsArrayCount(a))); + DEBUG_printf(("5_cupsMessageLoad: Returning %d messages...", cupsArrayCount(a))); return (a); } @@ -1126,13 +1156,15 @@ _cupsMessageLookup(cups_array_t *a, /* I - Message array */ *match; /* Matching message */ + DEBUG_printf(("_cupsMessageLookup(a=%p, m=\"%s\")", (void *)a, m)); + /* * Lookup the message string; if it doesn't exist in the catalog, * then return the message that was passed to us... */ - key.id = (char *)m; - match = (_cups_message_t *)cupsArrayFind(a, &key); + key.msg = (char *)m; + match = (_cups_message_t *)cupsArrayFind(a, &key); #if defined(__APPLE__) && defined(CUPS_BUNDLEDIR) if (!match && cupsArrayUserData(a)) @@ -1145,12 +1177,11 @@ _cupsMessageLookup(cups_array_t *a, /* I - Message array */ CFStringRef cfm, /* Message as a CF string */ cfstr; /* Localized text as a CF string */ - dict = (CFDictionaryRef)cupsArrayUserData(a); - cfm = CFStringCreateWithCString(kCFAllocatorDefault, m, - kCFStringEncodingUTF8); - match = calloc(1, sizeof(_cups_message_t)); - match->id = strdup(m); - cfstr = cfm ? CFDictionaryGetValue(dict, cfm) : NULL; + dict = (CFDictionaryRef)cupsArrayUserData(a); + cfm = CFStringCreateWithCString(kCFAllocatorDefault, m, kCFStringEncodingUTF8); + match = calloc(1, sizeof(_cups_message_t)); + match->msg = strdup(m); + cfstr = cfm ? CFDictionaryGetValue(dict, cfm) : NULL; if (cfstr) { @@ -1159,8 +1190,7 @@ _cupsMessageLookup(cups_array_t *a, /* I - Message array */ CFStringGetCString(cfstr, buffer, sizeof(buffer), kCFStringEncodingUTF8); match->str = strdup(buffer); - DEBUG_printf(("1_cupsMessageLookup: Found \"%s\" as \"%s\"...", - m, buffer)); + DEBUG_printf(("1_cupsMessageLookup: Found \"%s\" as \"%s\"...", m, buffer)); } else { @@ -1197,6 +1227,57 @@ _cupsMessageNew(void *context) /* I - User data */ } +/* + * '_cupsMessageSave()' - Save a message catalog array. + */ + +int /* O - 0 on success, -1 on failure */ +_cupsMessageSave(const char *filename,/* I - Output filename */ + int flags, /* I - Format flags */ + cups_array_t *a) /* I - Message array */ +{ + cups_file_t *fp; /* Output file */ + _cups_message_t *m; /* Current message */ + + + /* + * Output message catalog file... + */ + + if ((fp = cupsFileOpen(filename, "w")) == NULL) + return (-1); + + /* + * Write each message... + */ + + if (flags & _CUPS_MESSAGE_STRINGS) + { + for (m = (_cups_message_t *)cupsArrayFirst(a); m; m = (_cups_message_t *)cupsArrayNext(a)) + { + cupsFilePuts(fp, "\""); + cups_message_puts(fp, m->msg); + cupsFilePuts(fp, "\" = \""); + cups_message_puts(fp, m->str); + cupsFilePuts(fp, "\";\n"); + } + } + else + { + for (m = (_cups_message_t *)cupsArrayFirst(a); m; m = (_cups_message_t *)cupsArrayNext(a)) + { + cupsFilePuts(fp, "msgid \""); + cups_message_puts(fp, m->msg); + cupsFilePuts(fp, "\"\nmsgstr \""); + cups_message_puts(fp, m->str); + cupsFilePuts(fp, "\"\n"); + } + } + + return (cupsFileClose(fp)); +} + + #ifdef __APPLE__ /* * 'appleLangDefault()' - Get the default locale string. @@ -1336,11 +1417,13 @@ appleMessageLoad(const char *locale) /* I - Locale ID */ { char filename[1024], /* Path to cups.strings file */ applelang[256], /* Apple language ID */ - baselang[3]; /* Base language */ + baselang[4]; /* Base language */ CFURLRef url; /* URL to cups.strings file */ CFReadStreamRef stream = NULL; /* File stream */ CFPropertyListRef plist = NULL; /* Localization file */ #ifdef DEBUG + const char *cups_strings = getenv("CUPS_STRINGS"); + /* Test strings file */ CFErrorRef error = NULL; /* Error when opening file */ #endif /* DEBUG */ @@ -1351,6 +1434,15 @@ appleMessageLoad(const char *locale) /* I - Locale ID */ * Load the cups.strings file... */ +#ifdef DEBUG + if (cups_strings) + { + DEBUG_puts("1appleMessageLoad: Using debug CUPS_STRINGS file."); + strlcpy(filename, cups_strings, sizeof(filename)); + } + else +#endif /* DEBUG */ + snprintf(filename, sizeof(filename), CUPS_BUNDLEDIR "/Resources/%s.lproj/cups.strings", _cupsAppleLanguage(locale, applelang, sizeof(applelang))); @@ -1363,6 +1455,7 @@ appleMessageLoad(const char *locale) /* I - Locale ID */ * Try with original locale string... */ + DEBUG_printf(("1appleMessageLoad: \"%s\": %s", filename, strerror(errno))); snprintf(filename, sizeof(filename), CUPS_BUNDLEDIR "/Resources/%s.lproj/cups.strings", locale); } @@ -1374,18 +1467,23 @@ appleMessageLoad(const char *locale) /* I - Locale ID */ * Try with just the language code... */ + DEBUG_printf(("1appleMessageLoad: \"%s\": %s", filename, strerror(errno))); + strlcpy(baselang, locale, sizeof(baselang)); + if (baselang[3] == '-' || baselang[3] == '_') + baselang[3] = '\0'; + snprintf(filename, sizeof(filename), CUPS_BUNDLEDIR "/Resources/%s.lproj/cups.strings", baselang); } - DEBUG_printf(("1appleMessageLoad: filename=\"%s\"", filename)); - if (access(filename, 0)) { /* * Try alternate lproj directory names... */ + DEBUG_printf(("1appleMessageLoad: \"%s\": %s", filename, strerror(errno))); + if (!strncmp(locale, "en", 2)) locale = "English"; else if (!strncmp(locale, "nb", 2)) @@ -1402,7 +1500,7 @@ appleMessageLoad(const char *locale) /* I - Locale ID */ locale = "Japanese"; else if (!strncmp(locale, "es", 2)) locale = "Spanish"; - else if (!strcmp(locale, "zh_HK") || !strncmp(locale, "zh-Hant", 7)) + else if (!strcmp(locale, "zh_HK") || !strncasecmp(locale, "zh-Hant", 7) || !strncasecmp(locale, "zh_Hant", 7)) { /* * @@ -1423,14 +1521,18 @@ appleMessageLoad(const char *locale) /* I - Locale ID */ */ strlcpy(baselang, locale, sizeof(baselang)); + if (baselang[2] == '-' || baselang[2] == '_') + baselang[2] = '\0'; + locale = baselang; } snprintf(filename, sizeof(filename), CUPS_BUNDLEDIR "/Resources/%s.lproj/cups.strings", locale); - DEBUG_printf(("1appleMessageLoad: alternate filename=\"%s\"", filename)); } + DEBUG_printf(("1appleMessageLoad: filename=\"%s\"", filename)); + url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8 *)filename, (CFIndex)strlen(filename), false); @@ -1549,7 +1651,7 @@ cups_message_compare( _cups_message_t *m1, /* I - First message */ _cups_message_t *m2) /* I - Second message */ { - return (strcmp(m1->id, m2->id)); + return (strcmp(m1->msg, m2->msg)); } @@ -1560,8 +1662,8 @@ cups_message_compare( static void cups_message_free(_cups_message_t *m) /* I - Message */ { - if (m->id) - free(m->id); + if (m->msg) + free(m->msg); if (m->str) free(m->str); @@ -1615,11 +1717,166 @@ cups_message_load(cups_lang_t *lang) /* I - Language */ * Read the strings from the file... */ - lang->strings = _cupsMessageLoad(filename, 1); + lang->strings = _cupsMessageLoad(filename, _CUPS_MESSAGE_UNQUOTE); #endif /* __APPLE__ && CUPS_BUNDLEDIR */ } +/* + * 'cups_message_puts()' - Write a message string with quoting. + */ + +static void +cups_message_puts(cups_file_t *fp, /* I - File to write to */ + const char *s) /* I - String to write */ +{ + const char *start, /* Start of substring */ + *ptr; /* Pointer into string */ + + + for (start = s, ptr = s; *ptr; ptr ++) + { + if (strchr("\\\"\n\t", *ptr)) + { + if (ptr > start) + { + cupsFileWrite(fp, start, (size_t)(ptr - start)); + start = ptr + 1; + } + + if (*ptr == '\\') + cupsFileWrite(fp, "\\\\", 2); + else if (*ptr == '\"') + cupsFileWrite(fp, "\\\"", 2); + else if (*ptr == '\n') + cupsFileWrite(fp, "\\n", 2); + else /* if (*ptr == '\t') */ + cupsFileWrite(fp, "\\t", 2); + } + } + + if (ptr > start) + cupsFileWrite(fp, start, (size_t)(ptr - start)); +} + + +/* + * 'cups_read_strings()' - Read a pair of strings from a .strings file. + */ + +static int /* O - 1 on success, 0 on failure */ +cups_read_strings(cups_file_t *fp, /* I - .strings file */ + int flags, /* I - CUPS_MESSAGE_xxx flags */ + cups_array_t *a) /* I - Message catalog array */ +{ + char buffer[8192], /* Line buffer */ + *bufptr, /* Pointer into buffer */ + *msg, /* Pointer to start of message */ + *str; /* Pointer to start of translation string */ + _cups_message_t *m; /* New message */ + + + while (cupsFileGets(fp, buffer, sizeof(buffer))) + { + /* + * Skip any line (comments, blanks, etc.) that isn't: + * + * "message" = "translation"; + */ + + for (bufptr = buffer; *bufptr && isspace(*bufptr & 255); bufptr ++); + + if (*bufptr != '\"') + continue; + + /* + * Find the end of the message... + */ + + bufptr ++; + for (msg = bufptr; *bufptr && *bufptr != '\"'; bufptr ++) + if (*bufptr == '\\' && bufptr[1]) + bufptr ++; + + if (!*bufptr) + continue; + + *bufptr++ = '\0'; + + if (flags & _CUPS_MESSAGE_UNQUOTE) + cups_unquote(msg, msg); + + /* + * Find the start of the translation... + */ + + while (*bufptr && isspace(*bufptr & 255)) + bufptr ++; + + if (*bufptr != '=') + continue; + + bufptr ++; + while (*bufptr && isspace(*bufptr & 255)) + bufptr ++; + + if (*bufptr != '\"') + continue; + + /* + * Find the end of the translation... + */ + + bufptr ++; + for (str = bufptr; *bufptr && *bufptr != '\"'; bufptr ++) + if (*bufptr == '\\' && bufptr[1]) + bufptr ++; + + if (!*bufptr) + continue; + + *bufptr++ = '\0'; + + if (flags & _CUPS_MESSAGE_UNQUOTE) + cups_unquote(str, str); + + /* + * If we get this far we have a valid pair of strings, add them... + */ + + if ((m = malloc(sizeof(_cups_message_t))) == NULL) + break; + + m->msg = strdup(msg); + m->str = strdup(str); + + if (m->msg && m->str) + { + cupsArrayAdd(a, m); + } + else + { + if (m->msg) + free(m->msg); + + if (m->str) + free(m->str); + + free(m); + break; + } + + return (1); + } + + /* + * No more strings... + */ + + return (0); +} + + /* * 'cups_unquote()' - Unquote characters in strings... */ diff --git a/cups/language.h b/cups/language.h index c96cbfe..b5ec7e1 100644 --- a/cups/language.h +++ b/cups/language.h @@ -4,13 +4,7 @@ * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ #ifndef _CUPS_LANGUAGE_H_ @@ -96,11 +90,11 @@ typedef struct cups_lang_s /**** Language Cache Structure ****/ * Prototypes... */ -extern cups_lang_t *cupsLangDefault(void); -extern const char *cupsLangEncoding(cups_lang_t *lang); -extern void cupsLangFlush(void); -extern void cupsLangFree(cups_lang_t *lang); -extern cups_lang_t *cupsLangGet(const char *language); +extern cups_lang_t *cupsLangDefault(void) _CUPS_PUBLIC; +extern const char *cupsLangEncoding(cups_lang_t *lang) _CUPS_PUBLIC; +extern void cupsLangFlush(void) _CUPS_PUBLIC; +extern void cupsLangFree(cups_lang_t *lang) _CUPS_PUBLIC; +extern cups_lang_t *cupsLangGet(const char *language) _CUPS_PUBLIC; # ifdef __cplusplus } diff --git a/cups/libcups2.def b/cups/libcups2.def index a7be679..bcd4d08 100644 --- a/cups/libcups2.def +++ b/cups/libcups2.def @@ -1,5 +1,5 @@ LIBRARY libcups2 -VERSION 2.12 +VERSION 2.14 EXPORTS _cupsArrayAddStrings _cupsArrayNewStrings @@ -12,7 +12,9 @@ _cupsCondWait _cupsConnect _cupsConvertOptions _cupsCreateDest +_cupsEncodeOption _cupsEncodingName +_cupsFilePeekAhead _cupsGet1284Values _cupsGetDestResource _cupsGetDests @@ -24,13 +26,11 @@ _cupsLangPrintError _cupsLangPrintf _cupsLangPuts _cupsLangString -_cupsMD5Append -_cupsMD5Finish -_cupsMD5Init _cupsMessageFree _cupsMessageLoad _cupsMessageLookup _cupsMessageNew +_cupsMessageSave _cupsMutexInit _cupsMutexLock _cupsMutexUnlock @@ -39,18 +39,19 @@ _cupsRWInit _cupsRWLockRead _cupsRWLockWrite _cupsRWUnlock -_cupsSNMPClose -_cupsSNMPCopyOID -_cupsSNMPDefaultCommunity -_cupsSNMPIsOID -_cupsSNMPIsOIDPrefixed -_cupsSNMPOIDToString -_cupsSNMPOpen -_cupsSNMPRead -_cupsSNMPSetDebug -_cupsSNMPStringToOID -_cupsSNMPWalk -_cupsSNMPWrite +_cupsRasterAddError +_cupsRasterClearError +_cupsRasterColorSpaceString +_cupsRasterDelete +_cupsRasterErrorString +_cupsRasterExecPS +_cupsRasterInitPWGHeader +_cupsRasterInterpretPPD +_cupsRasterNew +_cupsRasterReadHeader +_cupsRasterReadPixels +_cupsRasterWriteHeader +_cupsRasterWritePixels _cupsSetDefaults _cupsSetError _cupsSetHTTPError @@ -65,15 +66,19 @@ _cupsStrScand _cupsStrStatistics _cupsThreadCancel _cupsThreadCreate +_cupsThreadDetach _cupsThreadWait _cupsUserDefault +_cups_gettimeofday _cups_safe_vsnprintf +_cups_snprintf _cups_strcasecmp _cups_strcpy _cups_strcpy _cups_strlcat _cups_strlcpy _cups_strncasecmp +_cups_vsnprintf _httpAddrSetPort _httpCreateCredentials _httpDecodeURI @@ -81,6 +86,7 @@ _httpDisconnect _httpEncodeURI _httpFreeCredentials _httpResolveURI +_httpSetDigestAuthString _httpStatus _httpTLSInitialize _httpTLSPending @@ -92,7 +98,15 @@ _httpTLSWrite _httpUpdate _httpWait _ippCheckOptions +_ippFileParse +_ippFileReadToken _ippFindOption +_ippVarsDeinit +_ippVarsExpand +_ippVarsGet +_ippVarsInit +_ippVarsPasswordCB +_ippVarsSet _ppdCacheCreateWithFile _ppdCacheCreateWithPPD _ppdCacheDestroy @@ -124,6 +138,8 @@ _pwgMediaTable _pwgMediaTypeForType _pwgPageSizeForMedia cupsAddDest +cupsAddDestMediaOptions +cupsAddIntegerOption cupsAddOption cupsAdminCreateWindowsPPD cupsAdminExportSamba @@ -171,6 +187,7 @@ cupsDoAuthentication cupsDoFileRequest cupsDoIORequest cupsDoRequest +cupsEncodeOption cupsEncodeOptions cupsEncodeOptions2 cupsEncryption @@ -227,6 +244,7 @@ cupsGetDests2 cupsGetDevices cupsGetFd cupsGetFile +cupsGetIntegerOption cupsGetJobs cupsGetJobs2 cupsGetNamedDest @@ -240,6 +258,7 @@ cupsGetPrinters cupsGetResponse cupsGetServerPPD cupsHashData +cupsHashString cupsLangDefault cupsLangEncoding cupsLangFlush @@ -261,6 +280,30 @@ cupsPrintFiles cupsPrintFiles2 cupsPutFd cupsPutFile +cupsRasterClose +cupsRasterClose +cupsRasterErrorString +cupsRasterErrorString +cupsRasterInitPWGHeader +cupsRasterInitPWGHeader +cupsRasterInterpretPPD +cupsRasterInterpretPPD +cupsRasterOpen +cupsRasterOpen +cupsRasterOpenIO +cupsRasterOpenIO +cupsRasterReadHeader +cupsRasterReadHeader +cupsRasterReadHeader2 +cupsRasterReadHeader2 +cupsRasterReadPixels +cupsRasterReadPixels +cupsRasterWriteHeader +cupsRasterWriteHeader +cupsRasterWriteHeader2 +cupsRasterWriteHeader2 +cupsRasterWritePixels +cupsRasterWritePixels cupsReadResponseData cupsRemoveDest cupsRemoveOption diff --git a/cups/libcups_s.exp b/cups/libcups_s.exp deleted file mode 100644 index b8b2207..0000000 --- a/cups/libcups_s.exp +++ /dev/null @@ -1,85 +0,0 @@ -_cups_debug_fd -_cupsBufferGet -_cupsBufferRelease -_cupsGet1284Values -_cupsGetDests -_cupsGetPassword -_cupsGlobals -_cupsLangPrintError -_cupsLangPrintf -_cupsLangPuts -_cupsLangString -_cupsMD5Append -_cupsMD5Finish -_cupsMD5Init -_cupsMessageFree -_cupsMessageLoad -_cupsMessageLookup -_cupsNextDelay -_cupsSetError -_cupsSetLocale -_cupsSNMPClose -_cupsSNMPCopyOID -_cupsSNMPDefaultCommunity -_cupsSNMPIsOID -_cupsSNMPIsOIDPrefixed -_cupsSNMPOIDToString -_cupsSNMPOpen -_cupsSNMPRead -_cupsSNMPSetDebug -_cupsSNMPStringToOID -_cupsSNMPWalk -_cupsSNMPWrite -_cupsStrAlloc -_cupsStrFlush -_cupsStrFormatd -_cupsStrFree -_cupsStrRetain -_cupsStrScand -_cupsStrStatistics -_cups_getifaddrs -_cups_freeifaddrs -_cups_strcpy -_cups_strlcat -_cups_strlcpy -_httpAddrPort -_httpAddrSetPort -_httpAssembleUUID -_httpBIOMethods -_httpCreate -_httpEncodeURI -_httpPeek -_httpResolveURI -_httpSetTimeout -_httpWait -_ippFindOption -_ppdFreeLanguages -_ppdGetEncoding -_ppdGetLanguages -_ppdHashName -_ppdLocalizedAttr -_ppdNormalizeMakeAndModel -_ppdOpen -_ppdOpenFile -_ppdParseOptions -_pwgCreateWithFile -_pwgDestroy -_pwgWriteFile -_pwgGenerateSize -_pwgInitSize -_pwgMediaForLegacy -_pwgMediaForPPD -_pwgMediaForPWG -_pwgMediaForSize -_pwgCreateWithPPD -_pwgGetBin -_pwgGetInputSlot -_pwgGetMediaType -_pwgGetOutputBin -_pwgGetPageSize -_pwgGetSize -_pwgGetSource -_pwgGetType -_pwgInputSlotForSource -_pwgMediaTypeForType -_pwgPageSizeForMedia diff --git a/cups/localize.c b/cups/localize.c deleted file mode 100644 index 7bb0fed..0000000 --- a/cups/localize.c +++ /dev/null @@ -1,779 +0,0 @@ -/* - * "$Id: localize.c 7679 2008-06-19 23:37:45Z mike $" - * - * PPD localization routines for CUPS. - * - * Copyright 2007-2012 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * PostScript is a trademark of Adobe Systems, Inc. - * - * This code and any derivative of it may be used and distributed - * freely under the terms of the GNU General Public License when - * used with GNU Ghostscript or its derivatives. Use of the code - * (or any derivative of it) with software other than GNU - * GhostScript (or its derivatives) is governed by the CUPS license - * agreement. - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * ppdLocalize() - Localize the PPD file to the current locale. - * ppdLocalizeAttr() - Localize an attribute. - * ppdLocalizeIPPReason() - Get the localized version of a cupsIPPReason - * attribute. - * ppdLocalizeMarkerName() - Get the localized version of a marker-names - * attribute value. - * _ppdFreeLanguages() - Free an array of languages from _ppdGetLanguages. - * _ppdGetLanguages() - Get an array of languages from a PPD file. - * _ppdHashName() - Generate a hash value for a device or profile - * name. - * _ppdLocalizedAttr() - Find a localized attribute. - * ppd_ll_CC() - Get the current locale names. - */ - -/* - * Include necessary headers. - */ - -#include "cups-private.h" -#include "ppd-private.h" - - -/* - * Local functions... - */ - -static cups_lang_t *ppd_ll_CC(char *ll_CC, int ll_CC_size); - - -/* - * 'ppdLocalize()' - Localize the PPD file to the current locale. - * - * All groups, options, and choices are localized, as are ICC profile - * descriptions, printer presets, and custom option parameters. Each - * localized string uses the UTF-8 character encoding. - * - * @since CUPS 1.2/OS X 10.5@ - */ - -int /* O - 0 on success, -1 on error */ -ppdLocalize(ppd_file_t *ppd) /* I - PPD file */ -{ - int i, j, k; /* Looping vars */ - ppd_group_t *group; /* Current group */ - ppd_option_t *option; /* Current option */ - ppd_choice_t *choice; /* Current choice */ - ppd_coption_t *coption; /* Current custom option */ - ppd_cparam_t *cparam; /* Current custom parameter */ - ppd_attr_t *attr, /* Current attribute */ - *locattr; /* Localized attribute */ - char ckeyword[PPD_MAX_NAME], /* Custom keyword */ - ll_CC[6]; /* Language + country locale */ - - - /* - * Range check input... - */ - - DEBUG_printf(("ppdLocalize(ppd=%p)", ppd)); - - if (!ppd) - return (-1); - - /* - * Get the default language... - */ - - ppd_ll_CC(ll_CC, sizeof(ll_CC)); - - /* - * Now lookup all of the groups, options, choices, etc. - */ - - for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++) - { - if ((locattr = _ppdLocalizedAttr(ppd, "Translation", group->name, - ll_CC)) != NULL) - strlcpy(group->text, locattr->text, sizeof(group->text)); - - for (j = group->num_options, option = group->options; j > 0; j --, option ++) - { - if ((locattr = _ppdLocalizedAttr(ppd, "Translation", option->keyword, - ll_CC)) != NULL) - strlcpy(option->text, locattr->text, sizeof(option->text)); - - for (k = option->num_choices, choice = option->choices; - k > 0; - k --, choice ++) - { - if (strcmp(choice->choice, "Custom") || - !ppdFindCustomOption(ppd, option->keyword)) - locattr = _ppdLocalizedAttr(ppd, option->keyword, choice->choice, - ll_CC); - else - { - snprintf(ckeyword, sizeof(ckeyword), "Custom%s", option->keyword); - - locattr = _ppdLocalizedAttr(ppd, ckeyword, "True", ll_CC); - } - - if (locattr) - strlcpy(choice->text, locattr->text, sizeof(choice->text)); - } - } - } - - /* - * Translate any custom parameters... - */ - - for (coption = (ppd_coption_t *)cupsArrayFirst(ppd->coptions); - coption; - coption = (ppd_coption_t *)cupsArrayNext(ppd->coptions)) - { - for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params); - cparam; - cparam = (ppd_cparam_t *)cupsArrayNext(coption->params)) - { - snprintf(ckeyword, sizeof(ckeyword), "ParamCustom%s", coption->keyword); - - if ((locattr = _ppdLocalizedAttr(ppd, ckeyword, cparam->name, - ll_CC)) != NULL) - strlcpy(cparam->text, locattr->text, sizeof(cparam->text)); - } - } - - /* - * Translate ICC profile names... - */ - - if ((attr = ppdFindAttr(ppd, "APCustomColorMatchingName", NULL)) != NULL) - { - if ((locattr = _ppdLocalizedAttr(ppd, "APCustomColorMatchingName", - attr->spec, ll_CC)) != NULL) - strlcpy(attr->text, locattr->text, sizeof(attr->text)); - } - - for (attr = ppdFindAttr(ppd, "cupsICCProfile", NULL); - attr; - attr = ppdFindNextAttr(ppd, "cupsICCProfile", NULL)) - { - cupsArraySave(ppd->sorted_attrs); - - if ((locattr = _ppdLocalizedAttr(ppd, "cupsICCProfile", attr->spec, - ll_CC)) != NULL) - strlcpy(attr->text, locattr->text, sizeof(attr->text)); - - cupsArrayRestore(ppd->sorted_attrs); - } - - /* - * Translate printer presets... - */ - - for (attr = ppdFindAttr(ppd, "APPrinterPreset", NULL); - attr; - attr = ppdFindNextAttr(ppd, "APPrinterPreset", NULL)) - { - cupsArraySave(ppd->sorted_attrs); - - if ((locattr = _ppdLocalizedAttr(ppd, "APPrinterPreset", attr->spec, - ll_CC)) != NULL) - strlcpy(attr->text, locattr->text, sizeof(attr->text)); - - cupsArrayRestore(ppd->sorted_attrs); - } - - return (0); -} - - -/* - * 'ppdLocalizeAttr()' - Localize an attribute. - * - * This function uses the current locale to find the localized attribute for - * the given main and option keywords. If no localized version of the - * attribute exists for the current locale, the unlocalized version is returned. - */ - -ppd_attr_t * /* O - Localized attribute or @code NULL@ if none exists */ -ppdLocalizeAttr(ppd_file_t *ppd, /* I - PPD file */ - const char *keyword, /* I - Main keyword */ - const char *spec) /* I - Option keyword or @code NULL@ for none */ -{ - ppd_attr_t *locattr; /* Localized attribute */ - char ll_CC[6]; /* Language + country locale */ - - - /* - * Get the default language... - */ - - ppd_ll_CC(ll_CC, sizeof(ll_CC)); - - /* - * Find the localized attribute... - */ - - if (spec) - locattr = _ppdLocalizedAttr(ppd, keyword, spec, ll_CC); - else - locattr = _ppdLocalizedAttr(ppd, "Translation", keyword, ll_CC); - - if (!locattr) - locattr = ppdFindAttr(ppd, keyword, spec); - - return (locattr); -} - - -/* - * 'ppdLocalizeIPPReason()' - Get the localized version of a cupsIPPReason - * attribute. - * - * This function uses the current locale to find the corresponding reason - * text or URI from the attribute value. If "scheme" is NULL or "text", - * the returned value contains human-readable (UTF-8) text from the translation - * string or attribute value. Otherwise the corresponding URI is returned. - * - * If no value of the requested scheme can be found, NULL is returned. - * - * @since CUPS 1.3/OS X 10.5@ - */ - -const char * /* O - Value or NULL if not found */ -ppdLocalizeIPPReason( - ppd_file_t *ppd, /* I - PPD file */ - const char *reason, /* I - IPP reason keyword to look up */ - const char *scheme, /* I - URI scheme or NULL for text */ - char *buffer, /* I - Value buffer */ - size_t bufsize) /* I - Size of value buffer */ -{ - cups_lang_t *lang; /* Current language */ - ppd_attr_t *locattr; /* Localized attribute */ - char ll_CC[6], /* Language + country locale */ - *bufptr, /* Pointer into buffer */ - *bufend, /* Pointer to end of buffer */ - *valptr; /* Pointer into value */ - int ch, /* Hex-encoded character */ - schemelen; /* Length of scheme name */ - - - /* - * Range check input... - */ - - if (buffer) - *buffer = '\0'; - - if (!ppd || !reason || (scheme && !*scheme) || - !buffer || bufsize < PPD_MAX_TEXT) - return (NULL); - - /* - * Get the default language... - */ - - lang = ppd_ll_CC(ll_CC, sizeof(ll_CC)); - - /* - * Find the localized attribute... - */ - - if ((locattr = _ppdLocalizedAttr(ppd, "cupsIPPReason", reason, - ll_CC)) == NULL) - locattr = ppdFindAttr(ppd, "cupsIPPReason", reason); - - if (!locattr) - { - if (lang && (!scheme || !strcmp(scheme, "text"))) - { - /* - * Try to localize a standard printer-state-reason keyword... - */ - - const char *message = NULL; /* Localized message */ - - if (!strncmp(reason, "media-needed", 12)) - message = _("The paper tray needs to be filled."); - else if (!strncmp(reason, "media-jam", 9)) - message = _("There is a paper jam."); - else if (!strncmp(reason, "offline", 7) || - !strncmp(reason, "shutdown", 8)) - message = _("The printer is not connected."); - else if (!strncmp(reason, "toner-low", 9)) - message = _("The printer is running low on toner."); - else if (!strncmp(reason, "toner-empty", 11)) - message = _("The printer may be out of toner."); - else if (!strncmp(reason, "cover-open", 10)) - message = _("The printer's cover is open."); - else if (!strncmp(reason, "interlock-open", 14)) - message = _("The printer's interlock is open."); - else if (!strncmp(reason, "door-open", 9)) - message = _("The printer's door is open."); - else if (!strncmp(reason, "input-tray-missing", 18)) - message = _("The paper tray is missing."); - else if (!strncmp(reason, "media-low", 9)) - message = _("The paper tray is almost empty."); - else if (!strncmp(reason, "media-empty", 11)) - message = _("The paper tray is empty."); - else if (!strncmp(reason, "output-tray-missing", 19)) - message = _("The output bin is missing."); - else if (!strncmp(reason, "output-area-almost-full", 23)) - message = _("The output bin is almost full."); - else if (!strncmp(reason, "output-area-full", 16)) - message = _("The output bin is full."); - else if (!strncmp(reason, "marker-supply-low", 17)) - message = _("The printer is running low on ink."); - else if (!strncmp(reason, "marker-supply-empty", 19)) - message = _("The printer may be out of ink."); - else if (!strncmp(reason, "marker-waste-almost-full", 24)) - message = _("The printer's waste bin is almost full."); - else if (!strncmp(reason, "marker-waste-full", 17)) - message = _("The printer's waste bin is full."); - else if (!strncmp(reason, "fuser-over-temp", 15)) - message = _("The fuser's temperature is high."); - else if (!strncmp(reason, "fuser-under-temp", 16)) - message = _("The fuser's temperature is low."); - else if (!strncmp(reason, "opc-near-eol", 12)) - message = _("The optical photoconductor will need to be replaced soon."); - else if (!strncmp(reason, "opc-life-over", 13)) - message = _("The optical photoconductor needs to be replaced."); - else if (!strncmp(reason, "developer-low", 13)) - message = _("The developer unit will need to be replaced soon."); - else if (!strncmp(reason, "developer-empty", 15)) - message = _("The developer unit needs to be replaced."); - - if (message) - { - strlcpy(buffer, _cupsLangString(lang, message), bufsize); - return (buffer); - } - } - - return (NULL); - } - - /* - * Now find the value we need... - */ - - bufend = buffer + bufsize - 1; - - if (!scheme || !strcmp(scheme, "text")) - { - /* - * Copy a text value (either the translation text or text:... URIs from - * the value... - */ - - strlcpy(buffer, locattr->text, bufsize); - - for (valptr = locattr->value, bufptr = buffer; *valptr && bufptr < bufend;) - { - if (!strncmp(valptr, "text:", 5)) - { - /* - * Decode text: URI and add to the buffer... - */ - - valptr += 5; - - while (*valptr && !_cups_isspace(*valptr) && bufptr < bufend) - { - if (*valptr == '%' && isxdigit(valptr[1] & 255) && - isxdigit(valptr[2] & 255)) - { - /* - * Pull a hex-encoded character from the URI... - */ - - valptr ++; - - if (isdigit(*valptr & 255)) - ch = (*valptr - '0') << 4; - else - ch = (tolower(*valptr) - 'a' + 10) << 4; - valptr ++; - - if (isdigit(*valptr & 255)) - *bufptr++ = ch | (*valptr - '0'); - else - *bufptr++ = ch | (tolower(*valptr) - 'a' + 10); - valptr ++; - } - else if (*valptr == '+') - { - *bufptr++ = ' '; - valptr ++; - } - else - *bufptr++ = *valptr++; - } - } - else - { - /* - * Skip this URI... - */ - - while (*valptr && !_cups_isspace(*valptr)) - valptr++; - } - - /* - * Skip whitespace... - */ - - while (_cups_isspace(*valptr)) - valptr ++; - } - - if (bufptr > buffer) - *bufptr = '\0'; - - return (buffer); - } - else - { - /* - * Copy a URI... - */ - - schemelen = strlen(scheme); - if (scheme[schemelen - 1] == ':') /* Force scheme to be just the name */ - schemelen --; - - for (valptr = locattr->value, bufptr = buffer; *valptr && bufptr < bufend;) - { - if ((!strncmp(valptr, scheme, schemelen) && valptr[schemelen] == ':') || - (*valptr == '/' && !strcmp(scheme, "file"))) - { - /* - * Copy URI... - */ - - while (*valptr && !_cups_isspace(*valptr) && bufptr < bufend) - *bufptr++ = *valptr++; - - *bufptr = '\0'; - - return (buffer); - } - else - { - /* - * Skip this URI... - */ - - while (*valptr && !_cups_isspace(*valptr)) - valptr++; - } - - /* - * Skip whitespace... - */ - - while (_cups_isspace(*valptr)) - valptr ++; - } - - return (NULL); - } -} - - -/* - * 'ppdLocalizeMarkerName()' - Get the localized version of a marker-names - * attribute value. - * - * This function uses the current locale to find the corresponding name - * text from the attribute value. If no localized text for the requested - * name can be found, @code NULL@ is returned. - * - * @since CUPS 1.4/OS X 10.6@ - */ - -const char * /* O - Value or @code NULL@ if not found */ -ppdLocalizeMarkerName( - ppd_file_t *ppd, /* I - PPD file */ - const char *name) /* I - Marker name to look up */ -{ - ppd_attr_t *locattr; /* Localized attribute */ - char ll_CC[6]; /* Language + country locale */ - - - /* - * Range check input... - */ - - if (!ppd || !name) - return (NULL); - - /* - * Get the default language... - */ - - ppd_ll_CC(ll_CC, sizeof(ll_CC)); - - /* - * Find the localized attribute... - */ - - if ((locattr = _ppdLocalizedAttr(ppd, "cupsMarkerName", name, - ll_CC)) == NULL) - locattr = ppdFindAttr(ppd, "cupsMarkerName", name); - - return (locattr ? locattr->text : NULL); -} - - -/* - * '_ppdFreeLanguages()' - Free an array of languages from _ppdGetLanguages. - */ - -void -_ppdFreeLanguages( - cups_array_t *languages) /* I - Languages array */ -{ - char *language; /* Current language */ - - - for (language = (char *)cupsArrayFirst(languages); - language; - language = (char *)cupsArrayNext(languages)) - free(language); - - cupsArrayDelete(languages); -} - - -/* - * '_ppdGetLanguages()' - Get an array of languages from a PPD file. - */ - -cups_array_t * /* O - Languages array */ -_ppdGetLanguages(ppd_file_t *ppd) /* I - PPD file */ -{ - cups_array_t *languages; /* Languages array */ - ppd_attr_t *attr; /* cupsLanguages attribute */ - char *value, /* Copy of attribute value */ - *start, /* Start of current language */ - *ptr; /* Pointer into languages */ - - - /* - * See if we have a cupsLanguages attribute... - */ - - if ((attr = ppdFindAttr(ppd, "cupsLanguages", NULL)) == NULL || !attr->value) - return (NULL); - - /* - * Yes, load the list... - */ - - if ((languages = cupsArrayNew((cups_array_func_t)strcmp, NULL)) == NULL) - return (NULL); - - if ((value = strdup(attr->value)) == NULL) - { - cupsArrayDelete(languages); - return (NULL); - } - - for (ptr = value; *ptr;) - { - /* - * Skip leading whitespace... - */ - - while (_cups_isspace(*ptr)) - ptr ++; - - if (!*ptr) - break; - - /* - * Find the end of this language name... - */ - - for (start = ptr; *ptr && !_cups_isspace(*ptr); ptr ++); - - if (*ptr) - *ptr++ = '\0'; - - if (!strcmp(start, "en")) - continue; - - cupsArrayAdd(languages, strdup(start)); - } - - /* - * Free the temporary string and return either an array with one or more - * values or a NULL pointer... - */ - - free(value); - - if (cupsArrayCount(languages) == 0) - { - cupsArrayDelete(languages); - return (NULL); - } - else - return (languages); -} - - -/* - * '_ppdHashName()' - Generate a hash value for a device or profile name. - * - * This function is primarily used on OS X, but is generally accessible - * since cupstestppd needs to check for profile name collisions in PPD files... - */ - -unsigned /* O - Hash value */ -_ppdHashName(const char *name) /* I - Name to hash */ -{ - int mult; /* Multiplier */ - unsigned hash = 0; /* Hash value */ - - - for (mult = 1; *name && mult <= 128; mult ++, name ++) - hash += (*name & 255) * mult; - - return (hash); -} - - -/* - * '_ppdLocalizedAttr()' - Find a localized attribute. - */ - -ppd_attr_t * /* O - Localized attribute or NULL */ -_ppdLocalizedAttr(ppd_file_t *ppd, /* I - PPD file */ - const char *keyword, /* I - Main keyword */ - const char *spec, /* I - Option keyword */ - const char *ll_CC) /* I - Language + country locale */ -{ - char lkeyword[PPD_MAX_NAME]; /* Localization keyword */ - ppd_attr_t *attr; /* Current attribute */ - - - DEBUG_printf(("4_ppdLocalizedAttr(ppd=%p, keyword=\"%s\", spec=\"%s\", " - "ll_CC=\"%s\")", ppd, keyword, spec, ll_CC)); - - /* - * Look for Keyword.ll_CC, then Keyword.ll... - */ - - snprintf(lkeyword, sizeof(lkeyword), "%s.%s", ll_CC, keyword); - if ((attr = ppdFindAttr(ppd, lkeyword, spec)) == NULL) - { - snprintf(lkeyword, sizeof(lkeyword), "%2.2s.%s", ll_CC, keyword); - attr = ppdFindAttr(ppd, lkeyword, spec); - - if (!attr) - { - if (!strncmp(ll_CC, "ja", 2)) - { - /* - * Due to a bug in the CUPS DDK 1.1.0 ppdmerge program, Japanese - * PPD files were incorrectly assigned "jp" as the locale name - * instead of "ja". Support both the old (incorrect) and new - * locale names for Japanese... - */ - - snprintf(lkeyword, sizeof(lkeyword), "jp.%s", keyword); - attr = ppdFindAttr(ppd, lkeyword, spec); - } - else if (!strncmp(ll_CC, "no", 2)) - { - /* - * Norway has two languages, "Bokmal" (the primary one) - * and "Nynorsk" (new Norwegian); we map "no" to "nb" here as - * recommended by the locale folks... - */ - - snprintf(lkeyword, sizeof(lkeyword), "nb.%s", keyword); - attr = ppdFindAttr(ppd, lkeyword, spec); - } - } - } - -#ifdef DEBUG - if (attr) - DEBUG_printf(("5_ppdLocalizedAttr: *%s %s/%s: \"%s\"\n", attr->name, - attr->spec, attr->text, attr->value ? attr->value : "")); - else - DEBUG_puts("5_ppdLocalizedAttr: NOT FOUND"); -#endif /* DEBUG */ - - return (attr); -} - - -/* - * 'ppd_ll_CC()' - Get the current locale names. - */ - -static cups_lang_t * /* O - Current language */ -ppd_ll_CC(char *ll_CC, /* O - Country-specific locale name */ - int ll_CC_size) /* I - Size of country-specific name */ -{ - cups_lang_t *lang; /* Current language */ - - - /* - * Get the current locale... - */ - - if ((lang = cupsLangDefault()) == NULL) - { - strlcpy(ll_CC, "en_US", ll_CC_size); - return (NULL); - } - - /* - * Copy the locale name... - */ - - strlcpy(ll_CC, lang->language, ll_CC_size); - - if (strlen(ll_CC) == 2) - { - /* - * Map "ll" to primary/origin country locales to have the best - * chance of finding a match... - */ - - if (!strcmp(ll_CC, "cs")) - strlcpy(ll_CC, "cs_CZ", ll_CC_size); - else if (!strcmp(ll_CC, "en")) - strlcpy(ll_CC, "en_US", ll_CC_size); - else if (!strcmp(ll_CC, "ja")) - strlcpy(ll_CC, "ja_JP", ll_CC_size); - else if (!strcmp(ll_CC, "sv")) - strlcpy(ll_CC, "sv_SE", ll_CC_size); - else if (!strcmp(ll_CC, "zh")) /* Simplified Chinese */ - strlcpy(ll_CC, "zh_CN", ll_CC_size); - } - - DEBUG_printf(("8ppd_ll_CC: lang->language=\"%s\", ll_CC=\"%s\"...", - lang->language, ll_CC)); - return (lang); -} - - -/* - * End of "$Id: localize.c 7679 2008-06-19 23:37:45Z mike $". - */ diff --git a/cups/mark.c b/cups/mark.c deleted file mode 100644 index dc2257f..0000000 --- a/cups/mark.c +++ /dev/null @@ -1,1101 +0,0 @@ -/* - * "$Id: mark.c 9042 2010-03-24 00:45:34Z mike $" - * - * Option marking routines for CUPS. - * - * Copyright 2007-2012 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * PostScript is a trademark of Adobe Systems, Inc. - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * cupsMarkOptions() - Mark command-line options in a PPD file. - * ppdFindChoice() - Return a pointer to an option choice. - * ppdFindMarkedChoice() - Return the marked choice for the specified option. - * ppdFindOption() - Return a pointer to the specified option. - * ppdIsMarked() - Check to see if an option is marked. - * ppdMarkDefaults() - Mark all default options in the PPD file. - * ppdMarkOption() - Mark an option in a PPD file and return the number - * of conflicts. - * ppdFirstOption() - Return the first option in the PPD file. - * ppdNextOption() - Return the next option in the PPD file. - * _ppdParseOptions() - Parse options from a PPD file. - * ppd_debug_marked() - Output the marked array to stdout... - * ppd_defaults() - Set the defaults for this group and all sub-groups. - * ppd_mark_choices() - Mark one or more option choices from a string. - * ppd_mark_option() - Quickly mark an option without checking for - * conflicts. - */ - -/* - * Include necessary headers... - */ - -#include "cups-private.h" - - -/* - * Local functions... - */ - -#ifdef DEBUG -static void ppd_debug_marked(ppd_file_t *ppd, const char *title); -#else -# define ppd_debug_marked(ppd,title) -#endif /* DEBUG */ -static void ppd_defaults(ppd_file_t *ppd, ppd_group_t *g); -static void ppd_mark_choices(ppd_file_t *ppd, const char *s); -static void ppd_mark_option(ppd_file_t *ppd, const char *option, - const char *choice); - - -/* - * 'cupsMarkOptions()' - Mark command-line options in a PPD file. - * - * This function maps the IPP "finishings", "media", "mirror", - * "multiple-document-handling", "output-bin", "print-color-mode", - * "print-quality", "printer-resolution", and "sides" attributes to their - * corresponding PPD options and choices. - */ - -int /* O - 1 if conflicts exist, 0 otherwise */ -cupsMarkOptions( - ppd_file_t *ppd, /* I - PPD file */ - int num_options, /* I - Number of options */ - cups_option_t *options) /* I - Options */ -{ - int i, j; /* Looping vars */ - char *ptr, /* Pointer into string */ - s[255]; /* Temporary string */ - const char *val, /* Pointer into value */ - *media, /* media option */ - *output_bin, /* output-bin option */ - *page_size, /* PageSize option */ - *ppd_keyword, /* PPD keyword */ - *print_color_mode, /* print-color-mode option */ - *print_quality, /* print-quality option */ - *sides; /* sides option */ - cups_option_t *optptr; /* Current option */ - ppd_attr_t *attr; /* PPD attribute */ - _ppd_cache_t *cache; /* PPD cache and mapping data */ - - - /* - * Check arguments... - */ - - if (!ppd || num_options <= 0 || !options) - return (0); - - ppd_debug_marked(ppd, "Before..."); - - /* - * Do special handling for finishings, media, output-bin, output-mode, - * print-color-mode, print-quality, and PageSize... - */ - - media = cupsGetOption("media", num_options, options); - output_bin = cupsGetOption("output-bin", num_options, options); - page_size = cupsGetOption("PageSize", num_options, options); - print_quality = cupsGetOption("print-quality", num_options, options); - sides = cupsGetOption("sides", num_options, options); - - if ((print_color_mode = cupsGetOption("print-color-mode", num_options, - options)) == NULL) - print_color_mode = cupsGetOption("output-mode", num_options, options); - - if ((media || output_bin || print_color_mode || print_quality || sides) && - !ppd->cache) - { - /* - * Load PPD cache and mapping data as needed... - */ - - ppd->cache = _ppdCacheCreateWithPPD(ppd); - } - - cache = ppd->cache; - - if (media) - { - /* - * Loop through the option string, separating it at commas and marking each - * individual option as long as the corresponding PPD option (PageSize, - * InputSlot, etc.) is not also set. - * - * For PageSize, we also check for an empty option value since some versions - * of MacOS X use it to specify auto-selection of the media based solely on - * the size. - */ - - for (val = media; *val;) - { - /* - * Extract the sub-option from the string... - */ - - for (ptr = s; *val && *val != ',' && (ptr - s) < (sizeof(s) - 1);) - *ptr++ = *val++; - *ptr++ = '\0'; - - if (*val == ',') - val ++; - - /* - * Mark it... - */ - - if (!page_size || !page_size[0]) - { - if (!_cups_strncasecmp(s, "Custom.", 7) || ppdPageSize(ppd, s)) - ppd_mark_option(ppd, "PageSize", s); - else if ((ppd_keyword = _ppdCacheGetPageSize(cache, NULL, s, NULL)) != NULL) - ppd_mark_option(ppd, "PageSize", ppd_keyword); - } - - if (cache && cache->source_option && - !cupsGetOption(cache->source_option, num_options, options) && - (ppd_keyword = _ppdCacheGetInputSlot(cache, NULL, s)) != NULL) - ppd_mark_option(ppd, cache->source_option, ppd_keyword); - - if (!cupsGetOption("MediaType", num_options, options) && - (ppd_keyword = _ppdCacheGetMediaType(cache, NULL, s)) != NULL) - ppd_mark_option(ppd, "MediaType", ppd_keyword); - } - } - - if (cache) - { - if (!cupsGetOption("com.apple.print.DocumentTicket.PMSpoolFormat", - num_options, options) && - !cupsGetOption("APPrinterPreset", num_options, options) && - (print_color_mode || print_quality)) - { - /* - * Map output-mode and print-quality to a preset... - */ - - _pwg_print_color_mode_t pwg_pcm;/* print-color-mode index */ - _pwg_print_quality_t pwg_pq; /* print-quality index */ - cups_option_t *preset;/* Current preset option */ - - if (print_color_mode && !strcmp(print_color_mode, "monochrome")) - pwg_pcm = _PWG_PRINT_COLOR_MODE_MONOCHROME; - else - pwg_pcm = _PWG_PRINT_COLOR_MODE_COLOR; - - if (print_quality) - { - pwg_pq = atoi(print_quality) - IPP_QUALITY_DRAFT; - if (pwg_pq < _PWG_PRINT_QUALITY_DRAFT) - pwg_pq = _PWG_PRINT_QUALITY_DRAFT; - else if (pwg_pq > _PWG_PRINT_QUALITY_HIGH) - pwg_pq = _PWG_PRINT_QUALITY_HIGH; - } - else - pwg_pq = _PWG_PRINT_QUALITY_NORMAL; - - if (cache->num_presets[pwg_pcm][pwg_pq] == 0) - { - /* - * Try to find a preset that works so that we maximize the chances of us - * getting a good print using IPP attributes. - */ - - if (cache->num_presets[pwg_pcm][_PWG_PRINT_QUALITY_NORMAL] > 0) - pwg_pq = _PWG_PRINT_QUALITY_NORMAL; - else if (cache->num_presets[_PWG_PRINT_COLOR_MODE_COLOR][pwg_pq] > 0) - pwg_pcm = _PWG_PRINT_COLOR_MODE_COLOR; - else - { - pwg_pq = _PWG_PRINT_QUALITY_NORMAL; - pwg_pcm = _PWG_PRINT_COLOR_MODE_COLOR; - } - } - - if (cache->num_presets[pwg_pcm][pwg_pq] > 0) - { - /* - * Copy the preset options as long as the corresponding names are not - * already defined in the IPP request... - */ - - for (i = cache->num_presets[pwg_pcm][pwg_pq], - preset = cache->presets[pwg_pcm][pwg_pq]; - i > 0; - i --, preset ++) - { - if (!cupsGetOption(preset->name, num_options, options)) - ppd_mark_option(ppd, preset->name, preset->value); - } - } - } - - if (output_bin && !cupsGetOption("OutputBin", num_options, options) && - (ppd_keyword = _ppdCacheGetOutputBin(cache, output_bin)) != NULL) - { - /* - * Map output-bin to OutputBin... - */ - - ppd_mark_option(ppd, "OutputBin", ppd_keyword); - } - - if (sides && cache->sides_option && - !cupsGetOption(cache->sides_option, num_options, options)) - { - /* - * Map sides to duplex option... - */ - - if (!strcmp(sides, "one-sided") && cache->sides_1sided) - ppd_mark_option(ppd, cache->sides_option, cache->sides_1sided); - else if (!strcmp(sides, "two-sided-long-edge") && - cache->sides_2sided_long) - ppd_mark_option(ppd, cache->sides_option, cache->sides_2sided_long); - else if (!strcmp(sides, "two-sided-short-edge") && - cache->sides_2sided_short) - ppd_mark_option(ppd, cache->sides_option, cache->sides_2sided_short); - } - } - - /* - * Mark other options... - */ - - for (i = num_options, optptr = options; i > 0; i --, optptr ++) - if (!_cups_strcasecmp(optptr->name, "media") || - !_cups_strcasecmp(optptr->name, "output-bin") || - !_cups_strcasecmp(optptr->name, "output-mode") || - !_cups_strcasecmp(optptr->name, "print-quality") || - !_cups_strcasecmp(optptr->name, "sides")) - continue; - else if (!_cups_strcasecmp(optptr->name, "resolution") || - !_cups_strcasecmp(optptr->name, "printer-resolution")) - { - ppd_mark_option(ppd, "Resolution", optptr->value); - ppd_mark_option(ppd, "SetResolution", optptr->value); - /* Calcomp, Linotype, QMS, Summagraphics, Tektronix, Varityper */ - ppd_mark_option(ppd, "JCLResolution", optptr->value); - /* HP */ - ppd_mark_option(ppd, "CNRes_PGP", optptr->value); - /* Canon */ - } - else if (!_cups_strcasecmp(optptr->name, "multiple-document-handling")) - { - if (!cupsGetOption("Collate", num_options, options) && - ppdFindOption(ppd, "Collate")) - { - if (_cups_strcasecmp(optptr->value, "separate-documents-uncollated-copies")) - ppd_mark_option(ppd, "Collate", "True"); - else - ppd_mark_option(ppd, "Collate", "False"); - } - } - else if (!_cups_strcasecmp(optptr->name, "finishings")) - { - /* - * Lookup cupsIPPFinishings attributes for each value... - */ - - for (ptr = optptr->value; *ptr;) - { - /* - * Get the next finishings number... - */ - - if (!isdigit(*ptr & 255)) - break; - - if ((j = strtol(ptr, &ptr, 10)) < 3) - break; - - /* - * Skip separator as needed... - */ - - if (*ptr == ',') - ptr ++; - - /* - * Look it up in the PPD file... - */ - - sprintf(s, "%d", j); - - if ((attr = ppdFindAttr(ppd, "cupsIPPFinishings", s)) == NULL) - continue; - - /* - * Apply "*Option Choice" settings from the attribute value... - */ - - ppd_mark_choices(ppd, attr->value); - } - } - else if (!_cups_strcasecmp(optptr->name, "APPrinterPreset")) - { - /* - * Lookup APPrinterPreset value... - */ - - if ((attr = ppdFindAttr(ppd, "APPrinterPreset", optptr->value)) != NULL) - { - /* - * Apply "*Option Choice" settings from the attribute value... - */ - - ppd_mark_choices(ppd, attr->value); - } - } - else if (!_cups_strcasecmp(optptr->name, "mirror")) - ppd_mark_option(ppd, "MirrorPrint", optptr->value); - else - ppd_mark_option(ppd, optptr->name, optptr->value); - - ppd_debug_marked(ppd, "After..."); - - return (ppdConflicts(ppd) > 0); -} - - -/* - * 'ppdFindChoice()' - Return a pointer to an option choice. - */ - -ppd_choice_t * /* O - Choice pointer or @code NULL@ */ -ppdFindChoice(ppd_option_t *o, /* I - Pointer to option */ - const char *choice) /* I - Name of choice */ -{ - int i; /* Looping var */ - ppd_choice_t *c; /* Current choice */ - - - if (!o || !choice) - return (NULL); - - if (choice[0] == '{' || !_cups_strncasecmp(choice, "Custom.", 7)) - choice = "Custom"; - - for (i = o->num_choices, c = o->choices; i > 0; i --, c ++) - if (!_cups_strcasecmp(c->choice, choice)) - return (c); - - return (NULL); -} - - -/* - * 'ppdFindMarkedChoice()' - Return the marked choice for the specified option. - */ - -ppd_choice_t * /* O - Pointer to choice or @code NULL@ */ -ppdFindMarkedChoice(ppd_file_t *ppd, /* I - PPD file */ - const char *option) /* I - Keyword/option name */ -{ - ppd_choice_t key, /* Search key for choice */ - *marked; /* Marked choice */ - - - DEBUG_printf(("2ppdFindMarkedChoice(ppd=%p, option=\"%s\")", ppd, option)); - - if ((key.option = ppdFindOption(ppd, option)) == NULL) - { - DEBUG_puts("3ppdFindMarkedChoice: Option not found, returning NULL"); - return (NULL); - } - - marked = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key); - - DEBUG_printf(("3ppdFindMarkedChoice: Returning %p(%s)...", marked, - marked ? marked->choice : "NULL")); - - return (marked); -} - - -/* - * 'ppdFindOption()' - Return a pointer to the specified option. - */ - -ppd_option_t * /* O - Pointer to option or @code NULL@ */ -ppdFindOption(ppd_file_t *ppd, /* I - PPD file data */ - const char *option) /* I - Option/Keyword name */ -{ - /* - * Range check input... - */ - - if (!ppd || !option) - return (NULL); - - if (ppd->options) - { - /* - * Search in the array... - */ - - ppd_option_t key; /* Option search key */ - - - strlcpy(key.keyword, option, sizeof(key.keyword)); - - return ((ppd_option_t *)cupsArrayFind(ppd->options, &key)); - } - else - { - /* - * Search in each group... - */ - - int i, j; /* Looping vars */ - ppd_group_t *group; /* Current group */ - ppd_option_t *optptr; /* Current option */ - - - for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++) - for (j = group->num_options, optptr = group->options; - j > 0; - j --, optptr ++) - if (!_cups_strcasecmp(optptr->keyword, option)) - return (optptr); - - return (NULL); - } -} - - -/* - * 'ppdIsMarked()' - Check to see if an option is marked. - */ - -int /* O - Non-zero if option is marked */ -ppdIsMarked(ppd_file_t *ppd, /* I - PPD file data */ - const char *option, /* I - Option/Keyword name */ - const char *choice) /* I - Choice name */ -{ - ppd_choice_t key, /* Search key */ - *c; /* Choice pointer */ - - - if (!ppd) - return (0); - - if ((key.option = ppdFindOption(ppd, option)) == NULL) - return (0); - - if ((c = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) == NULL) - return (0); - - return (!strcmp(c->choice, choice)); -} - - -/* - * 'ppdMarkDefaults()' - Mark all default options in the PPD file. - */ - -void -ppdMarkDefaults(ppd_file_t *ppd) /* I - PPD file record */ -{ - int i; /* Looping variables */ - ppd_group_t *g; /* Current group */ - ppd_choice_t *c; /* Current choice */ - - - if (!ppd) - return; - - /* - * Clean out the marked array... - */ - - for (c = (ppd_choice_t *)cupsArrayFirst(ppd->marked); - c; - c = (ppd_choice_t *)cupsArrayNext(ppd->marked)) - { - cupsArrayRemove(ppd->marked, c); - c->marked = 0; - } - - /* - * Then repopulate it with the defaults... - */ - - for (i = ppd->num_groups, g = ppd->groups; i > 0; i --, g ++) - ppd_defaults(ppd, g); -} - - -/* - * 'ppdMarkOption()' - Mark an option in a PPD file and return the number of - * conflicts. - */ - -int /* O - Number of conflicts */ -ppdMarkOption(ppd_file_t *ppd, /* I - PPD file record */ - const char *option, /* I - Keyword */ - const char *choice) /* I - Option name */ -{ - DEBUG_printf(("ppdMarkOption(ppd=%p, option=\"%s\", choice=\"%s\")", - ppd, option, choice)); - - /* - * Range check input... - */ - - if (!ppd || !option || !choice) - return (0); - - /* - * Mark the option... - */ - - ppd_mark_option(ppd, option, choice); - - /* - * Return the number of conflicts... - */ - - return (ppdConflicts(ppd)); -} - - -/* - * 'ppdFirstOption()' - Return the first option in the PPD file. - * - * Options are returned from all groups in ascending alphanumeric order. - * - * @since CUPS 1.2/OS X 10.5@ - */ - -ppd_option_t * /* O - First option or @code NULL@ */ -ppdFirstOption(ppd_file_t *ppd) /* I - PPD file */ -{ - if (!ppd) - return (NULL); - else - return ((ppd_option_t *)cupsArrayFirst(ppd->options)); -} - - -/* - * 'ppdNextOption()' - Return the next option in the PPD file. - * - * Options are returned from all groups in ascending alphanumeric order. - * - * @since CUPS 1.2/OS X 10.5@ - */ - -ppd_option_t * /* O - Next option or @code NULL@ */ -ppdNextOption(ppd_file_t *ppd) /* I - PPD file */ -{ - if (!ppd) - return (NULL); - else - return ((ppd_option_t *)cupsArrayNext(ppd->options)); -} - - -/* - * '_ppdParseOptions()' - Parse options from a PPD file. - * - * This function looks for strings of the form: - * - * *option choice ... *optionN choiceN - * property value ... propertyN valueN - * - * It stops when it finds a string that doesn't match this format. - */ - -int /* O - Number of options */ -_ppdParseOptions( - const char *s, /* I - String to parse */ - int num_options, /* I - Number of options */ - cups_option_t **options, /* IO - Options */ - _ppd_parse_t which) /* I - What to parse */ -{ - char option[PPD_MAX_NAME * 2 + 1], /* Current option/property */ - choice[PPD_MAX_NAME], /* Current choice/value */ - *ptr; /* Pointer into option or choice */ - - - if (!s) - return (num_options); - - /* - * Read all of the "*Option Choice" and "property value" pairs from the - * string, add them to an options array as we go... - */ - - while (*s) - { - /* - * Skip leading whitespace... - */ - - while (_cups_isspace(*s)) - s ++; - - /* - * Get the option/property name... - */ - - ptr = option; - while (*s && !_cups_isspace(*s) && ptr < (option + sizeof(option) - 1)) - *ptr++ = *s++; - - if (ptr == s || !_cups_isspace(*s)) - break; - - *ptr = '\0'; - - /* - * Get the choice... - */ - - while (_cups_isspace(*s)) - s ++; - - if (!*s) - break; - - ptr = choice; - while (*s && !_cups_isspace(*s) && ptr < (choice + sizeof(choice) - 1)) - *ptr++ = *s++; - - if (*s && !_cups_isspace(*s)) - break; - - *ptr = '\0'; - - /* - * Add it to the options array... - */ - - if (option[0] == '*' && which != _PPD_PARSE_PROPERTIES) - num_options = cupsAddOption(option + 1, choice, num_options, options); - else if (option[0] != '*' && which != _PPD_PARSE_OPTIONS) - num_options = cupsAddOption(option, choice, num_options, options); - } - - return (num_options); -} - - -#ifdef DEBUG -/* - * 'ppd_debug_marked()' - Output the marked array to stdout... - */ - -static void -ppd_debug_marked(ppd_file_t *ppd, /* I - PPD file data */ - const char *title) /* I - Title for list */ -{ - ppd_choice_t *c; /* Current choice */ - - - DEBUG_printf(("2cupsMarkOptions: %s", title)); - - for (c = (ppd_choice_t *)cupsArrayFirst(ppd->marked); - c; - c = (ppd_choice_t *)cupsArrayNext(ppd->marked)) - DEBUG_printf(("2cupsMarkOptions: %s=%s", c->option->keyword, c->choice)); -} -#endif /* DEBUG */ - - -/* - * 'ppd_defaults()' - Set the defaults for this group and all sub-groups. - */ - -static void -ppd_defaults(ppd_file_t *ppd, /* I - PPD file */ - ppd_group_t *g) /* I - Group to default */ -{ - int i; /* Looping var */ - ppd_option_t *o; /* Current option */ - ppd_group_t *sg; /* Current sub-group */ - - - for (i = g->num_options, o = g->options; i > 0; i --, o ++) - if (_cups_strcasecmp(o->keyword, "PageRegion") != 0) - ppdMarkOption(ppd, o->keyword, o->defchoice); - - for (i = g->num_subgroups, sg = g->subgroups; i > 0; i --, sg ++) - ppd_defaults(ppd, sg); -} - - -/* - * 'ppd_mark_choices()' - Mark one or more option choices from a string. - */ - -static void -ppd_mark_choices(ppd_file_t *ppd, /* I - PPD file */ - const char *s) /* I - "*Option Choice ..." string */ -{ - int i, /* Looping var */ - num_options; /* Number of options */ - cups_option_t *options, /* Options */ - *option; /* Current option */ - - - if (!s) - return; - - options = NULL; - num_options = _ppdParseOptions(s, 0, &options, 0); - - for (i = num_options, option = options; i > 0; i --, option ++) - ppd_mark_option(ppd, option->name, option->value); - - cupsFreeOptions(num_options, options); -} - - -/* - * 'ppd_mark_option()' - Quick mark an option without checking for conflicts. - */ - -static void -ppd_mark_option(ppd_file_t *ppd, /* I - PPD file */ - const char *option, /* I - Option name */ - const char *choice) /* I - Choice name */ -{ - int i, j; /* Looping vars */ - ppd_option_t *o; /* Option pointer */ - ppd_choice_t *c, /* Choice pointer */ - *oldc, /* Old choice pointer */ - key; /* Search key for choice */ - struct lconv *loc; /* Locale data */ - - - DEBUG_printf(("7ppd_mark_option(ppd=%p, option=\"%s\", choice=\"%s\")", - ppd, option, choice)); - - /* - * AP_D_InputSlot is the "default input slot" on MacOS X, and setting - * it clears the regular InputSlot choices... - */ - - if (!_cups_strcasecmp(option, "AP_D_InputSlot")) - { - cupsArraySave(ppd->options); - - if ((o = ppdFindOption(ppd, "InputSlot")) != NULL) - { - key.option = o; - if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL) - { - oldc->marked = 0; - cupsArrayRemove(ppd->marked, oldc); - } - } - - cupsArrayRestore(ppd->options); - } - - /* - * Check for custom options... - */ - - cupsArraySave(ppd->options); - - o = ppdFindOption(ppd, option); - - cupsArrayRestore(ppd->options); - - if (!o) - return; - - loc = localeconv(); - - if (!_cups_strncasecmp(choice, "Custom.", 7)) - { - /* - * Handle a custom option... - */ - - if ((c = ppdFindChoice(o, "Custom")) == NULL) - return; - - if (!_cups_strcasecmp(option, "PageSize")) - { - /* - * Handle custom page sizes... - */ - - ppdPageSize(ppd, choice); - } - else - { - /* - * Handle other custom options... - */ - - ppd_coption_t *coption; /* Custom option */ - ppd_cparam_t *cparam; /* Custom parameter */ - char *units; /* Custom points units */ - - - if ((coption = ppdFindCustomOption(ppd, option)) != NULL) - { - if ((cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params)) == NULL) - return; - - switch (cparam->type) - { - case PPD_CUSTOM_CURVE : - case PPD_CUSTOM_INVCURVE : - case PPD_CUSTOM_REAL : - cparam->current.custom_real = (float)_cupsStrScand(choice + 7, - NULL, loc); - break; - - case PPD_CUSTOM_POINTS : - cparam->current.custom_points = (float)_cupsStrScand(choice + 7, - &units, - loc); - - if (units) - { - if (!_cups_strcasecmp(units, "cm")) - cparam->current.custom_points *= 72.0f / 2.54f; - else if (!_cups_strcasecmp(units, "mm")) - cparam->current.custom_points *= 72.0f / 25.4f; - else if (!_cups_strcasecmp(units, "m")) - cparam->current.custom_points *= 72.0f / 0.0254f; - else if (!_cups_strcasecmp(units, "in")) - cparam->current.custom_points *= 72.0f; - else if (!_cups_strcasecmp(units, "ft")) - cparam->current.custom_points *= 12.0f * 72.0f; - } - break; - - case PPD_CUSTOM_INT : - cparam->current.custom_int = atoi(choice + 7); - break; - - case PPD_CUSTOM_PASSCODE : - case PPD_CUSTOM_PASSWORD : - case PPD_CUSTOM_STRING : - if (cparam->current.custom_string) - _cupsStrFree(cparam->current.custom_string); - - cparam->current.custom_string = _cupsStrAlloc(choice + 7); - break; - } - } - } - - /* - * Make sure that we keep the option marked below... - */ - - choice = "Custom"; - } - else if (choice[0] == '{') - { - /* - * Handle multi-value custom options... - */ - - ppd_coption_t *coption; /* Custom option */ - ppd_cparam_t *cparam; /* Custom parameter */ - char *units; /* Custom points units */ - int num_vals; /* Number of values */ - cups_option_t *vals, /* Values */ - *val; /* Value */ - - - if ((c = ppdFindChoice(o, "Custom")) == NULL) - return; - - if ((coption = ppdFindCustomOption(ppd, option)) != NULL) - { - num_vals = cupsParseOptions(choice, 0, &vals); - - for (i = 0, val = vals; i < num_vals; i ++, val ++) - { - if ((cparam = ppdFindCustomParam(coption, val->name)) == NULL) - continue; - - switch (cparam->type) - { - case PPD_CUSTOM_CURVE : - case PPD_CUSTOM_INVCURVE : - case PPD_CUSTOM_REAL : - cparam->current.custom_real = (float)_cupsStrScand(val->value, - NULL, loc); - break; - - case PPD_CUSTOM_POINTS : - cparam->current.custom_points = (float)_cupsStrScand(val->value, - &units, - loc); - - if (units) - { - if (!_cups_strcasecmp(units, "cm")) - cparam->current.custom_points *= 72.0f / 2.54f; - else if (!_cups_strcasecmp(units, "mm")) - cparam->current.custom_points *= 72.0f / 25.4f; - else if (!_cups_strcasecmp(units, "m")) - cparam->current.custom_points *= 72.0f / 0.0254f; - else if (!_cups_strcasecmp(units, "in")) - cparam->current.custom_points *= 72.0f; - else if (!_cups_strcasecmp(units, "ft")) - cparam->current.custom_points *= 12.0f * 72.0f; - } - break; - - case PPD_CUSTOM_INT : - cparam->current.custom_int = atoi(val->value); - break; - - case PPD_CUSTOM_PASSCODE : - case PPD_CUSTOM_PASSWORD : - case PPD_CUSTOM_STRING : - if (cparam->current.custom_string) - _cupsStrFree(cparam->current.custom_string); - - cparam->current.custom_string = _cupsStrRetain(val->value); - break; - } - } - - cupsFreeOptions(num_vals, vals); - } - } - else - { - for (i = o->num_choices, c = o->choices; i > 0; i --, c ++) - if (!_cups_strcasecmp(c->choice, choice)) - break; - - if (!i) - return; - } - - /* - * Option found; mark it and then handle unmarking any other options. - */ - - if (o->ui != PPD_UI_PICKMANY) - { - /* - * Unmark all other choices... - */ - - if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, c)) != NULL) - { - oldc->marked = 0; - cupsArrayRemove(ppd->marked, oldc); - } - - if (!_cups_strcasecmp(option, "PageSize") || !_cups_strcasecmp(option, "PageRegion")) - { - /* - * Mark current page size... - */ - - for (j = 0; j < ppd->num_sizes; j ++) - ppd->sizes[j].marked = !_cups_strcasecmp(ppd->sizes[j].name, - choice); - - /* - * Unmark the current PageSize or PageRegion setting, as - * appropriate... - */ - - cupsArraySave(ppd->options); - - if (!_cups_strcasecmp(option, "PageSize")) - { - if ((o = ppdFindOption(ppd, "PageRegion")) != NULL) - { - key.option = o; - if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL) - { - oldc->marked = 0; - cupsArrayRemove(ppd->marked, oldc); - } - } - } - else - { - if ((o = ppdFindOption(ppd, "PageSize")) != NULL) - { - key.option = o; - if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL) - { - oldc->marked = 0; - cupsArrayRemove(ppd->marked, oldc); - } - } - } - - cupsArrayRestore(ppd->options); - } - else if (!_cups_strcasecmp(option, "InputSlot")) - { - /* - * Unmark ManualFeed option... - */ - - cupsArraySave(ppd->options); - - if ((o = ppdFindOption(ppd, "ManualFeed")) != NULL) - { - key.option = o; - if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL) - { - oldc->marked = 0; - cupsArrayRemove(ppd->marked, oldc); - } - } - - cupsArrayRestore(ppd->options); - } - else if (!_cups_strcasecmp(option, "ManualFeed") && - !_cups_strcasecmp(choice, "True")) - { - /* - * Unmark InputSlot option... - */ - - cupsArraySave(ppd->options); - - if ((o = ppdFindOption(ppd, "InputSlot")) != NULL) - { - key.option = o; - if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL) - { - oldc->marked = 0; - cupsArrayRemove(ppd->marked, oldc); - } - } - - cupsArrayRestore(ppd->options); - } - } - - c->marked = 1; - - cupsArrayAdd(ppd->marked, c); -} - - -/* - * End of "$Id: mark.c 9042 2010-03-24 00:45:34Z mike $". - */ diff --git a/cups/md5-private.h b/cups/md5-internal.h similarity index 90% rename from cups/md5-private.h rename to cups/md5-internal.h index 8b9bf12..2cbf78b 100644 --- a/cups/md5-private.h +++ b/cups/md5-internal.h @@ -44,8 +44,10 @@ 1999-05-03 lpd Original version. */ -#ifndef _CUPS_MD5_PRIVATE_H_ -# define _CUPS_MD5_PRIVATE_H_ +#ifndef _CUPS_MD5_INTERNAL_H_ +# define _CUPS_MD5_INTERNAL_H_ + +# include /* Define the state of the MD5 Algorithm. */ typedef struct _cups_md5_state_s { @@ -59,15 +61,15 @@ extern "C" { # endif /* __cplusplus */ /* Initialize the algorithm. */ -void _cupsMD5Init(_cups_md5_state_t *pms); +void _cupsMD5Init(_cups_md5_state_t *pms) _CUPS_INTERNAL; /* Append a string to the message. */ -void _cupsMD5Append(_cups_md5_state_t *pms, const unsigned char *data, int nbytes); +void _cupsMD5Append(_cups_md5_state_t *pms, const unsigned char *data, int nbytes) _CUPS_INTERNAL; /* Finish the message and return the digest. */ -void _cupsMD5Finish(_cups_md5_state_t *pms, unsigned char digest[16]); +void _cupsMD5Finish(_cups_md5_state_t *pms, unsigned char digest[16]) _CUPS_INTERNAL; # ifdef __cplusplus } /* end extern "C" */ # endif /* __cplusplus */ -#endif /* !_CUPS_MD5_PRIVATE_H_ */ +#endif /* !_CUPS_MD5_INTERNAL_H_ */ diff --git a/cups/md5.c b/cups/md5.c index c0f5dd7..c3b2768 100644 --- a/cups/md5.c +++ b/cups/md5.c @@ -1,7 +1,7 @@ /* * Private MD5 implementation for CUPS. * - * Copyright 2007-2014 by Apple Inc. + * Copyright 2007-2017 by Apple Inc. * Copyright 2005 by Easy Software Products * Copyright (C) 1999 Aladdin Enterprises. All rights reserved. * @@ -40,73 +40,74 @@ 1999-05-03 lpd Original version. */ -#include "md5-private.h" +#include "md5-internal.h" #include "string-private.h" -#define T1 0xd76aa478 -#define T2 0xe8c7b756 -#define T3 0x242070db -#define T4 0xc1bdceee -#define T5 0xf57c0faf -#define T6 0x4787c62a -#define T7 0xa8304613 -#define T8 0xfd469501 -#define T9 0x698098d8 -#define T10 0x8b44f7af -#define T11 0xffff5bb1 -#define T12 0x895cd7be -#define T13 0x6b901122 -#define T14 0xfd987193 -#define T15 0xa679438e -#define T16 0x49b40821 -#define T17 0xf61e2562 -#define T18 0xc040b340 -#define T19 0x265e5a51 -#define T20 0xe9b6c7aa -#define T21 0xd62f105d -#define T22 0x02441453 -#define T23 0xd8a1e681 -#define T24 0xe7d3fbc8 -#define T25 0x21e1cde6 -#define T26 0xc33707d6 -#define T27 0xf4d50d87 -#define T28 0x455a14ed -#define T29 0xa9e3e905 -#define T30 0xfcefa3f8 -#define T31 0x676f02d9 -#define T32 0x8d2a4c8a -#define T33 0xfffa3942 -#define T34 0x8771f681 -#define T35 0x6d9d6122 -#define T36 0xfde5380c -#define T37 0xa4beea44 -#define T38 0x4bdecfa9 -#define T39 0xf6bb4b60 -#define T40 0xbebfbc70 -#define T41 0x289b7ec6 -#define T42 0xeaa127fa -#define T43 0xd4ef3085 -#define T44 0x04881d05 -#define T45 0xd9d4d039 -#define T46 0xe6db99e5 -#define T47 0x1fa27cf8 -#define T48 0xc4ac5665 -#define T49 0xf4292244 -#define T50 0x432aff97 -#define T51 0xab9423a7 -#define T52 0xfc93a039 -#define T53 0x655b59c3 -#define T54 0x8f0ccc92 -#define T55 0xffeff47d -#define T56 0x85845dd1 -#define T57 0x6fa87e4f -#define T58 0xfe2ce6e0 -#define T59 0xa3014314 -#define T60 0x4e0811a1 -#define T61 0xf7537e82 -#define T62 0xbd3af235 -#define T63 0x2ad7d2bb -#define T64 0xeb86d391 +#if !defined(__APPLE__) && !defined(HAVE_GNUTLS) +# define T1 0xd76aa478 +# define T2 0xe8c7b756 +# define T3 0x242070db +# define T4 0xc1bdceee +# define T5 0xf57c0faf +# define T6 0x4787c62a +# define T7 0xa8304613 +# define T8 0xfd469501 +# define T9 0x698098d8 +# define T10 0x8b44f7af +# define T11 0xffff5bb1 +# define T12 0x895cd7be +# define T13 0x6b901122 +# define T14 0xfd987193 +# define T15 0xa679438e +# define T16 0x49b40821 +# define T17 0xf61e2562 +# define T18 0xc040b340 +# define T19 0x265e5a51 +# define T20 0xe9b6c7aa +# define T21 0xd62f105d +# define T22 0x02441453 +# define T23 0xd8a1e681 +# define T24 0xe7d3fbc8 +# define T25 0x21e1cde6 +# define T26 0xc33707d6 +# define T27 0xf4d50d87 +# define T28 0x455a14ed +# define T29 0xa9e3e905 +# define T30 0xfcefa3f8 +# define T31 0x676f02d9 +# define T32 0x8d2a4c8a +# define T33 0xfffa3942 +# define T34 0x8771f681 +# define T35 0x6d9d6122 +# define T36 0xfde5380c +# define T37 0xa4beea44 +# define T38 0x4bdecfa9 +# define T39 0xf6bb4b60 +# define T40 0xbebfbc70 +# define T41 0x289b7ec6 +# define T42 0xeaa127fa +# define T43 0xd4ef3085 +# define T44 0x04881d05 +# define T45 0xd9d4d039 +# define T46 0xe6db99e5 +# define T47 0x1fa27cf8 +# define T48 0xc4ac5665 +# define T49 0xf4292244 +# define T50 0x432aff97 +# define T51 0xab9423a7 +# define T52 0xfc93a039 +# define T53 0x655b59c3 +# define T54 0x8f0ccc92 +# define T55 0xffeff47d +# define T56 0x85845dd1 +# define T57 0x6fa87e4f +# define T58 0xfe2ce6e0 +# define T59 0xa3014314 +# define T60 0x4e0811a1 +# define T61 0xf7537e82 +# define T62 0xbd3af235 +# define T63 0x2ad7d2bb +# define T64 0xeb86d391 static void _cups_md5_process(_cups_md5_state_t *pms, const unsigned char *data /*[64]*/) @@ -116,10 +117,10 @@ _cups_md5_process(_cups_md5_state_t *pms, const unsigned char *data /*[64]*/) c = pms->abcd[2], d = pms->abcd[3]; unsigned int t; -#ifndef ARCH_IS_BIG_ENDIAN -# define ARCH_IS_BIG_ENDIAN 1 /* slower, default implementation */ -#endif -#if ARCH_IS_BIG_ENDIAN +# ifndef ARCH_IS_BIG_ENDIAN +# define ARCH_IS_BIG_ENDIAN 1 /* slower, default implementation */ +# endif +# if ARCH_IS_BIG_ENDIAN /* * On big-endian machines, we must arrange the bytes in the right @@ -133,7 +134,7 @@ _cups_md5_process(_cups_md5_state_t *pms, const unsigned char *data /*[64]*/) X[i] = (unsigned)xp[0] + ((unsigned)xp[1] << 8) + ((unsigned)xp[2] << 16) + ((unsigned)xp[3] << 24); -#else /* !ARCH_IS_BIG_ENDIAN */ +# else /* !ARCH_IS_BIG_ENDIAN */ /* * On little-endian machines, we can process properly aligned data @@ -150,15 +151,15 @@ _cups_md5_process(_cups_md5_state_t *pms, const unsigned char *data /*[64]*/) memcpy(xbuf, data, 64); X = xbuf; } -#endif +# endif -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) +# define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) /* Round 1. */ /* Let [abcd k s i] denote the operation a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ -#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) -#define SET(a, b, c, d, k, s, Ti)\ +# define F(x, y, z) (((x) & (y)) | (~(x) & (z))) +# define SET(a, b, c, d, k, s, Ti)\ t = a + F(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ @@ -178,13 +179,13 @@ _cups_md5_process(_cups_md5_state_t *pms, const unsigned char *data /*[64]*/) SET(d, a, b, c, 13, 12, T14); SET(c, d, a, b, 14, 17, T15); SET(b, c, d, a, 15, 22, T16); -#undef SET +# undef SET /* Round 2. */ /* Let [abcd k s i] denote the operation a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ -#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ +# define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) +# define SET(a, b, c, d, k, s, Ti)\ t = a + G(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ @@ -204,13 +205,13 @@ _cups_md5_process(_cups_md5_state_t *pms, const unsigned char *data /*[64]*/) SET(d, a, b, c, 2, 9, T30); SET(c, d, a, b, 7, 14, T31); SET(b, c, d, a, 12, 20, T32); -#undef SET +# undef SET /* Round 3. */ /* Let [abcd k s t] denote the operation a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define SET(a, b, c, d, k, s, Ti)\ +# define H(x, y, z) ((x) ^ (y) ^ (z)) +# define SET(a, b, c, d, k, s, Ti)\ t = a + H(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ @@ -230,13 +231,13 @@ _cups_md5_process(_cups_md5_state_t *pms, const unsigned char *data /*[64]*/) SET(d, a, b, c, 12, 11, T46); SET(c, d, a, b, 15, 16, T47); SET(b, c, d, a, 2, 23, T48); -#undef SET +# undef SET /* Round 4. */ /* Let [abcd k s t] denote the operation a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ -#define I(x, y, z) ((y) ^ ((x) | ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ +# define I(x, y, z) ((y) ^ ((x) | ~(z))) +# define SET(a, b, c, d, k, s, Ti)\ t = a + I(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ @@ -256,7 +257,7 @@ _cups_md5_process(_cups_md5_state_t *pms, const unsigned char *data /*[64]*/) SET(d, a, b, c, 11, 10, T62); SET(c, d, a, b, 2, 15, T63); SET(b, c, d, a, 9, 21, T64); -#undef SET +# undef SET /* Then perform the following additions. (That is increment each of the four registers by the value it had before this block @@ -337,3 +338,4 @@ _cupsMD5Finish(_cups_md5_state_t *pms, unsigned char digest[16]) for (i = 0; i < 16; ++i) digest[i] = (unsigned char)(pms->abcd[i >> 2] >> ((i & 3) << 3)); } +#endif /* !__APPLE__ && !HAVE_GNUTLS */ diff --git a/cups/md5passwd.c b/cups/md5passwd.c index a9817aa..9af5de2 100644 --- a/cups/md5passwd.c +++ b/cups/md5passwd.c @@ -1,28 +1,25 @@ /* - * MD5 password support for CUPS. + * MD5 password support for CUPS (deprecated). * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2017 by Apple Inc. * Copyright 1997-2005 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* * Include necessary headers... */ +#include #include "http-private.h" #include "string-private.h" /* * 'httpMD5()' - Compute the MD5 sum of the username:group:password. + * + * @deprecated@ */ char * /* O - MD5 sum */ @@ -31,7 +28,6 @@ httpMD5(const char *username, /* I - User name */ const char *passwd, /* I - Password string */ char md5[33]) /* O - MD5 string */ { - _cups_md5_state_t state; /* MD5 state info */ unsigned char sum[16]; /* Sum data */ char line[256]; /* Line to sum */ @@ -41,15 +37,13 @@ httpMD5(const char *username, /* I - User name */ */ snprintf(line, sizeof(line), "%s:%s:%s", username, realm, passwd); - _cupsMD5Init(&state); - _cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line)); - _cupsMD5Finish(&state, sum); + cupsHashData("md5", (unsigned char *)line, strlen(line), sum, sizeof(sum)); /* * Return the sum... */ - return (httpMD5String(sum, md5)); + return ((char *)cupsHashString(sum, sizeof(sum), md5, 33)); } @@ -57,6 +51,8 @@ httpMD5(const char *username, /* I - User name */ * 'httpMD5Final()' - Combine the MD5 sum of the username, group, and password * with the server-supplied nonce value, method, and * request-uri. + * + * @deprecated@ */ char * /* O - New sum */ @@ -65,7 +61,6 @@ httpMD5Final(const char *nonce, /* I - Server nonce value */ const char *resource, /* I - Resource path */ char md5[33]) /* IO - MD5 sum */ { - _cups_md5_state_t state; /* MD5 state info */ unsigned char sum[16]; /* Sum data */ char line[1024]; /* Line of data */ char a2[33]; /* Hash of method and resource */ @@ -76,10 +71,8 @@ httpMD5Final(const char *nonce, /* I - Server nonce value */ */ snprintf(line, sizeof(line), "%s:%s", method, resource); - _cupsMD5Init(&state); - _cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line)); - _cupsMD5Finish(&state, sum); - httpMD5String(sum, a2); + cupsHashData("md5", (unsigned char *)line, strlen(line), sum, sizeof(sum)); + cupsHashString(sum, sizeof(sum), a2, sizeof(a2)); /* * Then combine A1 (MD5 of username, realm, and password) with the nonce @@ -88,17 +81,16 @@ httpMD5Final(const char *nonce, /* I - Server nonce value */ */ snprintf(line, sizeof(line), "%s:%s:%s", md5, nonce, a2); + cupsHashData("md5", (unsigned char *)line, strlen(line), sum, sizeof(sum)); - _cupsMD5Init(&state); - _cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line)); - _cupsMD5Finish(&state, sum); - - return (httpMD5String(sum, md5)); + return ((char *)cupsHashString(sum, sizeof(sum), md5, 33)); } /* * 'httpMD5String()' - Convert an MD5 sum to a character string. + * + * @deprecated@ */ char * /* O - MD5 sum in hex */ @@ -106,23 +98,5 @@ httpMD5String(const unsigned char *sum, /* I - MD5 sum data */ char md5[33]) /* O - MD5 sum in hex */ { - int i; /* Looping var */ - char *md5ptr; /* Pointer into MD5 string */ - static const char hex[] = "0123456789abcdef"; - /* Hex digits */ - - - /* - * Convert the MD5 sum to hexadecimal... - */ - - for (i = 16, md5ptr = md5; i > 0; i --, sum ++) - { - *md5ptr++ = hex[*sum >> 4]; - *md5ptr++ = hex[*sum & 15]; - } - - *md5ptr = '\0'; - - return (md5); + return ((char *)cupsHashString(sum, 16, md5, 33)); } diff --git a/cups/notify.c b/cups/notify.c index b58a136..590962c 100644 --- a/cups/notify.c +++ b/cups/notify.c @@ -4,13 +4,7 @@ * Copyright 2007-2013 by Apple Inc. * Copyright 2005-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -18,6 +12,7 @@ */ #include "cups-private.h" +#include "debug-internal.h" /* diff --git a/cups/options.c b/cups/options.c index 9aa20f8..11814c9 100644 --- a/cups/options.c +++ b/cups/options.c @@ -4,13 +4,7 @@ * Copyright 2007-2017 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -18,6 +12,7 @@ */ #include "cups-private.h" +#include "debug-internal.h" /* @@ -80,6 +75,11 @@ cupsAddOption(const char *name, /* I - Name of option */ return (num_options); } + if (!_cups_strcasecmp(name, "cupsPrintQuality")) + num_options = cupsRemoveOption("print-quality", num_options, options); + else if (!_cups_strcasecmp(name, "print-quality")) + num_options = cupsRemoveOption("cupsPrintQuality", num_options, options); + /* * Look for an existing option with the same name... */ diff --git a/cups/page.c b/cups/page.c deleted file mode 100644 index b5c5e34..0000000 --- a/cups/page.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * "$Id: page.c 7791 2008-07-24 00:55:30Z mike $" - * - * Page size functions for CUPS. - * - * Copyright 2007-2012 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * PostScript is a trademark of Adobe Systems, Inc. - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * ppdPageSize() - Get the page size record for the given size. - * ppdPageSizeLimits() - Return the custom page size limits. - * ppdPageWidth() - Get the page width for the given size. - * ppdPageLength() - Get the page length for the given size. - */ - -/* - * Include necessary headers... - */ - -#include "string-private.h" -#include "debug-private.h" -#include "ppd.h" - - -/* - * 'ppdPageSize()' - Get the page size record for the named size. - */ - -ppd_size_t * /* O - Size record for page or NULL */ -ppdPageSize(ppd_file_t *ppd, /* I - PPD file record */ - const char *name) /* I - Size name */ -{ - int i; /* Looping var */ - ppd_size_t *size; /* Current page size */ - double w, l; /* Width and length of page */ - char *nameptr; /* Pointer into name */ - struct lconv *loc; /* Locale data */ - ppd_coption_t *coption; /* Custom option for page size */ - ppd_cparam_t *cparam; /* Custom option parameter */ - - - DEBUG_printf(("2ppdPageSize(ppd=%p, name=\"%s\")", ppd, name)); - - if (!ppd) - { - DEBUG_puts("3ppdPageSize: Bad PPD pointer, returning NULL..."); - return (NULL); - } - - if (name) - { - if (!strncmp(name, "Custom.", 7) && ppd->variable_sizes) - { - /* - * Find the custom page size... - */ - - for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++) - if (!strcmp("Custom", size->name)) - break; - - if (!i) - { - DEBUG_puts("3ppdPageSize: No custom sizes, returning NULL..."); - return (NULL); - } - - /* - * Variable size; size name can be one of the following: - * - * Custom.WIDTHxLENGTHin - Size in inches - * Custom.WIDTHxLENGTHft - Size in feet - * Custom.WIDTHxLENGTHcm - Size in centimeters - * Custom.WIDTHxLENGTHmm - Size in millimeters - * Custom.WIDTHxLENGTHm - Size in meters - * Custom.WIDTHxLENGTH[pt] - Size in points - */ - - loc = localeconv(); - w = _cupsStrScand(name + 7, &nameptr, loc); - if (!nameptr || *nameptr != 'x') - return (NULL); - - l = _cupsStrScand(nameptr + 1, &nameptr, loc); - if (!nameptr) - return (NULL); - - if (!_cups_strcasecmp(nameptr, "in")) - { - w *= 72.0; - l *= 72.0; - } - else if (!_cups_strcasecmp(nameptr, "ft")) - { - w *= 12.0 * 72.0; - l *= 12.0 * 72.0; - } - else if (!_cups_strcasecmp(nameptr, "mm")) - { - w *= 72.0 / 25.4; - l *= 72.0 / 25.4; - } - else if (!_cups_strcasecmp(nameptr, "cm")) - { - w *= 72.0 / 2.54; - l *= 72.0 / 2.54; - } - else if (!_cups_strcasecmp(nameptr, "m")) - { - w *= 72.0 / 0.0254; - l *= 72.0 / 0.0254; - } - - size->width = (float)w; - size->length = (float)l; - size->left = ppd->custom_margins[0]; - size->bottom = ppd->custom_margins[1]; - size->right = (float)(w - ppd->custom_margins[2]); - size->top = (float)(l - ppd->custom_margins[3]); - - /* - * Update the custom option records for the page size, too... - */ - - if ((coption = ppdFindCustomOption(ppd, "PageSize")) != NULL) - { - if ((cparam = ppdFindCustomParam(coption, "Width")) != NULL) - cparam->current.custom_points = (float)w; - - if ((cparam = ppdFindCustomParam(coption, "Height")) != NULL) - cparam->current.custom_points = (float)l; - } - - /* - * Return the page size... - */ - - DEBUG_printf(("3ppdPageSize: Returning %p (\"%s\", %gx%g)", size, - size->name, size->width, size->length)); - - return (size); - } - else - { - /* - * Lookup by name... - */ - - for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++) - if (!_cups_strcasecmp(name, size->name)) - { - DEBUG_printf(("3ppdPageSize: Returning %p (\"%s\", %gx%g)", size, - size->name, size->width, size->length)); - - return (size); - } - } - } - else - { - /* - * Find default... - */ - - for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++) - if (size->marked) - { - DEBUG_printf(("3ppdPageSize: Returning %p (\"%s\", %gx%g)", size, - size->name, size->width, size->length)); - - return (size); - } - } - - DEBUG_puts("3ppdPageSize: Size not found, returning NULL"); - - return (NULL); -} - - -/* - * 'ppdPageSizeLimits()' - Return the custom page size limits. - * - * This function returns the minimum and maximum custom page sizes and printable - * areas based on the currently-marked (selected) options. - * - * If the specified PPD file does not support custom page sizes, both - * "minimum" and "maximum" are filled with zeroes. - * - * @since CUPS 1.4/OS X 10.6@ - */ - -int /* O - 1 if custom sizes are supported, 0 otherwise */ -ppdPageSizeLimits(ppd_file_t *ppd, /* I - PPD file record */ - ppd_size_t *minimum, /* O - Minimum custom size */ - ppd_size_t *maximum) /* O - Maximum custom size */ -{ - ppd_choice_t *qualifier2, /* Second media qualifier */ - *qualifier3; /* Third media qualifier */ - ppd_attr_t *attr; /* Attribute */ - float width, /* Min/max width */ - length; /* Min/max length */ - char spec[PPD_MAX_NAME]; /* Selector for min/max */ - - - /* - * Range check input... - */ - - if (!ppd || !ppd->variable_sizes || !minimum || !maximum) - { - if (minimum) - memset(minimum, 0, sizeof(ppd_size_t)); - - if (maximum) - memset(maximum, 0, sizeof(ppd_size_t)); - - return (0); - } - - /* - * See if we have the cupsMediaQualifier2 and cupsMediaQualifier3 attributes... - */ - - cupsArraySave(ppd->sorted_attrs); - - if ((attr = ppdFindAttr(ppd, "cupsMediaQualifier2", NULL)) != NULL && - attr->value) - qualifier2 = ppdFindMarkedChoice(ppd, attr->value); - else - qualifier2 = NULL; - - if ((attr = ppdFindAttr(ppd, "cupsMediaQualifier3", NULL)) != NULL && - attr->value) - qualifier3 = ppdFindMarkedChoice(ppd, attr->value); - else - qualifier3 = NULL; - - /* - * Figure out the current minimum width and length... - */ - - width = ppd->custom_min[0]; - length = ppd->custom_min[1]; - - if (qualifier2) - { - /* - * Try getting cupsMinSize... - */ - - if (qualifier3) - { - snprintf(spec, sizeof(spec), ".%s.%s", qualifier2->choice, - qualifier3->choice); - attr = ppdFindAttr(ppd, "cupsMinSize", spec); - } - else - attr = NULL; - - if (!attr) - { - snprintf(spec, sizeof(spec), ".%s.", qualifier2->choice); - attr = ppdFindAttr(ppd, "cupsMinSize", spec); - } - - if (!attr && qualifier3) - { - snprintf(spec, sizeof(spec), "..%s", qualifier3->choice); - attr = ppdFindAttr(ppd, "cupsMinSize", spec); - } - - if ((attr && attr->value && - sscanf(attr->value, "%f%f", &width, &length) != 2) || !attr) - { - width = ppd->custom_min[0]; - length = ppd->custom_min[1]; - } - } - - minimum->width = width; - minimum->length = length; - minimum->left = ppd->custom_margins[0]; - minimum->bottom = ppd->custom_margins[1]; - minimum->right = width - ppd->custom_margins[2]; - minimum->top = length - ppd->custom_margins[3]; - - /* - * Figure out the current maximum width and length... - */ - - width = ppd->custom_max[0]; - length = ppd->custom_max[1]; - - if (qualifier2) - { - /* - * Try getting cupsMaxSize... - */ - - if (qualifier3) - { - snprintf(spec, sizeof(spec), ".%s.%s", qualifier2->choice, - qualifier3->choice); - attr = ppdFindAttr(ppd, "cupsMaxSize", spec); - } - else - attr = NULL; - - if (!attr) - { - snprintf(spec, sizeof(spec), ".%s.", qualifier2->choice); - attr = ppdFindAttr(ppd, "cupsMaxSize", spec); - } - - if (!attr && qualifier3) - { - snprintf(spec, sizeof(spec), "..%s", qualifier3->choice); - attr = ppdFindAttr(ppd, "cupsMaxSize", spec); - } - - if (!attr || - (attr->value && sscanf(attr->value, "%f%f", &width, &length) != 2)) - { - width = ppd->custom_max[0]; - length = ppd->custom_max[1]; - } - } - - maximum->width = width; - maximum->length = length; - maximum->left = ppd->custom_margins[0]; - maximum->bottom = ppd->custom_margins[1]; - maximum->right = width - ppd->custom_margins[2]; - maximum->top = length - ppd->custom_margins[3]; - - /* - * Return the min and max... - */ - - cupsArrayRestore(ppd->sorted_attrs); - - return (1); -} - - -/* - * 'ppdPageWidth()' - Get the page width for the given size. - */ - -float /* O - Width of page in points or 0.0 */ -ppdPageWidth(ppd_file_t *ppd, /* I - PPD file record */ - const char *name) /* I - Size name */ -{ - ppd_size_t *size; /* Page size */ - - - if ((size = ppdPageSize(ppd, name)) == NULL) - return (0.0); - else - return (size->width); -} - - -/* - * 'ppdPageLength()' - Get the page length for the given size. - */ - -float /* O - Length of page in points or 0.0 */ -ppdPageLength(ppd_file_t *ppd, /* I - PPD file */ - const char *name) /* I - Size name */ -{ - ppd_size_t *size; /* Page size */ - - - if ((size = ppdPageSize(ppd, name)) == NULL) - return (0.0); - else - return (size->length); -} - - -/* - * End of "$Id: page.c 7791 2008-07-24 00:55:30Z mike $". - */ diff --git a/cups/ppd-attr.c b/cups/ppd-attr.c index da02637..982f901 100644 --- a/cups/ppd-attr.c +++ b/cups/ppd-attr.c @@ -4,11 +4,8 @@ * Copyright 2007-2015 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -17,6 +14,7 @@ #include "cups-private.h" #include "ppd-private.h" +#include "debug-internal.h" /* diff --git a/cups/ppd-cache.c b/cups/ppd-cache.c index 7e40214..6a35ef4 100644 --- a/cups/ppd-cache.c +++ b/cups/ppd-cache.c @@ -1,15 +1,10 @@ /* * PPD cache implementation for CUPS. * - * Copyright 2010-2017 by Apple Inc. + * Copyright © 2010-2019 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -18,6 +13,7 @@ #include "cups-private.h" #include "ppd-private.h" +#include "debug-internal.h" #include @@ -32,9 +28,12 @@ * Local functions... */ +static int cups_get_url(http_t **http, const char *url, char *name, size_t namesize); static void pwg_add_finishing(cups_array_t *finishings, ipp_finishings_t template, const char *name, const char *value); -static int pwg_compare_finishings(_pwg_finishings_t *a, - _pwg_finishings_t *b); +static void pwg_add_message(cups_array_t *a, const char *msg, const char *str); +static int pwg_compare_finishings(_pwg_finishings_t *a, _pwg_finishings_t *b); +static int pwg_compare_sizes(cups_size_t *a, cups_size_t *b); +static cups_size_t *pwg_copy_size(cups_size_t *size); static void pwg_free_finishings(_pwg_finishings_t *f); static void pwg_ppdize_name(const char *ipp, char *name, size_t namesize); static void pwg_ppdize_resolution(ipp_attribute_t *attr, int element, int *xres, int *yres, char *name, size_t namesize); @@ -74,10 +73,13 @@ _cupsConvertOptions( *media_type, /* media-type value */ *collate_str, /* multiple-document-handling value */ *color_attr_name, /* Supported color attribute */ - *mandatory; /* Mandatory attributes */ + *mandatory, /* Mandatory attributes */ + *finishing_template; /* Finishing template */ int num_finishings = 0, /* Number of finishing values */ finishings[10]; /* Finishing enum values */ ppd_choice_t *choice; /* Marked choice */ + int finishings_copies = copies; + /* Number of copies for finishings */ /* @@ -139,6 +141,8 @@ _cupsConvertOptions( if (strcmp(mandatory, "copies") && strcmp(mandatory, "destination-uris") && strcmp(mandatory, "finishings") && + strcmp(mandatory, "finishings-col") && + strcmp(mandatory, "finishing-template") && strcmp(mandatory, "job-account-id") && strcmp(mandatory, "job-accounting-user-id") && strcmp(mandatory, "job-password") && @@ -288,11 +292,11 @@ _cupsConvertOptions( ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides", NULL, keyword); else if (pc->sides_option && (choice = ppdFindMarkedChoice(ppd, pc->sides_option)) != NULL) { - if (!_cups_strcasecmp(choice->choice, pc->sides_1sided)) + if (pc->sides_1sided && !_cups_strcasecmp(choice->choice, pc->sides_1sided)) ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides", NULL, "one-sided"); - else if (!_cups_strcasecmp(choice->choice, pc->sides_2sided_long)) + else if (pc->sides_2sided_long && !_cups_strcasecmp(choice->choice, pc->sides_2sided_long)) ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides", NULL, "two-sided-long-edge"); - if (!_cups_strcasecmp(choice->choice, pc->sides_2sided_short)) + else if (pc->sides_2sided_short && !_cups_strcasecmp(choice->choice, pc->sides_2sided_short)) ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides", NULL, "two-sided-short-edge"); } @@ -361,18 +365,41 @@ _cupsConvertOptions( * Map finishing options... */ - num_finishings = _ppdCacheGetFinishingValues(pc, num_options, options, (int)(sizeof(finishings) / sizeof(finishings[0])), finishings); - if (num_finishings > 0) - { - ippAddIntegers(request, IPP_TAG_JOB, IPP_TAG_ENUM, "finishings", num_finishings, finishings); + if ((finishing_template = cupsGetOption("cupsFinishingTemplate", num_options, options)) == NULL) + finishing_template = cupsGetOption("finishing-template", num_options, options); - if (copies > 1 && (keyword = cupsGetOption("job-impressions", num_options, options)) != NULL) + if (finishing_template && strcmp(finishing_template, "none")) + { + ipp_t *fin_col = ippNew(); /* finishings-col value */ + + ippAddString(fin_col, IPP_TAG_JOB, IPP_TAG_KEYWORD, "finishing-template", NULL, finishing_template); + ippAddCollection(request, IPP_TAG_JOB, "finishings-col", fin_col); + ippDelete(fin_col); + + if (copies != finishings_copies && (keyword = cupsGetOption("job-impressions", num_options, options)) != NULL) { /* * Send job-pages-per-set attribute to apply finishings correctly... */ - ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-pages-per-set", atoi(keyword) / copies); + ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-pages-per-set", atoi(keyword) / finishings_copies); + } + } + else + { + num_finishings = _ppdCacheGetFinishingValues(ppd, pc, (int)(sizeof(finishings) / sizeof(finishings[0])), finishings); + if (num_finishings > 0) + { + ippAddIntegers(request, IPP_TAG_JOB, IPP_TAG_ENUM, "finishings", num_finishings, finishings); + + if (copies != finishings_copies && (keyword = cupsGetOption("job-impressions", num_options, options)) != NULL) + { + /* + * Send job-pages-per-set attribute to apply finishings correctly... + */ + + ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-pages-per-set", atoi(keyword) / finishings_copies); + } } } @@ -506,24 +533,20 @@ _ppdCacheCreateWithFile( else if (!_cups_strcasecmp(line, "Filter")) { if (!pc->filters) - pc->filters = cupsArrayNew3(NULL, NULL, NULL, 0, - (cups_acopy_func_t)_cupsStrAlloc, - (cups_afree_func_t)_cupsStrFree); + pc->filters = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free); cupsArrayAdd(pc->filters, value); } else if (!_cups_strcasecmp(line, "PreFilter")) { if (!pc->prefilters) - pc->prefilters = cupsArrayNew3(NULL, NULL, NULL, 0, - (cups_acopy_func_t)_cupsStrAlloc, - (cups_afree_func_t)_cupsStrFree); + pc->prefilters = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free); cupsArrayAdd(pc->prefilters, value); } else if (!_cups_strcasecmp(line, "Product")) { - pc->product = _cupsStrAlloc(value); + pc->product = strdup(value); } else if (!_cups_strcasecmp(line, "SingleFile")) { @@ -623,8 +646,8 @@ _ppdCacheCreateWithFile( } map = pc->bins + pc->num_bins; - map->pwg = _cupsStrAlloc(pwg_keyword); - map->ppd = _cupsStrAlloc(ppd_keyword); + map->pwg = strdup(pwg_keyword); + map->ppd = strdup(ppd_keyword); pc->num_bins ++; } @@ -678,8 +701,8 @@ _ppdCacheCreateWithFile( goto create_error; } - size->map.pwg = _cupsStrAlloc(pwg_keyword); - size->map.ppd = _cupsStrAlloc(ppd_keyword); + size->map.pwg = strdup(pwg_keyword); + size->map.ppd = strdup(ppd_keyword); pc->num_sizes ++; } @@ -707,15 +730,15 @@ _ppdCacheCreateWithFile( pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "max", pc->custom_max_width, pc->custom_max_length, NULL); - pc->custom_max_keyword = _cupsStrAlloc(pwg_keyword); + pc->custom_max_keyword = strdup(pwg_keyword); pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "min", pc->custom_min_width, pc->custom_min_length, NULL); - pc->custom_min_keyword = _cupsStrAlloc(pwg_keyword); + pc->custom_min_keyword = strdup(pwg_keyword); } else if (!_cups_strcasecmp(line, "SourceOption")) { - pc->source_option = _cupsStrAlloc(value); + pc->source_option = strdup(value); } else if (!_cups_strcasecmp(line, "NumSources")) { @@ -762,8 +785,8 @@ _ppdCacheCreateWithFile( } map = pc->sources + pc->num_sources; - map->pwg = _cupsStrAlloc(pwg_keyword); - map->ppd = _cupsStrAlloc(ppd_keyword); + map->pwg = strdup(pwg_keyword); + map->ppd = strdup(ppd_keyword); pc->num_sources ++; } @@ -811,8 +834,8 @@ _ppdCacheCreateWithFile( } map = pc->types + pc->num_types; - map->pwg = _cupsStrAlloc(pwg_keyword); - map->ppd = _cupsStrAlloc(ppd_keyword); + map->pwg = strdup(pwg_keyword); + map->ppd = strdup(ppd_keyword); pc->num_types ++; } @@ -842,13 +865,13 @@ _ppdCacheCreateWithFile( pc->presets[print_color_mode] + print_quality); } else if (!_cups_strcasecmp(line, "SidesOption")) - pc->sides_option = _cupsStrAlloc(value); + pc->sides_option = strdup(value); else if (!_cups_strcasecmp(line, "Sides1Sided")) - pc->sides_1sided = _cupsStrAlloc(value); + pc->sides_1sided = strdup(value); else if (!_cups_strcasecmp(line, "Sides2SidedLong")) - pc->sides_2sided_long = _cupsStrAlloc(value); + pc->sides_2sided_long = strdup(value); else if (!_cups_strcasecmp(line, "Sides2SidedShort")) - pc->sides_2sided_short = _cupsStrAlloc(value); + pc->sides_2sided_short = strdup(value); else if (!_cups_strcasecmp(line, "Finishings")) { if (!pc->finishings) @@ -866,16 +889,23 @@ _ppdCacheCreateWithFile( cupsArrayAdd(pc->finishings, finishings); } + else if (!_cups_strcasecmp(line, "FinishingTemplate")) + { + if (!pc->templates) + pc->templates = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free); + + cupsArrayAdd(pc->templates, value); + } else if (!_cups_strcasecmp(line, "MaxCopies")) pc->max_copies = atoi(value); else if (!_cups_strcasecmp(line, "ChargeInfoURI")) - pc->charge_info_uri = _cupsStrAlloc(value); + pc->charge_info_uri = strdup(value); else if (!_cups_strcasecmp(line, "JobAccountId")) pc->account_id = !_cups_strcasecmp(value, "true"); else if (!_cups_strcasecmp(line, "JobAccountingUserId")) pc->accounting_user_id = !_cups_strcasecmp(value, "true"); else if (!_cups_strcasecmp(line, "JobPassword")) - pc->password = _cupsStrAlloc(value); + pc->password = strdup(value); else if (!_cups_strcasecmp(line, "Mandatory")) { if (pc->mandatory) @@ -886,9 +916,7 @@ _ppdCacheCreateWithFile( else if (!_cups_strcasecmp(line, "SupportFile")) { if (!pc->support_files) - pc->support_files = cupsArrayNew3(NULL, NULL, NULL, 0, - (cups_acopy_func_t)_cupsStrAlloc, - (cups_afree_func_t)_cupsStrFree); + pc->support_files = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free); cupsArrayAdd(pc->support_files, value); } @@ -959,7 +987,8 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ *media_type, /* MediaType option */ *output_bin, /* OutputBin option */ *color_model, /* ColorModel option */ - *duplex; /* Duplex option */ + *duplex, /* Duplex option */ + *ppd_option; /* Other PPD option */ ppd_choice_t *choice; /* Current InputSlot/MediaType */ pwg_map_t *map; /* Current source/type map */ ppd_attr_t *ppd_attr; /* Current PPD preset attribute */ @@ -994,6 +1023,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ pwg_size_t *new_size; /* New size to add, if any */ const char *filter; /* Current filter */ _pwg_finishings_t *finishings; /* Current finishings value */ + char msg_id[256]; /* Message identifier */ DEBUG_printf(("_ppdCacheCreateWithPPD(ppd=%p)", ppd)); @@ -1015,6 +1045,8 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ goto create_error; } + pc->strings = _cupsMessageNew(NULL); + /* * Copy and convert size data... */ @@ -1128,8 +1160,8 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ */ new_size = old_size; - _cupsStrFree(old_size->map.ppd); - _cupsStrFree(old_size->map.pwg); + free(old_size->map.ppd); + free(old_size->map.pwg); } } @@ -1150,8 +1182,8 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ * Save this size... */ - new_size->map.ppd = _cupsStrAlloc(ppd_size->name); - new_size->map.pwg = _cupsStrAlloc(pwg_name); + new_size->map.ppd = strdup(ppd_size->name); + new_size->map.pwg = strdup(pwg_name); new_size->width = new_width; new_size->length = new_length; new_size->left = new_left; @@ -1171,14 +1203,14 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "max", PWG_FROM_POINTS(ppd->custom_max[0]), PWG_FROM_POINTS(ppd->custom_max[1]), NULL); - pc->custom_max_keyword = _cupsStrAlloc(pwg_keyword); + pc->custom_max_keyword = strdup(pwg_keyword); pc->custom_max_width = PWG_FROM_POINTS(ppd->custom_max[0]); pc->custom_max_length = PWG_FROM_POINTS(ppd->custom_max[1]); pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "min", PWG_FROM_POINTS(ppd->custom_min[0]), PWG_FROM_POINTS(ppd->custom_min[1]), NULL); - pc->custom_min_keyword = _cupsStrAlloc(pwg_keyword); + pc->custom_min_keyword = strdup(pwg_keyword); pc->custom_min_width = PWG_FROM_POINTS(ppd->custom_min[0]); pc->custom_min_length = PWG_FROM_POINTS(ppd->custom_min[1]); @@ -1197,7 +1229,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ if (input_slot) { - pc->source_option = _cupsStrAlloc(input_slot->keyword); + pc->source_option = strdup(input_slot->keyword); if ((pc->sources = calloc((size_t)input_slot->num_choices, sizeof(pwg_map_t))) == NULL) { @@ -1249,8 +1281,15 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ "_"); } - map->pwg = _cupsStrAlloc(pwg_name); - map->ppd = _cupsStrAlloc(choice->choice); + map->pwg = strdup(pwg_name); + map->ppd = strdup(choice->choice); + + /* + * Add localized text for PWG keyword to message catalog... + */ + + snprintf(msg_id, sizeof(msg_id), "media-source.%s", pwg_name); + pwg_add_message(pc->strings, msg_id, choice->text); } } @@ -1313,8 +1352,15 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ "_"); } - map->pwg = _cupsStrAlloc(pwg_name); - map->ppd = _cupsStrAlloc(choice->choice); + map->pwg = strdup(pwg_name); + map->ppd = strdup(choice->choice); + + /* + * Add localized text for PWG keyword to message catalog... + */ + + snprintf(msg_id, sizeof(msg_id), "media-type.%s", pwg_name); + pwg_add_message(pc->strings, msg_id, choice->text); } } @@ -1340,8 +1386,15 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ { pwg_unppdize_name(choice->choice, pwg_keyword, sizeof(pwg_keyword), "_"); - map->pwg = _cupsStrAlloc(pwg_keyword); - map->ppd = _cupsStrAlloc(choice->choice); + map->pwg = strdup(pwg_keyword); + map->ppd = strdup(choice->choice); + + /* + * Add localized text for PWG keyword to message catalog... + */ + + snprintf(msg_id, sizeof(msg_id), "output-bin.%s", pwg_keyword); + pwg_add_message(pc->strings, msg_id, choice->text); } } @@ -1359,6 +1412,17 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ do { + /* + * Add localized text for PWG keyword to message catalog... + */ + + snprintf(msg_id, sizeof(msg_id), "preset-name.%s", ppd_attr->spec); + pwg_add_message(pc->strings, msg_id, ppd_attr->text); + + /* + * Get the options for this preset... + */ + num_options = _ppdParseOptions(ppd_attr->value, 0, &options, _PPD_PARSE_ALL); @@ -1556,7 +1620,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ if (duplex) { - pc->sides_option = _cupsStrAlloc(duplex->keyword); + pc->sides_option = strdup(duplex->keyword); for (i = duplex->num_choices, choice = duplex->choices; i > 0; @@ -1564,16 +1628,16 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ { if ((!_cups_strcasecmp(choice->choice, "None") || !_cups_strcasecmp(choice->choice, "False")) && !pc->sides_1sided) - pc->sides_1sided = _cupsStrAlloc(choice->choice); + pc->sides_1sided = strdup(choice->choice); else if ((!_cups_strcasecmp(choice->choice, "DuplexNoTumble") || !_cups_strcasecmp(choice->choice, "LongEdge") || !_cups_strcasecmp(choice->choice, "Top")) && !pc->sides_2sided_long) - pc->sides_2sided_long = _cupsStrAlloc(choice->choice); + pc->sides_2sided_long = strdup(choice->choice); else if ((!_cups_strcasecmp(choice->choice, "DuplexTumble") || !_cups_strcasecmp(choice->choice, "ShortEdge") || !_cups_strcasecmp(choice->choice, "Bottom")) && !pc->sides_2sided_short) - pc->sides_2sided_short = _cupsStrAlloc(choice->choice); + pc->sides_2sided_short = strdup(choice->choice); } } @@ -1581,9 +1645,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ * Copy filters and pre-filters... */ - pc->filters = cupsArrayNew3(NULL, NULL, NULL, 0, - (cups_acopy_func_t)_cupsStrAlloc, - (cups_afree_func_t)_cupsStrFree); + pc->filters = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free); cupsArrayAdd(pc->filters, "application/vnd.cups-raw application/octet-stream 0 -"); @@ -1640,9 +1702,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ if ((ppd_attr = ppdFindAttr(ppd, "cupsPreFilter", NULL)) != NULL) { - pc->prefilters = cupsArrayNew3(NULL, NULL, NULL, 0, - (cups_acopy_func_t)_cupsStrAlloc, - (cups_afree_func_t)_cupsStrFree); + pc->prefilters = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free); do { @@ -1659,7 +1719,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ */ if (ppd->product) - pc->product = _cupsStrAlloc(ppd->product); + pc->product = strdup(ppd->product); /* * Copy finishings mapping data... @@ -1696,8 +1756,6 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ * No IPP mapping data, try to map common/standard PPD keywords... */ - ppd_option_t *ppd_option; /* PPD option */ - pc->finishings = cupsArrayNew3((cups_array_func_t)pwg_compare_finishings, NULL, NULL, 0, NULL, (cups_afree_func_t)pwg_free_finishings); if ((ppd_option = ppdFindOption(ppd, "StapleLocation")) != NULL) @@ -1799,6 +1857,23 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ } } + if ((ppd_option = ppdFindOption(ppd, "cupsFinishingTemplate")) != NULL) + { + pc->templates = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free); + + for (choice = ppd_option->choices, i = ppd_option->num_choices; i > 0; choice ++, i --) + { + cupsArrayAdd(pc->templates, (void *)choice->choice); + + /* + * Add localized text for PWG keyword to message catalog... + */ + + snprintf(msg_id, sizeof(msg_id), "finishing-template.%s", choice->choice); + pwg_add_message(pc->strings, msg_id, choice->text); + } + } + /* * Max copies... */ @@ -1816,7 +1891,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ */ if ((ppd_attr = ppdFindAttr(ppd, "cupsChargeInfoURI", NULL)) != NULL) - pc->charge_info_uri = _cupsStrAlloc(ppd_attr->value); + pc->charge_info_uri = strdup(ppd_attr->value); if ((ppd_attr = ppdFindAttr(ppd, "cupsJobAccountId", NULL)) != NULL) pc->account_id = !_cups_strcasecmp(ppd_attr->value, "true"); @@ -1825,7 +1900,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ pc->accounting_user_id = !_cups_strcasecmp(ppd_attr->value, "true"); if ((ppd_attr = ppdFindAttr(ppd, "cupsJobPassword", NULL)) != NULL) - pc->password = _cupsStrAlloc(ppd_attr->value); + pc->password = strdup(ppd_attr->value); if ((ppd_attr = ppdFindAttr(ppd, "cupsMandatory", NULL)) != NULL) pc->mandatory = _cupsArrayNewStrings(ppd_attr->value, ' '); @@ -1834,9 +1909,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ * Support files... */ - pc->support_files = cupsArrayNew3(NULL, NULL, NULL, 0, - (cups_acopy_func_t)_cupsStrAlloc, - (cups_afree_func_t)_cupsStrFree); + pc->support_files = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free); for (ppd_attr = ppdFindAttr(ppd, "cupsICCProfile", NULL); ppd_attr; @@ -1892,8 +1965,8 @@ _ppdCacheDestroy(_ppd_cache_t *pc) /* I - PPD cache and mapping data */ { for (i = pc->num_bins, map = pc->bins; i > 0; i --, map ++) { - _cupsStrFree(map->pwg); - _cupsStrFree(map->ppd); + free(map->pwg); + free(map->ppd); } free(pc->bins); @@ -1903,22 +1976,21 @@ _ppdCacheDestroy(_ppd_cache_t *pc) /* I - PPD cache and mapping data */ { for (i = pc->num_sizes, size = pc->sizes; i > 0; i --, size ++) { - _cupsStrFree(size->map.pwg); - _cupsStrFree(size->map.ppd); + free(size->map.pwg); + free(size->map.ppd); } free(pc->sizes); } - if (pc->source_option) - _cupsStrFree(pc->source_option); + free(pc->source_option); if (pc->sources) { for (i = pc->num_sources, map = pc->sources; i > 0; i --, map ++) { - _cupsStrFree(map->pwg); - _cupsStrFree(map->ppd); + free(map->pwg); + free(map->ppd); } free(pc->sources); @@ -1928,31 +2000,30 @@ _ppdCacheDestroy(_ppd_cache_t *pc) /* I - PPD cache and mapping data */ { for (i = pc->num_types, map = pc->types; i > 0; i --, map ++) { - _cupsStrFree(map->pwg); - _cupsStrFree(map->ppd); + free(map->pwg); + free(map->ppd); } free(pc->types); } - if (pc->custom_max_keyword) - _cupsStrFree(pc->custom_max_keyword); + free(pc->custom_max_keyword); + free(pc->custom_min_keyword); - if (pc->custom_min_keyword) - _cupsStrFree(pc->custom_min_keyword); - - _cupsStrFree(pc->product); + free(pc->product); cupsArrayDelete(pc->filters); cupsArrayDelete(pc->prefilters); cupsArrayDelete(pc->finishings); - _cupsStrFree(pc->charge_info_uri); - _cupsStrFree(pc->password); + free(pc->charge_info_uri); + free(pc->password); cupsArrayDelete(pc->mandatory); cupsArrayDelete(pc->support_files); + cupsArrayDelete(pc->strings); + free(pc); } @@ -2065,9 +2136,8 @@ _ppdCacheGetFinishingOptions( int /* O - Number of finishings values */ _ppdCacheGetFinishingValues( + ppd_file_t *ppd, /* I - Marked PPD file */ _ppd_cache_t *pc, /* I - PPD cache and mapping data */ - int num_options, /* I - Number of options */ - cups_option_t *options, /* I - Options */ int max_values, /* I - Maximum number of finishings values */ int *values) /* O - Finishings values */ { @@ -2075,20 +2145,25 @@ _ppdCacheGetFinishingValues( num_values = 0; /* Number of values */ _pwg_finishings_t *f; /* Current finishings option */ cups_option_t *option; /* Current option */ - const char *val; /* Value for option */ + ppd_choice_t *choice; /* Marked PPD choice */ /* * Range check input... */ - DEBUG_printf(("_ppdCacheGetFinishingValues(pc=%p, num_options=%d, options=%p, max_values=%d, values=%p)", pc, num_options, options, max_values, values)); + DEBUG_printf(("_ppdCacheGetFinishingValues(ppd=%p, pc=%p, max_values=%d, values=%p)", ppd, pc, max_values, values)); - if (!pc || !pc->finishings || num_options < 1 || max_values < 1 || !values) + if (!ppd || !pc || max_values < 1 || !values) { DEBUG_puts("_ppdCacheGetFinishingValues: Bad arguments, returning 0."); return (0); } + else if (!pc->finishings) + { + DEBUG_puts("_ppdCacheGetFinishingValues: No finishings support, returning 0."); + return (0); + } /* * Go through the finishings options and see what is set... @@ -2098,14 +2173,13 @@ _ppdCacheGetFinishingValues( f; f = (_pwg_finishings_t *)cupsArrayNext(pc->finishings)) { - DEBUG_printf(("_ppdCacheGetFinishingValues: Checking %d (%s)", f->value, ippEnumString("finishings", f->value))); + DEBUG_printf(("_ppdCacheGetFinishingValues: Checking %d (%s)", (int)f->value, ippEnumString("finishings", (int)f->value))); for (i = f->num_options, option = f->options; i > 0; i --, option ++) { DEBUG_printf(("_ppdCacheGetFinishingValues: %s=%s?", option->name, option->value)); - if ((val = cupsGetOption(option->name, num_options, options)) == NULL || - _cups_strcasecmp(option->value, val)) + if ((choice = ppdFindMarkedChoice(ppd, option->name)) == NULL || _cups_strcasecmp(option->value, choice->choice)) { DEBUG_puts("_ppdCacheGetFinishingValues: NO"); break; @@ -2114,15 +2188,26 @@ _ppdCacheGetFinishingValues( if (i == 0) { - DEBUG_printf(("_ppdCacheGetFinishingValues: Adding %d.", f->value)); + DEBUG_printf(("_ppdCacheGetFinishingValues: Adding %d (%s)", (int)f->value, ippEnumString("finishings", (int)f->value))); - values[num_values ++] = f->value; + values[num_values ++] = (int)f->value; if (num_values >= max_values) break; } } + if (num_values == 0) + { + /* + * Always have at least "finishings" = 'none'... + */ + + DEBUG_puts("_ppdCacheGetFinishingValues: Adding 3 (none)."); + values[0] = IPP_FINISHINGS_NONE; + num_values ++; + } + DEBUG_printf(("_ppdCacheGetFinishingValues: Returning %d.", num_values)); return (num_values); @@ -2708,7 +2793,7 @@ _ppdCacheWriteFile( pwg_map_t *map; /* Current map */ _pwg_finishings_t *f; /* Current finishing option */ cups_option_t *option; /* Current option */ - const char *value; /* Filter/pre-filter value */ + const char *value; /* String value */ char newfile[1024]; /* New filename */ @@ -2856,6 +2941,9 @@ _ppdCacheWriteFile( cupsFilePutChar(fp, '\n'); } + for (value = (const char *)cupsArrayFirst(pc->templates); value; value = (const char *)cupsArrayNext(pc->templates)) + cupsFilePutConf(fp, "FinishingTemplate", value); + /* * Max copies... */ @@ -2869,12 +2957,12 @@ _ppdCacheWriteFile( if (pc->charge_info_uri) cupsFilePutConf(fp, "ChargeInfoURI", pc->charge_info_uri); - cupsFilePrintf(fp, "AccountId %s\n", pc->account_id ? "true" : "false"); - cupsFilePrintf(fp, "AccountingUserId %s\n", + cupsFilePrintf(fp, "JobAccountId %s\n", pc->account_id ? "true" : "false"); + cupsFilePrintf(fp, "JobAccountingUserId %s\n", pc->accounting_user_id ? "true" : "false"); if (pc->password) - cupsFilePutConf(fp, "Password", pc->password); + cupsFilePutConf(fp, "JobPassword", pc->password); for (value = (char *)cupsArrayFirst(pc->mandatory); value; @@ -2928,12 +3016,14 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ ipp_t *response) /* I - Get-Printer-Attributes response */ { cups_file_t *fp; /* PPD file */ - cups_array_t *sizes; /* Media sizes we've added */ + cups_array_t *sizes; /* Media sizes supported by printer */ + cups_size_t *size; /* Current media size */ ipp_attribute_t *attr, /* xxx-supported */ *defattr, /* xxx-default */ *quality, /* print-quality-supported */ *x_dim, *y_dim; /* Media dimensions */ - ipp_t *media_size; /* Media size collection */ + ipp_t *media_col, /* Media collection */ + *media_size; /* Media size collection */ char make[256], /* Make and model */ *model, /* Model name */ ppdname[PPD_MAX_NAME]; @@ -2944,83 +3034,28 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ left, /* Largest left margin */ right, /* Largest right margin */ top, /* Largest top margin */ + max_length = 0, /* Maximum custom size */ + max_width = 0, + min_length = INT_MAX, + /* Minimum custom size */ + min_width = INT_MAX, is_apple = 0, /* Does the printer support Apple raster? */ is_pdf = 0, /* Does the printer support PDF? */ is_pwg = 0; /* Does the printer support PWG Raster? */ pwg_media_t *pwg; /* PWG media size */ int xres, yres; /* Resolution values */ + int resolutions[1000]; + /* Array of resolution indices */ + char msgid[256]; /* Message identifier (attr.value) */ + const char *keyword, /* Keyword value */ + *msgstr; /* Localized string */ cups_lang_t *lang = cupsLangDefault(); /* Localization info */ + cups_array_t *strings = NULL;/* Printer strings file */ struct lconv *loc = localeconv(); /* Locale data */ - static const char * const finishings[][2] = - { /* Finishings strings */ - { "bale", _("Bale") }, - { "bind", _("Bind") }, - { "bind-bottom", _("Bind (Reverse Landscape)") }, - { "bind-left", _("Bind (Portrait)") }, - { "bind-right", _("Bind (Reverse Portrait)") }, - { "bind-top", _("Bind (Landscape)") }, - { "booklet-maker", _("Booklet Maker") }, - { "coat", _("Coat") }, - { "cover", _("Cover") }, - { "edge-stitch", _("Staple Edge") }, - { "edge-stitch-bottom", _("Staple Edge (Reverse Landscape)") }, - { "edge-stitch-left", _("Staple Edge (Portrait)") }, - { "edge-stitch-right", _("Staple Edge (Reverse Portrait)") }, - { "edge-stitch-top", _("Staple Edge (Landscape)") }, - { "fold", _("Fold") }, - { "fold-accordian", _("Accordian Fold") }, - { "fold-double-gate", _("Double Gate Fold") }, - { "fold-engineering-z", _("Engineering Z Fold") }, - { "fold-gate", _("Gate Fold") }, - { "fold-half", _("Half Fold") }, - { "fold-half-z", _("Half Z Fold") }, - { "fold-left-gate", _("Left Gate Fold") }, - { "fold-letter", _("Letter Fold") }, - { "fold-parallel", _("Parallel Fold") }, - { "fold-poster", _("Poster Fold") }, - { "fold-right-gate", _("Right Gate Fold") }, - { "fold-z", _("Z Fold") }, - { "jog-offset", _("Jog") }, - { "laminate", _("Laminate") }, - { "punch", _("Punch") }, - { "punch-bottom-left", _("Single Punch (Reverse Landscape)") }, - { "punch-bottom-right", _("Single Punch (Reverse Portrait)") }, - { "punch-double-bottom", _("2-Hole Punch (Reverse Portrait)") }, - { "punch-double-left", _("2-Hole Punch (Reverse Landscape)") }, - { "punch-double-right", _("2-Hole Punch (Landscape)") }, - { "punch-double-top", _("2-Hole Punch (Portrait)") }, - { "punch-quad-bottom", _("4-Hole Punch (Reverse Landscape)") }, - { "punch-quad-left", _("4-Hole Punch (Portrait)") }, - { "punch-quad-right", _("4-Hole Punch (Reverse Portrait)") }, - { "punch-quad-top", _("4-Hole Punch (Landscape)") }, - { "punch-top-left", _("Single Punch (Portrait)") }, - { "punch-top-right", _("Single Punch (Landscape)") }, - { "punch-triple-bottom", _("3-Hole Punch (Reverse Landscape)") }, - { "punch-triple-left", _("3-Hole Punch (Portrait)") }, - { "punch-triple-right", _("3-Hole Punch (Reverse Portrait)") }, - { "punch-triple-top", _("3-Hole Punch (Landscape)") }, - { "punch-multiple-bottom", _("Multi-Hole Punch (Reverse Landscape)") }, - { "punch-multiple-left", _("Multi-Hole Punch (Portrait)") }, - { "punch-multiple-right", _("Multi-Hole Punch (Reverse Portrait)") }, - { "punch-multiple-top", _("Multi-Hole Punch (Landscape)") }, - { "saddle-stitch", _("Saddle Stitch") }, - { "staple", _("Staple") }, - { "staple-bottom-left", _("Single Staple (Reverse Landscape)") }, - { "staple-bottom-right", _("Single Staple (Reverse Portrait)") }, - { "staple-dual-bottom", _("Double Staple (Reverse Landscape)") }, - { "staple-dual-left", _("Double Staple (Portrait)") }, - { "staple-dual-right", _("Double Staple (Reverse Portrait)") }, - { "staple-dual-top", _("Double Staple (Landscape)") }, - { "staple-top-left", _("Single Staple (Portrait)") }, - { "staple-top-right", _("Single Staple (Landscape)") }, - { "staple-triple-bottom", _("Triple Staple (Reverse Landscape)") }, - { "staple-triple-left", _("Triple Staple (Portrait)") }, - { "staple-triple-right", _("Triple Staple (Reverse Portrait)") }, - { "staple-triple-top", _("Triple Staple (Landscape)") }, - { "trim", _("Cut Media") } - }; + cups_array_t *fin_options = NULL; + /* Finishing options */ /* @@ -3085,8 +3120,8 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ cupsFilePrintf(fp, "*Manufacturer: \"%s\"\n", make); cupsFilePrintf(fp, "*ModelName: \"%s\"\n", model); cupsFilePrintf(fp, "*Product: \"(%s)\"\n", model); - cupsFilePrintf(fp, "*NickName: \"%s\"\n", model); - cupsFilePrintf(fp, "*ShortNickName: \"%s\"\n", model); + cupsFilePrintf(fp, "*NickName: \"%s - IPP Everywhere\"\n", model); + cupsFilePrintf(fp, "*ShortNickName: \"%s - IPP Everywhere\"\n", model); if ((attr = ippFindAttribute(response, "color-supported", IPP_TAG_BOOLEAN)) != NULL && ippGetBoolean(attr, 0)) cupsFilePuts(fp, "*ColorDevice: True\n"); @@ -3095,7 +3130,76 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ cupsFilePrintf(fp, "*cupsVersion: %d.%d\n", CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR); cupsFilePuts(fp, "*cupsSNMPSupplies: False\n"); - cupsFilePuts(fp, "*cupsLanguages: \"en\"\n"); + cupsFilePrintf(fp, "*cupsLanguages: \"%s\"\n", lang->language); + + if ((attr = ippFindAttribute(response, "printer-more-info", IPP_TAG_URI)) != NULL) + cupsFilePrintf(fp, "*APSupplies: \"%s\"\n", ippGetString(attr, 0, NULL)); + + if ((attr = ippFindAttribute(response, "printer-charge-info-uri", IPP_TAG_URI)) != NULL) + cupsFilePrintf(fp, "*cupsChargeInfoURI: \"%s\"\n", ippGetString(attr, 0, NULL)); + + if ((attr = ippFindAttribute(response, "printer-strings-uri", IPP_TAG_URI)) != NULL) + { + http_t *http = NULL; /* Connection to printer */ + char stringsfile[1024]; /* Temporary strings file */ + + if (cups_get_url(&http, ippGetString(attr, 0, NULL), stringsfile, sizeof(stringsfile))) + { + cupsFilePrintf(fp, "*cupsStringsURI: \"%s\"\n", ippGetString(attr, 0, NULL)); + + strings = _cupsMessageLoad(stringsfile, _CUPS_MESSAGE_STRINGS | _CUPS_MESSAGE_UNQUOTE); + + unlink(stringsfile); + } + + if (http) + httpClose(http); + } + + /* + * Accounting... + */ + + if (ippGetBoolean(ippFindAttribute(response, "job-account-id-supported", IPP_TAG_BOOLEAN), 0)) + cupsFilePuts(fp, "*cupsJobAccountId: True\n"); + + if (ippGetBoolean(ippFindAttribute(response, "job-accounting-user-id-supported", IPP_TAG_BOOLEAN), 0)) + cupsFilePuts(fp, "*cupsJobAccountingUserId: True\n"); + + /* + * Password/PIN printing... + */ + + if ((attr = ippFindAttribute(response, "job-password-supported", IPP_TAG_INTEGER)) != NULL) + { + char pattern[33]; /* Password pattern */ + int maxlen = ippGetInteger(attr, 0); + /* Maximum length */ + const char *repertoire = ippGetString(ippFindAttribute(response, "job-password-repertoire-configured", IPP_TAG_KEYWORD), 0, NULL); + /* Type of password */ + + if (maxlen > (int)(sizeof(pattern) - 1)) + maxlen = (int)sizeof(pattern) - 1; + + if (!repertoire || !strcmp(repertoire, "iana_us-ascii_digits")) + memset(pattern, '1', (size_t)maxlen); + else if (!strcmp(repertoire, "iana_us-ascii_letters")) + memset(pattern, 'A', (size_t)maxlen); + else if (!strcmp(repertoire, "iana_us-ascii_complex")) + memset(pattern, 'C', (size_t)maxlen); + else if (!strcmp(repertoire, "iana_us-ascii_any")) + memset(pattern, '.', (size_t)maxlen); + else if (!strcmp(repertoire, "iana_utf-8_digits")) + memset(pattern, 'N', (size_t)maxlen); + else if (!strcmp(repertoire, "iana_utf-8_letters")) + memset(pattern, 'U', (size_t)maxlen); + else + memset(pattern, '*', (size_t)maxlen); + + pattern[maxlen] = '\0'; + + cupsFilePrintf(fp, "*cupsJobPassword: \"%s\"\n", pattern); + } /* * Filters... @@ -3105,24 +3209,30 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ { is_apple = ippContainsString(attr, "image/urf"); is_pdf = ippContainsString(attr, "application/pdf"); - is_pwg = ippContainsString(attr, "image/pwg-raster"); + is_pwg = ippContainsString(attr, "image/pwg-raster") && !is_apple; - for (i = 0, count = ippGetCount(attr); i < count; i ++) + if (ippContainsString(attr, "image/jpeg")) + cupsFilePuts(fp, "*cupsFilter2: \"image/jpeg image/jpeg 0 -\"\n"); + if (ippContainsString(attr, "image/png")) + cupsFilePuts(fp, "*cupsFilter2: \"image/png image/png 0 -\"\n"); + if (is_pdf) { - const char *format = ippGetString(attr, i, NULL); - /* PDL */ - /* - * Write cupsFilter2 lines for supported formats... + * Don't locally filter PDF content when printing to a CUPS shared + * printer, otherwise the options will be applied twice... */ - if (!_cups_strcasecmp(format, "application/pdf")) + if (ippContainsString(attr, "application/vnd.cups-pdf")) + cupsFilePuts(fp, "*cupsFilter2: \"application/pdf application/pdf 0 -\"\n"); + else cupsFilePuts(fp, "*cupsFilter2: \"application/vnd.cups-pdf application/pdf 10 -\"\n"); - else if (!_cups_strcasecmp(format, "image/jpeg") || !_cups_strcasecmp(format, "image/png")) - cupsFilePrintf(fp, "*cupsFilter2: \"%s %s 0 -\"\n", format, format); - else if (!_cups_strcasecmp(format, "image/pwg-raster") || !_cups_strcasecmp(format, "image/urf")) - cupsFilePrintf(fp, "*cupsFilter2: \"%s %s 100 -\"\n", format, format); } + else + cupsFilePuts(fp, "*cupsManualCopies: true\n"); + if (is_apple) + cupsFilePuts(fp, "*cupsFilter2: \"image/urf image/urf 100 -\"\n"); + if (is_pwg) + cupsFilePuts(fp, "*cupsFilter2: \"image/pwg-raster image/pwg-raster 100 -\"\n"); } if (!is_apple && !is_pdf && !is_pwg) @@ -3189,135 +3299,319 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ else strlcpy(ppdname, "Unknown", sizeof(ppdname)); - if ((attr = ippFindAttribute(response, "media-size-supported", IPP_TAG_BEGIN_COLLECTION)) == NULL) - attr = ippFindAttribute(response, "media-supported", IPP_TAG_ZERO); - if (attr) + sizes = cupsArrayNew3((cups_array_func_t)pwg_compare_sizes, NULL, NULL, 0, (cups_acopy_func_t)pwg_copy_size, (cups_afree_func_t)free); + + if ((attr = ippFindAttribute(response, "media-col-database", IPP_TAG_BEGIN_COLLECTION)) != NULL) { - cupsFilePrintf(fp, "*OpenUI *PageSize: PickOne\n" - "*OrderDependency: 10 AnySetup *PageSize\n" - "*DefaultPageSize: %s\n", ppdname); - - sizes = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free); - for (i = 0, count = ippGetCount(attr); i < count; i ++) { - if (ippGetValueTag(attr) == IPP_TAG_BEGIN_COLLECTION) - { - media_size = ippGetCollection(attr, i); - x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_INTEGER); - y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_INTEGER); + cups_size_t temp; /* Current size */ + ipp_attribute_t *margin; /* media-xxx-margin attribute */ - pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0)); - } - else - pwg = pwgMediaForPWG(ippGetString(attr, i, NULL)); + media_col = ippGetCollection(attr, i); + media_size = ippGetCollection(ippFindAttribute(media_col, "media-size", IPP_TAG_BEGIN_COLLECTION), 0); + x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_ZERO); + y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_ZERO); + pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0)); if (pwg) { - char twidth[256], /* Width string */ - tlength[256]; /* Length string */ + temp.width = pwg->width; + temp.length = pwg->length; - if (cupsArrayFind(sizes, (void *)pwg->ppd)) + if ((margin = ippFindAttribute(media_col, "media-bottom-margin", IPP_TAG_INTEGER)) != NULL) + temp.bottom = ippGetInteger(margin, 0); + else + temp.bottom = bottom; + + if ((margin = ippFindAttribute(media_col, "media-left-margin", IPP_TAG_INTEGER)) != NULL) + temp.left = ippGetInteger(margin, 0); + else + temp.left = left; + + if ((margin = ippFindAttribute(media_col, "media-right-margin", IPP_TAG_INTEGER)) != NULL) + temp.right = ippGetInteger(margin, 0); + else + temp.right = right; + + if ((margin = ippFindAttribute(media_col, "media-top-margin", IPP_TAG_INTEGER)) != NULL) + temp.top = ippGetInteger(margin, 0); + else + temp.top = top; + + if (temp.bottom == 0 && temp.left == 0 && temp.right == 0 && temp.top == 0) + snprintf(temp.media, sizeof(temp.media), "%s.Borderless", pwg->ppd); + else + strlcpy(temp.media, pwg->ppd, sizeof(temp.media)); + + if (!cupsArrayFind(sizes, &temp)) + cupsArrayAdd(sizes, &temp); + } + else if (ippGetValueTag(x_dim) == IPP_TAG_RANGE || ippGetValueTag(y_dim) == IPP_TAG_RANGE) + { + /* + * Custom size - record the min/max values... + */ + + int lower, upper; /* Range values */ + + if (ippGetValueTag(x_dim) == IPP_TAG_RANGE) + lower = ippGetRange(x_dim, 0, &upper); + else + lower = upper = ippGetInteger(x_dim, 0); + + if (lower < min_width) + min_width = lower; + if (upper > max_width) + max_width = upper; + + if (ippGetValueTag(y_dim) == IPP_TAG_RANGE) + lower = ippGetRange(y_dim, 0, &upper); + else + lower = upper = ippGetInteger(y_dim, 0); + + if (lower < min_length) + min_length = lower; + if (upper > max_length) + max_length = upper; + } + } + + if ((max_width == 0 || max_length == 0) && (attr = ippFindAttribute(response, "media-size-supported", IPP_TAG_BEGIN_COLLECTION)) != NULL) + { + /* + * Some printers don't list custom size support in media-col-database... + */ + + for (i = 0, count = ippGetCount(attr); i < count; i ++) + { + media_size = ippGetCollection(attr, i); + x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_ZERO); + y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_ZERO); + + if (ippGetValueTag(x_dim) == IPP_TAG_RANGE || ippGetValueTag(y_dim) == IPP_TAG_RANGE) + { + /* + * Custom size - record the min/max values... + */ + + int lower, upper; /* Range values */ + + if (ippGetValueTag(x_dim) == IPP_TAG_RANGE) + lower = ippGetRange(x_dim, 0, &upper); + else + lower = upper = ippGetInteger(x_dim, 0); + + if (lower < min_width) + min_width = lower; + if (upper > max_width) + max_width = upper; + + if (ippGetValueTag(y_dim) == IPP_TAG_RANGE) + lower = ippGetRange(y_dim, 0, &upper); + else + lower = upper = ippGetInteger(y_dim, 0); + + if (lower < min_length) + min_length = lower; + if (upper > max_length) + max_length = upper; + } + } + } + } + else if ((attr = ippFindAttribute(response, "media-size-supported", IPP_TAG_BEGIN_COLLECTION)) != NULL) + { + for (i = 0, count = ippGetCount(attr); i < count; i ++) + { + cups_size_t temp; /* Current size */ + + media_size = ippGetCollection(attr, i); + x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_ZERO); + y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_ZERO); + pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0)); + + if (pwg) + { + temp.width = pwg->width; + temp.length = pwg->length; + temp.bottom = bottom; + temp.left = left; + temp.right = right; + temp.top = top; + + if (temp.bottom == 0 && temp.left == 0 && temp.right == 0 && temp.top == 0) + snprintf(temp.media, sizeof(temp.media), "%s.Borderless", pwg->ppd); + else + strlcpy(temp.media, pwg->ppd, sizeof(temp.media)); + + if (!cupsArrayFind(sizes, &temp)) + cupsArrayAdd(sizes, &temp); + } + else if (ippGetValueTag(x_dim) == IPP_TAG_RANGE || ippGetValueTag(y_dim) == IPP_TAG_RANGE) + { + /* + * Custom size - record the min/max values... + */ + + int lower, upper; /* Range values */ + + if (ippGetValueTag(x_dim) == IPP_TAG_RANGE) + lower = ippGetRange(x_dim, 0, &upper); + else + lower = upper = ippGetInteger(x_dim, 0); + + if (lower < min_width) + min_width = lower; + if (upper > max_width) + max_width = upper; + + if (ippGetValueTag(y_dim) == IPP_TAG_RANGE) + lower = ippGetRange(y_dim, 0, &upper); + else + lower = upper = ippGetInteger(y_dim, 0); + + if (lower < min_length) + min_length = lower; + if (upper > max_length) + max_length = upper; + } + } + } + else if ((attr = ippFindAttribute(response, "media-supported", IPP_TAG_ZERO)) != NULL) + { + for (i = 0, count = ippGetCount(attr); i < count; i ++) + { + const char *pwg_size = ippGetString(attr, i, NULL); + /* PWG size name */ + cups_size_t temp; /* Current size */ + + if ((pwg = pwgMediaForPWG(pwg_size)) != NULL) + { + if (strstr(pwg_size, "_max_") || strstr(pwg_size, "_max.")) { - cupsFilePrintf(fp, "*%% warning: Duplicate size '%s' reported by printer.\n", pwg->ppd); - continue; + if (pwg->width > max_width) + max_width = pwg->width; + if (pwg->length > max_length) + max_length = pwg->length; } + else if (strstr(pwg_size, "_min_") || strstr(pwg_size, "_min.")) + { + if (pwg->width < min_width) + min_width = pwg->width; + if (pwg->length < min_length) + min_length = pwg->length; + } + else + { + temp.width = pwg->width; + temp.length = pwg->length; + temp.bottom = bottom; + temp.left = left; + temp.right = right; + temp.top = top; - cupsArrayAdd(sizes, (void *)pwg->ppd); + if (temp.bottom == 0 && temp.left == 0 && temp.right == 0 && temp.top == 0) + snprintf(temp.media, sizeof(temp.media), "%s.Borderless", pwg->ppd); + else + strlcpy(temp.media, pwg->ppd, sizeof(temp.media)); - _cupsStrFormatd(twidth, twidth + sizeof(twidth), pwg->width * 72.0 / 2540.0, loc); - _cupsStrFormatd(tlength, tlength + sizeof(tlength), pwg->length * 72.0 / 2540.0, loc); - - cupsFilePrintf(fp, "*PageSize %s: \"<>setpagedevice\"\n", pwg->ppd, twidth, tlength); + if (!cupsArrayFind(sizes, &temp)) + cupsArrayAdd(sizes, &temp); + } } } - cupsFilePuts(fp, "*CloseUI: *PageSize\n"); + } - cupsArrayDelete(sizes); - sizes = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free); + if (cupsArrayCount(sizes) > 0) + { + /* + * List all of the standard sizes... + */ - cupsFilePrintf(fp, "*OpenUI *PageRegion: PickOne\n" - "*OrderDependency: 10 AnySetup *PageRegion\n" - "*DefaultPageRegion: %s\n", ppdname); - for (i = 0, count = ippGetCount(attr); i < count; i ++) - { - if (ippGetValueTag(attr) == IPP_TAG_BEGIN_COLLECTION) - { - media_size = ippGetCollection(attr, i); - x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_INTEGER); - y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_INTEGER); - - pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0)); - } - else - pwg = pwgMediaForPWG(ippGetString(attr, i, NULL)); - - if (pwg) - { - char twidth[256], /* Width string */ - tlength[256]; /* Length string */ - - if (cupsArrayFind(sizes, (void *)pwg->ppd)) - continue; - - cupsArrayAdd(sizes, (void *)pwg->ppd); - - _cupsStrFormatd(twidth, twidth + sizeof(twidth), pwg->width * 72.0 / 2540.0, loc); - _cupsStrFormatd(tlength, tlength + sizeof(tlength), pwg->length * 72.0 / 2540.0, loc); - - cupsFilePrintf(fp, "*PageRegion %s: \"<>setpagedevice\"\n", pwg->ppd, twidth, tlength); - } - } - cupsFilePuts(fp, "*CloseUI: *PageRegion\n"); - - cupsArrayDelete(sizes); - sizes = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free); - - cupsFilePrintf(fp, "*DefaultImageableArea: %s\n" - "*DefaultPaperDimension: %s\n", ppdname, ppdname); - for (i = 0, count = ippGetCount(attr); i < count; i ++) - { - if (ippGetValueTag(attr) == IPP_TAG_BEGIN_COLLECTION) - { - media_size = ippGetCollection(attr, i); - x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_INTEGER); - y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_INTEGER); - - pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0)); - } - else - pwg = pwgMediaForPWG(ippGetString(attr, i, NULL)); - - if (pwg) - { - char tleft[256], /* Left string */ + char tleft[256], /* Left string */ tbottom[256], /* Bottom string */ tright[256], /* Right string */ ttop[256], /* Top string */ twidth[256], /* Width string */ tlength[256]; /* Length string */ - if (cupsArrayFind(sizes, (void *)pwg->ppd)) - continue; + cupsFilePrintf(fp, "*OpenUI *PageSize: PickOne\n" + "*OrderDependency: 10 AnySetup *PageSize\n" + "*DefaultPageSize: %s\n", ppdname); + for (size = (cups_size_t *)cupsArrayFirst(sizes); size; size = (cups_size_t *)cupsArrayNext(sizes)) + { + _cupsStrFormatd(twidth, twidth + sizeof(twidth), size->width * 72.0 / 2540.0, loc); + _cupsStrFormatd(tlength, tlength + sizeof(tlength), size->length * 72.0 / 2540.0, loc); - cupsArrayAdd(sizes, (void *)pwg->ppd); + cupsFilePrintf(fp, "*PageSize %s: \"<>setpagedevice\"\n", size->media, twidth, tlength); + } + cupsFilePuts(fp, "*CloseUI: *PageSize\n"); - _cupsStrFormatd(tleft, tleft + sizeof(tleft), left * 72.0 / 2540.0, loc); - _cupsStrFormatd(tbottom, tbottom + sizeof(tbottom), bottom * 72.0 / 2540.0, loc); - _cupsStrFormatd(tright, tright + sizeof(tright), (pwg->width - right) * 72.0 / 2540.0, loc); - _cupsStrFormatd(ttop, ttop + sizeof(ttop), (pwg->length - top) * 72.0 / 2540.0, loc); - _cupsStrFormatd(twidth, twidth + sizeof(twidth), pwg->width * 72.0 / 2540.0, loc); - _cupsStrFormatd(tlength, tlength + sizeof(tlength), pwg->length * 72.0 / 2540.0, loc); + cupsFilePrintf(fp, "*OpenUI *PageRegion: PickOne\n" + "*OrderDependency: 10 AnySetup *PageRegion\n" + "*DefaultPageRegion: %s\n", ppdname); + for (size = (cups_size_t *)cupsArrayFirst(sizes); size; size = (cups_size_t *)cupsArrayNext(sizes)) + { + _cupsStrFormatd(twidth, twidth + sizeof(twidth), size->width * 72.0 / 2540.0, loc); + _cupsStrFormatd(tlength, tlength + sizeof(tlength), size->length * 72.0 / 2540.0, loc); - cupsFilePrintf(fp, "*ImageableArea %s: \"%s %s %s %s\"\n", pwg->ppd, tleft, tbottom, tright, ttop); - cupsFilePrintf(fp, "*PaperDimension %s: \"%s %s\"\n", pwg->ppd, twidth, tlength); - } + cupsFilePrintf(fp, "*PageRegion %s: \"<>setpagedevice\"\n", size->media, twidth, tlength); + } + cupsFilePuts(fp, "*CloseUI: *PageRegion\n"); + + cupsFilePrintf(fp, "*DefaultImageableArea: %s\n" + "*DefaultPaperDimension: %s\n", ppdname, ppdname); + + for (size = (cups_size_t *)cupsArrayFirst(sizes); size; size = (cups_size_t *)cupsArrayNext(sizes)) + { + _cupsStrFormatd(tleft, tleft + sizeof(tleft), size->left * 72.0 / 2540.0, loc); + _cupsStrFormatd(tbottom, tbottom + sizeof(tbottom), size->bottom * 72.0 / 2540.0, loc); + _cupsStrFormatd(tright, tright + sizeof(tright), (size->width - size->right) * 72.0 / 2540.0, loc); + _cupsStrFormatd(ttop, ttop + sizeof(ttop), (size->length - size->top) * 72.0 / 2540.0, loc); + _cupsStrFormatd(twidth, twidth + sizeof(twidth), size->width * 72.0 / 2540.0, loc); + _cupsStrFormatd(tlength, tlength + sizeof(tlength), size->length * 72.0 / 2540.0, loc); + + cupsFilePrintf(fp, "*ImageableArea %s: \"%s %s %s %s\"\n", size->media, tleft, tbottom, tright, ttop); + cupsFilePrintf(fp, "*PaperDimension %s: \"%s %s\"\n", size->media, twidth, tlength); } cupsArrayDelete(sizes); + + /* + * Custom size support... + */ + + if (max_width > 0 && min_width < INT_MAX && max_length > 0 && min_length < INT_MAX) + { + char tmax[256], tmin[256]; /* Min/max values */ + + _cupsStrFormatd(tleft, tleft + sizeof(tleft), left * 72.0 / 2540.0, loc); + _cupsStrFormatd(tbottom, tbottom + sizeof(tbottom), bottom * 72.0 / 2540.0, loc); + _cupsStrFormatd(tright, tright + sizeof(tright), right * 72.0 / 2540.0, loc); + _cupsStrFormatd(ttop, ttop + sizeof(ttop), top * 72.0 / 2540.0, loc); + + cupsFilePrintf(fp, "*HWMargins: \"%s %s %s %s\"\n", tleft, tbottom, tright, ttop); + + _cupsStrFormatd(tmax, tmax + sizeof(tmax), max_width * 72.0 / 2540.0, loc); + _cupsStrFormatd(tmin, tmin + sizeof(tmin), min_width * 72.0 / 2540.0, loc); + cupsFilePrintf(fp, "*ParamCustomPageSize Width: 1 points %s %s\n", tmin, tmax); + + _cupsStrFormatd(tmax, tmax + sizeof(tmax), max_length * 72.0 / 2540.0, loc); + _cupsStrFormatd(tmin, tmin + sizeof(tmin), min_length * 72.0 / 2540.0, loc); + cupsFilePrintf(fp, "*ParamCustomPageSize Height: 2 points %s %s\n", tmin, tmax); + + cupsFilePuts(fp, "*ParamCustomPageSize WidthOffset: 3 points 0 0\n"); + cupsFilePuts(fp, "*ParamCustomPageSize HeightOffset: 4 points 0 0\n"); + cupsFilePuts(fp, "*ParamCustomPageSize Orientation: 5 int 0 3\n"); + cupsFilePuts(fp, "*CustomPageSize True: \"pop pop pop <>setpagedevice\"\n"); + } } else + { + cupsArrayDelete(sizes); goto bad_ppd; + } /* * InputSlot... @@ -3330,58 +3624,58 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ if ((attr = ippFindAttribute(response, "media-source-supported", IPP_TAG_ZERO)) != NULL && (count = ippGetCount(attr)) > 1) { - static const char * const sources[][2] = - { /* "media-source" strings */ - { "Auto", _("Automatic") }, - { "Main", _("Main") }, - { "Alternate", _("Alternate") }, - { "LargeCapacity", _("Large Capacity") }, - { "Manual", _("Manual") }, - { "Envelope", _("Envelope") }, - { "Disc", _("Disc") }, - { "Photo", _("Photo") }, - { "Hagaki", _("Hagaki") }, - { "MainRoll", _("Main Roll") }, - { "AlternateRoll", _("Alternate Roll") }, - { "Top", _("Top") }, - { "Middle", _("Middle") }, - { "Bottom", _("Bottom") }, - { "Side", _("Side") }, - { "Left", _("Left") }, - { "Right", _("Right") }, - { "Center", _("Center") }, - { "Rear", _("Rear") }, - { "ByPassTray", _("Multipurpose") }, - { "Tray1", _("Tray 1") }, - { "Tray2", _("Tray 2") }, - { "Tray3", _("Tray 3") }, - { "Tray4", _("Tray 4") }, - { "Tray5", _("Tray 5") }, - { "Tray6", _("Tray 6") }, - { "Tray7", _("Tray 7") }, - { "Tray8", _("Tray 8") }, - { "Tray9", _("Tray 9") }, - { "Tray10", _("Tray 10") }, - { "Tray11", _("Tray 11") }, - { "Tray12", _("Tray 12") }, - { "Tray13", _("Tray 13") }, - { "Tray14", _("Tray 14") }, - { "Tray15", _("Tray 15") }, - { "Tray16", _("Tray 16") }, - { "Tray17", _("Tray 17") }, - { "Tray18", _("Tray 18") }, - { "Tray19", _("Tray 19") }, - { "Tray20", _("Tray 20") }, - { "Roll1", _("Roll 1") }, - { "Roll2", _("Roll 2") }, - { "Roll3", _("Roll 3") }, - { "Roll4", _("Roll 4") }, - { "Roll5", _("Roll 5") }, - { "Roll6", _("Roll 6") }, - { "Roll7", _("Roll 7") }, - { "Roll8", _("Roll 8") }, - { "Roll9", _("Roll 9") }, - { "Roll10", _("Roll 10") } + static const char * const sources[] = + { /* Standard "media-source" strings */ + "auto", + "main", + "alternate", + "large-capacity", + "manual", + "envelope", + "disc", + "photo", + "hagaki", + "main-roll", + "alternate-roll", + "top", + "middle", + "bottom", + "side", + "left", + "right", + "center", + "rear", + "by-pass-tray", + "tray-1", + "tray-2", + "tray-3", + "tray-4", + "tray-5", + "tray-6", + "tray-7", + "tray-8", + "tray-9", + "tray-10", + "tray-11", + "tray-12", + "tray-13", + "tray-14", + "tray-15", + "tray-16", + "tray-17", + "tray-18", + "tray-19", + "tray-20", + "roll-1", + "roll-2", + "roll-3", + "roll-4", + "roll-5", + "roll-6", + "roll-7", + "roll-8", + "roll-9", + "roll-10" }; cupsFilePrintf(fp, "*OpenUI *InputSlot: PickOne\n" @@ -3389,12 +3683,16 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ "*DefaultInputSlot: %s\n", ppdname); for (i = 0, count = ippGetCount(attr); i < count; i ++) { - pwg_ppdize_name(ippGetString(attr, i, NULL), ppdname, sizeof(ppdname)); + keyword = ippGetString(attr, i, NULL); + + pwg_ppdize_name(keyword, ppdname, sizeof(ppdname)); for (j = 0; j < (int)(sizeof(sources) / sizeof(sources[0])); j ++) - if (!strcmp(sources[j][0], ppdname)) + if (!strcmp(sources[j], keyword)) { - cupsFilePrintf(fp, "*InputSlot %s/%s: \"<>setpagedevice\"\n", ppdname, _cupsLangString(lang, sources[j][1]), j); + snprintf(msgid, sizeof(msgid), "media-source.%s", keyword); + cupsFilePrintf(fp, "*InputSlot %s: \"<>setpagedevice\"\n", ppdname, j); + cupsFilePrintf(fp, "*%s.InputSlot %s/%s: \"\"\n", lang->language, ppdname, _cupsLangString(lang, msgid)); break; } } @@ -3412,167 +3710,22 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ if ((attr = ippFindAttribute(response, "media-type-supported", IPP_TAG_ZERO)) != NULL && (count = ippGetCount(attr)) > 1) { - static const char * const media_types[][2] = - { /* "media-type" strings */ - { "aluminum", _("Aluminum") }, - { "auto", _("Automatic") }, - { "back-print-film", _("Back Print Film") }, - { "cardboard", _("Cardboard") }, - { "cardstock", _("Cardstock") }, - { "cd", _("CD") }, - { "com.hp.advanced-photo", _("Advanced Photo Paper") }, /* HP */ - { "com.hp.brochure-glossy", _("Glossy Brochure Paper") }, /* HP */ - { "com.hp.brochure-matte", _("Matte Brochure Paper") }, /* HP */ - { "com.hp.cover-matte", _("Matte Cover Paper") }, /* HP */ - { "com.hp.ecosmart-lite", _("Office Recycled Paper") }, /* HP */ - { "com.hp.everyday-glossy", _("Everyday Glossy Photo Paper") }, /* HP */ - { "com.hp.everyday-matte", _("Everyday Matte Paper") }, /* HP */ - { "com.hp.extra-heavy", _("Extra Heavyweight Paper") }, /* HP */ - { "com.hp.intermediate", _("Multipurpose Paper") }, /* HP */ - { "com.hp.mid-weight", _("Mid-Weight Paper") }, /* HP */ - { "com.hp.premium-inkjet", _("Premium Inkjet Paper") }, /* HP */ - { "com.hp.premium-photo", _("Premium Photo Glossy Paper") }, /* HP */ - { "com.hp.premium-presentation-matte", _("Premium Presentation Matte Paper") }, /* HP */ - { "continuous", _("Continuous") }, - { "continuous-long", _("Continuous Long") }, - { "continuous-short", _("Continuous Short") }, - { "disc", _("Optical Disc") }, - { "disc-glossy", _("Glossy Optical Disc") }, - { "disc-high-gloss", _("High Gloss Optical Disc") }, - { "disc-matte", _("Matte Optical Disc") }, - { "disc-satin", _("Satin Optical Disc") }, - { "disc-semi-gloss", _("Semi-Gloss Optical Disc") }, - { "double-wall", _("Double Wall Cardboard") }, - { "dry-film", _("Dry Film") }, - { "dvd", _("DVD") }, - { "embossing-foil", _("Embossing Foil") }, - { "end-board", _("End Board") }, - { "envelope", _("Envelope") }, - { "envelope-archival", _("Archival Envelope") }, - { "envelope-bond", _("Bond Envelope") }, - { "envelope-coated", _("Coated Envelope") }, - { "envelope-cotton", _("Cotton Envelope") }, - { "envelope-fine", _("Fine Envelope") }, - { "envelope-heavyweight", _("Heavyweight Envelope") }, - { "envelope-inkjet", _("Inkjet Envelope") }, - { "envelope-lightweight", _("Lightweight Envelope") }, - { "envelope-plain", _("Plain Envelope") }, - { "envelope-preprinted", _("Preprinted Envelope") }, - { "envelope-window", _("Windowed Envelope") }, - { "fabric", _("Fabric") }, - { "fabric-archival", _("Archival Fabric") }, - { "fabric-glossy", _("Glossy Fabric") }, - { "fabric-high-gloss", _("High Gloss Fabric") }, - { "fabric-matte", _("Matte Fabric") }, - { "fabric-semi-gloss", _("Semi-Gloss Fabric") }, - { "fabric-waterproof", _("Waterproof Fabric") }, - { "film", _("Film") }, - { "flexo-base", _("Flexo Base") }, - { "flexo-photo-polymer", _("Flexo Photo Polymer") }, - { "flute", _("Flute") }, - { "foil", _("Foil") }, - { "full-cut-tabs", _("Full Cut Tabs") }, - { "glass", _("Glass") }, - { "glass-colored", _("Glass Colored") }, - { "glass-opaque", _("Glass Opaque") }, - { "glass-surfaced", _("Glass Surfaced") }, - { "glass-textured", _("Glass Textured") }, - { "gravure-cylinder", _("Gravure Cylinder") }, - { "image-setter-paper", _("Image Setter Paper") }, - { "imaging-cylinder", _("Imaging Cylinder") }, - { "jp.co.canon_photo-paper-plus-glossy-ii", _("Photo Paper Plus Glossy II") }, /* Canon */ - { "jp.co.canon_photo-paper-pro-platinum", _("Photo Paper Pro Platinum") }, /* Canon */ - { "jp.co.canon-photo-paper-plus-glossy-ii", _("Photo Paper Plus Glossy II") }, /* Canon */ - { "jp.co.canon-photo-paper-pro-platinum", _("Photo Paper Pro Platinum") }, /* Canon */ - { "labels", _("Labels") }, - { "labels-colored", _("Colored Labels") }, - { "labels-glossy", _("Glossy Labels") }, - { "labels-high-gloss", _("High Gloss Labels") }, - { "labels-inkjet", _("Inkjet Labels") }, - { "labels-matte", _("Matte Labels") }, - { "labels-permanent", _("Permanent Labels") }, - { "labels-satin", _("Satin Labels") }, - { "labels-security", _("Security Labels") }, - { "labels-semi-gloss", _("Semi-Gloss Labels") }, - { "laminating-foil", _("Laminating Foil") }, - { "letterhead", _("Letterhead") }, - { "metal", _("Metal") }, - { "metal-glossy", _("Metal Glossy") }, - { "metal-high-gloss", _("Metal High Gloss") }, - { "metal-matte", _("Metal Matte") }, - { "metal-satin", _("Metal Satin") }, - { "metal-semi-gloss", _("Metal Semi Gloss") }, - { "mounting-tape", _("Mounting Tape") }, - { "multi-layer", _("Multi Layer") }, - { "multi-part-form", _("Multi Part Form") }, - { "other", _("Other") }, - { "paper", _("Paper") }, - { "photo", _("Photo Paper") }, /* HP mis-spelling */ - { "photographic", _("Photo Paper") }, - { "photographic-archival", _("Archival Photo Paper") }, - { "photographic-film", _("Photo Film") }, - { "photographic-glossy", _("Glossy Photo Paper") }, - { "photographic-high-gloss", _("High Gloss Photo Paper") }, - { "photographic-matte", _("Matte Photo Paper") }, - { "photographic-satin", _("Satin Photo Paper") }, - { "photographic-semi-gloss", _("Semi-Gloss Photo Paper") }, - { "plastic", _("Plastic") }, - { "plastic-archival", _("Plastic Archival") }, - { "plastic-colored", _("Plastic Colored") }, - { "plastic-glossy", _("Plastic Glossy") }, - { "plastic-high-gloss", _("Plastic High Gloss") }, - { "plastic-matte", _("Plastic Matte") }, - { "plastic-satin", _("Plastic Satin") }, - { "plastic-semi-gloss", _("Plastic Semi Gloss") }, - { "plate", _("Plate") }, - { "polyester", _("Polyester") }, - { "pre-cut-tabs", _("Pre Cut Tabs") }, - { "roll", _("Roll") }, - { "screen", _("Screen") }, - { "screen-paged", _("Screen Paged") }, - { "self-adhesive", _("Self Adhesive") }, - { "self-adhesive-film", _("Self Adhesive Film") }, - { "shrink-foil", _("Shrink Foil") }, - { "single-face", _("Single Face") }, - { "single-wall", _("Single Wall Cardboard") }, - { "sleeve", _("Sleeve") }, - { "stationery", _("Plain Paper") }, - { "stationery-archival", _("Archival Paper") }, - { "stationery-coated", _("Coated Paper") }, - { "stationery-cotton", _("Cotton Paper") }, - { "stationery-fine", _("Vellum Paper") }, - { "stationery-heavyweight", _("Heavyweight Paper") }, - { "stationery-heavyweight-coated", _("Heavyweight Coated Paper") }, - { "stationery-inkjet", _("Inkjet Paper") }, - { "stationery-letterhead", _("Letterhead") }, - { "stationery-lightweight", _("Lightweight Paper") }, - { "stationery-preprinted", _("Preprinted Paper") }, - { "stationery-prepunched", _("Punched Paper") }, - { "tab-stock", _("Tab Stock") }, - { "tractor", _("Tractor") }, - { "transfer", _("Transfer") }, - { "transparency", _("Transparency") }, - { "triple-wall", _("Triple Wall Cardboard") }, - { "wet-film", _("Wet Film") } - }; - cupsFilePrintf(fp, "*OpenUI *MediaType: PickOne\n" "*OrderDependency: 10 AnySetup *MediaType\n" "*DefaultMediaType: %s\n", ppdname); for (i = 0; i < count; i ++) { - const char *keyword = ippGetString(attr, i, NULL); + keyword = ippGetString(attr, i, NULL); pwg_ppdize_name(keyword, ppdname, sizeof(ppdname)); - for (j = 0; j < (int)(sizeof(media_types) / sizeof(media_types[0])); j ++) - if (!strcmp(keyword, media_types[j][0])) - break; + snprintf(msgid, sizeof(msgid), "media-type.%s", keyword); + if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr)) + if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid) + msgstr = keyword; - if (j < (int)(sizeof(media_types) / sizeof(media_types[0]))) - cupsFilePrintf(fp, "*MediaType %s/%s: \"<>setpagedevice\"\n", ppdname, _cupsLangString(lang, media_types[j][1]), ppdname); - else - cupsFilePrintf(fp, "*MediaType %s/%s: \"<>setpagedevice\"\n", ppdname, keyword, ppdname); + cupsFilePrintf(fp, "*MediaType %s: \"<>setpagedevice\"\n", ppdname, ppdname); + cupsFilePrintf(fp, "*%s.MediaType %s/%s: \"\"\n", lang->language, ppdname, msgstr); } cupsFilePuts(fp, "*CloseUI: *MediaType\n"); } @@ -3581,70 +3734,123 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ * ColorModel... */ - if ((attr = ippFindAttribute(response, "pwg-raster-document-type-supported", IPP_TAG_KEYWORD)) == NULL) - if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) == NULL) + if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) == NULL) + if ((attr = ippFindAttribute(response, "pwg-raster-document-type-supported", IPP_TAG_KEYWORD)) == NULL) if ((attr = ippFindAttribute(response, "print-color-mode-supported", IPP_TAG_KEYWORD)) == NULL) attr = ippFindAttribute(response, "output-mode-supported", IPP_TAG_KEYWORD); if (attr) { + int wrote_color = 0; const char *default_color = NULL; /* Default */ for (i = 0, count = ippGetCount(attr); i < count; i ++) { - const char *keyword = ippGetString(attr, i, NULL); - /* Keyword for color/bit depth */ + keyword = ippGetString(attr, i, NULL); + +#define PRINTF_COLORMODEL if (!wrote_color) { cupsFilePrintf(fp, "*OpenUI *ColorModel: PickOne\n*OrderDependency: 10 AnySetup *ColorModel\n*%s.Translation ColorModel/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Color Mode"))); wrote_color = 1; } +#define PRINTF_COLOROPTION(name,text,cspace,bpp) { cupsFilePrintf(fp, "*ColorModel %s: \"<>setpagedevice\"\n", name, cspace, bpp); cupsFilePrintf(fp, "*%s.ColorModel %s/%s: \"\"\n", lang->language, name, _cupsLangString(lang, text)); } if (!strcasecmp(keyword, "black_1") || !strcmp(keyword, "bi-level") || !strcmp(keyword, "process-bi-level")) { - if (!default_color) - cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n" - "*OrderDependency: 10 AnySetup *ColorModel\n", _cupsLangString(lang, _("Color Mode"))); + PRINTF_COLORMODEL - cupsFilePrintf(fp, "*ColorModel FastGray/%s: \"<>setpagedevice\"\n", _cupsLangString(lang, _("Fast Grayscale"))); + PRINTF_COLOROPTION("FastGray", _("Fast Grayscale"), CUPS_CSPACE_K, 1) - if (!default_color) + if (!default_color) default_color = "FastGray"; } else if (!strcasecmp(keyword, "sgray_8") || !strcmp(keyword, "W8") || !strcmp(keyword, "monochrome") || !strcmp(keyword, "process-monochrome")) { - if (!default_color) - cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n" - "*OrderDependency: 10 AnySetup *ColorModel\n", _cupsLangString(lang, _("Color Mode"))); + PRINTF_COLORMODEL - cupsFilePrintf(fp, "*ColorModel Gray/%s: \"<>setpagedevice\"\n", _cupsLangString(lang, _("Grayscale"))); + PRINTF_COLOROPTION("Gray", _("Grayscale"), CUPS_CSPACE_SW, 8) - if (!default_color || !strcmp(default_color, "FastGray")) + if (!default_color || !strcmp(default_color, "FastGray")) default_color = "Gray"; } - else if (!strcasecmp(keyword, "srgb_8") || !strcmp(keyword, "SRGB24") || !strcmp(keyword, "color")) + else if (!strcasecmp(keyword, "sgray_16") || !strcmp(keyword, "W8-16")) { - if (!default_color) - cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n" - "*OrderDependency: 10 AnySetup *ColorModel\n", _cupsLangString(lang, _("Color Mode"))); + PRINTF_COLORMODEL - cupsFilePrintf(fp, "*ColorModel RGB/%s: \"<>setpagedevice\"\n", _cupsLangString(lang, _("Color"))); + if (!strcmp(keyword, "W8-16")) + { + PRINTF_COLOROPTION("Gray", _("Grayscale"), CUPS_CSPACE_SW, 8) + + if (!default_color || !strcmp(default_color, "FastGray")) + default_color = "Gray"; + } + + PRINTF_COLOROPTION("Gray16", _("Deep Gray"), CUPS_CSPACE_SW, 16) + } + else if (!strcasecmp(keyword, "srgb_8") || !strncmp(keyword, "SRGB24", 7) || !strcmp(keyword, "color")) + { + PRINTF_COLORMODEL + + PRINTF_COLOROPTION("RGB", _("Color"), CUPS_CSPACE_SRGB, 8) default_color = "RGB"; } - else if (!strcasecmp(keyword, "adobe-rgb_16") || !strcmp(keyword, "ADOBERGB48")) + else if (!strcasecmp(keyword, "adobe-rgb_16") || !strcmp(keyword, "ADOBERGB48") || !strcmp(keyword, "ADOBERGB24-48")) { - if (!default_color) - cupsFilePrintf(fp, "*OpenUI *ColorModel/%s: PickOne\n" - "*OrderDependency: 10 AnySetup *ColorModel\n", _cupsLangString(lang, _("Color Mode"))); + PRINTF_COLORMODEL - cupsFilePrintf(fp, "*ColorModel AdobeRGB/%s: \"<>setpagedevice\"\n", _cupsLangString(lang, _("Deep Color"))); + PRINTF_COLOROPTION("AdobeRGB", _("Deep Color"), CUPS_CSPACE_ADOBERGB, 16) - if (!default_color) + if (!default_color) default_color = "AdobeRGB"; } + else if ((!strcasecmp(keyword, "adobe-rgb_8") && !ippContainsString(attr, "adobe-rgb_16")) || !strcmp(keyword, "ADOBERGB24")) + { + PRINTF_COLORMODEL + + PRINTF_COLOROPTION("AdobeRGB", _("Deep Color"), CUPS_CSPACE_ADOBERGB, 8) + + if (!default_color) + default_color = "AdobeRGB"; + } + else if ((!strcasecmp(keyword, "black_8") && !ippContainsString(attr, "black_16")) || !strcmp(keyword, "DEVW8")) + { + PRINTF_COLORMODEL + + PRINTF_COLOROPTION("DeviceGray", _("Device Gray"), CUPS_CSPACE_W, 8) + } + else if (!strcasecmp(keyword, "black_16") || !strcmp(keyword, "DEVW16") || !strcmp(keyword, "DEVW8-16")) + { + PRINTF_COLORMODEL + + PRINTF_COLOROPTION("DeviceGray", _("Device Gray"), CUPS_CSPACE_W, 16) + } + else if ((!strcasecmp(keyword, "cmyk_8") && !ippContainsString(attr, "cmyk_16")) || !strcmp(keyword, "DEVCMYK32")) + { + PRINTF_COLORMODEL + + PRINTF_COLOROPTION("CMYK", _("Device CMYK"), CUPS_CSPACE_CMYK, 8) + } + else if (!strcasecmp(keyword, "cmyk_16") || !strcmp(keyword, "DEVCMYK32-64") || !strcmp(keyword, "DEVCMYK64")) + { + PRINTF_COLORMODEL + + PRINTF_COLOROPTION("CMYK", _("Device CMYK"), CUPS_CSPACE_CMYK, 16) + } + else if ((!strcasecmp(keyword, "rgb_8") && ippContainsString(attr, "rgb_16")) || !strcmp(keyword, "DEVRGB24")) + { + PRINTF_COLORMODEL + + PRINTF_COLOROPTION("DeviceRGB", _("Device RGB"), CUPS_CSPACE_RGB, 8) + } + else if (!strcasecmp(keyword, "rgb_16") || !strcmp(keyword, "DEVRGB24-48") || !strcmp(keyword, "DEVRGB48")) + { + PRINTF_COLORMODEL + + PRINTF_COLOROPTION("DeviceRGB", _("Device RGB"), CUPS_CSPACE_RGB, 16) + } } if (default_color) - { cupsFilePrintf(fp, "*DefaultColorModel: %s\n", default_color); + if (wrote_color) cupsFilePuts(fp, "*CloseUI: *ColorModel\n"); - } } /* @@ -3653,18 +3859,50 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ if ((attr = ippFindAttribute(response, "sides-supported", IPP_TAG_KEYWORD)) != NULL && ippContainsString(attr, "two-sided-long-edge")) { - cupsFilePrintf(fp, "*OpenUI *Duplex/%s: PickOne\n" + cupsFilePrintf(fp, "*OpenUI *Duplex: PickOne\n" "*OrderDependency: 10 AnySetup *Duplex\n" + "*%s.Translation Duplex/%s: \"\"\n" "*DefaultDuplex: None\n" - "*Duplex None/%s: \"<>setpagedevice\"\n" - "*Duplex DuplexNoTumble/%s: \"<>setpagedevice\"\n" - "*Duplex DuplexTumble/%s: \"<>setpagedevice\"\n" - "*CloseUI: *Duplex\n", _cupsLangString(lang, _("2-Sided Printing")), _cupsLangString(lang, _("Off (1-Sided)")), _cupsLangString(lang, _("Long-Edge (Portrait)")), _cupsLangString(lang, _("Short-Edge (Landscape)"))); + "*Duplex None: \"<>setpagedevice\"\n" + "*%s.Duplex None/%s: \"\"\n" + "*Duplex DuplexNoTumble: \"<>setpagedevice\"\n" + "*%s.Duplex DuplexNoTumble/%s: \"\"\n" + "*Duplex DuplexTumble: \"<>setpagedevice\"\n" + "*%s.Duplex DuplexTumble/%s: \"\"\n" + "*CloseUI: *Duplex\n", lang->language, _cupsLangString(lang, _("2-Sided Printing")), lang->language, _cupsLangString(lang, _("Off (1-Sided)")), lang->language, _cupsLangString(lang, _("Long-Edge (Portrait)")), lang->language, _cupsLangString(lang, _("Short-Edge (Landscape)"))); - if ((attr = ippFindAttribute(response, "pwg-raster-document-sheet-back", IPP_TAG_KEYWORD)) != NULL) + if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL) { - const char *keyword = ippGetString(attr, 0, NULL); - /* Keyword value */ + for (i = 0, count = ippGetCount(attr); i < count; i ++) + { + const char *dm = ippGetString(attr, i, NULL); + /* DM value */ + + if (!_cups_strcasecmp(dm, "DM1")) + { + cupsFilePuts(fp, "*cupsBackSide: Normal\n"); + break; + } + else if (!_cups_strcasecmp(dm, "DM2")) + { + cupsFilePuts(fp, "*cupsBackSide: Flipped\n"); + break; + } + else if (!_cups_strcasecmp(dm, "DM3")) + { + cupsFilePuts(fp, "*cupsBackSide: Rotated\n"); + break; + } + else if (!_cups_strcasecmp(dm, "DM4")) + { + cupsFilePuts(fp, "*cupsBackSide: ManualTumble\n"); + break; + } + } + } + else if ((attr = ippFindAttribute(response, "pwg-raster-document-sheet-back", IPP_TAG_KEYWORD)) != NULL) + { + keyword = ippGetString(attr, 0, NULL); if (!strcmp(keyword, "flipped")) cupsFilePuts(fp, "*cupsBackSide: Flipped\n"); @@ -3675,35 +3913,6 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ else cupsFilePuts(fp, "*cupsBackSide: Rotated\n"); } - else if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL) - { - for (i = 0, count = ippGetCount(attr); i < count; i ++) - { - const char *dm = ippGetString(attr, i, NULL); - /* DM value */ - - if (!_cups_strcasecmp(dm, "DM1")) - { - cupsFilePuts(fp, "*cupsBackSide: Normal\n"); - break; - } - else if (!_cups_strcasecmp(dm, "DM2")) - { - cupsFilePuts(fp, "*cupsBackSide: Flipped\n"); - break; - } - else if (!_cups_strcasecmp(dm, "DM3")) - { - cupsFilePuts(fp, "*cupsBackSide: Rotated\n"); - break; - } - else if (!_cups_strcasecmp(dm, "DM4")) - { - cupsFilePuts(fp, "*cupsBackSide: ManualTumble\n"); - break; - } - } - } } /* @@ -3717,85 +3926,68 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ if ((attr = ippFindAttribute(response, "output-bin-supported", IPP_TAG_ZERO)) != NULL && (count = ippGetCount(attr)) > 1) { - static const char * const output_bins[][2] = - { /* "output-bin" strings */ - { "auto", _("Automatic") }, - { "bottom", _("Bottom Tray") }, - { "center", _("Center Tray") }, - { "face-down", _("Face Down") }, - { "face-up", _("Face Up") }, - { "large-capacity", _("Large Capacity Tray") }, - { "left", _("Left Tray") }, - { "mailbox-1", _("Mailbox 1") }, - { "mailbox-2", _("Mailbox 2") }, - { "mailbox-3", _("Mailbox 3") }, - { "mailbox-4", _("Mailbox 4") }, - { "mailbox-5", _("Mailbox 5") }, - { "mailbox-6", _("Mailbox 6") }, - { "mailbox-7", _("Mailbox 7") }, - { "mailbox-8", _("Mailbox 8") }, - { "mailbox-9", _("Mailbox 9") }, - { "mailbox-10", _("Mailbox 10") }, - { "middle", _("Middle") }, - { "my-mailbox", _("My Mailbox") }, - { "rear", _("Rear Tray") }, - { "right", _("Right Tray") }, - { "side", _("Side Tray") }, - { "stacker-1", _("Stacker 1") }, - { "stacker-2", _("Stacker 2") }, - { "stacker-3", _("Stacker 3") }, - { "stacker-4", _("Stacker 4") }, - { "stacker-5", _("Stacker 5") }, - { "stacker-6", _("Stacker 6") }, - { "stacker-7", _("Stacker 7") }, - { "stacker-8", _("Stacker 8") }, - { "stacker-9", _("Stacker 9") }, - { "stacker-10", _("Stacker 10") }, - { "top", _("Top Tray") }, - { "tray-1", _("Tray 1") }, - { "tray-2", _("Tray 2") }, - { "tray-3", _("Tray 3") }, - { "tray-4", _("Tray 4") }, - { "tray-5", _("Tray 5") }, - { "tray-6", _("Tray 6") }, - { "tray-7", _("Tray 7") }, - { "tray-8", _("Tray 8") }, - { "tray-9", _("Tray 9") }, - { "tray-10", _("Tray 10") } - }; + ipp_attribute_t *trays = ippFindAttribute(response, "printer-output-tray", IPP_TAG_STRING); + /* printer-output-tray attribute, if any */ + const char *tray_ptr; /* printer-output-tray value */ + int tray_len; /* Len of printer-output-tray value */ + char tray[IPP_MAX_OCTETSTRING]; + /* printer-output-tray string value */ cupsFilePrintf(fp, "*OpenUI *OutputBin: PickOne\n" "*OrderDependency: 10 AnySetup *OutputBin\n" "*DefaultOutputBin: %s\n", ppdname); - for (i = 0; i < (int)(sizeof(output_bins) / sizeof(output_bins[0])); i ++) + if (!strcmp(ppdname, "FaceUp")) + cupsFilePuts(fp, "*DefaultOutputOrder: Reverse\n"); + else + cupsFilePuts(fp, "*DefaultOutputOrder: Normal\n"); + + for (i = 0; i < count; i ++) { - if (!ippContainsString(attr, output_bins[i][0])) - continue; + keyword = ippGetString(attr, i, NULL); - pwg_ppdize_name(output_bins[i][0], ppdname, sizeof(ppdname)); + pwg_ppdize_name(keyword, ppdname, sizeof(ppdname)); - cupsFilePrintf(fp, "*OutputBin %s/%s: \"\"\n", ppdname, _cupsLangString(lang, output_bins[i][1])); + snprintf(msgid, sizeof(msgid), "output-bin.%s", keyword); + if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr)) + if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid) + msgstr = keyword; + + cupsFilePrintf(fp, "*OutputBin %s: \"\"\n", ppdname); + cupsFilePrintf(fp, "*%s.OutputBin %s/%s: \"\"\n", lang->language, ppdname, msgstr); + + if ((tray_ptr = ippGetOctetString(trays, i, &tray_len)) != NULL) + { + if (tray_len >= (int)sizeof(tray)) + tray_len = (int)sizeof(tray) - 1; + + memcpy(tray, tray_ptr, (size_t)tray_len); + tray[tray_len] = '\0'; + + if (strstr(tray, "stackingorder=lastToFirst;")) + cupsFilePrintf(fp, "*PageStackOrder %s: Reverse\n", ppdname); + else + cupsFilePrintf(fp, "*PageStackOrder %s: Normal\n", ppdname); + } + else if (!strcmp(ppdname, "FaceUp")) + cupsFilePrintf(fp, "*PageStackOrder %s: Reverse\n", ppdname); + else + cupsFilePrintf(fp, "*PageStackOrder %s: Normal\n", ppdname); } cupsFilePuts(fp, "*CloseUI: *OutputBin\n"); } /* * Finishing options... - * - * Eventually need to re-add support for finishings-col-database, however - * it is difficult to map arbitrary finishing-template values to PPD options - * and have the right constraints apply (e.g. stapling vs. folding vs. - * punching, etc.) */ if ((attr = ippFindAttribute(response, "finishings-supported", IPP_TAG_ENUM)) != NULL) { - const char *name; /* String name */ int value; /* Enum value */ cups_array_t *names; /* Names we've added */ - count = ippGetCount(attr); - names = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free); + count = ippGetCount(attr); + names = cupsArrayNew3((cups_array_func_t)strcmp, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free); + fin_options = cupsArrayNew((cups_array_func_t)strcmp, NULL); /* * Staple/Bind/Stitch @@ -3803,42 +3995,45 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ for (i = 0; i < count; i ++) { - value = ippGetInteger(attr, i); - name = ippEnumString("finishings", value); + value = ippGetInteger(attr, i); + keyword = ippEnumString("finishings", value); - if (!strncmp(name, "staple-", 7) || !strncmp(name, "bind-", 5) || !strncmp(name, "edge-stitch-", 12) || !strcmp(name, "saddle-stitch")) + if (!strncmp(keyword, "staple-", 7) || !strncmp(keyword, "bind-", 5) || !strncmp(keyword, "edge-stitch-", 12) || !strcmp(keyword, "saddle-stitch")) break; } if (i < count) { - cupsFilePrintf(fp, "*OpenUI *StapleLocation/%s: PickOne\n", _cupsLangString(lang, _("Staple"))); + cupsArrayAdd(fin_options, "*StapleLocation"); + + cupsFilePuts(fp, "*OpenUI *StapleLocation: PickOne\n"); cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *StapleLocation\n"); + cupsFilePrintf(fp, "*%s.Translation StapleLocation/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Staple"))); cupsFilePuts(fp, "*DefaultStapleLocation: None\n"); - cupsFilePrintf(fp, "*StapleLocation None/%s: \"\"\n", _cupsLangString(lang, _("None"))); + cupsFilePuts(fp, "*StapleLocation None: \"\"\n"); + cupsFilePrintf(fp, "*%s.StapleLocation None/%s: \"\"\n", lang->language, _cupsLangString(lang, _("None"))); for (; i < count; i ++) { - value = ippGetInteger(attr, i); - name = ippEnumString("finishings", value); + value = ippGetInteger(attr, i); + keyword = ippEnumString("finishings", value); - if (strncmp(name, "staple-", 7) && strncmp(name, "bind-", 5) && strncmp(name, "edge-stitch-", 12) && strcmp(name, "saddle-stitch")) + if (strncmp(keyword, "staple-", 7) && strncmp(keyword, "bind-", 5) && strncmp(keyword, "edge-stitch-", 12) && strcmp(keyword, "saddle-stitch")) continue; - if (cupsArrayFind(names, (char *)name)) + if (cupsArrayFind(names, (char *)keyword)) continue; /* Already did this finishing template */ - cupsArrayAdd(names, (char *)name); + cupsArrayAdd(names, (char *)keyword); - for (j = 0; j < (int)(sizeof(finishings) / sizeof(finishings[0])); j ++) - { - if (!strcmp(finishings[j][0], name)) - { - cupsFilePrintf(fp, "*StapleLocation %s/%s: \"\"\n", name, _cupsLangString(lang, finishings[j][1])); - cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*StapleLocation %s\"\n", value, name, name); - break; - } - } + snprintf(msgid, sizeof(msgid), "finishings.%d", value); + if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr)) + if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid) + msgstr = keyword; + + cupsFilePrintf(fp, "*StapleLocation %s: \"\"\n", keyword); + cupsFilePrintf(fp, "*%s.StapleLocation %s/%s: \"\"\n", lang->language, keyword, msgstr); + cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*StapleLocation %s\"\n", value, keyword, keyword); } cupsFilePuts(fp, "*CloseUI: *StapleLocation\n"); @@ -3850,42 +4045,45 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ for (i = 0; i < count; i ++) { - value = ippGetInteger(attr, i); - name = ippEnumString("finishings", value); + value = ippGetInteger(attr, i); + keyword = ippEnumString("finishings", value); - if (!strncmp(name, "fold-", 5)) + if (!strncmp(keyword, "fold-", 5)) break; } if (i < count) { - cupsFilePrintf(fp, "*OpenUI *FoldType/%s: PickOne\n", _cupsLangString(lang, _("Fold"))); + cupsArrayAdd(fin_options, "*FoldType"); + + cupsFilePuts(fp, "*OpenUI *FoldType: PickOne\n"); cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *FoldType\n"); + cupsFilePrintf(fp, "*%s.Translation FoldType/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Fold"))); cupsFilePuts(fp, "*DefaultFoldType: None\n"); - cupsFilePrintf(fp, "*FoldType None/%s: \"\"\n", _cupsLangString(lang, _("None"))); + cupsFilePuts(fp, "*FoldType None: \"\"\n"); + cupsFilePrintf(fp, "*%s.FoldType None/%s: \"\"\n", lang->language, _cupsLangString(lang, _("None"))); for (; i < count; i ++) { - value = ippGetInteger(attr, i); - name = ippEnumString("finishings", value); + value = ippGetInteger(attr, i); + keyword = ippEnumString("finishings", value); - if (strncmp(name, "fold-", 5)) + if (strncmp(keyword, "fold-", 5)) continue; - if (cupsArrayFind(names, (char *)name)) + if (cupsArrayFind(names, (char *)keyword)) continue; /* Already did this finishing template */ - cupsArrayAdd(names, (char *)name); + cupsArrayAdd(names, (char *)keyword); - for (j = 0; j < (int)(sizeof(finishings) / sizeof(finishings[0])); j ++) - { - if (!strcmp(finishings[j][0], name)) - { - cupsFilePrintf(fp, "*FoldType %s/%s: \"\"\n", name, _cupsLangString(lang, finishings[j][1])); - cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*FoldType %s\"\n", value, name, name); - break; - } - } + snprintf(msgid, sizeof(msgid), "finishings.%d", value); + if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr)) + if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid) + msgstr = keyword; + + cupsFilePrintf(fp, "*FoldType %s: \"\"\n", keyword); + cupsFilePrintf(fp, "*%s.FoldType %s/%s: \"\"\n", lang->language, keyword, msgstr); + cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*FoldType %s\"\n", value, keyword, keyword); } cupsFilePuts(fp, "*CloseUI: *FoldType\n"); @@ -3897,42 +4095,45 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ for (i = 0; i < count; i ++) { - value = ippGetInteger(attr, i); - name = ippEnumString("finishings", value); + value = ippGetInteger(attr, i); + keyword = ippEnumString("finishings", value); - if (!strncmp(name, "punch-", 6)) + if (!strncmp(keyword, "punch-", 6)) break; } if (i < count) { - cupsFilePrintf(fp, "*OpenUI *PunchMedia/%s: PickOne\n", _cupsLangString(lang, _("Punch"))); + cupsArrayAdd(fin_options, "*PunchMedia"); + + cupsFilePuts(fp, "*OpenUI *PunchMedia: PickOne\n"); cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *PunchMedia\n"); + cupsFilePrintf(fp, "*%s.Translation PunchMedia/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Punch"))); cupsFilePuts(fp, "*DefaultPunchMedia: None\n"); - cupsFilePrintf(fp, "*PunchMedia None/%s: \"\"\n", _cupsLangString(lang, _("None"))); + cupsFilePuts(fp, "*PunchMedia None: \"\"\n"); + cupsFilePrintf(fp, "*%s.PunchMedia None/%s: \"\"\n", lang->language, _cupsLangString(lang, _("None"))); for (i = 0; i < count; i ++) { - value = ippGetInteger(attr, i); - name = ippEnumString("finishings", value); + value = ippGetInteger(attr, i); + keyword = ippEnumString("finishings", value); - if (strncmp(name, "punch-", 6)) + if (strncmp(keyword, "punch-", 6)) continue; - if (cupsArrayFind(names, (char *)name)) + if (cupsArrayFind(names, (char *)keyword)) continue; /* Already did this finishing template */ - cupsArrayAdd(names, (char *)name); + cupsArrayAdd(names, (char *)keyword); - for (j = 0; j < (int)(sizeof(finishings) / sizeof(finishings[0])); j ++) - { - if (!strcmp(finishings[j][0], name)) - { - cupsFilePrintf(fp, "*PunchMedia %s/%s: \"\"\n", name, _cupsLangString(lang, finishings[j][1])); - cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*PunchMedia %s\"\n", value, name, name); - break; - } - } + snprintf(msgid, sizeof(msgid), "finishings.%d", value); + if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr)) + if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid) + msgstr = keyword; + + cupsFilePrintf(fp, "*PunchMedia %s: \"\"\n", keyword); + cupsFilePrintf(fp, "*%s.PunchMedia %s/%s: \"\"\n", lang->language, keyword, msgstr); + cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*PunchMedia %s\"\n", value, keyword, keyword); } cupsFilePuts(fp, "*CloseUI: *PunchMedia\n"); @@ -3944,8 +4145,11 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ if (ippContainsInteger(attr, IPP_FINISHINGS_BOOKLET_MAKER)) { - cupsFilePrintf(fp, "*OpenUI *Booklet/%s: Boolean\n", _cupsLangString(lang, _("Booklet"))); + cupsArrayAdd(fin_options, "*Booklet"); + + cupsFilePuts(fp, "*OpenUI *Booklet: Boolean\n"); cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *Booklet\n"); + cupsFilePrintf(fp, "*%s.Translation Booklet/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Booklet"))); cupsFilePuts(fp, "*DefaultBooklet: False\n"); cupsFilePuts(fp, "*Booklet False: \"\"\n"); cupsFilePuts(fp, "*Booklet True: \"\"\n"); @@ -3956,48 +4160,93 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ cupsArrayDelete(names); } + if ((attr = ippFindAttribute(response, "finishings-col-database", IPP_TAG_BEGIN_COLLECTION)) != NULL) + { + ipp_t *finishing_col; /* Current finishing collection */ + ipp_attribute_t *finishing_attr; /* Current finishing member attribute */ + cups_array_t *templates; /* Finishing templates */ + + cupsFilePuts(fp, "*OpenUI *cupsFinishingTemplate: PickOne\n"); + cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *cupsFinishingTemplate\n"); + cupsFilePrintf(fp, "*%s.Translation cupsFinishingTemplate/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Finishing Preset"))); + cupsFilePuts(fp, "*DefaultcupsFinishingTemplate: none\n"); + cupsFilePuts(fp, "*cupsFinishingTemplate none: \"\"\n"); + cupsFilePrintf(fp, "*%s.cupsFinishingTemplate none/%s: \"\"\n", lang->language, _cupsLangString(lang, _("None"))); + + templates = cupsArrayNew((cups_array_func_t)strcmp, NULL); + count = ippGetCount(attr); + + for (i = 0; i < count; i ++) + { + finishing_col = ippGetCollection(attr, i); + keyword = ippGetString(ippFindAttribute(finishing_col, "finishing-template", IPP_TAG_ZERO), 0, NULL); + + if (!keyword || cupsArrayFind(templates, (void *)keyword)) + continue; + + if (strncmp(keyword, "fold-", 5) && (strstr(keyword, "-bottom") || strstr(keyword, "-left") || strstr(keyword, "-right") || strstr(keyword, "-top"))) + continue; + + cupsArrayAdd(templates, (void *)keyword); + + snprintf(msgid, sizeof(msgid), "finishing-template.%s", keyword); + if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr)) + if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid) + msgstr = keyword; + + cupsFilePrintf(fp, "*cupsFinishingTemplate %s: \"\n", keyword); + for (finishing_attr = ippFirstAttribute(finishing_col); finishing_attr; finishing_attr = ippNextAttribute(finishing_col)) + { + if (ippGetValueTag(finishing_attr) == IPP_TAG_BEGIN_COLLECTION) + { + const char *name = ippGetName(finishing_attr); + /* Member attribute name */ + + if (strcmp(name, "media-size")) + cupsFilePrintf(fp, "%% %s\n", name); + } + } + cupsFilePuts(fp, "\"\n"); + cupsFilePrintf(fp, "*%s.cupsFinishingTemplate %s/%s: \"\"\n", lang->language, keyword, msgstr); + cupsFilePuts(fp, "*End\n"); + } + + cupsFilePuts(fp, "*CloseUI: *cupsFinishingTemplate\n"); + + if (cupsArrayCount(fin_options)) + { + const char *fin_option; /* Current finishing option */ + + cupsFilePuts(fp, "*cupsUIConstraint finishing-template: \"*cupsFinishingTemplate"); + for (fin_option = (const char *)cupsArrayFirst(fin_options); fin_option; fin_option = (const char *)cupsArrayNext(fin_options)) + cupsFilePrintf(fp, " %s", fin_option); + cupsFilePuts(fp, "\"\n"); + + cupsFilePuts(fp, "*cupsUIResolver finishing-template: \"*cupsFinishingTemplate None"); + for (fin_option = (const char *)cupsArrayFirst(fin_options); fin_option; fin_option = (const char *)cupsArrayNext(fin_options)) + cupsFilePrintf(fp, " %s None", fin_option); + cupsFilePuts(fp, "\"\n"); + } + + cupsArrayDelete(templates); + } + + cupsArrayDelete(fin_options); + /* * cupsPrintQuality and DefaultResolution... */ quality = ippFindAttribute(response, "print-quality-supported", IPP_TAG_ENUM); - if ((attr = ippFindAttribute(response, "pwg-raster-document-resolution-supported", IPP_TAG_RESOLUTION)) != NULL) + if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL) { - count = ippGetCount(attr); - - pwg_ppdize_resolution(attr, count / 2, &xres, &yres, ppdname, sizeof(ppdname)); - cupsFilePrintf(fp, "*DefaultResolution: %s\n", ppdname); - - cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality/%s: PickOne\n" - "*OrderDependency: 10 AnySetup *cupsPrintQuality\n" - "*DefaultcupsPrintQuality: Normal\n", _cupsLangString(lang, _("Print Quality"))); - if (count > 2 || ippContainsInteger(quality, IPP_QUALITY_DRAFT)) - { - pwg_ppdize_resolution(attr, 0, &xres, &yres, NULL, 0); - cupsFilePrintf(fp, "*cupsPrintQuality Draft/%s: \"<>setpagedevice\"\n", _cupsLangString(lang, _("Draft")), xres, yres); - } - pwg_ppdize_resolution(attr, count / 2, &xres, &yres, NULL, 0); - cupsFilePrintf(fp, "*cupsPrintQuality Normal/%s: \"<>setpagedevice\"\n", _cupsLangString(lang, _("Normal")), xres, yres); - if (count > 1 || ippContainsInteger(quality, IPP_QUALITY_HIGH)) - { - if (count > 1) - pwg_ppdize_resolution(attr, count - 1, &xres, &yres, NULL, 0); - else - pwg_ppdize_resolution(attr, 0, &xres, &yres, NULL, 0); - cupsFilePrintf(fp, "*cupsPrintQuality High/%s: \"<>setpagedevice\"\n", _cupsLangString(lang, _("High")), xres, yres); - } - - cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n"); - } - else if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL) - { - int lowdpi = 0, hidpi = 0; /* Lower and higher resolution */ + int lowdpi = 0, hidpi = 0; /* Lower and higher resolution */ for (i = 0, count = ippGetCount(attr); i < count; i ++) { const char *rs = ippGetString(attr, i, NULL); - /* RS value */ + /* RS value */ if (_cups_strncasecmp(rs, "RS", 2)) continue; @@ -4026,19 +4275,92 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ cupsFilePrintf(fp, "*DefaultResolution: %ddpi\n", lowdpi); - cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality/%s: PickOne\n" + cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality: PickOne\n" "*OrderDependency: 10 AnySetup *cupsPrintQuality\n" - "*DefaultcupsPrintQuality: Normal\n", _cupsLangString(lang, _("Print Quality"))); + "*%s.Translation cupsPrintQuality/%s: \"\"\n" + "*DefaultcupsPrintQuality: Normal\n", lang->language, _cupsLangString(lang, _("Print Quality"))); if ((lowdpi & 1) == 0) - cupsFilePrintf(fp, "*cupsPrintQuality Draft/%s: \"<>setpagedevice\"\n", _cupsLangString(lang, _("Draft")), lowdpi, lowdpi / 2); + cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<>setpagedevice\"\n*%s.cupsPrintQuality Draft/%s: \"\"\n", lowdpi, lowdpi / 2, lang->language, _cupsLangString(lang, _("Draft"))); else if (ippContainsInteger(quality, IPP_QUALITY_DRAFT)) - cupsFilePrintf(fp, "*cupsPrintQuality Draft/%s: \"<>setpagedevice\"\n", _cupsLangString(lang, _("Draft")), lowdpi, lowdpi); - cupsFilePrintf(fp, "*cupsPrintQuality Normal/%s: \"<>setpagedevice\"\n", _cupsLangString(lang, _("Normal")), lowdpi, lowdpi); + cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<>setpagedevice\"\n*%s.cupsPrintQuality Draft/%s: \"\"\n", lowdpi, lowdpi, lang->language, _cupsLangString(lang, _("Draft"))); + + cupsFilePrintf(fp, "*cupsPrintQuality Normal: \"<>setpagedevice\"\n*%s.cupsPrintQuality Normal/%s: \"\"\n", lowdpi, lowdpi, lang->language, _cupsLangString(lang, _("Normal"))); + if (hidpi > lowdpi || ippContainsInteger(quality, IPP_QUALITY_HIGH)) - cupsFilePrintf(fp, "*cupsPrintQuality High/%s: \"<>setpagedevice\"\n", _cupsLangString(lang, _("High")), hidpi, hidpi); + cupsFilePrintf(fp, "*cupsPrintQuality High: \"<>setpagedevice\"\n*%s.cupsPrintQuality High/%s: \"\"\n", hidpi, hidpi, lang->language, _cupsLangString(lang, _("High"))); cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n"); } } + else if ((attr = ippFindAttribute(response, "pwg-raster-document-resolution-supported", IPP_TAG_RESOLUTION)) != NULL) + { + /* + * Make a sorted list of resolutions. + */ + + count = ippGetCount(attr); + if (count > (int)(sizeof(resolutions) / sizeof(resolutions[0]))) + count = (int)(sizeof(resolutions) / sizeof(resolutions[0])); + + resolutions[0] = 0; /* Not in loop to silence Clang static analyzer... */ + for (i = 1; i < count; i ++) + resolutions[i] = i; + + for (i = 0; i < (count - 1); i ++) + { + for (j = i + 1; j < count; j ++) + { + int ix, iy, /* First X and Y resolution */ + jx, jy, /* Second X and Y resolution */ + temp; /* Swap variable */ + ipp_res_t units; /* Resolution units */ + + ix = ippGetResolution(attr, resolutions[i], &iy, &units); + jx = ippGetResolution(attr, resolutions[j], &jy, &units); + + if (ix > jx || (ix == jx && iy > jy)) + { + /* + * Swap these two resolutions... + */ + + temp = resolutions[i]; + resolutions[i] = resolutions[j]; + resolutions[j] = temp; + } + } + } + + /* + * Generate print quality options... + */ + + pwg_ppdize_resolution(attr, resolutions[count / 2], &xres, &yres, ppdname, sizeof(ppdname)); + cupsFilePrintf(fp, "*DefaultResolution: %s\n", ppdname); + + cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality: PickOne\n" + "*OrderDependency: 10 AnySetup *cupsPrintQuality\n" + "*%s.Translation cupsPrintQuality/%s: \"\"\n" + "*DefaultcupsPrintQuality: Normal\n", lang->language, _cupsLangString(lang, _("Print Quality"))); + if (count > 2 || ippContainsInteger(quality, IPP_QUALITY_DRAFT)) + { + pwg_ppdize_resolution(attr, resolutions[0], &xres, &yres, NULL, 0); + cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<>setpagedevice\"\n", xres, yres); + cupsFilePrintf(fp, "*%s.cupsPrintQuality Draft/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Draft"))); + } + + pwg_ppdize_resolution(attr, resolutions[count / 2], &xres, &yres, NULL, 0); + cupsFilePrintf(fp, "*cupsPrintQuality Normal: \"<>setpagedevice\"\n", xres, yres); + cupsFilePrintf(fp, "*%s.cupsPrintQuality Normal/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Normal"))); + + if (count > 1 || ippContainsInteger(quality, IPP_QUALITY_HIGH)) + { + pwg_ppdize_resolution(attr, resolutions[count - 1], &xres, &yres, NULL, 0); + cupsFilePrintf(fp, "*cupsPrintQuality High: \"<>setpagedevice\"\n", xres, yres); + cupsFilePrintf(fp, "*%s.cupsPrintQuality High/%s: \"\"\n", lang->language, _cupsLangString(lang, _("High"))); + } + + cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n"); + } else if (is_apple || is_pwg) goto bad_ppd; else @@ -4055,17 +4377,164 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ cupsFilePrintf(fp, "*DefaultResolution: %s\n", ppdname); - cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality/%s: PickOne\n" + cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality: PickOne\n" "*OrderDependency: 10 AnySetup *cupsPrintQuality\n" - "*DefaultcupsPrintQuality: Normal\n", _cupsLangString(lang, _("Print Quality"))); + "*%s.Translation cupsPrintQuality/%s: \"\"\n" + "*DefaultcupsPrintQuality: Normal\n", lang->language, _cupsLangString(lang, _("Print Quality"))); if (ippContainsInteger(quality, IPP_QUALITY_DRAFT)) - cupsFilePrintf(fp, "*cupsPrintQuality Draft/%s: \"<>setpagedevice\"\n", _cupsLangString(lang, _("Draft")), xres, yres); - cupsFilePrintf(fp, "*cupsPrintQuality Normal/%s: \"<>setpagedevice\"\n", _cupsLangString(lang, _("Normal")), xres, yres); + cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<>setpagedevice\"\n*%s.cupsPrintQuality Draft/%s: \"\"\n", xres, yres, lang->language, _cupsLangString(lang, _("Draft"))); + + cupsFilePrintf(fp, "*cupsPrintQuality Normal: \"<>setpagedevice\"\n*%s.cupsPrintQuality Normal/%s: \"\"\n", xres, yres, lang->language, _cupsLangString(lang, _("Normal"))); + if (ippContainsInteger(quality, IPP_QUALITY_HIGH)) - cupsFilePrintf(fp, "*cupsPrintQuality High/%s: \"<>setpagedevice\"\n", _cupsLangString(lang, _("High")), xres, yres); + cupsFilePrintf(fp, "*cupsPrintQuality High: \"<>setpagedevice\"\n*%s.cupsPrintQuality High/%s: \"\"\n", xres, yres, lang->language, _cupsLangString(lang, _("High"))); cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n"); } + /* + * Presets... + */ + + if ((attr = ippFindAttribute(response, "job-presets-supported", IPP_TAG_BEGIN_COLLECTION)) != NULL) + { + for (i = 0, count = ippGetCount(attr); i < count; i ++) + { + ipp_t *preset = ippGetCollection(attr, i); + /* Preset collection */ + const char *preset_name = ippGetString(ippFindAttribute(preset, "preset-name", IPP_TAG_ZERO), 0, NULL), + /* Preset name */ + *localized_name; /* Localized preset name */ + ipp_attribute_t *member; /* Member attribute in preset */ + const char *member_name; /* Member attribute name */ + char member_value[256]; /* Member attribute value */ + + if (!preset || !preset_name) + continue; + + cupsFilePrintf(fp, "*APPrinterPreset %s: \"\n", preset_name); + for (member = ippFirstAttribute(preset); member; member = ippNextAttribute(preset)) + { + member_name = ippGetName(member); + + if (!member_name || !strcmp(member_name, "preset-name")) + continue; + + if (!strcmp(member_name, "finishings")) + { + for (i = 0, count = ippGetCount(member); i < count; i ++) + { + const char *option = NULL; /* PPD option name */ + + keyword = ippEnumString("finishings", ippGetInteger(member, i)); + + if (!strcmp(keyword, "booklet-maker")) + { + option = "Booklet"; + keyword = "True"; + } + else if (!strncmp(keyword, "fold-", 5)) + option = "FoldType"; + else if (!strncmp(keyword, "punch-", 6)) + option = "PunchMedia"; + else if (!strncmp(keyword, "bind-", 5) || !strncmp(keyword, "edge-stitch-", 12) || !strcmp(keyword, "saddle-stitch") || !strncmp(keyword, "staple-", 7)) + option = "StapleLocation"; + + if (option && keyword) + cupsFilePrintf(fp, "*%s %s\n", option, keyword); + } + } + else if (!strcmp(member_name, "finishings-col")) + { + ipp_t *fin_col; /* finishings-col value */ + + for (i = 0, count = ippGetCount(member); i < count; i ++) + { + fin_col = ippGetCollection(member, i); + + if ((keyword = ippGetString(ippFindAttribute(fin_col, "finishing-template", IPP_TAG_ZERO), 0, NULL)) != NULL) + cupsFilePrintf(fp, "*cupsFinishingTemplate %s\n", keyword); + } + } + else if (!strcmp(member_name, "media")) + { + /* + * Map media to PageSize... + */ + + if ((pwg = pwgMediaForPWG(ippGetString(member, 0, NULL))) != NULL && pwg->ppd) + cupsFilePrintf(fp, "*PageSize %s\n", pwg->ppd); + } + else if (!strcmp(member_name, "media-col")) + { + media_col = ippGetCollection(member, 0); + + if ((media_size = ippGetCollection(ippFindAttribute(media_col, "media-size", IPP_TAG_BEGIN_COLLECTION), 0)) != NULL) + { + x_dim = ippFindAttribute(media_size, "x-dimension", IPP_TAG_INTEGER); + y_dim = ippFindAttribute(media_size, "y-dimension", IPP_TAG_INTEGER); + if ((pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0))) != NULL && pwg->ppd) + cupsFilePrintf(fp, "*PageSize %s\n", pwg->ppd); + } + + if ((keyword = ippGetString(ippFindAttribute(media_col, "media-source", IPP_TAG_ZERO), 0, NULL)) != NULL) + { + pwg_ppdize_name(keyword, ppdname, sizeof(ppdname)); + cupsFilePrintf(fp, "*InputSlot %s\n", keyword); + } + + if ((keyword = ippGetString(ippFindAttribute(media_col, "media-type", IPP_TAG_ZERO), 0, NULL)) != NULL) + { + pwg_ppdize_name(keyword, ppdname, sizeof(ppdname)); + cupsFilePrintf(fp, "*MediaType %s\n", keyword); + } + } + else if (!strcmp(member_name, "print-quality")) + { + /* + * Map print-quality to cupsPrintQuality... + */ + + int qval = ippGetInteger(member, 0); + /* print-quality value */ + static const char * const qualities[] = { "Draft", "Normal", "High" }; + /* cupsPrintQuality values */ + + if (qval >= IPP_QUALITY_DRAFT && qval <= IPP_QUALITY_HIGH) + cupsFilePrintf(fp, "*cupsPrintQuality %s\n", qualities[qval - IPP_QUALITY_DRAFT]); + } + else if (!strcmp(member_name, "output-bin")) + { + pwg_ppdize_name(ippGetString(member, 0, NULL), ppdname, sizeof(ppdname)); + cupsFilePrintf(fp, "*OutputBin %s\n", ppdname); + } + else if (!strcmp(member_name, "sides")) + { + keyword = ippGetString(member, 0, NULL); + if (keyword && !strcmp(keyword, "one-sided")) + cupsFilePuts(fp, "*Duplex None\n"); + else if (keyword && !strcmp(keyword, "two-sided-long-edge")) + cupsFilePuts(fp, "*Duplex DuplexNoTumble\n"); + else if (keyword && !strcmp(keyword, "two-sided-short-edge")) + cupsFilePuts(fp, "*Duplex DuplexTumble\n"); + } + else + { + /* + * Add attribute name and value as-is... + */ + + ippAttributeString(member, member_value, sizeof(member_value)); + cupsFilePrintf(fp, "*%s %s\n", member_name, member_value); + } + } + + cupsFilePuts(fp, "\"\n*End\n"); + + if ((localized_name = _cupsMessageLookup(strings, preset_name)) != preset_name) + cupsFilePrintf(fp, "*%s.APPrinterPreset %s/%s: \"\"\n", lang->language, preset_name, localized_name); + } + } + /* * Close up and return... */ @@ -4192,9 +4661,9 @@ _pwgMediaTypeForType( const char * /* O - PageSize name */ _pwgPageSizeForMedia( - pwg_media_t *media, /* I - Media */ - char *name, /* I - PageSize name buffer */ - size_t namesize) /* I - Size of name buffer */ + pwg_media_t *media, /* I - Media */ + char *name, /* I - PageSize name buffer */ + size_t namesize) /* I - Size of name buffer */ { const char *sizeptr, /* Pointer to size in PWG name */ *dimptr; /* Pointer to dimensions in PWG name */ @@ -4245,6 +4714,62 @@ _pwgPageSizeForMedia( } +/* + * 'cups_get_url()' - Get a copy of the file at the given URL. + */ + +static int /* O - 1 on success, 0 on failure */ +cups_get_url(http_t **http, /* IO - Current HTTP connection */ + const char *url, /* I - URL to get */ + char *name, /* I - Temporary filename */ + size_t namesize) /* I - Size of temporary filename buffer */ +{ + char scheme[32], /* URL scheme */ + userpass[256], /* URL username:password */ + host[256], /* URL host */ + curhost[256], /* Current host */ + resource[256]; /* URL resource */ + int port; /* URL port */ + http_encryption_t encryption; /* Type of encryption to use */ + http_status_t status; /* Status of GET request */ + int fd; /* Temporary file */ + + + if (httpSeparateURI(HTTP_URI_CODING_ALL, url, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK) + return (0); + + if (port == 443 || !strcmp(scheme, "https")) + encryption = HTTP_ENCRYPTION_ALWAYS; + else + encryption = HTTP_ENCRYPTION_IF_REQUESTED; + + if (!*http || strcasecmp(host, httpGetHostname(*http, curhost, sizeof(curhost))) || httpAddrPort(httpGetAddress(*http)) != port) + { + httpClose(*http); + *http = httpConnect2(host, port, NULL, AF_UNSPEC, encryption, 1, 5000, NULL); + } + + if (!*http) + return (0); + + if ((fd = cupsTempFd(name, (int)namesize)) < 0) + return (0); + + status = cupsGetFd(*http, resource, fd); + + close(fd); + + if (status != HTTP_STATUS_OK) + { + unlink(name); + *name = '\0'; + return (0); + } + + return (1); +} + + /* * 'pwg_add_finishing()' - Add a finishings value. */ @@ -4269,6 +4794,27 @@ pwg_add_finishing( } +/* + * 'pwg_add_message()' - Add a message to the PPD cached strings. + */ + +static void +pwg_add_message(cups_array_t *a, /* I - Message catalog */ + const char *msg, /* I - Message identifier */ + const char *str) /* I - Localized string */ +{ + _cups_message_t *m; /* New message */ + + + if ((m = calloc(1, sizeof(_cups_message_t))) != NULL) + { + m->msg = strdup(msg); + m->str = strdup(str); + cupsArrayAdd(a, m); + } +} + + /* * 'pwg_compare_finishings()' - Compare two finishings values. */ @@ -4282,6 +4828,35 @@ pwg_compare_finishings( } +/* + * 'pwg_compare_sizes()' - Compare two media sizes... + */ + +static int /* O - Result of comparison */ +pwg_compare_sizes(cups_size_t *a, /* I - First media size */ + cups_size_t *b) /* I - Second media size */ +{ + return (strcmp(a->media, b->media)); +} + + +/* + * 'pwg_copy_size()' - Copy a media size. + */ + +static cups_size_t * /* O - New media size */ +pwg_copy_size(cups_size_t *size) /* I - Media size to copy */ +{ + cups_size_t *newsize = (cups_size_t *)calloc(1, sizeof(cups_size_t)); + /* New media size */ + + if (newsize) + memcpy(newsize, size, sizeof(cups_size_t)); + + return (newsize); +} + + /* * 'pwg_free_finishings()' - Free a finishings value. */ diff --git a/cups/ppd-conflicts.c b/cups/ppd-conflicts.c index 8f875a5..ffbacad 100644 --- a/cups/ppd-conflicts.c +++ b/cups/ppd-conflicts.c @@ -1,18 +1,13 @@ /* * Option conflict management routines for CUPS. * - * Copyright 2007-2015 by Apple Inc. + * Copyright 2007-2018 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. * * PostScript is a trademark of Adobe Systems, Inc. - * - * This file is subject to the Apple OS-Developed Software exception. */ /* @@ -21,6 +16,7 @@ #include "cups-private.h" #include "ppd-private.h" +#include "debug-internal.h" /* @@ -29,7 +25,6 @@ enum { - _PPD_NORMAL_CONSTRAINTS, _PPD_OPTION_CONSTRAINTS, _PPD_INSTALLABLE_CONSTRAINTS, _PPD_ALL_CONSTRAINTS @@ -998,7 +993,7 @@ ppd_test_constraints( if (!consts->installable && which == _PPD_INSTALLABLE_CONSTRAINTS) continue; /* Skip non-installable option constraint */ - if (which == _PPD_OPTION_CONSTRAINTS && option) + if ((which == _PPD_OPTION_CONSTRAINTS || which == _PPD_INSTALLABLE_CONSTRAINTS) && option) { /* * Skip constraints that do not involve the current option... diff --git a/cups/ppd-custom.c b/cups/ppd-custom.c index b7070fa..8cdd7c8 100644 --- a/cups/ppd-custom.c +++ b/cups/ppd-custom.c @@ -4,22 +4,10 @@ * Copyright 2007-2015 by Apple Inc. * Copyright 1997-2006 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. * * PostScript is a trademark of Adobe Systems, Inc. - * - * This code and any derivative of it may be used and distributed - * freely under the terms of the GNU General Public License when - * used with GNU Ghostscript or its derivatives. Use of the code - * (or any derivative of it) with software other than GNU - * GhostScript (or its derivatives) is governed by the CUPS license - * agreement. - * - * This file is subject to the Apple OS-Developed Software exception. */ /* @@ -28,6 +16,7 @@ #include "cups-private.h" #include "ppd-private.h" +#include "debug-internal.h" /* diff --git a/cups/ppd-emit.c b/cups/ppd-emit.c index 36e5bca..8bffb2b 100644 --- a/cups/ppd-emit.c +++ b/cups/ppd-emit.c @@ -1,18 +1,13 @@ /* * PPD code emission routines for CUPS. * - * Copyright 2007-2015 by Apple Inc. + * Copyright 2007-2019 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. * * PostScript is a trademark of Adobe Systems, Inc. - * - * This file is subject to the Apple OS-Developed Software exception. */ /* @@ -20,12 +15,13 @@ */ #include "cups-private.h" +#include "debug-internal.h" #include "ppd.h" -#if defined(WIN32) || defined(__EMX__) +#if defined(_WIN32) || defined(__EMX__) # include #else # include -#endif /* WIN32 || __EMX__ */ +#endif /* _WIN32 || __EMX__ */ /* @@ -328,11 +324,11 @@ ppdEmitFd(ppd_file_t *ppd, /* I - PPD file record */ while (buflength > 0) { -#ifdef WIN32 +#ifdef _WIN32 if ((bytes = (ssize_t)write(fd, bufptr, (unsigned)buflength)) < 0) #else if ((bytes = write(fd, bufptr, buflength)) < 0) -#endif /* WIN32 */ +#endif /* _WIN32 */ { if (errno == EAGAIN || errno == EINTR) continue; @@ -445,6 +441,9 @@ ppdEmitJCL(ppd_file_t *ppd, /* I - PPD file record */ * Clean up the job title... */ + if (!title) + title = "Unknown"; + if ((ptr = strrchr(title, '/')) != NULL) { /* @@ -494,6 +493,9 @@ ppdEmitJCL(ppd_file_t *ppd, /* I - PPD file record */ * issues with some printer's PJL implementations... */ + if (!user) + user = "anonymous"; + snprintf(displaymsg, sizeof(displaymsg), "%d %s %s", job_id, user, temp); /* @@ -662,6 +664,9 @@ ppdEmitString(ppd_file_t *ppd, /* I - PPD file record */ { switch (cparam->type) { + case PPD_CUSTOM_UNKNOWN : + break; + case PPD_CUSTOM_CURVE : case PPD_CUSTOM_INVCURVE : case PPD_CUSTOM_POINTS : @@ -708,6 +713,9 @@ ppdEmitString(ppd_file_t *ppd, /* I - PPD file record */ { switch (cparam->type) { + case PPD_CUSTOM_UNKNOWN : + break; + case PPD_CUSTOM_CURVE : case PPD_CUSTOM_INVCURVE : case PPD_CUSTOM_POINTS : @@ -803,6 +811,9 @@ ppdEmitString(ppd_file_t *ppd, /* I - PPD file record */ { switch (cparam->type) { + case PPD_CUSTOM_UNKNOWN : + break; + case PPD_CUSTOM_CURVE : case PPD_CUSTOM_INVCURVE : case PPD_CUSTOM_POINTS : @@ -836,7 +847,7 @@ ppdEmitString(ppd_file_t *ppd, /* I - PPD file record */ *bufptr++ = *cptr++; } } - else + else if (choices[i]->code) { /* * Otherwise just copy the option code directly... @@ -1005,6 +1016,9 @@ ppdEmitString(ppd_file_t *ppd, /* I - PPD file record */ { switch (cparam->type) { + case PPD_CUSTOM_UNKNOWN : + break; + case PPD_CUSTOM_CURVE : case PPD_CUSTOM_INVCURVE : case PPD_CUSTOM_POINTS : @@ -1069,7 +1083,7 @@ ppdEmitString(ppd_file_t *ppd, /* I - PPD file record */ DEBUG_printf(("2ppdEmitString: Offset in string is %d...", (int)(bufptr - buffer))); } - else + else if (choices[i]->code) { strlcpy(bufptr, choices[i]->code, (size_t)(bufend - bufptr + 1)); bufptr += strlen(bufptr); diff --git a/cups/ppd-localize.c b/cups/ppd-localize.c index ed75bf8..ea84915 100644 --- a/cups/ppd-localize.c +++ b/cups/ppd-localize.c @@ -1,25 +1,13 @@ /* * PPD localization routines for CUPS. * - * Copyright 2007-2017 by Apple Inc. + * Copyright 2007-2018 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. * * PostScript is a trademark of Adobe Systems, Inc. - * - * This code and any derivative of it may be used and distributed - * freely under the terms of the GNU General Public License when - * used with GNU Ghostscript or its derivatives. Use of the code - * (or any derivative of it) with software other than GNU - * GhostScript (or its derivatives) is governed by the CUPS license - * agreement. - * - * This file is subject to the Apple OS-Developed Software exception. */ /* @@ -28,6 +16,7 @@ #include "cups-private.h" #include "ppd-private.h" +#include "debug-internal.h" /* @@ -277,65 +266,23 @@ ppdLocalizeIPPReason( if (!locattr) { - if (lang && (!scheme || !strcmp(scheme, "text"))) + if (lang && (!scheme || !strcmp(scheme, "text")) && strcmp(reason, "none")) { /* * Try to localize a standard printer-state-reason keyword... */ + char msgid[1024], /* State message identifier */ + *ptr; /* Pointer to state suffix */ const char *message = NULL; /* Localized message */ - if (!strncmp(reason, "media-needed", 12)) - message = _("Load paper."); - else if (!strncmp(reason, "media-jam", 9)) - message = _("Paper jam."); - else if (!strncmp(reason, "offline", 7) || - !strncmp(reason, "shutdown", 8)) - message = _("The printer is not connected."); - else if (!strncmp(reason, "toner-low", 9)) - message = _("The printer is low on toner."); - else if (!strncmp(reason, "toner-empty", 11)) - message = _("The printer may be out of toner."); - else if (!strncmp(reason, "cover-open", 10)) - message = _("The printer's cover is open."); - else if (!strncmp(reason, "interlock-open", 14)) - message = _("The printer's interlock is open."); - else if (!strncmp(reason, "door-open", 9)) - message = _("The printer's door is open."); - else if (!strncmp(reason, "input-tray-missing", 18)) - message = _("Paper tray is missing."); - else if (!strncmp(reason, "media-low", 9)) - message = _("Paper tray is almost empty."); - else if (!strncmp(reason, "media-empty", 11)) - message = _("Paper tray is empty."); - else if (!strncmp(reason, "output-tray-missing", 19)) - message = _("Output bin is missing."); - else if (!strncmp(reason, "output-area-almost-full", 23)) - message = _("Output bin is almost full."); - else if (!strncmp(reason, "output-area-full", 16)) - message = _("Output bin is full."); - else if (!strncmp(reason, "marker-supply-low", 17)) - message = _("The printer is low on ink."); - else if (!strncmp(reason, "marker-supply-empty", 19)) - message = _("The printer may be out of ink."); - else if (!strncmp(reason, "marker-waste-almost-full", 24)) - message = _("The printer's waste bin is almost full."); - else if (!strncmp(reason, "marker-waste-full", 17)) - message = _("The printer's waste bin is full."); - else if (!strncmp(reason, "fuser-over-temp", 15)) - message = _("The fuser's temperature is high."); - else if (!strncmp(reason, "fuser-under-temp", 16)) - message = _("The fuser's temperature is low."); - else if (!strncmp(reason, "opc-near-eol", 12)) - message = _("The optical photoconductor will need to be replaced soon."); - else if (!strncmp(reason, "opc-life-over", 13)) - message = _("The optical photoconductor needs to be replaced."); - else if (!strncmp(reason, "developer-low", 13)) - message = _("The developer unit will need to be replaced soon."); - else if (!strncmp(reason, "developer-empty", 15)) - message = _("The developer unit needs to be replaced."); + snprintf(msgid, sizeof(msgid), "printer-state-reasons.%s", reason); + if ((ptr = strrchr(msgid, '-')) != NULL && (!strcmp(ptr, "-error") || !strcmp(ptr, "-report") || !strcmp(ptr, "-warning"))) + *ptr = '\0'; - if (message) + message = _cupsLangString(lang, msgid); + + if (message && strcmp(message, msgid)) { strlcpy(buffer, _cupsLangString(lang, message), bufsize); return (buffer); diff --git a/cups/ppd-mark.c b/cups/ppd-mark.c index 9fdaf0b..7ec0df4 100644 --- a/cups/ppd-mark.c +++ b/cups/ppd-mark.c @@ -1,18 +1,13 @@ /* * Option marking routines for CUPS. * - * Copyright 2007-2015 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. * * PostScript is a trademark of Adobe Systems, Inc. - * - * This file is subject to the Apple OS-Developed Software exception. */ /* @@ -21,6 +16,7 @@ #include "cups-private.h" #include "ppd-private.h" +#include "debug-internal.h" /* @@ -253,6 +249,7 @@ cupsMarkOptions( */ for (i = num_options, optptr = options; i > 0; i --, optptr ++) + { if (!_cups_strcasecmp(optptr->name, "media") || !_cups_strcasecmp(optptr->name, "output-bin") || !_cups_strcasecmp(optptr->name, "output-mode") || @@ -341,6 +338,19 @@ cupsMarkOptions( ppd_mark_option(ppd, "MirrorPrint", optptr->value); else ppd_mark_option(ppd, optptr->name, optptr->value); + } + + if (print_quality) + { + int pq = atoi(print_quality); /* print-quaity value */ + + if (pq == IPP_QUALITY_DRAFT) + ppd_mark_option(ppd, "cupsPrintQuality", "Draft"); + else if (pq == IPP_QUALITY_HIGH) + ppd_mark_option(ppd, "cupsPrintQuality", "High"); + else + ppd_mark_option(ppd, "cupsPrintQuality", "Normal"); + } ppd_debug_marked(ppd, "After..."); @@ -841,6 +851,9 @@ ppd_mark_option(ppd_file_t *ppd, /* I - PPD file */ switch (cparam->type) { + case PPD_CUSTOM_UNKNOWN : + break; + case PPD_CUSTOM_CURVE : case PPD_CUSTOM_INVCURVE : case PPD_CUSTOM_REAL : @@ -876,9 +889,9 @@ ppd_mark_option(ppd_file_t *ppd, /* I - PPD file */ case PPD_CUSTOM_PASSWORD : case PPD_CUSTOM_STRING : if (cparam->current.custom_string) - _cupsStrFree(cparam->current.custom_string); + free(cparam->current.custom_string); - cparam->current.custom_string = _cupsStrAlloc(choice + 7); + cparam->current.custom_string = strdup(choice + 7); break; } } @@ -918,6 +931,9 @@ ppd_mark_option(ppd_file_t *ppd, /* I - PPD file */ switch (cparam->type) { + case PPD_CUSTOM_UNKNOWN : + break; + case PPD_CUSTOM_CURVE : case PPD_CUSTOM_INVCURVE : case PPD_CUSTOM_REAL : @@ -953,9 +969,9 @@ ppd_mark_option(ppd_file_t *ppd, /* I - PPD file */ case PPD_CUSTOM_PASSWORD : case PPD_CUSTOM_STRING : if (cparam->current.custom_string) - _cupsStrFree(cparam->current.custom_string); + free(cparam->current.custom_string); - cparam->current.custom_string = _cupsStrRetain(val->value); + cparam->current.custom_string = strdup(val->value); break; } } diff --git a/cups/ppd-page.c b/cups/ppd-page.c index ccbf052..1f5860a 100644 --- a/cups/ppd-page.c +++ b/cups/ppd-page.c @@ -4,15 +4,10 @@ * Copyright 2007-2015 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. * * PostScript is a trademark of Adobe Systems, Inc. - * - * This file is subject to the Apple OS-Developed Software exception. */ /* @@ -20,7 +15,7 @@ */ #include "string-private.h" -#include "debug-private.h" +#include "debug-internal.h" #include "ppd.h" diff --git a/cups/ppd-private.h b/cups/ppd-private.h index b199bbd..7b406c9 100644 --- a/cups/ppd-private.h +++ b/cups/ppd-private.h @@ -1,25 +1,13 @@ /* * Private PPD definitions for CUPS. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. * * PostScript is a trademark of Adobe Systems, Inc. - * - * This code and any derivative of it may be used and distributed - * freely under the terms of the GNU General Public License when - * used with GNU Ghostscript or its derivatives. Use of the code - * (or any derivative of it) with software other than GNU - * GhostScript (or its derivatives) is governed by the CUPS license - * agreement. - * - * This file is subject to the Apple OS-Developed Software exception. */ #ifndef _CUPS_PPD_PRIVATE_H_ @@ -47,7 +35,7 @@ extern "C" { * Constants... */ -# define _PPD_CACHE_VERSION 8 /* Version number in cache file */ +# define _PPD_CACHE_VERSION 9 /* Version number in cache file */ /* @@ -151,12 +139,14 @@ struct _ppd_cache_s /**** PPD cache and PWG conversion data ****/ *prefilters; /* cupsPreFilter values */ int single_file; /* cupsSingleFile value */ cups_array_t *finishings; /* cupsIPPFinishings values */ + cups_array_t *templates; /* cupsFinishingTemplate values */ int max_copies, /* cupsMaxCopies value */ account_id, /* cupsJobAccountId value */ accounting_user_id; /* cupsJobAccountingUserId value */ char *password; /* cupsJobPassword value */ cups_array_t *mandatory; /* cupsMandatory value */ char *charge_info_uri; /* cupsChargeInfoURI value */ + cups_array_t *strings; /* Localization strings */ cups_array_t *support_files; /* Support files - ICC profiles, etc. */ }; @@ -165,63 +155,62 @@ struct _ppd_cache_s /**** PPD cache and PWG conversion data ****/ * Prototypes... */ -extern int _cupsConvertOptions(ipp_t *request, ppd_file_t *ppd, _ppd_cache_t *pc, ipp_attribute_t *media_col_sup, ipp_attribute_t *doc_handling_sup, ipp_attribute_t *print_color_mode_sup, const char *user, const char *format, int copies, int num_options, cups_option_t *options); +extern int _cupsConvertOptions(ipp_t *request, ppd_file_t *ppd, _ppd_cache_t *pc, ipp_attribute_t *media_col_sup, ipp_attribute_t *doc_handling_sup, ipp_attribute_t *print_color_mode_sup, const char *user, const char *format, int copies, int num_options, cups_option_t *options) _CUPS_PRIVATE; +extern int _cupsRasterExecPS(cups_page_header2_t *h, int *preferred_bits, const char *code) _CUPS_NONNULL(3) _CUPS_PRIVATE; +extern int _cupsRasterInterpretPPD(cups_page_header2_t *h, ppd_file_t *ppd, int num_options, cups_option_t *options, cups_interpret_cb_t func) _CUPS_PRIVATE; + extern _ppd_cache_t *_ppdCacheCreateWithFile(const char *filename, - ipp_t **attrs); -extern _ppd_cache_t *_ppdCacheCreateWithPPD(ppd_file_t *ppd); -extern void _ppdCacheDestroy(_ppd_cache_t *pc); + ipp_t **attrs) _CUPS_PRIVATE; +extern _ppd_cache_t *_ppdCacheCreateWithPPD(ppd_file_t *ppd) _CUPS_PRIVATE; +extern void _ppdCacheDestroy(_ppd_cache_t *pc) _CUPS_PRIVATE; extern const char *_ppdCacheGetBin(_ppd_cache_t *pc, - const char *output_bin); + const char *output_bin) _CUPS_PRIVATE; extern int _ppdCacheGetFinishingOptions(_ppd_cache_t *pc, ipp_t *job, ipp_finishings_t value, int num_options, - cups_option_t **options); -extern int _ppdCacheGetFinishingValues(_ppd_cache_t *pc, - int num_options, - cups_option_t *options, - int max_values, - int *values); + cups_option_t **options) _CUPS_PRIVATE; +extern int _ppdCacheGetFinishingValues(ppd_file_t *ppd, _ppd_cache_t *pc, int max_values, int *values) _CUPS_PRIVATE; extern const char *_ppdCacheGetInputSlot(_ppd_cache_t *pc, ipp_t *job, - const char *keyword); + const char *keyword) _CUPS_PRIVATE; extern const char *_ppdCacheGetMediaType(_ppd_cache_t *pc, ipp_t *job, - const char *keyword); + const char *keyword) _CUPS_PRIVATE; extern const char *_ppdCacheGetOutputBin(_ppd_cache_t *pc, - const char *keyword); + const char *keyword) _CUPS_PRIVATE; extern const char *_ppdCacheGetPageSize(_ppd_cache_t *pc, ipp_t *job, - const char *keyword, int *exact); + const char *keyword, int *exact) _CUPS_PRIVATE; extern pwg_size_t *_ppdCacheGetSize(_ppd_cache_t *pc, - const char *page_size); + const char *page_size) _CUPS_PRIVATE; extern const char *_ppdCacheGetSource(_ppd_cache_t *pc, - const char *input_slot); + const char *input_slot) _CUPS_PRIVATE; extern const char *_ppdCacheGetType(_ppd_cache_t *pc, - const char *media_type); + const char *media_type) _CUPS_PRIVATE; extern int _ppdCacheWriteFile(_ppd_cache_t *pc, - const char *filename, ipp_t *attrs); -extern char *_ppdCreateFromIPP(char *buffer, size_t bufsize, ipp_t *response); -extern void _ppdFreeLanguages(cups_array_t *languages); -extern cups_encoding_t _ppdGetEncoding(const char *name); -extern cups_array_t *_ppdGetLanguages(ppd_file_t *ppd); -extern _ppd_globals_t *_ppdGlobals(void); -extern unsigned _ppdHashName(const char *name); + const char *filename, ipp_t *attrs) _CUPS_PRIVATE; +extern char *_ppdCreateFromIPP(char *buffer, size_t bufsize, ipp_t *response) _CUPS_PRIVATE; +extern void _ppdFreeLanguages(cups_array_t *languages) _CUPS_PRIVATE; +extern cups_encoding_t _ppdGetEncoding(const char *name) _CUPS_PRIVATE; +extern cups_array_t *_ppdGetLanguages(ppd_file_t *ppd) _CUPS_PRIVATE; +extern _ppd_globals_t *_ppdGlobals(void) _CUPS_PRIVATE; +extern unsigned _ppdHashName(const char *name) _CUPS_PRIVATE; extern ppd_attr_t *_ppdLocalizedAttr(ppd_file_t *ppd, const char *keyword, - const char *spec, const char *ll_CC); + const char *spec, const char *ll_CC) _CUPS_PRIVATE; extern char *_ppdNormalizeMakeAndModel(const char *make_and_model, char *buffer, - size_t bufsize); + size_t bufsize) _CUPS_PRIVATE; extern ppd_file_t *_ppdOpen(cups_file_t *fp, - _ppd_localization_t localization); + _ppd_localization_t localization) _CUPS_PRIVATE; extern ppd_file_t *_ppdOpenFile(const char *filename, - _ppd_localization_t localization); + _ppd_localization_t localization) _CUPS_PRIVATE; extern int _ppdParseOptions(const char *s, int num_options, cups_option_t **options, - _ppd_parse_t which); + _ppd_parse_t which) _CUPS_PRIVATE; extern const char *_pwgInputSlotForSource(const char *media_source, - char *name, size_t namesize); + char *name, size_t namesize) _CUPS_PRIVATE; extern const char *_pwgMediaTypeForType(const char *media_type, - char *name, size_t namesize); + char *name, size_t namesize) _CUPS_PRIVATE; extern const char *_pwgPageSizeForMedia(pwg_media_t *media, - char *name, size_t namesize); + char *name, size_t namesize) _CUPS_PRIVATE; /* diff --git a/cups/ppd-util.c b/cups/ppd-util.c index d0194c8..5e43615 100644 --- a/cups/ppd-util.c +++ b/cups/ppd-util.c @@ -1,16 +1,11 @@ /* * PPD utilities for CUPS. * - * Copyright 2007-2015 by Apple Inc. - * Copyright 1997-2006 by Easy Software Products. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -19,13 +14,14 @@ #include "cups-private.h" #include "ppd-private.h" +#include "debug-internal.h" #include #include -#if defined(WIN32) || defined(__EMX__) +#if defined(_WIN32) || defined(__EMX__) # include #else # include -#endif /* WIN32 || __EMX__ */ +#endif /* _WIN32 || __EMX__ */ /* @@ -155,23 +151,26 @@ cupsGetPPD3(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAUL if (!name) { + DEBUG_puts("2cupsGetPPD3: No printer name, returning NULL."); _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No printer name"), 1); return (HTTP_STATUS_NOT_ACCEPTABLE); } if (!modtime) { + DEBUG_puts("2cupsGetPPD3: No modtime, returning NULL."); _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No modification time"), 1); return (HTTP_STATUS_NOT_ACCEPTABLE); } if (!buffer || bufsize <= 1) { + DEBUG_puts("2cupsGetPPD3: No filename buffer, returning NULL."); _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad filename buffer"), 1); return (HTTP_STATUS_NOT_ACCEPTABLE); } -#ifndef WIN32 +#ifndef _WIN32 /* * See if the PPD file is available locally... */ @@ -201,6 +200,8 @@ cupsGetPPD3(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAUL if (buffer[0]) { + DEBUG_printf(("2cupsGetPPD3: Using filename \"%s\".", buffer)); + unlink(buffer); if (symlink(ppdname, buffer) && errno != EEXIST) @@ -216,6 +217,28 @@ cupsGetPPD3(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAUL const char *tmpdir; /* TMPDIR environment variable */ struct timeval curtime; /* Current time */ + +#ifdef __APPLE__ + /* + * On macOS and iOS, the TMPDIR environment variable is not always the + * best location to place temporary files due to sandboxing. Instead, + * the confstr function should be called to get the proper per-user, + * per-process TMPDIR value. + */ + + char tmppath[1024]; /* Temporary directory */ + + if ((tmpdir = getenv("TMPDIR")) != NULL && access(tmpdir, W_OK)) + tmpdir = NULL; + + if (!tmpdir) + { + if (confstr(_CS_DARWIN_USER_TEMP_DIR, tmppath, sizeof(tmppath))) + tmpdir = tmppath; + else + tmpdir = "/private/tmp"; /* This should never happen */ + } +#else /* * Previously we put root temporary files in the default CUPS temporary * directory under /var/spool/cups. However, since the scheduler cleans @@ -224,11 +247,10 @@ cupsGetPPD3(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAUL */ if ((tmpdir = getenv("TMPDIR")) == NULL) -# ifdef __APPLE__ - tmpdir = "/private/tmp"; /* /tmp is a symlink to /private/tmp */ -# else - tmpdir = "/tmp"; -# endif /* __APPLE__ */ + tmpdir = "/tmp"; +#endif /* __APPLE__ */ + + DEBUG_printf(("2cupsGetPPD3: tmpdir=\"%s\".", tmpdir)); /* * Make the temporary name using the specified directory... @@ -259,12 +281,16 @@ cupsGetPPD3(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAUL if (!symlink(ppdname, buffer)) break; + DEBUG_printf(("2cupsGetPPD3: Symlink \"%s\" to \"%s\" failed: %s", ppdname, buffer, strerror(errno))); + tries ++; } while (tries < 1000); if (tries >= 1000) { + DEBUG_puts("2cupsGetPPD3: Unable to symlink after 1000 tries, returning error."); + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, NULL, 0); return (HTTP_STATUS_SERVER_ERROR); @@ -272,30 +298,42 @@ cupsGetPPD3(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAUL } if (*modtime >= ppdinfo.st_mtime) + { + DEBUG_printf(("2cupsGetPPD3: Returning not-modified, filename=\"%s\".", buffer)); return (HTTP_STATUS_NOT_MODIFIED); + } else { + DEBUG_printf(("2cupsGetPPD3: Returning ok, filename=\"%s\", modtime=%ld.", buffer, (long)ppdinfo.st_mtime)); *modtime = ppdinfo.st_mtime; return (HTTP_STATUS_OK); } } } -#endif /* !WIN32 */ +#endif /* !_WIN32 */ /* * Try finding a printer URI for this printer... */ + DEBUG_puts("2cupsGetPPD3: Unable to access local file, copying..."); + if (!http) + { if ((http = _cupsConnect()) == NULL) + { + DEBUG_puts("2cupsGetPPD3: Unable to connect to scheduler."); return (HTTP_STATUS_SERVICE_UNAVAILABLE); + } + } - if (!cups_get_printer_uri(http, name, hostname, sizeof(hostname), &port, - resource, sizeof(resource), 0)) + if (!cups_get_printer_uri(http, name, hostname, sizeof(hostname), &port, resource, sizeof(resource), 0)) + { + DEBUG_puts("2cupsGetPPD3: Unable to get printer URI."); return (HTTP_STATUS_NOT_FOUND); + } - DEBUG_printf(("2cupsGetPPD3: Printer hostname=\"%s\", port=%d", hostname, - port)); + DEBUG_printf(("2cupsGetPPD3: Printer hostname=\"%s\", port=%d", hostname, port)); if (cupsServer()[0] == '/' && !_cups_strcasecmp(hostname, "localhost") && port == ippPort()) { @@ -339,7 +377,7 @@ cupsGetPPD3(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAUL else if ((http2 = httpConnect2(hostname, port, NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL)) == NULL) { - DEBUG_puts("1cupsGetPPD3: Unable to connect to server"); + DEBUG_puts("2cupsGetPPD3: Unable to connect to server"); return (HTTP_STATUS_SERVICE_UNAVAILABLE); } @@ -411,7 +449,7 @@ cupsGetPPD3(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAUL * Return the PPD file... */ - DEBUG_printf(("1cupsGetPPD3: Returning status %d", status)); + DEBUG_printf(("2cupsGetPPD3: Returning status %d", status)); return (status); } @@ -511,23 +549,16 @@ cups_get_printer_uri( int depth) /* I - Depth of query */ { int i; /* Looping var */ - int http_port; /* Port number */ - http_t *http2; /* Alternate HTTP connection */ ipp_t *request, /* IPP request */ *response; /* IPP response */ ipp_attribute_t *attr; /* Current attribute */ char uri[HTTP_MAX_URI], /* printer-uri attribute */ scheme[HTTP_MAX_URI], /* Scheme name */ - username[HTTP_MAX_URI], /* Username:password */ - classname[255], /* Temporary class name */ - http_hostname[HTTP_MAX_HOST]; - /* Hostname associated with connection */ + username[HTTP_MAX_URI]; /* Username:password */ static const char * const requested_attrs[] = { /* Requested attributes */ - "device-uri", "member-uris", - "printer-uri-supported", - "printer-type" + "printer-uri-supported" }; @@ -549,15 +580,6 @@ cups_get_printer_uri( DEBUG_printf(("5cups_get_printer_uri: printer-uri=\"%s\"", uri)); - /* - * Get the hostname and port number we are connected to... - */ - - httpGetHostname(http, http_hostname, sizeof(http_hostname)); - http_port = httpAddrPort(http->hostaddr); - - DEBUG_printf(("5cups_get_printer_uri: http_hostname=\"%s\"", http_hostname)); - /* * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following * attributes: @@ -582,31 +604,7 @@ cups_get_printer_uri( if ((response = cupsDoRequest(http, request, resource)) != NULL) { - const char *device_uri = NULL; /* device-uri value */ - - if ((attr = ippFindAttribute(response, "device-uri", IPP_TAG_URI)) != NULL) - { - device_uri = attr->values[0].string.text; - DEBUG_printf(("5cups_get_printer_uri: device-uri=\"%s\"", device_uri)); - } - - if (device_uri && - (((!strncmp(device_uri, "ipp://", 6) || !strncmp(device_uri, "ipps://", 7)) && - (strstr(device_uri, "/printers/") != NULL || strstr(device_uri, "/classes/") != NULL)) || - ((strstr(device_uri, "._ipp.") != NULL || strstr(device_uri, "._ipps.") != NULL) && - !strcmp(device_uri + strlen(device_uri) - 5, "/cups")))) - { - /* - * Statically-configured shared printer. - */ - - httpSeparateURI(HTTP_URI_CODING_ALL, _httpResolveURI(device_uri, uri, sizeof(uri), _HTTP_RESOLVE_DEFAULT, NULL, NULL), scheme, sizeof(scheme), username, sizeof(username), host, hostsize, port, resource, resourcesize); - ippDelete(response); - - DEBUG_printf(("5cups_get_printer_uri: Resolved to host=\"%s\", port=%d, resource=\"%s\"", host, *port, resource)); - return (1); - } - else if ((attr = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL) + if ((attr = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL) { /* * Get the first actual printer name in the class... @@ -631,55 +629,6 @@ cups_get_printer_uri( return (1); } } - - /* - * No printers in this class - try recursively looking for a printer, - * but not more than 3 levels deep... - */ - - if (depth < 3) - { - for (i = 0; i < attr->num_values; i ++) - { - httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[i].string.text, - scheme, sizeof(scheme), username, sizeof(username), - host, hostsize, port, resource, resourcesize); - if (!strncmp(resource, "/classes/", 9)) - { - /* - * Found a class! Connect to the right server... - */ - - if (!_cups_strcasecmp(http_hostname, host) && *port == http_port) - http2 = http; - else if ((http2 = httpConnect2(host, *port, NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL)) == NULL) - { - DEBUG_puts("8cups_get_printer_uri: Unable to connect to server"); - - continue; - } - - /* - * Look up printers on that server... - */ - - strlcpy(classname, resource + 9, sizeof(classname)); - - cups_get_printer_uri(http2, classname, host, hostsize, port, - resource, resourcesize, depth + 1); - - /* - * Close the connection as needed... - */ - - if (http2 != http) - httpClose(http2); - - if (*host) - return (1); - } - } - } } else if ((attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI)) != NULL) { diff --git a/cups/ppd.c b/cups/ppd.c index 5bd839d..fae19c4 100644 --- a/cups/ppd.c +++ b/cups/ppd.c @@ -1,25 +1,13 @@ /* * PPD file routines for CUPS. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. * * PostScript is a trademark of Adobe Systems, Inc. - * - * This code and any derivative of it may be used and distributed - * freely under the terms of the GNU General Public License when - * used with GNU Ghostscript or its derivatives. Use of the code - * (or any derivative of it) with software other than GNU - * GhostScript (or its derivatives) is governed by the CUPS license - * agreement. - * - * This file is subject to the Apple OS-Developed Software exception. */ /* @@ -28,14 +16,13 @@ #include "cups-private.h" #include "ppd-private.h" +#include "debug-internal.h" /* * Definitions... */ -#define ppd_free(p) if (p) free(p) /* Safe free macro */ - #define PPD_KEYWORD 1 /* Line contained a keyword */ #define PPD_OPTION 2 /* Line contained an option name */ #define PPD_TEXT 4 /* Line contained human-readable text */ @@ -94,9 +81,9 @@ static ppd_group_t *ppd_get_group(ppd_file_t *ppd, const char *name, cups_encoding_t encoding); static ppd_option_t *ppd_get_option(ppd_group_t *group, const char *name); static _ppd_globals_t *ppd_globals_alloc(void); -#if defined(HAVE_PTHREAD_H) || defined(WIN32) +#if defined(HAVE_PTHREAD_H) || defined(_WIN32) static void ppd_globals_free(_ppd_globals_t *g); -#endif /* HAVE_PTHREAD_H || WIN32 */ +#endif /* HAVE_PTHREAD_H || _WIN32 */ #ifdef HAVE_PTHREAD_H static void ppd_globals_init(void); #endif /* HAVE_PTHREAD_H */ @@ -117,7 +104,6 @@ void ppdClose(ppd_file_t *ppd) /* I - PPD file record */ { int i; /* Looping var */ - ppd_emul_t *emul; /* Current emulation */ ppd_group_t *group; /* Current group */ char **font; /* Current font */ ppd_attr_t **attr; /* Current attribute */ @@ -136,28 +122,12 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ * Free all strings at the top level... */ - _cupsStrFree(ppd->lang_encoding); - _cupsStrFree(ppd->nickname); - if (ppd->patches) - free(ppd->patches); - _cupsStrFree(ppd->jcl_begin); - _cupsStrFree(ppd->jcl_end); - _cupsStrFree(ppd->jcl_ps); - - /* - * Free any emulations... - */ - - if (ppd->num_emulations > 0) - { - for (i = ppd->num_emulations, emul = ppd->emulations; i > 0; i --, emul ++) - { - _cupsStrFree(emul->start); - _cupsStrFree(emul->stop); - } - - ppd_free(ppd->emulations); - } + free(ppd->lang_encoding); + free(ppd->nickname); + free(ppd->patches); + free(ppd->jcl_begin); + free(ppd->jcl_end); + free(ppd->jcl_ps); /* * Free any UI groups, subgroups, and options... @@ -168,7 +138,7 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++) ppd_free_group(group); - ppd_free(ppd->groups); + free(ppd->groups); } cupsArrayDelete(ppd->options); @@ -179,14 +149,14 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ */ if (ppd->num_sizes > 0) - ppd_free(ppd->sizes); + free(ppd->sizes); /* * Free any constraints... */ if (ppd->num_consts > 0) - ppd_free(ppd->consts); + free(ppd->consts); /* * Free any filters... @@ -201,9 +171,9 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ if (ppd->num_fonts > 0) { for (i = ppd->num_fonts, font = ppd->fonts; i > 0; i --, font ++) - _cupsStrFree(*font); + free(*font); - ppd_free(ppd->fonts); + free(ppd->fonts); } /* @@ -211,7 +181,7 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ */ if (ppd->num_profiles > 0) - ppd_free(ppd->profiles); + free(ppd->profiles); /* * Free any attributes... @@ -221,11 +191,11 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ { for (i = ppd->num_attrs, attr = ppd->attrs; i > 0; i --, attr ++) { - _cupsStrFree((*attr)->value); - ppd_free(*attr); + free((*attr)->value); + free(*attr); } - ppd_free(ppd->attrs); + free(ppd->attrs); } cupsArrayDelete(ppd->sorted_attrs); @@ -247,7 +217,7 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ case PPD_CUSTOM_PASSCODE : case PPD_CUSTOM_PASSWORD : case PPD_CUSTOM_STRING : - _cupsStrFree(cparam->current.custom_string); + free(cparam->current.custom_string); break; default : @@ -295,7 +265,7 @@ ppdClose(ppd_file_t *ppd) /* I - PPD file record */ * Free the whole record... */ - ppd_free(ppd); + free(ppd); } @@ -333,7 +303,9 @@ ppdErrorString(ppd_status_t status) /* I - PPD status */ _("Bad custom parameter"), _("Missing option keyword"), _("Bad value string"), - _("Missing CloseGroup") + _("Missing CloseGroup"), + _("Bad CloseUI/JCLCloseUI"), + _("Missing CloseUI/JCLCloseUI") }; @@ -441,7 +413,6 @@ _ppdOpen( _ppd_localization_t localization) /* I - Localization to load */ { int i, j, k; /* Looping vars */ - int count; /* Temporary count */ _ppd_line_t line; /* Line buffer */ ppd_file_t *ppd; /* PPD file record */ ppd_group_t *group, /* Current group */ @@ -459,7 +430,6 @@ _ppdOpen( /* Human-readable text from file */ *string, /* Code/text from file */ *sptr, /* Pointer into string */ - *nameptr, /* Pointer into name */ *temp, /* Temporary string pointer */ **tempfonts; /* Temporary fonts pointer */ float order; /* Order dependency number */ @@ -633,16 +603,14 @@ _ppdOpen( if (pg->ppd_status == PPD_OK) pg->ppd_status = PPD_MISSING_PPDADOBE4; - _cupsStrFree(string); - ppd_free(line.buffer); + free(string); + free(line.buffer); return (NULL); } DEBUG_printf(("2_ppdOpen: keyword=%s, string=%p", keyword, string)); - _cupsStrFree(string); - /* * Allocate memory for the PPD file record... */ @@ -651,18 +619,20 @@ _ppdOpen( { pg->ppd_status = PPD_ALLOC_ERROR; - _cupsStrFree(string); - ppd_free(line.buffer); + free(string); + free(line.buffer); return (NULL); } + free(string); + string = NULL; + ppd->language_level = 2; ppd->color_device = 0; ppd->colorspace = PPD_CS_N; ppd->landscape = -90; - ppd->coptions = cupsArrayNew((cups_array_func_t)ppd_compare_coptions, - NULL); + ppd->coptions = cupsArrayNew((cups_array_func_t)ppd_compare_coptions, NULL); /* * Read lines from the PPD file and add them to the file record... @@ -735,6 +705,8 @@ _ppdOpen( strncmp(ll, keyword, ll_len))) { DEBUG_printf(("2_ppdOpen: Ignoring localization: \"%s\"\n", keyword)); + free(string); + string = NULL; continue; } else if (localization == _PPD_LOCALIZATION_ICC_PROFILES) @@ -754,6 +726,8 @@ _ppdOpen( if (i >= (int)(sizeof(color_keywords) / sizeof(color_keywords[0]))) { DEBUG_printf(("2_ppdOpen: Ignoring localization: \"%s\"\n", keyword)); + free(string); + string = NULL; continue; } } @@ -849,7 +823,7 @@ _ppdOpen( * Say all PPD files are UTF-8, since we convert to UTF-8... */ - ppd->lang_encoding = _cupsStrAlloc("UTF-8"); + ppd->lang_encoding = strdup("UTF-8"); encoding = _ppdGetEncoding(string); } else if (!strcmp(keyword, "LanguageVersion")) @@ -870,10 +844,10 @@ _ppdOpen( cupsCharsetToUTF8(utf8, string, sizeof(utf8), encoding); - ppd->nickname = _cupsStrAlloc((char *)utf8); + ppd->nickname = strdup((char *)utf8); } else - ppd->nickname = _cupsStrAlloc(string); + ppd->nickname = strdup(string); } else if (!strcmp(keyword, "Product")) ppd->product = string; @@ -883,17 +857,17 @@ _ppdOpen( ppd->ttrasterizer = string; else if (!strcmp(keyword, "JCLBegin")) { - ppd->jcl_begin = _cupsStrAlloc(string); + ppd->jcl_begin = strdup(string); ppd_decode(ppd->jcl_begin); /* Decode quoted string */ } else if (!strcmp(keyword, "JCLEnd")) { - ppd->jcl_end = _cupsStrAlloc(string); + ppd->jcl_end = strdup(string); ppd_decode(ppd->jcl_end); /* Decode quoted string */ } else if (!strcmp(keyword, "JCLToPSInterpreter")) { - ppd->jcl_ps = _cupsStrAlloc(string); + ppd->jcl_ps = strdup(string); ppd_decode(ppd->jcl_ps); /* Decode quoted string */ } else if (!strcmp(keyword, "AccurateScreensSupport")) @@ -961,10 +935,10 @@ _ppdOpen( ppd->num_filters ++; /* - * Retain a copy of the filter string... + * Make a copy of the filter string... */ - *filter = _cupsStrRetain(string); + *filter = strdup(string); } else if (!strcmp(keyword, "Throughput")) ppd->throughput = atoi(string); @@ -987,7 +961,7 @@ _ppdOpen( } ppd->fonts = tempfonts; - ppd->fonts[ppd->num_fonts] = _cupsStrAlloc(name); + ppd->fonts[ppd->num_fonts] = strdup(name); ppd->num_fonts ++; } else if (!strncmp(keyword, "ParamCustom", 11)) @@ -1018,6 +992,13 @@ _ppdOpen( goto error; } + if (cparam->type != PPD_CUSTOM_UNKNOWN) + { + pg->ppd_status = PPD_BAD_CUSTOM_PARAM; + + goto error; + } + /* * Get the parameter data... */ @@ -1152,7 +1133,7 @@ _ppdOpen( strlcpy(choice->text, text[0] ? text : _("Custom"), sizeof(choice->text)); - choice->code = _cupsStrAlloc(string); + choice->code = strdup(string); if (custom_option->section == PPD_ORDER_JCL) ppd_decode(choice->code); @@ -1201,59 +1182,23 @@ _ppdOpen( else if (!strcmp(string, "Plus90")) ppd->landscape = 90; } - else if (!strcmp(keyword, "Emulators") && string) + else if (!strcmp(keyword, "Emulators") && string && ppd->num_emulations == 0) { - for (count = 1, sptr = string; sptr != NULL;) - if ((sptr = strchr(sptr, ' ')) != NULL) - { - count ++; - while (*sptr == ' ') - sptr ++; - } + /* + * Issue #5562: Samsung printer drivers incorrectly use Emulators keyword + * to configure themselves + * + * The Emulators keyword was loaded but never used by anything in CUPS, + * and has no valid purpose in CUPS. The old code was removed due to a + * memory leak (Issue #5475), so the following (new) code supports a single + * name for the Emulators keyword, allowing these drivers to work until we + * remove PPD and driver support entirely in a future version of CUPS. + */ - ppd->num_emulations = count; - if ((ppd->emulations = calloc((size_t)count, sizeof(ppd_emul_t))) == NULL) - { - pg->ppd_status = PPD_ALLOC_ERROR; + ppd->num_emulations = 1; + ppd->emulations = calloc(1, sizeof(ppd_emul_t)); - goto error; - } - - for (i = 0, sptr = string; i < count; i ++) - { - for (nameptr = ppd->emulations[i].name; - *sptr != '\0' && *sptr != ' '; - sptr ++) - if (nameptr < (ppd->emulations[i].name + sizeof(ppd->emulations[i].name) - 1)) - *nameptr++ = *sptr; - - *nameptr = '\0'; - - while (*sptr == ' ') - sptr ++; - } - } - else if (!strncmp(keyword, "StartEmulator_", 14)) - { - ppd_decode(string); - - for (i = 0; i < ppd->num_emulations; i ++) - if (!strcmp(keyword + 14, ppd->emulations[i].name)) - { - ppd->emulations[i].start = string; - string = NULL; - } - } - else if (!strncmp(keyword, "StopEmulator_", 13)) - { - ppd_decode(string); - - for (i = 0; i < ppd->num_emulations; i ++) - if (!strcmp(keyword + 13, ppd->emulations[i].name)) - { - ppd->emulations[i].stop = string; - string = NULL; - } + strlcpy(ppd->emulations[0].name, string, sizeof(ppd->emulations[0].name)); } else if (!strcmp(keyword, "JobPatchFile")) { @@ -1408,7 +1353,7 @@ _ppdOpen( option->section = PPD_ORDER_ANY; - _cupsStrFree(string); + free(string); string = NULL; /* @@ -1436,7 +1381,7 @@ _ppdOpen( strlcpy(choice->text, custom_attr->text[0] ? custom_attr->text : _("Custom"), sizeof(choice->text)); - choice->code = _cupsStrRetain(custom_attr->value); + choice->code = strdup(custom_attr->value); } } else if (!strcmp(keyword, "JCLOpenUI")) @@ -1515,7 +1460,7 @@ _ppdOpen( option->section = PPD_ORDER_JCL; group = NULL; - _cupsStrFree(string); + free(string); string = NULL; /* @@ -1539,14 +1484,35 @@ _ppdOpen( strlcpy(choice->text, custom_attr->text[0] ? custom_attr->text : _("Custom"), sizeof(choice->text)); - choice->code = _cupsStrRetain(custom_attr->value); + choice->code = strdup(custom_attr->value); } } - else if (!strcmp(keyword, "CloseUI") || !strcmp(keyword, "JCLCloseUI")) + else if (!strcmp(keyword, "CloseUI")) { + if ((!option || option->section == PPD_ORDER_JCL) && pg->ppd_conform == PPD_CONFORM_STRICT) + { + pg->ppd_status = PPD_BAD_CLOSE_UI; + + goto error; + } + option = NULL; - _cupsStrFree(string); + free(string); + string = NULL; + } + else if (!strcmp(keyword, "JCLCloseUI")) + { + if ((!option || option->section != PPD_ORDER_JCL) && pg->ppd_conform == PPD_CONFORM_STRICT) + { + pg->ppd_status = PPD_BAD_CLOSE_UI; + + goto error; + } + + option = NULL; + + free(string); string = NULL; } else if (!strcmp(keyword, "OpenGroup")) @@ -1593,14 +1559,14 @@ _ppdOpen( if (group == NULL) goto error; - _cupsStrFree(string); + free(string); string = NULL; } else if (!strcmp(keyword, "CloseGroup")) { group = NULL; - _cupsStrFree(string); + free(string); string = NULL; } else if (!strcmp(keyword, "OrderDependency")) @@ -1658,7 +1624,7 @@ _ppdOpen( option->order = order; } - _cupsStrFree(string); + free(string); string = NULL; } else if (!strncmp(keyword, "Default", 7)) @@ -1901,11 +1867,18 @@ _ppdOpen( * Don't add this one as an attribute... */ - _cupsStrFree(string); + free(string); string = NULL; } else if (!strcmp(keyword, "PaperDimension")) { + if (!_cups_strcasecmp(name, "custom") || !_cups_strncasecmp(name, "custom.", 7)) + { + pg->ppd_status = PPD_ILLEGAL_OPTION_KEYWORD; + + goto error; + } + if ((size = ppdPageSize(ppd, name)) == NULL) size = ppd_add_size(ppd, name); @@ -1923,11 +1896,18 @@ _ppdOpen( size->width = (float)_cupsStrScand(string, &sptr, loc); size->length = (float)_cupsStrScand(sptr, NULL, loc); - _cupsStrFree(string); + free(string); string = NULL; } else if (!strcmp(keyword, "ImageableArea")) { + if (!_cups_strcasecmp(name, "custom") || !_cups_strncasecmp(name, "custom.", 7)) + { + pg->ppd_status = PPD_ILLEGAL_OPTION_KEYWORD; + + goto error; + } + if ((size = ppdPageSize(ppd, name)) == NULL) size = ppd_add_size(ppd, name); @@ -1947,7 +1927,7 @@ _ppdOpen( size->right = (float)_cupsStrScand(sptr, &sptr, loc); size->top = (float)_cupsStrScand(sptr, NULL, loc); - _cupsStrFree(string); + free(string); string = NULL; } else if (option != NULL && @@ -1957,6 +1937,13 @@ _ppdOpen( { DEBUG_printf(("2_ppdOpen: group=%p, subgroup=%p", group, subgroup)); + if (!_cups_strcasecmp(name, "custom") || !_cups_strncasecmp(name, "custom.", 7)) + { + pg->ppd_status = PPD_ILLEGAL_OPTION_KEYWORD; + + goto error; + } + if (!strcmp(keyword, "PageSize")) { /* @@ -2003,7 +1990,17 @@ _ppdOpen( (mask & (PPD_KEYWORD | PPD_STRING)) == (PPD_KEYWORD | PPD_STRING)) ppd_add_attr(ppd, keyword, name, text, string); else - _cupsStrFree(string); + free(string); + } + + /* + * Check for a missing CloseUI/JCLCloseUI... + */ + + if (option && pg->ppd_conform == PPD_CONFORM_STRICT) + { + pg->ppd_status = PPD_MISSING_CLOSE_UI; + goto error; } /* @@ -2016,7 +2013,7 @@ _ppdOpen( goto error; } - ppd_free(line.buffer); + free(line.buffer); /* * Reset language preferences... @@ -2098,8 +2095,8 @@ _ppdOpen( error: - _cupsStrFree(string); - ppd_free(line.buffer); + free(string); + free(line.buffer); ppdClose(ppd); @@ -2537,9 +2534,9 @@ ppd_free_filters(ppd_file_t *ppd) /* I - PPD file */ if (ppd->num_filters > 0) { for (i = ppd->num_filters, filter = ppd->filters; i > 0; i --, filter ++) - _cupsStrFree(*filter); + free(*filter); - ppd_free(ppd->filters); + free(ppd->filters); ppd->num_filters = 0; ppd->filters = NULL; @@ -2566,7 +2563,7 @@ ppd_free_group(ppd_group_t *group) /* I - Group to free */ i --, option ++) ppd_free_option(option); - ppd_free(group->options); + free(group->options); } if (group->num_subgroups > 0) @@ -2576,7 +2573,7 @@ ppd_free_group(ppd_group_t *group) /* I - Group to free */ i --, subgroup ++) ppd_free_group(subgroup); - ppd_free(group->subgroups); + free(group->subgroups); } } @@ -2598,10 +2595,10 @@ ppd_free_option(ppd_option_t *option) /* I - Option to free */ i > 0; i --, choice ++) { - _cupsStrFree(choice->code); + free(choice->code); } - ppd_free(option->choices); + free(option->choices); } } @@ -2671,6 +2668,7 @@ ppd_get_cparam(ppd_coption_t *opt, /* I - PPD file */ if ((cparam = calloc(1, sizeof(ppd_cparam_t))) == NULL) return (NULL); + cparam->type = PPD_CUSTOM_UNKNOWN; strlcpy(cparam->name, param, sizeof(cparam->name)); strlcpy(cparam->text, text[0] ? text : param, sizeof(cparam->text)); @@ -2804,13 +2802,13 @@ ppd_globals_alloc(void) * 'ppd_globals_free()' - Free global data. */ -#if defined(HAVE_PTHREAD_H) || defined(WIN32) +#if defined(HAVE_PTHREAD_H) || defined(_WIN32) static void ppd_globals_free(_ppd_globals_t *pg) /* I - Pointer to global data */ { free(pg); } -#endif /* HAVE_PTHREAD_H || WIN32 */ +#endif /* HAVE_PTHREAD_H || _WIN32 */ #ifdef HAVE_PTHREAD_H @@ -3338,7 +3336,7 @@ ppd_read(cups_file_t *fp, /* I - File to read from */ lineptr ++; } - *string = _cupsStrAlloc(lineptr); + *string = strdup(lineptr); mask |= PPD_STRING; } @@ -3460,7 +3458,7 @@ ppd_update_filters(ppd_file_t *ppd, /* I - PPD file */ filter += ppd->num_filters; ppd->num_filters ++; - *filter = _cupsStrAlloc(buffer); + *filter = strdup(buffer); } while ((attr = ppdFindNextAttr(ppd, "cupsFilter2", NULL)) != NULL); diff --git a/cups/ppd.h b/cups/ppd.h index fb33c08..f2ba50d 100644 --- a/cups/ppd.h +++ b/cups/ppd.h @@ -1,29 +1,16 @@ /* * PostScript Printer Description definitions for CUPS. * - * THESE APIS ARE DEPRECATED. TO COMPILE WITHOUT WARNINGS ADD - * -D_PPD_DEPRECATED="" TO YOUR COMPILE OPTIONS. THIS HEADER AND THESE - * FUNCTIONS WILL BE REMOVED IN A FUTURE RELEASE OF CUPS. + * THESE APIS ARE DEPRECATED. THIS HEADER AND THESE FUNCTIONS WILL BE REMOVED + * IN A FUTURE RELEASE OF CUPS. * - * Copyright 2007-2015 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. * * PostScript is a trademark of Adobe Systems, Inc. - * - * This code and any derivative of it may be used and distributed - * freely under the terms of the GNU General Public License when - * used with GNU Ghostscript or its derivatives. Use of the code - * (or any derivative of it) with software other than GNU - * GhostScript (or its derivatives) is governed by the CUPS license - * agreement. - * - * This file is subject to the Apple OS-Developed Software exception. */ #ifndef _CUPS_PPD_H_ @@ -49,16 +36,6 @@ extern "C" { # endif /* __cplusplus */ -/* - * Define _PPD_DEPRECATED to silence the warnings about PPD functions being - * deprecated... - */ - -# ifndef _PPD_DEPRECATED -# define _PPD_DEPRECATED _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead.") -# endif /* !_PPD_DEPRECATED */ - - /* * PPD version... */ @@ -79,14 +56,28 @@ extern "C" { * Types and structures... */ -typedef enum ppd_ui_e /**** UI Types ****/ +typedef int (*cups_interpret_cb_t)(cups_page_header2_t *header, int preferred_bits); + /**** cupsRasterInterpretPPD callback function + * + * This function is called by + * @link cupsRasterInterpretPPD@ to + * validate (and update, as needed) + * the page header attributes. The + * "preferred_bits" argument provides + * the value of the + * @code cupsPreferredBitsPerColor@ + * key from the PostScript page device + * dictionary and is 0 if undefined. + ****/ + +typedef enum ppd_ui_e /**** UI Types @deprecated@ ****/ { PPD_UI_BOOLEAN, /* True or False option */ PPD_UI_PICKONE, /* Pick one from a list */ PPD_UI_PICKMANY /* Pick zero or more from a list */ } ppd_ui_t; -typedef enum ppd_section_e /**** Order dependency sections ****/ +typedef enum ppd_section_e /**** Order dependency sections @deprecated@ ****/ { PPD_ORDER_ANY, /* Option code can be anywhere in the file */ PPD_ORDER_DOCUMENT, /* ... must be in the DocumentSetup section */ @@ -96,7 +87,7 @@ typedef enum ppd_section_e /**** Order dependency sections ****/ PPD_ORDER_PROLOG /* ... must be in the Prolog section */ } ppd_section_t; -typedef enum ppd_cs_e /**** Colorspaces ****/ +typedef enum ppd_cs_e /**** Colorspaces @deprecated@ ****/ { PPD_CS_CMYK = -4, /* CMYK colorspace */ PPD_CS_CMY, /* CMY colorspace */ @@ -106,7 +97,7 @@ typedef enum ppd_cs_e /**** Colorspaces ****/ PPD_CS_N /* DeviceN colorspace */ } ppd_cs_t; -typedef enum ppd_status_e /**** Status Codes @since CUPS 1.1.19/macOS 10.3@ ****/ +typedef enum ppd_status_e /**** Status Codes @deprecated@ ****/ { PPD_OK = 0, /* OK */ PPD_FILE_OPEN_ERROR, /* Unable to open PPD file */ @@ -132,19 +123,21 @@ typedef enum ppd_status_e /**** Status Codes @since CUPS 1.1.19/macOS 10.3@ *** PPD_MISSING_OPTION_KEYWORD, /* Missing option keyword */ PPD_BAD_VALUE, /* Bad value string */ PPD_MISSING_CLOSE_GROUP, /* Missing CloseGroup */ + PPD_BAD_CLOSE_UI, /* Bad CloseUI/JCLCloseUI */ + PPD_MISSING_CLOSE_UI, /* Missing CloseUI/JCLCloseUI */ PPD_MAX_STATUS /* @private@ */ } ppd_status_t; -enum ppd_conform_e /**** Conformance Levels @since CUPS 1.1.19/macOS 10.3@ ****/ +enum ppd_conform_e /**** Conformance Levels @deprecated@ ****/ { PPD_CONFORM_RELAXED, /* Relax whitespace and control char */ PPD_CONFORM_STRICT /* Require strict conformance */ }; typedef enum ppd_conform_e ppd_conform_t; - /**** Conformance Levels @since CUPS 1.1.19/macOS 10.3@ ****/ + /**** Conformance Levels @deprecated@ ****/ -typedef struct ppd_attr_s /**** PPD Attribute Structure @since CUPS 1.1.19/macOS 10.3@ ****/ +typedef struct ppd_attr_s /**** PPD Attribute Structure @deprecated@ ****/ { char name[PPD_MAX_NAME]; /* Name of attribute (cupsXYZ) */ char spec[PPD_MAX_NAME]; /* Specifier string, if any */ @@ -153,9 +146,9 @@ typedef struct ppd_attr_s /**** PPD Attribute Structure @since CUPS 1.1.19/macO } ppd_attr_t; typedef struct ppd_option_s ppd_option_t; - /**** Options ****/ + /**** Options @deprecated@ ****/ -typedef struct ppd_choice_s /**** Option choices ****/ +typedef struct ppd_choice_s /**** Option choices @deprecated@ ****/ { char marked; /* 0 if not selected, 1 otherwise */ char choice[PPD_MAX_NAME]; /* Computer-readable option name */ @@ -164,7 +157,7 @@ typedef struct ppd_choice_s /**** Option choices ****/ ppd_option_t *option; /* Pointer to parent option structure */ } ppd_choice_t; -struct ppd_option_s /**** Options ****/ +struct ppd_option_s /**** Options @deprecated@ ****/ { char conflicted; /* 0 if no conflicts exist, 1 otherwise */ char keyword[PPD_MAX_NAME]; /* Option keyword name ("PageSize", etc.) */ @@ -177,7 +170,7 @@ struct ppd_option_s /**** Options ****/ ppd_choice_t *choices; /* Option choices */ }; -typedef struct ppd_group_s /**** Groups ****/ +typedef struct ppd_group_s /**** Groups @deprecated@ ****/ { /**** Group text strings are limited to 39 chars + nul in order to **** preserve binary compatibility and allow applications to get @@ -192,7 +185,7 @@ typedef struct ppd_group_s /**** Groups ****/ struct ppd_group_s *subgroups; /* Sub-groups (max depth = 1) */ } ppd_group_t; -typedef struct ppd_const_s /**** Constraints ****/ +typedef struct ppd_const_s /**** Constraints @deprecated@ ****/ { char option1[PPD_MAX_NAME]; /* First keyword */ char choice1[PPD_MAX_NAME]; /* First option/choice (blank for all) */ @@ -200,7 +193,7 @@ typedef struct ppd_const_s /**** Constraints ****/ char choice2[PPD_MAX_NAME]; /* Second option/choice (blank for all) */ } ppd_const_t; -typedef struct ppd_size_s /**** Page Sizes ****/ +typedef struct ppd_size_s /**** Page Sizes @deprecated@ ****/ { int marked; /* Page size selected? */ char name[PPD_MAX_NAME]; /* Media size option */ @@ -212,14 +205,14 @@ typedef struct ppd_size_s /**** Page Sizes ****/ float top; /* Top printable margin in points */ } ppd_size_t; -typedef struct ppd_emul_s /**** Emulators ****/ +typedef struct ppd_emul_s /**** Emulators @deprecated@ ****/ { char name[PPD_MAX_NAME]; /* Emulator name */ char *start; /* Code to switch to this emulation */ char *stop; /* Code to stop this emulation */ } ppd_emul_t; -typedef struct ppd_profile_s /**** sRGB Color Profiles ****/ +typedef struct ppd_profile_s /**** sRGB Color Profiles @deprecated@ ****/ { char resolution[PPD_MAX_NAME]; /* Resolution or "-" */ @@ -231,8 +224,9 @@ typedef struct ppd_profile_s /**** sRGB Color Profiles ****/ } ppd_profile_t; /**** New in CUPS 1.2/macOS 10.5 ****/ -typedef enum ppd_cptype_e /**** Custom Parameter Type @since CUPS 1.2/macOS 10.5@ ****/ +typedef enum ppd_cptype_e /**** Custom Parameter Type @deprecated@ ****/ { + PPD_CUSTOM_UNKNOWN = -1, /* Unknown type (error) */ PPD_CUSTOM_CURVE, /* Curve value for f(x) = x^value */ PPD_CUSTOM_INT, /* Integer number value */ PPD_CUSTOM_INVCURVE, /* Curve value for f(x) = x^(1/value) */ @@ -243,7 +237,7 @@ typedef enum ppd_cptype_e /**** Custom Parameter Type @since CUPS 1.2/macOS 10. PPD_CUSTOM_STRING /* String of characters */ } ppd_cptype_t; -typedef union ppd_cplimit_u /**** Custom Parameter Limit @since CUPS 1.2/macOS 10.5@ ****/ +typedef union ppd_cplimit_u /**** Custom Parameter Limit @deprecated@ ****/ { float custom_curve; /* Gamma value */ int custom_int; /* Integer value */ @@ -255,7 +249,7 @@ typedef union ppd_cplimit_u /**** Custom Parameter Limit @since CUPS 1.2/macOS int custom_string; /* String length */ } ppd_cplimit_t; -typedef union ppd_cpvalue_u /**** Custom Parameter Value @since CUPS 1.2/macOS 10.5@ ****/ +typedef union ppd_cpvalue_u /**** Custom Parameter Value @deprecated@ ****/ { float custom_curve; /* Gamma value */ int custom_int; /* Integer value */ @@ -267,7 +261,7 @@ typedef union ppd_cpvalue_u /**** Custom Parameter Value @since CUPS 1.2/macOS char *custom_string; /* String value */ } ppd_cpvalue_t; -typedef struct ppd_cparam_s /**** Custom Parameter @since CUPS 1.2/macOS 10.5@ ****/ +typedef struct ppd_cparam_s /**** Custom Parameter @deprecated@ ****/ { char name[PPD_MAX_NAME]; /* Parameter name */ char text[PPD_MAX_TEXT]; /* Human-readable text */ @@ -278,7 +272,7 @@ typedef struct ppd_cparam_s /**** Custom Parameter @since CUPS 1.2/macOS 10.5@ ppd_cpvalue_t current; /* Current value */ } ppd_cparam_t; -typedef struct ppd_coption_s /**** Custom Option @since CUPS 1.2/macOS 10.5@ ****/ +typedef struct ppd_coption_s /**** Custom Option @deprecated@ ****/ { char keyword[PPD_MAX_NAME]; /* Name of option that is being extended... */ ppd_option_t *option; /* Option that is being extended... */ @@ -287,9 +281,9 @@ typedef struct ppd_coption_s /**** Custom Option @since CUPS 1.2/macOS 10.5@ ** } ppd_coption_t; typedef struct _ppd_cache_s _ppd_cache_t; - /**** PPD cache and mapping data @since CUPS 1.5/macOS 10.7@ @private@ ****/ + /**** PPD cache and mapping data @deprecated@ ****/ -typedef struct ppd_file_s /**** PPD File ****/ +typedef struct ppd_file_s /**** PPD File @deprecated@ ****/ { int language_level; /* Language level of device */ int color_device; /* 1 = color device, 0 = grayscale */ @@ -302,8 +296,8 @@ typedef struct ppd_file_s /**** PPD File ****/ int throughput; /* Pages per minute */ ppd_cs_t colorspace; /* Default colorspace */ char *patches; /* Patch commands to be sent to printer */ - int num_emulations; /* Number of emulations supported */ - ppd_emul_t *emulations; /* Emulations and the code to invoke them */ + int num_emulations; /* Number of emulations supported (no longer supported) @private@ */ + ppd_emul_t *emulations; /* Emulations and the code to invoke them (no longer supported) @private@ */ char *jcl_begin; /* Start JCL commands */ char *jcl_ps; /* Enter PostScript interpreter */ char *jcl_end; /* End JCL commands */ @@ -361,115 +355,115 @@ typedef struct ppd_file_s /**** PPD File ****/ * Prototypes... */ -extern const char *cupsGetPPD(const char *name) _PPD_DEPRECATED; -extern const char *cupsGetPPD2(http_t *http, const char *name) _PPD_DEPRECATED; -extern http_status_t cupsGetPPD3(http_t *http, const char *name, time_t *modtime, char *buffer, size_t bufsize) _PPD_DEPRECATED; -extern char *cupsGetServerPPD(http_t *http, const char *name) _PPD_DEPRECATED; -extern int cupsMarkOptions(ppd_file_t *ppd, int num_options, cups_option_t *options) _PPD_DEPRECATED; +extern const char *cupsGetPPD(const char *name) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); +extern const char *cupsGetPPD2(http_t *http, const char *name) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); +extern http_status_t cupsGetPPD3(http_t *http, const char *name, time_t *modtime, char *buffer, size_t bufsize) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); +extern char *cupsGetServerPPD(http_t *http, const char *name) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); +extern int cupsMarkOptions(ppd_file_t *ppd, int num_options, cups_option_t *options) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); -extern void ppdClose(ppd_file_t *ppd) _PPD_DEPRECATED; +extern void ppdClose(ppd_file_t *ppd) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern int ppdCollect(ppd_file_t *ppd, ppd_section_t section, - ppd_choice_t ***choices) _PPD_DEPRECATED; -extern int ppdConflicts(ppd_file_t *ppd) _PPD_DEPRECATED; + ppd_choice_t ***choices) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); +extern int ppdConflicts(ppd_file_t *ppd) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern int ppdEmit(ppd_file_t *ppd, FILE *fp, - ppd_section_t section) _PPD_DEPRECATED; + ppd_section_t section) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern int ppdEmitFd(ppd_file_t *ppd, int fd, - ppd_section_t section) _PPD_DEPRECATED; + ppd_section_t section) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern int ppdEmitJCL(ppd_file_t *ppd, FILE *fp, int job_id, const char *user, const char *title) - _PPD_DEPRECATED; + _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern ppd_choice_t *ppdFindChoice(ppd_option_t *o, const char *option) - _PPD_DEPRECATED; + _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern ppd_choice_t *ppdFindMarkedChoice(ppd_file_t *ppd, const char *keyword) - _PPD_DEPRECATED; + _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern ppd_option_t *ppdFindOption(ppd_file_t *ppd, const char *keyword) - _PPD_DEPRECATED; + _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern int ppdIsMarked(ppd_file_t *ppd, const char *keyword, - const char *option) _PPD_DEPRECATED; -extern void ppdMarkDefaults(ppd_file_t *ppd) _PPD_DEPRECATED; + const char *option) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); +extern void ppdMarkDefaults(ppd_file_t *ppd) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern int ppdMarkOption(ppd_file_t *ppd, const char *keyword, - const char *option) _PPD_DEPRECATED; -extern ppd_file_t *ppdOpen(FILE *fp) _PPD_DEPRECATED; -extern ppd_file_t *ppdOpenFd(int fd) _PPD_DEPRECATED; -extern ppd_file_t *ppdOpenFile(const char *filename) _PPD_DEPRECATED; + const char *option) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); +extern ppd_file_t *ppdOpen(FILE *fp) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); +extern ppd_file_t *ppdOpenFd(int fd) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); +extern ppd_file_t *ppdOpenFile(const char *filename) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern float ppdPageLength(ppd_file_t *ppd, const char *name) - _PPD_DEPRECATED; + _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern ppd_size_t *ppdPageSize(ppd_file_t *ppd, const char *name) - _PPD_DEPRECATED; + _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern float ppdPageWidth(ppd_file_t *ppd, const char *name) - _PPD_DEPRECATED; + _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); /**** New in CUPS 1.1.19 ****/ -extern const char *ppdErrorString(ppd_status_t status) _PPD_DEPRECATED; +extern const char *ppdErrorString(ppd_status_t status) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern ppd_attr_t *ppdFindAttr(ppd_file_t *ppd, const char *name, - const char *spec) _PPD_DEPRECATED; + const char *spec) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern ppd_attr_t *ppdFindNextAttr(ppd_file_t *ppd, const char *name, - const char *spec) _PPD_DEPRECATED; -extern ppd_status_t ppdLastError(int *line) _PPD_DEPRECATED; + const char *spec) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); +extern ppd_status_t ppdLastError(int *line) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); /**** New in CUPS 1.1.20 ****/ -extern void ppdSetConformance(ppd_conform_t c) _PPD_DEPRECATED; +extern void ppdSetConformance(ppd_conform_t c) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); /**** New in CUPS 1.2 ****/ extern int cupsRasterInterpretPPD(cups_page_header2_t *h, ppd_file_t *ppd, int num_options, cups_option_t *options, - cups_interpret_cb_t func) _PPD_DEPRECATED; + cups_interpret_cb_t func) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern int ppdCollect2(ppd_file_t *ppd, ppd_section_t section, float min_order, ppd_choice_t ***choices) - _PPD_DEPRECATED; + _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern int ppdEmitAfterOrder(ppd_file_t *ppd, FILE *fp, ppd_section_t section, int limit, - float min_order) _PPD_DEPRECATED; + float min_order) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern int ppdEmitJCLEnd(ppd_file_t *ppd, FILE *fp) - _PPD_DEPRECATED; + _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern char *ppdEmitString(ppd_file_t *ppd, ppd_section_t section, - float min_order) _PPD_DEPRECATED; + float min_order) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern ppd_coption_t *ppdFindCustomOption(ppd_file_t *ppd, const char *keyword) - _PPD_DEPRECATED; + _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern ppd_cparam_t *ppdFindCustomParam(ppd_coption_t *opt, - const char *name) _PPD_DEPRECATED; + const char *name) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern ppd_cparam_t *ppdFirstCustomParam(ppd_coption_t *opt) - _PPD_DEPRECATED; -extern ppd_option_t *ppdFirstOption(ppd_file_t *ppd) _PPD_DEPRECATED; -extern ppd_cparam_t *ppdNextCustomParam(ppd_coption_t *opt) _PPD_DEPRECATED; -extern ppd_option_t *ppdNextOption(ppd_file_t *ppd) _PPD_DEPRECATED; -extern int ppdLocalize(ppd_file_t *ppd) _PPD_DEPRECATED; -extern ppd_file_t *ppdOpen2(cups_file_t *fp) _PPD_DEPRECATED; + _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); +extern ppd_option_t *ppdFirstOption(ppd_file_t *ppd) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); +extern ppd_cparam_t *ppdNextCustomParam(ppd_coption_t *opt) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); +extern ppd_option_t *ppdNextOption(ppd_file_t *ppd) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); +extern int ppdLocalize(ppd_file_t *ppd) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); +extern ppd_file_t *ppdOpen2(cups_file_t *fp) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); /**** New in CUPS 1.3/macOS 10.5 ****/ extern const char *ppdLocalizeIPPReason(ppd_file_t *ppd, const char *reason, const char *scheme, char *buffer, - size_t bufsize) _PPD_DEPRECATED; + size_t bufsize) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); /**** New in CUPS 1.4/macOS 10.6 ****/ extern int cupsGetConflicts(ppd_file_t *ppd, const char *option, const char *choice, cups_option_t **options) - _PPD_DEPRECATED; + _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern int cupsResolveConflicts(ppd_file_t *ppd, const char *option, const char *choice, int *num_options, cups_option_t **options) - _PPD_DEPRECATED; + _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern int ppdInstallableConflict(ppd_file_t *ppd, const char *option, const char *choice) - _PPD_DEPRECATED; + _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern ppd_attr_t *ppdLocalizeAttr(ppd_file_t *ppd, const char *keyword, - const char *spec) _PPD_DEPRECATED; + const char *spec) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern const char *ppdLocalizeMarkerName(ppd_file_t *ppd, const char *name) - _PPD_DEPRECATED; + _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); extern int ppdPageSizeLimits(ppd_file_t *ppd, ppd_size_t *minimum, - ppd_size_t *maximum) _PPD_DEPRECATED; + ppd_size_t *maximum) _CUPS_DEPRECATED_1_6_MSG("Use cupsCopyDestInfo and friends instead."); /* diff --git a/cups/pwg-media.c b/cups/pwg-media.c index 73356fd..00bb2ed 100644 --- a/cups/pwg-media.c +++ b/cups/pwg-media.c @@ -1,15 +1,10 @@ /* * PWG media name API implementation for CUPS. * - * Copyright 2009-2017 by Apple Inc. + * Copyright 2009-2019 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -17,6 +12,7 @@ */ #include "cups-private.h" +#include "debug-internal.h" #include @@ -26,6 +22,7 @@ #define _PWG_MEDIA_IN(p,l,a,x,y) {p, l, a, (int)(x * 2540), (int)(y * 2540)} #define _PWG_MEDIA_MM(p,l,a,x,y) {p, l, a, (int)(x * 100), (int)(y * 100)} +#define _PWG_EPSILON 50 /* Matching tolerance */ /* @@ -189,6 +186,7 @@ static pwg_media_t const cups_pwg_media[] = _PWG_MEDIA_MM("jis_b1_728x1030mm", "jis-b1", "B1", 728, 1030), _PWG_MEDIA_MM("jis_b0_1030x1456mm", "jis-b0", "B0", 1030, 1456), _PWG_MEDIA_MM("jis_exec_216x330mm", NULL, "216x330mm", 216, 330), + _PWG_MEDIA_MM("jpn_kaku1_270x382mm", NULL, "EnvKaku1", 270, 382), _PWG_MEDIA_MM("jpn_kaku2_240x332mm", NULL, "EnvKaku2", 240, 332), _PWG_MEDIA_MM("jpn_kaku3_216x277mm", NULL, "EnvKaku3", 216, 277), _PWG_MEDIA_MM("jpn_kaku4_197x267mm", NULL, "EnvKaku4", 197, 267), @@ -843,18 +841,22 @@ pwgMediaForPWG(const char *pwg) /* I - PWG size name */ /* * Try decoding the self-describing name of the form: * - * class_name_WWWxHHHin - * class_name_WWWxHHHmm + * class_name_WWWxHHHin[_something] + * class_name_WWWxHHHmm[_something] */ int w, l; /* Width and length of page */ int numer; /* Scale factor for units */ - const char *units = ptr + strlen(ptr) - 2; - /* Units from size */ + const char *units; /* Units from size */ - ptr ++; + if ((units = strchr(ptr + 1, '_')) != NULL) + units -= 2; + else + units = ptr + strlen(ptr) - 2; - if (units >= ptr && !strcmp(units, "in")) + ptr ++; + + if (units >= ptr && (!strcmp(units, "in") || !strncmp(units, "in_", 3))) numer = 2540; else numer = 100; @@ -911,10 +913,11 @@ pwgMediaForSize(int width, /* I - Width in hundredths of millimeters */ { /* * Adobe uses a size matching algorithm with an epsilon of 5 points, which - * is just about 176/2540ths... + * is just about 176/2540ths... But a lot of international media sizes are + * very close so use 0.5mm (50/2540ths) as the maximum delta. */ - return (_pwgMediaNearSize(width, length, 176)); + return (_pwgMediaNearSize(width, length, _PWG_EPSILON)); } diff --git a/cups/pwg-private.h b/cups/pwg-private.h index e771590..e93a7f8 100644 --- a/cups/pwg-private.h +++ b/cups/pwg-private.h @@ -3,13 +3,7 @@ * * Copyright 2009-2016 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ #ifndef _CUPS_PWG_PRIVATE_H_ @@ -44,8 +38,8 @@ extern void _pwgGenerateSize(char *keyword, size_t keysize, extern int _pwgInitSize(pwg_size_t *size, ipp_t *job, int *margins_set) _CUPS_INTERNAL_MSG("Use pwgInitSize instead."); -extern const pwg_media_t *_pwgMediaTable(size_t *num_media); -extern pwg_media_t *_pwgMediaNearSize(int width, int length, int epsilon); +extern const pwg_media_t *_pwgMediaTable(size_t *num_media) _CUPS_PRIVATE; +extern pwg_media_t *_pwgMediaNearSize(int width, int length, int epsilon) _CUPS_PRIVATE; # ifdef __cplusplus } diff --git a/cups/pwg.h b/cups/pwg.h index 4204050..2d30847 100644 --- a/cups/pwg.h +++ b/cups/pwg.h @@ -3,13 +3,7 @@ * * Copyright 2009-2017 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ #ifndef _CUPS_PWG_H_ diff --git a/cups/raster-error.c b/cups/raster-error.c new file mode 100644 index 0000000..66f91e4 --- /dev/null +++ b/cups/raster-error.c @@ -0,0 +1,132 @@ +/* + * Raster error handling for CUPS. + * + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 2007 by Easy Software Products. + * + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. + */ + +/* + * Include necessary headers... + */ + +#include "cups-private.h" +#include "raster-private.h" +#include "debug-internal.h" + + +/* + * '_cupsRasterAddError()' - Add an error message to the error buffer. + */ + +void +_cupsRasterAddError(const char *f, /* I - Printf-style error message */ + ...) /* I - Additional arguments as needed */ +{ + _cups_globals_t *cg = _cupsGlobals(); + /* Thread globals */ + _cups_raster_error_t *buf = &cg->raster_error; + /* Error buffer */ + va_list ap; /* Pointer to additional arguments */ + char s[2048]; /* Message string */ + ssize_t bytes; /* Bytes in message string */ + + + DEBUG_printf(("_cupsRasterAddError(f=\"%s\", ...)", f)); + + va_start(ap, f); + bytes = vsnprintf(s, sizeof(s), f, ap); + va_end(ap); + + if (bytes <= 0) + return; + + DEBUG_printf(("1_cupsRasterAddError: %s", s)); + + bytes ++; + + if ((size_t)bytes >= sizeof(s)) + return; + + if (bytes > (ssize_t)(buf->end - buf->current)) + { + /* + * Allocate more memory... + */ + + char *temp; /* New buffer */ + size_t size; /* Size of buffer */ + + + size = (size_t)(buf->end - buf->start + 2 * bytes + 1024); + + if (buf->start) + temp = realloc(buf->start, size); + else + temp = malloc(size); + + if (!temp) + return; + + /* + * Update pointers... + */ + + buf->end = temp + size; + buf->current = temp + (buf->current - buf->start); + buf->start = temp; + } + + /* + * Append the message to the end of the current string... + */ + + memcpy(buf->current, s, (size_t)bytes); + buf->current += bytes - 1; +} + + +/* + * '_cupsRasterClearError()' - Clear the error buffer. + */ + +void +_cupsRasterClearError(void) +{ + _cups_globals_t *cg = _cupsGlobals(); + /* Thread globals */ + _cups_raster_error_t *buf = &cg->raster_error; + /* Error buffer */ + + + buf->current = buf->start; + + if (buf->start) + *(buf->start) = '\0'; +} + + +/* + * '_cupsRasterErrorString()' - Return the last error from a raster function. + * + * If there are no recent errors, NULL is returned. + * + * @since CUPS 1.3/macOS 10.5@ + */ + +const char * /* O - Last error */ +_cupsRasterErrorString(void) +{ + _cups_globals_t *cg = _cupsGlobals(); + /* Thread globals */ + _cups_raster_error_t *buf = &cg->raster_error; + /* Error buffer */ + + + if (buf->current == buf->start) + return (NULL); + else + return (buf->start); +} diff --git a/filter/interpret.c b/cups/raster-interpret.c similarity index 98% rename from filter/interpret.c rename to cups/raster-interpret.c index 031b1d5..fbe52f3 100644 --- a/filter/interpret.c +++ b/cups/raster-interpret.c @@ -1,16 +1,11 @@ /* * PPD command interpreter for CUPS. * - * Copyright 2007-2015 by Apple Inc. - * Copyright 1993-2007 by Easy Software Products. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1993-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -18,7 +13,8 @@ */ #include -#include +#include +#include "debug-internal.h" /* @@ -96,7 +92,7 @@ static void DEBUG_stack(const char *prefix, _cups_ps_stack_t *st); /* - * 'cupsRasterInterpretPPD()' - Interpret PPD commands to create a page header. + * '_cupsRasterInterpretPPD()' - Interpret PPD commands to create a page header. * * This function is used by raster image processing (RIP) filters like * cgpdftoraster and imagetoraster when writing CUPS raster data for a page. @@ -126,7 +122,7 @@ static void DEBUG_stack(const char *prefix, _cups_ps_stack_t *st); */ int /* O - 0 on success, -1 on failure */ -cupsRasterInterpretPPD( +_cupsRasterInterpretPPD( cups_page_header2_t *h, /* O - Page header to create */ ppd_file_t *ppd, /* I - PPD file */ int num_options, /* I - Number of options */ diff --git a/cups/raster-interstub.c b/cups/raster-interstub.c new file mode 100644 index 0000000..8355d22 --- /dev/null +++ b/cups/raster-interstub.c @@ -0,0 +1,63 @@ +/* + * cupsRasterInterpretPPD stub for CUPS. + * + * Copyright © 2018 by Apple Inc. + * + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. + */ + +/* + * Include necessary headers... + */ + +#include + + +/* + * This stub wraps the _cupsRasterInterpretPPD function in libcups - this allows + * one library to provide all of the CUPS API functions while still supporting + * the old split library organization... + */ + + +/* + * 'cupsRasterInterpretPPD()' - Interpret PPD commands to create a page header. + * + * This function is used by raster image processing (RIP) filters like + * cgpdftoraster and imagetoraster when writing CUPS raster data for a page. + * It is not used by raster printer driver filters which only read CUPS + * raster data. + * + * + * @code cupsRasterInterpretPPD@ does not mark the options in the PPD using + * the "num_options" and "options" arguments. Instead, mark the options with + * @code cupsMarkOptions@ and @code ppdMarkOption@ prior to calling it - + * this allows for per-page options without manipulating the options array. + * + * The "func" argument specifies an optional callback function that is + * called prior to the computation of the final raster data. The function + * can make changes to the @link cups_page_header2_t@ data as needed to use a + * supported raster format and then returns 0 on success and -1 if the + * requested attributes cannot be supported. + * + * + * @code cupsRasterInterpretPPD@ supports a subset of the PostScript language. + * Currently only the @code [@, @code ]@, @code <<@, @code >>@, @code {@, + * @code }@, @code cleartomark@, @code copy@, @code dup@, @code index@, + * @code pop@, @code roll@, @code setpagedevice@, and @code stopped@ operators + * are supported. + * + * @since CUPS 1.2/macOS 10.5@ + */ + +int /* O - 0 on success, -1 on failure */ +cupsRasterInterpretPPD( + cups_page_header2_t *h, /* O - Page header to create */ + ppd_file_t *ppd, /* I - PPD file */ + int num_options, /* I - Number of options */ + cups_option_t *options, /* I - Options */ + cups_interpret_cb_t func) /* I - Optional page header callback (@code NULL@ for none) */ +{ + return (_cupsRasterInterpretPPD(h, ppd, num_options, options, func)); +} diff --git a/cups/raster-private.h b/cups/raster-private.h index 3813581..4b03dbc 100644 --- a/cups/raster-private.h +++ b/cups/raster-private.h @@ -1,16 +1,11 @@ /* * Private image library definitions for CUPS. * - * Copyright 2007-2015 by Apple Inc. - * Copyright 1993-2006 by Easy Software Products. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1993-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ #ifndef _CUPS_RASTER_PRIVATE_H_ @@ -24,15 +19,52 @@ # include # include # include -# ifdef WIN32 +# ifdef _WIN32 # include # include /* for htonl() definition */ # else # include # include -# endif /* WIN32 */ +# endif /* _WIN32 */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ +/* + * Structure... + */ + +struct _cups_raster_s /**** Raster stream data ****/ +{ + unsigned sync; /* Sync word from start of stream */ + void *ctx; /* File descriptor */ + cups_raster_iocb_t iocb; /* IO callback */ + cups_mode_t mode; /* Read/write mode */ + cups_page_header2_t header; /* Raster header for current page */ + unsigned rowheight, /* Row height in lines */ + count, /* Current row run-length count */ + remaining, /* Remaining rows in page image */ + bpp; /* Bytes per pixel/color */ + unsigned char *pixels, /* Pixels for current row */ + *pend, /* End of pixel buffer */ + *pcurrent; /* Current byte in pixel buffer */ + int compressed, /* Non-zero if data is compressed */ + swapped; /* Non-zero if data is byte-swapped */ + unsigned char *buffer, /* Read/write buffer */ + *bufptr, /* Current (read) position in buffer */ + *bufend; /* End of current (read) buffer */ + size_t bufsize; /* Buffer size */ +# ifdef DEBUG + size_t iostart, /* Start of read/write buffer */ + iocount; /* Number of bytes read/written */ +# endif /* DEBUG */ + unsigned apple_page_count;/* Apple raster page count */ +}; + + +#if 0 /* * min/max macros... */ @@ -43,18 +75,27 @@ # ifndef min # define min(a,b) ((a) < (b) ? (a) : (b)) # endif /* !min */ +#endif // 0 /* * Prototypes... */ -extern int _cupsRasterExecPS(cups_page_header2_t *h, - int *preferred_bits, - const char *code) - __attribute__((nonnull(3))); -extern void _cupsRasterAddError(const char *f, ...) - __attribute__((__format__(__printf__, 1, 2))); -extern void _cupsRasterClearError(void); +extern void _cupsRasterAddError(const char *f, ...) _CUPS_FORMAT(1,2) _CUPS_PRIVATE; +extern void _cupsRasterClearError(void) _CUPS_PRIVATE; +extern const char *_cupsRasterColorSpaceString(cups_cspace_t cspace) _CUPS_PRIVATE; +extern void _cupsRasterDelete(cups_raster_t *r) _CUPS_PRIVATE; +extern const char *_cupsRasterErrorString(void) _CUPS_PRIVATE; +extern int _cupsRasterInitPWGHeader(cups_page_header2_t *h, pwg_media_t *media, const char *type, int xdpi, int ydpi, const char *sides, const char *sheet_back) _CUPS_PRIVATE; +extern cups_raster_t *_cupsRasterNew(cups_raster_iocb_t iocb, void *ctx, cups_mode_t mode) _CUPS_PRIVATE; +extern unsigned _cupsRasterReadHeader(cups_raster_t *r) _CUPS_PRIVATE; +extern unsigned _cupsRasterReadPixels(cups_raster_t *r, unsigned char *p, unsigned len) _CUPS_PRIVATE; +extern unsigned _cupsRasterWriteHeader(cups_raster_t *r) _CUPS_PRIVATE; +extern unsigned _cupsRasterWritePixels(cups_raster_t *r, unsigned char *p, unsigned len) _CUPS_PRIVATE; + +# ifdef __cplusplus +} +# endif /* __cplusplus */ #endif /* !_CUPS_RASTER_PRIVATE_H_ */ diff --git a/filter/raster.c b/cups/raster-stream.c similarity index 69% rename from filter/raster.c rename to cups/raster-stream.c index bacf5ba..d7db020 100644 --- a/filter/raster.c +++ b/cups/raster-stream.c @@ -1,25 +1,21 @@ /* * Raster file routines for CUPS. * - * Copyright 2007-2016 by Apple Inc. + * Copyright 2007-2018 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * * This file is part of the CUPS Imaging library. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* * Include necessary headers... */ -#include +#include "raster-private.h" +#include "debug-internal.h" #ifdef HAVE_STDINT_H # include #endif /* HAVE_STDINT_H */ @@ -29,31 +25,23 @@ * Private structures... */ -struct _cups_raster_s /**** Raster stream data ****/ -{ - unsigned sync; /* Sync word from start of stream */ - void *ctx; /* File descriptor */ - cups_raster_iocb_t iocb; /* IO callback */ - cups_mode_t mode; /* Read/write mode */ - cups_page_header2_t header; /* Raster header for current page */ - unsigned rowheight, /* Row height in lines */ - count, /* Current row run-length count */ - remaining, /* Remaining rows in page image */ - bpp; /* Bytes per pixel/color */ - unsigned char *pixels, /* Pixels for current row */ - *pend, /* End of pixel buffer */ - *pcurrent; /* Current byte in pixel buffer */ - int compressed, /* Non-zero if data is compressed */ - swapped; /* Non-zero if data is byte-swapped */ - unsigned char *buffer, /* Read/write buffer */ - *bufptr, /* Current (read) position in buffer */ - *bufend; /* End of current (read) buffer */ - size_t bufsize; /* Buffer size */ +typedef void (*_cups_copyfunc_t)(void *dst, const void *src, size_t bytes); + + +/* + * Local globals... + */ + #ifdef DEBUG - size_t iocount; /* Number of bytes read/written */ -#endif /* DEBUG */ - unsigned apple_page_count;/* Apple raster page count */ +static const char * const cups_modes[] = +{ /* Open modes */ + "CUPS_RASTER_READ", + "CUPS_RASTER_WRITE", + "CUPS_RASTER_WRITE_COMPRESSED", + "CUPS_RASTER_WRITE_PWG", + "CUPS_RASTER_WRITE_APPLE" }; +#endif /* DEBUG */ /* @@ -61,26 +49,105 @@ struct _cups_raster_s /**** Raster stream data ****/ */ static ssize_t cups_raster_io(cups_raster_t *r, unsigned char *buf, size_t bytes); -static unsigned cups_raster_read_header(cups_raster_t *r); -static ssize_t cups_raster_read(cups_raster_t *r, unsigned char *buf, - size_t bytes); +static ssize_t cups_raster_read(cups_raster_t *r, unsigned char *buf, size_t bytes); static int cups_raster_update(cups_raster_t *r); -static ssize_t cups_raster_write(cups_raster_t *r, - const unsigned char *pixels); -static ssize_t cups_read_fd(void *ctx, unsigned char *buf, size_t bytes); +static ssize_t cups_raster_write(cups_raster_t *r, const unsigned char *pixels); static void cups_swap(unsigned char *buf, size_t bytes); -static ssize_t cups_write_fd(void *ctx, unsigned char *buf, size_t bytes); +static void cups_swap_copy(unsigned char *dst, const unsigned char *src, size_t bytes); /* - * 'cupsRasterClose()' - Close a raster stream. + * '_cupsRasterColorSpaceString()' - Return the colorspace name for a + * cupsColorSpace value. + */ + +const char * +_cupsRasterColorSpaceString( + cups_cspace_t cspace) /* I - cupsColorSpace value */ +{ + static const char * const cups_color_spaces[] = + { /* Color spaces */ + "W", + "RGB", + "RGBA", + "K", + "CMY", + "YMC", + "CMYK", + "YMCK", + "KCMY", + "KCMYcm", + "GMCK", + "GMCS", + "WHITE", + "GOLD", + "SILVER", + "CIEXYZ", + "CIELab", + "RGBW", + "SW", + "SRGB", + "ADOBERGB", + "21", + "22", + "23", + "24", + "25", + "26", + "27", + "28", + "29", + "30", + "31", + "ICC1", + "ICC2", + "ICC3", + "ICC4", + "ICC5", + "ICC6", + "ICC7", + "ICC8", + "ICC9", + "ICCA", + "ICCB", + "ICCC", + "ICCD", + "ICCE", + "ICCF", + "47", + "DEVICE1", + "DEVICE2", + "DEVICE3", + "DEVICE4", + "DEVICE5", + "DEVICE6", + "DEVICE7", + "DEVICE8", + "DEVICE9", + "DEVICEA", + "DEVICEB", + "DEVICEC", + "DEVICED", + "DEVICEE", + "DEVICEF" + }; + + if (cspace < CUPS_CSPACE_W || cspace > CUPS_CSPACE_DEVICEF) + return ("Unknown"); + else + return (cups_color_spaces[cspace]); +} + + +/* + * '_cupsRasterDelete()' - Free a raster stream. * * The file descriptor associated with the raster stream must be closed * separately as needed. */ void -cupsRasterClose(cups_raster_t *r) /* I - Stream to close */ +_cupsRasterDelete(cups_raster_t *r) /* I - Stream to free */ { if (r != NULL) { @@ -96,7 +163,7 @@ cupsRasterClose(cups_raster_t *r) /* I - Stream to close */ /* - * 'cupsRasterInitPWGHeader()' - Initialize a page header for PWG Raster output. + * '_cupsRasterInitPWGHeader()' - Initialize a page header for PWG Raster output. * * The "media" argument specifies the media to use. * @@ -113,7 +180,7 @@ cupsRasterClose(cups_raster_t *r) /* I - Stream to close */ */ int /* O - 1 on success, 0 on failure */ -cupsRasterInitPWGHeader( +_cupsRasterInitPWGHeader( cups_page_header2_t *h, /* I - Page header */ pwg_media_t *media, /* I - PWG media information */ const char *type, /* I - PWG raster type string */ @@ -336,35 +403,7 @@ cupsRasterInitPWGHeader( /* - * 'cupsRasterOpen()' - Open a raster stream using a file descriptor. - * - * This function associates a raster stream with the given file descriptor. - * For most printer driver filters, "fd" will be 0 (stdin). For most raster - * image processor (RIP) filters that generate raster data, "fd" will be 1 - * (stdout). - * - * When writing raster data, the @code CUPS_RASTER_WRITE@, - * @code CUPS_RASTER_WRITE_COMPRESS@, or @code CUPS_RASTER_WRITE_PWG@ mode can - * be used - compressed and PWG output is generally 25-50% smaller but adds a - * 100-300% execution time overhead. - */ - -cups_raster_t * /* O - New stream */ -cupsRasterOpen(int fd, /* I - File descriptor */ - cups_mode_t mode) /* I - Mode - @code CUPS_RASTER_READ@, - @code CUPS_RASTER_WRITE@, - @code CUPS_RASTER_WRITE_COMPRESSED@, - or @code CUPS_RASTER_WRITE_PWG@ */ -{ - if (mode == CUPS_RASTER_READ) - return (cupsRasterOpenIO(cups_read_fd, (void *)((intptr_t)fd), mode)); - else - return (cupsRasterOpenIO(cups_write_fd, (void *)((intptr_t)fd), mode)); -} - - -/* - * 'cupsRasterOpenIO()' - Open a raster stream using a callback function. + * '_cupsRasterNew()' - Create a raster stream using a callback function. * * This function associates a raster stream with the given callback function and * context pointer. @@ -376,7 +415,7 @@ cupsRasterOpen(int fd, /* I - File descriptor */ */ cups_raster_t * /* O - New stream */ -cupsRasterOpenIO( +_cupsRasterNew( cups_raster_iocb_t iocb, /* I - Read/write callback */ void *ctx, /* I - Context pointer for callback */ cups_mode_t mode) /* I - Mode - @code CUPS_RASTER_READ@, @@ -387,12 +426,15 @@ cupsRasterOpenIO( cups_raster_t *r; /* New stream */ + DEBUG_printf(("_cupsRasterOpenIO(iocb=%p, ctx=%p, mode=%s)", (void *)iocb, ctx, cups_modes[mode])); + _cupsRasterClearError(); if ((r = calloc(sizeof(cups_raster_t), 1)) == NULL) { _cupsRasterAddError("Unable to allocate memory for raster stream: %s\n", strerror(errno)); + DEBUG_puts("1_cupsRasterOpenIO: Returning NULL."); return (NULL); } @@ -412,6 +454,7 @@ cupsRasterOpenIO( _cupsRasterAddError("Unable to read header from raster stream: %s\n", strerror(errno)); free(r); + DEBUG_puts("1_cupsRasterOpenIO: Unable to read header, returning NULL."); return (NULL); } @@ -426,6 +469,7 @@ cupsRasterOpenIO( { _cupsRasterAddError("Unknown raster format %08x!\n", r->sync); free(r); + DEBUG_puts("1_cupsRasterOpenIO: Unknown format, returning NULL."); return (NULL); } @@ -435,6 +479,8 @@ cupsRasterOpenIO( r->sync == CUPS_RASTER_REVSYNCapple) r->compressed = 1; + DEBUG_printf(("1_cupsRasterOpenIO: sync=%08x", r->sync)); + if (r->sync == CUPS_RASTER_REVSYNC || r->sync == CUPS_RASTER_REVSYNCv1 || r->sync == CUPS_RASTER_REVSYNCv2 || @@ -452,12 +498,14 @@ cupsRasterOpenIO( _cupsRasterAddError("Unable to read header from raster stream: %s\n", strerror(errno)); free(r); + DEBUG_puts("1_cupsRasterOpenIO: Unable to read header, returning NULL."); return (NULL); } - } - DEBUG_printf(("1cupsRasterOpenIO: r->swapped=%d, r->sync=%08x\n", r->swapped, r->sync)); +#ifdef DEBUG + r->iostart = r->iocount; +#endif /* DEBUG */ } else { @@ -496,88 +544,170 @@ cupsRasterOpenIO( _cupsRasterAddError("Unable to write raster stream header: %s\n", strerror(errno)); free(r); + DEBUG_puts("1_cupsRasterOpenIO: Unable to write header, returning NULL."); return (NULL); } } + DEBUG_printf(("1_cupsRasterOpenIO: compressed=%d, swapped=%d, returning %p", r->compressed, r->swapped, (void *)r)); + return (r); } /* - * 'cupsRasterReadHeader()' - Read a raster page header and store it in a - * version 1 page header structure. - * - * This function is deprecated. Use @link cupsRasterReadHeader2@ instead. - * - * Version 1 page headers were used in CUPS 1.0 and 1.1 and contain a subset - * of the version 2 page header data. This function handles reading version 2 - * page headers and copying only the version 1 data into the provided buffer. - * - * @deprecated@ + * '_cupsRasterReadHeader()' - Read a raster page header. */ -unsigned /* O - 1 on success, 0 on failure/end-of-file */ -cupsRasterReadHeader( - cups_raster_t *r, /* I - Raster stream */ - cups_page_header_t *h) /* I - Pointer to header data */ +unsigned /* O - 1 on success, 0 on fail */ +_cupsRasterReadHeader( + cups_raster_t *r) /* I - Raster stream */ { + size_t len; /* Length for read/swap */ + + + DEBUG_printf(("3_cupsRasterReadHeader(r=%p), r->mode=%s", (void *)r, r ? cups_modes[r->mode] : "")); + + if (r == NULL || r->mode != CUPS_RASTER_READ) + return (0); + + DEBUG_printf(("4_cupsRasterReadHeader: r->iocount=" CUPS_LLFMT, CUPS_LLCAST r->iocount)); + + memset(&(r->header), 0, sizeof(r->header)); + /* - * Get the raster header... + * Read the header... */ - if (!cups_raster_read_header(r)) + switch (r->sync) { - memset(h, 0, sizeof(cups_page_header_t)); - return (0); + default : + /* + * Get the length of the raster header... + */ + + if (r->sync == CUPS_RASTER_SYNCv1 || r->sync == CUPS_RASTER_REVSYNCv1) + len = sizeof(cups_page_header_t); + else + len = sizeof(cups_page_header2_t); + + DEBUG_printf(("4_cupsRasterReadHeader: len=%d", (int)len)); + + /* + * Read it... + */ + + if (cups_raster_read(r, (unsigned char *)&(r->header), len) < (ssize_t)len) + { + DEBUG_printf(("4_cupsRasterReadHeader: EOF, r->iocount=" CUPS_LLFMT, CUPS_LLCAST r->iocount)); + return (0); + } + + /* + * Swap bytes as needed... + */ + + if (r->swapped) + { + unsigned *s, /* Current word */ + temp; /* Temporary copy */ + + + DEBUG_puts("4_cupsRasterReadHeader: Swapping header bytes."); + + for (len = 81, s = &(r->header.AdvanceDistance); + len > 0; + len --, s ++) + { + temp = *s; + *s = ((temp & 0xff) << 24) | + ((temp & 0xff00) << 8) | + ((temp & 0xff0000) >> 8) | + ((temp & 0xff000000) >> 24); + + DEBUG_printf(("4_cupsRasterReadHeader: %08x => %08x", temp, *s)); + } + } + break; + + case CUPS_RASTER_SYNCapple : + case CUPS_RASTER_REVSYNCapple : + { + unsigned char appleheader[32]; /* Raw header */ + static const unsigned rawcspace[] = + { + CUPS_CSPACE_SW, + CUPS_CSPACE_SRGB, + CUPS_CSPACE_RGBW, + CUPS_CSPACE_ADOBERGB, + CUPS_CSPACE_W, + CUPS_CSPACE_RGB, + CUPS_CSPACE_CMYK + }; + static const unsigned rawnumcolors[] = + { + 1, + 3, + 4, + 3, + 1, + 3, + 4 + }; + + if (cups_raster_read(r, appleheader, sizeof(appleheader)) < (ssize_t)sizeof(appleheader)) + { + DEBUG_printf(("4_cupsRasterReadHeader: EOF, r->iocount=" CUPS_LLFMT, CUPS_LLCAST r->iocount)); + return (0); + } + + strlcpy(r->header.MediaClass, "PwgRaster", sizeof(r->header.MediaClass)); + /* PwgRaster */ + r->header.cupsBitsPerPixel = appleheader[0]; + r->header.cupsColorSpace = appleheader[1] >= (sizeof(rawcspace) / sizeof(rawcspace[0])) ? CUPS_CSPACE_DEVICE1 : rawcspace[appleheader[1]]; + r->header.cupsNumColors = appleheader[1] >= (sizeof(rawnumcolors) / sizeof(rawnumcolors[0])) ? 1 : rawnumcolors[appleheader[1]]; + r->header.cupsBitsPerColor = r->header.cupsBitsPerPixel / r->header.cupsNumColors; + r->header.cupsWidth = ((((((unsigned)appleheader[12] << 8) | (unsigned)appleheader[13]) << 8) | (unsigned)appleheader[14]) << 8) | (unsigned)appleheader[15]; + r->header.cupsHeight = ((((((unsigned)appleheader[16] << 8) | (unsigned)appleheader[17]) << 8) | (unsigned)appleheader[18]) << 8) | (unsigned)appleheader[19]; + r->header.cupsBytesPerLine = r->header.cupsWidth * r->header.cupsBitsPerPixel / 8; + r->header.cupsColorOrder = CUPS_ORDER_CHUNKED; + r->header.HWResolution[0] = r->header.HWResolution[1] = ((((((unsigned)appleheader[20] << 8) | (unsigned)appleheader[21]) << 8) | (unsigned)appleheader[22]) << 8) | (unsigned)appleheader[23]; + + if (r->header.HWResolution[0] > 0) + { + r->header.PageSize[0] = (unsigned)(r->header.cupsWidth * 72 / r->header.HWResolution[0]); + r->header.PageSize[1] = (unsigned)(r->header.cupsHeight * 72 / r->header.HWResolution[1]); + r->header.cupsPageSize[0] = (float)(r->header.cupsWidth * 72.0 / r->header.HWResolution[0]); + r->header.cupsPageSize[1] = (float)(r->header.cupsHeight * 72.0 / r->header.HWResolution[1]); + } + + r->header.cupsInteger[0] = r->apple_page_count; + r->header.cupsInteger[7] = 0xffffff; + } + break; } /* - * Copy the header to the user-supplied buffer... + * Update the header and row count... */ - memcpy(h, &(r->header), sizeof(cups_page_header_t)); + if (!cups_raster_update(r)) + return (0); - return (1); + DEBUG_printf(("4_cupsRasterReadHeader: cupsColorSpace=%s", _cupsRasterColorSpaceString(r->header.cupsColorSpace))); + DEBUG_printf(("4_cupsRasterReadHeader: cupsBitsPerColor=%u", r->header.cupsBitsPerColor)); + DEBUG_printf(("4_cupsRasterReadHeader: cupsBitsPerPixel=%u", r->header.cupsBitsPerPixel)); + DEBUG_printf(("4_cupsRasterReadHeader: cupsBytesPerLine=%u", r->header.cupsBytesPerLine)); + DEBUG_printf(("4_cupsRasterReadHeader: cupsWidth=%u", r->header.cupsWidth)); + DEBUG_printf(("4_cupsRasterReadHeader: cupsHeight=%u", r->header.cupsHeight)); + DEBUG_printf(("4_cupsRasterReadHeader: r->bpp=%d", r->bpp)); + + return (r->header.cupsBitsPerPixel > 0 && r->header.cupsBitsPerPixel <= 240 && r->header.cupsBitsPerColor > 0 && r->header.cupsBitsPerColor <= 16 && r->header.cupsBytesPerLine > 0 && r->header.cupsBytesPerLine <= 0x7fffffff && r->header.cupsHeight != 0 && (r->header.cupsBytesPerLine % r->bpp) == 0); } /* - * 'cupsRasterReadHeader2()' - Read a raster page header and store it in a - * version 2 page header structure. - * - * @since CUPS 1.2/macOS 10.5@ - */ - -unsigned /* O - 1 on success, 0 on failure/end-of-file */ -cupsRasterReadHeader2( - cups_raster_t *r, /* I - Raster stream */ - cups_page_header2_t *h) /* I - Pointer to header data */ -{ - /* - * Get the raster header... - */ - - DEBUG_printf(("cupsRasterReadHeader2(r=%p, h=%p)", (void *)r, (void *)h)); - - if (!cups_raster_read_header(r)) - { - memset(h, 0, sizeof(cups_page_header2_t)); - return (0); - } - - /* - * Copy the header to the user-supplied buffer... - */ - - memcpy(h, &(r->header), sizeof(cups_page_header2_t)); - - return (1); -} - - -/* - * 'cupsRasterReadPixels()' - Read raster pixels. + * '_cupsRasterReadPixels()' - Read raster pixels. * * For best performance, filters should read one or more whole lines. * The "cupsBytesPerLine" value from the page header can be used to allocate @@ -585,9 +715,10 @@ cupsRasterReadHeader2( */ unsigned /* O - Number of bytes read */ -cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */ - unsigned char *p, /* I - Pointer to pixel buffer */ - unsigned len) /* I - Number of bytes to read */ +_cupsRasterReadPixels( + cups_raster_t *r, /* I - Raster stream */ + unsigned char *p, /* I - Pointer to pixel buffer */ + unsigned len) /* I - Number of bytes to read */ { ssize_t bytes; /* Bytes read */ unsigned cupsBytesPerLine; /* cupsBytesPerLine value */ @@ -598,16 +729,16 @@ cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */ unsigned count; /* Repetition count */ - DEBUG_printf(("cupsRasterReadPixels(r=%p, p=%p, len=%u)", (void *)r, (void *)p, len)); + DEBUG_printf(("_cupsRasterReadPixels(r=%p, p=%p, len=%u)", (void *)r, (void *)p, len)); if (r == NULL || r->mode != CUPS_RASTER_READ || r->remaining == 0 || r->header.cupsBytesPerLine == 0) { - DEBUG_puts("1cupsRasterReadPixels: Returning 0."); + DEBUG_puts("1_cupsRasterReadPixels: Returning 0."); return (0); } - DEBUG_printf(("1cupsRasterReadPixels: compressed=%d, remaining=%u", r->compressed, r->remaining)); + DEBUG_printf(("1_cupsRasterReadPixels: compressed=%d, remaining=%u", r->compressed, r->remaining)); if (!r->compressed) { @@ -619,7 +750,7 @@ cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */ if (cups_raster_io(r, p, len) < (ssize_t)len) { - DEBUG_puts("1cupsRasterReadPixels: Read error, returning 0."); + DEBUG_puts("1_cupsRasterReadPixels: Read error, returning 0."); return (0); } @@ -637,7 +768,7 @@ cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */ * Return... */ - DEBUG_printf(("1cupsRasterReadPixels: Returning %u", len)); + DEBUG_printf(("1_cupsRasterReadPixels: Returning %u", len)); return (len); } @@ -668,7 +799,7 @@ cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */ if (!cups_raster_read(r, &byte, 1)) { - DEBUG_puts("1cupsRasterReadPixels: Read error, returning 0."); + DEBUG_puts("1_cupsRasterReadPixels: Read error, returning 0."); return (0); } @@ -688,7 +819,7 @@ cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */ if (!cups_raster_read(r, &byte, 1)) { - DEBUG_puts("1cupsRasterReadPixels: Read error, returning 0."); + DEBUG_puts("1_cupsRasterReadPixels: Read error, returning 0."); return (0); } @@ -729,7 +860,7 @@ cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */ if (!cups_raster_read(r, temp, count)) { - DEBUG_puts("1cupsRasterReadPixels: Read error, returning 0."); + DEBUG_puts("1_cupsRasterReadPixels: Read error, returning 0."); return (0); } @@ -753,7 +884,7 @@ cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */ if (!cups_raster_read(r, temp, r->bpp)) { - DEBUG_puts("1cupsRasterReadPixels: Read error, returning 0."); + DEBUG_puts("1_cupsRasterReadPixels: Read error, returning 0."); return (0); } @@ -777,7 +908,10 @@ cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */ r->header.cupsBitsPerPixel == 12 || r->header.cupsBitsPerPixel == 16) && r->swapped) - cups_swap(ptr, (size_t)bytes); + { + DEBUG_puts("1_cupsRasterReadPixels: Swapping bytes."); + cups_swap(ptr, (size_t)cupsBytesPerLine); + } /* * Update pointers... @@ -827,216 +961,44 @@ cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */ p += bytes; } - DEBUG_printf(("1cupsRasterReadPixels: Returning %u", len)); + DEBUG_printf(("1_cupsRasterReadPixels: Returning %u", len)); return (len); } /* - * 'cupsRasterWriteHeader()' - Write a raster page header from a version 1 page - * header structure. - * - * This function is deprecated. Use @link cupsRasterWriteHeader2@ instead. - * - * @deprecated@ + * '_cupsRasterWriteHeader()' - Write a raster page header. */ unsigned /* O - 1 on success, 0 on failure */ -cupsRasterWriteHeader( - cups_raster_t *r, /* I - Raster stream */ - cups_page_header_t *h) /* I - Raster page header */ +_cupsRasterWriteHeader( + cups_raster_t *r) /* I - Raster stream */ { - if (r == NULL || r->mode == CUPS_RASTER_READ) - return (0); + DEBUG_printf(("_cupsRasterWriteHeader(r=%p)", (void *)r)); + + DEBUG_printf(("1_cupsRasterWriteHeader: cupsColorSpace=%s", _cupsRasterColorSpaceString(r->header.cupsColorSpace))); + DEBUG_printf(("1_cupsRasterWriteHeader: cupsBitsPerColor=%u", r->header.cupsBitsPerColor)); + DEBUG_printf(("1_cupsRasterWriteHeader: cupsBitsPerPixel=%u", r->header.cupsBitsPerPixel)); + DEBUG_printf(("1_cupsRasterWriteHeader: cupsBytesPerLine=%u", r->header.cupsBytesPerLine)); + DEBUG_printf(("1_cupsRasterWriteHeader: cupsWidth=%u", r->header.cupsWidth)); + DEBUG_printf(("1_cupsRasterWriteHeader: cupsHeight=%u", r->header.cupsHeight)); /* - * Make a copy of the header, and compute the number of raster - * lines in the page image... + * Compute the number of raster lines in the page image... */ - memset(&(r->header), 0, sizeof(r->header)); - memcpy(&(r->header), h, sizeof(cups_page_header_t)); - if (!cups_raster_update(r)) - return (0); - - /* - * Write the raster header... - */ - - if (r->mode == CUPS_RASTER_WRITE_PWG) { - /* - * PWG raster data is always network byte order with much of the page header - * zeroed. - */ - - cups_page_header2_t fh; /* File page header */ - - memset(&fh, 0, sizeof(fh)); - - strlcpy(fh.MediaClass, "PwgRaster", sizeof(fh.MediaClass)); - /* PwgRaster */ - strlcpy(fh.MediaColor, r->header.MediaColor, sizeof(fh.MediaColor)); - strlcpy(fh.MediaType, r->header.MediaType, sizeof(fh.MediaType)); - strlcpy(fh.OutputType, r->header.OutputType, sizeof(fh.OutputType)); - /* PrintContentType */ - - fh.CutMedia = htonl(r->header.CutMedia); - fh.Duplex = htonl(r->header.Duplex); - fh.HWResolution[0] = htonl(r->header.HWResolution[0]); - fh.HWResolution[1] = htonl(r->header.HWResolution[1]); - fh.ImagingBoundingBox[0] = htonl(r->header.ImagingBoundingBox[0]); - fh.ImagingBoundingBox[1] = htonl(r->header.ImagingBoundingBox[1]); - fh.ImagingBoundingBox[2] = htonl(r->header.ImagingBoundingBox[2]); - fh.ImagingBoundingBox[3] = htonl(r->header.ImagingBoundingBox[3]); - fh.InsertSheet = htonl(r->header.InsertSheet); - fh.Jog = htonl(r->header.Jog); - fh.LeadingEdge = htonl(r->header.LeadingEdge); - fh.ManualFeed = htonl(r->header.ManualFeed); - fh.MediaPosition = htonl(r->header.MediaPosition); - fh.MediaWeight = htonl(r->header.MediaWeight); - fh.NumCopies = htonl(r->header.NumCopies); - fh.Orientation = htonl(r->header.Orientation); - fh.PageSize[0] = htonl(r->header.PageSize[0]); - fh.PageSize[1] = htonl(r->header.PageSize[1]); - fh.Tumble = htonl(r->header.Tumble); - fh.cupsWidth = htonl(r->header.cupsWidth); - fh.cupsHeight = htonl(r->header.cupsHeight); - fh.cupsBitsPerColor = htonl(r->header.cupsBitsPerColor); - fh.cupsBitsPerPixel = htonl(r->header.cupsBitsPerPixel); - fh.cupsBytesPerLine = htonl(r->header.cupsBytesPerLine); - fh.cupsColorOrder = htonl(r->header.cupsColorOrder); - fh.cupsColorSpace = htonl(r->header.cupsColorSpace); - fh.cupsNumColors = htonl(r->header.cupsNumColors); - fh.cupsInteger[0] = htonl(r->header.cupsInteger[0]); - /* TotalPageCount */ - fh.cupsInteger[1] = htonl(r->header.cupsInteger[1]); - /* CrossFeedTransform */ - fh.cupsInteger[2] = htonl(r->header.cupsInteger[2]); - /* FeedTransform */ - fh.cupsInteger[3] = htonl(r->header.cupsInteger[3]); - /* ImageBoxLeft */ - fh.cupsInteger[4] = htonl(r->header.cupsInteger[4]); - /* ImageBoxTop */ - fh.cupsInteger[5] = htonl(r->header.cupsInteger[5]); - /* ImageBoxRight */ - fh.cupsInteger[6] = htonl(r->header.cupsInteger[6]); - /* ImageBoxBottom */ - fh.cupsInteger[7] = htonl(r->header.cupsInteger[7]); - /* BlackPrimary */ - fh.cupsInteger[8] = htonl(r->header.cupsInteger[8]); - /* PrintQuality */ - fh.cupsInteger[14] = htonl(r->header.cupsInteger[14]); - /* VendorIdentifier */ - fh.cupsInteger[15] = htonl(r->header.cupsInteger[15]); - /* VendorLength */ - - void *dst = fh.cupsReal; /* Bypass bogus compiler warning */ - void *src = r->header.cupsReal; - memcpy(dst, src, sizeof(fh.cupsReal) + sizeof(fh.cupsString)); - /* VendorData */ - - strlcpy(fh.cupsRenderingIntent, r->header.cupsRenderingIntent, - sizeof(fh.cupsRenderingIntent)); - strlcpy(fh.cupsPageSizeName, r->header.cupsPageSizeName, - sizeof(fh.cupsPageSizeName)); - - return (cups_raster_io(r, (unsigned char *)&fh, sizeof(fh)) == sizeof(fh)); - } - else if (r->mode == CUPS_RASTER_WRITE_APPLE) - { - /* - * Raw raster data is always network byte order with most of the page header - * zeroed. - */ - - unsigned char appleheader[32]; /* Raw page header */ - - if (r->apple_page_count == 0xffffffffU) - { - /* - * Write raw page count from raster page header... - */ - - r->apple_page_count = r->header.cupsInteger[0]; - - appleheader[0] = 'A'; - appleheader[1] = 'S'; - appleheader[2] = 'T'; - appleheader[3] = 0; - appleheader[4] = (unsigned char)(r->apple_page_count >> 24); - appleheader[5] = (unsigned char)(r->apple_page_count >> 16); - appleheader[6] = (unsigned char)(r->apple_page_count >> 8); - appleheader[7] = (unsigned char)(r->apple_page_count); - - if (cups_raster_io(r, appleheader, 8) != 8) - return (0); - } - - memset(appleheader, 0, sizeof(appleheader)); - - appleheader[0] = (unsigned char)r->header.cupsBitsPerPixel; - appleheader[1] = r->header.cupsColorSpace == CUPS_CSPACE_SRGB ? 1 : - r->header.cupsColorSpace == CUPS_CSPACE_RGBW ? 2 : - r->header.cupsColorSpace == CUPS_CSPACE_ADOBERGB ? 3 : - r->header.cupsColorSpace == CUPS_CSPACE_W ? 4 : - r->header.cupsColorSpace == CUPS_CSPACE_RGB ? 5 : - r->header.cupsColorSpace == CUPS_CSPACE_CMYK ? 6 : 0; - appleheader[12] = (unsigned char)(r->header.cupsWidth >> 24); - appleheader[13] = (unsigned char)(r->header.cupsWidth >> 16); - appleheader[14] = (unsigned char)(r->header.cupsWidth >> 8); - appleheader[15] = (unsigned char)(r->header.cupsWidth); - appleheader[16] = (unsigned char)(r->header.cupsHeight >> 24); - appleheader[17] = (unsigned char)(r->header.cupsHeight >> 16); - appleheader[18] = (unsigned char)(r->header.cupsHeight >> 8); - appleheader[19] = (unsigned char)(r->header.cupsHeight); - appleheader[20] = (unsigned char)(r->header.HWResolution[0] >> 24); - appleheader[21] = (unsigned char)(r->header.HWResolution[0] >> 16); - appleheader[22] = (unsigned char)(r->header.HWResolution[0] >> 8); - appleheader[23] = (unsigned char)(r->header.HWResolution[0]); - - return (cups_raster_io(r, appleheader, sizeof(appleheader)) == sizeof(appleheader)); - } - else - return (cups_raster_io(r, (unsigned char *)&(r->header), sizeof(r->header)) - == sizeof(r->header)); -} - - -/* - * 'cupsRasterWriteHeader2()' - Write a raster page header from a version 2 - * page header structure. - * - * The page header can be initialized using @link cupsRasterInitPWGHeader@. - * - * @since CUPS 1.2/macOS 10.5@ - */ - -unsigned /* O - 1 on success, 0 on failure */ -cupsRasterWriteHeader2( - cups_raster_t *r, /* I - Raster stream */ - cups_page_header2_t *h) /* I - Raster page header */ -{ - if (r == NULL || r->mode == CUPS_RASTER_READ) - return (0); - - /* - * Make a copy of the header, and compute the number of raster - * lines in the page image... - */ - - memcpy(&(r->header), h, sizeof(cups_page_header2_t)); - - if (!cups_raster_update(r)) + DEBUG_puts("1_cupsRasterWriteHeader: Unable to update parameters, returning 0."); return (0); + } if (r->mode == CUPS_RASTER_WRITE_APPLE) { - r->rowheight = h->HWResolution[0] / h->HWResolution[1]; + r->rowheight = r->header.HWResolution[0] / r->header.HWResolution[1]; - if (h->HWResolution[0] != (r->rowheight * h->HWResolution[1])) + if (r->header.HWResolution[0] != (r->rowheight * r->header.HWResolution[1])) return (0); } else @@ -1049,7 +1011,7 @@ cupsRasterWriteHeader2( if (r->mode == CUPS_RASTER_WRITE_PWG) { /* - * PWG raster data is always network byte order with most of the page header + * PWG raster data is always network byte order with much of the page header * zeroed. */ @@ -1166,7 +1128,7 @@ cupsRasterWriteHeader2( /* - * 'cupsRasterWritePixels()' - Write raster pixels. + * '_cupsRasterWritePixels()' - Write raster pixels. * * For best performance, filters should write one or more whole lines. * The "cupsBytesPerLine" value from the page header can be used to allocate @@ -1174,15 +1136,16 @@ cupsRasterWriteHeader2( */ unsigned /* O - Number of bytes written */ -cupsRasterWritePixels(cups_raster_t *r, /* I - Raster stream */ - unsigned char *p, /* I - Bytes to write */ - unsigned len)/* I - Number of bytes to write */ +_cupsRasterWritePixels( + cups_raster_t *r, /* I - Raster stream */ + unsigned char *p, /* I - Bytes to write */ + unsigned len) /* I - Number of bytes to write */ { ssize_t bytes; /* Bytes read */ unsigned remaining; /* Bytes remaining */ - DEBUG_printf(("cupsRasterWritePixels(r=%p, p=%p, len=%u), remaining=%u", (void *)r, (void *)p, len, r->remaining)); + DEBUG_printf(("_cupsRasterWritePixels(r=%p, p=%p, len=%u), remaining=%u", (void *)r, (void *)p, len, r->remaining)); if (r == NULL || r->mode == CUPS_RASTER_READ || r->remaining == 0) return (0); @@ -1202,7 +1165,6 @@ cupsRasterWritePixels(cups_raster_t *r, /* I - Raster stream */ r->header.cupsBitsPerPixel == 16)) { unsigned char *bufptr; /* Pointer into write buffer */ - unsigned count; /* Remaining count */ /* * Allocate a write buffer as needed... @@ -1223,28 +1185,17 @@ cupsRasterWritePixels(cups_raster_t *r, /* I - Raster stream */ } /* - * Byte swap the pixels... + * Byte swap the pixels and write them... */ - for (bufptr = r->buffer, count = len; count > 1; count -= 2, bufptr += 2) - { - bufptr[1] = *p++; - bufptr[0] = *p++; - } - - if (count) /* This should never happen... */ - *bufptr = *p; - - /* - * Write the byte-swapped buffer... - */ + cups_swap_copy(r->buffer, p, len); bytes = cups_raster_io(r, r->buffer, len); } else bytes = cups_raster_io(r, p, len); - if (bytes < len) + if (bytes < (ssize_t)len) return (0); else return (len); @@ -1357,151 +1308,6 @@ cupsRasterWritePixels(cups_raster_t *r, /* I - Raster stream */ } -/* - * 'cups_raster_read_header()' - Read a raster page header. - */ - -static unsigned /* O - 1 on success, 0 on fail */ -cups_raster_read_header( - cups_raster_t *r) /* I - Raster stream */ -{ - size_t len; /* Length for read/swap */ - - - DEBUG_printf(("3cups_raster_read_header(r=%p), r->mode=%d", (void *)r, r ? r->mode : 0)); - - if (r == NULL || r->mode != CUPS_RASTER_READ) - return (0); - - DEBUG_printf(("4cups_raster_read_header: r->iocount=" CUPS_LLFMT, CUPS_LLCAST r->iocount)); - - memset(&(r->header), 0, sizeof(r->header)); - - /* - * Read the header... - */ - - switch (r->sync) - { - default : - /* - * Get the length of the raster header... - */ - - if (r->sync == CUPS_RASTER_SYNCv1 || r->sync == CUPS_RASTER_REVSYNCv1) - len = sizeof(cups_page_header_t); - else - len = sizeof(cups_page_header2_t); - - DEBUG_printf(("4cups_raster_read_header: len=%d", (int)len)); - - /* - * Read it... - */ - - if (cups_raster_read(r, (unsigned char *)&(r->header), len) < (ssize_t)len) - { - DEBUG_printf(("4cups_raster_read_header: EOF, r->iocount=" CUPS_LLFMT, CUPS_LLCAST r->iocount)); - return (0); - } - - /* - * Swap bytes as needed... - */ - - if (r->swapped) - { - unsigned *s, /* Current word */ - temp; /* Temporary copy */ - - - DEBUG_puts("4cups_raster_read_header: Swapping header bytes."); - - for (len = 81, s = &(r->header.AdvanceDistance); - len > 0; - len --, s ++) - { - temp = *s; - *s = ((temp & 0xff) << 24) | - ((temp & 0xff00) << 8) | - ((temp & 0xff0000) >> 8) | - ((temp & 0xff000000) >> 24); - - DEBUG_printf(("4cups_raster_read_header: %08x => %08x", temp, *s)); - } - } - break; - - case CUPS_RASTER_SYNCapple : - case CUPS_RASTER_REVSYNCapple : - { - unsigned char appleheader[32]; /* Raw header */ - static const unsigned rawcspace[] = - { - CUPS_CSPACE_SW, - CUPS_CSPACE_SRGB, - CUPS_CSPACE_RGBW, - CUPS_CSPACE_ADOBERGB, - CUPS_CSPACE_W, - CUPS_CSPACE_RGB, - CUPS_CSPACE_CMYK - }; - static const unsigned rawnumcolors[] = - { - 1, - 3, - 4, - 3, - 1, - 3, - 4 - }; - - if (cups_raster_read(r, appleheader, sizeof(appleheader)) < (ssize_t)sizeof(appleheader)) - { - DEBUG_printf(("4cups_raster_read_header: EOF, r->iocount=" CUPS_LLFMT, CUPS_LLCAST r->iocount)); - return (0); - } - - strlcpy(r->header.MediaClass, "PwgRaster", sizeof(r->header.MediaClass)); - /* PwgRaster */ - r->header.cupsBitsPerPixel = appleheader[0]; - r->header.cupsColorSpace = appleheader[1] >= (sizeof(rawcspace) / sizeof(rawcspace[0])) ? CUPS_CSPACE_DEVICE1 : rawcspace[appleheader[1]]; - r->header.cupsNumColors = appleheader[1] >= (sizeof(rawnumcolors) / sizeof(rawnumcolors[0])) ? 1 : rawnumcolors[appleheader[1]]; - r->header.cupsBitsPerColor = r->header.cupsBitsPerPixel / r->header.cupsNumColors; - r->header.cupsWidth = ((((((unsigned)appleheader[12] << 8) | (unsigned)appleheader[13]) << 8) | (unsigned)appleheader[14]) << 8) | (unsigned)appleheader[15]; - r->header.cupsHeight = ((((((unsigned)appleheader[16] << 8) | (unsigned)appleheader[17]) << 8) | (unsigned)appleheader[18]) << 8) | (unsigned)appleheader[19]; - r->header.cupsBytesPerLine = r->header.cupsWidth * r->header.cupsBitsPerPixel / 8; - r->header.cupsColorOrder = CUPS_ORDER_CHUNKED; - r->header.HWResolution[0] = r->header.HWResolution[1] = ((((((unsigned)appleheader[20] << 8) | (unsigned)appleheader[21]) << 8) | (unsigned)appleheader[22]) << 8) | (unsigned)appleheader[23]; - - if (r->header.HWResolution[0] > 0) - { - r->header.PageSize[0] = (unsigned)(r->header.cupsWidth * 72 / r->header.HWResolution[0]); - r->header.PageSize[1] = (unsigned)(r->header.cupsHeight * 72 / r->header.HWResolution[1]); - r->header.cupsPageSize[0] = (float)(r->header.cupsWidth * 72.0 / r->header.HWResolution[0]); - r->header.cupsPageSize[1] = (float)(r->header.cupsHeight * 72.0 / r->header.HWResolution[1]); - } - - r->header.cupsInteger[0] = r->apple_page_count; - r->header.cupsInteger[7] = 0xffffff; - } - break; - } - - /* - * Update the header and row count... - */ - - if (!cups_raster_update(r)) - return (0); - - DEBUG_printf(("4cups_raster_read_header: cupsBitsPerPixel=%u, cupsBitsPerColor=%u, cupsBytesPerLine=%u, cupsWidth=%u, cupsHeight=%u, r->bpp=%d", r->header.cupsBitsPerPixel, r->header.cupsBitsPerColor, r->header.cupsBytesPerLine, r->header.cupsWidth, r->header.cupsHeight, r->bpp)); - - return (r->header.cupsBitsPerPixel > 0 && r->header.cupsBitsPerPixel <= 240 && r->header.cupsBitsPerColor > 0 && r->header.cupsBitsPerColor <= 16 && r->header.cupsBytesPerLine > 0 && r->header.cupsBytesPerLine <= 0x7fffffff && r->header.cupsHeight != 0 && (r->header.cupsBytesPerLine % r->bpp) == 0); -} - - /* * 'cups_raster_io()' - Read/write bytes from a context, handling interruptions. */ @@ -1523,10 +1329,11 @@ cups_raster_io(cups_raster_t *r, /* I - Raster stream */ DEBUG_printf(("6cups_raster_io: count=%d, total=%d", (int)count, (int)total)); if (count == 0) - { - DEBUG_puts("6cups_raster_io: Returning 0."); - return (0); - } + break; +// { +// DEBUG_puts("6cups_raster_io: Returning 0."); +// return (0); +// } else if (count < 0) { DEBUG_puts("6cups_raster_io: Returning -1 on error."); @@ -1538,6 +1345,7 @@ cups_raster_io(cups_raster_t *r, /* I - Raster stream */ #endif /* DEBUG */ } + DEBUG_printf(("6cups_raster_io: iocount=" CUPS_LLFMT, CUPS_LLCAST r->iocount)); DEBUG_printf(("6cups_raster_io: Returning " CUPS_LLFMT ".", CUPS_LLCAST total)); return (total); @@ -1558,7 +1366,7 @@ cups_raster_read(cups_raster_t *r, /* I - Raster stream */ total; /* Total bytes read */ - DEBUG_printf(("5cups_raster_read(r=%p, buf=%p, bytes=" CUPS_LLFMT ")", (void *)r, (void *)buf, CUPS_LLCAST bytes)); + DEBUG_printf(("4cups_raster_read(r=%p, buf=%p, bytes=" CUPS_LLFMT "), offset=" CUPS_LLFMT, (void *)r, (void *)buf, CUPS_LLCAST bytes, CUPS_LLCAST (r->iostart + r->bufptr - r->buffer))); if (!r->compressed) return (cups_raster_io(r, buf, bytes)); @@ -1602,7 +1410,7 @@ cups_raster_read(cups_raster_t *r, /* I - Raster stream */ { count = (ssize_t)bytes - total; - DEBUG_printf(("6cups_raster_read: count=" CUPS_LLFMT ", remaining=" CUPS_LLFMT ", buf=%p, bufptr=%p, bufend=%p", CUPS_LLCAST count, CUPS_LLCAST remaining, (void *)buf, (void *)r->bufptr, (void *)r->bufend)); + DEBUG_printf(("5cups_raster_read: count=" CUPS_LLFMT ", remaining=" CUPS_LLFMT ", buf=%p, bufptr=%p, bufend=%p", CUPS_LLCAST count, CUPS_LLCAST remaining, (void *)buf, (void *)r->bufptr, (void *)r->bufend)); if (remaining == 0) { @@ -1612,6 +1420,10 @@ cups_raster_read(cups_raster_t *r, /* I - Raster stream */ * Read into the raster buffer and then copy... */ +#ifdef DEBUG + r->iostart += (size_t)(r->bufend - r->buffer); +#endif /* DEBUG */ + remaining = (*r->iocb)(r->ctx, r->buffer, r->bufsize); if (remaining <= 0) return (0); @@ -1635,6 +1447,7 @@ cups_raster_read(cups_raster_t *r, /* I - Raster stream */ return (0); #ifdef DEBUG + r->iostart += (size_t)count; r->iocount += (size_t)count; #endif /* DEBUG */ @@ -1687,7 +1500,7 @@ cups_raster_read(cups_raster_t *r, /* I - Raster stream */ } } - DEBUG_printf(("6cups_raster_read: Returning %ld", (long)total)); + DEBUG_printf(("5cups_raster_read: Returning %ld", (long)total)); return (total); } @@ -1850,11 +1663,24 @@ cups_raster_write( unsigned char *wptr; /* Pointer into write buffer */ unsigned bpp, /* Bytes per pixel */ count; /* Count */ + _cups_copyfunc_t cf; /* Copy function */ DEBUG_printf(("3cups_raster_write(r=%p, pixels=%p)", (void *)r, (void *)pixels)); /* + * Determine whether we need to swap bytes... + */ + + if (r->swapped && (r->header.cupsBitsPerColor == 16 || r->header.cupsBitsPerPixel == 12 || r->header.cupsBitsPerPixel == 16)) + { + DEBUG_puts("4cups_raster_write: Swapping bytes when writing."); + cf = (_cups_copyfunc_t)cups_swap_copy; + } + else + cf = (_cups_copyfunc_t)memcpy; + + /* * Allocate a write buffer as needed... */ @@ -1905,8 +1731,8 @@ cups_raster_write( */ *wptr++ = 0; - for (count = bpp; count > 0; count --) - *wptr++ = *start++; + (*cf)(wptr, start, bpp); + wptr += bpp; } else if (!memcmp(start, ptr, bpp)) { @@ -1919,8 +1745,9 @@ cups_raster_write( break; *wptr++ = (unsigned char)(count - 1); - for (count = bpp; count > 0; count --) - *wptr++ = *ptr++; + (*cf)(wptr, ptr, bpp); + wptr += bpp; + ptr += bpp; } else { @@ -1941,7 +1768,7 @@ cups_raster_write( *wptr++ = (unsigned char)(257 - count); count *= bpp; - memcpy(wptr, start, count); + (*cf)(wptr, start, count); wptr += count; } } @@ -1952,37 +1779,6 @@ cups_raster_write( } -/* - * 'cups_read_fd()' - Read bytes from a file. - */ - -static ssize_t /* O - Bytes read or -1 */ -cups_read_fd(void *ctx, /* I - File descriptor as pointer */ - unsigned char *buf, /* I - Buffer for read */ - size_t bytes) /* I - Maximum number of bytes to read */ -{ - int fd = (int)((intptr_t)ctx); - /* File descriptor */ - ssize_t count; /* Number of bytes read */ - - -#ifdef WIN32 /* Sigh */ - while ((count = read(fd, buf, (unsigned)bytes)) < 0) -#else - while ((count = read(fd, buf, bytes)) < 0) -#endif /* WIN32 */ - if (errno != EINTR && errno != EAGAIN) - { - DEBUG_printf(("4cups_read_fd: %s", strerror(errno))); - return (-1); - } - - DEBUG_printf(("4cups_read_fd: Returning %d bytes.", (int)count)); - - return (count); -} - - /* * 'cups_swap()' - Swap bytes in raster data... */ @@ -2010,29 +1806,24 @@ cups_swap(unsigned char *buf, /* I - Buffer to swap */ /* - * 'cups_write_fd()' - Write bytes to a file. + * 'cups_swap_copy()' - Copy and swap bytes in raster data... */ -static ssize_t /* O - Bytes written or -1 */ -cups_write_fd(void *ctx, /* I - File descriptor pointer */ - unsigned char *buf, /* I - Bytes to write */ - size_t bytes) /* I - Number of bytes to write */ +static void +cups_swap_copy( + unsigned char *dst, /* I - Destination */ + const unsigned char *src, /* I - Source */ + size_t bytes) /* I - Number of bytes to swap */ { - int fd = (int)((intptr_t)ctx); - /* File descriptor */ - ssize_t count; /* Number of bytes written */ + bytes /= 2; + while (bytes > 0) + { + dst[0] = src[1]; + dst[1] = src[0]; -#ifdef WIN32 /* Sigh */ - while ((count = write(fd, buf, (unsigned)bytes)) < 0) -#else - while ((count = write(fd, buf, bytes)) < 0) -#endif /* WIN32 */ - if (errno != EINTR && errno != EAGAIN) - { - DEBUG_printf(("4cups_write_fd: %s", strerror(errno))); - return (-1); - } - - return (count); + dst += 2; + src += 2; + bytes --; + } } diff --git a/cups/raster-stubs.c b/cups/raster-stubs.c new file mode 100644 index 0000000..11e0a14 --- /dev/null +++ b/cups/raster-stubs.c @@ -0,0 +1,355 @@ +/* + * Imaging library stubs for CUPS. + * + * Copyright © 2018 by Apple Inc. + * + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. + */ + +/* + * Include necessary headers... + */ + +#include "raster-private.h" + + +/* + * These stubs wrap the real functions in libcups - this allows one library to + * provide all of the CUPS API functions while still supporting the old split + * library organization... + */ + + +/* + * Local functions... + */ + +static ssize_t cups_read_fd(void *ctx, unsigned char *buf, size_t bytes); +static ssize_t cups_write_fd(void *ctx, unsigned char *buf, size_t bytes); + + + +/* + * 'cupsRasterClose()' - Close a raster stream. + * + * The file descriptor associated with the raster stream must be closed + * separately as needed. + */ + +void +cupsRasterClose(cups_raster_t *r) /* I - Stream to close */ +{ + _cupsRasterDelete(r); +} + + +/* + * 'cupsRasterErrorString()' - Return the last error from a raster function. + * + * If there are no recent errors, `NULL` is returned. + * + * @since CUPS 1.3/macOS 10.5@ + */ + +const char * /* O - Last error or `NULL` */ +cupsRasterErrorString(void) +{ + return (_cupsRasterErrorString()); +} + + +/* + * 'cupsRasterInitPWGHeader()' - Initialize a page header for PWG Raster output. + * + * The "media" argument specifies the media to use. + * + * The "type" argument specifies a "pwg-raster-document-type-supported" value + * that controls the color space and bit depth of the raster data. + * + * The "xres" and "yres" arguments specify the raster resolution in dots per + * inch. + * + * The "sheet_back" argument specifies a "pwg-raster-document-sheet-back" value + * to apply for the back side of a page. Pass @code NULL@ for the front side. + * + * @since CUPS 2.2/macOS 10.12@ + */ + +int /* O - 1 on success, 0 on failure */ +cupsRasterInitPWGHeader( + cups_page_header2_t *h, /* I - Page header */ + pwg_media_t *media, /* I - PWG media information */ + const char *type, /* I - PWG raster type string */ + int xdpi, /* I - Cross-feed direction (horizontal) resolution */ + int ydpi, /* I - Feed direction (vertical) resolution */ + const char *sides, /* I - IPP "sides" option value */ + const char *sheet_back) /* I - Transform for back side or @code NULL@ for none */ +{ + return (_cupsRasterInitPWGHeader(h, media, type, xdpi, ydpi, sides, sheet_back)); +} + + +/* + * 'cupsRasterOpen()' - Open a raster stream using a file descriptor. + * + * This function associates a raster stream with the given file descriptor. + * For most printer driver filters, "fd" will be 0 (stdin). For most raster + * image processor (RIP) filters that generate raster data, "fd" will be 1 + * (stdout). + * + * When writing raster data, the @code CUPS_RASTER_WRITE@, + * @code CUPS_RASTER_WRITE_COMPRESS@, or @code CUPS_RASTER_WRITE_PWG@ mode can + * be used - compressed and PWG output is generally 25-50% smaller but adds a + * 100-300% execution time overhead. + */ + +cups_raster_t * /* O - New stream */ +cupsRasterOpen(int fd, /* I - File descriptor */ + cups_mode_t mode) /* I - Mode - @code CUPS_RASTER_READ@, + @code CUPS_RASTER_WRITE@, + @code CUPS_RASTER_WRITE_COMPRESSED@, + or @code CUPS_RASTER_WRITE_PWG@ */ +{ + if (mode == CUPS_RASTER_READ) + return (_cupsRasterNew(cups_read_fd, (void *)((intptr_t)fd), mode)); + else + return (_cupsRasterNew(cups_write_fd, (void *)((intptr_t)fd), mode)); +} + + +/* + * 'cupsRasterOpenIO()' - Open a raster stream using a callback function. + * + * This function associates a raster stream with the given callback function and + * context pointer. + * + * When writing raster data, the @code CUPS_RASTER_WRITE@, + * @code CUPS_RASTER_WRITE_COMPRESS@, or @code CUPS_RASTER_WRITE_PWG@ mode can + * be used - compressed and PWG output is generally 25-50% smaller but adds a + * 100-300% execution time overhead. + */ + +cups_raster_t * /* O - New stream */ +cupsRasterOpenIO( + cups_raster_iocb_t iocb, /* I - Read/write callback */ + void *ctx, /* I - Context pointer for callback */ + cups_mode_t mode) /* I - Mode - @code CUPS_RASTER_READ@, + @code CUPS_RASTER_WRITE@, + @code CUPS_RASTER_WRITE_COMPRESSED@, + or @code CUPS_RASTER_WRITE_PWG@ */ +{ + return (_cupsRasterNew(iocb, ctx, mode)); +} + + +/* + * 'cupsRasterReadHeader()' - Read a raster page header and store it in a + * version 1 page header structure. + * + * This function is deprecated. Use @link cupsRasterReadHeader2@ instead. + * + * Version 1 page headers were used in CUPS 1.0 and 1.1 and contain a subset + * of the version 2 page header data. This function handles reading version 2 + * page headers and copying only the version 1 data into the provided buffer. + * + * @deprecated@ + */ + +unsigned /* O - 1 on success, 0 on failure/end-of-file */ +cupsRasterReadHeader( + cups_raster_t *r, /* I - Raster stream */ + cups_page_header_t *h) /* I - Pointer to header data */ +{ + /* + * Get the raster header... + */ + + if (!_cupsRasterReadHeader(r)) + { + memset(h, 0, sizeof(cups_page_header_t)); + return (0); + } + + /* + * Copy the header to the user-supplied buffer... + */ + + memcpy(h, &(r->header), sizeof(cups_page_header_t)); + return (1); +} + + +/* + * 'cupsRasterReadHeader2()' - Read a raster page header and store it in a + * version 2 page header structure. + * + * @since CUPS 1.2/macOS 10.5@ + */ + +unsigned /* O - 1 on success, 0 on failure/end-of-file */ +cupsRasterReadHeader2( + cups_raster_t *r, /* I - Raster stream */ + cups_page_header2_t *h) /* I - Pointer to header data */ +{ + /* + * Get the raster header... + */ + + if (!_cupsRasterReadHeader(r)) + { + memset(h, 0, sizeof(cups_page_header2_t)); + return (0); + } + + /* + * Copy the header to the user-supplied buffer... + */ + + memcpy(h, &(r->header), sizeof(cups_page_header2_t)); + return (1); +} + + +/* + * 'cupsRasterReadPixels()' - Read raster pixels. + * + * For best performance, filters should read one or more whole lines. + * The "cupsBytesPerLine" value from the page header can be used to allocate + * the line buffer and as the number of bytes to read. + */ + +unsigned /* O - Number of bytes read */ +cupsRasterReadPixels( + cups_raster_t *r, /* I - Raster stream */ + unsigned char *p, /* I - Pointer to pixel buffer */ + unsigned len) /* I - Number of bytes to read */ +{ + return (_cupsRasterReadPixels(r, p, len)); +} + + +/* + * 'cupsRasterWriteHeader()' - Write a raster page header from a version 1 page + * header structure. + * + * This function is deprecated. Use @link cupsRasterWriteHeader2@ instead. + * + * @deprecated@ + */ + +unsigned /* O - 1 on success, 0 on failure */ +cupsRasterWriteHeader( + cups_raster_t *r, /* I - Raster stream */ + cups_page_header_t *h) /* I - Raster page header */ +{ + if (r == NULL || r->mode == CUPS_RASTER_READ) + return (0); + + /* + * Make a copy of the header and write using the private function... + */ + + memset(&(r->header), 0, sizeof(r->header)); + memcpy(&(r->header), h, sizeof(cups_page_header_t)); + + return (_cupsRasterWriteHeader(r)); +} + + +/* + * 'cupsRasterWriteHeader2()' - Write a raster page header from a version 2 + * page header structure. + * + * The page header can be initialized using @link cupsRasterInitPWGHeader@. + * + * @since CUPS 1.2/macOS 10.5@ + */ + +unsigned /* O - 1 on success, 0 on failure */ +cupsRasterWriteHeader2( + cups_raster_t *r, /* I - Raster stream */ + cups_page_header2_t *h) /* I - Raster page header */ +{ + if (r == NULL || r->mode == CUPS_RASTER_READ) + return (0); + + /* + * Make a copy of the header, and compute the number of raster + * lines in the page image... + */ + + memcpy(&(r->header), h, sizeof(cups_page_header2_t)); + + return (_cupsRasterWriteHeader(r)); +} + + +/* + * 'cupsRasterWritePixels()' - Write raster pixels. + * + * For best performance, filters should write one or more whole lines. + * The "cupsBytesPerLine" value from the page header can be used to allocate + * the line buffer and as the number of bytes to write. + */ + +unsigned /* O - Number of bytes written */ +cupsRasterWritePixels( + cups_raster_t *r, /* I - Raster stream */ + unsigned char *p, /* I - Bytes to write */ + unsigned len) /* I - Number of bytes to write */ +{ + return (_cupsRasterWritePixels(r, p, len)); +} + + +/* + * 'cups_read_fd()' - Read bytes from a file. + */ + +static ssize_t /* O - Bytes read or -1 */ +cups_read_fd(void *ctx, /* I - File descriptor as pointer */ + unsigned char *buf, /* I - Buffer for read */ + size_t bytes) /* I - Maximum number of bytes to read */ +{ + int fd = (int)((intptr_t)ctx); + /* File descriptor */ + ssize_t count; /* Number of bytes read */ + + +#ifdef _WIN32 /* Sigh */ + while ((count = read(fd, buf, (unsigned)bytes)) < 0) +#else + while ((count = read(fd, buf, bytes)) < 0) +#endif /* _WIN32 */ + if (errno != EINTR && errno != EAGAIN) + return (-1); + + return (count); +} + + +/* + * 'cups_write_fd()' - Write bytes to a file. + */ + +static ssize_t /* O - Bytes written or -1 */ +cups_write_fd(void *ctx, /* I - File descriptor pointer */ + unsigned char *buf, /* I - Bytes to write */ + size_t bytes) /* I - Number of bytes to write */ +{ + int fd = (int)((intptr_t)ctx); + /* File descriptor */ + ssize_t count; /* Number of bytes written */ + + +#ifdef _WIN32 /* Sigh */ + while ((count = write(fd, buf, (unsigned)bytes)) < 0) +#else + while ((count = write(fd, buf, bytes)) < 0) +#endif /* _WIN32 */ + if (errno != EINTR && errno != EAGAIN) + return (-1); + + return (count); +} diff --git a/cups/raster.h b/cups/raster.h index 4067b3c..7d98a4e 100644 --- a/cups/raster.h +++ b/cups/raster.h @@ -1,18 +1,13 @@ /* * Raster file definitions for CUPS. * - * Copyright 2007-2016 by Apple Inc. - * Copyright 1997-2006 by Easy Software Products. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2006 by Easy Software Products. * * This file is part of the CUPS Imaging library. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ #ifndef _CUPS_RASTER_H_ @@ -359,20 +354,6 @@ typedef struct cups_page_header2_s /**** Version 2 page header @since CUPS 1.2/m typedef struct _cups_raster_s cups_raster_t; /**** Raster stream data ****/ -typedef int (*cups_interpret_cb_t)(cups_page_header2_t *header, int preferred_bits); - /**** cupsRasterInterpretPPD callback function - * - * This function is called by - * @link cupsRasterInterpretPPD@ to - * validate (and update, as needed) - * the page header attributes. The - * "preferred_bits" argument provides - * the value of the - * @code cupsPreferredBitsPerColor@ - * key from the PostScript page device - * dictionary and is 0 if undefined. - ****/ - /**** New in CUPS 1.5 ****/ typedef ssize_t (*cups_raster_iocb_t)(void *ctx, unsigned char *buffer, size_t length); /**** cupsRasterOpenIO callback function @@ -391,29 +372,22 @@ typedef ssize_t (*cups_raster_iocb_t)(void *ctx, unsigned char *buffer, size_t l * Prototypes... */ -extern void cupsRasterClose(cups_raster_t *r); -extern cups_raster_t *cupsRasterOpen(int fd, cups_mode_t mode); -extern unsigned cupsRasterReadHeader(cups_raster_t *r, - cups_page_header_t *h) _CUPS_DEPRECATED_MSG("Use cupsRasterReadHeader2 instead."); -extern unsigned cupsRasterReadPixels(cups_raster_t *r, - unsigned char *p, unsigned len); -extern unsigned cupsRasterWriteHeader(cups_raster_t *r, - cups_page_header_t *h) _CUPS_DEPRECATED_MSG("Use cupsRasterWriteHeader2 instead."); -extern unsigned cupsRasterWritePixels(cups_raster_t *r, - unsigned char *p, unsigned len); +extern void cupsRasterClose(cups_raster_t *r) _CUPS_PUBLIC; +extern cups_raster_t *cupsRasterOpen(int fd, cups_mode_t mode) _CUPS_PUBLIC; +extern unsigned cupsRasterReadHeader(cups_raster_t *r, cups_page_header_t *h) _CUPS_DEPRECATED_MSG("Use cupsRasterReadHeader2 instead.") _CUPS_PUBLIC; +extern unsigned cupsRasterReadPixels(cups_raster_t *r, unsigned char *p, unsigned len) _CUPS_PUBLIC; +extern unsigned cupsRasterWriteHeader(cups_raster_t *r, cups_page_header_t *h) _CUPS_DEPRECATED_MSG("Use cupsRasterWriteHeader2 instead.") _CUPS_PUBLIC; +extern unsigned cupsRasterWritePixels(cups_raster_t *r, unsigned char *p, unsigned len) _CUPS_PUBLIC; /**** New in CUPS 1.2 ****/ -extern unsigned cupsRasterReadHeader2(cups_raster_t *r, - cups_page_header2_t *h) _CUPS_API_1_2; -extern unsigned cupsRasterWriteHeader2(cups_raster_t *r, - cups_page_header2_t *h) _CUPS_API_1_2; +extern unsigned cupsRasterReadHeader2(cups_raster_t *r, cups_page_header2_t *h) _CUPS_API_1_2; +extern unsigned cupsRasterWriteHeader2(cups_raster_t *r, cups_page_header2_t *h) _CUPS_API_1_2; /**** New in CUPS 1.3 ****/ extern const char *cupsRasterErrorString(void) _CUPS_API_1_3; /**** New in CUPS 1.5 ****/ -extern cups_raster_t *cupsRasterOpenIO(cups_raster_iocb_t iocb, void *ctx, - cups_mode_t mode); +extern cups_raster_t *cupsRasterOpenIO(cups_raster_iocb_t iocb, void *ctx, cups_mode_t mode) _CUPS_API_1_5; /**** New in CUPS 2.2/macOS 10.12 ****/ extern int cupsRasterInitPWGHeader(cups_page_header2_t *h, pwg_media_t *media, const char *type, int xdpi, int ydpi, const char *sides, const char *sheet_back) _CUPS_API_2_2; diff --git a/filter/rasterbench.c b/cups/rasterbench.c similarity index 94% rename from filter/rasterbench.c rename to cups/rasterbench.c index 8746f31..f7d8c56 100644 --- a/filter/rasterbench.c +++ b/cups/rasterbench.c @@ -4,13 +4,7 @@ * Copyright 2007-2016 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* diff --git a/cups/request.c b/cups/request.c index 39cbe6c..69a7801 100644 --- a/cups/request.c +++ b/cups/request.c @@ -1,16 +1,10 @@ /* * IPP utilities for CUPS. * - * Copyright 2007-2014 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -18,13 +12,14 @@ */ #include "cups-private.h" +#include "debug-internal.h" #include #include -#if defined(WIN32) || defined(__EMX__) +#if defined(_WIN32) || defined(__EMX__) # include #else # include -#endif /* WIN32 || __EMX__ */ +#endif /* _WIN32 || __EMX__ */ #ifndef O_BINARY # define O_BINARY 0 #endif /* O_BINARY */ @@ -131,13 +126,12 @@ cupsDoIORequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP * Get the default connection as needed... */ - if (!http) - if ((http = _cupsConnect()) == NULL) - { - ippDelete(request); + if (!http && (http = _cupsConnect()) == NULL) + { + ippDelete(request); - return (NULL); - } + return (NULL); + } /* * See if we have a file to send... @@ -151,43 +145,39 @@ cupsDoIORequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP * Can't get file information! */ - _cupsSetError(errno == EBADF ? IPP_STATUS_ERROR_NOT_FOUND : IPP_STATUS_ERROR_NOT_AUTHORIZED, - NULL, 0); - + _cupsSetError(errno == EBADF ? IPP_STATUS_ERROR_NOT_FOUND : IPP_STATUS_ERROR_NOT_AUTHORIZED, NULL, 0); ippDelete(request); return (NULL); } -#ifdef WIN32 +#ifdef _WIN32 if (fileinfo.st_mode & _S_IFDIR) #else if (S_ISDIR(fileinfo.st_mode)) -#endif /* WIN32 */ +#endif /* _WIN32 */ { /* * Can't send a directory... */ - ippDelete(request); - _cupsSetError(IPP_STATUS_ERROR_NOT_POSSIBLE, strerror(EISDIR), 0); + ippDelete(request); return (NULL); } -#ifndef WIN32 +#ifndef _WIN32 if (!S_ISREG(fileinfo.st_mode)) length = 0; /* Chunk when piping */ else -#endif /* !WIN32 */ +#endif /* !_WIN32 */ length = ippLength(request) + (size_t)fileinfo.st_size; } else length = ippLength(request); - DEBUG_printf(("2cupsDoIORequest: Request length=%ld, total length=%ld", - (long)ippLength(request), (long)length)); + DEBUG_printf(("2cupsDoIORequest: Request length=%ld, total length=%ld", (long)ippLength(request), (long)length)); /* * Clear any "Local" authentication data since it is probably stale... @@ -220,9 +210,9 @@ cupsDoIORequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP * Send the file with the request... */ -#ifndef WIN32 +#ifndef _WIN32 if (S_ISREG(fileinfo.st_mode)) -#endif /* WIN32 */ +#endif /* _WIN32 */ lseek(infile, 0, SEEK_SET); while ((bytes = read(infile, buffer, sizeof(buffer))) > 0) @@ -596,6 +586,8 @@ cupsSendRequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP int got_status; /* Did we get the status? */ ipp_state_t state; /* State of IPP processing */ http_status_t expect; /* Expect: header to use */ + char date[256]; /* Date: header value */ + int digest; /* Are we using Digest authentication? */ DEBUG_printf(("cupsSendRequest(http=%p, request=%p(%s), resource=\"%s\", length=" CUPS_LLFMT ")", (void *)http, (void *)request, request ? ippOpString(request->request.op.operation_id) : "?", resource, CUPS_LLCAST length)); @@ -615,9 +607,8 @@ cupsSendRequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP * Get the default connection as needed... */ - if (!http) - if ((http = _cupsConnect()) == NULL) - return (HTTP_STATUS_SERVICE_UNAVAILABLE); + if (!http && (http = _cupsConnect()) == NULL) + return (HTTP_STATUS_SERVICE_UNAVAILABLE); /* * If the prior request was not flushed out, do so now... @@ -657,7 +648,7 @@ cupsSendRequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP * Reconnect if the last response had a "Connection: close"... */ - if (!_cups_strcasecmp(http->fields[HTTP_FIELD_CONNECTION], "close")) + if (!_cups_strcasecmp(httpGetField(http, HTTP_FIELD_CONNECTION), "close")) { DEBUG_puts("2cupsSendRequest: Connection: close"); httpClearFields(http); @@ -685,8 +676,20 @@ cupsSendRequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP httpClearFields(http); httpSetExpect(http, expect); httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/ipp"); + httpSetField(http, HTTP_FIELD_DATE, httpGetDateString2(time(NULL), date, (int)sizeof(date))); httpSetLength(http, length); + digest = http->authstring && !strncmp(http->authstring, "Digest ", 7); + + if (digest) + { + /* + * Update the Digest authentication string... + */ + + _httpSetDigestAuthString(http, http->nextnonce, "POST", resource); + } + #ifdef HAVE_GSSAPI if (http->authstring && !strncmp(http->authstring, "Negotiate", 9)) { @@ -771,9 +774,9 @@ cupsSendRequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP * Wait up to 1 second to get the 100-continue response as needed... */ - if (!got_status) + if (!got_status || (digest && status == HTTP_STATUS_CONTINUE)) { - if (expect == HTTP_STATUS_CONTINUE) + if (expect == HTTP_STATUS_CONTINUE || digest) { DEBUG_puts("2cupsSendRequest: Waiting for 100-continue..."); @@ -996,7 +999,11 @@ _cupsConnect(void) */ if (strcmp(cg->http->hostname, cg->server) || +#ifdef AF_LOCAL + (httpAddrFamily(cg->http->hostaddr) != AF_LOCAL && cg->ipp_port != httpAddrPort(cg->http->hostaddr)) || +#else cg->ipp_port != httpAddrPort(cg->http->hostaddr) || +#endif /* AF_LOCAL */ (cg->http->encryption != cg->encryption && cg->http->encryption == HTTP_ENCRYPTION_NEVER)) { @@ -1016,13 +1023,13 @@ _cupsConnect(void) char ch; /* Connection check byte */ ssize_t n; /* Number of bytes */ -#ifdef WIN32 +#ifdef _WIN32 if ((n = recv(cg->http->fd, &ch, 1, MSG_PEEK)) == 0 || (n < 0 && WSAGetLastError() != WSAEWOULDBLOCK)) #else if ((n = recv(cg->http->fd, &ch, 1, MSG_PEEK | MSG_DONTWAIT)) == 0 || (n < 0 && errno != EWOULDBLOCK)) -#endif /* WIN32 */ +#endif /* _WIN32 */ { /* * Nope, close the connection... diff --git a/cups/sidechannel.c b/cups/sidechannel.c index a4cd960..b43123a 100644 --- a/cups/sidechannel.c +++ b/cups/sidechannel.c @@ -4,13 +4,7 @@ * Copyright 2007-2014 by Apple Inc. * Copyright 2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -19,15 +13,14 @@ #include "sidechannel.h" #include "cups-private.h" -#ifdef WIN32 +#include "debug-internal.h" +#ifdef _WIN32 # include #else # include -#endif /* WIN32 */ -#ifndef WIN32 # include # include -#endif /* !WIN32 */ +#endif /* _WIN32 */ #ifdef HAVE_POLL # include #endif /* HAVE_POLL */ diff --git a/cups/sidechannel.h b/cups/sidechannel.h index a82408f..538b8b2 100644 --- a/cups/sidechannel.h +++ b/cups/sidechannel.h @@ -1,16 +1,10 @@ /* * Side-channel API definitions for CUPS. * - * Copyright 2007-2012 by Apple Inc. - * Copyright 2006 by Easy Software Products. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ #ifndef _CUPS_SIDECHANNEL_H_ @@ -21,6 +15,13 @@ */ # include "versioning.h" +# include +# if defined(_WIN32) && !defined(__CUPS_SSIZE_T_DEFINED) +# define __CUPS_SSIZE_T_DEFINED +# include +/* Windows does not support the ssize_t type, so map it to long... */ +typedef long ssize_t; /* @private@ */ +# endif /* _WIN32 && !__CUPS_SSIZE_T_DEFINED */ /* @@ -113,6 +114,13 @@ typedef void (*cups_sc_walk_func_t)(const char *oid, const char *data, * Prototypes... */ +/**** New in CUPS 1.2/macOS 10.5 ****/ +extern ssize_t cupsBackChannelRead(char *buffer, size_t bytes, + double timeout) _CUPS_API_1_2; +extern ssize_t cupsBackChannelWrite(const char *buffer, size_t bytes, + double timeout) _CUPS_API_1_2; + +/**** New in CUPS 1.3/macOS 10.5 ****/ extern cups_sc_status_t cupsSideChannelDoRequest(cups_sc_command_t command, char *data, int *datalen, double timeout) _CUPS_API_1_3; @@ -125,7 +133,7 @@ extern int cupsSideChannelWrite(cups_sc_command_t command, const char *data, int datalen, double timeout) _CUPS_API_1_3; -/**** New in CUPS 1.4 ****/ +/**** New in CUPS 1.4/macOS 10.6 ****/ extern cups_sc_status_t cupsSideChannelSNMPGet(const char *oid, char *data, int *datalen, double timeout) _CUPS_API_1_4; diff --git a/cups/snmp-private.h b/cups/snmp-private.h index 920ea36..3613019 100644 --- a/cups/snmp-private.h +++ b/cups/snmp-private.h @@ -1,16 +1,11 @@ /* * Private SNMP definitions for CUPS. * - * Copyright 2007-2014 by Apple Inc. - * Copyright 2006-2007 by Easy Software Products, all rights reserved. + * Copyright © 2007-2014 by Apple Inc. + * Copyright © 2006-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * "LICENSE" which should have been included with this file. If this - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ #ifndef _CUPS_SNMP_PRIVATE_H_ @@ -106,32 +101,32 @@ typedef void (*cups_snmp_cb_t)(cups_snmp_t *packet, void *data); extern "C" { # endif /* __cplusplus */ -extern void _cupsSNMPClose(int fd) _CUPS_API_1_4; +extern void _cupsSNMPClose(int fd) _CUPS_PRIVATE; extern int *_cupsSNMPCopyOID(int *dst, const int *src, int dstsize) - _CUPS_API_1_4; -extern const char *_cupsSNMPDefaultCommunity(void) _CUPS_API_1_4; + _CUPS_PRIVATE; +extern const char *_cupsSNMPDefaultCommunity(void) _CUPS_PRIVATE; extern int _cupsSNMPIsOID(cups_snmp_t *packet, const int *oid) - _CUPS_API_1_4; + _CUPS_PRIVATE; extern int _cupsSNMPIsOIDPrefixed(cups_snmp_t *packet, - const int *prefix) _CUPS_API_1_4; + const int *prefix) _CUPS_PRIVATE; extern char *_cupsSNMPOIDToString(const int *src, char *dst, - size_t dstsize) _CUPS_API_1_4; -extern int _cupsSNMPOpen(int family) _CUPS_API_1_4; + size_t dstsize) _CUPS_PRIVATE; +extern int _cupsSNMPOpen(int family) _CUPS_PRIVATE; extern cups_snmp_t *_cupsSNMPRead(int fd, cups_snmp_t *packet, - double timeout) _CUPS_API_1_4; -extern void _cupsSNMPSetDebug(int level) _CUPS_API_1_4; + double timeout) _CUPS_PRIVATE; +extern void _cupsSNMPSetDebug(int level) _CUPS_PRIVATE; extern int *_cupsSNMPStringToOID(const char *src, int *dst, int dstsize) - _CUPS_API_1_4; + _CUPS_PRIVATE; extern int _cupsSNMPWalk(int fd, http_addr_t *address, int version, const char *community, const int *prefix, double timeout, cups_snmp_cb_t cb, - void *data) _CUPS_API_1_4; + void *data) _CUPS_PRIVATE; extern int _cupsSNMPWrite(int fd, http_addr_t *address, int version, const char *community, cups_asn1_t request_type, const unsigned request_id, - const int *oid) _CUPS_API_1_4; + const int *oid) _CUPS_PRIVATE; # ifdef __cplusplus } diff --git a/cups/snmp.c b/cups/snmp.c index 7958b93..1d9da01 100644 --- a/cups/snmp.c +++ b/cups/snmp.c @@ -1,16 +1,11 @@ /* * SNMP functions for CUPS. * - * Copyright 2007-2014 by Apple Inc. - * Copyright 2006-2007 by Easy Software Products, all rights reserved. + * Copyright © 2007-2014 by Apple Inc. + * Copyright © 2006-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * "LICENSE" which should have been included with this file. If this - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -19,6 +14,7 @@ #include "cups-private.h" #include "snmp-private.h" +#include "debug-internal.h" #ifdef HAVE_POLL # include #endif /* HAVE_POLL */ @@ -133,9 +129,13 @@ _cupsSNMPDefaultCommunity(void) { linenum = 0; while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) - if (!_cups_strcasecmp(line, "Community") && value) + if (!_cups_strcasecmp(line, "Community")) { - strlcpy(cg->snmp_community, value, sizeof(cg->snmp_community)); + if (value) + strlcpy(cg->snmp_community, value, sizeof(cg->snmp_community)); + else + cg->snmp_community[0] = '\0'; + break; } @@ -395,11 +395,11 @@ _cupsSNMPRead(int fd, /* I - SNMP socket file descriptor */ ready = select(fd + 1, &input_set, NULL, NULL, &stimeout); } -# ifdef WIN32 +# ifdef _WIN32 while (ready < 0 && WSAGetLastError() == WSAEINTR); # else while (ready < 0 && (errno == EINTR || errno == EAGAIN)); -# endif /* WIN32 */ +# endif /* _WIN32 */ #endif /* HAVE_POLL */ /* @@ -1233,16 +1233,19 @@ asn1_get_integer( int value; /* Integer value */ + if (*buffer >= bufend) + return (0); + if (length > sizeof(int)) { (*buffer) += length; return (0); } - for (value = (**buffer & 0x80) ? -1 : 0; + for (value = (**buffer & 0x80) ? ~0 : 0; length > 0 && *buffer < bufend; length --, (*buffer) ++) - value = (value << 8) | **buffer; + value = ((value & 0xffffff) << 8) | **buffer; return (value); } @@ -1259,6 +1262,9 @@ asn1_get_length(unsigned char **buffer, /* IO - Pointer in buffer */ unsigned length; /* Length */ + if (*buffer >= bufend) + return (0); + length = **buffer; (*buffer) ++; @@ -1301,6 +1307,9 @@ asn1_get_oid( int number; /* OID number */ + if (*buffer >= bufend) + return (0); + valend = *buffer + length; oidptr = oid; oidend = oid + oidsize - 1; @@ -1349,9 +1358,12 @@ asn1_get_packed( int value; /* Value */ + if (*buffer >= bufend) + return (0); + value = 0; - while ((**buffer & 128) && *buffer < bufend) + while (*buffer < bufend && (**buffer & 128)) { value = (value << 7) | (**buffer & 127); (*buffer) ++; @@ -1379,6 +1391,9 @@ asn1_get_string( char *string, /* I - String buffer */ size_t strsize) /* I - String buffer size */ { + if (*buffer >= bufend) + return (NULL); + if (length > (unsigned)(bufend - *buffer)) length = (unsigned)(bufend - *buffer); @@ -1421,6 +1436,9 @@ asn1_get_type(unsigned char **buffer, /* IO - Pointer in buffer */ int type; /* Type */ + if (*buffer >= bufend) + return (0); + type = **buffer; (*buffer) ++; @@ -1617,7 +1635,7 @@ asn1_size_length(unsigned length) /* I - Length value */ /* - * 'asn1_size_oid()' - Figure out the numebr of bytes needed for an + * 'asn1_size_oid()' - Figure out the number of bytes needed for an * OID value. */ diff --git a/cups/snprintf.c b/cups/snprintf.c index c5d8908..49652e2 100644 --- a/cups/snprintf.c +++ b/cups/snprintf.c @@ -1,16 +1,11 @@ /* * snprintf functions for CUPS. * - * Copyright 2007-2013 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -177,7 +172,7 @@ _cups_vsnprintf(char *buffer, /* O - Output buffer */ break; sprintf(temp, tformat, va_arg(ap, double)); - templen = strlen(temp): + templen = strlen(temp); bytes += (int)templen; @@ -208,7 +203,7 @@ _cups_vsnprintf(char *buffer, /* O - Output buffer */ break; sprintf(temp, tformat, va_arg(ap, int)); - templen = strlen(temp): + templen = strlen(temp); bytes += (int)templen; @@ -232,7 +227,7 @@ _cups_vsnprintf(char *buffer, /* O - Output buffer */ break; sprintf(temp, tformat, va_arg(ap, void *)); - templen = strlen(temp): + templen = strlen(temp); bytes += (int)templen; diff --git a/cups/sspi-private.h b/cups/sspi-private.h deleted file mode 100644 index e8f36c2..0000000 --- a/cups/sspi-private.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Private SSPI definitions for CUPS. - * - * Copyright 2010 by Apple Inc. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - */ - -#ifndef _CUPS_SSPI_PRIVATE_H_ -# define _CUPS_SSPI_PRIVATE_H_ - -/* - * Include necessary headers... - */ - -# include -# include -# include -# include -# include -# include -# define SECURITY_WIN32 -# include -# include - -/* - * C++ magic... - */ - -# ifdef __cplusplus -extern "C" { -# endif /* __cplusplus */ - - -typedef struct /**** SSPI/SSL data structure ****/ -{ - SOCKET sock; /* TCP/IP socket */ - CredHandle creds; /* Credentials */ - CtxtHandle context; /* SSL context */ - BOOL contextInitialized; /* Is context init'd? */ - SecPkgContext_StreamSizes streamSizes; /* SSL data stream sizes */ - BYTE *decryptBuffer; /* Data pre-decryption*/ - size_t decryptBufferLength; /* Length of decrypt buffer */ - size_t decryptBufferUsed; /* Bytes used in buffer */ - BYTE *readBuffer; /* Data post-decryption */ - size_t readBufferLength; /* Length of read buffer */ - size_t readBufferUsed; /* Bytes used in buffer */ - DWORD certFlags; /* Cert verification flags */ -} _sspi_struct_t; - - -/* - * Prototypes... - */ -_sspi_struct_t *_sspiAlloc(void); -BOOL _sspiAccept(_sspi_struct_t *conn); -BOOL _sspiConnect(_sspi_struct_t *conn, - const CHAR *hostname); -void _sspiFree(_sspi_struct_t *conn); -BOOL _sspiGetCredentials(_sspi_struct_t *conn, - const LPWSTR containerName, - const TCHAR *commonName, - BOOL server); -int _sspiPending(_sspi_struct_t *conn); -int _sspiRead(_sspi_struct_t *conn, - void *buf, size_t len); -void _sspiSetAllowsAnyRoot(_sspi_struct_t *conn, - BOOL allow); -void _sspiSetAllowsExpiredCerts(_sspi_struct_t *conn, - BOOL allow); -int _sspiWrite(_sspi_struct_t *conn, - void *buf, size_t len); - - -# ifdef __cplusplus -} -# endif /* __cplusplus */ -#endif /* !_CUPS_SSPI_PRIVATE_H_ */ diff --git a/cups/sspi.c b/cups/sspi.c deleted file mode 100644 index ff79e5a..0000000 --- a/cups/sspi.c +++ /dev/null @@ -1,1485 +0,0 @@ -/* - * "$Id: sspi.c 3247 2011-05-12 06:22:31Z msweet $" - * - * Windows SSPI SSL implementation for CUPS. - * - * Copyright 2010-2011 by Apple Inc. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * Contents: - * - * sspi_alloc() - Allocate SSPI ssl object - * _sspiGetCredentials() - Retrieve an SSL/TLS certificate from the - * system store If one cannot be found, one is - * created. - * _sspiConnect() - Make an SSL connection. This function - * assumes a TCP/IP connection has already been - * successfully made - * _sspiAccept() - Accept an SSL/TLS connection - * _sspiSetAllowsAnyRoot() - Set the client cert policy for untrusted - * root certs - * _sspiSetAllowsExpiredCerts() - Set the client cert policy for expired root - * certs - * _sspiWrite() - Write a buffer to an ssl socket - * _sspiRead() - Read a buffer from an ssl socket - * _sspiPending() - Returns the number of available bytes - * _sspiFree() - Close a connection and free resources - * sspi_verify_certificate() - Verify a server certificate - */ - -/* - * Include necessary headers... - */ - -#include "sspi-private.h" -#include "debug-private.h" - - -/* required to link this library for certificate functions */ -#pragma comment(lib, "Crypt32.lib") -#pragma comment(lib, "Secur32.lib") -#pragma comment(lib, "Ws2_32.lib") - - -#if !defined(SECURITY_FLAG_IGNORE_UNKNOWN_CA) -# define SECURITY_FLAG_IGNORE_UNKNOWN_CA 0x00000100 /* Untrusted root */ -#endif - -#if !defined(SECURITY_FLAG_IGNORE_CERT_DATE_INVALID) -# define SECURITY_FLAG_IGNORE_CERT_DATE_INVALID 0x00002000 /* Expired X509 Cert. */ -#endif - -static DWORD sspi_verify_certificate(PCCERT_CONTEXT serverCert, - const CHAR *serverName, - DWORD dwCertFlags); - - -/* - * 'sspi_alloc()' - Allocate SSPI ssl object - */ -_sspi_struct_t* /* O - New SSPI/SSL object */ -_sspiAlloc(void) -{ - _sspi_struct_t *conn = calloc(sizeof(_sspi_struct_t), 1); - - if (conn) - conn->sock = INVALID_SOCKET; - - return (conn); -} - - -/* - * '_sspiGetCredentials()' - Retrieve an SSL/TLS certificate from the system store - * If one cannot be found, one is created. - */ -BOOL /* O - 1 on success, 0 on failure */ -_sspiGetCredentials(_sspi_struct_t *conn, - /* I - Client connection */ - const LPWSTR container, - /* I - Cert container name */ - const TCHAR *cn, /* I - Common name of certificate */ - BOOL isServer) - /* I - Is caller a server? */ -{ - HCERTSTORE store = NULL; /* Certificate store */ - PCCERT_CONTEXT storedContext = NULL; - /* Context created from the store */ - PCCERT_CONTEXT createdContext = NULL; - /* Context created by us */ - DWORD dwSize = 0; /* 32 bit size */ - PBYTE p = NULL; /* Temporary storage */ - HCRYPTPROV hProv = (HCRYPTPROV) NULL; - /* Handle to a CSP */ - CERT_NAME_BLOB sib; /* Arbitrary array of bytes */ - SCHANNEL_CRED SchannelCred; /* Schannel credential data */ - TimeStamp tsExpiry; /* Time stamp */ - SECURITY_STATUS Status; /* Status */ - HCRYPTKEY hKey = (HCRYPTKEY) NULL; - /* Handle to crypto key */ - CRYPT_KEY_PROV_INFO kpi; /* Key container info */ - SYSTEMTIME et; /* System time */ - CERT_EXTENSIONS exts; /* Array of cert extensions */ - CRYPT_KEY_PROV_INFO ckp; /* Handle to crypto key */ - BOOL ok = TRUE; /* Return value */ - - if (!conn) - return (FALSE); - if (!cn) - return (FALSE); - - if (!CryptAcquireContextW(&hProv, (LPWSTR) container, MS_DEF_PROV_W, - PROV_RSA_FULL, - CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET)) - { - if (GetLastError() == NTE_EXISTS) - { - if (!CryptAcquireContextW(&hProv, (LPWSTR) container, MS_DEF_PROV_W, - PROV_RSA_FULL, CRYPT_MACHINE_KEYSET)) - { - DEBUG_printf(("_sspiGetCredentials: CryptAcquireContext failed: %x\n", - GetLastError())); - ok = FALSE; - goto cleanup; - } - } - } - - store = CertOpenStore(CERT_STORE_PROV_SYSTEM, - X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, - hProv, - CERT_SYSTEM_STORE_LOCAL_MACHINE | - CERT_STORE_NO_CRYPT_RELEASE_FLAG | - CERT_STORE_OPEN_EXISTING_FLAG, - L"MY"); - - if (!store) - { - DEBUG_printf(("_sspiGetCredentials: CertOpenSystemStore failed: %x\n", - GetLastError())); - ok = FALSE; - goto cleanup; - } - - dwSize = 0; - - if (!CertStrToName(X509_ASN_ENCODING, cn, CERT_OID_NAME_STR, - NULL, NULL, &dwSize, NULL)) - { - DEBUG_printf(("_sspiGetCredentials: CertStrToName failed: %x\n", - GetLastError())); - ok = FALSE; - goto cleanup; - } - - p = (PBYTE) malloc(dwSize); - - if (!p) - { - DEBUG_printf(("_sspiGetCredentials: malloc failed for %d bytes", dwSize)); - ok = FALSE; - goto cleanup; - } - - if (!CertStrToName(X509_ASN_ENCODING, cn, CERT_OID_NAME_STR, NULL, - p, &dwSize, NULL)) - { - DEBUG_printf(("_sspiGetCredentials: CertStrToName failed: %x", - GetLastError())); - ok = FALSE; - goto cleanup; - } - - sib.cbData = dwSize; - sib.pbData = p; - - storedContext = CertFindCertificateInStore(store, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, - 0, CERT_FIND_SUBJECT_NAME, &sib, NULL); - - if (!storedContext) - { - /* - * If we couldn't find the context, then we'll - * create a new one - */ - if (!CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hKey)) - { - DEBUG_printf(("_sspiGetCredentials: CryptGenKey failed: %x", - GetLastError())); - ok = FALSE; - goto cleanup; - } - - ZeroMemory(&kpi, sizeof(kpi)); - kpi.pwszContainerName = (LPWSTR) container; - kpi.pwszProvName = MS_DEF_PROV_W; - kpi.dwProvType = PROV_RSA_FULL; - kpi.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID; - kpi.dwKeySpec = AT_KEYEXCHANGE; - - GetSystemTime(&et); - et.wYear += 10; - - ZeroMemory(&exts, sizeof(exts)); - - createdContext = CertCreateSelfSignCertificate(hProv, &sib, 0, &kpi, NULL, NULL, - &et, &exts); - - if (!createdContext) - { - DEBUG_printf(("_sspiGetCredentials: CertCreateSelfSignCertificate failed: %x", - GetLastError())); - ok = FALSE; - goto cleanup; - } - - if (!CertAddCertificateContextToStore(store, createdContext, - CERT_STORE_ADD_REPLACE_EXISTING, - &storedContext)) - { - DEBUG_printf(("_sspiGetCredentials: CertAddCertificateContextToStore failed: %x", - GetLastError())); - ok = FALSE; - goto cleanup; - } - - ZeroMemory(&ckp, sizeof(ckp)); - ckp.pwszContainerName = (LPWSTR) container; - ckp.pwszProvName = MS_DEF_PROV_W; - ckp.dwProvType = PROV_RSA_FULL; - ckp.dwFlags = CRYPT_MACHINE_KEYSET; - ckp.dwKeySpec = AT_KEYEXCHANGE; - - if (!CertSetCertificateContextProperty(storedContext, - CERT_KEY_PROV_INFO_PROP_ID, - 0, &ckp)) - { - DEBUG_printf(("_sspiGetCredentials: CertSetCertificateContextProperty failed: %x", - GetLastError())); - ok = FALSE; - goto cleanup; - } - } - - ZeroMemory(&SchannelCred, sizeof(SchannelCred)); - - SchannelCred.dwVersion = SCHANNEL_CRED_VERSION; - SchannelCred.cCreds = 1; - SchannelCred.paCred = &storedContext; - - /* - * SSPI doesn't seem to like it if grbitEnabledProtocols - * is set for a client - */ - if (isServer) - SchannelCred.grbitEnabledProtocols = SP_PROT_SSL3TLS1; - - /* - * Create an SSPI credential. - */ - Status = AcquireCredentialsHandle(NULL, UNISP_NAME, - isServer ? SECPKG_CRED_INBOUND:SECPKG_CRED_OUTBOUND, - NULL, &SchannelCred, NULL, NULL, &conn->creds, - &tsExpiry); - if (Status != SEC_E_OK) - { - DEBUG_printf(("_sspiGetCredentials: AcquireCredentialsHandle failed: %x", Status)); - ok = FALSE; - goto cleanup; - } - -cleanup: - - /* - * Cleanup - */ - if (hKey) - CryptDestroyKey(hKey); - - if (createdContext) - CertFreeCertificateContext(createdContext); - - if (storedContext) - CertFreeCertificateContext(storedContext); - - if (p) - free(p); - - if (store) - CertCloseStore(store, 0); - - if (hProv) - CryptReleaseContext(hProv, 0); - - return (ok); -} - - -/* - * '_sspiConnect()' - Make an SSL connection. This function - * assumes a TCP/IP connection has already - * been successfully made - */ -BOOL /* O - 1 on success, 0 on failure */ -_sspiConnect(_sspi_struct_t *conn, /* I - Client connection */ - const CHAR *hostname) /* I - Server hostname */ -{ - PCCERT_CONTEXT serverCert; /* Server certificate */ - DWORD dwSSPIFlags; /* SSL connection attributes we want */ - DWORD dwSSPIOutFlags; /* SSL connection attributes we got */ - TimeStamp tsExpiry; /* Time stamp */ - SECURITY_STATUS scRet; /* Status */ - DWORD cbData; /* Data count */ - SecBufferDesc inBuffer; /* Array of SecBuffer structs */ - SecBuffer inBuffers[2]; /* Security package buffer */ - SecBufferDesc outBuffer; /* Array of SecBuffer structs */ - SecBuffer outBuffers[1]; /* Security package buffer */ - BOOL ok = TRUE; /* Return value */ - - serverCert = NULL; - - dwSSPIFlags = ISC_REQ_SEQUENCE_DETECT | - ISC_REQ_REPLAY_DETECT | - ISC_REQ_CONFIDENTIALITY | - ISC_RET_EXTENDED_ERROR | - ISC_REQ_ALLOCATE_MEMORY | - ISC_REQ_STREAM; - - /* - * Initiate a ClientHello message and generate a token. - */ - outBuffers[0].pvBuffer = NULL; - outBuffers[0].BufferType = SECBUFFER_TOKEN; - outBuffers[0].cbBuffer = 0; - - outBuffer.cBuffers = 1; - outBuffer.pBuffers = outBuffers; - outBuffer.ulVersion = SECBUFFER_VERSION; - - scRet = InitializeSecurityContext(&conn->creds, NULL, TEXT(""), dwSSPIFlags, - 0, SECURITY_NATIVE_DREP, NULL, 0, &conn->context, - &outBuffer, &dwSSPIOutFlags, &tsExpiry); - - if (scRet != SEC_I_CONTINUE_NEEDED) - { - DEBUG_printf(("_sspiConnect: InitializeSecurityContext(1) failed: %x", scRet)); - ok = FALSE; - goto cleanup; - } - - /* - * Send response to server if there is one. - */ - if (outBuffers[0].cbBuffer && outBuffers[0].pvBuffer) - { - cbData = send(conn->sock, outBuffers[0].pvBuffer, outBuffers[0].cbBuffer, 0); - - if ((cbData == SOCKET_ERROR) || !cbData) - { - DEBUG_printf(("_sspiConnect: send failed: %d", WSAGetLastError())); - FreeContextBuffer(outBuffers[0].pvBuffer); - DeleteSecurityContext(&conn->context); - ok = FALSE; - goto cleanup; - } - - DEBUG_printf(("_sspiConnect: %d bytes of handshake data sent", cbData)); - - /* - * Free output buffer. - */ - FreeContextBuffer(outBuffers[0].pvBuffer); - outBuffers[0].pvBuffer = NULL; - } - - dwSSPIFlags = ISC_REQ_MANUAL_CRED_VALIDATION | - ISC_REQ_SEQUENCE_DETECT | - ISC_REQ_REPLAY_DETECT | - ISC_REQ_CONFIDENTIALITY | - ISC_RET_EXTENDED_ERROR | - ISC_REQ_ALLOCATE_MEMORY | - ISC_REQ_STREAM; - - conn->decryptBufferUsed = 0; - - /* - * Loop until the handshake is finished or an error occurs. - */ - scRet = SEC_I_CONTINUE_NEEDED; - - while(scRet == SEC_I_CONTINUE_NEEDED || - scRet == SEC_E_INCOMPLETE_MESSAGE || - scRet == SEC_I_INCOMPLETE_CREDENTIALS) - { - if ((conn->decryptBufferUsed == 0) || (scRet == SEC_E_INCOMPLETE_MESSAGE)) - { - if (conn->decryptBufferLength <= conn->decryptBufferUsed) - { - conn->decryptBufferLength += 4096; - conn->decryptBuffer = (BYTE*) realloc(conn->decryptBuffer, conn->decryptBufferLength); - - if (!conn->decryptBuffer) - { - DEBUG_printf(("_sspiConnect: unable to allocate %d byte decrypt buffer", - conn->decryptBufferLength)); - SetLastError(E_OUTOFMEMORY); - ok = FALSE; - goto cleanup; - } - } - - cbData = recv(conn->sock, conn->decryptBuffer + conn->decryptBufferUsed, - (int) (conn->decryptBufferLength - conn->decryptBufferUsed), 0); - - if (cbData == SOCKET_ERROR) - { - DEBUG_printf(("_sspiConnect: recv failed: %d", WSAGetLastError())); - ok = FALSE; - goto cleanup; - } - else if (cbData == 0) - { - DEBUG_printf(("_sspiConnect: server unexpectedly disconnected")); - ok = FALSE; - goto cleanup; - } - - DEBUG_printf(("_sspiConnect: %d bytes of handshake data received", - cbData)); - - conn->decryptBufferUsed += cbData; - } - - /* - * Set up the input buffers. Buffer 0 is used to pass in data - * received from the server. Schannel will consume some or all - * of this. Leftover data (if any) will be placed in buffer 1 and - * given a buffer type of SECBUFFER_EXTRA. - */ - inBuffers[0].pvBuffer = conn->decryptBuffer; - inBuffers[0].cbBuffer = (unsigned long) conn->decryptBufferUsed; - inBuffers[0].BufferType = SECBUFFER_TOKEN; - - inBuffers[1].pvBuffer = NULL; - inBuffers[1].cbBuffer = 0; - inBuffers[1].BufferType = SECBUFFER_EMPTY; - - inBuffer.cBuffers = 2; - inBuffer.pBuffers = inBuffers; - inBuffer.ulVersion = SECBUFFER_VERSION; - - /* - * Set up the output buffers. These are initialized to NULL - * so as to make it less likely we'll attempt to free random - * garbage later. - */ - outBuffers[0].pvBuffer = NULL; - outBuffers[0].BufferType= SECBUFFER_TOKEN; - outBuffers[0].cbBuffer = 0; - - outBuffer.cBuffers = 1; - outBuffer.pBuffers = outBuffers; - outBuffer.ulVersion = SECBUFFER_VERSION; - - /* - * Call InitializeSecurityContext. - */ - scRet = InitializeSecurityContext(&conn->creds, &conn->context, NULL, dwSSPIFlags, - 0, SECURITY_NATIVE_DREP, &inBuffer, 0, NULL, - &outBuffer, &dwSSPIOutFlags, &tsExpiry); - - /* - * If InitializeSecurityContext was successful (or if the error was - * one of the special extended ones), send the contends of the output - * buffer to the server. - */ - if (scRet == SEC_E_OK || - scRet == SEC_I_CONTINUE_NEEDED || - FAILED(scRet) && (dwSSPIOutFlags & ISC_RET_EXTENDED_ERROR)) - { - if (outBuffers[0].cbBuffer && outBuffers[0].pvBuffer) - { - cbData = send(conn->sock, outBuffers[0].pvBuffer, outBuffers[0].cbBuffer, 0); - - if ((cbData == SOCKET_ERROR) || !cbData) - { - DEBUG_printf(("_sspiConnect: send failed: %d", WSAGetLastError())); - FreeContextBuffer(outBuffers[0].pvBuffer); - DeleteSecurityContext(&conn->context); - ok = FALSE; - goto cleanup; - } - - DEBUG_printf(("_sspiConnect: %d bytes of handshake data sent", cbData)); - - /* - * Free output buffer. - */ - FreeContextBuffer(outBuffers[0].pvBuffer); - outBuffers[0].pvBuffer = NULL; - } - } - - /* - * If InitializeSecurityContext returned SEC_E_INCOMPLETE_MESSAGE, - * then we need to read more data from the server and try again. - */ - if (scRet == SEC_E_INCOMPLETE_MESSAGE) - continue; - - /* - * If InitializeSecurityContext returned SEC_E_OK, then the - * handshake completed successfully. - */ - if (scRet == SEC_E_OK) - { - /* - * If the "extra" buffer contains data, this is encrypted application - * protocol layer stuff. It needs to be saved. The application layer - * will later decrypt it with DecryptMessage. - */ - DEBUG_printf(("_sspiConnect: Handshake was successful")); - - if (inBuffers[1].BufferType == SECBUFFER_EXTRA) - { - if (conn->decryptBufferLength < inBuffers[1].cbBuffer) - { - conn->decryptBuffer = realloc(conn->decryptBuffer, inBuffers[1].cbBuffer); - - if (!conn->decryptBuffer) - { - DEBUG_printf(("_sspiConnect: unable to allocate %d bytes for decrypt buffer", - inBuffers[1].cbBuffer)); - SetLastError(E_OUTOFMEMORY); - ok = FALSE; - goto cleanup; - } - } - - memmove(conn->decryptBuffer, - conn->decryptBuffer + (conn->decryptBufferUsed - inBuffers[1].cbBuffer), - inBuffers[1].cbBuffer); - - conn->decryptBufferUsed = inBuffers[1].cbBuffer; - - DEBUG_printf(("_sspiConnect: %d bytes of app data was bundled with handshake data", - conn->decryptBufferUsed)); - } - else - conn->decryptBufferUsed = 0; - - /* - * Bail out to quit - */ - break; - } - - /* - * Check for fatal error. - */ - if (FAILED(scRet)) - { - DEBUG_printf(("_sspiConnect: InitializeSecurityContext(2) failed: %x", scRet)); - ok = FALSE; - break; - } - - /* - * If InitializeSecurityContext returned SEC_I_INCOMPLETE_CREDENTIALS, - * then the server just requested client authentication. - */ - if (scRet == SEC_I_INCOMPLETE_CREDENTIALS) - { - /* - * Unimplemented - */ - DEBUG_printf(("_sspiConnect: server requested client credentials")); - ok = FALSE; - break; - } - - /* - * Copy any leftover data from the "extra" buffer, and go around - * again. - */ - if (inBuffers[1].BufferType == SECBUFFER_EXTRA) - { - memmove(conn->decryptBuffer, - conn->decryptBuffer + (conn->decryptBufferUsed - inBuffers[1].cbBuffer), - inBuffers[1].cbBuffer); - - conn->decryptBufferUsed = inBuffers[1].cbBuffer; - } - else - { - conn->decryptBufferUsed = 0; - } - } - - if (ok) - { - conn->contextInitialized = TRUE; - - /* - * Get the server cert - */ - scRet = QueryContextAttributes(&conn->context, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (VOID*) &serverCert ); - - if (scRet != SEC_E_OK) - { - DEBUG_printf(("_sspiConnect: QueryContextAttributes failed(SECPKG_ATTR_REMOTE_CERT_CONTEXT): %x", scRet)); - ok = FALSE; - goto cleanup; - } - - scRet = sspi_verify_certificate(serverCert, hostname, conn->certFlags); - - if (scRet != SEC_E_OK) - { - DEBUG_printf(("_sspiConnect: sspi_verify_certificate failed: %x", scRet)); - ok = FALSE; - goto cleanup; - } - - /* - * Find out how big the header/trailer will be: - */ - scRet = QueryContextAttributes(&conn->context, SECPKG_ATTR_STREAM_SIZES, &conn->streamSizes); - - if (scRet != SEC_E_OK) - { - DEBUG_printf(("_sspiConnect: QueryContextAttributes failed(SECPKG_ATTR_STREAM_SIZES): %x", scRet)); - ok = FALSE; - } - } - -cleanup: - - if (serverCert) - CertFreeCertificateContext(serverCert); - - return (ok); -} - - -/* - * '_sspiAccept()' - Accept an SSL/TLS connection - */ -BOOL /* O - 1 on success, 0 on failure */ -_sspiAccept(_sspi_struct_t *conn) /* I - Client connection */ -{ - DWORD dwSSPIFlags; /* SSL connection attributes we want */ - DWORD dwSSPIOutFlags; /* SSL connection attributes we got */ - TimeStamp tsExpiry; /* Time stamp */ - SECURITY_STATUS scRet; /* SSPI Status */ - SecBufferDesc inBuffer; /* Array of SecBuffer structs */ - SecBuffer inBuffers[2]; /* Security package buffer */ - SecBufferDesc outBuffer; /* Array of SecBuffer structs */ - SecBuffer outBuffers[1]; /* Security package buffer */ - DWORD num = 0; /* 32 bit status value */ - BOOL fInitContext = TRUE; - /* Has the context been init'd? */ - BOOL ok = TRUE; /* Return value */ - - if (!conn) - return (FALSE); - - dwSSPIFlags = ASC_REQ_SEQUENCE_DETECT | - ASC_REQ_REPLAY_DETECT | - ASC_REQ_CONFIDENTIALITY | - ASC_REQ_EXTENDED_ERROR | - ASC_REQ_ALLOCATE_MEMORY | - ASC_REQ_STREAM; - - conn->decryptBufferUsed = 0; - - /* - * Set OutBuffer for AcceptSecurityContext call - */ - outBuffer.cBuffers = 1; - outBuffer.pBuffers = outBuffers; - outBuffer.ulVersion = SECBUFFER_VERSION; - - scRet = SEC_I_CONTINUE_NEEDED; - - while (scRet == SEC_I_CONTINUE_NEEDED || - scRet == SEC_E_INCOMPLETE_MESSAGE || - scRet == SEC_I_INCOMPLETE_CREDENTIALS) - { - if ((conn->decryptBufferUsed == 0) || (scRet == SEC_E_INCOMPLETE_MESSAGE)) - { - if (conn->decryptBufferLength <= conn->decryptBufferUsed) - { - conn->decryptBufferLength += 4096; - conn->decryptBuffer = (BYTE*) realloc(conn->decryptBuffer, - conn->decryptBufferLength); - - if (!conn->decryptBuffer) - { - DEBUG_printf(("_sspiAccept: unable to allocate %d byte decrypt buffer", - conn->decryptBufferLength)); - ok = FALSE; - goto cleanup; - } - } - - for (;;) - { - num = recv(conn->sock, - conn->decryptBuffer + conn->decryptBufferUsed, - (int)(conn->decryptBufferLength - conn->decryptBufferUsed), - 0); - - if ((num == SOCKET_ERROR) && (WSAGetLastError() == WSAEWOULDBLOCK)) - Sleep(1); - else - break; - } - - if (num == SOCKET_ERROR) - { - DEBUG_printf(("_sspiAccept: recv failed: %d", WSAGetLastError())); - ok = FALSE; - goto cleanup; - } - else if (num == 0) - { - DEBUG_printf(("_sspiAccept: client disconnected")); - ok = FALSE; - goto cleanup; - } - - DEBUG_printf(("_sspiAccept: received %d (handshake) bytes from client", - num)); - conn->decryptBufferUsed += num; - } - - /* - * InBuffers[1] is for getting extra data that - * SSPI/SCHANNEL doesn't proccess on this - * run around the loop. - */ - inBuffers[0].pvBuffer = conn->decryptBuffer; - inBuffers[0].cbBuffer = (unsigned long) conn->decryptBufferUsed; - inBuffers[0].BufferType = SECBUFFER_TOKEN; - - inBuffers[1].pvBuffer = NULL; - inBuffers[1].cbBuffer = 0; - inBuffers[1].BufferType = SECBUFFER_EMPTY; - - inBuffer.cBuffers = 2; - inBuffer.pBuffers = inBuffers; - inBuffer.ulVersion = SECBUFFER_VERSION; - - /* - * Initialize these so if we fail, pvBuffer contains NULL, - * so we don't try to free random garbage at the quit - */ - outBuffers[0].pvBuffer = NULL; - outBuffers[0].BufferType = SECBUFFER_TOKEN; - outBuffers[0].cbBuffer = 0; - - scRet = AcceptSecurityContext(&conn->creds, (fInitContext?NULL:&conn->context), - &inBuffer, dwSSPIFlags, SECURITY_NATIVE_DREP, - (fInitContext?&conn->context:NULL), &outBuffer, - &dwSSPIOutFlags, &tsExpiry); - - fInitContext = FALSE; - - if (scRet == SEC_E_OK || - scRet == SEC_I_CONTINUE_NEEDED || - (FAILED(scRet) && ((dwSSPIOutFlags & ISC_RET_EXTENDED_ERROR) != 0))) - { - if (outBuffers[0].cbBuffer && outBuffers[0].pvBuffer) - { - /* - * Send response to server if there is one - */ - num = send(conn->sock, outBuffers[0].pvBuffer, outBuffers[0].cbBuffer, 0); - - if ((num == SOCKET_ERROR) || (num == 0)) - { - DEBUG_printf(("_sspiAccept: handshake send failed: %d", WSAGetLastError())); - ok = FALSE; - goto cleanup; - } - - DEBUG_printf(("_sspiAccept: send %d handshake bytes to client", - outBuffers[0].cbBuffer)); - - FreeContextBuffer(outBuffers[0].pvBuffer); - outBuffers[0].pvBuffer = NULL; - } - } - - if (scRet == SEC_E_OK) - { - /* - * If there's extra data then save it for - * next time we go to decrypt - */ - if (inBuffers[1].BufferType == SECBUFFER_EXTRA) - { - memcpy(conn->decryptBuffer, - (LPBYTE) (conn->decryptBuffer + (conn->decryptBufferUsed - inBuffers[1].cbBuffer)), - inBuffers[1].cbBuffer); - conn->decryptBufferUsed = inBuffers[1].cbBuffer; - } - else - { - conn->decryptBufferUsed = 0; - } - - ok = TRUE; - break; - } - else if (FAILED(scRet) && (scRet != SEC_E_INCOMPLETE_MESSAGE)) - { - DEBUG_printf(("_sspiAccept: AcceptSecurityContext failed: %x", scRet)); - ok = FALSE; - break; - } - - if (scRet != SEC_E_INCOMPLETE_MESSAGE && - scRet != SEC_I_INCOMPLETE_CREDENTIALS) - { - if (inBuffers[1].BufferType == SECBUFFER_EXTRA) - { - memcpy(conn->decryptBuffer, - (LPBYTE) (conn->decryptBuffer + (conn->decryptBufferUsed - inBuffers[1].cbBuffer)), - inBuffers[1].cbBuffer); - conn->decryptBufferUsed = inBuffers[1].cbBuffer; - } - else - { - conn->decryptBufferUsed = 0; - } - } - } - - if (ok) - { - conn->contextInitialized = TRUE; - - /* - * Find out how big the header will be: - */ - scRet = QueryContextAttributes(&conn->context, SECPKG_ATTR_STREAM_SIZES, &conn->streamSizes); - - if (scRet != SEC_E_OK) - { - DEBUG_printf(("_sspiAccept: QueryContextAttributes failed: %x", scRet)); - ok = FALSE; - } - } - -cleanup: - - return (ok); -} - - -/* - * '_sspiSetAllowsAnyRoot()' - Set the client cert policy for untrusted root certs - */ -void -_sspiSetAllowsAnyRoot(_sspi_struct_t *conn, - /* I - Client connection */ - BOOL allow) - /* I - Allow any root */ -{ - conn->certFlags = (allow) ? conn->certFlags | SECURITY_FLAG_IGNORE_UNKNOWN_CA : - conn->certFlags & ~SECURITY_FLAG_IGNORE_UNKNOWN_CA; -} - - -/* - * '_sspiSetAllowsExpiredCerts()' - Set the client cert policy for expired root certs - */ -void -_sspiSetAllowsExpiredCerts(_sspi_struct_t *conn, - /* I - Client connection */ - BOOL allow) - /* I - Allow expired certs */ -{ - conn->certFlags = (allow) ? conn->certFlags | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID : - conn->certFlags & ~SECURITY_FLAG_IGNORE_CERT_DATE_INVALID; -} - - -/* - * '_sspiWrite()' - Write a buffer to an ssl socket - */ -int /* O - Bytes written or SOCKET_ERROR */ -_sspiWrite(_sspi_struct_t *conn, /* I - Client connection */ - void *buf, /* I - Buffer */ - size_t len) /* I - Buffer length */ -{ - SecBufferDesc message; /* Array of SecBuffer struct */ - SecBuffer buffers[4] = { 0 }; /* Security package buffer */ - BYTE *buffer = NULL; /* Scratch buffer */ - int bufferLen; /* Buffer length */ - size_t bytesLeft; /* Bytes left to write */ - int index = 0; /* Index into buffer */ - int num = 0; /* Return value */ - - if (!conn || !buf || !len) - { - WSASetLastError(WSAEINVAL); - num = SOCKET_ERROR; - goto cleanup; - } - - bufferLen = conn->streamSizes.cbMaximumMessage + - conn->streamSizes.cbHeader + - conn->streamSizes.cbTrailer; - - buffer = (BYTE*) malloc(bufferLen); - - if (!buffer) - { - DEBUG_printf(("_sspiWrite: buffer alloc of %d bytes failed", bufferLen)); - WSASetLastError(E_OUTOFMEMORY); - num = SOCKET_ERROR; - goto cleanup; - } - - bytesLeft = len; - - while (bytesLeft) - { - size_t chunk = min(conn->streamSizes.cbMaximumMessage, /* Size of data to write */ - bytesLeft); - SECURITY_STATUS scRet; /* SSPI status */ - - /* - * Copy user data into the buffer, starting - * just past the header - */ - memcpy(buffer + conn->streamSizes.cbHeader, - ((BYTE*) buf) + index, - chunk); - - /* - * Setup the SSPI buffers - */ - message.ulVersion = SECBUFFER_VERSION; - message.cBuffers = 4; - message.pBuffers = buffers; - buffers[0].pvBuffer = buffer; - buffers[0].cbBuffer = conn->streamSizes.cbHeader; - buffers[0].BufferType = SECBUFFER_STREAM_HEADER; - buffers[1].pvBuffer = buffer + conn->streamSizes.cbHeader; - buffers[1].cbBuffer = (unsigned long) chunk; - buffers[1].BufferType = SECBUFFER_DATA; - buffers[2].pvBuffer = buffer + conn->streamSizes.cbHeader + chunk; - buffers[2].cbBuffer = conn->streamSizes.cbTrailer; - buffers[2].BufferType = SECBUFFER_STREAM_TRAILER; - buffers[3].BufferType = SECBUFFER_EMPTY; - - /* - * Encrypt the data - */ - scRet = EncryptMessage(&conn->context, 0, &message, 0); - - if (FAILED(scRet)) - { - DEBUG_printf(("_sspiWrite: EncryptMessage failed: %x", scRet)); - WSASetLastError(WSASYSCALLFAILURE); - num = SOCKET_ERROR; - goto cleanup; - } - - /* - * Send the data. Remember the size of - * the total data to send is the size - * of the header, the size of the data - * the caller passed in and the size - * of the trailer - */ - num = send(conn->sock, - buffer, - buffers[0].cbBuffer + buffers[1].cbBuffer + buffers[2].cbBuffer, - 0); - - if ((num == SOCKET_ERROR) || (num == 0)) - { - DEBUG_printf(("_sspiWrite: send failed: %ld", WSAGetLastError())); - goto cleanup; - } - - bytesLeft -= (int) chunk; - index += (int) chunk; - } - - num = (int) len; - -cleanup: - - if (buffer) - free(buffer); - - return (num); -} - - -/* - * '_sspiRead()' - Read a buffer from an ssl socket - */ -int /* O - Bytes read or SOCKET_ERROR */ -_sspiRead(_sspi_struct_t *conn, /* I - Client connection */ - void *buf, /* I - Buffer */ - size_t len) /* I - Buffer length */ -{ - SecBufferDesc message; /* Array of SecBuffer struct */ - SecBuffer buffers[4] = { 0 }; /* Security package buffer */ - int num = 0; /* Return value */ - - if (!conn) - { - WSASetLastError(WSAEINVAL); - num = SOCKET_ERROR; - goto cleanup; - } - - /* - * If there are bytes that have already been - * decrypted and have not yet been read, return - * those - */ - if (buf && (conn->readBufferUsed > 0)) - { - int bytesToCopy = (int) min(conn->readBufferUsed, len); /* Amount of bytes to copy */ - /* from read buffer */ - - memcpy(buf, conn->readBuffer, bytesToCopy); - conn->readBufferUsed -= bytesToCopy; - - if (conn->readBufferUsed > 0) - /* - * If the caller didn't request all the bytes - * we have in the buffer, then move the unread - * bytes down - */ - memmove(conn->readBuffer, - conn->readBuffer + bytesToCopy, - conn->readBufferUsed); - - num = bytesToCopy; - } - else - { - PSecBuffer pDataBuffer; /* Data buffer */ - PSecBuffer pExtraBuffer; /* Excess data buffer */ - SECURITY_STATUS scRet; /* SSPI status */ - int i; /* Loop control variable */ - - /* - * Initialize security buffer structs - */ - message.ulVersion = SECBUFFER_VERSION; - message.cBuffers = 4; - message.pBuffers = buffers; - - do - { - /* - * If there is not enough space in the - * buffer, then increase it's size - */ - if (conn->decryptBufferLength <= conn->decryptBufferUsed) - { - conn->decryptBufferLength += 4096; - conn->decryptBuffer = (BYTE*) realloc(conn->decryptBuffer, - conn->decryptBufferLength); - - if (!conn->decryptBuffer) - { - DEBUG_printf(("_sspiRead: unable to allocate %d byte buffer", - conn->decryptBufferLength)); - WSASetLastError(E_OUTOFMEMORY); - num = SOCKET_ERROR; - goto cleanup; - } - } - - buffers[0].pvBuffer = conn->decryptBuffer; - buffers[0].cbBuffer = (unsigned long) conn->decryptBufferUsed; - buffers[0].BufferType = SECBUFFER_DATA; - buffers[1].BufferType = SECBUFFER_EMPTY; - buffers[2].BufferType = SECBUFFER_EMPTY; - buffers[3].BufferType = SECBUFFER_EMPTY; - - scRet = DecryptMessage(&conn->context, &message, 0, NULL); - - if (scRet == SEC_E_INCOMPLETE_MESSAGE) - { - if (buf) - { - num = recv(conn->sock, - conn->decryptBuffer + conn->decryptBufferUsed, - (int)(conn->decryptBufferLength - conn->decryptBufferUsed), - 0); - if (num == SOCKET_ERROR) - { - DEBUG_printf(("_sspiRead: recv failed: %d", WSAGetLastError())); - goto cleanup; - } - else if (num == 0) - { - DEBUG_printf(("_sspiRead: server disconnected")); - goto cleanup; - } - - conn->decryptBufferUsed += num; - } - else - { - num = (int) conn->readBufferUsed; - goto cleanup; - } - } - } - while (scRet == SEC_E_INCOMPLETE_MESSAGE); - - if (scRet == SEC_I_CONTEXT_EXPIRED) - { - DEBUG_printf(("_sspiRead: context expired")); - WSASetLastError(WSAECONNRESET); - num = SOCKET_ERROR; - goto cleanup; - } - else if (scRet != SEC_E_OK) - { - DEBUG_printf(("_sspiRead: DecryptMessage failed: %lx", scRet)); - WSASetLastError(WSASYSCALLFAILURE); - num = SOCKET_ERROR; - goto cleanup; - } - - /* - * The decryption worked. Now, locate data buffer. - */ - pDataBuffer = NULL; - pExtraBuffer = NULL; - for (i = 1; i < 4; i++) - { - if (buffers[i].BufferType == SECBUFFER_DATA) - pDataBuffer = &buffers[i]; - else if (!pExtraBuffer && (buffers[i].BufferType == SECBUFFER_EXTRA)) - pExtraBuffer = &buffers[i]; - } - - /* - * If a data buffer is found, then copy - * the decrypted bytes to the passed-in - * buffer - */ - if (pDataBuffer) - { - int bytesToCopy = min(pDataBuffer->cbBuffer, (int) len); - /* Number of bytes to copy into buf */ - int bytesToSave = pDataBuffer->cbBuffer - bytesToCopy; - /* Number of bytes to save in our read buffer */ - - if (bytesToCopy) - memcpy(buf, pDataBuffer->pvBuffer, bytesToCopy); - - /* - * If there are more decrypted bytes than can be - * copied to the passed in buffer, then save them - */ - if (bytesToSave) - { - if ((int)(conn->readBufferLength - conn->readBufferUsed) < bytesToSave) - { - conn->readBufferLength = conn->readBufferUsed + bytesToSave; - conn->readBuffer = realloc(conn->readBuffer, - conn->readBufferLength); - - if (!conn->readBuffer) - { - DEBUG_printf(("_sspiRead: unable to allocate %d bytes", conn->readBufferLength)); - WSASetLastError(E_OUTOFMEMORY); - num = SOCKET_ERROR; - goto cleanup; - } - } - - memcpy(((BYTE*) conn->readBuffer) + conn->readBufferUsed, - ((BYTE*) pDataBuffer->pvBuffer) + bytesToCopy, - bytesToSave); - - conn->readBufferUsed += bytesToSave; - } - - num = (buf) ? bytesToCopy : (int) conn->readBufferUsed; - } - else - { - DEBUG_printf(("_sspiRead: unable to find data buffer")); - WSASetLastError(WSASYSCALLFAILURE); - num = SOCKET_ERROR; - goto cleanup; - } - - /* - * If the decryption process left extra bytes, - * then save those back in decryptBuffer. They will - * be processed the next time through the loop. - */ - if (pExtraBuffer) - { - memmove(conn->decryptBuffer, pExtraBuffer->pvBuffer, pExtraBuffer->cbBuffer); - conn->decryptBufferUsed = pExtraBuffer->cbBuffer; - } - else - { - conn->decryptBufferUsed = 0; - } - } - -cleanup: - - return (num); -} - - -/* - * '_sspiPending()' - Returns the number of available bytes - */ -int /* O - Number of available bytes */ -_sspiPending(_sspi_struct_t *conn) /* I - Client connection */ -{ - return (_sspiRead(conn, NULL, 0)); -} - - -/* - * '_sspiFree()' - Close a connection and free resources - */ -void -_sspiFree(_sspi_struct_t *conn) /* I - Client connection */ -{ - if (!conn) - return; - - if (conn->contextInitialized) - { - SecBufferDesc message; /* Array of SecBuffer struct */ - SecBuffer buffers[1] = { 0 }; - /* Security package buffer */ - DWORD dwType; /* Type */ - DWORD status; /* Status */ - - /* - * Notify schannel that we are about to close the connection. - */ - dwType = SCHANNEL_SHUTDOWN; - - buffers[0].pvBuffer = &dwType; - buffers[0].BufferType = SECBUFFER_TOKEN; - buffers[0].cbBuffer = sizeof(dwType); - - message.cBuffers = 1; - message.pBuffers = buffers; - message.ulVersion = SECBUFFER_VERSION; - - status = ApplyControlToken(&conn->context, &message); - - if (SUCCEEDED(status)) - { - PBYTE pbMessage; /* Message buffer */ - DWORD cbMessage; /* Message buffer count */ - DWORD cbData; /* Data count */ - DWORD dwSSPIFlags; /* SSL attributes we requested */ - DWORD dwSSPIOutFlags; /* SSL attributes we received */ - TimeStamp tsExpiry; /* Time stamp */ - - dwSSPIFlags = ASC_REQ_SEQUENCE_DETECT | - ASC_REQ_REPLAY_DETECT | - ASC_REQ_CONFIDENTIALITY | - ASC_REQ_EXTENDED_ERROR | - ASC_REQ_ALLOCATE_MEMORY | - ASC_REQ_STREAM; - - buffers[0].pvBuffer = NULL; - buffers[0].BufferType = SECBUFFER_TOKEN; - buffers[0].cbBuffer = 0; - - message.cBuffers = 1; - message.pBuffers = buffers; - message.ulVersion = SECBUFFER_VERSION; - - status = AcceptSecurityContext(&conn->creds, &conn->context, NULL, - dwSSPIFlags, SECURITY_NATIVE_DREP, NULL, - &message, &dwSSPIOutFlags, &tsExpiry); - - if (SUCCEEDED(status)) - { - pbMessage = buffers[0].pvBuffer; - cbMessage = buffers[0].cbBuffer; - - /* - * Send the close notify message to the client. - */ - if (pbMessage && cbMessage) - { - cbData = send(conn->sock, pbMessage, cbMessage, 0); - if ((cbData == SOCKET_ERROR) || (cbData == 0)) - { - status = WSAGetLastError(); - DEBUG_printf(("_sspiFree: sending close notify failed: %d", status)); - } - else - { - FreeContextBuffer(pbMessage); - } - } - } - else - { - DEBUG_printf(("_sspiFree: AcceptSecurityContext failed: %x", status)); - } - } - else - { - DEBUG_printf(("_sspiFree: ApplyControlToken failed: %x", status)); - } - - DeleteSecurityContext(&conn->context); - conn->contextInitialized = FALSE; - } - - if (conn->decryptBuffer) - { - free(conn->decryptBuffer); - conn->decryptBuffer = NULL; - } - - if (conn->readBuffer) - { - free(conn->readBuffer); - conn->readBuffer = NULL; - } - - if (conn->sock != INVALID_SOCKET) - { - closesocket(conn->sock); - conn->sock = INVALID_SOCKET; - } - - free(conn); -} - - -/* - * 'sspi_verify_certificate()' - Verify a server certificate - */ -static DWORD /* 0 - Error code (0 == No error) */ -sspi_verify_certificate(PCCERT_CONTEXT serverCert, - /* I - Server certificate */ - const CHAR *serverName, - /* I - Server name */ - DWORD dwCertFlags) - /* I - Verification flags */ -{ - HTTPSPolicyCallbackData httpsPolicy; - /* HTTPS Policy Struct */ - CERT_CHAIN_POLICY_PARA policyPara; - /* Cert chain policy parameters */ - CERT_CHAIN_POLICY_STATUS policyStatus; - /* Cert chain policy status */ - CERT_CHAIN_PARA chainPara; - /* Used for searching and matching criteria */ - PCCERT_CHAIN_CONTEXT chainContext = NULL; - /* Certificate chain */ - PWSTR serverNameUnicode = NULL; - /* Unicode server name */ - LPSTR rgszUsages[] = { szOID_PKIX_KP_SERVER_AUTH, - szOID_SERVER_GATED_CRYPTO, - szOID_SGC_NETSCAPE }; - /* How are we using this certificate? */ - DWORD cUsages = sizeof(rgszUsages) / sizeof(LPSTR); - /* Number of ites in rgszUsages */ - DWORD count; /* 32 bit count variable */ - DWORD status; /* Return value */ - - if (!serverCert) - { - status = SEC_E_WRONG_PRINCIPAL; - goto cleanup; - } - - /* - * Convert server name to unicode. - */ - if (!serverName || (strlen(serverName) == 0)) - { - status = SEC_E_WRONG_PRINCIPAL; - goto cleanup; - } - - count = MultiByteToWideChar(CP_ACP, 0, serverName, -1, NULL, 0); - serverNameUnicode = LocalAlloc(LMEM_FIXED, count * sizeof(WCHAR)); - if (!serverNameUnicode) - { - status = SEC_E_INSUFFICIENT_MEMORY; - goto cleanup; - } - count = MultiByteToWideChar(CP_ACP, 0, serverName, -1, serverNameUnicode, count); - if (count == 0) - { - status = SEC_E_WRONG_PRINCIPAL; - goto cleanup; - } - - /* - * Build certificate chain. - */ - ZeroMemory(&chainPara, sizeof(chainPara)); - chainPara.cbSize = sizeof(chainPara); - chainPara.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR; - chainPara.RequestedUsage.Usage.cUsageIdentifier = cUsages; - chainPara.RequestedUsage.Usage.rgpszUsageIdentifier = rgszUsages; - - if (!CertGetCertificateChain(NULL, serverCert, NULL, serverCert->hCertStore, - &chainPara, 0, NULL, &chainContext)) - { - status = GetLastError(); - DEBUG_printf(("CertGetCertificateChain returned 0x%x\n", status)); - goto cleanup; - } - - /* - * Validate certificate chain. - */ - ZeroMemory(&httpsPolicy, sizeof(HTTPSPolicyCallbackData)); - httpsPolicy.cbStruct = sizeof(HTTPSPolicyCallbackData); - httpsPolicy.dwAuthType = AUTHTYPE_SERVER; - httpsPolicy.fdwChecks = dwCertFlags; - httpsPolicy.pwszServerName = serverNameUnicode; - - memset(&policyPara, 0, sizeof(policyPara)); - policyPara.cbSize = sizeof(policyPara); - policyPara.pvExtraPolicyPara = &httpsPolicy; - - memset(&policyStatus, 0, sizeof(policyStatus)); - policyStatus.cbSize = sizeof(policyStatus); - - if (!CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_SSL, chainContext, - &policyPara, &policyStatus)) - { - status = GetLastError(); - DEBUG_printf(("CertVerifyCertificateChainPolicy returned %d", status)); - goto cleanup; - } - - if (policyStatus.dwError) - { - status = policyStatus.dwError; - goto cleanup; - } - - status = SEC_E_OK; - -cleanup: - - if (chainContext) - CertFreeCertificateChain(chainContext); - - if (serverNameUnicode) - LocalFree(serverNameUnicode); - - return (status); -} - - -/* - * End of "$Id: sspi.c 3247 2011-05-12 06:22:31Z msweet $". - */ diff --git a/cups/string-private.h b/cups/string-private.h index e8448d1..e1ae603 100644 --- a/cups/string-private.h +++ b/cups/string-private.h @@ -1,16 +1,11 @@ /* * Private string definitions for CUPS. * - * Copyright 2007-2015 by Apple Inc. - * Copyright 1997-2006 by Easy Software Products. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ #ifndef _CUPS_STRING_PRIVATE_H_ @@ -20,6 +15,7 @@ * Include necessary headers... */ +# include "config.h" # include # include # include @@ -28,7 +24,7 @@ # include # include -# include "config.h" +# include # ifdef HAVE_STRING_H # include @@ -42,12 +38,12 @@ # include # endif /* HAVE_BSTRING_H */ -# if defined(WIN32) && !defined(__CUPS_SSIZE_T_DEFINED) +# if defined(_WIN32) && !defined(__CUPS_SSIZE_T_DEFINED) # define __CUPS_SSIZE_T_DEFINED # include /* Windows does not support the ssize_t type, so map it to long... */ typedef long ssize_t; /* @private@ */ -# endif /* WIN32 && !__CUPS_SSIZE_T_DEFINED */ +# endif /* _WIN32 && !__CUPS_SSIZE_T_DEFINED */ /* @@ -152,36 +148,35 @@ extern int _cups_toupper(int ch); * Prototypes... */ -extern ssize_t _cups_safe_vsnprintf(char *, size_t, const char *, va_list); -extern void _cups_strcpy(char *dst, const char *src); +extern ssize_t _cups_safe_vsnprintf(char *buffer, size_t bufsize, const char *format, va_list args) _CUPS_PRIVATE; +extern void _cups_strcpy(char *dst, const char *src) _CUPS_PRIVATE; # ifndef HAVE_STRDUP -extern char *_cups_strdup(const char *); +extern char *_cups_strdup(const char *) _CUPS_PRIVATE; # define strdup _cups_strdup # endif /* !HAVE_STRDUP */ -extern int _cups_strcasecmp(const char *, const char *); +extern int _cups_strcasecmp(const char *, const char *) _CUPS_PRIVATE; -extern int _cups_strncasecmp(const char *, const char *, size_t n); +extern int _cups_strncasecmp(const char *, const char *, size_t n) _CUPS_PRIVATE; # ifndef HAVE_STRLCAT -extern size_t _cups_strlcat(char *, const char *, size_t); +extern size_t _cups_strlcat(char *, const char *, size_t) _CUPS_PRIVATE; # define strlcat _cups_strlcat # endif /* !HAVE_STRLCAT */ # ifndef HAVE_STRLCPY -extern size_t _cups_strlcpy(char *, const char *, size_t); +extern size_t _cups_strlcpy(char *, const char *, size_t) _CUPS_PRIVATE; # define strlcpy _cups_strlcpy # endif /* !HAVE_STRLCPY */ # ifndef HAVE_SNPRINTF -extern int _cups_snprintf(char *, size_t, const char *, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); +extern int _cups_snprintf(char *, size_t, const char *, ...) _CUPS_FORMAT(3, 4) _CUPS_PRIVATE; # define snprintf _cups_snprintf # endif /* !HAVE_SNPRINTF */ # ifndef HAVE_VSNPRINTF -extern int _cups_vsnprintf(char *, size_t, const char *, va_list); +extern int _cups_vsnprintf(char *, size_t, const char *, va_list) _CUPS_PRIVATE; # define vsnprintf _cups_vsnprintf # endif /* !HAVE_VSNPRINTF */ @@ -189,11 +184,11 @@ extern int _cups_vsnprintf(char *, size_t, const char *, va_list); * String pool functions... */ -extern char *_cupsStrAlloc(const char *s); -extern void _cupsStrFlush(void); -extern void _cupsStrFree(const char *s); -extern char *_cupsStrRetain(const char *s); -extern size_t _cupsStrStatistics(size_t *alloc_bytes, size_t *total_bytes); +extern char *_cupsStrAlloc(const char *s) _CUPS_PRIVATE; +extern void _cupsStrFlush(void) _CUPS_PRIVATE; +extern void _cupsStrFree(const char *s) _CUPS_PRIVATE; +extern char *_cupsStrRetain(const char *s) _CUPS_PRIVATE; +extern size_t _cupsStrStatistics(size_t *alloc_bytes, size_t *total_bytes) _CUPS_PRIVATE; /* @@ -201,16 +196,16 @@ extern size_t _cupsStrStatistics(size_t *alloc_bytes, size_t *total_bytes); */ extern char *_cupsStrFormatd(char *buf, char *bufend, double number, - struct lconv *loc); + struct lconv *loc) _CUPS_PRIVATE; extern double _cupsStrScand(const char *buf, char **bufptr, - struct lconv *loc); + struct lconv *loc) _CUPS_PRIVATE; /* * Date function... */ -extern char *_cupsStrDate(char *buf, size_t bufsize, time_t timeval); +extern char *_cupsStrDate(char *buf, size_t bufsize, time_t timeval) _CUPS_PRIVATE; /* diff --git a/cups/string.c b/cups/string.c index 0d4ed0f..54f7bd0 100644 --- a/cups/string.c +++ b/cups/string.c @@ -1,16 +1,11 @@ /* * String functions for CUPS. * - * Copyright 2007-2014 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -19,6 +14,7 @@ #define _CUPS_STRING_C_ #include "cups-private.h" +#include "debug-internal.h" #include #include @@ -316,15 +312,6 @@ _cupsStrFree(const char *s) /* I - String to free */ key = (_cups_sp_item_t *)(s - offsetof(_cups_sp_item_t, str)); -#ifdef DEBUG_GUARDS - if (key->guard != _CUPS_STR_GUARD) - { - DEBUG_printf(("5_cupsStrFree: Freeing string %p(%s), guard=%08x, " - "ref_count=%d", key, key->str, key->guard, key->ref_count)); - abort(); - } -#endif /* DEBUG_GUARDS */ - if ((item = (_cups_sp_item_t *)cupsArrayFind(stringpool, key)) != NULL && item == key) { @@ -332,6 +319,14 @@ _cupsStrFree(const char *s) /* I - String to free */ * Found it, dereference... */ +#ifdef DEBUG_GUARDS + if (key->guard != _CUPS_STR_GUARD) + { + DEBUG_printf(("5_cupsStrFree: Freeing string %p(%s), guard=%08x, ref_count=%d", key, key->str, key->guard, key->ref_count)); + abort(); + } +#endif /* DEBUG_GUARDS */ + item->ref_count --; if (!item->ref_count) diff --git a/cups/tempfile.c b/cups/tempfile.c index da705a9..fb39802 100644 --- a/cups/tempfile.c +++ b/cups/tempfile.c @@ -1,16 +1,11 @@ /* * Temp file utilities for CUPS. * - * Copyright 2007-2014 by Apple Inc. - * Copyright 1997-2006 by Easy Software Products. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -18,14 +13,15 @@ */ #include "cups-private.h" +#include "debug-internal.h" #include #include #include -#if defined(WIN32) || defined(__EMX__) +#if defined(_WIN32) || defined(__EMX__) # include #else # include -#endif /* WIN32 || __EMX__ */ +#endif /* _WIN32 || __EMX__ */ /* @@ -42,24 +38,46 @@ cupsTempFd(char *filename, /* I - Pointer to buffer */ int fd; /* File descriptor for temp file */ int tries; /* Number of tries */ const char *tmpdir; /* TMPDIR environment var */ -#ifdef WIN32 - char tmppath[1024]; /* Windows temporary directory */ +#if defined(__APPLE__) || defined(_WIN32) + char tmppath[1024]; /* Temporary directory */ +#endif /* __APPLE__ || _WIN32 */ +#ifdef _WIN32 DWORD curtime; /* Current time */ #else struct timeval curtime; /* Current time */ -#endif /* WIN32 */ +#endif /* _WIN32 */ /* * See if TMPDIR is defined... */ -#ifdef WIN32 +#ifdef _WIN32 if ((tmpdir = getenv("TEMP")) == NULL) { - GetTempPath(sizeof(tmppath), tmppath); + GetTempPathA(sizeof(tmppath), tmppath); tmpdir = tmppath; } + +#elif defined(__APPLE__) + /* + * On macOS and iOS, the TMPDIR environment variable is not always the best + * location to place temporary files due to sandboxing. Instead, the confstr + * function should be called to get the proper per-user, per-process TMPDIR + * value. + */ + + if ((tmpdir = getenv("TMPDIR")) != NULL && access(tmpdir, W_OK)) + tmpdir = NULL; + + if (!tmpdir) + { + if (confstr(_CS_DARWIN_USER_TEMP_DIR, tmppath, sizeof(tmppath))) + tmpdir = tmppath; + else + tmpdir = "/private/tmp"; /* This should never happen */ + } + #else /* * Previously we put root temporary files in the default CUPS temporary @@ -69,12 +87,8 @@ cupsTempFd(char *filename, /* I - Pointer to buffer */ */ if ((tmpdir = getenv("TMPDIR")) == NULL) -# if defined(__APPLE__) && !TARGET_OS_IOS - tmpdir = "/private/tmp"; /* /tmp is a symlink to /private/tmp */ -# else tmpdir = "/tmp"; -# endif /* __APPLE__ && !TARGET_OS_IOS */ -#endif /* WIN32 */ +#endif /* _WIN32 */ /* * Make the temporary name using the specified directory... @@ -84,7 +98,7 @@ cupsTempFd(char *filename, /* I - Pointer to buffer */ do { -#ifdef WIN32 +#ifdef _WIN32 /* * Get the current time of day... */ @@ -108,21 +122,21 @@ cupsTempFd(char *filename, /* I - Pointer to buffer */ */ snprintf(filename, (size_t)len - 1, "%s/%05x%08x", tmpdir, (unsigned)getpid(), (unsigned)(curtime.tv_sec + curtime.tv_usec + tries)); -#endif /* WIN32 */ +#endif /* _WIN32 */ /* * Open the file in "exclusive" mode, making sure that we don't * stomp on an existing file or someone's symlink crack... */ -#ifdef WIN32 +#ifdef _WIN32 fd = open(filename, _O_CREAT | _O_RDWR | _O_TRUNC | _O_BINARY, _S_IREAD | _S_IWRITE); #elif defined(O_NOFOLLOW) fd = open(filename, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600); #else fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600); -#endif /* WIN32 */ +#endif /* _WIN32 */ if (fd < 0 && errno != EEXIST) break; diff --git a/cups/test.ppd b/cups/test.ppd index 1f64fe5..00bbe9b 100644 --- a/cups/test.ppd +++ b/cups/test.ppd @@ -1,7 +1,5 @@ *PPD-Adobe: "4.3" *% -*% "$Id: test.ppd 7819 2008-08-01 00:27:24Z mike $" -*% *% Test PPD file for CUPS. *% *% This file is used to test the CUPS PPD API functions and cannot be @@ -12,22 +10,19 @@ *% to create your PPD files - not only will it save you time, it produces *% consistently high-quality files. *% -*% Copyright 2007-2010 by Apple Inc. -*% Copyright 2002-2006 by Easy Software Products. +*% Copyright (c) 2007-2018 by Apple Inc. +*% Copyright (c) 2002-2006 by Easy Software Products. *% -*% These coded instructions, statements, and computer programs are the -*% property of Apple Inc. and are protected by Federal copyright -*% law. Distribution and use rights are outlined in the file "LICENSE.txt" -*% which should have been included with this file. If this file is -*% file is missing or damaged, see the license at "http://www.cups.org/". +*% Licensed under Apache License v2.0. See the file "LICENSE" for more +*% information. *FormatVersion: "4.3" -*FileVersion: "1.3" +*FileVersion: "2.3" *LanguageVersion: English *LanguageEncoding: ISOLatin1 *PCFileName: "TEST.PPD" -*Manufacturer: "ESP" +*Manufacturer: "Apple" *Product: "(Test)" -*cupsVersion: 1.4 +*cupsVersion: 2.3 *ModelName: "Test" *ShortNickName: "Test" *NickName: "Test for CUPS" @@ -266,6 +261,3 @@ help:anchor='foo'%20bookID=Vendor%20Help *Font Times-Roman: Standard "(001.007S)" Standard ROM *Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM *Font ZapfDingbats: Special "(001.004S)" Standard ROM -*% -*% End of "$Id: test.ppd 7819 2008-08-01 00:27:24Z mike $". -*% diff --git a/cups/test2.ppd b/cups/test2.ppd index 353afb6..4f8d4ea 100644 --- a/cups/test2.ppd +++ b/cups/test2.ppd @@ -1,7 +1,5 @@ *PPD-Adobe: "4.3" *% -*% "$Id: test2.ppd 7791 2008-07-24 00:55:30Z mike $" -*% *% Test PPD file #2 for CUPS. *% *% This file is used to test the CUPS PPD API functions and cannot be @@ -12,22 +10,19 @@ *% to create your PPD files - not only will it save you time, it produces *% consistently high-quality files. *% -*% Copyright 2007-2011 by Apple Inc. -*% Copyright 2002-2006 by Easy Software Products. +*% Copyright (c) 2007-2018 by Apple Inc. +*% Copyright (c) 2002-2006 by Easy Software Products. *% -*% These coded instructions, statements, and computer programs are the -*% property of Apple Inc. and are protected by Federal copyright -*% law. Distribution and use rights are outlined in the file "LICENSE.txt" -*% which should have been included with this file. If this file is -*% file is missing or damaged, see the license at "http://www.cups.org/". +*% Licensed under Apache License v2.0. See the file "LICENSE" for more +*% information. *FormatVersion: "4.3" -*FileVersion: "1.3" +*FileVersion: "2.3" *LanguageVersion: English *LanguageEncoding: ISOLatin1 *PCFileName: "TEST.PPD" -*Manufacturer: "ESP" +*Manufacturer: "Apple" *Product: "(Test2)" -*cupsVersion: 1.4 +*cupsVersion: 2.3 *ModelName: "Test2" *ShortNickName: "Test2" *NickName: "Test2 for CUPS" @@ -247,6 +242,3 @@ help:anchor='foo'%20bookID=Vendor%20Help *Font Times-Roman: Standard "(001.007S)" Standard ROM *Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM *Font ZapfDingbats: Special "(001.004S)" Standard ROM -*% -*% End of "$Id: test2.ppd 7791 2008-07-24 00:55:30Z mike $". -*% diff --git a/cups/testadmin.c b/cups/testadmin.c index 69b5efb..58424ea 100644 --- a/cups/testadmin.c +++ b/cups/testadmin.c @@ -4,13 +4,7 @@ * Copyright 2007-2013 by Apple Inc. * Copyright 2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* diff --git a/cups/testarray.c b/cups/testarray.c index 6164ffc..185fcbe 100644 --- a/cups/testarray.c +++ b/cups/testarray.c @@ -4,13 +4,7 @@ * Copyright 2007-2014 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -234,8 +228,7 @@ main(void) puts("PASS"); else { - printf("FAIL (returned %p with %d elements, expected pointer with 4 elements)\n", - dup_array, cupsArrayCount(dup_array)); + printf("FAIL (returned %p with %d elements, expected pointer with 4 elements)\n", (void *)dup_array, cupsArrayCount(dup_array)); status ++; } @@ -494,7 +487,7 @@ main(void) * 'get_seconds()' - Get the current time in seconds... */ -#ifdef WIN32 +#ifdef _WIN32 # include @@ -515,7 +508,7 @@ get_seconds(void) gettimeofday(&curtime, NULL); return (curtime.tv_sec + 0.000001 * curtime.tv_usec); } -#endif /* WIN32 */ +#endif /* _WIN32 */ /* diff --git a/cups/testcache.c b/cups/testcache.c index e7816a3..44f7508 100644 --- a/cups/testcache.c +++ b/cups/testcache.c @@ -1,15 +1,9 @@ /* * PPD cache testing program for CUPS. * - * Copyright 2009-2014 by Apple Inc. + * Copyright 2009-2018 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -70,7 +64,7 @@ main(int argc, /* I - Number of command-line args */ ppdMarkDefaults(ppd); cupsMarkOptions(ppd, num_options, options); - num_finishings = _ppdCacheGetFinishingValues(pc, num_options, options, (int)sizeof(finishings) / sizeof(finishings[0]), finishings); + num_finishings = _ppdCacheGetFinishingValues(ppd, pc, (int)sizeof(finishings) / sizeof(finishings[0]), finishings); if (num_finishings > 0) { diff --git a/cups/testclient.c b/cups/testclient.c new file mode 100644 index 0000000..cf945df --- /dev/null +++ b/cups/testclient.c @@ -0,0 +1,1058 @@ +/* + * Simulated client test program for CUPS. + * + * Copyright © 2017-2019 by Apple Inc. + * + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include +#include + + +/* + * Constants... + */ + +#define MAX_CLIENTS 16 /* Maximum number of client threads */ + + +/* + * Local types... + */ + +typedef struct _client_data_s +{ + const char *uri, /* Printer URI */ + *hostname, /* Hostname */ + *user, /* Username */ + *resource; /* Resource path */ + int port; /* Port number */ + http_encryption_t encryption; /* Use encryption? */ + const char *docfile, /* Document file */ + *docformat; /* Document format */ + int grayscale, /* Force grayscale? */ + keepfile; /* Keep temporary file? */ + ipp_pstate_t printer_state; /* Current printer state */ + char printer_state_reasons[1024]; + /* Current printer-state-reasons */ + int job_id; /* Job ID for submitted job */ + ipp_jstate_t job_state; /* Current job state */ + char job_state_reasons[1024]; + /* Current job-state-reasons */ +} _client_data_t; + + +/* + * Local globals... + */ + +static int client_count = 0; +static _cups_mutex_t client_mutex = _CUPS_MUTEX_INITIALIZER; +static int verbosity = 0; + + +/* + * Local functions... + */ + +static const char *make_raster_file(ipp_t *response, int grayscale, char *tempname, size_t tempsize, const char **format); +static void *monitor_printer(_client_data_t *data); +static void *run_client(_client_data_t *data); +static void show_attributes(const char *title, int request, ipp_t *ipp); +static void show_capabilities(ipp_t *response); +static void usage(void); + + +/* + * 'main()' - Main entry. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + const char *opt; /* Current option */ + int num_clients = 0,/* Number of clients to simulate */ + clients_started = 0; + /* Number of clients that have been started */ + char scheme[32], /* URI scheme */ + userpass[256], /* Username:password */ + hostname[256], /* Hostname */ + resource[256]; /* Resource path */ + _client_data_t data; /* Client data */ + + + /* + * Parse command-line options... + */ + + if (argc == 1) + return (0); + + memset(&data, 0, sizeof(data)); + + for (i = 1; i < argc; i ++) + { + if (argv[i][0] == '-') + { + for (opt = argv[i] + 1; *opt; opt ++) + { + switch (*opt) + { + case 'c' : /* -c num-clients */ + if (num_clients) + { + puts("Number of clients can only be specified once."); + usage(); + return (1); + } + + i ++; + if (i >= argc) + { + puts("Expected client count after '-c'."); + usage(); + return (1); + } + + if ((num_clients = atoi(argv[i])) < 1) + { + puts("Number of clients must be one or more."); + usage(); + return (1); + } + break; + + case 'd' : /* -d document-format */ + if (data.docformat) + { + puts("Document format can only be specified once."); + usage(); + return (1); + } + + i ++; + if (i >= argc) + { + puts("Expected document format after '-d'."); + usage(); + return (1); + } + + data.docformat = argv[i]; + break; + + case 'f' : /* -f print-file */ + if (data.docfile) + { + puts("Print file can only be specified once."); + usage(); + return (1); + } + + i ++; + if (i >= argc) + { + puts("Expected print file after '-f'."); + usage(); + return (1); + } + + data.docfile = argv[i]; + break; + + case 'g' : + data.grayscale = 1; + break; + + case 'k' : + data.keepfile = 1; + break; + + case 'v' : + verbosity ++; + break; + + default : + printf("Unknown option '-%c'.\n", *opt); + usage(); + return (1); + } + } + } + else if (data.uri || (strncmp(argv[i], "ipp://", 6) && strncmp(argv[i], "ipps://", 7))) + { + printf("Unknown command-line argument '%s'.\n", argv[i]); + usage(); + return (1); + } + else + data.uri = argv[i]; + } + + /* + * Make sure we have everything we need. + */ + + if (!data.uri) + { + puts("Expected printer URI."); + usage(); + return (1); + } + + if (num_clients < 1) + num_clients = 1; + + /* + * Connect to the printer... + */ + + if (httpSeparateURI(HTTP_URI_CODING_ALL, data.uri, scheme, sizeof(scheme), userpass, sizeof(userpass), hostname, sizeof(hostname), &data.port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK) + { + printf("Bad printer URI '%s'.\n", data.uri); + return (1); + } + + if (!data.port) + data.port = IPP_PORT; + + if (!strcmp(scheme, "https") || !strcmp(scheme, "ipps")) + data.encryption = HTTP_ENCRYPTION_ALWAYS; + else + data.encryption = HTTP_ENCRYPTION_IF_REQUESTED; + + /* + * Start the client threads... + */ + + data.hostname = hostname; + data.resource = resource; + + while (clients_started < num_clients) + { + _cupsMutexLock(&client_mutex); + if (client_count < MAX_CLIENTS) + { + _cups_thread_t tid; /* New thread */ + + client_count ++; + _cupsMutexUnlock(&client_mutex); + tid = _cupsThreadCreate((_cups_thread_func_t)run_client, &data); + _cupsThreadDetach(tid); + } + else + { + _cupsMutexUnlock(&client_mutex); + sleep(1); + } + } + + while (client_count > 0) + { + _cupsMutexLock(&client_mutex); + printf("%d RUNNING CLIENTS\n", client_count); + _cupsMutexUnlock(&client_mutex); + sleep(1); + } + + return (0); +} + + +/* + * 'make_raster_file()' - Create a temporary raster file. + */ + +static const char * /* O - Print filename */ +make_raster_file(ipp_t *response, /* I - Printer attributes */ + int grayscale, /* I - Force grayscale? */ + char *tempname, /* I - Temporary filename buffer */ + size_t tempsize, /* I - Size of temp file buffer */ + const char **format) /* O - Print format */ +{ + int i, /* Looping var */ + count; /* Number of values */ + ipp_attribute_t *attr; /* Printer attribute */ + const char *type = NULL; /* Raster type (colorspace + bits) */ + pwg_media_t *media = NULL; /* Media size */ + int xdpi = 0, /* Horizontal resolution */ + ydpi = 0; /* Vertical resolution */ + int fd; /* Temporary file */ + cups_mode_t mode; /* Raster mode */ + cups_raster_t *ras; /* Raster stream */ + cups_page_header2_t header; /* Page header */ + unsigned char *line, /* Line of raster data */ + *lineptr; /* Pointer into line */ + unsigned y, /* Current position on page */ + xcount, ycount, /* Current count for X and Y */ + xrep, yrep, /* Repeat count for X and Y */ + xoff, yoff, /* Offsets for X and Y */ + yend; /* End Y value */ + int temprow, /* Row in template */ + tempcolor; /* Template color */ + const char *template; /* Pointer into template */ + const unsigned char *color; /* Current color */ + static const unsigned char colors[][3] = + { /* Colors for test */ + { 191, 191, 191 }, + { 127, 127, 127 }, + { 63, 63, 63 }, + { 0, 0, 0 }, + { 255, 0, 0 }, + { 255, 127, 0 }, + { 255, 255, 0 }, + { 127, 255, 0 }, + { 0, 255, 0 }, + { 0, 255, 127 }, + { 0, 255, 255 }, + { 0, 127, 255 }, + { 0, 0, 255 }, + { 127, 0, 255 }, + { 255, 0, 255 } + }; + static const char * const templates[] = + { /* Raster template */ + " CCC U U PPPP SSS TTTTT EEEEE SSS TTTTT 000 1 222 333 4 55555 66 77777 888 999 ", + "C C U U P P S S T E S S T 0 0 11 2 2 3 3 4 4 5 6 7 8 8 9 9 ", + "C U U P P S T E S T 0 0 1 2 3 4 4 5 6 7 8 8 9 9 ", + "C U U PPPP SSS ----- T EEEE SSS T 0 0 0 1 22 333 44444 555 6666 7 888 9999 ", + "C U U P S T E S T 0 0 1 2 3 4 5 6 6 7 8 8 9 ", + "C C U U P S S T E S S T 0 0 1 2 3 3 4 5 5 6 6 7 8 8 9 ", + " CCC UUU P SSS T EEEEE SSS T 000 111 22222 333 4 555 666 7 888 99 ", + " " + }; + + + /* + * Figure out the output format... + */ + + if ((attr = ippFindAttribute(response, "document-format-supported", IPP_TAG_MIMETYPE)) == NULL) + { + puts("No supported document formats, aborting."); + return (NULL); + } + + if (*format) + { + if (!ippContainsString(attr, *format)) + { + printf("Printer does not support document-format '%s'.\n", *format); + return (NULL); + } + + if (!strcmp(*format, "image/urf")) + mode = CUPS_RASTER_WRITE_APPLE; + else if (!strcmp(*format, "image/pwg-raster")) + mode = CUPS_RASTER_WRITE_PWG; + else + { + printf("Unable to generate document-format '%s'.\n", *format); + return (NULL); + } + } + else if (ippContainsString(attr, "image/urf")) + { + /* + * Apple Raster format... + */ + + *format = "image/urf"; + mode = CUPS_RASTER_WRITE_APPLE; + } + else if (ippContainsString(attr, "image/pwg-raster")) + { + /* + * PWG Raster format... + */ + + *format = "image/pwg-raster"; + mode = CUPS_RASTER_WRITE_PWG; + } + else + { + /* + * No supported raster format... + */ + + puts("Printer does not support Apple or PWG raster files, aborting."); + return (NULL); + } + + /* + * Figure out the the media, resolution, and color mode... + */ + + if ((attr = ippFindAttribute(response, "media-default", IPP_TAG_KEYWORD)) != NULL) + { + /* + * Use default media... + */ + + media = pwgMediaForPWG(ippGetString(attr, 0, NULL)); + } + else if ((attr = ippFindAttribute(response, "media-ready", IPP_TAG_KEYWORD)) != NULL) + { + /* + * Use ready media... + */ + + if (ippContainsString(attr, "na_letter_8.5x11in")) + media = pwgMediaForPWG("na_letter_8.5x11in"); + else if (ippContainsString(attr, "iso_a4_210x297mm")) + media = pwgMediaForPWG("iso_a4_210x297mm"); + else + media = pwgMediaForPWG(ippGetString(attr, 0, NULL)); + } + else + { + puts("No default or ready media reported by printer, aborting."); + return (NULL); + } + + if (mode == CUPS_RASTER_WRITE_APPLE && (attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL) + { + for (i = 0, count = ippGetCount(attr); i < count; i ++) + { + const char *val = ippGetString(attr, i, NULL); + + if (!strncmp(val, "RS", 2)) + xdpi = ydpi = atoi(val + 2); + else if (!strncmp(val, "W8", 2) && !type) + type = "sgray_8"; + else if (!strncmp(val, "SRGB24", 6) && !grayscale) + type = "srgb_8"; + } + } + else if (mode == CUPS_RASTER_WRITE_PWG && (attr = ippFindAttribute(response, "pwg-raster-document-resolution-supported", IPP_TAG_RESOLUTION)) != NULL) + { + for (i = 0, count = ippGetCount(attr); i < count; i ++) + { + int tempxdpi, tempydpi; + ipp_res_t tempunits; + + tempxdpi = ippGetResolution(attr, 0, &tempydpi, &tempunits); + + if (i == 0 || tempxdpi < xdpi || tempydpi < ydpi) + { + xdpi = tempxdpi; + ydpi = tempydpi; + } + } + + if ((attr = ippFindAttribute(response, "pwg-raster-document-type-supported", IPP_TAG_KEYWORD)) != NULL) + { + if (!grayscale && ippContainsString(attr, "srgb_8")) + type = "srgb_8"; + else if (ippContainsString(attr, "sgray_8")) + type = "sgray_8"; + } + } + + if (xdpi < 72 || ydpi < 72) + { + puts("No supported raster resolutions, aborting."); + return (NULL); + } + + if (!type) + { + puts("No supported color spaces or bit depths, aborting."); + return (NULL); + } + + /* + * Make the raster context and details... + */ + + if (!cupsRasterInitPWGHeader(&header, media, type, xdpi, ydpi, "one-sided", NULL)) + { + printf("Unable to initialize raster context: %s\n", cupsRasterErrorString()); + return (NULL); + } + + header.cupsInteger[CUPS_RASTER_PWG_TotalPageCount] = 1; + + if (header.cupsWidth > (4 * header.HWResolution[0])) + { + xoff = header.HWResolution[0] / 2; + yoff = header.HWResolution[1] / 2; + } + else + { + xoff = 0; + yoff = 0; + } + + xrep = (header.cupsWidth - 2 * xoff) / 140; + yrep = xrep * header.HWResolution[1] / header.HWResolution[0]; + yend = header.cupsHeight - yoff; + + /* + * Prepare the raster file... + */ + + if ((line = malloc(header.cupsBytesPerLine)) == NULL) + { + printf("Unable to allocate %u bytes for raster output: %s\n", header.cupsBytesPerLine, strerror(errno)); + return (NULL); + } + + if ((fd = cupsTempFd(tempname, (int)tempsize)) < 0) + { + printf("Unable to create temporary print file: %s\n", strerror(errno)); + free(line); + return (NULL); + } + + if ((ras = cupsRasterOpen(fd, mode)) == NULL) + { + printf("Unable to open raster stream: %s\n", cupsRasterErrorString()); + close(fd); + free(line); + return (NULL); + } + + /* + * Write a single page consisting of the template dots repeated over the page. + */ + + cupsRasterWriteHeader2(ras, &header); + + memset(line, 0xff, header.cupsBytesPerLine); + + for (y = 0; y < yoff; y ++) + cupsRasterWritePixels(ras, line, header.cupsBytesPerLine); + + for (temprow = 0, tempcolor = 0; y < yend;) + { + template = templates[temprow]; + color = colors[tempcolor]; + + temprow ++; + if (temprow >= (int)(sizeof(templates) / sizeof(templates[0]))) + { + temprow = 0; + tempcolor ++; + if (tempcolor >= (int)(sizeof(colors) / sizeof(colors[0]))) + tempcolor = 0; + else if (tempcolor > 3 && header.cupsColorSpace == CUPS_CSPACE_SW) + tempcolor = 0; + } + + memset(line, 0xff, header.cupsBytesPerLine); + + if (header.cupsColorSpace == CUPS_CSPACE_SW) + { + /* + * Do grayscale output... + */ + + for (lineptr = line + xoff; *template; template ++) + { + if (*template != ' ') + { + for (xcount = xrep; xcount > 0; xcount --) + *lineptr++ = *color; + } + else + { + lineptr += xrep; + } + } + } + else + { + /* + * Do color output... + */ + + for (lineptr = line + 3 * xoff; *template; template ++) + { + if (*template != ' ') + { + for (xcount = xrep; xcount > 0; xcount --, lineptr += 3) + memcpy(lineptr, color, 3); + } + else + { + lineptr += 3 * xrep; + } + } + } + + for (ycount = yrep; ycount > 0 && y < yend; ycount --, y ++) + cupsRasterWritePixels(ras, line, header.cupsBytesPerLine); + } + + memset(line, 0xff, header.cupsBytesPerLine); + + for (y = 0; y < header.cupsHeight; y ++) + cupsRasterWritePixels(ras, line, header.cupsBytesPerLine); + + cupsRasterClose(ras); + + close(fd); + + printf("PRINT FILE: %s\n", tempname); + + return (tempname); +} + + +/* + * 'monitor_printer()' - Monitor the job and printer states. + */ + +static void * /* O - Thread exit code */ +monitor_printer( + _client_data_t *data) /* I - Client data */ +{ + http_t *http; /* Connection to printer */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + ipp_attribute_t *attr; /* Attribute in response */ + ipp_pstate_t printer_state; /* Printer state */ + char printer_state_reasons[1024]; + /* Printer state reasons */ + ipp_jstate_t job_state; /* Job state */ + char job_state_reasons[1024];/* Printer state reasons */ + static const char * const jattrs[] = /* Job attributes we want */ + { + "job-state", + "job-state-reasons" + }; + static const char * const pattrs[] = /* Printer attributes we want */ + { + "printer-state", + "printer-state-reasons" + }; + + + /* + * Open a connection to the printer... + */ + + http = httpConnect2(data->hostname, data->port, NULL, AF_UNSPEC, data->encryption, 1, 0, NULL); + + /* + * Loop until the job is canceled, aborted, or completed. + */ + + printer_state = (ipp_pstate_t)0; + printer_state_reasons[0] = '\0'; + + job_state = (ipp_jstate_t)0; + job_state_reasons[0] = '\0'; + + while (data->job_state < IPP_JSTATE_CANCELED) + { + /* + * Reconnect to the printer as needed... + */ + + if (httpGetFd(http) < 0) + httpReconnect2(http, 30000, NULL); + + if (httpGetFd(http) >= 0) + { + /* + * Connected, so check on the printer state... + */ + + request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, data->uri); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (int)(sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs); + + response = cupsDoRequest(http, request, data->resource); + + if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL) + printer_state = (ipp_pstate_t)ippGetInteger(attr, 0); + + if ((attr = ippFindAttribute(response, "printer-state-reasons", IPP_TAG_KEYWORD)) != NULL) + ippAttributeString(attr, printer_state_reasons, sizeof(printer_state_reasons)); + + if (printer_state != data->printer_state || strcmp(printer_state_reasons, data->printer_state_reasons)) + { + printf("PRINTER: %s (%s)\n", ippEnumString("printer-state", (int)printer_state), printer_state_reasons); + + data->printer_state = printer_state; + strlcpy(data->printer_state_reasons, printer_state_reasons, sizeof(data->printer_state_reasons)); + } + + ippDelete(response); + + if (data->job_id > 0) + { + /* + * Check the status of the job itself... + */ + + request = ippNewRequest(IPP_OP_GET_JOB_ATTRIBUTES); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, data->uri); + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", data->job_id); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (int)(sizeof(jattrs) / sizeof(jattrs[0])), NULL, jattrs); + + response = cupsDoRequest(http, request, data->resource); + + if ((attr = ippFindAttribute(response, "job-state", IPP_TAG_ENUM)) != NULL) + job_state = (ipp_jstate_t)ippGetInteger(attr, 0); + + if ((attr = ippFindAttribute(response, "job-state-reasons", IPP_TAG_KEYWORD)) != NULL) + ippAttributeString(attr, job_state_reasons, sizeof(job_state_reasons)); + + if (job_state != data->job_state || strcmp(job_state_reasons, data->job_state_reasons)) + { + printf("JOB %d: %s (%s)\n", data->job_id, ippEnumString("job-state", (int)job_state), job_state_reasons); + + data->job_state = job_state; + strlcpy(data->job_state_reasons, job_state_reasons, sizeof(data->job_state_reasons)); + } + + ippDelete(response); + } + } + + if (data->job_state < IPP_JSTATE_CANCELED) + { + /* + * Sleep for 5 seconds... + */ + + sleep(5); + } + } + + /* + * Cleanup and return... + */ + + httpClose(http); + + printf("FINISHED MONITORING JOB %d\n", data->job_id); + + return (NULL); +} + + +/* + * 'run_client()' - Run a client thread. + */ + +static void * /* O - Thread exit code */ +run_client( + _client_data_t *data) /* I - Client data */ +{ + _cups_thread_t monitor_id; /* Monitoring thread ID */ + const char *name; /* Job name */ + char tempfile[1024] = ""; /* Temporary file (if any) */ + _client_data_t ldata; /* Local client data */ + http_t *http; /* Connection to printer */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + ipp_attribute_t *attr; /* Attribute in response */ + static const char * const pattrs[] = /* Printer attributes we are interested in */ + { + "job-template", + "printer-defaults", + "printer-description", + "media-col-database", + "media-col-ready" + }; + + + ldata = *data; + + /* + * Start monitoring the printer in the background... + */ + + monitor_id = _cupsThreadCreate((_cups_thread_func_t)monitor_printer, &ldata); + + /* + * Open a connection to the printer... + */ + + http = httpConnect2(data->hostname, data->port, NULL, AF_UNSPEC, data->encryption, 1, 0, NULL); + + /* + * Query printer status and capabilities... + */ + + request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, ldata.uri); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (int)(sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs); + + response = cupsDoRequest(http, request, ldata.resource); + + if (verbosity) + show_capabilities(response); + + /* + * Now figure out what we will be printing... + */ + + if (ldata.docfile) + { + /* + * User specified a print file, figure out the format... + */ + const char *ext; /* Filename extension */ + + if ((ext = strrchr(ldata.docfile, '.')) != NULL) + { + /* + * Guess the format from the extension... + */ + + if (!strcmp(ext, ".jpg")) + ldata.docformat = "image/jpeg"; + else if (!strcmp(ext, ".pdf")) + ldata.docformat = "application/pdf"; + else if (!strcmp(ext, ".ps")) + ldata.docformat = "application/postscript"; + else if (!strcmp(ext, ".pwg")) + ldata.docformat = "image/pwg-raster"; + else if (!strcmp(ext, ".urf")) + ldata.docformat = "image/urf"; + else + ldata.docformat = "application/octet-stream"; + } + else + { + /* + * Tell the printer to auto-detect... + */ + + ldata.docformat = "application/octet-stream"; + } + } + else + { + /* + * No file specified, make something to test with... + */ + + if ((ldata.docfile = make_raster_file(response, ldata.grayscale, tempfile, sizeof(tempfile), &ldata.docformat)) == NULL) + return ((void *)1); + } + + ippDelete(response); + + /* + * Create a job and wait for completion... + */ + + request = ippNewRequest(IPP_OP_CREATE_JOB); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, ldata.uri); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); + + if ((name = strrchr(ldata.docfile, '/')) != NULL) + name ++; + else + name = ldata.docfile; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, name); + + if (verbosity) + show_attributes("Create-Job request", 1, request); + + response = cupsDoRequest(http, request, ldata.resource); + + if (verbosity) + show_attributes("Create-Job response", 0, response); + + if (cupsLastError() >= IPP_STATUS_REDIRECTION_OTHER_SITE) + { + printf("Unable to create print job: %s\n", cupsLastErrorString()); + + ldata.job_state = IPP_JSTATE_ABORTED; + + goto cleanup; + } + + if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) == NULL) + { + puts("No job-id returned in Create-Job request."); + + ldata.job_state = IPP_JSTATE_ABORTED; + + goto cleanup; + } + + ldata.job_id = ippGetInteger(attr, 0); + + printf("CREATED JOB %d, sending %s of type %s\n", ldata.job_id, ldata.docfile, ldata.docformat); + + ippDelete(response); + + request = ippNewRequest(IPP_OP_SEND_DOCUMENT); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, ldata.uri); + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", ldata.job_id); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", NULL, ldata.docformat); + ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1); + + if (verbosity) + show_attributes("Send-Document request", 1, request); + + response = cupsDoFileRequest(http, request, ldata.resource, ldata.docfile); + + if (verbosity) + show_attributes("Send-Document response", 0, response); + + if (cupsLastError() >= IPP_STATUS_REDIRECTION_OTHER_SITE) + { + printf("Unable to print file: %s\n", cupsLastErrorString()); + + ldata.job_state = IPP_JSTATE_ABORTED; + + goto cleanup; + } + + puts("WAITING FOR JOB TO COMPLETE"); + + while (ldata.job_state < IPP_JSTATE_CANCELED) + sleep(1); + + /* + * Cleanup after ourselves... + */ + + cleanup: + + httpClose(http); + + if (tempfile[0] && !ldata.keepfile) + unlink(tempfile); + + _cupsThreadWait(monitor_id); + + _cupsMutexLock(&client_mutex); + client_count --; + _cupsMutexUnlock(&client_mutex); + + return (NULL); +} + + +/* + * 'show_attributes()' - Show attributes in a request or response. + */ + +static void +show_attributes(const char *title, /* I - Title */ + int request, /* I - 1 for request, 0 for response */ + ipp_t *ipp) /* I - IPP request/response */ +{ + int minor, major = ippGetVersion(ipp, &minor); + /* IPP version number */ + ipp_tag_t group = IPP_TAG_ZERO; + /* Current group tag */ + ipp_attribute_t *attr; /* Current attribute */ + const char *name; /* Attribute name */ + char buffer[1024]; /* Value */ + + + printf("%s:\n", title); + printf(" version=%d.%d\n", major, minor); + printf(" request-id=%d\n", ippGetRequestId(ipp)); + if (!request) + printf(" status-code=%s\n", ippErrorString(ippGetStatusCode(ipp))); + + for (attr = ippFirstAttribute(ipp); attr; attr = ippNextAttribute(ipp)) + { + if (group != ippGetGroupTag(attr)) + { + group = ippGetGroupTag(attr); + if (group) + printf(" %s:\n", ippTagString(group)); + } + + if ((name = ippGetName(attr)) != NULL) + { + ippAttributeString(attr, buffer, sizeof(buffer)); + printf(" %s(%s%s)=%s\n", name, ippGetCount(attr) > 1 ? "1setOf " : "", ippTagString(ippGetValueTag(attr)), buffer); + } + } +} + + +/* + * 'show_capabilities()' - Show printer capabilities. + */ + +static void +show_capabilities(ipp_t *response) /* I - Printer attributes */ +{ + int i; /* Looping var */ + ipp_attribute_t *attr; /* Attribute */ + char buffer[1024]; /* Attribute value buffer */ + static const char * const pattrs[] = /* Attributes we want to show */ + { + "copies-default", + "copies-supported", + "finishings-default", + "finishings-ready", + "finishings-supported", + "media-default", + "media-ready", + "media-supported", + "output-bin-default", + "output-bin-supported", + "print-color-mode-default", + "print-color-mode-supported", + "sides-default", + "sides-supported", + "document-format-default", + "document-format-supported", + "pwg-raster-document-resolution-supported", + "pwg-raster-document-type-supported", + "urf-supported" + }; + + + puts("CAPABILITIES:"); + for (i = 0; i < (int)(sizeof(pattrs) / sizeof(pattrs[0])); i ++) + { + if ((attr = ippFindAttribute(response, pattrs[i], IPP_TAG_ZERO)) != NULL) + { + ippAttributeString(attr, buffer, sizeof(buffer)); + printf(" %s=%s\n", pattrs[i], buffer); + } + } +} + + +/* + * 'usage()' - Show program usage... + */ + +static void +usage(void) +{ + puts("Usage: ./testclient printer-uri [options]"); + puts("Options:"); + puts(" -c num-clients Simulate multiple clients"); + puts(" -d document-format Generate the specified format"); + puts(" -f print-file Print the named file"); + puts(" -g Force grayscale printing"); + puts(" -k Keep temporary files"); + puts(" -v Be more verbose"); +} diff --git a/cups/testconflicts.c b/cups/testconflicts.c index 973c5a0..6ea70fa 100644 --- a/cups/testconflicts.c +++ b/cups/testconflicts.c @@ -3,13 +3,7 @@ * * Copyright 2008-2012 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* diff --git a/cups/testcreds.c b/cups/testcreds.c index bc17a20..02d16a8 100644 --- a/cups/testcreds.c +++ b/cups/testcreds.c @@ -4,13 +4,7 @@ * Copyright 2007-2016 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* diff --git a/cups/testcups.c b/cups/testcups.c index aa58766..53b4ffe 100644 --- a/cups/testcups.c +++ b/cups/testcups.c @@ -1,16 +1,10 @@ /* * CUPS API test program for CUPS. * - * Copyright 2007-2014 by Apple Inc. - * Copyright 2007 by Easy Software Products. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -18,8 +12,7 @@ */ #undef _CUPS_NO_DEPRECATED -#include "string-private.h" -#include "cups.h" +#include "cups-private.h" #include "ppd.h" #include @@ -41,13 +34,17 @@ int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { + http_t *http, /* First HTTP connection */ + *http2; /* Second HTTP connection */ int status = 0, /* Exit status */ i, /* Looping var */ num_dests; /* Number of destinations */ cups_dest_t *dests, /* Destinations */ *dest, /* Current destination */ *named_dest; /* Current named destination */ - const char *ppdfile; /* PPD file */ + const char *dest_name, /* Destination name */ + *dval, /* Destination value */ + *ppdfile; /* PPD file */ ppd_file_t *ppd; /* PPD file data */ int num_jobs; /* Number of jobs for queue */ cups_job_t *jobs; /* Jobs for queue */ @@ -268,6 +265,24 @@ main(int argc, /* I - Number of command-line arguments */ return (0); } + /* + * _cupsConnect() connection reuse... + */ + + fputs("_cupsConnect: ", stdout); + http = _cupsConnect(); + http2 = _cupsConnect(); + + if (http == http2) + { + puts("PASS"); + } + else + { + puts("FAIL (different connections)"); + return (1); + } + /* * cupsGetDests() */ @@ -360,11 +375,19 @@ main(int argc, /* I - Number of command-line arguments */ * cupsGetDest(printer) */ - printf("cupsGetDest(\"%s\"): ", dests[num_dests / 2].name); + for (i = 0, dest_name = NULL; i < num_dests; i ++) + { + if ((dval = cupsGetOption("printer-is-temporary", dests[i].num_options, dest[i].options)) != NULL && !strcmp(dval, "false")) + { + dest_name = dests[i].name; + break; + } + } + + printf("cupsGetDest(\"%s\"): ", dest_name ? dest_name : "(null)"); fflush(stdout); - if ((dest = cupsGetDest(dests[num_dests / 2].name, NULL, num_dests, - dests)) == NULL) + if ((dest = cupsGetDest(dest_name, NULL, num_dests, dests)) == NULL) { puts("FAIL"); return (1); @@ -380,8 +403,7 @@ main(int argc, /* I - Number of command-line arguments */ dest->instance ? dest->instance : "(null)"); fflush(stdout); - if ((named_dest = cupsGetNamedDest(NULL, dest->name, - dest->instance)) == NULL || + if ((named_dest = cupsGetNamedDest(NULL, dest->name, dest->instance)) == NULL || !dests_equal(dest, named_dest)) { if (named_dest) @@ -408,7 +430,7 @@ main(int argc, /* I - Number of command-line arguments */ fputs("cupsPrintFile: ", stdout); fflush(stdout); - if (cupsPrintFile(dest->name, "../data/testprint", "Test Page", + if (cupsPrintFile(dest->name, "../test/testfile.pdf", "Test Page", dest->num_options, dest->options) <= 0) { printf("FAIL (%s)\n", cupsLastErrorString()); @@ -421,7 +443,7 @@ main(int argc, /* I - Number of command-line arguments */ * cupsGetPPD(printer) */ - fputs("cupsGetPPD(): ", stdout); + fputs("cupsGetPPD: ", stdout); fflush(stdout); if ((ppdfile = cupsGetPPD(dest->name)) == NULL) @@ -436,7 +458,7 @@ main(int argc, /* I - Number of command-line arguments */ * ppdOpenFile() */ - fputs("ppdOpenFile(): ", stdout); + fputs("ppdOpenFile: ", stdout); fflush(stdout); if ((ppd = ppdOpenFile(ppdfile)) == NULL) @@ -550,33 +572,39 @@ show_diffs(cups_dest_t *a, /* I - First destination */ { int i; /* Looping var */ cups_option_t *aoption; /* Current option */ + cups_option_t *boption; /* Current option */ const char *bval; /* Option value */ if (!a || !b) return; - puts(" Item cupsGetDest cupsGetNamedDest"); - puts(" -------------------- -------------------- --------------------"); + puts(" Item cupsGetDest cupsGetNamedDest"); + puts(" -------------------- ------------------------ ------------------------"); if (_cups_strcasecmp(a->name, b->name)) - printf(" name %-20.20s %-20.20s\n", a->name, b->name); + printf(" name %-24.24s %-24.24s\n", a->name, b->name); if ((a->instance && !b->instance) || (!a->instance && b->instance) || (a->instance && _cups_strcasecmp(a->instance, b->instance))) - printf(" instance %-20.20s %-20.20s\n", + printf(" instance %-24.24s %-24.24s\n", a->instance ? a->instance : "(null)", b->instance ? b->instance : "(null)"); if (a->num_options != b->num_options) - printf(" num_options %-20d %-20d\n", a->num_options, + printf(" num_options %-24d %-24d\n", a->num_options, b->num_options); for (i = a->num_options, aoption = a->options; i > 0; i --, aoption ++) if ((bval = cupsGetOption(aoption->name, b->num_options, b->options)) == NULL || strcmp(aoption->value, bval)) - printf(" %-20.20s %-20.20s %-20.20s\n", aoption->name, + printf(" %-20.20s %-24.24s %-24.24s\n", aoption->name, aoption->value, bval ? bval : "(null)"); + + for (i = b->num_options, boption = b->options; i > 0; i --, boption ++) + if (!cupsGetOption(boption->name, a->num_options, a->options)) + printf(" %-20.20s %-24.24s %-24.24s\n", boption->name, + boption->value, "(null)"); } diff --git a/cups/testdest.c b/cups/testdest.c index 4e2cbed..a65e099 100644 --- a/cups/testdest.c +++ b/cups/testdest.c @@ -1,15 +1,9 @@ /* * CUPS destination API test program for CUPS. * - * Copyright 2012-2016 by Apple Inc. + * Copyright © 2012-2018 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -32,7 +26,7 @@ static void show_conflicts(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, static void show_default(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option); static void show_media(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, unsigned flags, const char *name); static void show_supported(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option, const char *value); -static void usage(const char *arg) __attribute__((noreturn)); +static void usage(const char *arg) _CUPS_NORETURN; /* @@ -43,17 +37,31 @@ int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { + int i; /* Looping var */ http_t *http; /* Connection to destination */ cups_dest_t *dest = NULL; /* Destination */ cups_dinfo_t *dinfo; /* Destination info */ + unsigned dflags = CUPS_DEST_FLAGS_NONE; + /* Destination flags */ if (argc < 2) - usage(NULL); + return (0); - if (!strcmp(argv[1], "--enum")) + if (!strcmp(argv[1], "--get")) + { + cups_dest_t *dests; /* Destinations */ + int num_dests = cupsGetDests2(CUPS_HTTP_DEFAULT, &dests); + /* Number of destinations */ + + for (i = 0; i < num_dests; i ++) + enum_cb(NULL, 0, dests + i); + + cupsFreeDests(num_dests, dests); + return (0); + } + else if (!strcmp(argv[1], "--enum")) { - int i; /* Looping var */ cups_ptype_t type = 0, /* Printer type filter */ mask = 0; /* Printer type mask */ @@ -103,70 +111,91 @@ main(int argc, /* I - Number of command-line arguments */ return (0); } - else if (!strncmp(argv[1], "ipp://", 6) || !strncmp(argv[1], "ipps://", 7)) - dest = cupsGetDestWithURI(NULL, argv[1]); + + i = 1; + if (!strcmp(argv[i], "--device")) + { + dflags = CUPS_DEST_FLAGS_DEVICE; + i ++; + } + + if (!strncmp(argv[i], "ipp://", 6) || !strncmp(argv[i], "ipps://", 7)) + dest = cupsGetDestWithURI(NULL, argv[i]); + else if (!strcmp(argv[i], "default")) + { + dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, NULL, NULL); + if (dest && dest->instance) + printf("default is \"%s/%s\".\n", dest->name, dest->instance); + else if (dest) + printf("default is \"%s\".\n", dest->name); + else + puts("no default destination."); + } else - dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, argv[1], NULL); + dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, argv[i], NULL); if (!dest) { - printf("testdest: Unable to get destination \"%s\": %s\n", argv[1], cupsLastErrorString()); + printf("testdest: Unable to get destination \"%s\": %s\n", argv[i], cupsLastErrorString()); return (1); } - if ((http = cupsConnectDest(dest, CUPS_DEST_FLAGS_NONE, 30000, NULL, NULL, 0, NULL, NULL)) == NULL) + i ++; + + if ((http = cupsConnectDest(dest, dflags, 30000, NULL, NULL, 0, NULL, NULL)) == NULL) { - printf("testdest: Unable to connect to destination \"%s\": %s\n", argv[1], cupsLastErrorString()); + printf("testdest: Unable to connect to destination \"%s\": %s\n", dest->name, cupsLastErrorString()); return (1); } if ((dinfo = cupsCopyDestInfo(http, dest)) == NULL) { - printf("testdest: Unable to get information for destination \"%s\": %s\n", argv[1], cupsLastErrorString()); + printf("testdest: Unable to get information for destination \"%s\": %s\n", dest->name, cupsLastErrorString()); return (1); } - if (argc == 2 || (!strcmp(argv[2], "supported") && argc < 6)) + if (i == argc || !strcmp(argv[i], "supported")) { - if (argc > 3) - show_supported(http, dest, dinfo, argv[3], argv[4]); + i ++; + + if ((i + 1) < argc) + show_supported(http, dest, dinfo, argv[i], argv[i + 1]); else if (argc > 2) - show_supported(http, dest, dinfo, argv[3], NULL); + show_supported(http, dest, dinfo, argv[i], NULL); else show_supported(http, dest, dinfo, NULL, NULL); } - else if (!strcmp(argv[2], "conflicts") && argc > 3) + else if (!strcmp(argv[i], "conflicts") && (i + 1) < argc) { - int i, /* Looping var */ - num_options = 0;/* Number of options */ + int num_options = 0;/* Number of options */ cups_option_t *options = NULL;/* Options */ - for (i = 3; i < argc; i ++) + for (i ++; i < argc; i ++) num_options = cupsParseOptions(argv[i], num_options, &options); show_conflicts(http, dest, dinfo, num_options, options); } - else if (!strcmp(argv[2], "default") && argc == 4) + else if (!strcmp(argv[i], "default") && (i + 1) < argc) { - show_default(http, dest, dinfo, argv[3]); + show_default(http, dest, dinfo, argv[i + 1]); } - else if (!strcmp(argv[2], "localize") && argc < 6) + else if (!strcmp(argv[i], "localize")) { - if (argc > 3) - localize(http, dest, dinfo, argv[3], argv[4]); + i ++; + if ((i + 1) < argc) + localize(http, dest, dinfo, argv[i], argv[i + 1]); else if (argc > 2) - localize(http, dest, dinfo, argv[3], NULL); + localize(http, dest, dinfo, argv[i], NULL); else localize(http, dest, dinfo, NULL, NULL); } - else if (!strcmp(argv[2], "media")) + else if (!strcmp(argv[i], "media")) { - int i; /* Looping var */ const char *name = NULL; /* Media name, if any */ unsigned flags = CUPS_MEDIA_FLAGS_DEFAULT; /* Media selection flags */ - for (i = 3; i < argc; i ++) + for (i ++; i < argc; i ++) { if (!strcmp(argv[i], "borderless")) flags = CUPS_MEDIA_FLAGS_BORDERLESS; @@ -184,19 +213,19 @@ main(int argc, /* I - Number of command-line arguments */ show_media(http, dest, dinfo, flags, name); } - else if (!strcmp(argv[2], "print") && argc > 3) + else if (!strcmp(argv[i], "print") && (i + 1) < argc) { - int i, /* Looping var */ - num_options = 0;/* Number of options */ + int num_options = 0;/* Number of options */ cups_option_t *options = NULL;/* Options */ + const char *filename = argv[i + 1]; - for (i = 4; i < argc; i ++) + for (i += 2; i < argc; i ++) num_options = cupsParseOptions(argv[i], num_options, &options); - print_file(http, dest, dinfo, argv[3], num_options, options); + print_file(http, dest, dinfo, filename, num_options, options); } else - usage(argv[2]); + usage(argv[i]); return (0); } @@ -218,13 +247,15 @@ enum_cb(void *user_data, /* I - User data (unused) */ (void)flags; if (dest->instance) - printf("%s%s/%s:\n", (flags & CUPS_DEST_FLAGS_REMOVED) ? "REMOVE " : "", dest->name, dest->instance); + printf("%s%s/%s%s:\n", (flags & CUPS_DEST_FLAGS_REMOVED) ? "REMOVE " : "", dest->name, dest->instance, dest->is_default ? " (Default)" : ""); else - printf("%s%s:\n", (flags & CUPS_DEST_FLAGS_REMOVED) ? "REMOVE " : "", dest->name); + printf("%s%s%s:\n", (flags & CUPS_DEST_FLAGS_REMOVED) ? "REMOVE " : "", dest->name, dest->is_default ? " (Default)" : ""); for (i = 0; i < dest->num_options; i ++) printf(" %s=\"%s\"\n", dest->options[i].name, dest->options[i].value); + puts(""); + return (1); } @@ -463,10 +494,37 @@ show_default(http_t *http, /* I - Connection to destination */ cups_dinfo_t *dinfo, /* I - Destination information */ const char *option) /* I - Option */ { - (void)http; - (void)dest; - (void)dinfo; - (void)option; + if (!strcmp(option, "media")) + { + /* + * Show default media option... + */ + + cups_size_t size; /* Media size information */ + + if (cupsGetDestMediaDefault(http, dest, dinfo, CUPS_MEDIA_FLAGS_DEFAULT, &size)) + printf("%s (%.2fx%.2fmm, margins=[%.2f %.2f %.2f %.2f])\n", size.media, size.width * 0.01, size.length * 0.01, size.left * 0.01, size.bottom * 0.01, size.right * 0.01, size.top * 0.01); + else + puts("FAILED"); + } + else + { + /* + * Show default other option... + */ + + ipp_attribute_t *defattr; /* Default attribute */ + + if ((defattr = cupsFindDestDefault(http, dest, dinfo, option)) != NULL) + { + char value[1024]; /* Value of default attribute */ + + ippAttributeString(defattr, value, sizeof(value)); + puts(value); + } + else + puts("FAILED"); + } } @@ -594,7 +652,7 @@ show_supported(http_t *http, /* I - Connection to destination */ } else if (!value) { - printf("%s (%s)\n", option, cupsCheckDestSupported(http, dest, dinfo, option, NULL) ? "supported" : "not-supported"); + printf("%s (%s - %s)\n", option, cupsLocalizeDestOption(http, dest, dinfo, option), cupsCheckDestSupported(http, dest, dinfo, option, NULL) ? "supported" : "not-supported"); if ((attr = cupsFindDestSupported(http, dest, dinfo, option)) != NULL) { @@ -609,7 +667,13 @@ show_supported(http_t *http, /* I - Connection to destination */ case IPP_TAG_ENUM : for (i = 0; i < count; i ++) - printf(" %s\n", ippEnumString(option, ippGetInteger(attr, i))); + { + int val = ippGetInteger(attr, i); + char valstr[256]; + + snprintf(valstr, sizeof(valstr), "%d", val); + printf(" %s (%s)\n", ippEnumString(option, ippGetInteger(attr, i)), cupsLocalizeDestValue(http, dest, dinfo, option, valstr)); + } break; case IPP_TAG_RANGE : @@ -635,11 +699,15 @@ show_supported(http_t *http, /* I - Connection to destination */ } break; + case IPP_TAG_KEYWORD : + for (i = 0; i < count; i ++) + printf(" %s (%s)\n", ippGetString(attr, i, NULL), cupsLocalizeDestValue(http, dest, dinfo, option, ippGetString(attr, i, NULL))); + break; + case IPP_TAG_TEXTLANG : case IPP_TAG_NAMELANG : case IPP_TAG_TEXT : case IPP_TAG_NAME : - case IPP_TAG_KEYWORD : case IPP_TAG_URI : case IPP_TAG_URISCHEME : case IPP_TAG_CHARSET : @@ -695,9 +763,10 @@ usage(const char *arg) /* I - Argument for usage message */ printf("testdest: Unknown option \"%s\".\n", arg); puts("Usage:"); - puts(" ./testdest name [operation ...]"); - puts(" ./testdest ipp://... [operation ...]"); - puts(" ./testdest ipps://... [operation ...]"); + puts(" ./testdest [--device] name [operation ...]"); + puts(" ./testdest [--device] ipp://... [operation ...]"); + puts(" ./testdest [--device] ipps://... [operation ...]"); + puts(" ./testdest --get"); puts(" ./testdest --enum [grayscale] [color] [duplex] [staple] [small]\n" " [medium] [large]"); puts(""); diff --git a/cups/testfile.c b/cups/testfile.c index b2ec8cd..633415d 100644 --- a/cups/testfile.c +++ b/cups/testfile.c @@ -1,16 +1,11 @@ /* * File test program for CUPS. * - * Copyright 2007-2015 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -22,14 +17,11 @@ #include "file.h" #include #include -#ifdef HAVE_LIBZ -# include -#endif /* HAVE_LIBZ */ -#ifdef WIN32 +#ifdef _WIN32 # include #else # include -#endif /* WIN32 */ +#endif /* _WIN32 */ #include @@ -53,10 +45,10 @@ main(int argc, /* I - Number of command-line arguments */ int status; /* Exit status */ char filename[1024]; /* Filename buffer */ cups_file_t *fp; /* File pointer */ -#ifndef WIN32 +#ifndef _WIN32 int fds[2]; /* Open file descriptors */ cups_file_t *fdfile; /* File opened with cupsFileOpenFd() */ -#endif /* !WIN32 */ +#endif /* !_WIN32 */ int count; /* Number of lines in file */ @@ -84,7 +76,7 @@ main(int argc, /* I - Number of command-line arguments */ status += random_tests(); -#ifndef WIN32 +#ifndef _WIN32 /* * Test fdopen and close without reading... */ @@ -118,15 +110,15 @@ main(int argc, /* I - Number of command-line arguments */ puts("PASS"); } -#endif /* !WIN32 */ +#endif /* !_WIN32 */ /* - * Count lines in psglyphs, rewind, then count again. + * Count lines in test file, rewind, then count again. */ - fputs("\ncupsFileOpen(\"../data/media.defs\", \"r\"): ", stdout); + fputs("\ncupsFileOpen(\"testfile.txt\", \"r\"): ", stdout); - if ((fp = cupsFileOpen("../data/media.defs", "r")) == NULL) + if ((fp = cupsFileOpen("testfile.txt", "r")) == NULL) { puts("FAIL"); status ++; @@ -136,9 +128,9 @@ main(int argc, /* I - Number of command-line arguments */ puts("PASS"); fputs("cupsFileGets: ", stdout); - if ((count = count_lines(fp)) != 201) + if ((count = count_lines(fp)) != 477) { - printf("FAIL (got %d lines, expected 201)\n", count); + printf("FAIL (got %d lines, expected 477)\n", count); status ++; } else @@ -156,9 +148,9 @@ main(int argc, /* I - Number of command-line arguments */ puts("PASS"); fputs("cupsFileGets: ", stdout); - if ((count = count_lines(fp)) != 201) + if ((count = count_lines(fp)) != 477) { - printf("FAIL (got %d lines, expected 201)\n", count); + printf("FAIL (got %d lines, expected 477)\n", count); status ++; } else @@ -174,13 +166,13 @@ main(int argc, /* I - Number of command-line arguments */ */ fputs("\ncupsFileFind: ", stdout); -#ifdef WIN32 +#ifdef _WIN32 if (cupsFileFind("notepad.exe", "C:/WINDOWS", 1, filename, sizeof(filename)) && cupsFileFind("notepad.exe", "C:/WINDOWS;C:/WINDOWS/SYSTEM32", 1, filename, sizeof(filename))) #else if (cupsFileFind("cat", "/bin", 1, filename, sizeof(filename)) && cupsFileFind("cat", "/bin:/usr/bin", 1, filename, sizeof(filename))) -#endif /* WIN32 */ +#endif /* _WIN32 */ printf("PASS (%s)\n", filename); else { diff --git a/cups/testfile.txt b/cups/testfile.txt new file mode 100644 index 0000000..d33c04c --- /dev/null +++ b/cups/testfile.txt @@ -0,0 +1,477 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi faucibus viverra +nibh ut molestie. Sed aliquet vestibulum dignissim. Praesent dignissim mauris +arcu. Donec porta velit quis nibh rutrum sollicitudin. Aliquam vel tellus +vulputate, sollicitudin turpis in, luctus quam. Donec hendrerit enim dignissim +varius tincidunt. Phasellus mi felis, ultrices nec magna in, ultrices interdum +justo. Nulla aliquam sem ac porta tincidunt. Praesent nec fermentum mauris. +Suspendisse ullamcorper mauris orci, eu ornare dui mollis quis. + +In vitae lorem id nulla pellentesque sagittis. Duis aliquet ligula nisl, sed +mollis sapien commodo nec. Etiam placerat arcu turpis, eget viverra magna +ultrices sed. Nullam dapibus urna et tristique consectetur. Curabitur iaculis +nisl lobortis condimentum accumsan. Praesent sagittis purus nunc, vitae bibendum +leo ornare a. Maecenas neque mauris, mollis a sem ut, rhoncus posuere orci. +Aliquam luctus suscipit erat ut semper. In neque augue, vulputate ornare massa +fermentum, sodales faucibus mauris. Vestibulum ante ipsum primis in faucibus +orci luctus et ultrices posuere cubilia Curae; + +Pellentesque mattis ante nunc, sit amet blandit felis cursus sed. Quisque +pellentesque ipsum ac mauris fringilla, a rhoncus nunc lacinia. Vestibulum +tempor orci ut nisl cursus, at euismod sem sodales. Integer ornare tellus at +sapien tincidunt ultrices. Interdum et malesuada fames ac ante ipsum primis in +faucibus. Integer placerat eleifend magna, eget volutpat nibh vulputate eget. +Donec cursus orci nisl, eget malesuada sem porta at. + +Sed maximus eleifend leo, posuere pellentesque urna viverra id. Aenean pharetra +nunc ut suscipit aliquam. Sed dolor massa, ultrices sed sollicitudin nec, +dapibus vitae tortor. Cras in scelerisque tellus. Sed eu felis vitae neque +tempor eleifend vitae ac augue. Nunc felis ex, fringilla quis sapien vel, tempor +congue nibh. Nullam placerat sit amet lacus quis facilisis. + +Sed semper nisi eget auctor semper. Phasellus sodales tempus massa ut suscipit. +Integer malesuada convallis neque, sed pretium leo rhoncus ac. In hac habitasse +platea dictumst. Nullam efficitur mollis lorem. Integer convallis lobortis +dictum. Suspendisse euismod in mauris vel pharetra. Sed vitae magna ut turpis +viverra rhoncus ut sit amet mauris. Nam vel lacinia metus. Proin ut elementum +felis. Nullam massa velit, euismod vel metus eget, feugiat aliquet odio. Fusce +venenatis lorem ut lectus ultricies, vitae accumsan nibh dictum. Maecenas porta +euismod cursus. Nunc at ligula congue, lobortis quam id, volutpat felis. + +Proin blandit pulvinar ligula, at dapibus dui rutrum dictum. Etiam non finibus +urna. Pellentesque semper pharetra arcu non dapibus. Vestibulum gravida dictum +libero, quis dictum odio hendrerit sit amet. Aenean a venenatis ante, tincidunt +convallis orci. Morbi tincidunt, orci vitae suscipit lacinia, nisl nunc rutrum +ex, vitae convallis nulla libero ut mauris. Donec ac pellentesque sapien. +Phasellus elementum orci a nisl feugiat tempus. Quisque id justo sed tellus +ultricies porttitor. Fusce elementum mauris nunc. Nullam vel elit ultrices, +rhoncus elit id, scelerisque erat. + +Pellentesque molestie efficitur purus, at malesuada orci efficitur et. Curabitur +blandit nisi a ante viverra, vel ornare turpis molestie. Class aptent taciti +sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras +scelerisque est non velit placerat, eu volutpat sem fermentum. Cras vitae +gravida nisi, non vestibulum velit. Interdum et malesuada fames ac ante ipsum +primis in faucibus. Cras sollicitudin rutrum tincidunt. Pellentesque non nisl +condimentum, commodo turpis non, fringilla ante. Nunc non ante vel est porttitor +tempor sed vitae nunc. Donec bibendum orci justo, lobortis laoreet purus +accumsan vel. Phasellus non posuere orci. In hac habitasse platea dictumst. +Praesent nec mi sit amet urna ornare pulvinar faucibus at sem. Vestibulum vel +cursus nisl, vel ultricies justo. Proin sed consequat odio, eget dignissim +dolor. Fusce mattis porttitor nulla rutrum aliquet. + +Duis vehicula enim nec condimentum dignissim. Phasellus viverra ex at erat +lacinia varius. Nullam rutrum felis ac lacus dignissim elementum quis sit amet +felis. Phasellus eget sapien sit amet sapien maximus tincidunt elementum ut +ante. Mauris dictum pulvinar diam ac lobortis. Duis vitae dui metus. Donec +imperdiet risus vitae augue placerat ultrices. Integer euismod, sapien sit amet +faucibus venenatis, nisl lacus rhoncus lacus, a auctor justo ante sed turpis. +Integer facilisis est non venenatis hendrerit. Vivamus quis ante sodales, mollis +turpis in, bibendum turpis. In hac habitasse platea dictumst. Phasellus nisl +est, porta feugiat eros ut, scelerisque efficitur diam. Suspendisse sit amet +magna libero. Quisque eu arcu vel orci iaculis sagittis nec id orci. Mauris +mattis nunc id quam tristique pellentesque. + +Vestibulum vehicula, mauris ac venenatis lobortis, ex risus bibendum nunc, eu +bibendum dolor metus vitae purus. Ut bibendum sed ante viverra tincidunt. +Vestibulum id semper lacus. Fusce lacinia dignissim semper. Proin diam enim, +pellentesque vel dui eu, maximus tincidunt mauris. Cras lorem lectus, malesuada +non dui ac, iaculis elementum justo. Fusce fringilla tempor arcu. Proin vel +turpis vitae purus facilisis dapibus condimentum sed ipsum. Duis mollis justo at +ante convallis ornare. Suspendisse accumsan eleifend mauris, ut aliquet eros +scelerisque eget. Proin ornare elit eu felis dapibus, sit amet posuere est +porttitor. Vivamus tincidunt metus ac nisl pharetra, vel mollis neque egestas. + +Quisque turpis ligula, lacinia id suscipit eget, cursus eget mauris. Class +aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos +himenaeos. Curabitur sodales, urna eget luctus congue, metus magna viverra nisl, +ut eleifend nulla urna eu arcu. Pellentesque interdum interdum erat, et +hendrerit arcu rhoncus ut. Nulla congue tortor nec egestas aliquam. Nulla +elementum augue eu est imperdiet, nec maximus sapien ornare. Donec aliquam +blandit felis, sed vulputate orci ultrices non. Vivamus rutrum dapibus ligula, +non ullamcorper ante eleifend vel. Pellentesque habitant morbi tristique +senectus et netus et malesuada fames ac turpis egestas. Aliquam sed lacus +condimentum odio commodo tristique. + +Proin ultrices non tellus sit amet condimentum. Ut aliquam nulla eget viverra +aliquet. Fusce aliquet orci nec finibus tempor. Etiam luctus eleifend diam vitae +tempor. Fusce sagittis porttitor dignissim. Morbi euismod pellentesque mi vel +malesuada. Praesent cursus rutrum diam sit amet auctor. Praesent non leo +consequat, dapibus massa pellentesque, egestas nulla. Nulla efficitur luctus +purus eu aliquet. Phasellus sed enim pharetra, molestie felis eget, tempor +neque. Proin efficitur vestibulum libero ut hendrerit. Mauris vitae vestibulum +augue, in pellentesque ligula. Phasellus at libero dictum, pretium mauris vitae, +elementum ex. Pellentesque ut euismod orci. In ac elit vel nisl bibendum +fermentum eget in dui. Donec fringilla, nisl vitae tincidunt varius, tellus +sapien accumsan lectus, ac tincidunt eros ipsum nec libero. + +Sed mollis purus nec magna tempus, vitae laoreet purus luctus. Morbi accumsan, +urna eget placerat volutpat, nunc magna mattis mi, vitae efficitur eros quam +quis lacus. Etiam eros ligula, tempus vel consectetur non, consectetur quis +risus. Phasellus venenatis lectus arcu, quis bibendum diam dignissim a. Donec +tristique, felis quis dignissim tempor, justo sapien faucibus odio, at venenatis +arcu purus et justo. Nunc vel ex a augue luctus pharetra ac ac turpis. Proin +auctor turpis lobortis, scelerisque mi sit amet, elementum dui. Duis blandit +arcu eros, eu dapibus enim imperdiet sed. Sed auctor urna sed lectus condimentum +rhoncus. Mauris luctus dolor rhoncus suscipit semper. Sed molestie felis ut +laoreet porta. Duis at purus viverra, faucibus elit eu, fringilla odio. +Suspendisse sit amet sodales urna. In hac habitasse platea dictumst. Integer a +sem sed augue sodales dictum. Quisque ut nisi pellentesque, lobortis lectus et, +hendrerit eros. + +Phasellus posuere metus sit amet orci viverra vehicula. Nulla urna est, +pellentesque in placerat ut, congue a ligula. Maecenas non viverra arcu. Vivamus +fermentum odio tincidunt tellus tempus, ut suscipit justo hendrerit. Nunc quis +sapien eget turpis mollis porta. Curabitur ultrices est molestie lacus finibus, +vel sodales leo aliquam. Quisque ultrices semper porta. Nulla facilisi. Aenean +nunc leo, ultrices quis augue non, hendrerit semper lectus. + +Nulla facilisi. In in volutpat tellus. Sed tincidunt efficitur sem, vel bibendum +ex pharetra eleifend. Class aptent taciti sociosqu ad litora torquent per +conubia nostra, per inceptos himenaeos. Sed nec erat at ipsum fringilla commodo +eget eu est. Donec suscipit ligula eu ipsum lobortis tristique. Nulla dignissim +nisi quis dignissim faucibus. Nunc finibus lacus eget est laoreet ultrices. + +Fusce molestie mattis facilisis. Fusce dictum blandit sem ac tincidunt. +Suspendisse aliquam, dolor ac tincidunt scelerisque, lacus leo luctus quam, ac +auctor ligula neque quis dolor. Maecenas laoreet viverra lectus, eget hendrerit +urna congue ac. Donec convallis, erat ut consectetur ornare, diam diam accumsan +lacus, at consectetur mauris nisi vitae massa. Vestibulum vestibulum dictum +volutpat. Quisque et commodo velit. Praesent in odio nunc. + +Vivamus consectetur leo sem, sit amet auctor arcu blandit vitae. Donec non +auctor mauris. Pellentesque habitant morbi tristique senectus et netus et +malesuada fames ac turpis egestas. Proin nibh tellus, fermentum quis erat in, +vulputate faucibus nunc. Vestibulum imperdiet ipsum purus, eget efficitur mi +hendrerit vel. Aenean iaculis elementum metus nec consectetur. Suspendisse felis +turpis, maximus sit amet diam at, elementum vestibulum nulla. Quisque et lacinia +elit. Pellentesque tincidunt bibendum neque, non molestie massa ultrices eget. + +Duis scelerisque magna in blandit dictum. Pellentesque lacinia augue vitae +fermentum mollis. Etiam mi velit, tempor at risus vel, luctus vestibulum odio. +Phasellus vel ipsum sit amet velit malesuada hendrerit. Donec consequat laoreet +enim. Aliquam sed justo eget ex rhoncus laoreet. Duis maximus tortor at odio +suscipit, non accumsan arcu efficitur. Nunc pharetra id neque nec dignissim. Sed +condimentum magna ut viverra porttitor. Pellentesque rutrum magna et pretium +semper. Fusce tincidunt ipsum at auctor commodo. Duis et ipsum nec turpis +pharetra pulvinar a nec risus. Praesent in enim et ligula maximus consectetur. +Aenean nec turpis turpis. + +Quisque mollis dignissim elit, sit amet interdum urna venenatis sit amet. +Quisque interdum, diam eu ullamcorper suscipit, augue purus fermentum purus, nec +consequat purus nibh laoreet lectus. Ut nisi mauris, ultrices non euismod ac, +mollis id libero. Vestibulum ante ipsum primis in faucibus orci luctus et +ultrices posuere cubilia Curae; Cras vitae tristique mi. Mauris ut bibendum +dolor. Suspendisse potenti. Ut tempus ultricies erat, a molestie sapien aliquet +non. Aliquam sagittis nisi vel enim rhoncus eleifend. Proin aliquam eros ut +metus consectetur suscipit. Curabitur ornare mi eget faucibus aliquam. Praesent +ultricies libero est, eget porttitor risus ornare nec. Curabitur pharetra ex ut +eleifend lacinia. Nam nec finibus nunc. Sed hendrerit risus nisi, eu +sollicitudin tellus sollicitudin nec. Proin vel est leo. + +Fusce et orci finibus, auctor purus eu, varius magna. Sed sollicitudin elit +vitae turpis tincidunt, at suscipit lacus ultricies. Mauris pretium, nisi sed +cursus ullamcorper, sem sem vulputate neque, a pellentesque lectus massa vel +metus. Sed tincidunt iaculis lectus, non facilisis elit finibus at. Nunc odio +purus, eleifend ac pretium nec, malesuada condimentum eros. Aenean interdum +dolor et malesuada auctor. Donec placerat velit ex, vel cursus metus posuere +sed. Phasellus rutrum nisl vel imperdiet egestas. Interdum et malesuada fames ac +ante ipsum primis in faucibus. Etiam volutpat quam ut risus ultricies blandit. +Mauris commodo ullamcorper pretium. Nam interdum lobortis eleifend. Fusce quam +nisl, feugiat vitae dui non, egestas eleifend erat. Mauris in ligula purus. +Morbi vel mollis diam. Praesent leo felis, luctus ac blandit sit amet, aliquam +at enim. + +Duis sit amet augue enim. Donec feugiat ultricies neque, ut porttitor lectus +sagittis ut. Sed ante sem, mollis ut dui quis, finibus rutrum justo. Phasellus +ornare nibh ac scelerisque fringilla. Donec rhoncus luctus elit sed accumsan. +Maecenas fermentum quam nec eros consequat, vitae sollicitudin elit facilisis. +Phasellus urna metus, viverra at nibh ac, euismod fringilla mi. Aliquam nec odio +neque. Duis pulvinar congue aliquam. Suspendisse laoreet bibendum sapien, non +ultricies velit porta id. Vivamus dignissim rhoncus mi, sit amet mollis arcu +cursus nec. Maecenas sagittis cursus dictum. Nam fermentum tincidunt +pellentesque. Vivamus tempus tincidunt rutrum. Mauris semper orci non +scelerisque accumsan. + +Nulla fermentum in lacus at aliquet. Proin ut ligula venenatis, maximus elit a, +finibus felis. Nam euismod arcu vel diam laoreet, sed hendrerit urna pharetra. +Phasellus non hendrerit tortor. Donec ut congue odio. Nunc pellentesque ipsum et +est venenatis, sed vehicula magna convallis. Quisque eget euismod orci. In ut +nulla ac augue auctor dapibus a vel arcu. Duis elementum, libero at ullamcorper +consequat, libero nulla vestibulum elit, vel congue lacus nulla quis nulla. +Nulla vel dolor vulputate, dictum nunc nec, pellentesque lacus. Nulla nibh mi, +gravida vel velit vel, tempus dapibus magna. Mauris ornare elementum feugiat. +Vestibulum non finibus lorem, a ullamcorper quam. + +Duis eget velit sodales, rhoncus odio nec, laoreet lorem. Donec fermentum est eu +ornare placerat. Sed interdum metus ac metus hendrerit rhoncus. In molestie diam +sem, et faucibus purus lacinia eu. Donec quam arcu, tempus ac commodo sit amet, +porttitor sit amet urna. Suspendisse pellentesque placerat mi, at semper orci +tincidunt non. Fusce ut mattis nisi. Pellentesque vel nisi quis massa volutpat +aliquam vel nec tortor. Maecenas vitae risus quis nibh vestibulum rutrum. +Vestibulum egestas dolor ullamcorper lorem placerat tincidunt. Curabitur massa +urna, pharetra sed gravida vitae, venenatis a tellus. Duis condimentum lectus +tellus, ut sodales ipsum hendrerit ac. Nullam sed accumsan arcu, ut sollicitudin +diam. Integer eu ligula vitae purus vehicula vulputate nec et metus. Aenean +mollis tempor lectus eu elementum. Integer in dui tempus, porttitor erat sed, +malesuada magna. + +Cras nec orci sed tellus porta tristique a ac dui. Nam eu faucibus mi. Praesent +condimentum laoreet augue id pellentesque. In malesuada ex sed turpis +consectetur, non sodales mi cursus. Nunc id sem luctus, mattis lorem vel, tempus +ipsum. Nunc efficitur augue et nunc hendrerit, non tincidunt magna commodo. +Aenean sodales porta mi. Sed semper accumsan turpis vitae aliquam. Phasellus +vitae ex faucibus, suscipit ante non, commodo ligula. Aliquam erat volutpat. +Etiam odio sem, fringilla in sem eu, bibendum ornare est. Pellentesque habitant +morbi tristique senectus et netus et malesuada fames ac turpis egestas. Lorem +ipsum dolor sit amet, consectetur adipiscing elit. + +Nulla nec fringilla magna. Morbi eu cursus sem. Fusce euismod eget turpis et +bibendum. Donec vel tincidunt neque. Suspendisse commodo euismod sodales. +Integer pretium congue tortor nec ullamcorper. Nam imperdiet, urna auctor +pretium facilisis, sem arcu malesuada turpis, sit amet sodales nisi lectus +sollicitudin tellus. Praesent consequat leo in dui congue, euismod ornare risus +malesuada. Nunc id tincidunt tortor. Vestibulum sit amet sapien urna. Donec quis +tristique elit, non facilisis neque. Donec gravida molestie tellus, sagittis +accumsan metus varius eu. + +Duis nec est vitae augue laoreet rhoncus non nec mi. Phasellus pretium pharetra +magna, et congue urna posuere eget. Sed finibus arcu magna, sed luctus ante +suscipit quis. Pellentesque habitant morbi tristique senectus et netus et +malesuada fames ac turpis egestas. Fusce at accumsan quam. Mauris dolor lectus, +tempus auctor ante ut, auctor maximus turpis. Proin pulvinar dolor in +consectetur aliquam. Fusce sagittis elementum fermentum. + +Aliquam nec posuere ipsum. Nulla commodo est at magna fringilla lobortis. Etiam +diam orci, venenatis non erat iaculis, commodo hendrerit diam. Nam imperdiet +justo vitae massa consectetur, ornare feugiat ipsum molestie. Curabitur +dignissim vitae augue et euismod. Interdum et malesuada fames ac ante ipsum +primis in faucibus. Praesent justo nunc, pellentesque vel ante vitae, dignissim +maximus felis. Proin vel congue nisl. Quisque ac tempus libero. In at placerat +tellus. Integer lobortis ligula vel dolor ornare finibus. + +Donec semper nisl mauris, eu consectetur lacus sollicitudin a. Integer sem enim, +consectetur sed tincidunt id, dignissim at mauris. In a justo non erat cursus +tincidunt et sed sapien. Aenean vulputate placerat ornare. Etiam id lectus +lacus. Donec a sodales sapien. Duis in suscipit est, ultrices mollis magna. +Etiam blandit diam vitae sollicitudin sodales. Proin vel diam nec neque +ullamcorper ullamcorper ut at sapien. Sed quis sollicitudin libero. Nulla sed +arcu consequat, egestas libero viverra, dignissim magna. + +Nullam semper turpis a sem tincidunt, ut molestie ante tincidunt. Curabitur +efficitur nisl quis aliquam tristique. Proin a auctor lectus. Donec dictum +mauris a leo consequat, eu bibendum neque efficitur. Donec euismod, mi nec +faucibus ornare, elit est tincidunt ligula, at molestie neque augue non justo. +Vestibulum condimentum varius felis non pretium. Praesent maximus ex sed justo +tristique elementum. Phasellus nec feugiat dolor. Nulla sed odio quam. Nulla nec +massa sit amet tellus efficitur accumsan sed et orci. Nullam sed mollis augue, +eget dictum metus. Etiam ut velit elit. Nullam nibh eros, commodo vitae maximus +sit amet, convallis sit amet elit. Nullam faucibus arcu tortor, vitae tincidunt +augue ullamcorper in. + +Praesent quis metus et purus volutpat pulvinar. Sed commodo vehicula sodales. +Phasellus fringilla vehicula placerat. Vestibulum sit amet ante in ante +condimentum laoreet. Sed id purus diam. Suspendisse in libero in risus eleifend +fringilla. Cras non sapien vel sapien condimentum tristique. + +Integer non semper mi, a aliquet enim. Phasellus congue erat sed lorem molestie +consectetur. Integer iaculis nisi et nisi blandit auctor. Nullam magna diam, +hendrerit sollicitudin urna vel, gravida congue diam. Curabitur finibus ipsum +ex, ac feugiat massa posuere at. Pellentesque in molestie lorem. Fusce rhoncus +velit at magna accumsan convallis. Aliquam posuere elementum turpis, eget +eleifend quam auctor et. Mauris a diam vitae magna malesuada fermentum sit amet +ut justo. Quisque in purus et erat rhoncus accumsan. Donec feugiat, ipsum vel +pulvinar suscipit, nibh nisi volutpat felis, nec rutrum nisi turpis at diam. +Suspendisse posuere, ante ut imperdiet tempor, tortor magna maximus risus, id +fermentum urna mauris hendrerit magna. Interdum et malesuada fames ac ante ipsum +primis in faucibus. + +Ut eu faucibus neque. Fusce tempus luctus dui ut ullamcorper. Suspendisse in +velit a turpis facilisis scelerisque. Nullam ultricies sodales convallis. Proin +viverra vulputate justo sit amet interdum. Donec mi neque, dapibus ac ex at, +dignissim tincidunt lacus. Praesent ultricies, erat ac sagittis tempor, justo +turpis porta tortor, eget consectetur turpis odio sed nibh. Vestibulum vitae +porta lorem, efficitur viverra enim. + +Nullam sodales sagittis tristique. Duis ac velit ultrices, efficitur tortor sit +amet, varius lacus. Praesent blandit et arcu sit amet tempus. Quisque neque +lectus, congue at rutrum at, commodo eu velit. Aliquam sed mi a ante condimentum +consectetur. Morbi feugiat risus dolor, ac auctor massa ultrices in. Praesent +laoreet metus non urna rhoncus, vel lacinia ex dapibus. Class aptent taciti +sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. +Curabitur vitae arcu vel enim feugiat rhoncus. Nullam nec neque sed nulla +hendrerit iaculis sed non erat. Pellentesque orci lacus, ullamcorper posuere +odio vel, efficitur elementum ipsum. Morbi justo risus, faucibus sit amet urna +eu, facilisis consequat ipsum. Quisque et congue ipsum, at ornare lacus. + +Nunc laoreet elit nec arcu lobortis consectetur. Sed consectetur ultrices risus, +quis tincidunt lectus fermentum at. Nunc libero sem, dignissim pharetra lacinia +eu, posuere quis libero. Sed at lacus consectetur, molestie nisi quis, +scelerisque tortor. Etiam accumsan placerat nulla, vel consectetur felis aliquam +et. Cras pellentesque massa a ex commodo condimentum. Integer nec nulla sed +metus dignissim placerat. Ut vel urna augue. Donec pharetra justo ac ex pretium, +ut condimentum erat lacinia. Nunc id porta nunc, ac dapibus massa. Suspendisse +accumsan justo quis felis pharetra tempus. Donec rutrum nulla in consectetur +tincidunt. + +Sed eu orci eu ligula maximus aliquet eget sed ex. Donec rhoncus fringilla +tellus, a bibendum mi placerat eu. Pellentesque luctus finibus neque blandit +pharetra. Aenean nec elit pretium, sodales lacus sed, mollis felis. Duis commodo +pellentesque risus et semper. Praesent pretium, libero pharetra fringilla +faucibus, ipsum urna porta nunc, nec euismod dolor risus eget lacus. Curabitur +malesuada dapibus tellus ut luctus. Aliquam gravida mauris tellus, ut vestibulum +massa dignissim vestibulum. Sed pulvinar, ex et consequat malesuada, erat tellus +bibendum mi, nec auctor nulla massa eu justo. Suspendisse imperdiet interdum +ligula. Donec at pretium urna. Donec quis diam leo. Aenean ac lectus non justo +aliquam consequat vitae mattis ipsum. Integer at consectetur felis, et volutpat +sapien. Suspendisse efficitur libero eu pulvinar cursus. + +Suspendisse interdum enim id nibh imperdiet, et pulvinar lectus aliquet. Donec +ultricies mattis lorem eget malesuada. Sed hendrerit massa in rutrum auctor. +Suspendisse interdum mauris in sem vestibulum volutpat. Maecenas interdum +facilisis dui, posuere volutpat eros suscipit eget. Curabitur blandit odio +turpis, non dignissim magna varius sit amet. Suspendisse cursus ipsum id metus +venenatis, eu malesuada arcu congue. + +Nulla vitae mi ut nibh pretium cursus in vitae turpis. In hac habitasse platea +dictumst. Phasellus consectetur, metus at tempus sollicitudin, nibh est molestie +nunc, sed imperdiet purus sapien in lorem. Etiam eget leo nec sem efficitur +luctus. Vestibulum mattis a odio ut volutpat. Duis consequat magna eget luctus +vulputate. Nam viverra posuere ultricies. + +Duis sagittis nunc et sem sagittis venenatis. Sed massa lacus, vestibulum eget +convallis ac, facilisis nec turpis. Morbi ac ornare ex. Quisque non laoreet +lectus, sed tempus libero. Sed non neque risus. Sed gravida, mauris ac aliquam +porttitor, dolor massa faucibus est, eget vestibulum eros eros et risus. Morbi +sit amet tincidunt eros, ut cursus mauris. Integer a lectus pharetra, molestie +massa vel, laoreet sem. Suspendisse et enim libero. Nam molestie risus nec ex +laoreet, a faucibus massa rhoncus. Vivamus faucibus sapien eget lorem efficitur +auctor. + +Curabitur sit amet leo non massa tempor bibendum. Nunc in tristique est. Donec +id mollis mauris, vel porta magna. Nulla vulputate eleifend lacus sed tincidunt. +Maecenas vitae sapien eu neque hendrerit venenatis sit amet nec nulla. Morbi +vestibulum dui lectus, id commodo dui vehicula eget. Nulla laoreet turpis vitae +lacus vehicula lacinia. Integer rhoncus tellus mi, vitae gravida metus convallis +quis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per +inceptos himenaeos. Mauris et accumsan sem. Sed elementum egestas tellus eget +eleifend. Sed finibus luctus felis. + +Maecenas ultrices sodales orci non dapibus. Phasellus vitae lacus at diam +ultrices mattis porta non ipsum. Aliquam erat volutpat. Vestibulum auctor diam +vehicula gravida volutpat. In rhoncus, dui sit amet consequat convallis, odio +mauris tincidunt mi, vestibulum imperdiet lacus erat sed metus. Aenean in augue +eu tortor dictum tempor a ac magna. Mauris aliquet justo eget sem sollicitudin, +congue facilisis velit mollis. Proin dignissim, nulla a efficitur fringilla, +orci nulla malesuada velit, eget cursus dolor metus vitae nisl. Phasellus non +neque ipsum. Pellentesque porta vehicula ipsum, nec posuere urna bibendum et. +Etiam nec nisl eu nulla tempus placerat. Pellentesque risus magna, accumsan +vitae sem vitae, cursus fermentum elit. Ut varius efficitur turpis, et +pellentesque libero rutrum hendrerit. Maecenas condimentum lobortis eros, a +euismod metus. + +Ut risus sapien, pulvinar quis euismod id, vestibulum ac erat. Donec feugiat +tempor commodo. Donec ligula est, aliquet eu sagittis eu, posuere vel eros. +Nullam sollicitudin diam eget libero malesuada, vel tempus lectus congue. +Praesent a odio risus. Nullam maximus tellus sed ligula eleifend, sed mollis +nunc consequat. Quisque eros mi, imperdiet nec ipsum in, pretium feugiat nibh. +Pellentesque cursus justo at metus condimentum consectetur. Nulla facilisi. Ut +tincidunt sem eget diam rhoncus, vitae gravida ipsum facilisis. Integer et +condimentum purus. + +Sed faucibus tempus orci, id cursus eros volutpat non. Nam pulvinar ex nec enim +egestas ultricies. Suspendisse at eros ac metus sodales varius eu in ante. Cras +sed est quis magna tempus mollis id faucibus nibh. Curabitur convallis nisi +dolor, in imperdiet ante tempor eu. Quisque placerat leo et leo cursus, nec +eleifend urna scelerisque. Duis consequat ex a sapien facilisis consectetur. +Vivamus et aliquam lacus. + +Praesent consequat lacus in aliquam ultricies. Sed consectetur vehicula aliquet. +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos +himenaeos. Vivamus tellus neque, eleifend sed purus quis, elementum luctus mi. +Nullam elit lacus, finibus a sollicitudin in, suscipit non nunc. Nulla vulputate +odio vitae mauris tristique, ac interdum urna interdum. Phasellus nec tortor +hendrerit, mattis ante non, pharetra tortor. + +Pellentesque vitae tempor urna, ut gravida enim. Sed eget sem purus. Nunc semper +quam mi, sed mollis ligula feugiat at. Pellentesque finibus augue risus, et +ultricies lacus scelerisque vel. Proin euismod tortor quam, et cursus ipsum +dictum ac. Suspendisse laoreet velit consequat ullamcorper cursus. Nam ultricies +gravida viverra. Vivamus non sodales quam, eget rutrum quam. Suspendisse +venenatis lorem sodales lectus eleifend, ac consequat odio finibus. Morbi id +maximus metus, a molestie neque. Integer eget felis sit amet sem tempor +placerat. Suspendisse lobortis congue justo eu accumsan. Nullam accumsan laoreet +purus. Nulla quis efficitur risus. + +Ut ac leo libero. Nam nec nisi iaculis, ornare nunc fringilla, sodales lectus. +Nulla laoreet mauris sodales, sagittis enim non, vestibulum orci. Fusce orci +dui, dapibus nec ligula vitae, vulputate maximus ante. Mauris vitae felis +tincidunt, ullamcorper neque quis, pulvinar nisl. Fusce ut augue ac nisl posuere +tristique ac sed leo. Nunc pellentesque pretium turpis. Integer maximus rutrum +felis, ut molestie mauris mattis non. Morbi ac risus ut mauris porta pharetra. +Fusce mollis pharetra turpis nec consequat. Aenean tincidunt felis vel nulla +porta, faucibus egestas ligula efficitur. Morbi et dictum velit. + +Proin scelerisque justo in tristique congue. Maecenas consequat ante dapibus +justo vehicula pretium. Sed consequat turpis ac orci suscipit malesuada non a +risus. In id leo molestie, venenatis risus quis, dignissim nulla. Nulla aliquet +risus nulla, a convallis sem tincidunt ac. Pellentesque scelerisque, elit eu +finibus eleifend, orci lectus egestas lorem, nec bibendum libero est non leo. +Nullam nisl ante, ullamcorper in efficitur a, consectetur sit amet tellus. Ut et +pellentesque eros. Etiam mattis nulla justo, sed ultricies dui commodo vel. Ut +tristique posuere leo, ac facilisis massa lobortis nec. Quisque leo ligula, +venenatis vel facilisis vel, volutpat ac sapien. Fusce sed porttitor urna. +Phasellus tempus semper condimentum. Aliquam sit amet felis vel nulla porta +luctus id vel leo. + +Ut ut odio tincidunt, ultrices enim at, pellentesque sem. Proin bibendum ligula +lacus, ut tempus mauris tincidunt id. Praesent sollicitudin interdum tellus, vel +tincidunt nisi ultrices a. Aliquam cursus faucibus elit, quis lacinia erat +elementum eu. Duis sollicitudin lectus lectus, ut ultrices elit malesuada quis. +Phasellus viverra turpis sit amet erat iaculis dapibus. Donec semper turpis sed +risus pharetra pharetra. Donec ut ante ac orci blandit interdum. Pellentesque +facilisis id purus egestas placerat. Suspendisse sit amet euismod velit, et +rutrum ipsum. Maecenas at mi pulvinar, dignissim erat quis, blandit libero. +Praesent quam tortor, tempus et laoreet nec, aliquet sed libero. Duis vestibulum +est sed risus venenatis rhoncus. Phasellus arcu libero, commodo eget tincidunt +non, aliquam in velit. Phasellus imperdiet ante a laoreet gravida. Cras faucibus +semper nulla eu facilisis. + +Praesent non sem sem. Nulla tempus ullamcorper sollicitudin. Ut eget nisi eget +augue fermentum consequat. Proin congue a nisi eget ullamcorper. Pellentesque +luctus diam felis, a pharetra nunc cursus in. Vivamus a quam dolor. Curabitur +fermentum elit sit amet purus ultricies, ut placerat nisl finibus. Nunc sed +ligula diam. Ut efficitur risus tortor. Suspendisse sem elit, posuere sit amet +nisi et, placerat tristique ipsum. Ut nunc ex, fermentum sed tempor vitae, +scelerisque quis nulla. + +Duis ac aliquam lectus. Curabitur consequat maximus leo sed cursus. Maecenas +cursus lectus non porttitor consectetur. Vivamus ultricies, lectus non tempor +porttitor, turpis velit auctor leo, at auctor nibh justo ut mi. Vivamus interdum +massa at fermentum cursus. Nulla suscipit purus nulla, vel condimentum eros +rhoncus eget. Nulla malesuada aliquet maximus. Nulla blandit ipsum finibus leo +rhoncus, non lobortis felis scelerisque. Duis blandit massa quis velit efficitur +cursus. Aliquam nibh arcu, dictum et feugiat eget, iaculis ac risus. Nunc +facilisis pellentesque mauris, a aliquet libero eleifend eu. Pellentesque a +turpis et justo blandit maximus. Phasellus imperdiet dui odio, eu facilisis quam +porttitor id. Morbi accumsan, mauris eget fermentum porta, mi risus sagittis +nisi, in semper odio orci a magna. Praesent maximus accumsan odio, vitae +bibendum ipsum ultrices eu. Vestibulum laoreet purus nec neque fringilla +dignissim. + +Morbi interdum diam eget ornare vestibulum. Etiam egestas at ipsum eget dapibus. +Nullam feugiat mi ex, et varius odio ornare id. Sed sagittis augue quam, in +maximus orci tincidunt vel. Duis molestie felis nunc, et feugiat risus +vestibulum et. Integer efficitur augue elit, id commodo lorem volutpat sed. +Fusce quam velit, suscipit a posuere sit amet, pulvinar sed nisi. Fusce lacinia +accumsan nunc vitae lobortis. Vivamus eu fringilla velit. Cras hendrerit +efficitur faucibus. Praesent facilisis a nulla non efficitur. Etiam quis est ac +neque pharetra bibendum a vitae neque. + +Phasellus dui dui, pellentesque in facilisis quis, vulputate non nibh. Integer +in lobortis velit. Curabitur efficitur imperdiet dolor, vel tempus dui fermentum +quis. Maecenas porttitor nibh at nibh cursus mattis. In dolor neque, efficitur +at ligula nec, lobortis aliquam ipsum. Phasellus quam magna, imperdiet at nunc +a, suscipit aliquam metus. Cras consequat, enim vitae feugiat venenatis, enim +urna venenatis ligula, vel cursus odio lectus id purus. Integer sit amet finibus +diam. Fusce aliquet vehicula mauris, a varius metus semper in. Cras sodales +malesuada consectetur. \ No newline at end of file diff --git a/cups/testgetdests.c b/cups/testgetdests.c new file mode 100644 index 0000000..5b90695 --- /dev/null +++ b/cups/testgetdests.c @@ -0,0 +1,45 @@ +/* + * CUPS cupsGetDests API test program for CUPS. + * + * Copyright 2017 by Apple Inc. + * + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. + */ + +/* + * Include necessary headers... + */ + +#include +#include "cups.h" +#include + + +/* + * 'main()' - Loop calling cupsGetDests. + */ + +int /* O - Exit status */ +main(void) +{ + int num_dests; /* Number of destinations */ + cups_dest_t *dests; /* Destinations */ + struct timeval start, end; /* Start and stop time */ + double secs; /* Total seconds to run cupsGetDests */ + + + for (;;) + { + gettimeofday(&start, NULL); + num_dests = cupsGetDests(&dests); + gettimeofday(&end, NULL); + secs = end.tv_sec - start.tv_sec + 0.000001 * (end.tv_usec - start.tv_usec); + + printf("Found %d printers in %.3f seconds...\n", num_dests, secs); + + cupsFreeDests(num_dests, dests); + sleep(1); + } + + return (0); +} diff --git a/cups/testhttp.c b/cups/testhttp.c index 376d71f..dfb767c 100644 --- a/cups/testhttp.c +++ b/cups/testhttp.c @@ -1,16 +1,11 @@ /* * HTTP test program for CUPS. * - * Copyright 2007-2014 by Apple Inc. - * Copyright 1997-2006 by Easy Software Products. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -120,6 +115,9 @@ static uri_test_t uri_tests[] = /* URI test data */ { HTTP_URI_STATUS_OK, "ipp://%22%23%2F%3A%3C%3E%3F%40%5B%5C%5D%5E%60%7B%7C%7D/", "ipp", "", "\"#/:<>?@[\\]^`{|}", "/", 631, 0, HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_UNKNOWN_SCHEME, "smb://server/Some%20Printer", + "smb", "", "server", "/Some Printer", 0, 0, + HTTP_URI_CODING_ALL }, /* Missing scheme */ { HTTP_URI_STATUS_MISSING_SCHEME, "/path/to/file/index.html", @@ -148,6 +146,9 @@ static uri_test_t uri_tests[] = /* URI test data */ HTTP_URI_CODING_MOST }, /* Bad scheme */ + { HTTP_URI_STATUS_BAD_SCHEME, "://server/ipp", + "", "", "", "", 0, 0, + HTTP_URI_CODING_MOST }, { HTTP_URI_STATUS_BAD_SCHEME, "bad_scheme://server/resource", "", "", "", "", 0, 0, HTTP_URI_CODING_MOST }, @@ -180,6 +181,9 @@ static uri_test_t uri_tests[] = /* URI test data */ HTTP_URI_CODING_MOST }, /* Bad resource */ + { HTTP_URI_STATUS_BAD_RESOURCE, "mailto:\r\nbla", + "mailto", "", "", "", 0, 0, + HTTP_URI_CODING_MOST }, { HTTP_URI_STATUS_BAD_RESOURCE, "http://server/index.html%", "http", "", "server", "", 80, 0, HTTP_URI_CODING_MOST }, @@ -332,6 +336,40 @@ main(int argc, /* I - Number of command-line arguments */ if (!j) puts("PASS"); +#if 0 + /* + * _httpDigest() + */ + + fputs("_httpDigest(MD5): ", stdout); + if (!_httpDigest(buffer, sizeof(buffer), "MD5", "Mufasa", "http-auth@example.org", "Circle of Life", "7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v", 1, "f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ", "auth", "GET", "/dir/index.html")) + { + failures ++; + puts("FAIL (unable to calculate hash)"); + } + else if (strcmp(buffer, "8ca523f5e9506fed4657c9700eebdbec")) + { + failures ++; + printf("FAIL (got \"%s\", expected \"8ca523f5e9506fed4657c9700eebdbec\")\n", buffer); + } + else + puts("PASS"); + + fputs("_httpDigest(SHA-256): ", stdout); + if (!_httpDigest(buffer, sizeof(buffer), "SHA-256", "Mufasa", "http-auth@example.org", "Circle of Life", "7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v", 1, "f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ", "auth", "GET", "/dir/index.html")) + { + failures ++; + puts("FAIL (unable to calculate hash)"); + } + else if (strcmp(buffer, "753927fa0e85d155564e2e272a28d1802ca10daf4496794697cf8db5856cb6c1")) + { + failures ++; + printf("FAIL (got \"%s\", expected \"753927fa0e85d155564e2e272a28d1802ca10daf4496794697cf8db5856cb6c1\")\n", buffer); + } + else + puts("PASS"); +#endif /* 0 */ + /* * httpGetHostname() */ @@ -590,6 +628,8 @@ main(int argc, /* I - Number of command-line arguments */ for (i = 1; i < argc; i ++) { + int new_auth; + if (!strcmp(argv[i], "-o")) { i ++; @@ -673,6 +713,8 @@ main(int argc, /* I - Number of command-line arguments */ printf("Checking file \"%s\"...\n", resource); + new_auth = 0; + do { if (!_cups_strcasecmp(httpGetField(http, HTTP_FIELD_CONNECTION), "close")) @@ -685,9 +727,13 @@ main(int argc, /* I - Number of command-line arguments */ } } + if (http->authstring && !strncmp(http->authstring, "Digest ", 7) && !new_auth) + _httpSetDigestAuthString(http, http->nextnonce, "HEAD", resource); + httpClearFields(http); httpSetField(http, HTTP_FIELD_AUTHORIZATION, httpGetAuthString(http)); httpSetField(http, HTTP_FIELD_ACCEPT_LANGUAGE, "en"); + if (httpHead(http, resource)) { if (httpReconnect2(http, 30000, NULL)) @@ -704,6 +750,8 @@ main(int argc, /* I - Number of command-line arguments */ while ((status = httpUpdate(http)) == HTTP_STATUS_CONTINUE); + new_auth = 0; + if (status == HTTP_STATUS_UNAUTHORIZED) { /* @@ -716,7 +764,9 @@ main(int argc, /* I - Number of command-line arguments */ * See if we can do authentication... */ - if (cupsDoAuthentication(http, "GET", resource)) + new_auth = 1; + + if (cupsDoAuthentication(http, "HEAD", resource)) { status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; break; @@ -764,6 +814,8 @@ main(int argc, /* I - Number of command-line arguments */ printf("Requesting file \"%s\" (Accept-Encoding: %s)...\n", resource, encoding ? encoding : "identity"); + new_auth = 0; + do { if (!_cups_strcasecmp(httpGetField(http, HTTP_FIELD_CONNECTION), "close")) @@ -776,6 +828,9 @@ main(int argc, /* I - Number of command-line arguments */ } } + if (http->authstring && !strncmp(http->authstring, "Digest ", 7) && !new_auth) + _httpSetDigestAuthString(http, http->nextnonce, "GET", resource); + httpClearFields(http); httpSetField(http, HTTP_FIELD_AUTHORIZATION, httpGetAuthString(http)); httpSetField(http, HTTP_FIELD_ACCEPT_LANGUAGE, "en"); @@ -797,6 +852,8 @@ main(int argc, /* I - Number of command-line arguments */ while ((status = httpUpdate(http)) == HTTP_STATUS_CONTINUE); + new_auth = 0; + if (status == HTTP_STATUS_UNAUTHORIZED) { /* @@ -809,6 +866,8 @@ main(int argc, /* I - Number of command-line arguments */ * See if we can do authentication... */ + new_auth = 1; + if (cupsDoAuthentication(http, "GET", resource)) { status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; diff --git a/cups/testi18n.c b/cups/testi18n.c index beaf236..45e1cab 100644 --- a/cups/testi18n.c +++ b/cups/testi18n.c @@ -4,13 +4,7 @@ * Copyright 2007-2014 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* diff --git a/cups/testipp.c b/cups/testipp.c index 017ee9d..aad53e4 100644 --- a/cups/testipp.c +++ b/cups/testipp.c @@ -1,16 +1,11 @@ /* * IPP test program for CUPS. * - * Copyright 2007-2014 by Apple Inc. - * Copyright 1997-2005 by Easy Software Products. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2005 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -20,12 +15,12 @@ #include "file.h" #include "string-private.h" #include "ipp-private.h" -#ifdef WIN32 +#ifdef _WIN32 # include #else # include # include -#endif /* WIN32 */ +#endif /* _WIN32 */ /* @@ -50,7 +45,7 @@ static ipp_uchar_t collection[] = /* Collection buffer */ 0x01, 0x01, /* IPP version */ 0x00, 0x02, /* Print-Job operation */ 0x00, 0x00, 0x00, 0x01, - /* Request ID */ + /* Request ID */ IPP_TAG_OPERATION, @@ -80,7 +75,7 @@ static ipp_uchar_t collection[] = /* Collection buffer */ IPP_TAG_JOB, /* job group tag */ IPP_TAG_BEGIN_COLLECTION, - /* begCollection tag */ + /* begCollection tag */ 0x00, 0x09, /* Name length + name */ 'm', 'e', 'd', 'i', 'a', '-', 'c', 'o', 'l', 0x00, 0x00, /* No value */ @@ -89,11 +84,11 @@ static ipp_uchar_t collection[] = /* Collection buffer */ 0x00, 0x0a, /* Value length + value */ 'm', 'e', 'd', 'i', 'a', '-', 's', 'i', 'z', 'e', IPP_TAG_BEGIN_COLLECTION, - /* begCollection tag */ + /* begCollection tag */ 0x00, 0x00, /* Name length + name */ 0x00, 0x00, /* No value */ IPP_TAG_MEMBERNAME, - /* memberAttrName tag */ + /* memberAttrName tag */ 0x00, 0x00, /* No name */ 0x00, 0x0b, /* Value length + value */ 'x', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n', @@ -102,7 +97,7 @@ static ipp_uchar_t collection[] = /* Collection buffer */ 0x00, 0x04, /* Value length + value */ 0x00, 0x00, 0x54, 0x56, IPP_TAG_MEMBERNAME, - /* memberAttrName tag */ + /* memberAttrName tag */ 0x00, 0x00, /* No name */ 0x00, 0x0b, /* Value length + value */ 'y', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n', @@ -111,7 +106,7 @@ static ipp_uchar_t collection[] = /* Collection buffer */ 0x00, 0x04, /* Value length + value */ 0x00, 0x00, 0x6d, 0x24, IPP_TAG_END_COLLECTION, - /* endCollection tag */ + /* endCollection tag */ 0x00, 0x00, /* No name */ 0x00, 0x00, /* No value */ IPP_TAG_MEMBERNAME, /* memberAttrName tag */ @@ -132,12 +127,12 @@ static ipp_uchar_t collection[] = /* Collection buffer */ 0x00, 0x05, /* Value length + value */ 'p', 'l', 'a', 'i', 'n', IPP_TAG_END_COLLECTION, - /* endCollection tag */ + /* endCollection tag */ 0x00, 0x00, /* No name */ 0x00, 0x00, /* No value */ IPP_TAG_BEGIN_COLLECTION, - /* begCollection tag */ + /* begCollection tag */ 0x00, 0x00, /* No name */ 0x00, 0x00, /* No value */ IPP_TAG_MEMBERNAME, /* memberAttrName tag */ @@ -145,11 +140,11 @@ static ipp_uchar_t collection[] = /* Collection buffer */ 0x00, 0x0a, /* Value length + value */ 'm', 'e', 'd', 'i', 'a', '-', 's', 'i', 'z', 'e', IPP_TAG_BEGIN_COLLECTION, - /* begCollection tag */ + /* begCollection tag */ 0x00, 0x00, /* Name length + name */ 0x00, 0x00, /* No value */ IPP_TAG_MEMBERNAME, - /* memberAttrName tag */ + /* memberAttrName tag */ 0x00, 0x00, /* No name */ 0x00, 0x0b, /* Value length + value */ 'x', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n', @@ -158,7 +153,7 @@ static ipp_uchar_t collection[] = /* Collection buffer */ 0x00, 0x04, /* Value length + value */ 0x00, 0x00, 0x52, 0x08, IPP_TAG_MEMBERNAME, - /* memberAttrName tag */ + /* memberAttrName tag */ 0x00, 0x00, /* No name */ 0x00, 0x0b, /* Value length + value */ 'y', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n', @@ -167,7 +162,7 @@ static ipp_uchar_t collection[] = /* Collection buffer */ 0x00, 0x04, /* Value length + value */ 0x00, 0x00, 0x74, 0x04, IPP_TAG_END_COLLECTION, - /* endCollection tag */ + /* endCollection tag */ 0x00, 0x00, /* No name */ 0x00, 0x00, /* No value */ IPP_TAG_MEMBERNAME, /* memberAttrName tag */ @@ -188,7 +183,72 @@ static ipp_uchar_t collection[] = /* Collection buffer */ 0x00, 0x06, /* Value length + value */ 'g', 'l', 'o', 's', 's', 'y', IPP_TAG_END_COLLECTION, - /* endCollection tag */ + /* endCollection tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x00, /* No value */ + + IPP_TAG_END /* end tag */ + }; +static ipp_uchar_t bad_collection[] = /* Collection buffer (bad encoding) */ + { + 0x01, 0x01, /* IPP version */ + 0x00, 0x02, /* Print-Job operation */ + 0x00, 0x00, 0x00, 0x01, + /* Request ID */ + + IPP_TAG_OPERATION, + + IPP_TAG_CHARSET, + 0x00, 0x12, /* Name length + name */ + 'a','t','t','r','i','b','u','t','e','s','-', + 'c','h','a','r','s','e','t', + 0x00, 0x05, /* Value length + value */ + 'u','t','f','-','8', + + IPP_TAG_LANGUAGE, + 0x00, 0x1b, /* Name length + name */ + 'a','t','t','r','i','b','u','t','e','s','-', + 'n','a','t','u','r','a','l','-','l','a','n', + 'g','u','a','g','e', + 0x00, 0x02, /* Value length + value */ + 'e','n', + + IPP_TAG_URI, + 0x00, 0x0b, /* Name length + name */ + 'p','r','i','n','t','e','r','-','u','r','i', + 0x00, 0x1c, /* Value length + value */ + 'i','p','p',':','/','/','l','o','c','a','l', + 'h','o','s','t','/','p','r','i','n','t','e', + 'r','s','/','f','o','o', + + IPP_TAG_JOB, /* job group tag */ + + IPP_TAG_BEGIN_COLLECTION, + /* begCollection tag */ + 0x00, 0x09, /* Name length + name */ + 'm', 'e', 'd', 'i', 'a', '-', 'c', 'o', 'l', + 0x00, 0x00, /* No value */ + IPP_TAG_BEGIN_COLLECTION, + /* begCollection tag */ + 0x00, 0x0a, /* Name length + name */ + 'm', 'e', 'd', 'i', 'a', '-', 's', 'i', 'z', 'e', + 0x00, 0x00, /* No value */ + IPP_TAG_INTEGER, /* integer tag */ + 0x00, 0x0b, /* Name length + name */ + 'x', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n', + 0x00, 0x04, /* Value length + value */ + 0x00, 0x00, 0x54, 0x56, + IPP_TAG_INTEGER, /* integer tag */ + 0x00, 0x0b, /* Name length + name */ + 'y', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n', + 0x00, 0x04, /* Value length + value */ + 0x00, 0x00, 0x6d, 0x24, + IPP_TAG_END_COLLECTION, + /* endCollection tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x00, /* No value */ + IPP_TAG_END_COLLECTION, + /* endCollection tag */ 0x00, 0x00, /* No name */ 0x00, 0x00, /* No value */ @@ -200,7 +260,7 @@ static ipp_uchar_t mixed[] = /* Mixed value buffer */ 0x01, 0x01, /* IPP version */ 0x00, 0x02, /* Print-Job operation */ 0x00, 0x00, 0x00, 0x01, - /* Request ID */ + /* Request ID */ IPP_TAG_OPERATION, @@ -229,6 +289,8 @@ static ipp_uchar_t mixed[] = /* Mixed value buffer */ void hex_dump(const char *title, ipp_uchar_t *buffer, size_t bytes); void print_attributes(ipp_t *ipp, int indent); ssize_t read_cb(_ippdata_t *data, ipp_uchar_t *buffer, size_t bytes); +ssize_t read_hex(cups_file_t *fp, ipp_uchar_t *buffer, size_t bytes); +int token_cb(_ipp_file_t *f, _ipp_vars_t *v, void *user_data, const char *token); ssize_t write_cb(_ippdata_t *data, ipp_uchar_t *buffer, size_t bytes); @@ -589,12 +651,33 @@ main(int argc, /* I - Number of command-line arguments */ ippDelete(request); + /* + * Read the bad collection data and confirm we get an error... + */ + + fputs("Read Bad Collection from Memory: ", stdout); + + request = ippNew(); + data.rpos = 0; + data.wused = sizeof(bad_collection); + data.wsize = sizeof(bad_collection); + data.wbuffer = bad_collection; + + while ((state = ippReadIO(&data, (ipp_iocb_t)read_cb, 1, NULL, request)) != IPP_STATE_DATA) + if (state == IPP_STATE_ERROR) + break; + + if (state != IPP_STATE_ERROR) + puts("FAIL (read successful)"); + else + puts("PASS"); + /* * Read the mixed data and confirm we converted everything to rangeOfInteger * values... */ - printf("Read Mixed integer/rangeOfInteger from Memory: "); + fputs("Read Mixed integer/rangeOfInteger from Memory: ", stdout); request = ippNew(); data.rpos = 0; @@ -712,30 +795,80 @@ main(int argc, /* I - Number of command-line arguments */ for (i = 1; i < (size_t)argc; i ++) { - if ((fp = cupsFileOpen(argv[i], "r")) == NULL) + if (strlen(argv[i]) > 5 && !strcmp(argv[i] + strlen(argv[i]) - 5, ".test")) { - printf("Unable to open \"%s\" - %s\n", argv[i], strerror(errno)); - status = 1; - continue; + /* + * Read an ASCII IPP message... + */ + + _ipp_vars_t v; /* IPP variables */ + + _ippVarsInit(&v, NULL, NULL, token_cb); + request = _ippFileParse(&v, argv[i], NULL); + _ippVarsDeinit(&v); } - - request = ippNew(); - while ((state = ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL, - request)) == IPP_STATE_ATTRIBUTE); - - if (state != IPP_STATE_DATA) + else if (strlen(argv[i]) > 4 && !strcmp(argv[i] + strlen(argv[i]) - 4, ".hex")) { - printf("Error reading IPP message from \"%s\"!\n", argv[i]); - status = 1; + /* + * Read a hex-encoded IPP message... + */ + + if ((fp = cupsFileOpen(argv[i], "r")) == NULL) + { + printf("Unable to open \"%s\" - %s\n", argv[i], strerror(errno)); + status = 1; + continue; + } + + request = ippNew(); + while ((state = ippReadIO(fp, (ipp_iocb_t)read_hex, 1, NULL, request)) == IPP_STATE_ATTRIBUTE); + + if (state != IPP_STATE_DATA) + { + printf("Error reading IPP message from \"%s\": %s\n", argv[i], cupsLastErrorString()); + status = 1; + + ippDelete(request); + request = NULL; + } + + cupsFileClose(fp); } else { - printf("\n%s:\n", argv[i]); - print_attributes(request, 4); + /* + * Read a raw (binary) IPP message... + */ + + if ((fp = cupsFileOpen(argv[i], "r")) == NULL) + { + printf("Unable to open \"%s\" - %s\n", argv[i], strerror(errno)); + status = 1; + continue; + } + + request = ippNew(); + while ((state = ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL, + request)) == IPP_STATE_ATTRIBUTE); + + if (state != IPP_STATE_DATA) + { + printf("Error reading IPP message from \"%s\": %s\n", argv[i], cupsLastErrorString()); + status = 1; + + ippDelete(request); + request = NULL; + } + + cupsFileClose(fp); } - ippDelete(request); - cupsFileClose(fp); + if (request) + { + printf("\n%s:\n", argv[i]); + print_attributes(request, 4); + ippDelete(request); + } } } @@ -810,88 +943,9 @@ void print_attributes(ipp_t *ipp, /* I - IPP request */ int indent) /* I - Indentation */ { - int i; /* Looping var */ ipp_tag_t group; /* Current group */ ipp_attribute_t *attr; /* Current attribute */ - _ipp_value_t *val; /* Current value */ - static const char * const tags[] = /* Value/group tag strings */ - { - "reserved-00", - "operation-attributes-tag", - "job-attributes-tag", - "end-of-attributes-tag", - "printer-attributes-tag", - "unsupported-attributes-tag", - "subscription-attributes-tag", - "event-attributes-tag", - "reserved-08", - "reserved-09", - "reserved-0A", - "reserved-0B", - "reserved-0C", - "reserved-0D", - "reserved-0E", - "reserved-0F", - "unsupported", - "default", - "unknown", - "no-value", - "reserved-14", - "not-settable", - "delete-attr", - "admin-define", - "reserved-18", - "reserved-19", - "reserved-1A", - "reserved-1B", - "reserved-1C", - "reserved-1D", - "reserved-1E", - "reserved-1F", - "reserved-20", - "integer", - "boolean", - "enum", - "reserved-24", - "reserved-25", - "reserved-26", - "reserved-27", - "reserved-28", - "reserved-29", - "reserved-2a", - "reserved-2b", - "reserved-2c", - "reserved-2d", - "reserved-2e", - "reserved-2f", - "octetString", - "dateTime", - "resolution", - "rangeOfInteger", - "begCollection", - "textWithLanguage", - "nameWithLanguage", - "endCollection", - "reserved-38", - "reserved-39", - "reserved-3a", - "reserved-3b", - "reserved-3c", - "reserved-3d", - "reserved-3e", - "reserved-3f", - "reserved-40", - "textWithoutLanguage", - "nameWithoutLanguage", - "reserved-43", - "keyword", - "uri", - "uriScheme", - "charset", - "naturalLanguage", - "mimeMediaType", - "memberName" - }; + char buffer[2048]; /* Value string */ for (group = IPP_TAG_ZERO, attr = ipp->attrs; attr; attr = attr->next) @@ -907,83 +961,12 @@ print_attributes(ipp_t *ipp, /* I - IPP request */ { group = attr->group_tag; - printf("\n%*s%s:\n\n", indent - 4, "", tags[group]); + printf("\n%*s%s:\n\n", indent - 4, "", ippTagString(group)); } - printf("%*s%s (", indent, "", attr->name ? attr->name : "(null)"); - if (attr->num_values > 1) - printf("1setOf "); - printf("%s):", tags[attr->value_tag]); + ippAttributeString(attr, buffer, sizeof(buffer)); - switch (attr->value_tag) - { - case IPP_TAG_ENUM : - case IPP_TAG_INTEGER : - for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) - printf(" %d", val->integer); - putchar('\n'); - break; - - case IPP_TAG_BOOLEAN : - for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) - printf(" %s", val->boolean ? "true" : "false"); - putchar('\n'); - break; - - case IPP_TAG_RANGE : - for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) - printf(" %d-%d", val->range.lower, val->range.upper); - putchar('\n'); - break; - - case IPP_TAG_DATE : - { - char vstring[256]; /* Formatted time */ - - for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) - printf(" (%s)", _cupsStrDate(vstring, sizeof(vstring), ippDateToTime(val->date))); - } - putchar('\n'); - break; - - case IPP_TAG_RESOLUTION : - for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) - printf(" %dx%d%s", val->resolution.xres, val->resolution.yres, - val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpcm"); - putchar('\n'); - break; - - case IPP_TAG_STRING : - case IPP_TAG_TEXTLANG : - case IPP_TAG_NAMELANG : - case IPP_TAG_TEXT : - case IPP_TAG_NAME : - case IPP_TAG_KEYWORD : - case IPP_TAG_URI : - case IPP_TAG_URISCHEME : - case IPP_TAG_CHARSET : - case IPP_TAG_LANGUAGE : - case IPP_TAG_MIMETYPE : - for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) - printf(" \"%s\"", val->string.text); - putchar('\n'); - break; - - case IPP_TAG_BEGIN_COLLECTION : - putchar('\n'); - - for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) - { - if (i) - putchar('\n'); - print_attributes(val->collection, indent + 4); - } - break; - - default : - printf("UNKNOWN (%d values)\n", attr->num_values); - break; - } + printf("%*s%s (%s%s): %s\n", indent, "", attr->name ? attr->name : "(null)", attr->num_values > 1 ? "1setOf " : "", ippTagString(attr->value_tag), buffer); } } @@ -1018,6 +1001,76 @@ read_cb(_ippdata_t *data, /* I - Data */ } +/* + * 'read_hex()' - Read a hex dump of an IPP request. + */ + +ssize_t /* O - Number of bytes read */ +read_hex(cups_file_t *fp, /* I - File to read from */ + ipp_uchar_t *buffer, /* I - Buffer to read */ + size_t bytes) /* I - Number of bytes to read */ +{ + size_t total = 0; /* Total bytes read */ + static char hex[256] = ""; /* Line from file */ + static char *hexptr = NULL; /* Pointer in line */ + + + while (total < bytes) + { + if (!hexptr || (isspace(hexptr[0] & 255) && isspace(hexptr[1] & 255))) + { + if (!cupsFileGets(fp, hex, sizeof(hex))) + break; + + hexptr = hex; + while (isxdigit(*hexptr & 255)) + hexptr ++; + while (isspace(*hexptr & 255)) + hexptr ++; + + if (!isxdigit(*hexptr & 255)) + { + hexptr = NULL; + continue; + } + } + + *buffer++ = (ipp_uchar_t)strtol(hexptr, &hexptr, 16); + total ++; + } + + return (total == 0 ? -1 : (ssize_t)total); +} + + +/* + * 'token_cb()' - Token callback for ASCII IPP data file parser. + */ + +int /* O - 1 on success, 0 on failure */ +token_cb(_ipp_file_t *f, /* I - IPP file data */ + _ipp_vars_t *v, /* I - IPP variables */ + void *user_data, /* I - User data pointer */ + const char *token) /* I - Token string */ +{ + (void)v; + (void)user_data; + + if (!token) + { + f->attrs = ippNew(); + f->group_tag = IPP_TAG_PRINTER; + } + else + { + fprintf(stderr, "Unknown directive \"%s\" on line %d of \"%s\".\n", token, f->linenum, f->filename); + return (0); + } + + return (1); +} + + /* * 'write_cb()' - Write data into a buffer. */ diff --git a/cups/testlang.c b/cups/testlang.c index 6aa49ab..613ae32 100644 --- a/cups/testlang.c +++ b/cups/testlang.c @@ -1,16 +1,14 @@ /* * Localization test program for CUPS. * - * Copyright 2007-2015 by Apple Inc. + * Usage: + * + * ./testlang [-l locale] [-p ppd] ["String to localize"] + * + * Copyright 2007-2017 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -19,6 +17,18 @@ #include "cups-private.h" #include "ppd-private.h" +#ifdef __APPLE__ +# include +#endif /* __APPLE__ */ + + +/* + * Local functions... + */ + +static int show_ppd(const char *filename); +static int test_string(cups_lang_t *language, const char *msgid); +static void usage(void); /* @@ -30,9 +40,12 @@ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ + const char *opt; /* Current option */ int errors = 0; /* Number of errors */ - cups_lang_t *language; /* Message catalog */ - cups_lang_t *language2; /* Message catalog */ + int dotests = 1; /* Do standard tests? */ + cups_lang_t *language = NULL;/* Message catalog */ + cups_lang_t *language2 = NULL; + /* Message catalog (second time) */ struct lconv *loc; /* Locale data */ char buffer[1024]; /* String buffer */ double number; /* Number */ @@ -45,21 +58,84 @@ main(int argc, /* I - Number of command-line arguments */ }; - if (argc == 1) + /* + * Parse command-line... + */ + + _cupsSetLocale(argv); + + for (i = 1; i < argc; i ++) + { + if (argv[i][0] == '-') + { + if (!strcmp(argv[i], "--help")) + { + usage(); + } + else + { + for (opt = argv[i] + 1; *opt; opt ++) + { + switch (*opt) + { + case 'l' : + i ++; + if (i >= argc) + { + usage(); + return (1); + } + + language = cupsLangGet(argv[i]); + language2 = cupsLangGet(argv[i]); + + setenv("LANG", argv[i], 1); + setenv("SOFTWARE", "CUPS/" CUPS_SVERSION, 1); + break; + + case 'p' : + i ++; + if (i >= argc) + { + usage(); + return (1); + } + + if (!language) + { + language = cupsLangDefault(); + language2 = cupsLangDefault(); + } + + dotests = 0; + errors += show_ppd(argv[i]); + break; + + default : + usage(); + return (1); + } + } + } + } + else + { + if (!language) + { + language = cupsLangDefault(); + language2 = cupsLangDefault(); + } + + dotests = 0; + errors += test_string(language, argv[i]); + } + } + + if (!language) { language = cupsLangDefault(); language2 = cupsLangDefault(); } - else - { - language = cupsLangGet(argv[1]); - language2 = cupsLangGet(argv[1]); - - setenv("LANG", argv[1], 1); - setenv("SOFTWARE", "CUPS/" CUPS_SVERSION, 1); - } - - _cupsSetLocale(argv); if (language != language2) { @@ -71,76 +147,228 @@ main(int argc, /* I - Number of command-line arguments */ printf("Language = \"%s\"\n", language->language); printf("Encoding = \"%s\"\n", _cupsEncodingName(language->encoding)); - printf("No = \"%s\"\n", _cupsLangString(language, "No")); - printf("Yes = \"%s\"\n", _cupsLangString(language, "Yes")); - if (language != language2) + if (dotests) { - puts("Second result from cupsLangGet:"); + errors += test_string(language, "No"); + errors += test_string(language, "Yes"); - printf("Language = \"%s\"\n", language2->language); - printf("Encoding = \"%s\"\n", _cupsEncodingName(language2->encoding)); - printf("No = \"%s\"\n", _cupsLangString(language2, "No")); - printf("Yes = \"%s\"\n", _cupsLangString(language2, "Yes")); - } - - loc = localeconv(); - - for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i ++) - { - number = _cupsStrScand(tests[i], NULL, loc); - - printf("_cupsStrScand(\"%s\") number=%f\n", tests[i], number); - - _cupsStrFormatd(buffer, buffer + sizeof(buffer), number, loc); - - printf("_cupsStrFormatd(%f) buffer=\"%s\"\n", number, buffer); - - if (strcmp(buffer, tests[i])) + if (language != language2) { - errors ++; - puts("**** ERROR: Bad formatted number! ****"); + puts("Second result from cupsLangGet:"); + + printf("Language = \"%s\"\n", language2->language); + printf("Encoding = \"%s\"\n", _cupsEncodingName(language2->encoding)); + printf("No = \"%s\"\n", _cupsLangString(language2, "No")); + printf("Yes = \"%s\"\n", _cupsLangString(language2, "Yes")); } - } - if (argc == 3) - { - ppd_file_t *ppd; /* PPD file */ - ppd_option_t *option; /* PageSize option */ - ppd_choice_t *choice; /* PageSize/Letter choice */ + loc = localeconv(); - if ((ppd = ppdOpenFile(argv[2])) == NULL) + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i ++) { - printf("Unable to open PPD file \"%s\".\n", argv[2]); - errors ++; - } - else - { - ppdLocalize(ppd); + number = _cupsStrScand(tests[i], NULL, loc); - if ((option = ppdFindOption(ppd, "PageSize")) == NULL) + printf("_cupsStrScand(\"%s\") number=%f\n", tests[i], number); + + _cupsStrFormatd(buffer, buffer + sizeof(buffer), number, loc); + + printf("_cupsStrFormatd(%f) buffer=\"%s\"\n", number, buffer); + + if (strcmp(buffer, tests[i])) { - puts("No PageSize option."); + errors ++; + puts("**** ERROR: Bad formatted number! ****"); + } + } + +#ifdef __APPLE__ + /* + * Test all possible language IDs for compatibility with _cupsAppleLocale... + */ + + CFIndex j, /* Looping var */ + num_locales; /* Number of locales */ + CFArrayRef locales; /* Locales */ + CFStringRef locale_id, /* Current locale ID */ + language_id; /* Current language ID */ + char locale_str[256], /* Locale ID C string */ + language_str[256], /* Language ID C string */ + *bufptr; /* Pointer to ".UTF-8" in POSIX locale */ + size_t buflen; /* Length of POSIX locale */ +# if TEST_COUNTRY_CODES + CFIndex k, /* Looping var */ + num_country_codes; /* Number of country codes */ + CFArrayRef country_codes; /* Country codes */ + CFStringRef country_code, /* Current country code */ + temp_id; /* Temporary language ID */ + char country_str[256]; /* Country code C string */ +# endif /* TEST_COUNTRY_CODES */ + + locales = CFLocaleCopyAvailableLocaleIdentifiers(); + num_locales = CFArrayGetCount(locales); + +# if TEST_COUNTRY_CODES + country_codes = CFLocaleCopyISOCountryCodes(); + num_country_codes = CFArrayGetCount(country_codes); +# endif /* TEST_COUNTRY_CODES */ + + printf("%d locales are available:\n", (int)num_locales); + + for (j = 0; j < num_locales; j ++) + { + locale_id = CFArrayGetValueAtIndex(locales, j); + language_id = CFLocaleCreateCanonicalLanguageIdentifierFromString(kCFAllocatorDefault, locale_id); + + if (!locale_id || !CFStringGetCString(locale_id, locale_str, (CFIndex)sizeof(locale_str), kCFStringEncodingASCII)) + { + printf("%d: FAIL (unable to get locale ID string)\n", (int)j + 1); errors ++; + continue; } - else + + if (!language_id || !CFStringGetCString(language_id, language_str, (CFIndex)sizeof(language_str), kCFStringEncodingASCII)) { - printf("PageSize: %s\n", option->text); - - if ((choice = ppdFindChoice(option, "Letter")) == NULL) - { - puts("No Letter PageSize choice."); - errors ++; - } - else - { - printf("Letter: %s\n", choice->text); - } + printf("%d %s: FAIL (unable to get language ID string)\n", (int)j + 1, locale_str); + errors ++; + continue; } - ppdClose(ppd); + if (!_cupsAppleLocale(language_id, buffer, sizeof(buffer))) + { + printf("%d %s(%s): FAIL (unable to convert language ID string to POSIX locale)\n", (int)j + 1, locale_str, language_str); + errors ++; + continue; + } + + if ((bufptr = strstr(buffer, ".UTF-8")) != NULL) + buflen = (size_t)(bufptr - buffer); + else + buflen = strlen(buffer); + + if ((language = cupsLangGet(buffer)) == NULL) + { + printf("%d %s(%s): FAIL (unable to load POSIX locale \"%s\")\n", (int)j + 1, locale_str, language_str, buffer); + errors ++; + continue; + } + + if (strncasecmp(language->language, buffer, buflen)) + { + printf("%d %s(%s): FAIL (unable to load POSIX locale \"%s\", got \"%s\")\n", (int)j + 1, locale_str, language_str, buffer, language->language); + errors ++; + continue; + } + + printf("%d %s(%s): PASS (POSIX locale is \"%s\")\n", (int)j + 1, locale_str, language_str, buffer); } + + CFRelease(locales); + +# if TEST_COUNTRY_CODES + CFRelease(country_codes); +# endif /* TEST_COUNTRY_CODES */ +#endif /* __APPLE__ */ } + if (errors == 0 && dotests) + puts("ALL TESTS PASSED"); + return (errors > 0); } + + +/* + * 'show_ppd()' - Show localized strings in a PPD file. + */ + +static int /* O - Number of errors */ +show_ppd(const char *filename) /* I - Filename */ +{ + ppd_file_t *ppd; /* PPD file */ + ppd_option_t *option; /* PageSize option */ + ppd_choice_t *choice; /* PageSize/Letter choice */ + char buffer[1024]; /* String buffer */ + + + if ((ppd = ppdOpenFile(filename)) == NULL) + { + printf("Unable to open PPD file \"%s\".\n", filename); + return (1); + } + + ppdLocalize(ppd); + + if ((option = ppdFindOption(ppd, "PageSize")) == NULL) + { + puts("No PageSize option."); + return (1); + } + else + { + printf("PageSize: %s\n", option->text); + + if ((choice = ppdFindChoice(option, "Letter")) == NULL) + { + puts("No Letter PageSize choice."); + return (1); + } + else + { + printf("Letter: %s\n", choice->text); + } + } + + printf("media-empty: %s\n", ppdLocalizeIPPReason(ppd, "media-empty", NULL, buffer, sizeof(buffer))); + + ppdClose(ppd); + + return (0); +} + + +/* + * 'test_string()' - Test the localization of a string. + */ + +static int /* O - 1 on failure, 0 on success */ +test_string(cups_lang_t *language, /* I - Language */ + const char *msgid) /* I - Message */ +{ + const char *msgstr; /* Localized string */ + + + /* + * Get the localized string and then see if we got what we expected. + * + * For the POSIX locale, the string pointers should be the same. + * For any other locale, the string pointers should be different. + */ + + msgstr = _cupsLangString(language, msgid); + if (strcmp(language->language, "C") && msgid == msgstr) + { + printf("%-8s = \"%s\" (FAIL - no message catalog loaded)\n", msgid, msgstr); + return (1); + } + else if (!strcmp(language->language, "C") && msgid != msgstr) + { + printf("%-8s = \"%s\" (FAIL - POSIX locale is localized)\n", msgid, msgstr); + return (1); + } + + printf("%-8s = \"%s\" (PASS)\n", msgid, msgstr); + + return (0); +} + + +/* + * 'usage()' - Show program usage. + */ + +static void +usage(void) +{ + puts("./testlang [-l locale] [-p ppd] [\"String to localize\"]"); +} diff --git a/cups/testoptions.c b/cups/testoptions.c index f5ce2e2..1cc2f74 100644 --- a/cups/testoptions.c +++ b/cups/testoptions.c @@ -3,13 +3,7 @@ * * Copyright 2008-2016 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* diff --git a/cups/testppd.c b/cups/testppd.c index e1b5156..36707f2 100644 --- a/cups/testppd.c +++ b/cups/testppd.c @@ -1,16 +1,11 @@ /* * PPD test program for CUPS. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2006 by Easy Software Products. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -20,20 +15,180 @@ #undef _CUPS_NO_DEPRECATED #include "cups-private.h" #include "ppd-private.h" +#include "raster-private.h" #include -#ifdef WIN32 +#ifdef _WIN32 # include #else # include # include -#endif /* WIN32 */ +#endif /* _WIN32 */ #include +/* + * Local functions... + */ + +static int do_ppd_tests(const char *filename, int num_options, cups_option_t *options); +static int do_ps_tests(void); +static void print_changes(cups_page_header2_t *header, cups_page_header2_t *expected); + + /* * Test data... */ +static const char *dsc_code = +"[{\n" +"%%BeginFeature: *PageSize Tabloid\n" +"<>setpagedevice\n" +"%%EndFeature\n" +"} stopped cleartomark\n"; +static const char *setpagedevice_code = +"<<" +"/MediaClass(Media Class)" +"/MediaColor((Media Color))" +"/MediaType(Media\\\\Type)" +"/OutputType<416263>" +"/AdvanceDistance 1000" +"/AdvanceMedia 1" +"/Collate false" +"/CutMedia 2" +"/Duplex true" +"/HWResolution[100 200]" +"/InsertSheet true" +"/Jog 3" +"/LeadingEdge 1" +"/ManualFeed true" +"/MediaPosition 8#777" +"/MediaWeight 16#fe01" +"/MirrorPrint true" +"/NegativePrint true" +"/NumCopies 1" +"/Orientation 1" +"/OutputFaceUp true" +"/PageSize[612 792.1]" +"/Separations true" +"/TraySwitch true" +"/Tumble true" +"/cupsMediaType 2" +"/cupsColorOrder 1" +"/cupsColorSpace 1" +"/cupsCompression 1" +"/cupsRowCount 1" +"/cupsRowFeed 1" +"/cupsRowStep 1" +"/cupsBorderlessScalingFactor 1.001" +"/cupsInteger0 1" +"/cupsInteger1 2" +"/cupsInteger2 3" +"/cupsInteger3 4" +"/cupsInteger4 5" +"/cupsInteger5 6" +"/cupsInteger6 7" +"/cupsInteger7 8" +"/cupsInteger8 9" +"/cupsInteger9 10" +"/cupsInteger10 11" +"/cupsInteger11 12" +"/cupsInteger12 13" +"/cupsInteger13 14" +"/cupsInteger14 15" +"/cupsInteger15 16" +"/cupsReal0 1.1" +"/cupsReal1 2.1" +"/cupsReal2 3.1" +"/cupsReal3 4.1" +"/cupsReal4 5.1" +"/cupsReal5 6.1" +"/cupsReal6 7.1" +"/cupsReal7 8.1" +"/cupsReal8 9.1" +"/cupsReal9 10.1" +"/cupsReal10 11.1" +"/cupsReal11 12.1" +"/cupsReal12 13.1" +"/cupsReal13 14.1" +"/cupsReal14 15.1" +"/cupsReal15 16.1" +"/cupsString0(1)" +"/cupsString1(2)" +"/cupsString2(3)" +"/cupsString3(4)" +"/cupsString4(5)" +"/cupsString5(6)" +"/cupsString6(7)" +"/cupsString7(8)" +"/cupsString8(9)" +"/cupsString9(10)" +"/cupsString10(11)" +"/cupsString11(12)" +"/cupsString12(13)" +"/cupsString13(14)" +"/cupsString14(15)" +"/cupsString15(16)" +"/cupsMarkerType(Marker Type)" +"/cupsRenderingIntent(Rendering Intent)" +"/cupsPageSizeName(Letter)" +"/cupsPreferredBitsPerColor 17" +">> setpagedevice"; + +static cups_page_header2_t setpagedevice_header = +{ + "Media Class", /* MediaClass */ + "(Media Color)", /* MediaColor */ + "Media\\Type", /* MediaType */ + "Abc", /* OutputType */ + 1000, /* AdvanceDistance */ + CUPS_ADVANCE_FILE, /* AdvanceMedia */ + CUPS_FALSE, /* Collate */ + CUPS_CUT_JOB, /* CutMedia */ + CUPS_TRUE, /* Duplex */ + { 100, 200 }, /* HWResolution */ + { 0, 0, 0, 0 }, /* ImagingBoundingBox */ + CUPS_TRUE, /* InsertSheet */ + CUPS_JOG_SET, /* Jog */ + CUPS_EDGE_RIGHT, /* LeadingEdge */ + { 0, 0 }, /* Margins */ + CUPS_TRUE, /* ManualFeed */ + 0777, /* MediaPosition */ + 0xfe01, /* MediaWeight */ + CUPS_TRUE, /* MirrorPrint */ + CUPS_TRUE, /* NegativePrint */ + 1, /* NumCopies */ + CUPS_ORIENT_90, /* Orientation */ + CUPS_TRUE, /* OutputFaceUp */ + { 612, 792 }, /* PageSize */ + CUPS_TRUE, /* Separations */ + CUPS_TRUE, /* TraySwitch */ + CUPS_TRUE, /* Tumble */ + 0, /* cupsWidth */ + 0, /* cupsHeight */ + 2, /* cupsMediaType */ + 0, /* cupsBitsPerColor */ + 0, /* cupsBitsPerPixel */ + 0, /* cupsBytesPerLine */ + CUPS_ORDER_BANDED, /* cupsColorOrder */ + CUPS_CSPACE_RGB, /* cupsColorSpace */ + 1, /* cupsCompression */ + 1, /* cupsRowCount */ + 1, /* cupsRowFeed */ + 1, /* cupsRowStep */ + 0, /* cupsNumColors */ + 1.001f, /* cupsBorderlessScalingFactor */ + { 612.0f, 792.1f }, /* cupsPageSize */ + { 0.0f, 0.0f, 0.0f, 0.0f }, /* cupsImagingBBox */ + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, + /* cupsInteger[16] */ + { 1.1f, 2.1f, 3.1f, 4.1f, 5.1f, 6.1f, 7.1f, 8.1f, 9.1f, 10.1f, 11.1f, 12.1f, 13.1f, 14.1f, 15.1f, 16.1f }, /* cupsReal[16] */ + { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", + "14", "15", "16" }, /* cupsString[16] */ + "Marker Type", /* cupsMarkerType */ + "Rendering Intent", /* cupsRenderingIntent */ + "Letter" /* cupsPageSizeName */ +}; + static const char *default_code = "[{\n" "%%BeginFeature: *InstalledDuplexer False\n" @@ -144,7 +299,7 @@ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ - ppd_file_t *ppd; /* PPD file loaded from disk */ + ppd_file_t *ppd = NULL; /* PPD file loaded from disk */ int status; /* Status of tests (0 = success, 1 = fail) */ int conflicts; /* Number of conflicts */ char *s; /* String */ @@ -861,6 +1016,42 @@ main(int argc, /* I - Number of command-line arguments */ puts("FAIL (returned 0)"); status ++; } + + status += do_ps_tests(); + } + else if (!strcmp(argv[1], "--raster")) + { + for (status = 0, num_options = 0, options = NULL, i = 1; i < argc; i ++) + { + if (argv[i][0] == '-') + { + if (argv[i][1] == 'o') + { + if (argv[i][2]) + num_options = cupsParseOptions(argv[i] + 2, num_options, &options); + else + { + i ++; + if (i < argc) + num_options = cupsParseOptions(argv[i], num_options, &options); + else + { + puts("Usage: testppd --raster [-o name=value ...] [filename.ppd ...]"); + return (1); + } + } + } + else + { + puts("Usage: testppd --raster [-o name=value ...] [filename.ppd ...]"); + return (1); + } + } + else + status += do_ppd_tests(argv[i], num_options, options); + } + + cupsFreeOptions(num_options, options); } else if (!strncmp(argv[1], "ipp://", 6) || !strncmp(argv[1], "ipps://", 7)) { @@ -876,6 +1067,13 @@ main(int argc, /* I - Number of command-line arguments */ host[256], /* Hostname */ resource[256]; /* Resource path */ int port; /* Port number */ + static const char * const pattrs[] =/* Requested printer attributes */ + { + "job-template", + "printer-defaults", + "printer-description", + "media-col-database" + }; if (httpSeparateURI(HTTP_URI_CODING_ALL, argv[1], scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK) { @@ -892,6 +1090,7 @@ main(int argc, /* I - Number of command-line arguments */ request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, argv[1]); + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]), NULL, pattrs); response = cupsDoRequest(http, request, resource); if (_ppdCreateFromIPP(buffer, sizeof(buffer), response)) @@ -1046,6 +1245,10 @@ main(int argc, /* I - Number of command-line arguments */ { switch (cparam->type) { + case PPD_CUSTOM_UNKNOWN : + printf(" %s(%s): PPD_CUSTOM_UNKNOWN (error)\n", cparam->name, cparam->text); + break; + case PPD_CUSTOM_CURVE : printf(" %s(%s): PPD_CUSTOM_CURVE (%g to %g)\n", cparam->name, cparam->text, @@ -1166,3 +1369,418 @@ main(int argc, /* I - Number of command-line arguments */ return (status); } + + +/* + * 'do_ppd_tests()' - Test the default option commands in a PPD file. + */ + +static int /* O - Number of errors */ +do_ppd_tests(const char *filename, /* I - PPD file */ + int num_options, /* I - Number of options */ + cups_option_t *options) /* I - Options */ +{ + ppd_file_t *ppd; /* PPD file data */ + cups_page_header2_t header; /* Page header */ + + + printf("\"%s\": ", filename); + fflush(stdout); + + if ((ppd = ppdOpenFile(filename)) == NULL) + { + ppd_status_t status; /* Status from PPD loader */ + int line; /* Line number containing error */ + + + status = ppdLastError(&line); + + puts("FAIL (bad PPD file)"); + printf(" %s on line %d\n", ppdErrorString(status), line); + + return (1); + } + + ppdMarkDefaults(ppd); + cupsMarkOptions(ppd, num_options, options); + + if (cupsRasterInterpretPPD(&header, ppd, 0, NULL, NULL)) + { + puts("FAIL (error from function)"); + puts(cupsRasterErrorString()); + + return (1); + } + else + { + puts("PASS"); + + return (0); + } +} + + +/* + * 'do_ps_tests()' - Test standard PostScript commands. + */ + +static int +do_ps_tests(void) +{ + cups_page_header2_t header; /* Page header */ + int preferred_bits; /* Preferred bits */ + int errors = 0; /* Number of errors */ + + + /* + * Test PS exec code... + */ + + fputs("_cupsRasterExecPS(\"setpagedevice\"): ", stdout); + fflush(stdout); + + memset(&header, 0, sizeof(header)); + header.Collate = CUPS_TRUE; + preferred_bits = 0; + + if (_cupsRasterExecPS(&header, &preferred_bits, setpagedevice_code)) + { + puts("FAIL (error from function)"); + puts(cupsRasterErrorString()); + errors ++; + } + else if (preferred_bits != 17 || + memcmp(&header, &setpagedevice_header, sizeof(header))) + { + puts("FAIL (bad header)"); + + if (preferred_bits != 17) + printf(" cupsPreferredBitsPerColor %d, expected 17\n", + preferred_bits); + + print_changes(&setpagedevice_header, &header); + errors ++; + } + else + puts("PASS"); + + fputs("_cupsRasterExecPS(\"roll\"): ", stdout); + fflush(stdout); + + if (_cupsRasterExecPS(&header, &preferred_bits, + "792 612 0 0 0\n" + "pop pop pop\n" + "<>" + "setpagedevice\n")) + { + puts("FAIL (error from function)"); + puts(cupsRasterErrorString()); + errors ++; + } + else if (header.PageSize[0] != 792 || header.PageSize[1] != 612) + { + printf("FAIL (PageSize [%d %d], expected [792 612])\n", header.PageSize[0], + header.PageSize[1]); + errors ++; + } + else + puts("PASS"); + + fputs("_cupsRasterExecPS(\"dup index\"): ", stdout); + fflush(stdout); + + if (_cupsRasterExecPS(&header, &preferred_bits, + "true false dup\n" + "<>setpagedevice\n" + "pop pop pop")) + { + puts("FAIL (error from function)"); + puts(cupsRasterErrorString()); + errors ++; + } + else + { + if (!header.Collate) + { + printf("FAIL (Collate false, expected true)\n"); + errors ++; + } + + if (header.Duplex) + { + printf("FAIL (Duplex true, expected false)\n"); + errors ++; + } + + if (header.Tumble) + { + printf("FAIL (Tumble true, expected false)\n"); + errors ++; + } + + if(header.Collate && !header.Duplex && !header.Tumble) + puts("PASS"); + } + + fputs("_cupsRasterExecPS(\"%%Begin/EndFeature code\"): ", stdout); + fflush(stdout); + + if (_cupsRasterExecPS(&header, &preferred_bits, dsc_code)) + { + puts("FAIL (error from function)"); + puts(cupsRasterErrorString()); + errors ++; + } + else if (header.PageSize[0] != 792 || header.PageSize[1] != 1224) + { + printf("FAIL (bad PageSize [%d %d], expected [792 1224])\n", + header.PageSize[0], header.PageSize[1]); + errors ++; + } + else + puts("PASS"); + + return (errors); +} + + + + +/* + * 'print_changes()' - Print differences in the page header. + */ + +static void +print_changes( + cups_page_header2_t *header, /* I - Actual page header */ + cups_page_header2_t *expected) /* I - Expected page header */ +{ + int i; /* Looping var */ + + + if (strcmp(header->MediaClass, expected->MediaClass)) + printf(" MediaClass (%s), expected (%s)\n", header->MediaClass, + expected->MediaClass); + + if (strcmp(header->MediaColor, expected->MediaColor)) + printf(" MediaColor (%s), expected (%s)\n", header->MediaColor, + expected->MediaColor); + + if (strcmp(header->MediaType, expected->MediaType)) + printf(" MediaType (%s), expected (%s)\n", header->MediaType, + expected->MediaType); + + if (strcmp(header->OutputType, expected->OutputType)) + printf(" OutputType (%s), expected (%s)\n", header->OutputType, + expected->OutputType); + + if (header->AdvanceDistance != expected->AdvanceDistance) + printf(" AdvanceDistance %d, expected %d\n", header->AdvanceDistance, + expected->AdvanceDistance); + + if (header->AdvanceMedia != expected->AdvanceMedia) + printf(" AdvanceMedia %d, expected %d\n", header->AdvanceMedia, + expected->AdvanceMedia); + + if (header->Collate != expected->Collate) + printf(" Collate %d, expected %d\n", header->Collate, + expected->Collate); + + if (header->CutMedia != expected->CutMedia) + printf(" CutMedia %d, expected %d\n", header->CutMedia, + expected->CutMedia); + + if (header->Duplex != expected->Duplex) + printf(" Duplex %d, expected %d\n", header->Duplex, + expected->Duplex); + + if (header->HWResolution[0] != expected->HWResolution[0] || + header->HWResolution[1] != expected->HWResolution[1]) + printf(" HWResolution [%d %d], expected [%d %d]\n", + header->HWResolution[0], header->HWResolution[1], + expected->HWResolution[0], expected->HWResolution[1]); + + if (memcmp(header->ImagingBoundingBox, expected->ImagingBoundingBox, + sizeof(header->ImagingBoundingBox))) + printf(" ImagingBoundingBox [%d %d %d %d], expected [%d %d %d %d]\n", + header->ImagingBoundingBox[0], + header->ImagingBoundingBox[1], + header->ImagingBoundingBox[2], + header->ImagingBoundingBox[3], + expected->ImagingBoundingBox[0], + expected->ImagingBoundingBox[1], + expected->ImagingBoundingBox[2], + expected->ImagingBoundingBox[3]); + + if (header->InsertSheet != expected->InsertSheet) + printf(" InsertSheet %d, expected %d\n", header->InsertSheet, + expected->InsertSheet); + + if (header->Jog != expected->Jog) + printf(" Jog %d, expected %d\n", header->Jog, + expected->Jog); + + if (header->LeadingEdge != expected->LeadingEdge) + printf(" LeadingEdge %d, expected %d\n", header->LeadingEdge, + expected->LeadingEdge); + + if (header->Margins[0] != expected->Margins[0] || + header->Margins[1] != expected->Margins[1]) + printf(" Margins [%d %d], expected [%d %d]\n", + header->Margins[0], header->Margins[1], + expected->Margins[0], expected->Margins[1]); + + if (header->ManualFeed != expected->ManualFeed) + printf(" ManualFeed %d, expected %d\n", header->ManualFeed, + expected->ManualFeed); + + if (header->MediaPosition != expected->MediaPosition) + printf(" MediaPosition %d, expected %d\n", header->MediaPosition, + expected->MediaPosition); + + if (header->MediaWeight != expected->MediaWeight) + printf(" MediaWeight %d, expected %d\n", header->MediaWeight, + expected->MediaWeight); + + if (header->MirrorPrint != expected->MirrorPrint) + printf(" MirrorPrint %d, expected %d\n", header->MirrorPrint, + expected->MirrorPrint); + + if (header->NegativePrint != expected->NegativePrint) + printf(" NegativePrint %d, expected %d\n", header->NegativePrint, + expected->NegativePrint); + + if (header->NumCopies != expected->NumCopies) + printf(" NumCopies %d, expected %d\n", header->NumCopies, + expected->NumCopies); + + if (header->Orientation != expected->Orientation) + printf(" Orientation %d, expected %d\n", header->Orientation, + expected->Orientation); + + if (header->OutputFaceUp != expected->OutputFaceUp) + printf(" OutputFaceUp %d, expected %d\n", header->OutputFaceUp, + expected->OutputFaceUp); + + if (header->PageSize[0] != expected->PageSize[0] || + header->PageSize[1] != expected->PageSize[1]) + printf(" PageSize [%d %d], expected [%d %d]\n", + header->PageSize[0], header->PageSize[1], + expected->PageSize[0], expected->PageSize[1]); + + if (header->Separations != expected->Separations) + printf(" Separations %d, expected %d\n", header->Separations, + expected->Separations); + + if (header->TraySwitch != expected->TraySwitch) + printf(" TraySwitch %d, expected %d\n", header->TraySwitch, + expected->TraySwitch); + + if (header->Tumble != expected->Tumble) + printf(" Tumble %d, expected %d\n", header->Tumble, + expected->Tumble); + + if (header->cupsWidth != expected->cupsWidth) + printf(" cupsWidth %d, expected %d\n", header->cupsWidth, + expected->cupsWidth); + + if (header->cupsHeight != expected->cupsHeight) + printf(" cupsHeight %d, expected %d\n", header->cupsHeight, + expected->cupsHeight); + + if (header->cupsMediaType != expected->cupsMediaType) + printf(" cupsMediaType %d, expected %d\n", header->cupsMediaType, + expected->cupsMediaType); + + if (header->cupsBitsPerColor != expected->cupsBitsPerColor) + printf(" cupsBitsPerColor %d, expected %d\n", header->cupsBitsPerColor, + expected->cupsBitsPerColor); + + if (header->cupsBitsPerPixel != expected->cupsBitsPerPixel) + printf(" cupsBitsPerPixel %d, expected %d\n", header->cupsBitsPerPixel, + expected->cupsBitsPerPixel); + + if (header->cupsBytesPerLine != expected->cupsBytesPerLine) + printf(" cupsBytesPerLine %d, expected %d\n", header->cupsBytesPerLine, + expected->cupsBytesPerLine); + + if (header->cupsColorOrder != expected->cupsColorOrder) + printf(" cupsColorOrder %d, expected %d\n", header->cupsColorOrder, + expected->cupsColorOrder); + + if (header->cupsColorSpace != expected->cupsColorSpace) + printf(" cupsColorSpace %s, expected %s\n", _cupsRasterColorSpaceString(header->cupsColorSpace), + _cupsRasterColorSpaceString(expected->cupsColorSpace)); + + if (header->cupsCompression != expected->cupsCompression) + printf(" cupsCompression %d, expected %d\n", header->cupsCompression, + expected->cupsCompression); + + if (header->cupsRowCount != expected->cupsRowCount) + printf(" cupsRowCount %d, expected %d\n", header->cupsRowCount, + expected->cupsRowCount); + + if (header->cupsRowFeed != expected->cupsRowFeed) + printf(" cupsRowFeed %d, expected %d\n", header->cupsRowFeed, + expected->cupsRowFeed); + + if (header->cupsRowStep != expected->cupsRowStep) + printf(" cupsRowStep %d, expected %d\n", header->cupsRowStep, + expected->cupsRowStep); + + if (header->cupsNumColors != expected->cupsNumColors) + printf(" cupsNumColors %d, expected %d\n", header->cupsNumColors, + expected->cupsNumColors); + + if (fabs(header->cupsBorderlessScalingFactor - expected->cupsBorderlessScalingFactor) > 0.001) + printf(" cupsBorderlessScalingFactor %g, expected %g\n", + header->cupsBorderlessScalingFactor, + expected->cupsBorderlessScalingFactor); + + if (fabs(header->cupsPageSize[0] - expected->cupsPageSize[0]) > 0.001 || + fabs(header->cupsPageSize[1] - expected->cupsPageSize[1]) > 0.001) + printf(" cupsPageSize [%g %g], expected [%g %g]\n", + header->cupsPageSize[0], header->cupsPageSize[1], + expected->cupsPageSize[0], expected->cupsPageSize[1]); + + if (fabs(header->cupsImagingBBox[0] - expected->cupsImagingBBox[0]) > 0.001 || + fabs(header->cupsImagingBBox[1] - expected->cupsImagingBBox[1]) > 0.001 || + fabs(header->cupsImagingBBox[2] - expected->cupsImagingBBox[2]) > 0.001 || + fabs(header->cupsImagingBBox[3] - expected->cupsImagingBBox[3]) > 0.001) + printf(" cupsImagingBBox [%g %g %g %g], expected [%g %g %g %g]\n", + header->cupsImagingBBox[0], header->cupsImagingBBox[1], + header->cupsImagingBBox[2], header->cupsImagingBBox[3], + expected->cupsImagingBBox[0], expected->cupsImagingBBox[1], + expected->cupsImagingBBox[2], expected->cupsImagingBBox[3]); + + for (i = 0; i < 16; i ++) + if (header->cupsInteger[i] != expected->cupsInteger[i]) + printf(" cupsInteger%d %d, expected %d\n", i, header->cupsInteger[i], + expected->cupsInteger[i]); + + for (i = 0; i < 16; i ++) + if (fabs(header->cupsReal[i] - expected->cupsReal[i]) > 0.001) + printf(" cupsReal%d %g, expected %g\n", i, header->cupsReal[i], + expected->cupsReal[i]); + + for (i = 0; i < 16; i ++) + if (strcmp(header->cupsString[i], expected->cupsString[i])) + printf(" cupsString%d (%s), expected (%s)\n", i, + header->cupsString[i], expected->cupsString[i]); + + if (strcmp(header->cupsMarkerType, expected->cupsMarkerType)) + printf(" cupsMarkerType (%s), expected (%s)\n", header->cupsMarkerType, + expected->cupsMarkerType); + + if (strcmp(header->cupsRenderingIntent, expected->cupsRenderingIntent)) + printf(" cupsRenderingIntent (%s), expected (%s)\n", + header->cupsRenderingIntent, + expected->cupsRenderingIntent); + + if (strcmp(header->cupsPageSizeName, expected->cupsPageSizeName)) + printf(" cupsPageSizeName (%s), expected (%s)\n", + header->cupsPageSizeName, + expected->cupsPageSizeName); +} diff --git a/cups/testpwg.c b/cups/testpwg.c index d2332c2..6473c8c 100644 --- a/cups/testpwg.c +++ b/cups/testpwg.c @@ -3,13 +3,7 @@ * * Copyright 2009-2016 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* diff --git a/filter/testraster.c b/cups/testraster.c similarity index 65% rename from filter/testraster.c rename to cups/testraster.c index d5d63de..d3dab4b 100644 --- a/filter/testraster.c +++ b/cups/testraster.c @@ -1,16 +1,11 @@ /* * Raster test program routines for CUPS. * - * Copyright 2007-2016 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -18,172 +13,13 @@ */ #include -#include #include -/* - * Test PS commands and header... - */ - -static const char *dsc_code = -"[{\n" -"%%BeginFeature: *PageSize Tabloid\n" -"<>setpagedevice\n" -"%%EndFeature\n" -"} stopped cleartomark\n"; -static const char *setpagedevice_code = -"<<" -"/MediaClass(Media Class)" -"/MediaColor((Media Color))" -"/MediaType(Media\\\\Type)" -"/OutputType<416263>" -"/AdvanceDistance 1000" -"/AdvanceMedia 1" -"/Collate false" -"/CutMedia 2" -"/Duplex true" -"/HWResolution[100 200]" -"/InsertSheet true" -"/Jog 3" -"/LeadingEdge 1" -"/ManualFeed true" -"/MediaPosition 8#777" -"/MediaWeight 16#fe01" -"/MirrorPrint true" -"/NegativePrint true" -"/NumCopies 1" -"/Orientation 1" -"/OutputFaceUp true" -"/PageSize[612 792.1]" -"/Separations true" -"/TraySwitch true" -"/Tumble true" -"/cupsMediaType 2" -"/cupsColorOrder 1" -"/cupsColorSpace 1" -"/cupsCompression 1" -"/cupsRowCount 1" -"/cupsRowFeed 1" -"/cupsRowStep 1" -"/cupsBorderlessScalingFactor 1.001" -"/cupsInteger0 1" -"/cupsInteger1 2" -"/cupsInteger2 3" -"/cupsInteger3 4" -"/cupsInteger4 5" -"/cupsInteger5 6" -"/cupsInteger6 7" -"/cupsInteger7 8" -"/cupsInteger8 9" -"/cupsInteger9 10" -"/cupsInteger10 11" -"/cupsInteger11 12" -"/cupsInteger12 13" -"/cupsInteger13 14" -"/cupsInteger14 15" -"/cupsInteger15 16" -"/cupsReal0 1.1" -"/cupsReal1 2.1" -"/cupsReal2 3.1" -"/cupsReal3 4.1" -"/cupsReal4 5.1" -"/cupsReal5 6.1" -"/cupsReal6 7.1" -"/cupsReal7 8.1" -"/cupsReal8 9.1" -"/cupsReal9 10.1" -"/cupsReal10 11.1" -"/cupsReal11 12.1" -"/cupsReal12 13.1" -"/cupsReal13 14.1" -"/cupsReal14 15.1" -"/cupsReal15 16.1" -"/cupsString0(1)" -"/cupsString1(2)" -"/cupsString2(3)" -"/cupsString3(4)" -"/cupsString4(5)" -"/cupsString5(6)" -"/cupsString6(7)" -"/cupsString7(8)" -"/cupsString8(9)" -"/cupsString9(10)" -"/cupsString10(11)" -"/cupsString11(12)" -"/cupsString12(13)" -"/cupsString13(14)" -"/cupsString14(15)" -"/cupsString15(16)" -"/cupsMarkerType(Marker Type)" -"/cupsRenderingIntent(Rendering Intent)" -"/cupsPageSizeName(Letter)" -"/cupsPreferredBitsPerColor 17" -">> setpagedevice"; - -static cups_page_header2_t setpagedevice_header = -{ - "Media Class", /* MediaClass */ - "(Media Color)", /* MediaColor */ - "Media\\Type", /* MediaType */ - "Abc", /* OutputType */ - 1000, /* AdvanceDistance */ - CUPS_ADVANCE_FILE, /* AdvanceMedia */ - CUPS_FALSE, /* Collate */ - CUPS_CUT_JOB, /* CutMedia */ - CUPS_TRUE, /* Duplex */ - { 100, 200 }, /* HWResolution */ - { 0, 0, 0, 0 }, /* ImagingBoundingBox */ - CUPS_TRUE, /* InsertSheet */ - CUPS_JOG_SET, /* Jog */ - CUPS_EDGE_RIGHT, /* LeadingEdge */ - { 0, 0 }, /* Margins */ - CUPS_TRUE, /* ManualFeed */ - 0777, /* MediaPosition */ - 0xfe01, /* MediaWeight */ - CUPS_TRUE, /* MirrorPrint */ - CUPS_TRUE, /* NegativePrint */ - 1, /* NumCopies */ - CUPS_ORIENT_90, /* Orientation */ - CUPS_TRUE, /* OutputFaceUp */ - { 612, 792 }, /* PageSize */ - CUPS_TRUE, /* Separations */ - CUPS_TRUE, /* TraySwitch */ - CUPS_TRUE, /* Tumble */ - 0, /* cupsWidth */ - 0, /* cupsHeight */ - 2, /* cupsMediaType */ - 0, /* cupsBitsPerColor */ - 0, /* cupsBitsPerPixel */ - 0, /* cupsBytesPerLine */ - CUPS_ORDER_BANDED, /* cupsColorOrder */ - CUPS_CSPACE_RGB, /* cupsColorSpace */ - 1, /* cupsCompression */ - 1, /* cupsRowCount */ - 1, /* cupsRowFeed */ - 1, /* cupsRowStep */ - 0, /* cupsNumColors */ - 1.001f, /* cupsBorderlessScalingFactor */ - { 612.0f, 792.1f }, /* cupsPageSize */ - { 0.0f, 0.0f, 0.0f, 0.0f }, /* cupsImagingBBox */ - { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, - /* cupsInteger[16] */ - { 1.1f, 2.1f, 3.1f, 4.1f, 5.1f, 6.1f, 7.1f, 8.1f, 9.1f, 10.1f, 11.1f, 12.1f, 13.1f, 14.1f, 15.1f, 16.1f }, /* cupsReal[16] */ - { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", - "14", "15", "16" }, /* cupsString[16] */ - "Marker Type", /* cupsMarkerType */ - "Rendering Intent", /* cupsRenderingIntent */ - "Letter" /* cupsPageSizeName */ -}; - - /* * Local functions... */ -static int do_ppd_tests(const char *filename, int num_options, - cups_option_t *options); -static int do_ps_tests(void); static int do_ras_file(const char *filename); static int do_raster_tests(cups_mode_t mode); static void print_changes(cups_page_header2_t *header, @@ -198,13 +34,11 @@ int /* O - Exit status */ main(int argc, /* I - Number of command-line args */ char *argv[]) /* I - Command-line arguments */ { - int errors; /* Number of errors */ - const char *ext; /* Filename extension */ + int errors = 0; /* Number of errors */ if (argc == 1) { - errors = do_ps_tests(); errors += do_raster_tests(CUPS_RASTER_WRITE); errors += do_raster_tests(CUPS_RASTER_WRITE_COMPRESSED); errors += do_raster_tests(CUPS_RASTER_WRITE_PWG); @@ -213,235 +47,15 @@ main(int argc, /* I - Number of command-line args */ else { int i; /* Looping var */ - int num_options; /* Number of options */ - cups_option_t *options; /* Options */ - - for (errors = 0, num_options = 0, options = NULL, i = 1; i < argc; i ++) - { - if (argv[i][0] == '-') - { - if (argv[i][1] == 'o') - { - if (argv[i][2]) - num_options = cupsParseOptions(argv[i] + 2, num_options, &options); - else - { - i ++; - if (i < argc) - num_options = cupsParseOptions(argv[i], num_options, &options); - else - { - puts("Usage: testraster [-o name=value ...] [filename.ppd ...]"); - puts(" testraster [filename.ras ...]"); - return (1); - } - } - } - else - { - puts("Usage: testraster [-o name=value ...] [filename.ppd ...]"); - puts(" testraster [filename.ras ...]"); - return (1); - } - } - else if ((ext = strrchr(argv[i], '.')) != NULL) - { - if (!strcmp(ext, ".ppd")) - errors += do_ppd_tests(argv[i], num_options, options); - else - errors += do_ras_file(argv[i]); - } - else - { - puts("Usage: testraster [-o name=value ...] [filename.ppd ...]"); - puts(" testraster [filename.ras ...]"); - return (1); - } - } - - cupsFreeOptions(num_options, options); + for (i = 1; i < argc; i ++) + errors += do_ras_file(argv[i]); } return (errors); } -/* - * 'do_ppd_tests()' - Test the default option commands in a PPD file. - */ - -static int /* O - Number of errors */ -do_ppd_tests(const char *filename, /* I - PPD file */ - int num_options, /* I - Number of options */ - cups_option_t *options) /* I - Options */ -{ - ppd_file_t *ppd; /* PPD file data */ - cups_page_header2_t header; /* Page header */ - - - printf("\"%s\": ", filename); - fflush(stdout); - - if ((ppd = ppdOpenFile(filename)) == NULL) - { - ppd_status_t status; /* Status from PPD loader */ - int line; /* Line number containing error */ - - - status = ppdLastError(&line); - - puts("FAIL (bad PPD file)"); - printf(" %s on line %d\n", ppdErrorString(status), line); - - return (1); - } - - ppdMarkDefaults(ppd); - cupsMarkOptions(ppd, num_options, options); - - if (cupsRasterInterpretPPD(&header, ppd, 0, NULL, NULL)) - { - puts("FAIL (error from function)"); - puts(cupsRasterErrorString()); - - return (1); - } - else - { - puts("PASS"); - - return (0); - } -} - - -/* - * 'do_ps_tests()' - Test standard PostScript commands. - */ - -static int -do_ps_tests(void) -{ - cups_page_header2_t header; /* Page header */ - int preferred_bits; /* Preferred bits */ - int errors = 0; /* Number of errors */ - - - /* - * Test PS exec code... - */ - - fputs("_cupsRasterExecPS(\"setpagedevice\"): ", stdout); - fflush(stdout); - - memset(&header, 0, sizeof(header)); - header.Collate = CUPS_TRUE; - preferred_bits = 0; - - if (_cupsRasterExecPS(&header, &preferred_bits, setpagedevice_code)) - { - puts("FAIL (error from function)"); - puts(cupsRasterErrorString()); - errors ++; - } - else if (preferred_bits != 17 || - memcmp(&header, &setpagedevice_header, sizeof(header))) - { - puts("FAIL (bad header)"); - - if (preferred_bits != 17) - printf(" cupsPreferredBitsPerColor %d, expected 17\n", - preferred_bits); - - print_changes(&setpagedevice_header, &header); - errors ++; - } - else - puts("PASS"); - - fputs("_cupsRasterExecPS(\"roll\"): ", stdout); - fflush(stdout); - - if (_cupsRasterExecPS(&header, &preferred_bits, - "792 612 0 0 0\n" - "pop pop pop\n" - "<>" - "setpagedevice\n")) - { - puts("FAIL (error from function)"); - puts(cupsRasterErrorString()); - errors ++; - } - else if (header.PageSize[0] != 792 || header.PageSize[1] != 612) - { - printf("FAIL (PageSize [%d %d], expected [792 612])\n", header.PageSize[0], - header.PageSize[1]); - errors ++; - } - else - puts("PASS"); - - fputs("_cupsRasterExecPS(\"dup index\"): ", stdout); - fflush(stdout); - - if (_cupsRasterExecPS(&header, &preferred_bits, - "true false dup\n" - "<>setpagedevice\n" - "pop pop pop")) - { - puts("FAIL (error from function)"); - puts(cupsRasterErrorString()); - errors ++; - } - else - { - if (!header.Collate) - { - printf("FAIL (Collate false, expected true)\n"); - errors ++; - } - - if (header.Duplex) - { - printf("FAIL (Duplex true, expected false)\n"); - errors ++; - } - - if (header.Tumble) - { - printf("FAIL (Tumble true, expected false)\n"); - errors ++; - } - - if(header.Collate && !header.Duplex && !header.Tumble) - puts("PASS"); - } - - fputs("_cupsRasterExecPS(\"%%Begin/EndFeature code\"): ", stdout); - fflush(stdout); - - if (_cupsRasterExecPS(&header, &preferred_bits, dsc_code)) - { - puts("FAIL (error from function)"); - puts(cupsRasterErrorString()); - errors ++; - } - else if (header.PageSize[0] != 792 || header.PageSize[1] != 1224) - { - printf("FAIL (bad PageSize [%d %d], expected [792 1224])\n", - header.PageSize[0], header.PageSize[1]); - errors ++; - } - else - puts("PASS"); - - return (errors); -} - - /* * 'do_ras_file()' - Test reading of a raster file. */ @@ -512,7 +126,7 @@ do_ras_file(const char *filename) /* I - Filename */ static int /* O - Number of errors */ do_raster_tests(cups_mode_t mode) /* O - Write mode */ { - unsigned page, x, y; /* Looping vars */ + unsigned page, x, y, count;/* Looping vars */ FILE *fp; /* Raster file */ cups_raster_t *r; /* Raster stream */ cups_page_header2_t header, /* Page header */ @@ -586,11 +200,15 @@ do_raster_tests(cups_mode_t mode) /* O - Write mode */ header.cupsBitsPerPixel = (page & 1) ? 32 : 8; } + printf("cupsRasterWriteHeader2(page %d): ", page + 1); + if (cupsRasterWriteHeader2(r, &header)) - puts("cupsRasterWriteHeader2: PASS"); + { + puts("PASS"); + } else { - puts("cupsRasterWriteHeader2: FAIL"); + puts("FAIL"); errors ++; } @@ -728,7 +346,7 @@ do_raster_tests(cups_mode_t mode) /* O - Write mode */ expected.cupsBitsPerPixel = (page & 1) ? 32 : 8; } - fputs("cupsRasterReadHeader2: ", stdout); + printf("cupsRasterReadHeader2(page %d): ", page + 1); fflush(stdout); if (!cupsRasterReadHeader2(r, &header)) @@ -737,13 +355,14 @@ do_raster_tests(cups_mode_t mode) /* O - Write mode */ errors ++; break; } - - if (memcmp(&header, &expected, sizeof(header))) + else if (memcmp(&header, &expected, sizeof(header))) { puts("FAIL (bad page header)"); errors ++; print_changes(&header, &expected); } + else + puts("PASS"); fputs("cupsRasterReadPixels: ", stdout); fflush(stdout); @@ -760,6 +379,20 @@ do_raster_tests(cups_mode_t mode) /* O - Write mode */ if (data[0] != 0 || memcmp(data, data + 1, header.cupsBytesPerLine - 1)) { printf("FAIL (raster line %d corrupt)\n", y); + + for (x = 0, count = 0; x < header.cupsBytesPerLine && count < 10; x ++) + { + if (data[x]) + { + count ++; + + if (count == 10) + puts(" ..."); + else + printf(" %4u %02X (expected %02X)\n", x, data[x], 0); + } + } + errors ++; break; } @@ -783,6 +416,20 @@ do_raster_tests(cups_mode_t mode) /* O - Write mode */ if (x < header.cupsBytesPerLine) { printf("FAIL (raster line %d corrupt)\n", y + 64); + + for (x = 0, count = 0; x < header.cupsBytesPerLine && count < 10; x ++) + { + if (data[x] != (x & 255)) + { + count ++; + + if (count == 10) + puts(" ..."); + else + printf(" %4u %02X (expected %02X)\n", x, data[x], x & 255); + } + } + errors ++; break; } @@ -802,6 +449,20 @@ do_raster_tests(cups_mode_t mode) /* O - Write mode */ if (data[0] != 255 || memcmp(data, data + 1, header.cupsBytesPerLine - 1)) { printf("fail (raster line %d corrupt)\n", y + 128); + + for (x = 0, count = 0; x < header.cupsBytesPerLine && count < 10; x ++) + { + if (data[x] != 255) + { + count ++; + + if (count == 10) + puts(" ..."); + else + printf(" %4u %02X (expected %02X)\n", x, data[x], 255); + } + } + errors ++; break; } @@ -825,6 +486,20 @@ do_raster_tests(cups_mode_t mode) /* O - Write mode */ if (x < header.cupsBytesPerLine) { printf("FAIL (raster line %d corrupt)\n", y + 192); + + for (x = 0, count = 0; x < header.cupsBytesPerLine && count < 10; x ++) + { + if (data[x] != ((x / 4) & 255)) + { + count ++; + + if (count == 10) + puts(" ..."); + else + printf(" %4u %02X (expected %02X)\n", x, data[x], (x / 4) & 255); + } + } + errors ++; break; } diff --git a/cups/testsnmp.c b/cups/testsnmp.c index 4026a28..8071847 100644 --- a/cups/testsnmp.c +++ b/cups/testsnmp.c @@ -3,13 +3,7 @@ * * Copyright 2008-2014 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -27,7 +21,7 @@ static void print_packet(cups_snmp_t *packet, void *data); static int show_oid(int fd, const char *community, http_addr_t *addr, const char *s, int walk); -static void usage(void) __attribute__((noreturn)); +static void usage(void) _CUPS_NORETURN; /* diff --git a/cups/thread-private.h b/cups/thread-private.h index ca4ef4c..1b8b106 100644 --- a/cups/thread-private.h +++ b/cups/thread-private.h @@ -1,15 +1,9 @@ /* * Private threading definitions for CUPS. * - * Copyright 2009-2016 by Apple Inc. + * Copyright 2009-2017 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ #ifndef _CUPS_THREAD_PRIVATE_H_ @@ -20,6 +14,7 @@ */ # include "config.h" +# include /* @@ -46,7 +41,7 @@ typedef pthread_key_t _cups_threadkey_t; # define _cupsThreadGetData(k) pthread_getspecific(k) # define _cupsThreadSetData(k,p) pthread_setspecific(k,p) -# elif defined(WIN32) /* Windows threading */ +# elif defined(_WIN32) /* Windows threading */ # include # include typedef void *(__stdcall *_cups_thread_func_t)(void *arg); @@ -87,19 +82,20 @@ typedef void *_cups_threadkey_t; * Functions... */ -extern void _cupsCondBroadcast(_cups_cond_t *cond); -extern void _cupsCondInit(_cups_cond_t *cond); -extern void _cupsCondWait(_cups_cond_t *cond, _cups_mutex_t *mutex, double timeout); -extern void _cupsMutexInit(_cups_mutex_t *mutex); -extern void _cupsMutexLock(_cups_mutex_t *mutex); -extern void _cupsMutexUnlock(_cups_mutex_t *mutex); -extern void _cupsRWInit(_cups_rwlock_t *rwlock); -extern void _cupsRWLockRead(_cups_rwlock_t *rwlock); -extern void _cupsRWLockWrite(_cups_rwlock_t *rwlock); -extern void _cupsRWUnlock(_cups_rwlock_t *rwlock); -extern void _cupsThreadCancel(_cups_thread_t thread); -extern _cups_thread_t _cupsThreadCreate(_cups_thread_func_t func, void *arg); -extern void *_cupsThreadWait(_cups_thread_t thread); +extern void _cupsCondBroadcast(_cups_cond_t *cond) _CUPS_PRIVATE; +extern void _cupsCondInit(_cups_cond_t *cond) _CUPS_PRIVATE; +extern void _cupsCondWait(_cups_cond_t *cond, _cups_mutex_t *mutex, double timeout) _CUPS_PRIVATE; +extern void _cupsMutexInit(_cups_mutex_t *mutex) _CUPS_PRIVATE; +extern void _cupsMutexLock(_cups_mutex_t *mutex) _CUPS_PRIVATE; +extern void _cupsMutexUnlock(_cups_mutex_t *mutex) _CUPS_PRIVATE; +extern void _cupsRWInit(_cups_rwlock_t *rwlock) _CUPS_PRIVATE; +extern void _cupsRWLockRead(_cups_rwlock_t *rwlock) _CUPS_PRIVATE; +extern void _cupsRWLockWrite(_cups_rwlock_t *rwlock) _CUPS_PRIVATE; +extern void _cupsRWUnlock(_cups_rwlock_t *rwlock) _CUPS_PRIVATE; +extern void _cupsThreadCancel(_cups_thread_t thread) _CUPS_PRIVATE; +extern _cups_thread_t _cupsThreadCreate(_cups_thread_func_t func, void *arg) _CUPS_PRIVATE; +extern void _cupsThreadDetach(_cups_thread_t thread) _CUPS_PRIVATE; +extern void *_cupsThreadWait(_cups_thread_t thread) _CUPS_PRIVATE; # ifdef __cplusplus } diff --git a/cups/thread.c b/cups/thread.c index 77b4442..fcab938 100644 --- a/cups/thread.c +++ b/cups/thread.c @@ -1,15 +1,10 @@ /* * Threading primitives for CUPS. * - * Copyright 2009-2016 by Apple Inc. + * Copyright © 2009-2018 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -56,8 +51,16 @@ _cupsCondWait(_cups_cond_t *cond, /* I - Condition */ { struct timespec abstime; /* Timeout */ - abstime.tv_sec = (long)timeout; - abstime.tv_nsec = (long)(1000000000 * (timeout - (long)timeout)); + clock_gettime(CLOCK_REALTIME, &abstime); + + abstime.tv_sec += (long)timeout; + abstime.tv_nsec += (long)(1000000000 * (timeout - (long)timeout)); + + while (abstime.tv_nsec >= 1000000000) + { + abstime.tv_nsec -= 1000000000; + abstime.tv_sec ++; + }; pthread_cond_timedwait(cond, mutex, &abstime); } @@ -172,6 +175,17 @@ _cupsThreadCreate( } +/* + * '_cupsThreadDetach()' - Tell the OS that the thread is running independently. + */ + +void +_cupsThreadDetach(_cups_thread_t thread)/* I - Thread ID */ +{ + pthread_detach(thread); +} + + /* * '_cupsThreadWait()' - Wait for a thread to exit. */ @@ -189,7 +203,7 @@ _cupsThreadWait(_cups_thread_t thread) /* I - Thread ID */ } -#elif defined(WIN32) +#elif defined(_WIN32) # include @@ -343,6 +357,18 @@ _cupsThreadCreate( } +/* + * '_cupsThreadDetach()' - Tell the OS that the thread is running independently. + */ + +void +_cupsThreadDetach(_cups_thread_t thread)/* I - Thread ID */ +{ + // TODO: Implement me + (void)thread; +} + + /* * '_cupsThreadWait()' - Wait for a thread to exit. */ @@ -490,8 +516,7 @@ _cupsThreadCreate( _cups_thread_func_t func, /* I - Entry point */ void *arg) /* I - Entry point context */ { - fputs("DEBUG: CUPS was compiled without threading support, no thread " - "created.\n", stderr); + fputs("DEBUG: CUPS was compiled without threading support, no thread created.\n", stderr); (void)func; (void)arg; @@ -500,6 +525,17 @@ _cupsThreadCreate( } +/* + * '_cupsThreadDetach()' - Tell the OS that the thread is running independently. + */ + +void +_cupsThreadDetach(_cups_thread_t thread)/* I - Thread ID */ +{ + (void)thread; +} + + /* * '_cupsThreadWait()' - Wait for a thread to exit. */ diff --git a/cups/tls-darwin.c b/cups/tls-darwin.c index 78d6de2..e8c4fb7 100644 --- a/cups/tls-darwin.c +++ b/cups/tls-darwin.c @@ -1,16 +1,11 @@ /* * TLS support code for CUPS on macOS. * - * Copyright 2007-2016 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /**** This file is included from tls.c ****/ @@ -20,9 +15,7 @@ */ #include - -extern char **environ; /* @private@ */ - +#include "tls-darwin.h" /* * Constants, very secure stuff... @@ -40,7 +33,7 @@ static int tls_auto_create = 0; /* Auto-create self-signed certs? */ static char *tls_common_name = NULL; /* Default common name */ -#ifdef HAVE_SECKEYCHAINOPEN +#if TARGET_OS_OSX static int tls_cups_keychain = 0; /* Opened the CUPS keychain? */ static SecKeychainRef tls_keychain = NULL; @@ -48,12 +41,14 @@ static SecKeychainRef tls_keychain = NULL; #else static SecIdentityRef tls_selfsigned = NULL; /* Temporary self-signed cert */ -#endif /* HAVE_SECKEYCHAINOPEN */ +#endif /* TARGET_OS_OSX */ static char *tls_keypath = NULL; /* Server cert keychain path */ static _cups_mutex_t tls_mutex = _CUPS_MUTEX_INITIALIZER; /* Mutex for keychain/certs */ -static int tls_options = -1;/* Options for TLS connections */ +static int tls_options = -1,/* Options for TLS connections */ + tls_min_version = _HTTP_TLS_1_0, + tls_max_version = _HTTP_TLS_MAX; /* @@ -62,11 +57,11 @@ static int tls_options = -1;/* Options for TLS connections */ static CFArrayRef http_cdsa_copy_server(const char *common_name); static SecCertificateRef http_cdsa_create_credential(http_credential_t *credential); -#ifdef HAVE_SECKEYCHAINOPEN +#if TARGET_OS_OSX static const char *http_cdsa_default_path(char *buffer, size_t bufsize); static SecKeychainRef http_cdsa_open_keychain(const char *path, char *filename, size_t filesize); static SecKeychainRef http_cdsa_open_system_keychain(void); -#endif /* HAVE_SECKEYCHAINOPEN */ +#endif /* TARGET_OS_OSX */ static OSStatus http_cdsa_read(SSLConnectionRef connection, void *data, size_t *dataLength); static int http_cdsa_set_credentials(http_t *http); static OSStatus http_cdsa_write(SSLConnectionRef connection, const void *data, size_t *dataLength); @@ -86,7 +81,107 @@ cupsMakeServerCredentials( const char **alt_names, /* I - Subject Alternate Names */ time_t expiration_date) /* I - Expiration date */ { -#if defined(HAVE_SECGENERATESELFSIGNEDCERTIFICATE) +#if TARGET_OS_OSX + int pid, /* Process ID of command */ + status, /* Status of command */ + i; /* Looping var */ + char command[1024], /* Command */ + *argv[5], /* Command-line arguments */ + *envp[1000], /* Environment variables */ + days[32], /* CERTTOOL_EXPIRATION_DAYS env var */ + keychain[1024], /* Keychain argument */ + infofile[1024], /* Type-in information for cert */ + filename[1024]; /* Default keychain path */ + cups_file_t *fp; /* Seed/info file */ + + + DEBUG_printf(("cupsMakeServerCredentials(path=\"%s\", common_name=\"%s\", num_alt_names=%d, alt_names=%p, expiration_date=%d)", path, common_name, num_alt_names, (void *)alt_names, (int)expiration_date)); + + (void)num_alt_names; + (void)alt_names; + + if (!path) + path = http_cdsa_default_path(filename, sizeof(filename)); + + /* + * Run the "certtool" command to generate a self-signed certificate... + */ + + if (!cupsFileFind("certtool", getenv("PATH"), 1, command, sizeof(command))) + return (-1); + + /* + * Create a file with the certificate information fields... + * + * Note: This assumes that the default questions are asked by the certtool + * command... + */ + + if ((fp = cupsTempFile2(infofile, sizeof(infofile))) == NULL) + return (-1); + + cupsFilePrintf(fp, + "CUPS Self-Signed Certificate\n" + /* Enter key and certificate label */ + "r\n" /* Generate RSA key pair */ + "2048\n" /* 2048 bit encryption key */ + "y\n" /* OK (y = yes) */ + "b\n" /* Usage (b=signing/encryption) */ + "2\n" /* Sign with SHA256 */ + "y\n" /* OK (y = yes) */ + "%s\n" /* Common name */ + "\n" /* Country (default) */ + "\n" /* Organization (default) */ + "\n" /* Organizational unit (default) */ + "\n" /* State/Province (default) */ + "\n" /* Email address */ + "y\n", /* OK (y = yes) */ + common_name); + cupsFileClose(fp); + + snprintf(keychain, sizeof(keychain), "k=%s", path); + + argv[0] = "certtool"; + argv[1] = "c"; + argv[2] = keychain; + argv[3] = NULL; + + snprintf(days, sizeof(days), "CERTTOOL_EXPIRATION_DAYS=%d", (int)((expiration_date - time(NULL) + 86399) / 86400)); + envp[0] = days; + for (i = 0; i < (int)(sizeof(envp) / sizeof(envp[0]) - 2) && environ[i]; i ++) + envp[i + 1] = environ[i]; + envp[i] = NULL; + + posix_spawn_file_actions_t actions; /* File actions */ + + posix_spawn_file_actions_init(&actions); + posix_spawn_file_actions_addclose(&actions, 0); + posix_spawn_file_actions_addopen(&actions, 0, infofile, O_RDONLY, 0); + posix_spawn_file_actions_addclose(&actions, 1); + posix_spawn_file_actions_addopen(&actions, 1, "/dev/null", O_WRONLY, 0); + posix_spawn_file_actions_addclose(&actions, 2); + posix_spawn_file_actions_addopen(&actions, 2, "/dev/null", O_WRONLY, 0); + + if (posix_spawn(&pid, command, &actions, NULL, argv, envp)) + { + unlink(infofile); + return (-1); + } + + posix_spawn_file_actions_destroy(&actions); + + unlink(infofile); + + while (waitpid(pid, &status, 0) < 0) + if (errno != EINTR) + { + status = -1; + break; + } + + return (!status); + +#else int status = 0; /* Return status */ OSStatus err; /* Error code (if any) */ CFStringRef cfcommon_name = NULL; @@ -244,107 +339,7 @@ cleanup: DEBUG_printf(("1cupsMakeServerCredentials: Returning %d.", status)); return (status); - -#else /* !HAVE_SECGENERATESELFSIGNEDCERTIFICATE */ - int pid, /* Process ID of command */ - status, /* Status of command */ - i; /* Looping var */ - char command[1024], /* Command */ - *argv[5], /* Command-line arguments */ - *envp[1000], /* Environment variables */ - days[32], /* CERTTOOL_EXPIRATION_DAYS env var */ - keychain[1024], /* Keychain argument */ - infofile[1024], /* Type-in information for cert */ - filename[1024]; /* Default keychain path */ - cups_file_t *fp; /* Seed/info file */ - - - DEBUG_printf(("cupsMakeServerCredentials(path=\"%s\", common_name=\"%s\", num_alt_names=%d, alt_names=%p, expiration_date=%d)", path, common_name, num_alt_names, (void *)alt_names, (int)expiration_date)); - - (void)num_alt_names; - (void)alt_names; - - if (!path) - path = http_cdsa_default_path(filename, sizeof(filename)); - - /* - * Run the "certtool" command to generate a self-signed certificate... - */ - - if (!cupsFileFind("certtool", getenv("PATH"), 1, command, sizeof(command))) - return (-1); - - /* - * Create a file with the certificate information fields... - * - * Note: This assumes that the default questions are asked by the certtool - * command... - */ - - if ((fp = cupsTempFile2(infofile, sizeof(infofile))) == NULL) - return (-1); - - cupsFilePrintf(fp, - "CUPS Self-Signed Certificate\n" - /* Enter key and certificate label */ - "r\n" /* Generate RSA key pair */ - "2048\n" /* 2048 bit encryption key */ - "y\n" /* OK (y = yes) */ - "b\n" /* Usage (b=signing/encryption) */ - "2\n" /* Sign with SHA256 */ - "y\n" /* OK (y = yes) */ - "%s\n" /* Common name */ - "\n" /* Country (default) */ - "\n" /* Organization (default) */ - "\n" /* Organizational unit (default) */ - "\n" /* State/Province (default) */ - "\n" /* Email address */ - "y\n", /* OK (y = yes) */ - common_name); - cupsFileClose(fp); - - snprintf(keychain, sizeof(keychain), "k=%s", path); - - argv[0] = "certtool"; - argv[1] = "c"; - argv[2] = keychain; - argv[3] = NULL; - - snprintf(days, sizeof(days), "CERTTOOL_EXPIRATION_DAYS=%d", (int)((expiration_date - time(NULL) + 86399) / 86400)); - envp[0] = days; - for (i = 0; i < (int)(sizeof(envp) / sizeof(envp[0]) - 2) && environ[i]; i ++) - envp[i + 1] = environ[i]; - envp[i] = NULL; - - posix_spawn_file_actions_t actions; /* File actions */ - - posix_spawn_file_actions_init(&actions); - posix_spawn_file_actions_addclose(&actions, 0); - posix_spawn_file_actions_addopen(&actions, 0, infofile, O_RDONLY, 0); - posix_spawn_file_actions_addclose(&actions, 1); - posix_spawn_file_actions_addopen(&actions, 1, "/dev/null", O_WRONLY, 0); - posix_spawn_file_actions_addclose(&actions, 2); - posix_spawn_file_actions_addopen(&actions, 2, "/dev/null", O_WRONLY, 0); - - if (posix_spawn(&pid, command, &actions, NULL, argv, envp)) - { - unlink(infofile); - return (-1); - } - - posix_spawn_file_actions_destroy(&actions); - - unlink(infofile); - - while (waitpid(pid, &status, 0) < 0) - if (errno != EINTR) - { - status = -1; - break; - } - - return (!status); -#endif /* HAVE_SECGENERATESELFSIGNEDCERTIFICATE && HAVE_SECKEYCHAINOPEN */ +#endif /* TARGET_OS_OSX */ } @@ -365,7 +360,7 @@ cupsSetServerCredentials( { DEBUG_printf(("cupsSetServerCredentials(path=\"%s\", common_name=\"%s\", auto_create=%d)", path, common_name, auto_create)); -#ifdef HAVE_SECKEYCHAINOPEN +#if TARGET_OS_OSX char filename[1024]; /* Keychain filename */ SecKeychainRef keychain = http_cdsa_open_keychain(path, filename, sizeof(filename)); @@ -415,7 +410,7 @@ cupsSetServerCredentials( tls_common_name = _cupsStrAlloc(common_name); return (1); -#endif /* HAVE_SECKEYCHAINOPEN */ +#endif /* TARGET_OS_OSX */ } @@ -804,27 +799,89 @@ httpCredentialsString( if ((first = (http_credential_t *)cupsArrayFirst(credentials)) != NULL && (secCert = http_cdsa_create_credential(first)) != NULL) { - CFStringRef cf_name; /* CF common name string */ - char name[256]; /* Common name associated with cert */ + /* + * Copy certificate (string) values from the SecCertificateRef and produce + * a one-line summary. The API for accessing certificate values like the + * issuer name is, um, "interesting"... + */ + +# if TARGET_OS_OSX + CFDictionaryRef cf_dict; /* Dictionary for certificate */ +# endif /* TARGET_OS_OSX */ + CFStringRef cf_string; /* CF string */ + char commonName[256],/* Common name associated with cert */ + issuer[256], /* Issuer name */ + sigalg[256]; /* Signature algorithm */ time_t expiration; /* Expiration date of cert */ - _cups_md5_state_t md5_state; /* MD5 state */ unsigned char md5_digest[16]; /* MD5 result */ - if ((cf_name = SecCertificateCopySubjectSummary(secCert)) != NULL) + if (SecCertificateCopyCommonName(secCert, &cf_string) == noErr) { - CFStringGetCString(cf_name, name, (CFIndex)sizeof(name), kCFStringEncodingUTF8); - CFRelease(cf_name); + CFStringGetCString(cf_string, commonName, (CFIndex)sizeof(commonName), kCFStringEncodingUTF8); + CFRelease(cf_string); } else - strlcpy(name, "unknown", sizeof(name)); + { + strlcpy(commonName, "unknown", sizeof(commonName)); + } + + strlcpy(issuer, "unknown", sizeof(issuer)); + strlcpy(sigalg, "UnknownSignature", sizeof(sigalg)); + +# if TARGET_OS_OSX + if ((cf_dict = SecCertificateCopyValues(secCert, NULL, NULL)) != NULL) + { + CFDictionaryRef cf_issuer = CFDictionaryGetValue(cf_dict, kSecOIDX509V1IssuerName); + CFDictionaryRef cf_sigalg = CFDictionaryGetValue(cf_dict, kSecOIDX509V1SignatureAlgorithm); + + if (cf_issuer) + { + CFArrayRef cf_values = CFDictionaryGetValue(cf_issuer, kSecPropertyKeyValue); + CFIndex i, count = CFArrayGetCount(cf_values); + CFDictionaryRef cf_value; + + for (i = 0; i < count; i ++) + { + cf_value = CFArrayGetValueAtIndex(cf_values, i); + + if (!CFStringCompare(CFDictionaryGetValue(cf_value, kSecPropertyKeyLabel), kSecOIDOrganizationName, kCFCompareCaseInsensitive)) + CFStringGetCString(CFDictionaryGetValue(cf_value, kSecPropertyKeyValue), issuer, (CFIndex)sizeof(issuer), kCFStringEncodingUTF8); + } + } + + if (cf_sigalg) + { + CFArrayRef cf_values = CFDictionaryGetValue(cf_sigalg, kSecPropertyKeyValue); + CFIndex i, count = CFArrayGetCount(cf_values); + CFDictionaryRef cf_value; + + for (i = 0; i < count; i ++) + { + cf_value = CFArrayGetValueAtIndex(cf_values, i); + + if (!CFStringCompare(CFDictionaryGetValue(cf_value, kSecPropertyKeyLabel), CFSTR("Algorithm"), kCFCompareCaseInsensitive)) + { + CFStringRef cf_algorithm = CFDictionaryGetValue(cf_value, kSecPropertyKeyValue); + + if (!CFStringCompare(cf_algorithm, CFSTR("1.2.840.113549.1.1.5"), kCFCompareCaseInsensitive)) + strlcpy(sigalg, "SHA1WithRSAEncryption", sizeof(sigalg)); + else if (!CFStringCompare(cf_algorithm, CFSTR("1.2.840.113549.1.1.11"), kCFCompareCaseInsensitive)) + strlcpy(sigalg, "SHA256WithRSAEncryption", sizeof(sigalg)); + else if (!CFStringCompare(cf_algorithm, CFSTR("1.2.840.113549.1.1.4"), kCFCompareCaseInsensitive)) + strlcpy(sigalg, "MD5WithRSAEncryption", sizeof(sigalg)); + } + } + } + + CFRelease(cf_dict); + } +# endif /* TARGET_OS_OSX */ expiration = (time_t)(SecCertificateNotValidAfter(secCert) + kCFAbsoluteTimeIntervalSince1970); - _cupsMD5Init(&md5_state); - _cupsMD5Append(&md5_state, first->data, (int)first->datalen); - _cupsMD5Finish(&md5_state, md5_digest); + cupsHashData("md5", first->data, first->datalen, md5_digest, sizeof(md5_digest)); - snprintf(buffer, bufsize, "%s / %s / %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", name, httpGetDateString(expiration), md5_digest[0], md5_digest[1], md5_digest[2], md5_digest[3], md5_digest[4], md5_digest[5], md5_digest[6], md5_digest[7], md5_digest[8], md5_digest[9], md5_digest[10], md5_digest[11], md5_digest[12], md5_digest[13], md5_digest[14], md5_digest[15]); + snprintf(buffer, bufsize, "%s (issued by %s) / %s / %s / %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", commonName, issuer, httpGetDateString(expiration), sigalg, md5_digest[0], md5_digest[1], md5_digest[2], md5_digest[3], md5_digest[4], md5_digest[5], md5_digest[6], md5_digest[7], md5_digest[8], md5_digest[9], md5_digest[10], md5_digest[11], md5_digest[12], md5_digest[13], md5_digest[14], md5_digest[15]); CFRelease(secCert); } @@ -863,12 +920,12 @@ httpLoadCredentials( const char *common_name) /* I - Common name for credentials */ { OSStatus err; /* Error info */ -#ifdef HAVE_SECKEYCHAINOPEN +#if TARGET_OS_OSX char filename[1024]; /* Filename for keychain */ SecKeychainRef keychain = NULL,/* Keychain reference */ syschain = NULL;/* System keychain */ CFArrayRef list; /* Keychain list */ -#endif /* HAVE_SECKEYCHAINOPEN */ +#endif /* TARGET_OS_OSX */ SecCertificateRef cert = NULL; /* Certificate */ CFDataRef data; /* Certificate data */ SecPolicyRef policy = NULL; /* Policy ref */ @@ -884,7 +941,7 @@ httpLoadCredentials( *credentials = NULL; -#ifdef HAVE_SECKEYCHAINOPEN +#if TARGET_OS_OSX keychain = http_cdsa_open_keychain(path, filename, sizeof(filename)); if (!keychain) @@ -895,7 +952,7 @@ httpLoadCredentials( #else if (path) return (-1); -#endif /* HAVE_SECKEYCHAINOPEN */ +#endif /* TARGET_OS_OSX */ cfcommon_name = CFStringCreateWithCString(kCFAllocatorDefault, common_name, kCFStringEncodingUTF8); @@ -915,7 +972,7 @@ httpLoadCredentials( CFDictionaryAddValue(query, kSecReturnRef, kCFBooleanTrue); CFDictionaryAddValue(query, kSecMatchLimit, kSecMatchLimitOne); -#ifdef HAVE_SECKEYCHAINOPEN +#if TARGET_OS_OSX if (syschain) { const void *values[2] = { syschain, keychain }; @@ -926,7 +983,7 @@ httpLoadCredentials( list = CFArrayCreate(kCFAllocatorDefault, (const void **)&keychain, 1, &kCFTypeArrayCallBacks); CFDictionaryAddValue(query, kSecMatchSearchList, list); CFRelease(list); -#endif /* HAVE_SECKEYCHAINOPEN */ +#endif /* TARGET_OS_OSX */ err = SecItemCopyMatching(query, (CFTypeRef *)&cert); @@ -947,13 +1004,13 @@ httpLoadCredentials( cleanup : -#ifdef HAVE_SECKEYCHAINOPEN +#if TARGET_OS_OSX if (keychain) CFRelease(keychain); if (syschain) CFRelease(syschain); -#endif /* HAVE_SECKEYCHAINOPEN */ +#endif /* TARGET_OS_OSX */ if (cert) CFRelease(cert); if (policy) @@ -981,11 +1038,11 @@ httpSaveCredentials( { int ret = -1; /* Return value */ OSStatus err; /* Error info */ -#ifdef HAVE_SECKEYCHAINOPEN +#if TARGET_OS_OSX char filename[1024]; /* Filename for keychain */ SecKeychainRef keychain = NULL;/* Keychain reference */ CFArrayRef list; /* Keychain list */ -#endif /* HAVE_SECKEYCHAINOPEN */ +#endif /* TARGET_OS_OSX */ SecCertificateRef cert = NULL; /* Certificate */ CFMutableDictionaryRef attrs = NULL; /* Attributes for add */ @@ -1006,7 +1063,7 @@ httpSaveCredentials( goto cleanup; } -#ifdef HAVE_SECKEYCHAINOPEN +#if TARGET_OS_OSX keychain = http_cdsa_open_keychain(path, filename, sizeof(filename)); if (!keychain) @@ -1015,7 +1072,7 @@ httpSaveCredentials( #else if (path) return (-1); -#endif /* HAVE_SECKEYCHAINOPEN */ +#endif /* TARGET_OS_OSX */ if ((attrs = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)) == NULL) { @@ -1026,7 +1083,7 @@ httpSaveCredentials( CFDictionaryAddValue(attrs, kSecClass, kSecClassCertificate); CFDictionaryAddValue(attrs, kSecValueRef, cert); -#ifdef HAVE_SECKEYCHAINOPEN +#if TARGET_OS_OSX if ((list = CFArrayCreate(kCFAllocatorDefault, (const void **)&keychain, 1, &kCFTypeArrayCallBacks)) == NULL) { DEBUG_puts("1httpSaveCredentials: Unable to create list of keychains."); @@ -1034,7 +1091,7 @@ httpSaveCredentials( } CFDictionaryAddValue(attrs, kSecMatchSearchList, list); CFRelease(list); -#endif /* HAVE_SECKEYCHAINOPEN */ +#endif /* TARGET_OS_OSX */ /* Note: SecItemAdd consumes "attrs"... */ err = SecItemAdd(attrs, NULL); @@ -1042,10 +1099,10 @@ httpSaveCredentials( cleanup : -#ifdef HAVE_SECKEYCHAINOPEN +#if TARGET_OS_OSX if (keychain) CFRelease(keychain); -#endif /* HAVE_SECKEYCHAINOPEN */ +#endif /* TARGET_OS_OSX */ if (cert) CFRelease(cert); @@ -1139,9 +1196,16 @@ _httpTLSRead(http_t *http, /* I - HTTP connection */ */ void -_httpTLSSetOptions(int options) /* I - Options */ +_httpTLSSetOptions(int options, /* I - Options */ + int min_version, /* I - Minimum TLS version */ + int max_version) /* I - Maximum TLS version */ { - tls_options = options; + if (!(options & _HTTP_TLS_SET_DEFAULT) || tls_options < 0) + { + tls_options = options; + tls_min_version = min_version; + tls_max_version = max_version; + } } @@ -1158,6 +1222,7 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */ /* Pointer to library globals */ OSStatus error; /* Error code */ const char *message = NULL;/* Error message */ + char msgbuf[1024]; /* Error message buffer */ cups_array_t *credentials; /* Credentials array */ cups_array_t *names; /* CUPS distinguished names */ CFArrayRef dn_array; /* CF distinguished names array */ @@ -1173,10 +1238,10 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */ { DEBUG_puts("4_httpTLSStart: Setting defaults."); _cupsSetDefaults(); - DEBUG_printf(("4_httpTLSStart: tls_options=%x", tls_options)); + DEBUG_printf(("4_httpTLSStart: tls_options=%x, tls_min_version=%d, tls_max_version=%d", tls_options, tls_min_version, tls_max_version)); } -#ifdef HAVE_SECKEYCHAINOPEN +#if TARGET_OS_OSX if (http->mode == _HTTP_MODE_SERVER && !tls_keychain) { DEBUG_puts("4_httpTLSStart: cupsSetServerCredentials not called."); @@ -1186,7 +1251,7 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */ return (-1); } -#endif /* HAVE_SECKEYCHAINOPEN */ +#endif /* TARGET_OS_OSX */ if ((http->tls = SSLCreateContext(kCFAllocatorDefault, http->mode == _HTTP_MODE_CLIENT ? kSSLClientSide : kSSLServerSide, kSSLStreamType)) == NULL) { @@ -1216,20 +1281,28 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */ if (!error) { - SSLProtocol minProtocol; + static const SSLProtocol protocols[] = /* Min/max protocol versions */ + { + kSSLProtocol3, + kTLSProtocol1, + kTLSProtocol11, + kTLSProtocol12, + kTLSProtocol13 + }; - if (tls_options & _HTTP_TLS_DENY_TLS10) - minProtocol = kTLSProtocol11; - else if (tls_options & _HTTP_TLS_ALLOW_SSL3) - minProtocol = kSSLProtocol3; - else - minProtocol = kTLSProtocol1; + if (tls_min_version < _HTTP_TLS_MAX) + { + error = SSLSetProtocolVersionMin(http->tls, protocols[tls_min_version]); + DEBUG_printf(("4_httpTLSStart: SSLSetProtocolVersionMin(%d), error=%d", protocols[tls_min_version], (int)error)); + } - error = SSLSetProtocolVersionMin(http->tls, minProtocol); - DEBUG_printf(("4_httpTLSStart: SSLSetProtocolVersionMin(%d), error=%d", minProtocol, (int)error)); + if (!error && tls_max_version < _HTTP_TLS_MAX) + { + error = SSLSetProtocolVersionMax(http->tls, protocols[tls_max_version]); + DEBUG_printf(("4_httpTLSStart: SSLSetProtocolVersionMax(%d), error=%d", protocols[tls_max_version], (int)error)); + } } -# if HAVE_SSLSETENABLEDCIPHERS if (!error) { SSLCipherSuite supported[100]; /* Supported cipher suites */ @@ -1369,6 +1442,9 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */ case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 : case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 : case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 : + case TLS_RSA_WITH_3DES_EDE_CBC_SHA : + case TLS_RSA_WITH_AES_128_CBC_SHA : + case TLS_RSA_WITH_AES_256_CBC_SHA : if (tls_options & _HTTP_TLS_DENY_CBC) { DEBUG_printf(("4_httpTLSStart: Excluding CBC cipher suite %d", supported[i])); @@ -1386,7 +1462,6 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */ error = SSLSetEnabledCiphers(http->tls, enabled, num_enabled); } } -#endif /* HAVE_SSLSETENABLEDCIPHERS */ if (!error && http->mode == _HTTP_MODE_CLIENT) { @@ -1414,7 +1489,7 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */ * Server: find/create a certificate for TLS... */ - if (http->fields[HTTP_FIELD_HOST][0]) + if (http->fields[HTTP_FIELD_HOST]) { /* * Use hostname for TLS upgrade... @@ -1522,7 +1597,28 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */ if (!error) { - int done = 0; /* Are we done yet? */ + int done = 0; /* Are we done yet? */ + double old_timeout; /* Old timeout value */ + http_timeout_cb_t old_cb; /* Old timeout callback */ + void *old_data; /* Old timeout data */ + + /* + * Enforce a minimum timeout of 10 seconds for the TLS handshake... + */ + + old_timeout = http->timeout_value; + old_cb = http->timeout_cb; + old_data = http->timeout_data; + + if (!old_cb || old_timeout < 10.0) + { + DEBUG_puts("4_httpTLSStart: Setting timeout to 10 seconds."); + httpSetTimeout(http, 10.0, NULL, NULL); + } + + /* + * Do the TLS handshake... + */ while (!error && !done) { @@ -1643,6 +1739,12 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */ break; } } + + /* + * Restore the previous timeout settings... + */ + + httpSetTimeout(http, old_timeout, old_cb, old_data); } if (error) @@ -1659,11 +1761,13 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */ */ if (!message) -#ifdef HAVE_CSSMERRORSTRING - message = cssmErrorString(error); -#else - message = _("Unable to establish a secure connection to host."); -#endif /* HAVE_CSSMERRORSTRING */ + { + if (!cg->lang_default) + cg->lang_default = cupsLangDefault(); + + snprintf(msgbuf, sizeof(msgbuf), _cupsLangString(cg->lang_default, _("Unable to establish a secure connection to host (%d).")), error); + message = msgbuf; + } _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI, message, 1); @@ -1758,7 +1862,7 @@ static CFArrayRef /* O - Array of certificates or NULL */ http_cdsa_copy_server( const char *common_name) /* I - Server's hostname */ { -#ifdef HAVE_SECKEYCHAINOPEN +#if TARGET_OS_OSX OSStatus err; /* Error info */ SecIdentityRef identity = NULL;/* Identity */ CFArrayRef certificates = NULL; @@ -1856,11 +1960,13 @@ http_cdsa_copy_server( return (certificates); #else + (void)common_name; + if (!tls_selfsigned) return (NULL); return (CFArrayCreate(NULL, (const void **)&tls_selfsigned, 1, &kCFTypeArrayCallBacks)); -#endif /* HAVE_SECKEYCHAINOPEN */ +#endif /* TARGET_OS_OSX */ } @@ -1872,14 +1978,22 @@ static SecCertificateRef /* O - Certificate */ http_cdsa_create_credential( http_credential_t *credential) /* I - Credential */ { + SecCertificateRef cert; /* Certificate */ + CFDataRef data; /* Data object */ + + if (!credential) return (NULL); - return (SecCertificateCreateWithBytes(kCFAllocatorDefault, credential->data, (CFIndex)credential->datalen)); + data = CFDataCreate(kCFAllocatorDefault, credential->data, (CFIndex)credential->datalen); + cert = SecCertificateCreateWithData(kCFAllocatorDefault, data); + CFRelease(data); + + return (cert); } -#ifdef HAVE_SECKEYCHAINOPEN +#if TARGET_OS_OSX /* * 'http_cdsa_default_path()' - Get the default keychain path. */ @@ -2055,7 +2169,7 @@ http_cdsa_open_system_keychain(void) return (keychain); } -#endif /* HAVE_SECKEYCHAINOPEN */ +#endif /* TARGET_OS_OSX */ /* @@ -2075,7 +2189,7 @@ http_cdsa_read( http = (http_t *)connection; - if (!http->blocking) + if (!http->blocking || http->timeout_value > 0.0) { /* * Make sure we have data before we read... diff --git a/cups/tls-darwin.h b/cups/tls-darwin.h new file mode 100644 index 0000000..ca4136e --- /dev/null +++ b/cups/tls-darwin.h @@ -0,0 +1,35 @@ +/* + * TLS support header for CUPS on macOS. + * + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products, all rights reserved. + * + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. + */ + +/**** This file is included from tls-darwin.c ****/ + +extern char **environ; + +#ifndef _SECURITY_VERSION_GREATER_THAN_57610_ +typedef CF_OPTIONS(uint32_t, SecKeyUsage) { + kSecKeyUsageAll = 0x7FFFFFFF +}; +#endif /* !_SECURITY_VERSION_GREATER_THAN_57610_ */ +extern const void * kSecCSRChallengePassword; +extern const void * kSecSubjectAltName; +extern const void * kSecCertificateKeyUsage; +extern const void * kSecCSRBasicContraintsPathLen; +extern const void * kSecCertificateExtensions; +extern const void * kSecCertificateExtensionsEncoded; +extern const void * kSecOidCommonName; +extern const void * kSecOidCountryName; +extern const void * kSecOidStateProvinceName; +extern const void * kSecOidLocalityName; +extern const void * kSecOidOrganization; +extern const void * kSecOidOrganizationalUnit; +extern bool SecCertificateIsValid(SecCertificateRef certificate, CFAbsoluteTime verifyTime); +extern CFAbsoluteTime SecCertificateNotValidAfter(SecCertificateRef certificate); +extern SecCertificateRef SecGenerateSelfSignedCertificate(CFArrayRef subject, CFDictionaryRef parameters, SecKeyRef publicKey, SecKeyRef privateKey); +extern SecIdentityRef SecIdentityCreate(CFAllocatorRef allocator, SecCertificateRef certificate, SecKeyRef privateKey); diff --git a/cups/tls-gnutls.c b/cups/tls-gnutls.c index 98cc8b4..fc52f49 100644 --- a/cups/tls-gnutls.c +++ b/cups/tls-gnutls.c @@ -1,16 +1,11 @@ /* * TLS support code for CUPS using GNU TLS. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /**** This file is included from tls.c ****/ @@ -35,7 +30,9 @@ static char *tls_keypath = NULL; /* Server cert keychain path */ static _cups_mutex_t tls_mutex = _CUPS_MUTEX_INITIALIZER; /* Mutex for keychain/certs */ -static int tls_options = -1;/* Options for TLS connections */ +static int tls_options = -1,/* Options for TLS connections */ + tls_min_version = _HTTP_TLS_1_0, + tls_max_version = _HTTP_TLS_MAX; /* @@ -171,10 +168,33 @@ cupsMakeServerCredentials( gnutls_x509_crt_set_activation_time(crt, curtime); gnutls_x509_crt_set_expiration_time(crt, curtime + 10 * 365 * 86400); gnutls_x509_crt_set_ca_status(crt, 0); + gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME, common_name, (unsigned)strlen(common_name), GNUTLS_FSAN_SET); + if (!strchr(common_name, '.')) + { + /* + * Add common_name.local to the list, too... + */ + + char localname[256]; /* hostname.local */ + + snprintf(localname, sizeof(localname), "%s.local", common_name); + gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME, localname, (unsigned)strlen(localname), GNUTLS_FSAN_APPEND); + } + gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME, "localhost", 9, GNUTLS_FSAN_APPEND); if (num_alt_names > 0) - gnutls_x509_crt_set_subject_alternative_name(crt, GNUTLS_SAN_DNSNAME, alt_names[0]); + { + int i; /* Looping var */ + + for (i = 0; i < num_alt_names; i ++) + { + if (strcmp(alt_names[i], "localhost")) + { + gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME, alt_names[i], (unsigned)strlen(alt_names[i]), GNUTLS_FSAN_APPEND); + } + } + } gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0); - gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_KEY_ENCIPHERMENT); + gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT); gnutls_x509_crt_set_version(crt, 3); bytes = sizeof(buffer); @@ -378,8 +398,8 @@ httpCredentialsAreValidForName( if (result) { - int i, /* Looping var */ - count; /* Number of revoked certificates */ + gnutls_x509_crl_iter_t iter = NULL; + /* Iterator */ unsigned char cserial[1024], /* Certificate serial number */ rserial[1024]; /* Revoked serial number */ size_t cserial_size, /* Size of cert serial number */ @@ -387,22 +407,24 @@ httpCredentialsAreValidForName( _cupsMutexLock(&tls_mutex); - count = gnutls_x509_crl_get_crt_count(tls_crl); - - if (count > 0) + if (gnutls_x509_crl_get_crt_count(tls_crl) > 0) { cserial_size = sizeof(cserial); gnutls_x509_crt_get_serial(cert, cserial, &cserial_size); - for (i = 0; i < count; i ++) - { - rserial_size = sizeof(rserial); - if (!gnutls_x509_crl_get_crt_serial(tls_crl, (unsigned)i, rserial, &rserial_size, NULL) && cserial_size == rserial_size && !memcmp(cserial, rserial, rserial_size)) + rserial_size = sizeof(rserial); + + while (!gnutls_x509_crl_iter_crt_serial(tls_crl, &iter, rserial, &rserial_size, NULL)) + { + if (cserial_size == rserial_size && !memcmp(cserial, rserial, rserial_size)) { result = 0; break; } + + rserial_size = sizeof(rserial); } + gnutls_x509_crl_iter_deinit(iter); } _cupsMutexUnlock(&tls_mutex); @@ -643,25 +665,31 @@ httpCredentialsString( if ((first = (http_credential_t *)cupsArrayFirst(credentials)) != NULL && (cert = http_gnutls_create_credential(first)) != NULL) { - char name[256]; /* Common name associated with cert */ - size_t namelen; /* Length of name */ + char name[256], /* Common name associated with cert */ + issuer[256]; /* Issuer associated with cert */ + size_t len; /* Length of string */ time_t expiration; /* Expiration date of cert */ - _cups_md5_state_t md5_state; /* MD5 state */ + int sigalg; /* Signature algorithm */ unsigned char md5_digest[16]; /* MD5 result */ - namelen = sizeof(name) - 1; - if (gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME, 0, 0, name, &namelen) >= 0) - name[namelen] = '\0'; + len = sizeof(name) - 1; + if (gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME, 0, 0, name, &len) >= 0) + name[len] = '\0'; else strlcpy(name, "unknown", sizeof(name)); + len = sizeof(issuer) - 1; + if (gnutls_x509_crt_get_issuer_dn_by_oid(cert, GNUTLS_OID_X520_ORGANIZATION_NAME, 0, 0, issuer, &len) >= 0) + issuer[len] = '\0'; + else + strlcpy(issuer, "unknown", sizeof(issuer)); + expiration = gnutls_x509_crt_get_expiration_time(cert); + sigalg = gnutls_x509_crt_get_signature_algorithm(cert); - _cupsMD5Init(&md5_state); - _cupsMD5Append(&md5_state, first->data, (int)first->datalen); - _cupsMD5Finish(&md5_state, md5_digest); + cupsHashData("md5", first->data, first->datalen, md5_digest, sizeof(md5_digest)); - snprintf(buffer, bufsize, "%s / %s / %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", name, httpGetDateString(expiration), md5_digest[0], md5_digest[1], md5_digest[2], md5_digest[3], md5_digest[4], md5_digest[5], md5_digest[6], md5_digest[7], md5_digest[8], md5_digest[9], md5_digest[10], md5_digest[11], md5_digest[12], md5_digest[13], md5_digest[14], md5_digest[15]); + snprintf(buffer, bufsize, "%s (issued by %s) / %s / %s / %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", name, issuer, httpGetDateString(expiration), gnutls_sign_get_name((gnutls_sign_algorithm_t)sigalg), md5_digest[0], md5_digest[1], md5_digest[2], md5_digest[3], md5_digest[4], md5_digest[5], md5_digest[6], md5_digest[7], md5_digest[8], md5_digest[9], md5_digest[10], md5_digest[11], md5_digest[12], md5_digest[13], md5_digest[14], md5_digest[15]); gnutls_x509_crt_deinit(cert); } @@ -1094,7 +1122,7 @@ http_gnutls_read( http = (http_t *)ptr; - if (!http->blocking) + if (!http->blocking || http->timeout_value > 0.0) { /* * Make sure we have data before we read... @@ -1206,27 +1234,21 @@ _httpTLSRead(http_t *http, /* I - Connection to server */ } -/* - * '_httpTLSSetCredentials()' - Set the TLS credentials. - */ - -int /* O - Status of connection */ -_httpTLSSetCredentials(http_t *http) /* I - Connection to server */ -{ - (void)http; - - return (0); -} - - /* * '_httpTLSSetOptions()' - Set TLS protocol and cipher suite options. */ void -_httpTLSSetOptions(int options) /* I - Options */ +_httpTLSSetOptions(int options, /* I - Options */ + int min_version, /* I - Minimum TLS version */ + int max_version) /* I - Maximum TLS version */ { - tls_options = options; + if (!(options & _HTTP_TLS_SET_DEFAULT) || tls_options < 0) + { + tls_options = options; + tls_min_version = min_version; + tls_max_version = max_version; + } } @@ -1242,8 +1264,21 @@ _httpTLSStart(http_t *http) /* I - Connection to server */ int status; /* Status of handshake */ gnutls_certificate_credentials_t *credentials; /* TLS credentials */ - char priority_string[1024]; + char priority_string[2048]; /* Priority string */ + int version; /* Current version */ + double old_timeout; /* Old timeout value */ + http_timeout_cb_t old_cb; /* Old timeout callback */ + void *old_data; /* Old timeout data */ + static const char * const versions[] =/* SSL/TLS versions */ + { + "VERS-SSL3.0", + "VERS-TLS1.0", + "VERS-TLS1.1", + "VERS-TLS1.2", + "VERS-TLS1.3", + "VERS-TLS-ALL" + }; DEBUG_printf(("3_httpTLSStart(http=%p)", http)); @@ -1333,7 +1368,7 @@ _httpTLSStart(http_t *http) /* I - Connection to server */ keyfile[1024]; /* Private key file */ int have_creds = 0; /* Have credentials? */ - if (http->fields[HTTP_FIELD_HOST][0]) + if (http->fields[HTTP_FIELD_HOST]) { /* * Use hostname for TLS upgrade... @@ -1505,21 +1540,50 @@ _httpTLSStart(http_t *http) /* I - Connection to server */ strlcpy(priority_string, "NORMAL", sizeof(priority_string)); - if (tls_options & _HTTP_TLS_DENY_TLS10) - strlcat(priority_string, ":+VERS-TLS-ALL:-VERS-TLS1.0:-VERS-SSL3.0", sizeof(priority_string)); - else if (tls_options & _HTTP_TLS_ALLOW_SSL3) - strlcat(priority_string, ":+VERS-TLS-ALL", sizeof(priority_string)); + if (tls_max_version < _HTTP_TLS_MAX) + { + /* + * Require specific TLS versions... + */ + + strlcat(priority_string, ":-VERS-TLS-ALL", sizeof(priority_string)); + for (version = tls_min_version; version <= tls_max_version; version ++) + { + strlcat(priority_string, ":+", sizeof(priority_string)); + strlcat(priority_string, versions[version], sizeof(priority_string)); + } + } + else if (tls_min_version == _HTTP_TLS_SSL3) + { + /* + * Allow all versions of TLS and SSL/3.0... + */ + + strlcat(priority_string, ":+VERS-TLS-ALL:+VERS-SSL3.0", sizeof(priority_string)); + } else - strlcat(priority_string, ":+VERS-TLS-ALL:-VERS-SSL3.0", sizeof(priority_string)); + { + /* + * Require a minimum version... + */ - if (!(tls_options & _HTTP_TLS_ALLOW_RC4)) - strlcat(priority_string, ":-ARCFOUR-128", sizeof(priority_string)); + strlcat(priority_string, ":+VERS-TLS-ALL", sizeof(priority_string)); + for (version = 0; version < tls_min_version; version ++) + { + strlcat(priority_string, ":-", sizeof(priority_string)); + strlcat(priority_string, versions[version], sizeof(priority_string)); + } + } - if (!(tls_options & _HTTP_TLS_ALLOW_DH)) - strlcat(priority_string, ":!ANON-DH", sizeof(priority_string)); + if (tls_options & _HTTP_TLS_ALLOW_RC4) + strlcat(priority_string, ":+ARCFOUR-128", sizeof(priority_string)); + else + strlcat(priority_string, ":!ARCFOUR-128", sizeof(priority_string)); - if (!(tls_options & _HTTP_TLS_DENY_CBC)) - strlcat(priority_string, ":!CBC", sizeof(priority_string)); + strlcat(priority_string, ":!ANON-DH", sizeof(priority_string)); + + if (tls_options & _HTTP_TLS_DENY_CBC) + strlcat(priority_string, ":!AES-128-CBC:!AES-256-CBC:!CAMELLIA-128-CBC:!CAMELLIA-256-CBC:!3DES-CBC", sizeof(priority_string)); #ifdef HAVE_GNUTLS_PRIORITY_SET_DIRECT gnutls_priority_set_direct(http->tls, priority_string, NULL); @@ -1539,6 +1603,24 @@ _httpTLSStart(http_t *http) /* I - Connection to server */ #endif /* HAVE_GNUTLS_TRANSPORT_SET_PULL_TIMEOUT_FUNCTION */ gnutls_transport_set_push_function(http->tls, http_gnutls_write); + /* + * Enforce a minimum timeout of 10 seconds for the TLS handshake... + */ + + old_timeout = http->timeout_value; + old_cb = http->timeout_cb; + old_data = http->timeout_data; + + if (!old_cb || old_timeout < 10.0) + { + DEBUG_puts("4_httpTLSStart: Setting timeout to 10 seconds."); + httpSetTimeout(http, 10.0, NULL, NULL); + } + + /* + * Do the TLS handshake... + */ + while ((status = gnutls_handshake(http->tls)) != GNUTLS_E_SUCCESS) { DEBUG_printf(("5_httpStartTLS: gnutls_handshake returned %d (%s)", @@ -1556,10 +1638,18 @@ _httpTLSStart(http_t *http) /* I - Connection to server */ free(credentials); http->tls = NULL; + httpSetTimeout(http, old_timeout, old_cb, old_data); + return (-1); } } + /* + * Restore the previous timeout settings... + */ + + httpSetTimeout(http, old_timeout, old_cb, old_data); + http->tls_credentials = credentials; return (0); @@ -1576,9 +1666,7 @@ _httpTLSStop(http_t *http) /* I - Connection to server */ int error; /* Error code */ - // 12/06/2018 Mopria-notice: Using GNUTLS_SHUT_RDWR causes a 30 seconds timeout - // when the server does not respond with the shut down message - error = gnutls_bye(http->tls, GNUTLS_SHUT_WR); + error = gnutls_bye(http->tls, http->mode == _HTTP_MODE_CLIENT ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR); if (error != GNUTLS_E_SUCCESS) _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gnutls_strerror(errno), 0); diff --git a/cups/tls-sspi.c b/cups/tls-sspi.c index 77b883b..6e3c03b 100644 --- a/cups/tls-sspi.c +++ b/cups/tls-sspi.c @@ -2,15 +2,9 @@ * TLS support for CUPS on Windows using the Security Support Provider * Interface (SSPI). * - * Copyright 2010-2015 by Apple Inc. + * Copyright 2010-2018 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /**** This file is included from tls.c ****/ @@ -52,7 +46,9 @@ * Local globals... */ -static int tls_options = -1;/* Options for TLS connections */ +static int tls_options = -1,/* Options for TLS connections */ + tls_min_version = _HTTP_TLS_1_0, + tls_max_version = _HTTP_TLS_MAX; /* @@ -190,7 +186,7 @@ httpCredentialsAreValidForName( if (cert) { - if (CertNameToStr(X509_ASN_ENCODING, &(cert->pCertInfo->Subject), CERT_SIMPLE_NAME_STR, cert_name, sizeof(cert_name))) + if (CertNameToStrA(X509_ASN_ENCODING, &(cert->pCertInfo->Subject), CERT_SIMPLE_NAME_STR, cert_name, sizeof(cert_name))) { /* * Extract common name at end... @@ -351,7 +347,6 @@ httpCredentialsString( SYSTEMTIME systime; /* System time */ struct tm tm; /* UNIX date/time */ time_t expiration; /* Expiration date of cert */ - _cups_md5_state_t md5_state; /* MD5 state */ unsigned char md5_digest[16]; /* MD5 result */ FileTimeToSystemTime(&(cert->pCertInfo->NotAfter), &systime); @@ -365,7 +360,7 @@ httpCredentialsString( expiration = mktime(&tm); - if (CertNameToStr(X509_ASN_ENCODING, &(cert->pCertInfo->Subject), CERT_SIMPLE_NAME_STR, cert_name, sizeof(cert_name))) + if (CertNameToStrA(X509_ASN_ENCODING, &(cert->pCertInfo->Subject), CERT_SIMPLE_NAME_STR, cert_name, sizeof(cert_name))) { /* * Extract common name at end... @@ -378,9 +373,7 @@ httpCredentialsString( else strlcpy(cert_name, "unknown", sizeof(cert_name)); - _cupsMD5Init(&md5_state); - _cupsMD5Append(&md5_state, first->data, (int)first->datalen); - _cupsMD5Finish(&md5_state, md5_digest); + cupsHashData("md5", first->data, first->datalen, md5_digest, sizeof(md5_digest)); snprintf(buffer, bufsize, "%s / %s / %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", cert_name, httpGetDateString(expiration), md5_digest[0], md5_digest[1], md5_digest[2], md5_digest[3], md5_digest[4], md5_digest[5], md5_digest[6], md5_digest[7], md5_digest[8], md5_digest[9], md5_digest[10], md5_digest[11], md5_digest[12], md5_digest[13], md5_digest[14], md5_digest[15]); @@ -474,7 +467,7 @@ httpLoadCredentials( dwSize = 0; - if (!CertStrToName(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL)) + if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL)) { DEBUG_printf(("1httpLoadCredentials: CertStrToName failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError()))); goto cleanup; @@ -488,7 +481,7 @@ httpLoadCredentials( goto cleanup; } - if (!CertStrToName(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL)) + if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL)) { DEBUG_printf(("1httpLoadCredentials: CertStrToName failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError()))); goto cleanup; @@ -597,7 +590,7 @@ httpSaveCredentials( dwSize = 0; - if (!CertStrToName(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL)) + if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL)) { DEBUG_printf(("1httpSaveCredentials: CertStrToName failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError()))); goto cleanup; @@ -611,7 +604,7 @@ httpSaveCredentials( goto cleanup; } - if (!CertStrToName(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL)) + if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL)) { DEBUG_printf(("1httpSaveCredentials: CertStrToName failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError()))); goto cleanup; @@ -911,9 +904,16 @@ _httpTLSRead(http_t *http, /* I - HTTP connection */ */ void -_httpTLSSetOptions(int options) /* I - Options */ +_httpTLSSetOptions(int options, /* I - Options */ + int min_version, /* I - Minimum TLS version */ + int max_version) /* I - Maximum TLS version */ { - tls_options = options; + if (!(options & _HTTP_TLS_SET_DEFAULT) || tls_options < 0) + { + tls_options = options; + tls_min_version = min_version; + tls_max_version = max_version; + } } @@ -970,7 +970,7 @@ _httpTLSStart(http_t *http) /* I - HTTP connection */ * Server: determine hostname to use... */ - if (http->fields[HTTP_FIELD_HOST][0]) + if (http->fields[HTTP_FIELD_HOST]) { /* * Use hostname for TLS upgrade... @@ -1350,7 +1350,7 @@ http_sspi_client(http_t *http, /* I - Client connection */ */ dwSize = sizeof(username); - GetUserName(username, &dwSize); + GetUserNameA(username, &dwSize); snprintf(common_name, sizeof(common_name), "CN=%s", username); if (!http_sspi_find_credentials(http, L"ClientContainer", common_name)) @@ -1713,7 +1713,7 @@ http_sspi_find_credentials( dwSize = 0; - if (!CertStrToName(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL)) + if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL)) { DEBUG_printf(("5http_sspi_find_credentials: CertStrToName failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); ok = FALSE; @@ -1729,7 +1729,7 @@ http_sspi_find_credentials( goto cleanup; } - if (!CertStrToName(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL)) + if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL)) { DEBUG_printf(("5http_sspi_find_credentials: CertStrToName failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); ok = FALSE; @@ -1761,18 +1761,22 @@ http_sspi_find_credentials( #ifdef SP_PROT_TLS1_2_SERVER if (http->mode == _HTTP_MODE_SERVER) { - if (tls_options & _HTTP_TLS_DENY_TLS10) + if (tls_min_version > _HTTP_TLS_1_1) + SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER; + else if (tls_min_version > _HTTP_TLS_1_0) SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER | SP_PROT_TLS1_1_SERVER; - else if (tls_options & _HTTP_TLS_ALLOW_SSL3) + else if (tls_min_version == _HTTP_TLS_SSL3) SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER | SP_PROT_TLS1_1_SERVER | SP_PROT_TLS1_0_SERVER | SP_PROT_SSL3_SERVER; else SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER | SP_PROT_TLS1_1_SERVER | SP_PROT_TLS1_0_SERVER; } else { - if (tls_options & _HTTP_TLS_DENY_TLS10) + if (tls_min_version > _HTTP_TLS_1_1) + SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT; + else if (tls_min_version > _HTTP_TLS_1_0) SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_1_CLIENT; - else if (tls_options & _HTTP_TLS_ALLOW_SSL3) + else if (tls_min_version == _HTTP_TLS_SSL3) SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_0_CLIENT | SP_PROT_SSL3_CLIENT; else SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_0_CLIENT; @@ -1781,14 +1785,14 @@ http_sspi_find_credentials( #else if (http->mode == _HTTP_MODE_SERVER) { - if (tls_options & _HTTP_TLS_ALLOW_SSL3) + if (tls_min_version == _HTTP_TLS_SSL3) SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_SERVER | SP_PROT_SSL3_SERVER; else SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_SERVER; } else { - if (tls_options & _HTTP_TLS_ALLOW_SSL3) + if (tls_min_version == _HTTP_TLS_SSL3) SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT | SP_PROT_SSL3_CLIENT; else SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT; @@ -1920,7 +1924,7 @@ http_sspi_make_credentials( dwSize = 0; - if (!CertStrToName(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL)) + if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL)) { DEBUG_printf(("5http_sspi_make_credentials: CertStrToName failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); ok = FALSE; @@ -1936,7 +1940,7 @@ http_sspi_make_credentials( goto cleanup; } - if (!CertStrToName(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL)) + if (!CertStrToNameA(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL)) { DEBUG_printf(("5http_sspi_make_credentials: CertStrToName failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError()))); ok = FALSE; @@ -2292,7 +2296,7 @@ http_sspi_strerror(char *buffer, /* I - Error message buffer */ size_t bufsize, /* I - Size of buffer */ DWORD code) /* I - Error code */ { - if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, code, 0, buffer, bufsize, NULL)) + if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, code, 0, buffer, bufsize, NULL)) { /* * Strip trailing CR + LF... diff --git a/cups/tls.c b/cups/tls.c index 36d484c..5caa84d 100644 --- a/cups/tls.c +++ b/cups/tls.c @@ -7,13 +7,7 @@ * This file contains Kerberos support code, copyright 2006 by * Jelmer Vernooij. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -21,22 +15,23 @@ */ #include "cups-private.h" +#include "debug-internal.h" #include #include -#ifdef WIN32 +#ifdef _WIN32 # include #else # include # include # include -#endif /* WIN32 */ +#endif /* _WIN32 */ #ifdef HAVE_POLL # include #endif /* HAVE_POLL */ /* - * Local functions... + * Include platform-specific TLS code... */ #ifdef HAVE_SSL diff --git a/cups/tlscheck.c b/cups/tlscheck.c index 32cbcca..c88e7d0 100644 --- a/cups/tlscheck.c +++ b/cups/tlscheck.c @@ -1,16 +1,10 @@ /* * TLS check program for CUPS. * - * Copyright 2007-2015 by Apple Inc. + * Copyright 2007-2017 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -43,6 +37,8 @@ main(int argc, /* I - Number of command-line arguments */ http_t *http; /* HTTP connection */ const char *server = NULL; /* Hostname from command-line */ int port = 0; /* Port number */ + cups_array_t *creds; /* Server credentials */ + char creds_str[2048]; /* Credentials string */ const char *cipherName = "UNKNOWN";/* Cipher suite name */ int dhBits = 0; /* Diffie-Hellman bits */ int tlsVersion = 0; /* TLS version number */ @@ -54,6 +50,8 @@ main(int argc, /* I - Number of command-line arguments */ int af = AF_UNSPEC, /* Address family */ tls_options = _HTTP_TLS_NONE, /* TLS options */ + tls_min_version = _HTTP_TLS_1_0, + tls_max_version = _HTTP_TLS_MAX, verbose = 0; /* Verbosity */ ipp_t *request, /* IPP Get-Printer-Attributes request */ *response; /* IPP Get-Printer-Attributes response */ @@ -82,9 +80,33 @@ main(int argc, /* I - Number of command-line arguments */ { tls_options |= _HTTP_TLS_ALLOW_DH; } + else if (!strcmp(argv[i], "--no-cbc")) + { + tls_options |= _HTTP_TLS_DENY_CBC; + } else if (!strcmp(argv[i], "--no-tls10")) { - tls_options |= _HTTP_TLS_DENY_TLS10; + tls_min_version = _HTTP_TLS_1_1; + } + else if (!strcmp(argv[i], "--tls10")) + { + tls_min_version = _HTTP_TLS_1_0; + tls_max_version = _HTTP_TLS_1_0; + } + else if (!strcmp(argv[i], "--tls11")) + { + tls_min_version = _HTTP_TLS_1_1; + tls_max_version = _HTTP_TLS_1_1; + } + else if (!strcmp(argv[i], "--tls12")) + { + tls_min_version = _HTTP_TLS_1_2; + tls_max_version = _HTTP_TLS_1_2; + } + else if (!strcmp(argv[i], "--tls13")) + { + tls_min_version = _HTTP_TLS_1_3; + tls_max_version = _HTTP_TLS_1_3; } else if (!strcmp(argv[i], "--rc4")) { @@ -140,7 +162,7 @@ main(int argc, /* I - Number of command-line arguments */ if (!port) port = 631; - _httpTLSSetOptions(tls_options); + _httpTLSSetOptions(tls_options, tls_min_version, tls_max_version); http = httpConnect2(server, port, NULL, af, HTTP_ENCRYPTION_ALWAYS, 1, 30000, NULL); if (!http) @@ -149,6 +171,16 @@ main(int argc, /* I - Number of command-line arguments */ return (1); } + if (httpCopyCredentials(http, &creds)) + { + strlcpy(creds_str, "Unable to get server X.509 credentials.", sizeof(creds_str)); + } + else + { + httpCredentialsString(creds, creds_str, sizeof(creds_str)); + httpFreeCredentials(creds); + } + #ifdef __APPLE__ SSLProtocol protocol; SSLCipherSuite cipher; @@ -686,6 +718,8 @@ main(int argc, /* I - Number of command-line arguments */ else printf("%s: OK (TLS: %d.%d, %s)\n", server, tlsVersion / 10, tlsVersion % 10, cipherName); + printf(" %s\n", creds_str); + if (verbose) { httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipps", NULL, host, port, resource); @@ -709,6 +743,7 @@ main(int argc, /* I - Number of command-line arguments */ } ippDelete(response); + puts(""); } httpClose(http); @@ -729,8 +764,13 @@ usage(void) puts(""); puts("Options:"); puts(" --dh Allow DH/DHE key exchange"); + puts(" --no-cbc Disable CBC cipher suites"); puts(" --no-tls10 Disable TLS/1.0"); puts(" --rc4 Allow RC4 encryption"); + puts(" --tls10 Only use TLS/1.0"); + puts(" --tls11 Only use TLS/1.1"); + puts(" --tls12 Only use TLS/1.2"); + puts(" --tls13 Only use TLS/1.3"); puts(" --verbose Be verbose"); puts(" -4 Connect using IPv4 addresses only"); puts(" -6 Connect using IPv6 addresses only"); diff --git a/cups/transcode.c b/cups/transcode.c index 6f73a42..4267813 100644 --- a/cups/transcode.c +++ b/cups/transcode.c @@ -4,13 +4,7 @@ * Copyright 2007-2014 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -18,6 +12,7 @@ */ #include "cups-private.h" +#include "debug-internal.h" #include #include #ifdef HAVE_ICONV_H diff --git a/cups/transcode.h b/cups/transcode.h index cd12cb5..844de4d 100644 --- a/cups/transcode.h +++ b/cups/transcode.h @@ -4,13 +4,7 @@ * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ #ifndef _CUPS_TRANSCODE_H_ diff --git a/cups/usersys.c b/cups/usersys.c index ff5cb30..497681e 100644 --- a/cups/usersys.c +++ b/cups/usersys.c @@ -1,16 +1,11 @@ /* * User, system, and password routines for CUPS. * - * Copyright 2007-2017 by Apple Inc. + * Copyright 2007-2019 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -18,15 +13,19 @@ */ #include "cups-private.h" +#include "debug-internal.h" #include #include -#ifdef WIN32 +#ifdef _WIN32 # include #else # include # include # include -#endif /* WIN32 */ +#endif /* _WIN32 */ +#ifdef __APPLE__ +# include +#endif /* __APPLE__ */ /* @@ -34,14 +33,25 @@ */ #ifdef __APPLE__ -# define kCUPSPrintingPrefs CFSTR("org.cups.PrintingPrefs") -# define kAllowAnyRootKey CFSTR("AllowAnyRoot") -# define kAllowExpiredCertsKey CFSTR("AllowExpiredCerts") -# define kEncryptionKey CFSTR("Encryption") -# define kGSSServiceNameKey CFSTR("GSSServiceName") -# define kSSLOptionsKey CFSTR("SSLOptions") -# define kTrustOnFirstUseKey CFSTR("TrustOnFirstUse") -# define kValidateCertsKey CFSTR("ValidateCerts") +# if TARGET_OS_OSX +# define kCUPSPrintingPrefs CFSTR("org.cups.PrintingPrefs") +# define kPREFIX "" +# else +# define kCUPSPrintingPrefs CFSTR(".GlobalPreferences") +# define kPREFIX "AirPrint" +# endif /* TARGET_OS_OSX */ +# define kUserAgentTokensKey CFSTR(kPREFIX "UserAgentTokens") +# define kAllowAnyRootKey CFSTR(kPREFIX "AllowAnyRoot") +# define kAllowExpiredCertsKey CFSTR(kPREFIX "AllowExpiredCerts") +# define kEncryptionKey CFSTR(kPREFIX "Encryption") +# define kGSSServiceNameKey CFSTR(kPREFIX "GSSServiceName") +# define kSSLOptionsKey CFSTR(kPREFIX "SSLOptions") +# define kTrustOnFirstUseKey CFSTR(kPREFIX "TrustOnFirstUse") +# define kValidateCertsKey CFSTR(kPREFIX "ValidateCerts") +/* Deprecated */ +# define kAllowRC4 CFSTR(kPREFIX "AllowRC4") +# define kAllowSSL3 CFSTR(kPREFIX "AllowSSL3") +# define kAllowDH CFSTR(kPREFIX "AllowDH") #endif /* __APPLE__ */ #define _CUPS_PASSCHAR '*' /* Character that is echoed for password */ @@ -53,8 +63,11 @@ typedef struct _cups_client_conf_s /**** client.conf config data ****/ { + _cups_uatokens_t uatokens; /* UserAgentTokens values */ #ifdef HAVE_SSL - int ssl_options; /* SSLOptions values */ + int ssl_options, /* SSLOptions values */ + ssl_min_version,/* Minimum SSL/TLS version */ + ssl_max_version;/* Maximum SSL/TLS version */ #endif /* HAVE_SSL */ int trust_first, /* Trust on first use? */ any_root, /* Allow any (e.g., self-signed) root */ @@ -92,6 +105,7 @@ static void cups_set_server_name(_cups_client_conf_t *cc, const char *value); #ifdef HAVE_SSL static void cups_set_ssl_options(_cups_client_conf_t *cc, const char *value); #endif /* HAVE_SSL */ +static void cups_set_uatokens(_cups_client_conf_t *cc, const char *value); static void cups_set_user(_cups_client_conf_t *cc, const char *value); @@ -488,12 +502,17 @@ cupsSetUserAgent(const char *user_agent)/* I - User-Agent string or @code NULL@ { _cups_globals_t *cg = _cupsGlobals(); /* Thread globals */ -#ifdef WIN32 +#ifdef _WIN32 SYSTEM_INFO sysinfo; /* System information */ - OSVERSIONINFO version; /* OS version info */ + OSVERSIONINFOA version; /* OS version info */ + const char *machine; /* Hardware/machine name */ +#elif defined(__APPLE__) + struct utsname name; /* uname info */ + char version[256]; /* macOS/iOS version */ + size_t len; /* Length of value */ #else struct utsname name; /* uname info */ -#endif /* WIN32 */ +#endif /* _WIN32 */ if (user_agent) @@ -502,31 +521,104 @@ cupsSetUserAgent(const char *user_agent)/* I - User-Agent string or @code NULL@ return; } -#ifdef WIN32 + if (cg->uatokens < _CUPS_UATOKENS_OS) + { + switch (cg->uatokens) + { + default : + case _CUPS_UATOKENS_NONE : + cg->user_agent[0] = '\0'; + break; + case _CUPS_UATOKENS_PRODUCT_ONLY : + strlcpy(cg->user_agent, "CUPS IPP", sizeof(cg->user_agent)); + break; + case _CUPS_UATOKENS_MAJOR : + snprintf(cg->user_agent, sizeof(cg->user_agent), "CUPS/%d IPP/2", CUPS_VERSION_MAJOR); + break; + case _CUPS_UATOKENS_MINOR : + snprintf(cg->user_agent, sizeof(cg->user_agent), "CUPS/%d.%d IPP/2.1", CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR); + break; + case _CUPS_UATOKENS_MINIMAL : + strlcpy(cg->user_agent, CUPS_MINIMAL " IPP/2.1", sizeof(cg->user_agent)); + break; + } + } + +#ifdef _WIN32 + /* + * Gather Windows version information for the User-Agent string... + */ + version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&version); + GetVersionExA(&version); GetNativeSystemInfo(&sysinfo); - snprintf(cg->user_agent, sizeof(cg->user_agent), - CUPS_MINIMAL " (Windows %d.%d; %s) IPP/2.0", - version.dwMajorVersion, version.dwMinorVersion, - sysinfo.wProcessorArchitecture - == PROCESSOR_ARCHITECTURE_AMD64 ? "amd64" : - sysinfo.wProcessorArchitecture - == PROCESSOR_ARCHITECTURE_ARM ? "arm" : - sysinfo.wProcessorArchitecture - == PROCESSOR_ARCHITECTURE_IA64 ? "ia64" : - sysinfo.wProcessorArchitecture - == PROCESSOR_ARCHITECTURE_INTEL ? "intel" : - "unknown"); + switch (sysinfo.wProcessorArchitecture) + { + case PROCESSOR_ARCHITECTURE_AMD64 : + machine = "amd64"; + break; + + case PROCESSOR_ARCHITECTURE_ARM : + machine = "arm"; + break; + + case PROCESSOR_ARCHITECTURE_IA64 : + machine = "ia64"; + break; + + case PROCESSOR_ARCHITECTURE_INTEL : + machine = "intel"; + break; + + default : + machine = "unknown"; + break; + } + + if (cg->uatokens == _CUPS_UATOKENS_OS) + snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (Windows %d.%d) IPP/2.0", version.dwMajorVersion, version.dwMinorVersion); + else + snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (Windows %d.%d; %s) IPP/2.0", version.dwMajorVersion, version.dwMinorVersion, machine); + +#elif defined(__APPLE__) + /* + * Gather macOS/iOS version information for the User-Agent string... + */ -#else uname(&name); - snprintf(cg->user_agent, sizeof(cg->user_agent), - CUPS_MINIMAL " (%s %s; %s) IPP/2.0", - name.sysname, name.release, name.machine); -#endif /* WIN32 */ + len = sizeof(version) - 1; + if (!sysctlbyname("kern.osproductversion", version, &len, NULL, 0)) + version[len] = '\0'; + else + strlcpy(version, "unknown", sizeof(version)); + +# if TARGET_OS_OSX + if (cg->uatokens == _CUPS_UATOKENS_OS) + snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (macOS %s) IPP/2.0", version); + else + snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (macOS %s; %s) IPP/2.0", version, name.machine); + +# else + if (cg->uatokens == _CUPS_UATOKENS_OS) + snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (iOS %s) IPP/2.0", version); + else + snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (iOS %s; %s) IPP/2.0", version, name.machine); +# endif /* TARGET_OS_OSX */ + +#else + /* + * Gather generic UNIX version information for the User-Agent string... + */ + + uname(&name); + + if (cg->uatokens == _CUPS_UATOKENS_OS) + snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (%s %s) IPP/2.0", name.sysname, name.release); + else + snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (%s %s; %s) IPP/2.0", name.sysname, name.release, name.machine); +#endif /* _WIN32 */ } @@ -578,7 +670,7 @@ cupsUserAgent(void) const char * /* O - Password or @code NULL@ if none */ _cupsGetPassword(const char *prompt) /* I - Prompt string */ { -#ifdef WIN32 +#ifdef _WIN32 HANDLE tty; /* Console handle */ DWORD mode; /* Console mode */ char passch, /* Current key press */ @@ -844,7 +936,7 @@ _cupsGetPassword(const char *prompt) /* I - Prompt string */ memset(cg->password, 0, sizeof(cg->password)); return (NULL); } -#endif /* WIN32 */ +#endif /* _WIN32 */ } @@ -903,7 +995,7 @@ _cupsSetDefaults(void) # ifdef HAVE_GETEUID if ((geteuid() == getuid() || !getuid()) && getegid() == getgid() && (home = getenv("HOME")) != NULL) -# elif !defined(WIN32) +# elif !defined(_WIN32) if (getuid() && (home = getenv("HOME")) != NULL) # else if ((home = getenv("HOME")) != NULL) @@ -927,6 +1019,8 @@ _cupsSetDefaults(void) cups_finalize_client_conf(&cc); + cg->uatokens = cc.uatokens; + if (cg->encryption == (http_encryption_t)-1) cg->encryption = cc.encryption; @@ -957,7 +1051,7 @@ _cupsSetDefaults(void) cg->validate_certs = cc.validate_certs; #ifdef HAVE_SSL - _httpTLSSetOptions(cc.ssl_options); + _httpTLSSetOptions(cc.ssl_options | _HTTP_TLS_SET_DEFAULT, cc.ssl_min_version, cc.ssl_max_version); #endif /* HAVE_SSL */ } @@ -1084,22 +1178,27 @@ cups_finalize_client_conf( if (!cc->server_name[0]) { -#ifdef CUPS_DEFAULT_DOMAINSOCKET /* * If we are compiled with domain socket support, only use the * domain socket if it exists and has the right permissions... */ +#if defined(__APPLE__) && !TARGET_OS_OSX + cups_set_server_name(cc, "/private/var/run/printd"); + +#else +# ifdef CUPS_DEFAULT_DOMAINSOCKET if (!access(CUPS_DEFAULT_DOMAINSOCKET, R_OK)) cups_set_server_name(cc, CUPS_DEFAULT_DOMAINSOCKET); else -#endif /* CUPS_DEFAULT_DOMAINSOCKET */ - cups_set_server_name(cc, "localhost"); +# endif /* CUPS_DEFAULT_DOMAINSOCKET */ + cups_set_server_name(cc, "localhost"); +#endif /* __APPLE__ && !TARGET_OS_OSX */ } if (!cc->user[0]) { -#ifdef WIN32 +#ifdef _WIN32 /* * Get the current user name from the OS... */ @@ -1107,7 +1206,7 @@ cups_finalize_client_conf( DWORD size; /* Size of string */ size = sizeof(cc->user); - if (!GetUserName(cc->user, &size)) + if (!GetUserNameA(cc->user, &size)) #else /* * Try the USER environment variable as the default username... @@ -1135,7 +1234,7 @@ cups_finalize_client_conf( if (pw) strlcpy(cc->user, pw->pw_name, sizeof(cc->user)); else -#endif /* WIN32 */ +#endif /* _WIN32 */ { /* * Use the default "unknown" user name... @@ -1164,19 +1263,30 @@ cups_init_client_conf( memset(cc, 0, sizeof(_cups_client_conf_t)); - cc->encryption = (http_encryption_t)-1; - cc->trust_first = -1; - cc->any_root = -1; - cc->expired_certs = -1; - cc->validate_certs = -1; + cc->uatokens = _CUPS_UATOKENS_MINIMAL; + +#if defined(__APPLE__) && !TARGET_OS_OSX + cups_set_user(cc, "mobile"); +#endif /* __APPLE__ && !TARGET_OS_OSX */ + +#ifdef HAVE_SSL + cc->ssl_min_version = _HTTP_TLS_1_0; + cc->ssl_max_version = _HTTP_TLS_MAX; +#endif /* HAVE_SSL */ + cc->encryption = (http_encryption_t)-1; + cc->trust_first = -1; + cc->any_root = -1; + cc->expired_certs = -1; + cc->validate_certs = -1; /* * Load settings from the org.cups.PrintingPrefs plist (which trump * everything...) */ -#ifdef __APPLE__ +#if defined(__APPLE__) char sval[1024]; /* String value */ +# ifdef HAVE_SSL int bval; /* Boolean value */ if (cups_apple_get_boolean(kAllowAnyRootKey, &bval)) @@ -1189,13 +1299,35 @@ cups_init_client_conf( cups_set_encryption(cc, sval); if (cups_apple_get_string(kSSLOptionsKey, sval, sizeof(sval))) + { cups_set_ssl_options(cc, sval); + } + else + { + sval[0] = '\0'; + + if (cups_apple_get_boolean(kAllowRC4, &bval) && bval) + strlcat(sval, " AllowRC4", sizeof(sval)); + if (cups_apple_get_boolean(kAllowSSL3, &bval) && bval) + strlcat(sval, " AllowSSL3", sizeof(sval)); + if (cups_apple_get_boolean(kAllowDH, &bval) && bval) + strlcat(sval, " AllowDH", sizeof(sval)); + + if (sval[0]) + cups_set_ssl_options(cc, sval); + } if (cups_apple_get_boolean(kTrustOnFirstUseKey, &bval)) cc->trust_first = bval; if (cups_apple_get_boolean(kValidateCertsKey, &bval)) cc->validate_certs = bval; +# endif /* HAVE_SSL */ + + if (cups_apple_get_string(kUserAgentTokensKey, sval, sizeof(sval))) + { + cups_set_uatokens(cc, sval); + } #endif /* __APPLE__ */ } @@ -1233,6 +1365,8 @@ cups_read_client_conf( #endif /* !__APPLE__ */ else if (!_cups_strcasecmp(line, "User") && value) cups_set_user(cc, value); + else if (!_cups_strcasecmp(line, "UserAgentTokens") && value) + cups_set_uatokens(cc, value); else if (!_cups_strcasecmp(line, "TrustOnFirstUse") && value) cc->trust_first = cups_boolean_value(value); else if (!_cups_strcasecmp(line, "AllowAnyRoot") && value) @@ -1336,7 +1470,9 @@ cups_set_ssl_options( * SSLOptions [AllowRC4] [AllowSSL3] [AllowDH] [DenyTLS1.0] [None] */ - int options = _HTTP_TLS_NONE; /* SSL/TLS options */ + int options = _HTTP_TLS_NONE, /* SSL/TLS options */ + min_version = _HTTP_TLS_1_0, /* Minimum SSL/TLS version */ + max_version = _HTTP_TLS_MAX; /* Maximum SSL/TLS version */ char temp[256], /* Copy of value */ *start, /* Start of option */ *end; /* End of option */ @@ -1364,24 +1500,74 @@ cups_set_ssl_options( if (!_cups_strcasecmp(start, "AllowRC4")) options |= _HTTP_TLS_ALLOW_RC4; else if (!_cups_strcasecmp(start, "AllowSSL3")) - options |= _HTTP_TLS_ALLOW_SSL3; + min_version = _HTTP_TLS_SSL3; else if (!_cups_strcasecmp(start, "AllowDH")) options |= _HTTP_TLS_ALLOW_DH; else if (!_cups_strcasecmp(start, "DenyCBC")) options |= _HTTP_TLS_DENY_CBC; else if (!_cups_strcasecmp(start, "DenyTLS1.0")) - options |= _HTTP_TLS_DENY_TLS10; + min_version = _HTTP_TLS_1_1; + else if (!_cups_strcasecmp(start, "MaxTLS1.0")) + max_version = _HTTP_TLS_1_0; + else if (!_cups_strcasecmp(start, "MaxTLS1.1")) + max_version = _HTTP_TLS_1_1; + else if (!_cups_strcasecmp(start, "MaxTLS1.2")) + max_version = _HTTP_TLS_1_2; + else if (!_cups_strcasecmp(start, "MaxTLS1.3")) + max_version = _HTTP_TLS_1_3; + else if (!_cups_strcasecmp(start, "MinTLS1.0")) + min_version = _HTTP_TLS_1_0; + else if (!_cups_strcasecmp(start, "MinTLS1.1")) + min_version = _HTTP_TLS_1_1; + else if (!_cups_strcasecmp(start, "MinTLS1.2")) + min_version = _HTTP_TLS_1_2; + else if (!_cups_strcasecmp(start, "MinTLS1.3")) + min_version = _HTTP_TLS_1_3; else if (!_cups_strcasecmp(start, "None")) options = _HTTP_TLS_NONE; } - cc->ssl_options = options; + cc->ssl_options = options; + cc->ssl_max_version = max_version; + cc->ssl_min_version = min_version; - DEBUG_printf(("4cups_set_ssl_options(cc=%p, value=\"%s\") options=%x", (void *)cc, value, options)); + DEBUG_printf(("4cups_set_ssl_options(cc=%p, value=\"%s\") options=%x, min_version=%d, max_version=%d", (void *)cc, value, options, min_version, max_version)); } #endif /* HAVE_SSL */ +/* + * 'cups_set_uatokens()' - Set the UserAgentTokens value. + */ + +static void +cups_set_uatokens( + _cups_client_conf_t *cc, /* I - client.conf values */ + const char *value) /* I - Value */ +{ + int i; /* Looping var */ + static const char * const uatokens[] =/* UserAgentTokens values */ + { + "NONE", + "PRODUCTONLY", + "MAJOR", + "MINOR", + "MINIMAL", + "OS", + "FULL" + }; + + for (i = 0; i < (int)(sizeof(uatokens) / sizeof(uatokens[0])); i ++) + { + if (!_cups_strcasecmp(value, uatokens[i])) + { + cc->uatokens = (_cups_uatokens_t)i; + return; + } + } +} + + /* * 'cups_set_user()' - Set the User value. */ diff --git a/cups/util.c b/cups/util.c index 2f5ebdf..0961ac9 100644 --- a/cups/util.c +++ b/cups/util.c @@ -1,16 +1,11 @@ /* * Printing utilities for CUPS. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2006 by Easy Software Products. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -18,26 +13,14 @@ */ #include "cups-private.h" +#include "debug-internal.h" #include #include -#if defined(WIN32) || defined(__EMX__) +#if defined(_WIN32) || defined(__EMX__) # include #else # include -#endif /* WIN32 || __EMX__ */ - - -/* - * Enumeration data and callback... - */ - -typedef struct _cups_createdata_s -{ - const char *name; /* Destination name */ - cups_dest_t *dest; /* Matching destination */ -} _cups_createdata_t; - -static int cups_create_cb(_cups_createdata_t *data, unsigned flags, cups_dest_t *dest); +#endif /* _WIN32 || __EMX__ */ /* @@ -174,7 +157,7 @@ cupsCreateJob( { int job_id = 0; /* job-id value */ ipp_status_t status; /* Create-Job status */ - _cups_createdata_t data; /* Enumeration data */ + cups_dest_t *dest; /* Destination */ cups_dinfo_t *info; /* Destination information */ @@ -194,12 +177,7 @@ cupsCreateJob( * Lookup the destination... */ - data.name = name; - data.dest = NULL; - - cupsEnumDests(0, 1000, NULL, 0, 0, (cups_dest_cb_t)cups_create_cb, &data); - - if (!data.dest) + if ((dest = cupsGetNamedDest(http, name, NULL)) == NULL) { DEBUG_puts("1cupsCreateJob: Destination not found."); _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0); @@ -211,18 +189,18 @@ cupsCreateJob( */ DEBUG_puts("1cupsCreateJob: Querying destination info."); - if ((info = cupsCopyDestInfo(http, data.dest)) == NULL) + if ((info = cupsCopyDestInfo(http, dest)) == NULL) { DEBUG_puts("1cupsCreateJob: Query failed."); - cupsFreeDests(1, data.dest); + cupsFreeDests(1, dest); return (0); } - status = cupsCreateDestJob(http, data.dest, info, &job_id, title, num_options, options); + status = cupsCreateDestJob(http, dest, info, &job_id, title, num_options, options); DEBUG_printf(("1cupsCreateJob: cupsCreateDestJob returned %04x (%s)", status, ippErrorString(status))); cupsFreeDestInfo(info); - cupsFreeDests(1, data.dest); + cupsFreeDests(1, dest); /* * Return the job... @@ -974,25 +952,3 @@ cupsStartDocument( return (status); } - -/* - * 'cups_create_cb()' - Find the destination for printing. - */ - -static int /* O - 0 on match */ -cups_create_cb( - _cups_createdata_t *data, /* I - Data from cupsCreateJob call */ - unsigned flags, /* I - Enumeration flags */ - cups_dest_t *dest) /* I - Destination */ -{ - DEBUG_printf(("2cups_create_cb(data=%p(%s), flags=%08x, dest=%p(%s))", (void *)data, data->name, flags, (void *)dest, dest->name)); - - (void)flags; - - if (dest->instance || strcasecmp(data->name, dest->name)) - return (1); - - cupsCopyDest(dest, 0, &data->dest); - - return (0); -} diff --git a/cups/versioning.h b/cups/versioning.h index 5a000c0..14c218f 100644 --- a/cups/versioning.h +++ b/cups/versioning.h @@ -1,98 +1,51 @@ /* * API versioning definitions for CUPS. * - * Copyright 2007-2017 by Apple Inc. + * Copyright © 2007-2019 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ #ifndef _CUPS_VERSIONING_H_ # define _CUPS_VERSIONING_H_ /* - * This header defines several constants - _CUPS_DEPRECATED, - * _CUPS_DEPRECATED_MSG, _CUPS_INTERNAL_MSG, _CUPS_API_major_minor, and - * _CUPS_API_major_minor_patch - which add compiler-specific attributes that - * flag functions that are deprecated, added in particular releases, or internal - * to CUPS. + * This header defines several macros that add compiler-specific attributes for + * functions: * - * On macOS, the _CUPS_API_* constants are defined based on the values of - * the MAC_OS_X_VERSION_MIN_ALLOWED and MAC_OS_X_VERSION_MAX_ALLOWED constants - * provided by the compiler. + * - _CUPS_API_major_minor[_patch]: Specifies when an API became available by + * CUPS version. + * - _CUPS_DEPRECATED: Function is deprecated with no replacement. + * - _CUPS_DEPRECATED_MSG("message"): Function is deprecated and has a + * replacement. + * - _CUPS_FORMAT(format-index, additional-args-index): Function has a + * printf-style format argument followed by zero or more additional + * arguments. Indices start at 1. + * - _CUPS_INTERNAL: Function is internal with no replacement API. + * - _CUPS_INTERNAL_MSG("msg"): Function is internal - use specified API + * instead. + * - _CUPS_NONNULL((arg list)): Specifies the comma-separated argument indices + * are assumed non-NULL. Indices start at 1. + * - _CUPS_NORETURN: Specifies the function does not return. + * - _CUPS_PRIVATE: Specifies the function is private to CUPS. + * - _CUPS_PUBLIC: Specifies the function is public API. */ -# if defined(__APPLE__) && !defined(_CUPS_SOURCE) && !TARGET_OS_IOS -# include -# ifndef AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER -# define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER __attribute__((unavailable)) -# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER */ -# ifndef AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER -# define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER __attribute__((unavailable)) -# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER */ -# ifndef AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER -# define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER __attribute__((unavailable)) -# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER */ -# ifndef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER -# define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER __attribute__((unavailable)) -# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER */ -# ifndef AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER -# define AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER __attribute__((unavailable)) -# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER */ -# ifndef AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER -# define AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER __attribute__((unavailable)) -# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER */ -# ifndef AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER -# define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER __attribute__((unavailable)) -# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER */ -# ifndef AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER -# define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER __attribute__((unavailable)) -# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER */ -# ifndef AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER -# define AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER __attribute__((unavailable)) -# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER */ -# ifndef AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER -# define AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER __attribute__((unavailable)) -# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER */ -# define _CUPS_API_1_1_19 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER -# define _CUPS_API_1_1_20 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER -# define _CUPS_API_1_1_21 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER -# define _CUPS_API_1_2 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER -# define _CUPS_API_1_3 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER -# define _CUPS_API_1_4 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER -# define _CUPS_API_1_5 AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER -# define _CUPS_API_1_6 AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER -# define _CUPS_API_1_7 AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER -# define _CUPS_API_2_0 AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER -# define _CUPS_API_2_2 AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER -# define _CUPS_API_2_2_4 AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER -# else -# define _CUPS_API_1_1_19 -# define _CUPS_API_1_1_20 -# define _CUPS_API_1_1_21 -# define _CUPS_API_1_2 -# define _CUPS_API_1_3 -# define _CUPS_API_1_4 -# define _CUPS_API_1_5 -# define _CUPS_API_1_6 -# define _CUPS_API_1_7 -# define _CUPS_API_2_0 -# define _CUPS_API_2_2 -# define _CUPS_API_2_2_4 -# endif /* __APPLE__ && !_CUPS_SOURCE */ - /* - * With GCC and Clang we can mark old APIs as "deprecated" or "unavailable" with - * messages so you get warnings/errors are compile-time... + * Determine which compiler is being used and what annotation features are + * available... */ +# ifdef __APPLE__ +# include +# endif /* __APPLE__ */ + # ifdef __has_extension /* Clang */ # define _CUPS_HAS_DEPRECATED +# define _CUPS_HAS_FORMAT +# define _CUPS_HAS_NORETURN +# define _CUPS_HAS_VISIBILITY # if __has_extension(attribute_deprecated_with_message) # define _CUPS_HAS_DEPRECATED_WITH_MESSAGE # endif @@ -102,6 +55,9 @@ # elif defined(__GNUC__) /* GCC and compatible */ # if __GNUC__ >= 3 /* GCC 3.0 or higher */ # define _CUPS_HAS_DEPRECATED +# define _CUPS_HAS_FORMAT +# define _CUPS_HAS_NORETURN +# define _CUPS_HAS_VISIBILITY # endif /* __GNUC__ >= 3 */ # if __GNUC__ >= 5 /* GCC 5.x */ # define _CUPS_HAS_DEPRECATED_WITH_MESSAGE @@ -109,61 +65,203 @@ /* GCC 4.5 or higher */ # define _CUPS_HAS_DEPRECATED_WITH_MESSAGE # endif /* __GNUC__ >= 5 */ +# elif defined(_WIN32) +# define __attribute__(...) # endif /* __has_extension */ + +/* + * Define _CUPS_INTERNAL, _CUPS_PRIVATE, and _CUPS_PUBLIC visibilty macros for + * internal/private/public functions... + */ + +# ifdef _CUPS_HAS_VISIBILITY +# define _CUPS_INTERNAL __attribute__ ((visibility("hidden"))) +# define _CUPS_PRIVATE __attribute__ ((visibility("default"))) +# define _CUPS_PUBLIC __attribute__ ((visibility("default"))) +# elif defined(_WIN32) && defined(LIBCUPS2_EXPORTS) && 0 +# define _CUPS_INTERNAL +# define _CUPS_PRIVATE __declspec(dllexport) +# define _CUPS_PUBLIC __declspec(dllexport) +# else +# define _CUPS_INTERNAL +# define _CUPS_PRIVATE +# define _CUPS_PUBLIC +# endif /* _CUPS_HAS_VISIBILITY */ + + +/* + * Define _CUPS_API_major_minor[_patch] availability macros for CUPS. + * + * Note: Using any of the _CUPS_API macros automatically adds _CUPS_PUBLIC. + */ + +# if defined(__APPLE__) && !defined(_CUPS_SOURCE) && TARGET_OS_OSX +/* + * On Apple operating systems, the _CUPS_API_* constants are defined using the + * API_ macros in . + * + * On iOS, we don't actually have libcups available directly, but the supplied + * libcups_static target in the Xcode project supports building on iOS 11.0 and + * later. + */ +# define _CUPS_API_1_1_19 API_AVAILABLE(macos(10.3), ios(11.0)) _CUPS_PUBLIC +# define _CUPS_API_1_1_20 API_AVAILABLE(macos(10.4), ios(11.0)) _CUPS_PUBLIC +# define _CUPS_API_1_1_21 API_AVAILABLE(macos(10.4), ios(11.0)) _CUPS_PUBLIC +# define _CUPS_API_1_2 API_AVAILABLE(macos(10.5), ios(11.0)) _CUPS_PUBLIC +# define _CUPS_API_1_3 API_AVAILABLE(macos(10.5), ios(11.0)) _CUPS_PUBLIC +# define _CUPS_API_1_4 API_AVAILABLE(macos(10.6), ios(11.0)) _CUPS_PUBLIC +# define _CUPS_API_1_5 API_AVAILABLE(macos(10.7), ios(11.0)) _CUPS_PUBLIC +# define _CUPS_API_1_6 API_AVAILABLE(macos(10.8), ios(11.0)) _CUPS_PUBLIC +# define _CUPS_API_1_7 API_AVAILABLE(macos(10.9), ios(11.0)) _CUPS_PUBLIC +# define _CUPS_API_2_0 API_AVAILABLE(macos(10.10), ios(11.0)) _CUPS_PUBLIC +# define _CUPS_API_2_2 API_AVAILABLE(macos(10.12), ios(11.0)) _CUPS_PUBLIC +# define _CUPS_API_2_2_4 API_AVAILABLE(macos(10.13), ios(12.0)) _CUPS_PUBLIC +# define _CUPS_API_2_2_7 API_AVAILABLE(macos(10.14), ios(13.0)) _CUPS_PUBLIC +# define _CUPS_API_2_3 API_AVAILABLE(macos(10.14), ios(13.0)) _CUPS_PUBLIC +# else +# define _CUPS_API_1_1_19 _CUPS_PUBLIC +# define _CUPS_API_1_1_20 _CUPS_PUBLIC +# define _CUPS_API_1_1_21 _CUPS_PUBLIC +# define _CUPS_API_1_2 _CUPS_PUBLIC +# define _CUPS_API_1_3 _CUPS_PUBLIC +# define _CUPS_API_1_4 _CUPS_PUBLIC +# define _CUPS_API_1_5 _CUPS_PUBLIC +# define _CUPS_API_1_6 _CUPS_PUBLIC +# define _CUPS_API_1_7 _CUPS_PUBLIC +# define _CUPS_API_2_0 _CUPS_PUBLIC +# define _CUPS_API_2_2 _CUPS_PUBLIC +# define _CUPS_API_2_2_4 _CUPS_PUBLIC +# define _CUPS_API_2_2_7 _CUPS_PUBLIC +# define _CUPS_API_2_3 _CUPS_PUBLIC +# endif /* __APPLE__ && !_CUPS_SOURCE */ + + +/* + * Define _CUPS_DEPRECATED and _CUPS_INTERNAL macros to mark old APIs as + * "deprecated" or "unavailable" with messages so you get warnings/errors are + * compile-time... + * + * Note: Using any of the _CUPS_DEPRECATED macros automatically adds + * _CUPS_PUBLIC. + */ + # if !defined(_CUPS_HAS_DEPRECATED) || (defined(_CUPS_SOURCE) && !defined(_CUPS_NO_DEPRECATED)) /* * Don't mark functions deprecated if the compiler doesn't support it * or we are building CUPS source that doesn't care. */ -# define _CUPS_DEPRECATED -# define _CUPS_DEPRECATED_MSG(m) -# define _CUPS_DEPRECATED_1_6_MSG(m) -# define _CUPS_DEPRECATED_1_7_MSG(m) -# define _CUPS_INTERNAL_MSG(m) +# define _CUPS_DEPRECATED _CUPS_PUBLIC +# define _CUPS_DEPRECATED_MSG(m) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_1_2_MSG(m) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_1_6_MSG(m) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_1_7_MSG(m) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_2_2_MSG(m) _CUPS_PUBLIC +# elif defined(__APPLE__) && defined(_CUPS_NO_DEPRECATED) + /* + * Compiler supports the unavailable attribute, so use it when the code + * wants to exclude the use of deprecated API. + */ +# define _CUPS_DEPRECATED __attribute__ ((unavailable)) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_MSG(m) __attribute__ ((unavailable(m))) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_1_2_MSG(m) API_DEPRECATED(m, macos(10.2,10.5), ios(11.0,11.0)) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_1_6_MSG(m) API_DEPRECATED(m, macos(10.2,10.8), ios(11.0,11.0)) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_1_7_MSG(m) API_DEPRECATED(m, macos(10.2,10.9), ios(11.0,11.0)) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_2_2_MSG(m) API_DEPRECATED(m, macos(10.2,10.12), ios(11.0,11.0)) _CUPS_PUBLIC + +# elif defined(__APPLE__) + /* + * Just mark things as deprecated... + */ +# define _CUPS_DEPRECATED __attribute__ ((deprecated)) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_MSG(m) __attribute__ ((deprecated(m))) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_1_2_MSG(m) API_DEPRECATED(m, macos(10.2,10.5), ios(11.0,11.0)) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_1_6_MSG(m) API_DEPRECATED(m, macos(10.2,10.8), ios(11.0,11.0)) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_1_7_MSG(m) API_DEPRECATED(m, macos(10.2,10.9), ios(11.0,11.0)) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_2_2_MSG(m) API_DEPRECATED(m, macos(10.2,10.12), ios(11.0,11.0)) _CUPS_PUBLIC + # elif defined(_CUPS_HAS_UNAVAILABLE_WITH_MESSAGE) && defined(_CUPS_NO_DEPRECATED) /* * Compiler supports the unavailable attribute, so use it when the code * wants to exclude the use of deprecated API. */ -# define _CUPS_DEPRECATED __attribute__ ((unavailable)) -# define _CUPS_DEPRECATED_MSG(m) __attribute__ ((unavailable(m))) -# define _CUPS_DEPRECATED_1_6_MSG(m) __attribute__ ((unavailable(m))) -# define _CUPS_DEPRECATED_1_7_MSG(m) __attribute__ ((unavailable(m))) -# define _CUPS_INTERNAL_MSG(m) __attribute__ ((unavailable(m))) +# define _CUPS_DEPRECATED __attribute__ ((unavailable)) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_MSG(m) __attribute__ ((unavailable(m))) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_1_2_MSG(m) __attribute__ ((unavailable(m))) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_1_6_MSG(m) __attribute__ ((unavailable(m))) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_1_7_MSG(m) __attribute__ ((unavailable(m))) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_2_2_MSG(m) __attribute__ ((unavailable(m))) _CUPS_PUBLIC # else /* * Compiler supports the deprecated attribute, so use it. */ -# define _CUPS_DEPRECATED __attribute__ ((deprecated)) +# define _CUPS_DEPRECATED __attribute__ ((deprecated)) _CUPS_PUBLIC # ifdef _CUPS_HAS_DEPRECATED_WITH_MESSAGE -# define _CUPS_DEPRECATED_MSG(m) __attribute__ ((deprecated(m))) +# define _CUPS_DEPRECATED_MSG(m) __attribute__ ((deprecated(m))) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_1_2_MSG(m) __attribute__ ((deprecated(m))) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_1_6_MSG(m) __attribute__ ((deprecated(m))) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_1_7_MSG(m) __attribute__ ((deprecated(m))) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_2_2_MSG(m) __attribute__ ((deprecated(m))) _CUPS_PUBLIC # else -# define _CUPS_DEPRECATED_MSG(m) __attribute__ ((deprecated)) +# define _CUPS_DEPRECATED_MSG(m) __attribute__ ((deprecated)) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_1_2_MSG(m) __attribute__ ((deprecated)) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_1_6_MSG(m) __attribute__ ((deprecated)) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_1_7_MSG(m) __attribute__ ((deprecated)) _CUPS_PUBLIC +# define _CUPS_DEPRECATED_2_2_MSG(m) __attribute__ ((deprecated)) _CUPS_PUBLIC # endif /* _CUPS_HAS_DEPRECATED_WITH_MESSAGE */ -# if defined(MAC_OS_X_VERSION_10_8) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8 -# define _CUPS_DEPRECATED_1_6_MSG(m) _CUPS_DEPRECATED_MSG(m) -# else -# define _CUPS_DEPRECATED_1_6_MSG(m) -# endif /* MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_8 */ -# if defined(MAC_OS_X_VERSION_10_9) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 -# define _CUPS_DEPRECATED_1_7_MSG(m) _CUPS_DEPRECATED_MSG(m) -# else -# define _CUPS_DEPRECATED_1_7_MSG(m) -# endif /* MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_9 */ -# ifdef _CUPS_SOURCE -# define _CUPS_INTERNAL_MSG(m) -# elif defined(_CUPS_HAS_UNAVAILABLE_WITH_MESSAGE) -# define _CUPS_INTERNAL_MSG(m) __attribute__ ((unavailable(m))) -# elif defined(_CUPS_HAS_DEPRECATED_WITH_MESSAGE) -# define _CUPS_INTERNAL_MSG(m) __attribute__ ((deprecated(m))) -# else -# define _CUPS_INTERNAL_MSG(m) __attribute__ ((deprecated)) -# endif /* _CUPS_SOURCE */ # endif /* !_CUPS_HAS_DEPRECATED || (_CUPS_SOURCE && !_CUPS_NO_DEPRECATED) */ -# ifndef __GNUC__ -# define __attribute__(x) -# endif /* !__GNUC__ */ + +/* + * Define _CUPS_FORMAT macro for printf-style functions... + */ + +# ifdef _CUPS_HAS_FORMAT +# define _CUPS_FORMAT(a,b) __attribute__ ((__format__(__printf__, a,b))) +# else +# define _CUPS_FORMAT(a,b) +# endif /* _CUPS_HAS_FORMAT */ + + +/* + * Define _CUPS_INTERNAL_MSG macro for private APIs that have (historical) + * public visibility. + * + * Note: Using the _CUPS_INTERNAL_MSG macro automatically adds _CUPS_PUBLIC. + */ + +# ifdef _CUPS_SOURCE +# define _CUPS_INTERNAL_MSG(m) _CUPS_PUBLIC +# elif defined(_CUPS_HAS_UNAVAILABLE_WITH_MESSAGE) +# define _CUPS_INTERNAL_MSG(m) __attribute__ ((unavailable(m))) _CUPS_PUBLIC +# elif defined(_CUPS_HAS_DEPRECATED_WITH_MESSAGE) +# define _CUPS_INTERNAL_MSG(m) __attribute__ ((deprecated(m))) _CUPS_PUBLIC +# else +# define _CUPS_INTERNAL_MSG(m) __attribute__ ((deprecated)) _CUPS_PUBLIC +# endif /* _CUPS_SOURCE */ + + +/* + * Define _CUPS_NONNULL macro for functions that don't expect non-null + * arguments... + */ + +# ifdef _CUPS_HAS_NONNULL +# define _CUPS_NONNULL(...) __attribute__ ((nonnull(__VA_ARGS__))) +# else +# define _CUPS_NONNULL(...) +# endif /* _CUPS_HAS_FORMAT */ + + +/* + * Define _CUPS_NORETURN macro for functions that don't return. + */ + +# ifdef _CUPS_HAS_NORETURN +# define _CUPS_NORETURN __attribute__ ((noreturn)) +# else +# define _CUPS_NORETURN +# endif /* _CUPS_HAS_NORETURN */ + #endif /* !_CUPS_VERSIONING_H_ */ diff --git a/filter/Dependencies b/filter/Dependencies index 80a49b6..50320a1 100644 --- a/filter/Dependencies +++ b/filter/Dependencies @@ -1,43 +1,26 @@ -error.o: error.c ../cups/raster-private.h ../cups/raster.h ../cups/cups.h \ - ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h \ - ../cups/array.h ../cups/language.h ../cups/pwg.h \ - ../cups/debug-private.h ../cups/string-private.h ../config.h -interpret.o: interpret.c ../cups/raster-private.h ../cups/raster.h \ - ../cups/cups.h ../cups/file.h ../cups/versioning.h ../cups/ipp.h \ - ../cups/http.h ../cups/array.h ../cups/language.h ../cups/pwg.h \ - ../cups/debug-private.h ../cups/string-private.h ../config.h \ - ../cups/ppd.h -raster.o: raster.c ../cups/raster-private.h ../cups/raster.h \ - ../cups/cups.h ../cups/file.h ../cups/versioning.h ../cups/ipp.h \ - ../cups/http.h ../cups/array.h ../cups/language.h ../cups/pwg.h \ - ../cups/debug-private.h ../cups/string-private.h ../config.h commandtops.o: commandtops.c ../cups/cups-private.h \ - ../cups/string-private.h ../config.h ../cups/debug-private.h \ - ../cups/versioning.h ../cups/array-private.h ../cups/array.h \ - ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h \ - ../cups/http-private.h ../cups/language.h ../cups/md5-private.h \ - ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \ - ../cups/cups.h ../cups/file.h ../cups/pwg.h ../cups/thread-private.h \ - ../cups/ppd.h ../cups/raster.h ../cups/sidechannel.h -gziptoany.o: gziptoany.c ../cups/cups-private.h ../cups/string-private.h \ - ../config.h ../cups/debug-private.h ../cups/versioning.h \ + ../cups/string-private.h ../config.h ../cups/versioning.h \ ../cups/array-private.h ../cups/array.h ../cups/ipp-private.h \ - ../cups/ipp.h ../cups/http.h ../cups/http-private.h ../cups/language.h \ - ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \ - ../cups/pwg-private.h ../cups/cups.h ../cups/file.h ../cups/pwg.h \ - ../cups/thread-private.h + ../cups/cups.h ../cups/file.h ../cups/ipp.h ../cups/http.h \ + ../cups/language.h ../cups/pwg.h ../cups/http-private.h \ + ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \ + ../cups/thread-private.h ../cups/ppd.h ../cups/raster.h \ + ../cups/sidechannel.h +gziptoany.o: gziptoany.c ../cups/cups-private.h ../cups/string-private.h \ + ../config.h ../cups/versioning.h ../cups/array-private.h \ + ../cups/array.h ../cups/ipp-private.h ../cups/cups.h ../cups/file.h \ + ../cups/ipp.h ../cups/http.h ../cups/language.h ../cups/pwg.h \ + ../cups/http-private.h ../cups/language-private.h ../cups/transcode.h \ + ../cups/pwg-private.h ../cups/thread-private.h common.o: common.c common.h ../cups/string-private.h ../config.h \ - ../cups/cups.h ../cups/file.h ../cups/versioning.h ../cups/ipp.h \ + ../cups/versioning.h ../cups/cups.h ../cups/file.h ../cups/ipp.h \ ../cups/http.h ../cups/array.h ../cups/language.h ../cups/pwg.h \ ../cups/ppd.h ../cups/raster.h pstops.o: pstops.c common.h ../cups/string-private.h ../config.h \ - ../cups/cups.h ../cups/file.h ../cups/versioning.h ../cups/ipp.h \ + ../cups/versioning.h ../cups/cups.h ../cups/file.h ../cups/ipp.h \ ../cups/http.h ../cups/array.h ../cups/language.h ../cups/pwg.h \ ../cups/ppd.h ../cups/raster.h ../cups/language-private.h \ ../cups/transcode.h -rasterbench.o: rasterbench.c ../config.h ../cups/raster.h ../cups/cups.h \ - ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h \ - ../cups/array.h ../cups/language.h ../cups/pwg.h rastertoepson.o: rastertoepson.c ../cups/cups.h ../cups/file.h \ ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h \ ../cups/language.h ../cups/pwg.h ../cups/ppd.h ../cups/raster.h \ @@ -54,15 +37,10 @@ rastertolabel.o: rastertolabel.c ../cups/cups.h ../cups/file.h \ ../cups/string-private.h ../config.h ../cups/language-private.h \ ../cups/transcode.h rastertopwg.o: rastertopwg.c ../cups/cups-private.h \ - ../cups/string-private.h ../config.h ../cups/debug-private.h \ - ../cups/versioning.h ../cups/array-private.h ../cups/array.h \ - ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h \ - ../cups/http-private.h ../cups/language.h ../cups/md5-private.h \ + ../cups/string-private.h ../config.h ../cups/versioning.h \ + ../cups/array-private.h ../cups/array.h ../cups/ipp-private.h \ + ../cups/cups.h ../cups/file.h ../cups/ipp.h ../cups/http.h \ + ../cups/language.h ../cups/pwg.h ../cups/http-private.h \ ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \ - ../cups/cups.h ../cups/file.h ../cups/pwg.h ../cups/thread-private.h \ - ../cups/ppd-private.h ../cups/ppd.h ../cups/raster.h -testraster.o: testraster.c ../cups/raster-private.h ../cups/raster.h \ - ../cups/cups.h ../cups/file.h ../cups/versioning.h ../cups/ipp.h \ - ../cups/http.h ../cups/array.h ../cups/language.h ../cups/pwg.h \ - ../cups/debug-private.h ../cups/string-private.h ../config.h \ - ../cups/ppd.h + ../cups/thread-private.h ../cups/ppd-private.h ../cups/ppd.h \ + ../cups/raster.h diff --git a/filter/Makefile b/filter/Makefile index 7da764d..4109ff2 100644 --- a/filter/Makefile +++ b/filter/Makefile @@ -1,22 +1,17 @@ # # Filter makefile for CUPS. # -# Copyright 2007-2012 by Apple Inc. -# Copyright 1997-2006 by Easy Software Products. +# Copyright © 2007-2019 by Apple Inc. +# Copyright © 1997-2006 by Easy Software Products. # -# These coded instructions, statements, and computer programs are the -# property of Apple Inc. and are protected by Federal copyright -# law. Distribution and use rights are outlined in the file "LICENSE.txt" -# which should have been included with this file. If this file is -# missing or damaged, see the license at "http://www.cups.org/". -# -# This file is subject to the Apple OS-Developed Software exception. +# Licensed under Apache License v2.0. See the file "LICENSE" for more +# information. # include ../Makedefs -FILTERS = \ +TARGETS = \ commandtops \ gziptoany \ pstops \ @@ -24,21 +19,10 @@ FILTERS = \ rastertohp \ rastertolabel \ rastertopwg -LIBTARGETS = \ - $(LIBCUPSIMAGE) \ - libcupsimage.a -UNITTARGETS = \ - rasterbench \ - testraster -TARGETS = \ - $(LIBTARGETS) \ - $(FILTERS) -IMAGEOBJS = error.o interpret.o raster.o -OBJS = $(IMAGEOBJS) \ - commandtops.o gziptoany.o common.o pstops.o \ - rasterbench.o rastertoepson.o rastertohp.o rastertolabel.o \ - rastertopwg.o testraster.o +OBJS = commandtops.o gziptoany.o common.o pstops.o \ + rastertoepson.o rastertohp.o rastertolabel.o \ + rastertopwg.o # @@ -52,14 +36,14 @@ all: $(TARGETS) # Make library targets... # -libs: $(LIBTARGETS) +libs: # # Make unit tests... # -unittests: $(UNITTARGETS) +unittests: # @@ -67,8 +51,7 @@ unittests: $(UNITTARGETS) # clean: - $(RM) $(OBJS) $(TARGETS) $(UNITTARGETS) - $(RM) libcupsimage.so libcupsimage.sl libcupsimage.dylib + $(RM) $(OBJS) $(TARGETS) # @@ -99,14 +82,12 @@ install-data: install-exec: $(INSTALL_DIR) -m 755 $(SERVERBIN)/filter - for file in $(FILTERS); do \ + for file in $(TARGETS); do \ $(INSTALL_BIN) $$file $(SERVERBIN)/filter; \ done - $(RM) $(SERVERBIN)/filter/rastertodymo - $(LN) rastertolabel $(SERVERBIN)/filter/rastertodymo if test "x$(SYMROOT)" != "x"; then \ $(INSTALL_DIR) $(SYMROOT); \ - for file in $(FILTERS); do \ + for file in $(TARGETS); do \ cp $$file $(SYMROOT); \ dsymutil $(SYMROOT)/$$file; \ done \ @@ -124,28 +105,7 @@ install-headers: # Install libraries... # -install-libs: $(INSTALLSTATIC) - $(INSTALL_DIR) -m 755 $(LIBDIR) - $(INSTALL_LIB) $(LIBCUPSIMAGE) $(LIBDIR) - -if test $(LIBCUPSIMAGE) = "libcupsimage.so.2" -o $(LIBCUPSIMAGE) = "libcupsimage.sl.2"; then \ - $(RM) $(LIBDIR)/`basename $(LIBCUPSIMAGE) .2`; \ - $(LN) $(LIBCUPSIMAGE) $(LIBDIR)/`basename $(LIBCUPSIMAGE) .2`; \ - fi - -if test $(LIBCUPSIMAGE) = "libcupsimage.2.dylib"; then \ - $(RM) $(LIBDIR)/libcupsimage.dylib; \ - $(LN) $(LIBCUPSIMAGE) $(LIBDIR)/libcupsimage.dylib; \ - fi - if test "x$(SYMROOT)" != "x"; then \ - $(INSTALL_DIR) $(SYMROOT); \ - cp $(LIBCUPSIMAGE) $(SYMROOT); \ - dsymutil $(SYMROOT)/$(LIBCUPSIMAGE); \ - fi - -installstatic: - $(INSTALL_DIR) -m 755 $(LIBDIR) - $(INSTALL_LIB) -m 755 libcupsimage.a $(LIBDIR) - $(RANLIB) $(LIBDIR)/libcupsimage.a - $(CHMOD) 555 $(LIBDIR)/libcupsimage.a +install-libs: # @@ -153,21 +113,11 @@ installstatic: # uninstall: - for file in $(FILTERS); do \ + for file in $(TARGETS); do \ $(RM) $(SERVERBIN)/filter/$$file; \ done - $(RM) $(SERVERBIN)/filter/rastertodymo -$(RMDIR) $(SERVERBIN)/filter -$(RMDIR) $(SERVERBIN) - $(RM) $(LIBDIR)/libcupsimage.2.dylib - $(RM) $(LIBDIR)/libcupsimage.a - $(RM) $(LIBDIR)/libcupsimage.dylib - $(RM) $(LIBDIR)/libcupsimage_s.a - $(RM) $(LIBDIR)/libcupsimage.sl - $(RM) $(LIBDIR)/libcupsimage.sl.2 - $(RM) $(LIBDIR)/libcupsimage.so - $(RM) $(LIBDIR)/libcupsimage.so.2 - -$(RMDIR) $(LIBDIR) # @@ -176,37 +126,29 @@ uninstall: apihelp: echo Generating CUPS API help files... - mxmldoc --section "Programming" --title "Raster API" \ - --css ../doc/cups-printable.css \ - --header api-raster.header --intro api-raster.shtml \ - api-raster.xml \ - ../cups/raster.h interpret.c raster.c \ - >../doc/help/api-raster.html - mxmldoc --tokens help/api-raster.html api-raster.xml >../doc/help/api-raster.tokens - $(RM) api-raster.xml - mxmldoc --section "Programming" \ + codedoc --section "Programming" \ --title "Developing PostScript Printer Drivers" \ --css ../doc/cups-printable.css \ --header postscript-driver.header \ - --intro postscript-driver.shtml \ + --body postscript-driver.shtml \ >../doc/help/postscript-driver.html - mxmldoc --section "Programming" \ + codedoc --section "Programming" \ --title "Introduction to the PPD Compiler" \ --css ../doc/cups-printable.css \ --header ppd-compiler.header \ - --intro ppd-compiler.shtml \ + --body ppd-compiler.shtml \ >../doc/help/ppd-compiler.html - mxmldoc --section "Programming" \ + codedoc --section "Programming" \ --title "Developing Raster Printer Drivers" \ --css ../doc/cups-printable.css \ --header raster-driver.header \ - --intro raster-driver.shtml \ + --body raster-driver.shtml \ >../doc/help/raster-driver.html - mxmldoc --section "Specifications" \ + codedoc --section "Specifications" \ --title "CUPS PPD Extensions" \ --css ../doc/cups-printable.css \ --header spec-ppd.header \ - --intro spec-ppd.shtml \ + --body spec-ppd.shtml \ >../doc/help/spec-ppd.html @@ -216,7 +158,8 @@ apihelp: commandtops: commandtops.o ../cups/$(LIBCUPS) echo Linking $@... - $(CC) $(LDFLAGS) -o $@ commandtops.o $(LIBS) + $(LD_CC) $(ALL_LDFLAGS) -o $@ commandtops.o $(LINKCUPS) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ # @@ -225,68 +168,8 @@ commandtops: commandtops.o ../cups/$(LIBCUPS) gziptoany: gziptoany.o ../Makedefs ../cups/$(LIBCUPS) echo Linking $@... - $(CC) $(LDFLAGS) -o $@ gziptoany.o $(LIBZ) $(LIBS) - - -# -# libcupsimage.so.2, libcupsimage.sl.2 -# - -libcupsimage.so.2 libcupsimage.sl.2: $(IMAGEOBJS) - echo Linking $@... - $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(IMAGEOBJS) $(DSOLIBS) \ - -L../cups $(LINKCUPS) - $(RM) `basename $@ .2` - $(LN) $@ `basename $@ .2` - - -# -# libcupsimage.2.dylib -# - -libcupsimage.2.dylib: $(IMAGEOBJS) $(LIBCUPSIMAGEORDER) - echo Linking $@... - $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ \ - -install_name $(libdir)/$@ \ - -current_version 2.3.0 \ - -compatibility_version 2.0.0 \ - $(IMAGEOBJS) $(DSOLIBS) -L../cups $(LINKCUPS) - $(RM) libcupsimage.dylib - $(LN) $@ libcupsimage.dylib - - -# -# libcupsimage_s.a -# - -libcupsimage_s.a: $(IMAGEOBJS) libcupsimage_s.exp - echo Linking $@... - $(DSO) $(DSOFLAGS) -Wl,-berok,-bexport:libcupsimage_s.exp \ - -o libcupsimage_s.o $(IMAGEOBJS) $(DSOLIBS) - $(RM) $@ - $(AR) $(ARFLAGS) $@ libcupsimage_s.o - - -# -# libcupsimage.la -# - -libcupsimage.la: $(IMAGEOBJS) - echo Linking $@... - $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(IMAGEOBJS:.o=.lo) $(DSOLIBS) \ - -L../cups $(LINKCUPS) \ - -rpath $(LIBDIR) -version-info 2:3 - - -# -# libcupsimage.a -# - -libcupsimage.a: $(IMAGEOBJS) - echo Archiving $@... - $(RM) $@ - $(AR) $(ARFLAGS) $@ $(IMAGEOBJS) - $(RANLIB) $@ + $(LD_CC) $(ALL_LDFLAGS) -o $@ gziptoany.o $(LINKCUPS) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ # @@ -295,71 +178,53 @@ libcupsimage.a: $(IMAGEOBJS) pstops: pstops.o common.o ../cups/$(LIBCUPS) echo Linking $@... - $(CC) $(LDFLAGS) -o $@ pstops.o common.o $(LIBS) + $(LD_CC) $(ALL_LDFLAGS) -o $@ pstops.o common.o $(LINKCUPS) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ # # rastertoepson # -rastertoepson: rastertoepson.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE) +rastertoepson: rastertoepson.o ../cups/$(LIBCUPS) echo Linking $@... - $(CC) $(LDFLAGS) -o $@ rastertoepson.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS) + $(LD_CC) $(ALL_LDFLAGS) -o $@ rastertoepson.o $(LINKCUPS) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ # # rastertohp # -rastertohp: rastertohp.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE) +rastertohp: rastertohp.o ../cups/$(LIBCUPS) echo Linking $@... - $(CC) $(LDFLAGS) -o $@ rastertohp.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS) + $(LD_CC) $(ALL_LDFLAGS) -o $@ rastertohp.o $(LINKCUPS) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ # # rastertolabel # -rastertolabel: rastertolabel.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE) +rastertolabel: rastertolabel.o ../cups/$(LIBCUPS) echo Linking $@... - $(CC) $(LDFLAGS) -o $@ rastertolabel.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS) + $(LD_CC) $(ALL_LDFLAGS) -o $@ rastertolabel.o $(LINKCUPS) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ # # rastertopwg # -rastertopwg: rastertopwg.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE) +rastertopwg: rastertopwg.o ../cups/$(LIBCUPS) echo Linking $@... - $(CC) $(LDFLAGS) -o $@ rastertopwg.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS) + $(LD_CC) $(ALL_LDFLAGS) -o $@ rastertopwg.o $(LINKCUPS) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ -rastertopwg-static: rastertopwg.o ../cups/$(LIBCUPSSTATIC) libcupsimage.a +rastertopwg-static: rastertopwg.o ../cups/$(LIBCUPSSTATIC) echo Linking $@... - $(CC) $(LDFLAGS) -o $@ rastertopwg.o libcupsimage.a \ - ../cups/$(LIBCUPSSTATIC) $(IMGLIBS) $(DSOLIBS) $(COMMONLIBS) \ - $(SSLLIBS) $(DNSSDLIBS) $(LIBGSSAPI) - - -# -# testraster -# - -testraster: testraster.o ../cups/$(LIBCUPSSTATIC) libcupsimage.a - echo Linking $@... - $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testraster.o libcupsimage.a \ - ../cups/$(LIBCUPSSTATIC) $(IMGLIBS) $(DSOLIBS) $(COMMONLIBS) \ - $(SSLLIBS) $(DNSSDLIBS) $(LIBGSSAPI) - echo Running raster API tests... - ./testraster - - -# -# rasterbench -# - -rasterbench: rasterbench.o libcupsimage.a - echo Linking $@... - $(CC) $(LDFLAGS) -o $@ rasterbench.o libcupsimage.a $(LIBS) + $(LD_CC) $(ALL_LDFLAGS) -o $@ rastertopwg.o $(LINKCUPSSTATIC) + $(CODE_SIGN) -s "$(CODE_SIGN_IDENTITY)" $@ # diff --git a/filter/api-raster.header b/filter/api-raster.header deleted file mode 100644 index 31b87b1..0000000 --- a/filter/api-raster.header +++ /dev/null @@ -1,35 +0,0 @@ - - -

    Raster API

    - -
    - - - - - - - - - - - - - - - - -
    Headercups/raster.h
    Library-lcupsimage
    See AlsoProgramming: Introduction to CUPS Programming
    - Programming: CUPS API
    - Programming: PPD API
    - References: CUPS PPD Specification
    diff --git a/filter/commandtops.c b/filter/commandtops.c index 07979e0..3edcc6a 100644 --- a/filter/commandtops.c +++ b/filter/commandtops.c @@ -3,11 +3,7 @@ * * Copyright 2008-2014 by Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* diff --git a/filter/common.c b/filter/common.c index 86b5f8e..672b7c8 100644 --- a/filter/common.c +++ b/filter/common.c @@ -4,13 +4,7 @@ * Copyright 2007-2014 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* diff --git a/filter/common.h b/filter/common.h index e72b27f..29e7365 100644 --- a/filter/common.h +++ b/filter/common.h @@ -4,13 +4,7 @@ * Copyright 2007-2010 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* diff --git a/filter/error.c b/filter/error.c deleted file mode 100644 index 3c552cb..0000000 --- a/filter/error.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Raster error handling for CUPS. - * - * Copyright 2007-2015 by Apple Inc. - * Copyright 2007 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - */ - -/* - * Include necessary headers... - */ - -#include - - -/* - * Local structures... - */ - -typedef struct _cups_raster_error_s /**** Error buffer structure ****/ -{ - char *start, /* Start of buffer */ - *current, /* Current position in buffer */ - *end; /* End of buffer */ -} _cups_raster_error_t; - - -/* - * Local functions... - */ - -static _cups_raster_error_t *get_error_buffer(void); - - -/* - * '_cupsRasterAddError()' - Add an error message to the error buffer. - */ - -void -_cupsRasterAddError(const char *f, /* I - Printf-style error message */ - ...) /* I - Additional arguments as needed */ -{ - _cups_raster_error_t *buf = get_error_buffer(); - /* Error buffer */ - va_list ap; /* Pointer to additional arguments */ - char s[2048]; /* Message string */ - ssize_t bytes; /* Bytes in message string */ - - - DEBUG_printf(("_cupsRasterAddError(f=\"%s\", ...)", f)); - - va_start(ap, f); - bytes = vsnprintf(s, sizeof(s), f, ap); - va_end(ap); - - if (bytes <= 0) - return; - - DEBUG_printf(("1_cupsRasterAddError: %s", s)); - - bytes ++; - - if ((size_t)bytes >= sizeof(s)) - return; - - if (bytes > (ssize_t)(buf->end - buf->current)) - { - /* - * Allocate more memory... - */ - - char *temp; /* New buffer */ - size_t size; /* Size of buffer */ - - - size = (size_t)(buf->end - buf->start + 2 * bytes + 1024); - - if (buf->start) - temp = realloc(buf->start, size); - else - temp = malloc(size); - - if (!temp) - return; - - /* - * Update pointers... - */ - - buf->end = temp + size; - buf->current = temp + (buf->current - buf->start); - buf->start = temp; - } - - /* - * Append the message to the end of the current string... - */ - - memcpy(buf->current, s, (size_t)bytes); - buf->current += bytes - 1; -} - - -/* - * '_cupsRasterClearError()' - Clear the error buffer. - */ - -void -_cupsRasterClearError(void) -{ - _cups_raster_error_t *buf = get_error_buffer(); - /* Error buffer */ - - - buf->current = buf->start; - - if (buf->start) - *(buf->start) = '\0'; -} - - -/* - * 'cupsRasterErrorString()' - Return the last error from a raster function. - * - * If there are no recent errors, NULL is returned. - * - * @since CUPS 1.3/macOS 10.5@ - */ - -const char * /* O - Last error */ -cupsRasterErrorString(void) -{ - _cups_raster_error_t *buf = get_error_buffer(); - /* Error buffer */ - - - if (buf->current == buf->start) - return (NULL); - else - return (buf->start); -} - - -#ifdef HAVE_PTHREAD_H -/* - * Implement per-thread globals... - */ - -# include - - -/* - * Local globals... - */ - -static pthread_key_t raster_key = 0; /* Thread local storage key */ -static pthread_once_t raster_key_once = PTHREAD_ONCE_INIT; - /* One-time initialization object */ - - -/* - * Local functions... - */ - -static void raster_init(void); -static void raster_destructor(void *value); - - -/* - * 'get_error_buffer()' - Return a pointer to thread local storage. - */ - -_cups_raster_error_t * /* O - Pointer to error buffer */ -get_error_buffer(void) -{ - _cups_raster_error_t *buf; /* Pointer to error buffer */ - - - /* - * Initialize the global data exactly once... - */ - - DEBUG_puts("3get_error_buffer()"); - - pthread_once(&raster_key_once, raster_init); - - /* - * See if we have allocated the data yet... - */ - - if ((buf = (_cups_raster_error_t *)pthread_getspecific(raster_key)) - == NULL) - { - DEBUG_puts("4get_error_buffer: allocating memory for thread."); - - /* - * No, allocate memory as set the pointer for the key... - */ - - buf = calloc(1, sizeof(_cups_raster_error_t)); - pthread_setspecific(raster_key, buf); - - DEBUG_printf(("4get_error_buffer: buf=%p", (void *)buf)); - } - - /* - * Return the pointer to the data... - */ - - return (buf); -} - - -/* - * 'raster_init()' - Initialize error buffer once. - */ - -static void -raster_init(void) -{ - pthread_key_create(&raster_key, raster_destructor); - - DEBUG_printf(("3raster_init(): raster_key=%x(%u)", (unsigned)raster_key, (unsigned)raster_key)); -} - - -/* - * 'raster_destructor()' - Free memory allocated by get_error_buffer(). - */ - -static void -raster_destructor(void *value) /* I - Data to free */ -{ - _cups_raster_error_t *buf = (_cups_raster_error_t *)value; - /* Error buffer */ - - - DEBUG_printf(("3raster_destructor(value=%p)", value)); - - if (buf->start) - free(buf->start); - - free(value); -} - - -#else -/* - * Implement static globals... - */ - -/* - * 'get_error_buffer()' - Return a pointer to thread local storage. - */ - -_cups_raster_error_t * /* O - Pointer to error buffer */ -get_error_buffer(void) -{ - static _cups_raster_error_t buf = { 0, 0, 0 }; - /* Error buffer */ - - - return (&buf); -} -#endif /* HAVE_PTHREAD_H */ diff --git a/filter/gziptoany.c b/filter/gziptoany.c index 0eae85e..5d216e8 100644 --- a/filter/gziptoany.c +++ b/filter/gziptoany.c @@ -4,13 +4,7 @@ * Copyright 2007-2015 by Apple Inc. * Copyright 1993-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* diff --git a/filter/libcupsimage2.def b/filter/libcupsimage2.def deleted file mode 100644 index 3c20284..0000000 --- a/filter/libcupsimage2.def +++ /dev/null @@ -1,14 +0,0 @@ -LIBRARY libcupsimage2 -VERSION 2.3 -EXPORTS -cupsRasterClose -cupsRasterErrorString -cupsRasterInterpretPPD -cupsRasterOpen -cupsRasterOpenIO -cupsRasterReadHeader -cupsRasterReadHeader2 -cupsRasterReadPixels -cupsRasterWriteHeader -cupsRasterWriteHeader2 -cupsRasterWritePixels diff --git a/filter/libcupsimage_s.exp b/filter/libcupsimage_s.exp deleted file mode 100644 index 57f4259..0000000 --- a/filter/libcupsimage_s.exp +++ /dev/null @@ -1,16 +0,0 @@ -_cupsImagePutCol -_cupsImagePutRow -_cupsImageReadBMP -_cupsImageReadGIF -_cupsImageReadJPEG -_cupsImageReadPIX -_cupsImageReadPNG -_cupsImageReadPNM -_cupsImageReadPhotoCD -_cupsImageReadSGI -_cupsImageReadSunRaster -_cupsImageReadTIFF -_cupsImageZoomDelete -_cupsImageZoomFill -_cupsImageZoomNew -_cupsRasterExecPS diff --git a/filter/postscript-driver.header b/filter/postscript-driver.header index 331792a..c8425a0 100644 --- a/filter/postscript-driver.header +++ b/filter/postscript-driver.header @@ -1,14 +1,11 @@

    Developing PostScript Printer Drivers

    diff --git a/filter/ppd-compiler.header b/filter/ppd-compiler.header index 7248754..951373c 100644 --- a/filter/ppd-compiler.header +++ b/filter/ppd-compiler.header @@ -1,14 +1,11 @@

    Introduction to the PPD Compiler

    diff --git a/filter/pstops.c b/filter/pstops.c index 072356e..d251abb 100644 --- a/filter/pstops.c +++ b/filter/pstops.c @@ -1,16 +1,11 @@ /* * PostScript filter for CUPS. * - * Copyright 2007-2015 by Apple Inc. - * Copyright 1993-2007 by Easy Software Products. + * Copyright © 2007-2018 by Apple Inc. + * Copyright © 1993-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -162,8 +157,7 @@ static ssize_t copy_trailer(cups_file_t *fp, pstops_doc_t *doc, ssize_t linelen, size_t linesize); static void do_prolog(pstops_doc_t *doc, ppd_file_t *ppd); static void do_setup(pstops_doc_t *doc, ppd_file_t *ppd); -static void doc_printf(pstops_doc_t *doc, const char *format, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); +static void doc_printf(pstops_doc_t *doc, const char *format, ...) _CUPS_FORMAT(2, 3); static void doc_puts(pstops_doc_t *doc, const char *s); static void doc_write(pstops_doc_t *doc, const char *s, size_t len); static void end_nup(pstops_doc_t *doc, int number); @@ -2235,7 +2229,7 @@ parse_text(const char *start, /* I - Start of text value */ bufptr = buffer; bufend = buffer + bufsize - 1; - while (bufptr < bufend) + while (*start && bufptr < bufend) { if (isspace(*start & 255) && !level) break; diff --git a/filter/raster-driver.header b/filter/raster-driver.header index 5028a59..797388d 100644 --- a/filter/raster-driver.header +++ b/filter/raster-driver.header @@ -1,14 +1,11 @@

    Developing Raster Printer Drivers

    diff --git a/filter/rastertoepson.c b/filter/rastertoepson.c index 4efe669..4522e6b 100644 --- a/filter/rastertoepson.c +++ b/filter/rastertoepson.c @@ -1,16 +1,11 @@ /* * EPSON ESC/P and ESC/P2 filter for CUPS. * - * Copyright 2007-2015 by Apple Inc. + * Copyright 2007-2018 by Apple Inc. * Copyright 1993-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -307,7 +302,7 @@ StartPage( if (DotBytes) { - if ((LineBuffers[0] = calloc((size_t)DotBytes, header->cupsWidth * (size_t)(Shingling + 1))) == NULL) + if ((LineBuffers[0] = calloc((size_t)DotBytes, (header->cupsWidth + 7) * (size_t)(Shingling + 1))) == NULL) { fputs("ERROR: Unable to allocate memory\n", stderr); exit(1); diff --git a/filter/rastertohp.c b/filter/rastertohp.c index eb11c8c..0d76c42 100644 --- a/filter/rastertohp.c +++ b/filter/rastertohp.c @@ -4,13 +4,7 @@ * Copyright 2007-2015 by Apple Inc. * Copyright 1993-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* @@ -37,8 +31,8 @@ unsigned char *Planes[4], /* Output buffers */ unsigned NumPlanes, /* Number of color planes */ ColorBits, /* Number of bits per color */ Feed; /* Number of lines to skip */ -int Duplex, /* Current duplex mode */ - Page, /* Current page number */ +cups_bool_t Duplex; /* Current duplex mode */ +int Page, /* Current page number */ Canceled; /* Has the current job been canceled? */ diff --git a/filter/rastertolabel.c b/filter/rastertolabel.c index 4e49181..35d678d 100644 --- a/filter/rastertolabel.c +++ b/filter/rastertolabel.c @@ -1,16 +1,11 @@ /* * Label printer filter for CUPS. * - * Copyright 2007-2016 by Apple Inc. - * Copyright 2001-2007 by Easy Software Products. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 2001-2007 by Easy Software Products. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -305,7 +300,7 @@ StartPage(ppd_file_t *ppd, /* I - PPD file */ header->HWResolution[1], header->cupsHeight, header->NumCopies); printf("PAGE-WIDTH %u\r\n", header->cupsWidth); - printf("PAGE-HEIGHT %u\r\n", header->cupsWidth); + printf("PAGE-HEIGHT %u\r\n", header->cupsHeight); break; case INTELLITECH_PCL : @@ -374,7 +369,7 @@ StartPage(ppd_file_t *ppd, /* I - PPD file */ if (header->cupsCompression != ~0U) /* inPrintDensity */ - printf("\033&d%uA", 30 * header->cupsCompression / 100 - 15); + printf("\033&d%dA", 30 * header->cupsCompression / 100 - 15); if ((choice = ppdFindMarkedChoice(ppd, "inPrintMode")) != NULL) { @@ -619,7 +614,14 @@ EndPage(ppd_file_t *ppd, /* I - PPD file */ */ puts("^XZ"); + + /* + * Delete the label image... + */ + + puts("^XA"); puts("^IDR:CUPS.GRF^FS"); + puts("^XZ"); /* * Cut the label as needed... diff --git a/filter/rastertopwg.c b/filter/rastertopwg.c index 5413df0..1e63e4e 100644 --- a/filter/rastertopwg.c +++ b/filter/rastertopwg.c @@ -1,15 +1,10 @@ /* * CUPS raster to PWG raster format filter for CUPS. * - * Copyright 2011, 2014-2017 Apple Inc. + * Copyright © 2011, 2014-2017 Apple Inc. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright law. - * Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* diff --git a/filter/spec-ppd.header b/filter/spec-ppd.header index e7e1ab7..0d0181e 100644 --- a/filter/spec-ppd.header +++ b/filter/spec-ppd.header @@ -1,14 +1,11 @@

    CUPS PPD Extensions

    diff --git a/filter/spec-ppd.shtml b/filter/spec-ppd.shtml index 3b75430..938bb87 100644 --- a/filter/spec-ppd.shtml +++ b/filter/spec-ppd.shtml @@ -30,7 +30,8 @@ LINE-END = CR / LF / CR LF

    CUPS supports several methods of auto-configuration via PPD keywords.

    -

    macOS 10.5APAutoSetupTool

    + +

    macOS 10.5APAutoSetupTool

    *APAutoSetupTool: "/LibraryPrinters/vendor/filename"

    @@ -45,7 +46,8 @@ LINE-END = CR / LF / CR LF *APAutoSetupTool: "/Library/Printers/vendor/Tools/autosetuptool" -

    macOS 10.2/CUPS 1.4?MainKeyword

    + +

    macOS 10.2/CUPS 1.4?MainKeyword

    *?MainKeyword: "
    PostScript query code that writes a message using the = operator...
    @@ -74,7 +76,8 @@ LINE-END = CR / LF / CR LF *CloseUI: OptionDuplex -

    macOS 10.4/CUPS 1.5OIDMainKeyword

    + +

    macOS 10.4/CUPS 1.5OIDMainKeyword

    *?OIDMainKeyword: ".n.n.n..."
    *OIDMainKeyword OptionKeyword1: "value"
    @@ -105,7 +108,8 @@ LINE-END = CR / LF / CR LF

-

DeprecatedcupsColorProfile

+ +

DeprecatedcupsColorProfile

*cupsColorProfile Resolution/MediaType: "density gamma m00 m01 m02 m10 m11 m12 m20 m21 m22"

@@ -142,7 +146,7 @@ f(x) = density * x gamma -

macOS 10.3/CUPS 1.2cupsICCProfile

+

macOS 10.3/CUPS 1.2cupsICCProfile

*cupsICCProfile ColorModel.MediaType.Resolution/Description: "filename"

@@ -163,7 +167,7 @@ f(x) = density * x gamma *cupsICCProfile ../Default: "/Library/Printers/vendor/Profiles/foo-default.icc" -

Customizing the Profile Selection Keywords

+

Customizing the Profile Selection Keywords

The ColorModel, MediaType, and Resolution main keywords can be reassigned to different main keywords, allowing drivers to do color profile selection based on different parameters. The cupsICCQualifier1, cupsICCQualifier2, and cupsICCQualifier3 keywords define the mapping from selector to main keyword:

@@ -181,7 +185,8 @@ f(x) = density * x gamma *cupsICCQualifier3: Resolution -

macOS 10.4Custom Color Matching Support

+ +

macOS 10.4Custom Color Matching Support

*APSupportsCustomColorMatching: true
*APCustomColorMatchingName name/text: ""
@@ -196,7 +201,7 @@ f(x) = density * x gamma -

macOS 10.5APCustomColorMatchingName

+

macOS 10.5APCustomColorMatchingName

*APCustomColorMatchingName name/text: ""

@@ -210,7 +215,7 @@ f(x) = density * x gamma *fr.APCustomColorMatchingName name/La AcmeColor(tm): "" -

macOS 10.5APCustomColorMatchingProfile

+

macOS 10.5APCustomColorMatchingProfile

*APCustomColorMatchingProfile: name

@@ -232,7 +237,7 @@ f(x) = density * x gamma *APCustomColorMatchingProfile: AdobeRGB -

macOS 10.5APDefaultCustomColorMatchingProfile

+

macOS 10.5APDefaultCustomColorMatchingProfile

*APDefaultCustomColorMatchingProfile: name

@@ -246,7 +251,7 @@ f(x) = density * x gamma *APDefaultCustomColorMatchingProfile: sRGB -

macOS 10.4APSupportsCustomColorMatching

+

macOS 10.4APSupportsCustomColorMatching

*APSupportsCustomColorMatching: boolean

@@ -282,7 +287,8 @@ f(x) = density * x gamma -

CUPS 1.4/macOS 10.6cupsUIConstraints

+ +

CUPS 1.4/macOS 10.6cupsUIConstraints

*cupsUIConstraints resolver: "*Keyword1 *Keyword2 ..."
*cupsUIConstraints resolver: "*Keyword1 OptionKeyword1 *Keyword2 ..."
@@ -312,7 +318,8 @@ f(x) = density * x gamma *cupsUIConstraints photo: "*OutputMode Photo *MediaType Transparency *Resolution 1200dpi" -

CUPS 1.4/macOS 10.6cupsUIResolver

+ +

CUPS 1.4/macOS 10.6cupsUIResolver

*cupsUIResolver resolver: "*Keyword1 OptionKeyword1 *Keyword2 OptionKeyword2 ..."

@@ -529,7 +536,8 @@ option value is "1234" then CUPS will output the string "@PJL SET PASSCODE=1234"

The resulting dictionary sets the page device attributes that are sent to your raster driver in the page header.

-

Custom Page Size Code

+ +

Custom Page Size Code

There are many possible implementations of the CustomPageSize code. For CUPS raster drivers, the following code is recommended:

@@ -542,7 +550,8 @@ option value is "1234" then CUPS will output the string "@PJL SET PASSCODE=1234" *CustomPageSize True: "pop pop pop <</PageSize[5 -2 roll]/ImagingBBox null>>setpagedevice" -

Supported PostScript Operators

+ +

Supported PostScript Operators

CUPS supports the following PostScript operators in addition to the usual PostScript number, string (literal and hex-encoded), boolean, null, and name values:

@@ -601,7 +610,8 @@ PRE B { -

Supported Page Device Attributes

+ +

Supported Page Device Attributes

Table 2 shows the supported page device attributes along with PostScript code examples.

@@ -872,7 +882,8 @@ PRE B {

The CUPS media keywords allow drivers to specify alternate custom page size limits based on up to two options.

-

CUPS 1.4/macOS 10.6cupsMediaQualifier2

+ +

CUPS 1.4/macOS 10.6cupsMediaQualifier2

*cupsMediaQualifier2: MainKeyword

@@ -891,7 +902,8 @@ custom page size limits.

*cupsMinSize ..Photo: "300 300" -

CUPS 1.4/macOS 10.6cupsMediaQualifier3

+ +

CUPS 1.4/macOS 10.6cupsMediaQualifier3

*cupsMediaQualifier3: MainKeyword

@@ -910,7 +922,8 @@ custom page size limits.

*cupsMinSize ..Photo: "300 300" -

CUPS 1.4/macOS 10.6cupsMinSize

+ +

CUPS 1.4/macOS 10.6cupsMinSize

*cupsMinSize .Qualifier2.Qualifier3: "width length"
*cupsMinSize .Qualifier2.: "width length"
@@ -933,7 +946,8 @@ are used to identify options to use for matching.

*cupsMinSize ..Photo: "300 300" -

CUPS 1.4/macOS 10.6cupsMaxSize

+ +

CUPS 1.4/macOS 10.6cupsMaxSize

*cupsMaxSize .Qualifier2.Qualifier3: "width length"
*cupsMaxSize .Qualifier2.: "width length"
@@ -957,7 +971,7 @@ are used to identify options to use for matching.

-

CUPS 1.4/macOS 10.6cupsPageSizeCategory

+

CUPS 1.4/macOS 10.6cupsPageSizeCategory

*cupsPageSizeCategory name/text: "name name2 ... nameN"

@@ -974,7 +988,7 @@ are used to identify options to use for matching.

General Attributes

-

CUPS 1.3/macOS 10.5cupsBackSide

+

CUPS 1.3/macOS 10.5cupsBackSide

*cupsBackSide: keyword

@@ -1070,7 +1084,8 @@ will be ignored.

Also see the related APDuplexRequiresFlippedMargin keyword.

-

CUPS 1.4/macOS 10.6cupsCommands

+ +

CUPS 1.4/macOS 10.6cupsCommands

*cupsCommands: "name name2 ... nameN"

@@ -1086,7 +1101,7 @@ by whitespace.

-

CUPS 1.3/macOS 10.5cupsEvenDuplex

+

CUPS 1.3/macOS 10.5cupsEvenDuplex

*cupsEvenDuplex: boolean

@@ -1101,7 +1116,8 @@ printing is selected. The default value is false.

*cupsEvenDuplex: true -

cupsFax

+ +

cupsFax

*cupsFax: boolean

@@ -1113,7 +1129,8 @@ printing is selected. The default value is false.

*cupsFax: true -

cupsFilter

+ +

cupsFilter

*cupsFilter: "source/type cost program"

@@ -1135,7 +1152,8 @@ the special filter program "-" may be specified.

*cupsFilter: "application/vnd.cups-postscript 0 -" -

CUPS 1.5cupsFilter2

+ +

CUPS 1.5cupsFilter2

*cupsFilter2: "source/type destination/type cost program"

@@ -1160,7 +1178,27 @@ the special filter program "-" may be specified.

*cupsFilter2: "application/vnd.cups-postscript application/postscript 0 -" -

DeprecatedcupsFlipDuplex

+ +

CUPS 2.3cupsFinishingTemplate

+ +

*cupsFinishingTemplate name/text: ""

+ +

This option keyword specifies a finishing template (preset) that applies zero or more finishing processes to a job. Unlike cupsIPPFinishings, only one template can be selected by the user. PPD files also generally apply a constraint between this option and other finishing options like Booklet, FoldType, PunchMedia, and StapleWhen.

+ +

Examples:

+ +
+*cupsFinishingTemplate none/None: ""
+*cupsFinishingTemplate fold/Letter Fold: ""
+*cupsFinishingTemplate punch/2/3-Hole Punch: ""
+*cupsFinishingTemplate staple/Corner Staple: ""
+*cupsFinishingTemplate staple-dual/Double Staple: ""
+*cupsFinishingTemplate staple-and-fold/Corner Staple and Letter Fold: ""
+*cupsFinishingTemplate staple-and-punch/Corner Staple and 2/3-Hole Punch: ""
+
+ + +

DeprecatedcupsFlipDuplex

*cupsFlipDuplex: boolean

@@ -1195,7 +1233,8 @@ Ghostscript can use:

*cupsFlipDuplex: true -

CUPS 1.3/macOS 10.5cupsIPPFinishings

+ +

CUPS 1.3/macOS 10.5cupsIPPFinishings

*cupsIPPFinishings number/text: "*Option Choice ..."

@@ -1211,7 +1250,8 @@ values to PPD options and choices.

*cupsIPPFinishings 21/staple-bottom-left: "*StapleLocation SingleLandscape" -

CUPS 1.3/macOS 10.5cupsIPPReason

+ +

CUPS 1.3/macOS 10.5cupsIPPReason

*cupsIPPReason reason/Reason Text: "optional URIs"

@@ -1251,7 +1291,8 @@ http://www.vendor.com/help" *End -

CUPS 1.5cupsIPPSupplies

+ +

CUPS 1.5cupsIPPSupplies

*cupsIPPSupplies: boolean

@@ -1265,7 +1306,7 @@ http://www.vendor.com/help" -

CUPS 1.7/macOS 10.9cupsJobAccountId

+

CUPS 1.7/macOS 10.9cupsJobAccountId

*cupsJobAccountId: boolean

@@ -1279,7 +1320,7 @@ http://www.vendor.com/help" -

CUPS 1.7/macOS 10.9cupsJobAccountingUserId

+

CUPS 1.7/macOS 10.9cupsJobAccountingUserId

*cupsJobAccountingUserId: boolean

@@ -1293,11 +1334,24 @@ http://www.vendor.com/help" -

CUPS 1.7/macOS 10.9cupsJobPassword

+

CUPS 1.7/macOS 10.9cupsJobPassword

*cupsJobPassword: "format"

-

This keyword defines the format of the job-password IPP attribute, if supported by the printer. Currently the only supported format is "1111" indicating a 4-digit PIN code.

+

This keyword defines the format of the "job-password" IPP attribute, if supported by the printer. The following format characters are supported:

+ +
    +
  • 1: US ASCII digits.
  • +
  • A: US ASCII letters.
  • +
  • C: US ASCII letters, numbers, and punctuation.
  • +
  • .: Any US ASCII printable character (0x20 to 0x7e).
  • +
  • N: Any Unicode digit character.
  • +
  • U: Any Unicode letter character.
  • +
  • *: Any Unicode (utf-8) character.
  • +
+ +

The format characters are repeated to indicate the length of the +password string. For example, "1111" indicated a 4-digit US ASCII PIN code.

Example:

@@ -1307,7 +1361,7 @@ http://www.vendor.com/help" -

CUPS 1.2/macOS 10.5cupsLanguages

+

CUPS 1.2/macOS 10.5cupsLanguages

*cupsLanguages: "locale list"

@@ -1323,7 +1377,7 @@ list of locale names ("en", "en_US", "fr_CA", etc.)

-

CUPS 1.7/macOS 10.9cupsMandatory

+

CUPS 1.7/macOS 10.9cupsMandatory

*cupsMandatory: "attribute1 attribute2 ... attributeN"

@@ -1337,7 +1391,7 @@ list of locale names ("en", "en_US", "fr_CA", etc.)

-

cupsManualCopies

+

cupsManualCopies

*cupsManualCopies: boolean

@@ -1352,7 +1406,8 @@ hardware. The default value is false.

*cupsManualCopies: true -

CUPS 1.4/macOS 10.6cupsMarkerName

+ +

CUPS 1.4/macOS 10.6cupsMarkerName

*cupsMarkerName/Name Text: ""

@@ -1366,7 +1421,8 @@ generated by the driver to human readable text.

*cupsMarkerName cyanToner/Cyan Toner: "" -

CUPS 1.4/macOS 10.6cupsMarkerNotice

+ +

CUPS 1.4/macOS 10.6cupsMarkerNotice

*cupsMarkerNotice: "disclaimer text"

@@ -1380,7 +1436,8 @@ are approximate".

*cupsMarkerNotice: "Supply levels are approximate." -

CUPS 1.6/macOS 10.8cupsMaxCopies

+ +

CUPS 1.6/macOS 10.8cupsMaxCopies

*cupsMaxCopies: integer

@@ -1393,7 +1450,8 @@ are approximate".

*cupsMaxCopies: 99 -

cupsModelNumber

+ +

cupsModelNumber

*cupsModelNumber: number

@@ -1409,7 +1467,7 @@ the output for a specific model of printer.

-

CUPS 1.3/macOS 10.5cupsPJLCharset

+

CUPS 1.3/macOS 10.5cupsPJLCharset

*cupsPJLCharset: "ISO character set name"

@@ -1424,7 +1482,8 @@ assumed.

*cupsPJLCharset: "UTF-8" -

CUPS 1.4/macOS 10.6cupsPJLDisplay

+ +

CUPS 1.4/macOS 10.6cupsPJLDisplay

*cupsPJLDisplay: "what"

@@ -1443,7 +1502,8 @@ to use "@PJL RDYMSG DISPLAY". The default is "job".

*cupsPJLDisplay: "none" -

CUPS 1.2/macOS 10.5cupsPortMonitor

+ +

CUPS 1.2/macOS 10.5cupsPortMonitor

*cupsPortMonitor urischeme/Descriptive Text: "port monitor"

@@ -1475,7 +1535,8 @@ to disable the port monitor for the given URI scheme.

*cupsPortMonitor usb/USB Status Monitor: "epson-usb" -

CUPS 1.3/macOS 10.5cupsPreFilter

+ +

CUPS 1.3/macOS 10.5cupsPreFilter

*cupsPreFilter: "source/type cost program"

@@ -1494,7 +1555,7 @@ before the filter that accepts the given MIME type.

-

CUPS 1.5cupsPrintQuality

+

CUPS 1.5cupsPrintQuality

*cupsPrintQuality keyword/text: "code"

@@ -1518,7 +1579,8 @@ before the filter that accepts the given MIME type.

*CloseUI: *cupsPrintQuality -

CUPS 1.5cupsSingleFile

+ +

CUPS 1.5cupsSingleFile

*cupsSingleFile: Boolean

@@ -1534,7 +1596,8 @@ before the filter that accepts the given MIME type.

*cupsSingleFile: True -

CUPS 1.4/macOS 10.6cupsSNMPSupplies

+ +

CUPS 1.4/macOS 10.6cupsSNMPSupplies

*cupsSNMPSupplies: boolean

@@ -1549,7 +1612,8 @@ the standard SNMP Printer MIB OIDs for supply levels. The default value is *cupsSNMPSupplies: False -

cupsVersion

+ +

cupsVersion

*cupsVersion: major.minor

@@ -1565,7 +1629,7 @@ PPD file extensions was used. Currently it must be the string -

CUPS 1.6/macOS 10.8JCLToPDFInterpreter

+

CUPS 1.6/macOS 10.8JCLToPDFInterpreter

*JCLToPDFInterpreter: "JCL"

@@ -1581,7 +1645,7 @@ PPD file extensions was used. Currently it must be the string

macOS Attributes

-

macOS 10.3APDialogExtension

+

DeprecatedAPDialogExtension

*APDialogExtension: "/Library/Printers/vendor/filename.plugin"

@@ -1593,9 +1657,13 @@ plug-ins.

Note: -

Starting with macOS 10.5, each plug-in must be compiled "4-way fat" -(32-bit and 64-bit for both PowerPC and Intel) with garbage collection enabled -in order to be usable with all applications.

+

Since 2010, AirPrint has enabled the printing of full quality photos and +documents from the Mac without requiring driver software. Starting with macOS +10.12, system level security features prevent print dialog plug-ins from being +loaded into applications that have enabled the library validation security +feature. As of macOS 10.14 the APDialogExtension attribute used to +create macOS print drivers is deprecated. All new printer models should support +AirPrint moving forward.

@@ -1607,7 +1675,8 @@ in order to be usable with all applications.

*APDialogExtension: "/Library/Printers/vendor/options.plugin" -

macOS 10.4APDuplexRequiresFlippedMargin

+ +

macOS 10.4APDuplexRequiresFlippedMargin

*APDuplexRequiresFlippedMargin: boolean

@@ -1689,7 +1758,8 @@ and the Tumble page attribute.

Also see the related cupsBackSide keyword.

-

APHelpBook

+ +

APHelpBook

*APHelpBook: "bundle URL"

@@ -1704,7 +1774,8 @@ looking up IPP reason codes for this printer driver. The *APHelpBook: "file:///Library/Printers/vendor/Help.bundle" -

macOS 10.6APICADriver

+ +

macOS 10.6APICADriver

*APICADriver: boolean

@@ -1718,7 +1789,8 @@ Architecture (ICA) driver for scanning. The default is False.

*APScanAppBundleID: "com.apple.ImageCaptureApp" -

macOS 10.3APPrinterIconPath

+ +

macOS 10.3APPrinterIconPath

*APPrinterIconPath: "/Library/Printers/vendor/filename.icns"

@@ -1732,7 +1804,8 @@ displaying the printer. The file must be in the Apple icon format.

*APPrinterIconPath: "/Library/Printers/vendor/Icons/filename.icns" -

macOS 10.4APPrinterLowInkTool

+ +

macOS 10.4APPrinterLowInkTool

*APPrinterLowInkTool: "/Library/Printers/vendor/program"

@@ -1749,7 +1822,8 @@ Technical Note TN2144 for more information.

*APPrinterLowInkTool: "/Library/Printers/vendor/Tools/lowinktool" -

macOS 10.5APPrinterPreset

+ +

macOS 10.5APPrinterPreset

*APPrinterPreset name/text: "*Option Choice ..."

@@ -1819,7 +1893,8 @@ choice (*MainKeyword OptionKeyword) or a preset identifier and value *fr.APPrinterPreset Photo_on_Photo_Paper/Photo sur papier photographique: "" -

macOS 10.3APPrinterUtilityPath

+ +

macOS 10.3APPrinterUtilityPath

*APPrinterPrinterUtilityPath: "/Library/Printers/vendor/filename.app"

@@ -1834,7 +1909,8 @@ information.

*APPrinterPrinterUtilityPath: "/Library/Printers/vendor/Tools/utility.app" -

macOS 10.6APScannerOnly

+ +

macOS 10.6APScannerOnly

*APScannerOnly: boolean

@@ -1848,7 +1924,8 @@ capabilities. The default is False.

*APScannerOnly: True -

macOS 10.3APScanAppBundleID

+ +

macOS 10.3APScanAppBundleID

*APScanAppBundleID: "bundle ID"

@@ -1865,7 +1942,16 @@ the device.

Change History

-

Changes in CUPS 1.7

+

Changes in CUPS 2.3

+ + + + +

Changes in CUPS 1.7

    @@ -1877,7 +1963,7 @@ the device.

-

Changes in CUPS 1.6

+

Changes in CUPS 1.6

    @@ -1892,7 +1978,7 @@ the device.

-

Changes in CUPS 1.5

+

Changes in CUPS 1.5

    @@ -1901,7 +1987,7 @@ the device.

-

Changes in CUPS 1.4.5

+

Changes in CUPS 1.4.5

    @@ -1912,7 +1998,7 @@ the device.

-

Changes in CUPS 1.4

+

Changes in CUPS 1.4

    @@ -1947,7 +2033,7 @@ the device.

-

Changes in CUPS 1.3.1

+

Changes in CUPS 1.3.1

    @@ -1962,7 +2048,7 @@ the device.

-

Changes in CUPS 1.3

+

Changes in CUPS 1.3

    @@ -1981,7 +2067,8 @@ the device.

-

Changes in CUPS 1.2.8

+ +

Changes in CUPS 1.2.8

    @@ -1990,7 +2077,8 @@ the device.

-

Changes in CUPS 1.2

+ +

Changes in CUPS 1.2

    @@ -2015,7 +2103,8 @@ the device.

-

Changes in CUPS 1.1

+ +

Changes in CUPS 1.1

    diff --git a/mopria.c b/mopria.c new file mode 100644 index 0000000..0ca08db --- /dev/null +++ b/mopria.c @@ -0,0 +1,12 @@ +#include +#include + +// 08/28/2018 Mopria-notice: localeconv not present in Android. +inline struct lconv *localeconv(void) { + return NULL; +} + +// 08/28/2018 Mopria-notice: pthread_cancel not present in Android +void pthread_cancel(int thread) { + // Ignore thread cancel attempts +}