adding CUPS code

This commit is contained in:
Glade Diviney
2016-10-14 09:01:09 -07:00
parent b9fe22a24c
commit 52519bfb65
161 changed files with 103847 additions and 0 deletions

82
Android.mk Normal file
View File

@@ -0,0 +1,82 @@
# (c) Copyright 2013 Hewlett-Packard Development Company, L.P.
#
# 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.
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
cups/array.c \
cups/attr.c \
cups/auth.c \
cups/backchannel.c \
cups/backend.c \
cups/conflicts.c \
cups/custom.c \
cups/debug.c \
cups/dest.c \
cups/dest-job.c \
cups/dest-localization.c \
cups/dest-options.c \
cups/dir.c \
cups/emit.c \
cups/encode.c \
cups/file.c \
cups/getdevices.c \
cups/getifaddrs.c \
cups/getputfile.c \
cups/globals.c \
cups/http.c \
cups/http-addr.c \
cups/http-addrlist.c \
cups/http-support.c \
cups/ipp.c \
cups/ipp-support.c \
cups/langprintf.c \
cups/language.c \
cups/localize.c \
cups/mark.c \
cups/md5.c \
cups/md5passwd.c \
cups/notify.c \
cups/options.c \
cups/page.c \
cups/ppd.c \
cups/ppd-cache.c \
cups/pwg-media.c \
cups/request.c \
cups/sidechannel.c \
cups/snmp.c \
cups/snprintf.c \
cups/string.c \
cups/tempfile.c \
cups/thread.c \
cups/transcode.c \
cups/usersys.c \
cups/util.c \
filter/error.c \
filter/raster.c \
disabled_src_files:= \
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/cups \
$(LOCAL_PATH)/../openssl/include
LOCAL_CFLAGS := -D_PPD_DEPRECATED=
LOCAL_MODULE := lib$(PRIV_LIB_NAME)cups
LOCAL_MODULE_TAGS := optional
LOCAL_LDLIBS += -lz -llog
LOCAL_STATIC_LIBRARIES := libssl libcrypto
include $(BUILD_SHARED_LIBRARY)

217
CHANGES-1.0.txt Normal file
View File

@@ -0,0 +1,217 @@
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.

3462
CHANGES-1.1.txt Normal file

File diff suppressed because it is too large Load Diff

1261
CHANGES-1.2.txt Normal file

File diff suppressed because it is too large Load Diff

856
CHANGES-1.3.txt Normal file
View File

@@ -0,0 +1,856 @@
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 </LimitExcept> (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 </Foo> 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.

843
CHANGES-1.4.txt Normal file
View File

@@ -0,0 +1,843 @@
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.

312
CHANGES-1.5.txt Normal file
View File

@@ -0,0 +1,312 @@
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 (<cups/cups.h>) no longer includes the PPD header
(<cups/ppd.h>).
- 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)

225
CHANGES.txt Normal file
View File

@@ -0,0 +1,225 @@
CHANGES.txt - 1.6.3 - 2013-07-11
--------------------------------
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 (<rdar://problem/14401718>)
- The lp, lpq, lpr, and lpstat now display an error message advising the
use of the /version=1.1 ServerName option (<rdar://problem/14290628>)
- Added documentation about the /version=1.1 option to ServerName in
client.conf (<rdar://problem/14216262>)
- httpStatus(HTTP_ERROR) did not return a useful error message
(<rdar://problem/14217326>)
- The lp, lpq, lpr, and lpstat commands incorrectly ignored the default
printer set in the lpoptions file (<rdar://problem/14216472>)
- Fixed a URI encoding issue for hostnames containing the ` (backquote)
character (<rdar://problem/14243133>)
- Added support for RFC 6874's IPv6 link local address format in URIs
(<rdar://problem/13979453>)
- The USB backend could crash on libusb-based systems if USB was
disabled in the BIOS (<rdar://problem/13875729>)
- Fixed a rounding error in the PWG media size mapping code
(<rdar://problem/13493241>)
- 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,
<rdar://problem/13736470>)
- 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)

51
CREDITS.txt Normal file
View File

@@ -0,0 +1,51 @@
CREDITS.txt - 2012-07-16
------------------------
Few projects are completed by one person, and CUPS is no exception. We'd
like to thank the following individuals for their contributions:
Nathaniel Barbour - Lots of testing and feedback.
N. Becker - setsid().
Philippe Combes - French localization and buttons script.
Jean-Eric Cuendet - GhostScript filters for CUPS.
Van Dang - HTTP and IPP policeman.
L. Peter Deutsch - MD5 code.
Dr. ZP Han - setgid()/setuid().
Guy Harris - *BSD shared libraries and lots of other
fixes.
Bjoern Jacke - I18N stuff.
Wang Jian - CUPS RPM corrections.
Roderick Johnstone - Beta tester of the millenium.
Till Kamppeter - Bug fixes, beta testing, evangelism.
Iñaki Larrañaga - Basque localization.
Kenshi Muto - Japanese localization, patches, and
testing.
Tomohiro Kato - Japanese localization.
Kiko - Bug fixes.
Sergey V. Kovalyov - ESP Print Pro and CUPS beta tester.
Marek Laane - Estonian translation.
Mark Lawrence - Microsoft interoperability testing.
Jeff Licquia - Bug fixes, beta testing, evangelism.
Jason McMullan - Original CUPS RPM distributions.
Àngel Mompó - Catalan localization.
Wes Morgan - *BSD fixes.
Daniel Nylander - Swedish localization.
Niklas 'Nille' Åkerström - Swedish localization.
Naruiko Ogasawara - Japanese localization.
Giulio Orsero - Bug fixes and testing.
Michal Osowiecki - Polish localization.
Citra Paska - Indonesian localization.
Kurt Pfeifle - Bug fixes, beta testing, evangelism.
Vincenzo Reale - Italian localization.
Petter Reinholdtsen - HP-UX compiler stuff.
Juan Pablo González Riopedre - Spanish localization.
Opher Shachar - Hebrew localization.
Stuart Stevens - HP JetDirect IPP information.
Andrea Suatoni - IRIX desktop integration and testing.
Teppo Turliainen - Finnish localization.
Tim Waugh - Lots of patches, testing, and Linux
integration.
Yugami - LDAP browsing support.
If I've missed someone, please let me know by sending an email to
"msweet@apple.com".

213
INSTALL.txt Normal file
View File

@@ -0,0 +1,213 @@
INSTALL - CUPS v1.6.3 - 2013-07-11
----------------------------------
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".
*******************************************************************************
*******************************************************************************
**** ****
**** 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. ****
**** ****
*******************************************************************************
*******************************************************************************
BEFORE YOU BEGIN
You'll need ANSI-compliant C and C++ compilers, plus a make program and
POSIX-compliant shell (/bin/sh). The GNU compiler tools and Bash work well
and we have tested the current CUPS code against several versions of GCC
with excellent results.
The makefiles used by the project should work with most versions of make.
We've tested them with GNU make as well as the make programs shipped by
Compaq, HP, SGI, and Sun. BSD users should use GNU make (gmake) since BSD
make does not support "include".
Besides these tools you'll want the JPEG, PNG, TIFF, and ZLIB libraries for
image support, the CDSA, GNU TLS, or OpenSSL libraries for encryption
support, the OpenLDAP and OpenSLP libraries for directory services support,
and either MIT (1.6.3 or higher) or Heimdal Kerberos for Kerberos support.
CUPS will compile and run without these, however you'll miss out on many of
the features provided by CUPS.
Also, please note that CUPS does not include the Ghostscript-based
PostScript filter needed by non-PostScript printers. You *must* download
GPL Ghostscript separately from the CUPS web site if you want to print
PostScript files to non-PostScript printers on operating systems other than
OS X.
COMPILING THE SUBVERSION REPOSITORY CODE
The CUPS Subversion repository doesn't hold a copy of the pre-built
configure script. You'll need to run the GNU autoconf software (2.60 or
higher) to create it:
autoconf
CONFIGURATION
CUPS uses GNU autoconf, so you should find the usual "configure" script in
the main CUPS source directory. To configure CUPS for your system, type:
./configure
The default installation will put the CUPS software in the "/etc", "/usr",
and "/var" directories on your system, which will overwrite any existing
printing commands on your system. Use the "--prefix" option to install the
CUPS software in another location:
./configure --prefix=/some/directory
To see a complete list of configuration options, use the --help option:
./configure --help
If any of the dependent libraries are not installed in a system default
location (typically "/usr/include" and "/usr/lib") you'll need to set the
CFLAGS, CPPFLAGS, CXXFLAGS, DSOFLAGS, and LDFLAGS environment variables
prior to running configure:
setenv CFLAGS "-I/some/directory"
setenv CPPFLAGS "-I/some/directory"
setenv CXXFLAGS "-I/some/directory"
setenv DSOFLAGS "-L/some/directory"
setenv LDFLAGS "-L/some/directory"
./configure ...
or:
CFLAGS="-I/some/directory" \
CPPFLAGS="-I/some/directory" \
CXXFLAGS="-I/some/directory" \
DSOFLAGS="-L/some/directory" \
LDFLAGS="-L/some/directory" \
./configure ...
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.
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.
Once you have configured things, just type:
make ENTER
or if you have FreeBSD, NetBSD, or OpenBSD type:
gmake ENTER
to build the software.
TESTING THE SOFTWARE
Aside from the built-in unit tests, CUPS includes an automated test
framework for testing the entire printing system. To run the tests, just
type:
make check ENTER
or if you have FreeBSD, NetBSD, or OpenBSD type:
gmake check ENTER
The test framework runs a copy of the CUPS scheduler (cupsd) on port 8631
in /tmp/cups-$USER and produces a nice HTML report of the results.
INSTALLING THE SOFTWARE
Once you have built the software you need to install it. The "install"
target provides a quick way to install the software on your local system:
make install ENTER
or for FreeBSD, NetBSD, or OpenBSD:
gmake install ENTER
You can also build binary packages that can be installed on other machines
using the RPM spec file ("packaging/cups.spec") or EPM list file
("packaging/cups.list"). The latter also supports building of binary RPMs,
so it may be more convenient to use.
You can find the RPM software at:
http://www.rpm.org/
The EPM software is available at:
http://www.epmhome.org/
CREATING BINARY DISTRIBUTIONS WITH EPM
The top level makefile supports generation of many types of binary
distributions using EPM. To build a binary distribution type:
make <format> ENTER
or
gmake <format> ENTER
for FreeBSD, NetBSD, and OpenBSD. The <format> target is one of the
following:
epm - Builds a script + tarfile package
aix - Builds an AIX package
bsd - Builds a *BSD package
deb - Builds a Debian package
depot - Builds a HP-UX package (also swinstall)
inst - Builds an IRIX package (also tardist)
pkg - Builds a Solaris package
rpm - Builds a RPM package
setld - Build a Tru64 UNIX package
slackware - Build a Slackware package
swinstall - Build a HP-UX package (also depot)
tardist - Builds an IRIX package (also inst)
GETTING DEBUG LOGGING FROM CUPS
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:
CUPS_DEBUG_FILTER Specifies a POSIX regular expression to control
which messages are logged.
CUPS_DEBUG_LEVEL Specifies a number from 0 to 9 to control the
verbosity of 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.
REPORTING PROBLEMS
If you have problems, READ THE DOCUMENTATION FIRST! If the documentation
does not solve your problems, please post a message on the "cups.general"
forum at:
http://www.cups.org/newsgroups.php
Include your operating system and version, compiler and version, and any
errors or problems you've run into. The "config.log" file and the output
from the configure script and make should also be sent, as it often helps to
determine the cause of your problem.
If you are running a version of Linux, be sure to provide the Linux
distribution you have, too.

971
LICENSE.txt Normal file
View File

@@ -0,0 +1,971 @@
CUPS License Agreement
Copyright 2007-2012 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
exceptions for Apple operating systems and the OpenSSL toolkit. A
copy of the exceptions 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 exceptions:
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, OS X, and OS X Server
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.
2. OpenSSL Toolkit License Exception;
a. Apple Inc. explicitly allows the compilation and
distribution of the CUPS software with the OpenSSL
Toolkit.
No developer is required to provide these exceptions 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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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.
<signature of Ty Coon>, 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.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

262
Makedefs.in Normal file
View File

@@ -0,0 +1,262 @@
#
# "$Id: Makedefs.in 7900 2008-09-03 13:47:57Z mike $"
#
# Common makefile definitions 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/".
#
#
# Programs...
#
AR = @AR@
AWK = @AWK@
CC = @LIBTOOL@ @CC@
CHMOD = @CHMOD@
CXX = @LIBTOOL@ @CXX@
DSO = @DSO@
DSOXX = @DSOXX@
GZIP = @GZIP@
INSTALL = @INSTALL@
LD = @LD@
LIBTOOL = @LIBTOOL@
LN = @LN@ -sf
MV = @MV@
RANLIB = @RANLIB@
RM = @RM@ -f
RMDIR = @RMDIR@
SED = @SED@
SHELL = /bin/sh
#
# Installation programs...
#
INSTALL_BIN = $(LIBTOOL) $(INSTALL) -c -m 555 @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 555 @INSTALL_STRIP@
INSTALL_MAN = $(INSTALL) -c -m 444
INSTALL_SCRIPT = $(INSTALL) -c -m 555
#
# Default user, group, and system groups for the scheduler...
#
CUPS_USER = @CUPS_USER@
CUPS_GROUP = @CUPS_GROUP@
CUPS_SYSTEM_GROUPS = @CUPS_SYSTEM_GROUPS@
CUPS_PRIMARY_SYSTEM_GROUP = @CUPS_PRIMARY_SYSTEM_GROUP@
#
# Default permissions...
#
CUPS_CONFIG_FILE_PERM = @CUPS_CONFIG_FILE_PERM@
CUPS_CUPSD_FILE_PERM = @CUPS_CUPSD_FILE_PERM@
CUPS_LOG_FILE_PERM = @CUPS_LOG_FILE_PERM@
#
# Languages to install...
#
LANGUAGES = @LANGUAGES@
INSTALL_LANGUAGES = @INSTALL_LANGUAGES@
UNINSTALL_LANGUAGES = @UNINSTALL_LANGUAGES@
#
# Libraries...
#
LIBCUPS = @LIBCUPS@
LIBCUPSCGI = @LIBCUPSCGI@
LIBCUPSIMAGE = @LIBCUPSIMAGE@
LIBCUPSMIME = @LIBCUPSMIME@
LIBCUPSPPDC = @LIBCUPSPPDC@
LIBCUPSSTATIC = @LIBCUPSSTATIC@
LIBGSSAPI = @LIBGSSAPI@
LIBMALLOC = @LIBMALLOC@
LIBMXML = @LIBMXML@
LIBPAPER = @LIBPAPER@
LIBUSB = @LIBUSB@
LIBWRAP = @LIBWRAP@
LIBZ = @LIBZ@
#
# Install static libraries?
#
INSTALLSTATIC = @INSTALLSTATIC@
#
# IPP backend aliases...
#
IPPALIASES = @IPPALIASES@
#
# Install XPC backends?
#
INSTALLXPC = @INSTALLXPC@
#
# Program options...
#
# ARCHFLAGS Defines the default architecture build options.
# OPTIM Defines the common compiler optimization/debugging options
# for all architectures.
# OPTIONS Defines other compile-time options (currently only -DDEBUG
# for extra debug info)
#
ALL_CFLAGS = -I.. -D_CUPS_SOURCE $(CFLAGS) $(SSLFLAGS) \
@LARGEFILE@ @PTHREAD_FLAGS@ $(OPTIONS)
ALL_CXXFLAGS = -I.. -D_CUPS_SOURCE $(CXXFLAGS) $(SSLFLAGS) \
@LARGEFILE@ @PTHREAD_FLAGS@ $(OPTIONS)
ARCHFLAGS = @ARCHFLAGS@
ARFLAGS = @ARFLAGS@
BACKLIBS = @BACKLIBS@
BUILDDIRS = @BUILDDIRS@
CFLAGS = @CPPFLAGS@ @CFLAGS@
COMMONLIBS = @LIBS@
CXXFLAGS = @CPPFLAGS@ @CXXFLAGS@
CXXLIBS = @CXXLIBS@
DBUS_NOTIFIER = @DBUS_NOTIFIER@
DBUS_NOTIFIERLIBS = @DBUS_NOTIFIERLIBS@
DNSSD_BACKEND = @DNSSD_BACKEND@
DSOFLAGS = -L../cups @DSOFLAGS@
DSOLIBS = @DSOLIBS@ $(COMMONLIBS)
DNSSDLIBS = @DNSSDLIBS@
LAUNCHDLIBS = @LAUNCHDLIBS@
LDFLAGS = -L../cgi-bin -L../cups -L../filter -L../ppdc \
-L../scheduler @LDARCHFLAGS@ \
@LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM)
LINKCUPS = @LINKCUPS@ $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(LIBZ)
LINKCUPSIMAGE = @LINKCUPSIMAGE@
LIBS = $(LINKCUPS) $(COMMONLIBS)
OPTIM = @OPTIM@
OPTIONS =
PAMLIBS = @PAMLIBS@
SERVERLIBS = @SERVERLIBS@
SSLFLAGS = @SSLFLAGS@
SSLLIBS = @SSLLIBS@
UNITTESTS = @UNITTESTS@
#
# Directories...
#
# The first section uses the GNU names (which are *extremely*
# difficult to find in a makefile because they are lowercase...)
# We have to define these first because autoconf uses ${prefix}
# and ${exec_prefix} for most of the other directories...
#
# The "datarootdir" variable may not get defined if you are using
# a version of autoconf prior to 2.60.
#
# This is immediately followed by definition in ALL CAPS for the
# needed directories...
#
bindir = @bindir@
datadir = @datadir@
datarootdir = @datarootdir@
exec_prefix = @exec_prefix@
includedir = @includedir@
infodir = @infodir@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
prefix = @prefix@
privateinclude = @privateinclude@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
top_srcdir = @top_srcdir@
BUILDROOT = $(DSTROOT)
AMANDIR = $(BUILDROOT)@AMANDIR@
BINDIR = $(BUILDROOT)@bindir@
BUNDLEDIR = @CUPS_BUNDLEDIR@
CACHEDIR = $(BUILDROOT)@CUPS_CACHEDIR@
DATADIR = $(BUILDROOT)@CUPS_DATADIR@
DOCDIR = $(BUILDROOT)@CUPS_DOCROOT@
ICONDIR = @ICONDIR@
INCLUDEDIR = $(BUILDROOT)$(includedir)
INITDIR = @INITDIR@
INITDDIR = @INITDDIR@
LIBDIR = $(BUILDROOT)$(libdir)
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@
SBINDIR = $(BUILDROOT)@sbindir@
SERVERBIN = $(BUILDROOT)@CUPS_SERVERBIN@
SERVERROOT = $(BUILDROOT)@CUPS_SERVERROOT@
SMFMANIFESTDIR = @SMFMANIFESTDIR@
STATEDIR = $(BUILDROOT)@CUPS_STATEDIR@
XINETD = @XINETD@
MAN1EXT = @MAN1EXT@
MAN5EXT = @MAN5EXT@
MAN7EXT = @MAN7EXT@
MAN8EXT = @MAN8EXT@
MAN8DIR = @MAN8DIR@
PAMDIR = @PAMDIR@
PAMFILE = @PAMFILE@
DEFAULT_LAUNCHD_CONF = @DEFAULT_LAUNCHD_CONF@
DBUSDIR = @DBUSDIR@
#
# Rules...
#
.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
.c.o:
echo Compiling $<...
$(CC) $(ARCHFLAGS) $(OPTIM) $(ALL_CFLAGS) -c -o $@ $<
.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 <$< >$@
#
# End of "$Id: Makedefs.in 7900 2008-09-03 13:47:57Z mike $"
#

336
Makefile Normal file
View File

@@ -0,0 +1,336 @@
#
# "$Id: Makefile 9391 2010-11-30 21:53:04Z mike $"
#
# Top-level Makefile for CUPS.
#
# Copyright 2007-2013 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/".
#
include Makedefs
#
# Directories to make...
#
DIRS = cups test $(BUILDDIRS)
#
# Make all targets...
#
all:
chmod +x cups-config
echo Using ARCHFLAGS="$(ARCHFLAGS)"
echo Using ALL_CFLAGS="$(ALL_CFLAGS)"
echo Using ALL_CXXFLAGS="$(ALL_CXXFLAGS)"
echo Using CC="$(CC)"
echo Using CXX="$(CC)"
echo Using DSOFLAGS="$(DSOFLAGS)"
echo Using LDFLAGS="$(LDFLAGS)"
echo Using LIBS="$(LIBS)"
for dir in $(DIRS); do\
echo Making all in $$dir... ;\
(cd $$dir ; $(MAKE) $(MFLAGS) all $(UNITTESTS)) || exit 1;\
done
#
# Make library targets...
#
libs:
echo Using ARCHFLAGS="$(ARCHFLAGS)"
echo Using ALL_CFLAGS="$(ALL_CFLAGS)"
echo Using ALL_CXXFLAGS="$(ALL_CXXFLAGS)"
echo Using CC="$(CC)"
echo Using CXX="$(CC)"
echo Using DSOFLAGS="$(DSOFLAGS)"
echo Using LDFLAGS="$(LDFLAGS)"
echo Using LIBS="$(LIBS)"
for dir in $(DIRS); do\
echo Making libraries in $$dir... ;\
(cd $$dir ; $(MAKE) $(MFLAGS) libs) || exit 1;\
done
#
# Make unit test targets...
#
unittests:
echo Using ARCHFLAGS="$(ARCHFLAGS)"
echo Using ALL_CFLAGS="$(ALL_CFLAGS)"
echo Using ALL_CXXFLAGS="$(ALL_CXXFLAGS)"
echo Using CC="$(CC)"
echo Using CXX="$(CC)"
echo Using DSOFLAGS="$(DSOFLAGS)"
echo Using LDFLAGS="$(LDFLAGS)"
echo Using LIBS="$(LIBS)"
for dir in $(DIRS); do\
echo Making all in $$dir... ;\
(cd $$dir ; $(MAKE) $(MFLAGS) unittests) || exit 1;\
done
#
# Remove object and target files...
#
clean:
for dir in $(DIRS); do\
echo Cleaning in $$dir... ;\
(cd $$dir; $(MAKE) $(MFLAGS) clean) || exit 1;\
done
#
# Remove all non-distribution files...
#
distclean: clean
$(RM) Makedefs config.h config.log config.status
$(RM) cups-config
$(RM) conf/cups-files.conf conf/cupsd.conf
$(RM) conf/mime.convs conf/pam.std conf/snmp.conf
$(RM) doc/help/ref-cups-files-conf.html doc/help/ref-cupsd-conf.html
$(RM) doc/help/standard.html doc/index.html
$(RM) man/client.conf.man
$(RM) man/cups-deviced.man man/cups-driverd.man
$(RM) man/cups-lpd.man man/cupsaddsmb.man man/cupsd.man
$(RM) man/cupsd.conf.man man/drv.man man/lpoptions.man
$(RM) packaging/cups.list
$(RM) packaging/cups-desc.plist packaging/cups-info.plist
$(RM) templates/header.tmpl
$(RM) desktop/cups.desktop
$(RM) scheduler/cups.sh scheduler/cups-lpd.xinetd
$(RM) scheduler/org.cups.cups-lpd.plist scheduler/cups.xml
-$(RM) doc/*/index.html
-$(RM) templates/*/header.tmpl
-$(RM) -r autom4te*.cache clang cups/charmaps cups/locale driver/test
#
# Make dependencies
#
depend:
for dir in $(DIRS); do\
echo Making dependencies in $$dir... ;\
(cd $$dir; $(MAKE) $(MFLAGS) depend) || exit 1;\
done
#
# Run the clang.llvm.org static code analysis tool on the C sources.
# (at least checker-231 is required for scan-build to work this way)
#
.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
#
# Generate a ctags file...
#
ctags:
ctags -R .
#
# Install everything...
#
install: install-data install-headers install-libs install-exec
#
# Install data files...
#
install-data:
echo Making all in cups...
(cd cups; $(MAKE) $(MFLAGS) all)
for dir in $(DIRS); do\
echo Installing data files in $$dir... ;\
(cd $$dir; $(MAKE) $(MFLAGS) install-data) || exit 1;\
done
echo Installing cups-config script...
$(INSTALL_DIR) -m 755 $(BINDIR)
$(INSTALL_SCRIPT) cups-config $(BINDIR)/cups-config
#
# Install header files...
#
install-headers:
for dir in $(DIRS); do\
echo Installing header files in $$dir... ;\
(cd $$dir; $(MAKE) $(MFLAGS) install-headers) || exit 1;\
done
if test "x$(privateinclude)" != x; then \
echo Installing config.h into $(PRIVATEINCLUDE)...; \
$(INSTALL_DIR) -m 755 $(PRIVATEINCLUDE); \
$(INSTALL_DATA) config.h $(PRIVATEINCLUDE)/config.h; \
fi
#
# Install programs...
#
install-exec: all
for dir in $(DIRS); do\
echo Installing programs in $$dir... ;\
(cd $$dir; $(MAKE) $(MFLAGS) install-exec) || exit 1;\
done
#
# Install libraries...
#
install-libs: libs
for dir in $(DIRS); do\
echo Installing libraries in $$dir... ;\
(cd $$dir; $(MAKE) $(MFLAGS) install-libs) || exit 1;\
done
#
# Uninstall object and target files...
#
uninstall:
for dir in $(DIRS); do\
echo Uninstalling in $$dir... ;\
(cd $$dir; $(MAKE) $(MFLAGS) uninstall) || exit 1;\
done
echo Uninstalling cups-config script...
$(RM) $(BINDIR)/cups-config
-$(RMDIR) $(BINDIR)
#
# Run the test suite...
#
test: all unittests
echo Running CUPS test suite...
cd test; ./run-stp-tests.sh
check: all unittests
echo Running CUPS test suite with defaults...
cd test; ./run-stp-tests.sh 1 0 n n
debugcheck: all unittests
echo Running CUPS test suite with debug printfs...
cd test; ./run-stp-tests.sh 1 0 n y
#
# Create HTML documentation...
#
apihelp:
for dir in cgi-bin cups filter ppdc scheduler; do\
echo Generating API help in $$dir... ;\
(cd $$dir; $(MAKE) $(MFLAGS) apihelp) || exit 1;\
done
framedhelp:
for dir in cgi-bin cups filter ppdc scheduler; do\
echo Generating framed API help in $$dir... ;\
(cd $$dir; $(MAKE) $(MFLAGS) framedhelp) || exit 1;\
done
#
# Create an Xcode docset...
#
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...
#
sloc:
for dir in cups scheduler; do \
(cd $$dir; $(MAKE) $(MFLAGS) sloc) || exit 1;\
done
#
# Make software distributions using EPM (http://www.epmhome.org/)...
#
EPMFLAGS = -v --output-dir dist $(EPMARCH)
aix bsd deb depot inst pkg setld slackware swinstall tardist:
epm $(EPMFLAGS) -f $@ cups packaging/cups.list
epm:
epm $(EPMFLAGS) -s packaging/installer.gif cups packaging/cups.list
rpm:
epm $(EPMFLAGS) -f rpm -s packaging/installer.gif cups packaging/cups.list
.PHONEY: dist
dist: all
$(RM) -r dist
$(MAKE) $(MFLAGS) epm
case `uname` in \
*BSD*) $(MAKE) $(MFLAGS) bsd;; \
Darwin*) $(MAKE) $(MFLAGS) osx;; \
IRIX*) $(MAKE) $(MFLAGS) tardist;; \
Linux*) test ! -x /usr/bin/rpm || $(MAKE) $(MFLAGS) rpm;; \
SunOS*) $(MAKE) $(MFLAGS) pkg;; \
esac
#
# Don't run top-level build targets in parallel...
#
.NOTPARALLEL:
#
# End of "$Id: Makefile 9391 2010-11-30 21:53:04Z mike $".
#

163
README.txt Normal file
View File

@@ -0,0 +1,163 @@
README - CUPS v1.6.3 - 2013-07-11
---------------------------------
Looking for compile instructions? Read the file "INSTALL.txt" instead...
INTRODUCTION
CUPS is a standards-based, open source printing system developed by Apple
Inc. for OS® X and other UNIX®-like operating systems. CUPS uses the
Internet Printing Protocol ("IPP") and provides System V and Berkeley
command-line interfaces, a web interface, and a C API to manage printers and
print jobs. It supports printing to both local (parallel, serial, USB) and
networked printers, and printers can be shared from one computer to another,
even over the Internet!
Internally, CUPS uses PostScript Printer Description ("PPD") files to
describe printer capabilities and features and a wide variety of generic
and device-specific programs to convert and print many types of files.
Sample drivers are 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.
READING THE DOCUMENTATION
Once you have installed the software you can access the documentation (and
a bunch of other stuff) online at:
http://localhost:631/
If you're having trouble getting that far, the documentation is located
under the "doc/help" directory.
Please read the documentation before asking questions.
GETTING SUPPORT AND OTHER RESOURCES
If you have problems, READ THE DOCUMENTATION FIRST! We also provide many
discussion forums which are available at:
http://www.cups.org/newsgroups.php
See the CUPS web site at "http://www.cups.org/" for other resources.
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/
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.
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
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 includes several sample PPD files you can use:
Driver PPD Name
----------------------------- ------------------------------
Dymo Label Printers drv:///sample.drv/dymo.ppd
Intellitech Intellibar drv:///sample.drv/intelbar.ppd
EPSON Stylus Color Series drv:///sample.drv/stcolor.ppd
EPSON Stylus Photo Series drv:///sample.drv/stphoto.ppd
EPSON Stylus New Color Series drv:///sample.drv/stcolor2.ppd
EPSON Stylus New Photo Series drv:///sample.drv/stphoto2.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
Run the "lpinfo -m" command to list the available drivers:
lpinfo -m
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:
lpadmin -p printername -E -v device-uri -m ppd-name
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. The CUPS web site
provides links and drivers:
http://www.cups.org/ppd.php PPD files
http://www.cups.org/links.php Links to other drivers
PRINTING FILES
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:
lp -o media=A4 -o resolution=600dpi filename
lpr -o media=A4 -o resolution=600dpi filename
CUPS recognizes many types of images files as well as PDF, PostScript,
HP-GL/2, 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:
lp -o raw filename
lpr -l filename
This will prevent the filters from misinterpreting your print
file.
LEGAL STUFF
CUPS is Copyright 2007-2013 by Apple Inc. CUPS and the CUPS logo are
trademarks of Apple Inc.
The MD5 Digest code is Copyright 1999 Aladdin Enterprises.
This software is based in part on the work of the Independent JPEG Group.
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.

750
config.h Normal file
View File

@@ -0,0 +1,750 @@
/* 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.
*
* Copyright 2007-2012 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*/
/* 07/22/2016 Mopria-notice: some config changes were applied directly to this generated file
* rather than by running the configure script again.
*/
#ifndef _CUPS_CONFIG_H_
#define _CUPS_CONFIG_H_
/*
* Version of software...
*/
#define CUPS_SVERSION "CUPS v1.6.3"
#define CUPS_MINIMAL "CUPS/1.6.3"
/*
* Default user and groups...
*/
#define CUPS_DEFAULT_USER "lp"
#define CUPS_DEFAULT_GROUP "lp"
#define CUPS_DEFAULT_SYSTEM_GROUPS "lpadmin sys root"
#define CUPS_DEFAULT_PRINTOPERATOR_AUTH "@SYSTEM"
/*
* Default file permissions...
*/
#define CUPS_DEFAULT_CONFIG_FILE_PERM 0644
#define CUPS_DEFAULT_LOG_FILE_PERM 0644
/*
* Default logging settings...
*/
#define CUPS_DEFAULT_LOG_LEVEL "warn"
#define CUPS_DEFAULT_ACCESS_LOG_LEVEL "actions"
/*
* Default fatal error settings...
*/
#define CUPS_DEFAULT_FATAL_ERRORS "config"
/*
* Default browsing settings...
*/
#define CUPS_DEFAULT_BROWSING 1
#define CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS "dnssd"
#define CUPS_DEFAULT_DEFAULT_SHARED 1
/*
* Default IPP port...
*/
#define CUPS_DEFAULT_IPP_PORT 631
/*
* Default printcap file...
*/
#define CUPS_DEFAULT_PRINTCAP "/etc/printcap"
/*
* Default Samba and LPD config files...
*/
#define CUPS_DEFAULT_SMB_CONFIG_FILE ""
#define CUPS_DEFAULT_LPD_CONFIG_FILE ""
/*
* Default MaxCopies value...
*/
#define CUPS_DEFAULT_MAX_COPIES 9999
/*
* Do we have domain socket support, and if so what is the default one?
*/
#define CUPS_DEFAULT_DOMAINSOCKET "/private/var/run/cupsd"
/*
* Default WebInterface value...
*/
#define CUPS_DEFAULT_WEBIF 0
/*
* Where are files stored?
*
* Note: These are defaults, which can be overridden by environment
* variables at run-time...
*/
#define CUPS_BINDIR "/usr/bin"
#define CUPS_CACHEDIR "/var/cache/cups"
#define CUPS_DATADIR "/usr/share/cups"
#define CUPS_DOCROOT "/usr/share/doc/cups"
#define CUPS_FONTPATH "/usr/share/cups/fonts"
#define CUPS_LOCALEDIR "/usr/share/locale"
#define CUPS_LOGDIR "/var/log/cups"
#define CUPS_REQUESTS "/var/spool/cups"
#define CUPS_SBINDIR "/usr/sbin"
#define CUPS_SERVERBIN "/usr/lib/cups"
#define CUPS_SERVERROOT "/etc/cups"
#define CUPS_STATEDIR "/var/run/cups"
/*
* Do we have various image libraries?
*/
/* #undef HAVE_LIBPNG */
#define HAVE_LIBZ 1
/* #undef HAVE_LIBJPEG */
/* #undef HAVE_LIBTIFF */
/*
* Do we have PAM stuff?
*/
#ifndef HAVE_LIBPAM
#define HAVE_LIBPAM 0
#endif /* !HAVE_LIBPAM */
/* #undef HAVE_PAM_PAM_APPL_H */
//#define HAVE_PAM_SET_ITEM 1
//#define HAVE_PAM_SETCRED 1
/*
* Do we have <shadow.h>?
*/
#define HAVE_SHADOW_H 1
/*
* Do we have <crypt.h>?
*/
#define HAVE_CRYPT_H 1
/*
* Do we have <scsi/sg.h>?
*/
/* #undef HAVE_SCSI_SG_H */
/*
* Use <stdint.h>?
*/
#define HAVE_STDINT_H 1
/*
* Use <string.h>, <strings.h>, and/or <bstring.h>?
*/
#define HAVE_STRING_H 1
#define HAVE_STRINGS_H 1
/* #undef HAVE_BSTRING_H */
/*
* Do we have the long long type?
*/
#define HAVE_LONG_LONG 1
#ifdef HAVE_LONG_LONG
# define CUPS_LLFMT "%lld"
# define CUPS_LLCAST (long long)
#else
# define CUPS_LLFMT "%ld"
# define CUPS_LLCAST (long)
#endif /* HAVE_LONG_LONG */
/*
* Do we have the strtoll() function?
*/
#define HAVE_STRTOLL 1
#ifndef HAVE_STRTOLL
# define strtoll(nptr,endptr,base) strtol((nptr), (endptr), (base))
#endif /* !HAVE_STRTOLL */
/*
* Do we have the strXXX() functions?
*/
#define HAVE_STRDUP 1
//#define HAVE_STRLCAT 1
//#define HAVE_STRLCPY 1
/*
* Do we have the geteuid() function?
*/
#define HAVE_GETEUID 1
/*
* Do we have the setpgid() function?
*/
#define HAVE_SETPGID 1
/*
* Do we have the vsyslog() function?
*/
#define HAVE_VSYSLOG 1
/*
* Do we have the (v)snprintf() functions?
*/
#define HAVE_SNPRINTF 1
#define HAVE_VSNPRINTF 1
/*
* What signal functions to use?
*/
//#define HAVE_SIGSET 1
#define HAVE_SIGACTION 1
/*
* What wait functions to use?
*/
#define HAVE_WAITPID 1
#define HAVE_WAIT3 1
/*
* Do we have the mallinfo function and malloc.h?
*/
/* #undef HAVE_MALLINFO */
/* #undef HAVE_MALLOC_H */
/*
* Do we have the POSIX ACL functions?
*/
#define HAVE_ACL_INIT 1
/*
* Do we have the langinfo.h header file?
*/
//#define HAVE_LANGINFO_H 1
/*
* Which encryption libraries do we have?
*/
//#define HAVE_CDSASSL 1
/* #undef HAVE_GNUTLS */
#define HAVE_LIBSSL 1
#define HAVE_SSL 1
/*
* Do we have the SSL_set_tlsext_host_name function?
*/
/* #undef HAVE_SSL_SET_TLSEXT_HOST_NAME */
/*
* What Security framework headers do we have?
*/
//#define HAVE_AUTHORIZATION_H 1
/* #undef HAVE_SECBASEPRIV_H */
//#define HAVE_SECCERTIFICATE_H 1
/* #undef HAVE_SECIDENTITYSEARCHPRIV_H */
//#define HAVE_SECITEM_H 1
/* #undef HAVE_SECITEMPRIV_H */
//#define HAVE_SECPOLICY_H 1
/* #undef HAVE_SECPOLICYPRIV_H */
/* #undef HAVE_SECURETRANSPORTPRIV_H */
/*
* Do we have the SecCertificateCopyData function?
*/
#define HAVE_SECCERTIFICATECOPYDATA 1
/*
* Do we have the SecIdentitySearchCreateWithPolicy function?
*/
#define HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY 1
/*
* Do we have the SecPolicyCreateSSL function?
*/
#define HAVE_SECPOLICYCREATESSL 1
/*
* Do we have the SecPolicyCreateSSL function?
*/
#define HAVE_SECPOLICYCREATESSL 1
/*
* Do we have the cssmErrorString function?
*/
#define HAVE_CSSMERRORSTRING 1
/*
* Do we have libpaper?
*/
/* #undef HAVE_LIBPAPER */
/*
* Do we have mDNSResponder for DNS Service Discovery (aka Bonjour)?
*/
//#define HAVE_DNSSD 1
/*
* Do we have Avahi for DNS Service Discovery (aka Bonjour)?
*/
/* #undef HAVE_AVAHI */
/*
* Do we have <sys/ioctl.h>?
*/
#define HAVE_SYS_IOCTL_H 1
/*
* Does the "stat" structure contain the "st_gen" member?
*/
//#define HAVE_ST_GEN 1
/*
* Does the "tm" structure contain the "tm_gmtoff" member?
*/
//#define HAVE_TM_GMTOFF 1
/*
* Do we have rresvport_af()?
*/
#define HAVE_RRESVPORT_AF 1
/*
* Do we have getaddrinfo()?
*/
#define HAVE_GETADDRINFO 1
/*
* Do we have getnameinfo()?
*/
#define HAVE_GETNAMEINFO 1
/*
* Do we have getifaddrs()?
*/
//#define HAVE_GETIFADDRS 1
/*
* Do we have hstrerror()?
*/
#define HAVE_HSTRERROR 1
/*
* Do we have res_init()?
*/
#define HAVE_RES_INIT 1
/*
* Do we have <resolv.h>
*/
#define HAVE_RESOLV_H 1
/*
* Do we have the <sys/sockio.h> header file?
*/
//#define HAVE_SYS_SOCKIO_H 1
/*
* Does the sockaddr structure contain an sa_len parameter?
*/
/* #undef HAVE_STRUCT_SOCKADDR_SA_LEN */
/*
* Do we have the AIX usersec.h header file?
*/
/* #undef HAVE_USERSEC_H */
/*
* Do we have pthread support?
*/
#define HAVE_PTHREAD_H 1
/*
* Do we have launchd support?
*/
//#define HAVE_LAUNCH_H 1
//#define HAVE_LAUNCHD 1
/*
* Various scripting languages...
*/
#define HAVE_JAVA 1
#define CUPS_JAVA "/usr/bin/java"
#define HAVE_PERL 1
#define CUPS_PERL "/usr/bin/perl"
//#define HAVE_PHP 1
#define CUPS_PHP ""
#define HAVE_PYTHON 1
#define CUPS_PYTHON "/usr/bin/python"
/*
* Location of the poppler/Xpdf pdftops program...
*/
/* #undef HAVE_PDFTOPS */
/* #undef HAVE_PDFTOPS_WITH_ORIGPAGESIZES */
#define CUPS_PDFTOPS "/usr/bin/pdftops"
/*
* Location of the Ghostscript gs program...
*/
/* #undef HAVE_GHOSTSCRIPT */
/* #undef HAVE_GHOSTSCRIPT_PS2WRITE */
#define CUPS_GHOSTSCRIPT "/usr/bin/gs"
/*
* Do we have CoreFoundation public and private headers?
*/
//#define HAVE_COREFOUNDATION_H 1
/* #undef HAVE_CFPRIV_H */
/* #undef HAVE_CFBUNDLEPRIV_H */
/*
* Do we have ApplicationServices public headers?
*/
#define HAVE_APPLICATIONSERVICES_H 1
/*
* Do we have the SCDynamicStoreCopyComputerName function?
*/
//#define HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME 1
/*
* Do we have OS X 10.4's mbr_XXX functions?
*/
#define HAVE_MEMBERSHIP_H 1
/* #undef HAVE_MEMBERSHIPPRIV_H */
#define HAVE_MBR_UID_TO_UUID 1
/*
* Do we have Darwin's notify_post header and function?
*/
//#define HAVE_NOTIFY_H 1
//#define HAVE_NOTIFY_POST 1
/*
* Do we have Darwin's IOKit private headers?
*/
/* #undef HAVE_IOKIT_PWR_MGT_IOPMLIBPRIVATE_H */
/*
* Do we have DBUS?
*/
/* #undef HAVE_DBUS */
/* #undef HAVE_DBUS_MESSAGE_ITER_INIT_APPEND */
/*
* Do we have the GSSAPI support library (for Kerberos support)?
*/
//#define HAVE_GSS_ACQUIRE_CRED_EX_F 1
//#define HAVE_GSS_C_NT_HOSTBASED_SERVICE 1
//#define HAVE_GSS_GSSAPI_H 1
/* #undef HAVE_GSS_GSSAPI_SPI_H */
/* #undef HAVE_GSSAPI */
/* #undef HAVE_GSSAPI_GSSAPI_H */
/* #undef HAVE_GSSAPI_H */
/*
* Default GSS service name...
*/
#define CUPS_DEFAULT_GSSSERVICENAME "host"
/*
* Select/poll interfaces...
*/
#define HAVE_POLL 1
/* #undef HAVE_EPOLL */
#define HAVE_KQUEUE 1
/*
* Do we have the <dlfcn.h> header?
*/
#define HAVE_DLFCN_H 1
/*
* Do we have <sys/param.h>?
*/
#define HAVE_SYS_PARAM_H 1
/*
* Do we have <sys/ucred.h>?
*/
#define HAVE_SYS_UCRED_H 1
/*
* Do we have removefile()?
*/
#define HAVE_REMOVEFILE 1
/*
* Do we have <sandbox.h>?
*/
#define HAVE_SANDBOX_H 1
/*
* Which random number generator function to use...
*/
// #define HAVE_ARC4RANDOM 1
#define HAVE_RANDOM 1
#define HAVE_LRAND48 1
#ifdef HAVE_ARC4RANDOM
# define CUPS_RAND() arc4random()
# define CUPS_SRAND(v) arc4random_stir()
#elif defined(HAVE_RANDOM)
# define CUPS_RAND() random()
# define CUPS_SRAND(v) srandom(v)
#elif defined(HAVE_LRAND48)
# define CUPS_RAND() lrand48()
# define CUPS_SRAND(v) srand48(v)
#else
# define CUPS_RAND() rand()
# define CUPS_SRAND(v) srand(v)
#endif /* HAVE_ARC4RANDOM */
/*
* Do we have vproc_transaction_begin/end?
*/
#define HAVE_VPROC_TRANSACTION_BEGIN 1
/*
* Do we have libusb?
*/
/* #undef HAVE_LIBUSB */
/*
* Do we have libwrap and tcpd.h?
*/
/* #undef HAVE_TCPD_H */
/*
* Do we have <iconv.h>?
*/
//#define HAVE_ICONV_H 1
/*
* Do we have statfs or statvfs and one of the corresponding headers?
*/
#define HAVE_STATFS 1
#define HAVE_STATVFS 1
#define HAVE_SYS_MOUNT_H 1
/* #undef HAVE_SYS_STATFS_H */
#define HAVE_SYS_STATVFS_H 1
/* #undef HAVE_SYS_VFS_H */
/*
* Location of OS X localization bundle, if any.
*/
#define CUPS_BUNDLEDIR "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/PrintCore.framework/Versions/A"
/*
* Do we have XPC?
*/
#define HAVE_XPC 1
/* #undef HAVE_XPC_PRIVATE_H */
/*
* Do we have Mini-XML?
*/
/* #undef HAVE_MXML_H */
/*
* Do we have the C99 abs() function?
*/
#define HAVE_ABS 1
#if !defined(HAVE_ABS) && !defined(abs)
# if defined(__GNUC__) || __STDC_VERSION__ >= 199901L
# define abs(x) _cups_abs(x)
static inline int _cups_abs(int i) { return (i < 0 ? -i : i); }
# elif defined(_MSC_VER)
# define abs(x) _cups_abs(x)
static __inline int _cups_abs(int i) { return (i < 0 ? -i : i); }
# else
# define abs(x) ((x) < 0 ? -(x) : (x))
# endif /* __GNUC__ || __STDC_VERSION__ */
#endif /* !HAVE_ABS && !abs */
#endif /* !_CUPS_CONFIG_H_ */
/*
* End of "$Id: config.h.in 10776 2012-12-17 22:17:08Z mike $".
*/

747
config.h.in Normal file
View File

@@ -0,0 +1,747 @@
/*
* "$Id: config.h.in 7918 2008-09-08 22:03:01Z mike $"
*
* Configuration file for CUPS.
*
* Copyright 2007-2012 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*/
#ifndef _CUPS_CONFIG_H_
#define _CUPS_CONFIG_H_
/*
* Version of software...
*/
#define CUPS_SVERSION ""
#define CUPS_MINIMAL ""
/*
* Default user and groups...
*/
#define CUPS_DEFAULT_USER "lp"
#define CUPS_DEFAULT_GROUP "sys"
#define CUPS_DEFAULT_SYSTEM_GROUPS "sys root system"
#define CUPS_DEFAULT_PRINTOPERATOR_AUTH "@SYSTEM"
#define CUPS_DEFAULT_SYSTEM_AUTHKEY "system.print.admin"
/*
* Default file permissions...
*/
#define CUPS_DEFAULT_CONFIG_FILE_PERM 0640
#define CUPS_DEFAULT_LOG_FILE_PERM 0644
/*
* Default logging settings...
*/
#define CUPS_DEFAULT_LOG_LEVEL "warn"
#define CUPS_DEFAULT_ACCESS_LOG_LEVEL "actions"
/*
* Default fatal error settings...
*/
#define CUPS_DEFAULT_FATAL_ERRORS "config"
/*
* Default browsing settings...
*/
#define CUPS_DEFAULT_BROWSING 1
#define CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS ""
#define CUPS_DEFAULT_DEFAULT_SHARED 1
/*
* Default IPP port...
*/
#define CUPS_DEFAULT_IPP_PORT 631
/*
* Default printcap file...
*/
#define CUPS_DEFAULT_PRINTCAP "/etc/printcap"
/*
* Default Samba and LPD config files...
*/
#define CUPS_DEFAULT_SMB_CONFIG_FILE ""
#define CUPS_DEFAULT_LPD_CONFIG_FILE ""
/*
* Default MaxCopies value...
*/
#define CUPS_DEFAULT_MAX_COPIES 100
/*
* Do we have domain socket support, and if so what is the default one?
*/
#undef CUPS_DEFAULT_DOMAINSOCKET
/*
* Default WebInterface value...
*/
#undef CUPS_DEFAULT_WEBIF
/*
* Where are files stored?
*
* Note: These are defaults, which can be overridden by environment
* variables at run-time...
*/
#define CUPS_BINDIR "/usr/bin"
#define CUPS_CACHEDIR "/var/cache/cups"
#define CUPS_DATADIR "/usr/share/cups"
#define CUPS_DOCROOT "/usr/share/doc/cups"
#define CUPS_FONTPATH "/usr/share/cups/fonts"
#define CUPS_LOCALEDIR "/usr/share/locale"
#define CUPS_LOGDIR "/var/logs/cups"
#define CUPS_REQUESTS "/var/spool/cups"
#define CUPS_SBINDIR "/usr/sbin"
#define CUPS_SERVERBIN "/usr/lib/cups"
#define CUPS_SERVERROOT "/etc/cups"
#define CUPS_STATEDIR "/var/run/cups"
/*
* Do we have various image libraries?
*/
#undef HAVE_LIBPNG
#undef HAVE_LIBZ
#undef HAVE_LIBJPEG
#undef HAVE_LIBTIFF
/*
* Do we have PAM stuff?
*/
#ifndef HAVE_LIBPAM
#define HAVE_LIBPAM 0
#endif /* !HAVE_LIBPAM */
#undef HAVE_PAM_PAM_APPL_H
#undef HAVE_PAM_SET_ITEM
#undef HAVE_PAM_SETCRED
/*
* Do we have <shadow.h>?
*/
#undef HAVE_SHADOW_H
/*
* Do we have <crypt.h>?
*/
#undef HAVE_CRYPT_H
/*
* Do we have <scsi/sg.h>?
*/
#undef HAVE_SCSI_SG_H
/*
* Use <stdint.h>?
*/
#undef HAVE_STDINT_H
/*
* Use <string.h>, <strings.h>, and/or <bstring.h>?
*/
#undef HAVE_STRING_H
#undef HAVE_STRINGS_H
#undef HAVE_BSTRING_H
/*
* Do we have the long long type?
*/
#undef HAVE_LONG_LONG
#ifdef HAVE_LONG_LONG
# define CUPS_LLFMT "%lld"
# define CUPS_LLCAST (long long)
#else
# define CUPS_LLFMT "%ld"
# define CUPS_LLCAST (long)
#endif /* HAVE_LONG_LONG */
/*
* Do we have the strtoll() function?
*/
#undef HAVE_STRTOLL
#ifndef HAVE_STRTOLL
# define strtoll(nptr,endptr,base) strtol((nptr), (endptr), (base))
#endif /* !HAVE_STRTOLL */
/*
* Do we have the strXXX() functions?
*/
#undef HAVE_STRDUP
#undef HAVE_STRLCAT
#undef HAVE_STRLCPY
/*
* Do we have the geteuid() function?
*/
#undef HAVE_GETEUID
/*
* Do we have the setpgid() function?
*/
#undef HAVE_SETPGID
/*
* Do we have the vsyslog() function?
*/
#undef HAVE_VSYSLOG
/*
* Do we have the (v)snprintf() functions?
*/
#undef HAVE_SNPRINTF
#undef HAVE_VSNPRINTF
/*
* What signal functions to use?
*/
#undef HAVE_SIGSET
#undef HAVE_SIGACTION
/*
* What wait functions to use?
*/
#undef HAVE_WAITPID
#undef HAVE_WAIT3
/*
* Do we have the mallinfo function and malloc.h?
*/
#undef HAVE_MALLINFO
#undef HAVE_MALLOC_H
/*
* Do we have the POSIX ACL functions?
*/
#undef HAVE_ACL_INIT
/*
* Do we have the langinfo.h header file?
*/
#undef HAVE_LANGINFO_H
/*
* Which encryption libraries do we have?
*/
#undef HAVE_CDSASSL
#undef HAVE_GNUTLS
#undef HAVE_LIBSSL
#undef HAVE_SSL
/*
* Do we have the SSL_set_tlsext_host_name function?
*/
#undef HAVE_SSL_SET_TLSEXT_HOST_NAME
/*
* What Security framework headers do we have?
*/
#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 SecCertificateCopyData function?
*/
#undef HAVE_SECCERTIFICATECOPYDATA
/*
* Do we have the SecIdentitySearchCreateWithPolicy function?
*/
#undef HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY
/*
* Do we have the SecPolicyCreateSSL function?
*/
#undef HAVE_SECPOLICYCREATESSL
/*
* Do we have the SecPolicyCreateSSL function?
*/
#undef HAVE_SECPOLICYCREATESSL
/*
* Do we have the cssmErrorString function?
*/
#undef HAVE_CSSMERRORSTRING
/*
* Do we have libpaper?
*/
#undef HAVE_LIBPAPER
/*
* Do we have mDNSResponder for DNS Service Discovery (aka Bonjour)?
*/
#undef HAVE_DNSSD
/*
* Do we have Avahi for DNS Service Discovery (aka Bonjour)?
*/
#undef HAVE_AVAHI
/*
* Do we have <sys/ioctl.h>?
*/
#undef HAVE_SYS_IOCTL_H
/*
* Does the "stat" structure contain the "st_gen" member?
*/
#undef HAVE_ST_GEN
/*
* Does the "tm" structure contain the "tm_gmtoff" member?
*/
#undef HAVE_TM_GMTOFF
/*
* Do we have rresvport_af()?
*/
#undef HAVE_RRESVPORT_AF
/*
* Do we have getaddrinfo()?
*/
#undef HAVE_GETADDRINFO
/*
* Do we have getnameinfo()?
*/
#undef HAVE_GETNAMEINFO
/*
* Do we have getifaddrs()?
*/
#undef HAVE_GETIFADDRS
/*
* Do we have hstrerror()?
*/
#undef HAVE_HSTRERROR
/*
* Do we have res_init()?
*/
#undef HAVE_RES_INIT
/*
* Do we have <resolv.h>
*/
#undef HAVE_RESOLV_H
/*
* Do we have the <sys/sockio.h> header file?
*/
#undef HAVE_SYS_SOCKIO_H
/*
* Does the sockaddr structure contain an sa_len parameter?
*/
#undef HAVE_STRUCT_SOCKADDR_SA_LEN
/*
* Do we have the AIX usersec.h header file?
*/
#undef HAVE_USERSEC_H
/*
* Do we have pthread support?
*/
#undef HAVE_PTHREAD_H
/*
* Do we have launchd support?
*/
#undef HAVE_LAUNCH_H
#undef HAVE_LAUNCHD
/*
* 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"
/*
* Location of the poppler/Xpdf pdftops program...
*/
#undef HAVE_PDFTOPS
#undef HAVE_PDFTOPS_WITH_ORIGPAGESIZES
#define CUPS_PDFTOPS "/usr/bin/pdftops"
/*
* Location of the Ghostscript gs program...
*/
#undef HAVE_GHOSTSCRIPT
#undef HAVE_GHOSTSCRIPT_PS2WRITE
#define CUPS_GHOSTSCRIPT "/usr/bin/gs"
/*
* Do we have CoreFoundation public and private headers?
*/
#undef HAVE_COREFOUNDATION_H
#undef HAVE_CFPRIV_H
#undef HAVE_CFBUNDLEPRIV_H
/*
* Do we have ApplicationServices public headers?
*/
#undef HAVE_APPLICATIONSERVICES_H
/*
* Do we have the SCDynamicStoreCopyComputerName function?
*/
#undef HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME
/*
* Do we have OS X 10.4's mbr_XXX functions?
*/
#undef HAVE_MEMBERSHIP_H
#undef HAVE_MEMBERSHIPPRIV_H
#undef HAVE_MBR_UID_TO_UUID
/*
* Do we have Darwin's notify_post header and function?
*/
#undef HAVE_NOTIFY_H
#undef HAVE_NOTIFY_POST
/*
* Do we have Darwin's IOKit private headers?
*/
#undef HAVE_IOKIT_PWR_MGT_IOPMLIBPRIVATE_H
/*
* Do we have DBUS?
*/
#undef HAVE_DBUS
#undef HAVE_DBUS_MESSAGE_ITER_INIT_APPEND
/*
* Do we have the GSSAPI support library (for Kerberos support)?
*/
#undef HAVE_GSS_ACQUIRE_CRED_EX_F
#undef HAVE_GSS_C_NT_HOSTBASED_SERVICE
#undef HAVE_GSS_GSSAPI_H
#undef HAVE_GSS_GSSAPI_SPI_H
#undef HAVE_GSSAPI
#undef HAVE_GSSAPI_GSSAPI_H
#undef HAVE_GSSAPI_H
/*
* Default GSS service name...
*/
#define CUPS_DEFAULT_GSSSERVICENAME ""
/*
* Select/poll interfaces...
*/
#undef HAVE_POLL
#undef HAVE_EPOLL
#undef HAVE_KQUEUE
/*
* Do we have the <dlfcn.h> header?
*/
#undef HAVE_DLFCN_H
/*
* Do we have <sys/param.h>?
*/
#undef HAVE_SYS_PARAM_H
/*
* Do we have <sys/ucred.h>?
*/
#undef HAVE_SYS_UCRED_H
/*
* Do we have removefile()?
*/
#undef HAVE_REMOVEFILE
/*
* Do we have <sandbox.h>?
*/
#undef HAVE_SANDBOX_H
/*
* Which random number generator function to use...
*/
#undef HAVE_ARC4RANDOM
#undef HAVE_RANDOM
#undef HAVE_LRAND48
#ifdef HAVE_ARC4RANDOM
# define CUPS_RAND() arc4random()
# define CUPS_SRAND(v) arc4random_stir()
#elif defined(HAVE_RANDOM)
# define CUPS_RAND() random()
# define CUPS_SRAND(v) srandom(v)
#elif defined(HAVE_LRAND48)
# define CUPS_RAND() lrand48()
# define CUPS_SRAND(v) srand48(v)
#else
# define CUPS_RAND() rand()
# define CUPS_SRAND(v) srand(v)
#endif /* HAVE_ARC4RANDOM */
/*
* Do we have vproc_transaction_begin/end?
*/
#undef HAVE_VPROC_TRANSACTION_BEGIN
/*
* Do we have libusb?
*/
#undef HAVE_LIBUSB
/*
* Do we have libwrap and tcpd.h?
*/
#undef HAVE_TCPD_H
/*
* Do we have <iconv.h>?
*/
#undef HAVE_ICONV_H
/*
* Do we have statfs or statvfs and one of the corresponding headers?
*/
#undef HAVE_STATFS
#undef HAVE_STATVFS
#undef HAVE_SYS_MOUNT_H
#undef HAVE_SYS_STATFS_H
#undef HAVE_SYS_STATVFS_H
#undef HAVE_SYS_VFS_H
/*
* Location of OS X localization bundle, if any.
*/
#undef CUPS_BUNDLEDIR
/*
* Do we have XPC?
*/
#undef HAVE_XPC
#undef HAVE_XPC_PRIVATE_H
/*
* Do we have Mini-XML?
*/
#undef HAVE_MXML_H
/*
* Do we have the C99 abs() function?
*/
#undef HAVE_ABS
#if !defined(HAVE_ABS) && !defined(abs)
# if defined(__GNUC__) || __STDC_VERSION__ >= 199901L
# define abs(x) _cups_abs(x)
static inline int _cups_abs(int i) { return (i < 0 ? -i : i); }
# elif defined(_MSC_VER)
# define abs(x) _cups_abs(x)
static __inline int _cups_abs(int i) { return (i < 0 ? -i : i); }
# else
# define abs(x) ((x) < 0 ? -(x) : (x))
# endif /* __GNUC__ || __STDC_VERSION__ */
#endif /* !HAVE_ABS && !abs */
#endif /* !_CUPS_CONFIG_H_ */
/*
* End of "$Id: config.h.in 7918 2008-09-08 22:03:01Z mike $".
*/

97
configure.in Normal file
View File

@@ -0,0 +1,97 @@
dnl
dnl "$Id: configure.in 7833 2008-08-04 20:55:13Z mike $"
dnl
dnl Configuration script for CUPS.
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
AC_INIT(cups/cups.h)
sinclude(config-scripts/cups-opsys.m4)
sinclude(config-scripts/cups-common.m4)
sinclude(config-scripts/cups-directories.m4)
sinclude(config-scripts/cups-manpages.m4)
sinclude(config-scripts/cups-sharedlibs.m4)
sinclude(config-scripts/cups-libtool.m4)
sinclude(config-scripts/cups-compiler.m4)
sinclude(config-scripts/cups-network.m4)
sinclude(config-scripts/cups-poll.m4)
sinclude(config-scripts/cups-gssapi.m4)
sinclude(config-scripts/cups-threads.m4)
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-defaults.m4)
sinclude(config-scripts/cups-scripting.m4)
INSTALL_LANGUAGES=""
UNINSTALL_LANGUAGES=""
LANGFILES=""
if test "x$LANGUAGES" != x; then
INSTALL_LANGUAGES="install-languages"
UNINSTALL_LANGUAGES="uninstall-languages"
for lang in $LANGUAGES; do
if test -f doc/$lang/index.html.in; then
LANGFILES="$LANGFILES doc/$lang/index.html"
fi
if test -f templates/$lang/header.tmpl.in; then
LANGFILES="$LANGFILES templates/$lang/header.tmpl"
fi
done
elif test "x$CUPS_BUNDLEDIR" != x; then
INSTALL_LANGUAGES="install-langbundle"
UNINSTALL_LANGUAGES="uninstall-langbundle"
fi
AC_SUBST(INSTALL_LANGUAGES)
AC_SUBST(UNINSTALL_LANGUAGES)
AC_OUTPUT(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)
chmod +x cups-config
dnl
dnl End of "$Id: configure.in 7833 2008-08-04 20:55:13Z mike $".
dnl

146
cups-config.in Executable file
View File

@@ -0,0 +1,146 @@
#! /bin/sh
#
# "$Id: cups-config.in 9926 2011-08-27 09:23:01Z mike $"
#
# CUPS configuration utility.
#
# Copyright 2007-2011 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/".
#
VERSION="@CUPS_VERSION@"
APIVERSION="1.6"
BUILD="@CUPS_BUILD@"
prefix=@prefix@
exec_prefix=@exec_prefix@
bindir=@bindir@
includedir=@includedir@
libdir=@libdir@
imagelibdir=@libdir@
datarootdir=@datadir@
datadir=@datadir@
sysconfdir=@sysconfdir@
cups_datadir=@CUPS_DATADIR@
cups_serverbin=@CUPS_SERVERBIN@
cups_serverroot=@CUPS_SERVERROOT@
INSTALLSTATIC=@INSTALLSTATIC@
# flags for C++ compiler:
CFLAGS=""
LDFLAGS="@EXPORT_LDFLAGS@"
LIBS="@LIBGSSAPI@ @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"
libdir="$selfdir/cups"
imagelibdir="$selfdir/filter"
else
if test $includedir != /usr/include; then
CFLAGS="$CFLAGS -I$includedir"
fi
if test $libdir != /usr/lib -a $libdir != /usr/lib32 -a $libdir != /usr/lib64; then
LDFLAGS="$LDFLAGS -L$libdir"
fi
fi
usage ()
{
echo "Usage: cups-config --api-version"
echo " cups-config --build"
echo " cups-config --cflags"
echo " cups-config --datadir"
echo " cups-config --help"
echo " cups-config --ldflags"
echo " cups-config [--image] [--static] --libs"
echo " cups-config --serverbin"
echo " cups-config --serverroot"
echo " cups-config --version"
exit $1
}
if test $# -eq 0; then
usage 1
fi
# Parse command line options
static=no
image=no
while test $# -gt 0; do
case $1 in
--api-version)
echo $APIVERSION
;;
--build)
echo $BUILD
;;
--cflags)
echo $CFLAGS
;;
--datadir)
echo $cups_datadir
;;
--help)
usage 0
;;
--image)
image=yes
;;
--ldflags)
echo $LDFLAGS
;;
--libs)
if test $static = no; then
libs="@EXTLINKCUPS@ $LIBS";
if test $image = yes; then
libs="@EXTLINKCUPSIMAGE@ $libs"
fi
else
libs="$libdir/libcups.a $LIBS";
if test $image = yes; then
libs="$libdir/libcupsimage.a $libs"
fi
fi
echo $libs
;;
--serverbin)
echo $cups_serverbin
;;
--serverroot)
echo $cups_serverroot
;;
--static)
if test -z "$INSTALLSTATIC"; then
echo "WARNING: Static libraries not installed!" >&2
else
static=yes
fi
;;
--version)
echo $VERSION
;;
*)
usage 1
;;
esac
shift
done
#
# End of "$Id: cups-config.in 9926 2011-08-27 09:23:01Z mike $".
#

260
cups/Dependencies Normal file
View File

@@ -0,0 +1,260 @@
adminutil.o: adminutil.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h adminutil.h
array.o: array.c string-private.h ../config.h debug-private.h \
../cups/versioning.h array-private.h ../cups/array.h
attr.o: attr.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
auth.o: auth.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
backchannel.o: backchannel.c cups.h file.h versioning.h ipp.h http.h \
array.h language.h
backend.o: backend.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h backend.h
conflicts.o: conflicts.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
custom.o: custom.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
debug.o: debug.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
dest.o: dest.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
dest-job.o: dest-job.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
dest-localization.o: dest-localization.c cups-private.h string-private.h \
../config.h debug-private.h ../cups/versioning.h ipp-private.h \
../cups/ipp.h http.h array.h http-private.h md5-private.h \
language-private.h ../cups/transcode.h language.h pwg-private.h \
../cups/cups.h file.h ppd-private.h ../cups/ppd.h thread-private.h
dest-options.o: dest-options.c cups-private.h string-private.h \
../config.h debug-private.h ../cups/versioning.h ipp-private.h \
../cups/ipp.h http.h array.h http-private.h md5-private.h \
language-private.h ../cups/transcode.h language.h pwg-private.h \
../cups/cups.h file.h ppd-private.h ../cups/ppd.h thread-private.h
dir.o: dir.c string-private.h ../config.h debug-private.h \
../cups/versioning.h dir.h
emit.o: emit.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
encode.o: encode.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.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 ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
getdevices.o: getdevices.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
getifaddrs.o: getifaddrs.c http-private.h ../config.h ../cups/http.h \
versioning.h array.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 ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
globals.o: globals.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
http.o: http.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
http-addr.o: http-addr.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
http-addrlist.o: http-addrlist.c cups-private.h string-private.h \
../config.h debug-private.h ../cups/versioning.h ipp-private.h \
../cups/ipp.h http.h array.h http-private.h md5-private.h \
language-private.h ../cups/transcode.h language.h pwg-private.h \
../cups/cups.h file.h ppd-private.h ../cups/ppd.h thread-private.h
http-support.o: http-support.c cups-private.h string-private.h \
../config.h debug-private.h ../cups/versioning.h ipp-private.h \
../cups/ipp.h http.h array.h http-private.h md5-private.h \
language-private.h ../cups/transcode.h language.h pwg-private.h \
../cups/cups.h file.h ppd-private.h ../cups/ppd.h thread-private.h
ipp.o: ipp.c cups-private.h string-private.h ../config.h debug-private.h \
../cups/versioning.h ipp-private.h ../cups/ipp.h http.h array.h \
http-private.h md5-private.h language-private.h ../cups/transcode.h \
language.h pwg-private.h ../cups/cups.h file.h ppd-private.h \
../cups/ppd.h thread-private.h
ipp-support.o: ipp-support.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
langprintf.o: langprintf.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
language.o: language.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
localize.o: localize.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
mark.o: mark.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.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/http.h \
versioning.h array.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 ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
options.o: options.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
page.o: 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
ppd.o: ppd.c cups-private.h string-private.h ../config.h debug-private.h \
../cups/versioning.h ipp-private.h ../cups/ipp.h http.h array.h \
http-private.h md5-private.h language-private.h ../cups/transcode.h \
language.h pwg-private.h ../cups/cups.h file.h ppd-private.h \
../cups/ppd.h thread-private.h
ppd-cache.o: ppd-cache.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
pwg-media.o: pwg-media.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
request.o: request.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
sidechannel.o: sidechannel.c sidechannel.h versioning.h cups-private.h \
string-private.h ../config.h debug-private.h ipp-private.h \
../cups/ipp.h http.h array.h http-private.h md5-private.h \
language-private.h ../cups/transcode.h language.h pwg-private.h \
../cups/cups.h file.h ppd-private.h ../cups/ppd.h thread-private.h
snmp.o: snmp.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h snmp-private.h
snprintf.o: snprintf.c string-private.h ../config.h
string.o: string.c string-private.h ../config.h debug-private.h \
../cups/versioning.h thread-private.h array.h
tempfile.o: tempfile.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
thread.o: thread.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
transcode.o: transcode.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
usersys.o: usersys.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
util.o: util.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
testadmin.o: testadmin.c adminutil.h cups.h file.h versioning.h ipp.h \
http.h array.h language.h string-private.h ../config.h
testarray.o: testarray.c string-private.h ../config.h debug-private.h \
../cups/versioning.h array.h dir.h
testconflicts.o: testconflicts.c cups.h file.h versioning.h ipp.h http.h \
array.h language.h ppd.h string-private.h ../config.h
testcups.o: testcups.c string-private.h ../config.h cups.h file.h \
versioning.h ipp.h http.h array.h language.h ppd.h
testfile.o: testfile.c string-private.h ../config.h debug-private.h \
../cups/versioning.h file.h
testhttp.o: testhttp.c string-private.h ../config.h http-private.h \
../cups/http.h versioning.h array.h md5-private.h ipp-private.h \
../cups/ipp.h
testi18n.o: testi18n.c string-private.h ../config.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
testoptions.o: testoptions.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
testlang.o: testlang.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
testppd.o: testppd.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h
testpwg.o: testpwg.c ppd-private.h ../cups/cups.h file.h versioning.h \
ipp.h http.h array.h language.h ../cups/ppd.h pwg-private.h \
file-private.h cups-private.h string-private.h ../config.h \
debug-private.h ipp-private.h http-private.h md5-private.h \
language-private.h ../cups/transcode.h thread-private.h
testsnmp.o: testsnmp.c cups-private.h string-private.h ../config.h \
debug-private.h ../cups/versioning.h ipp-private.h ../cups/ipp.h \
http.h array.h http-private.h md5-private.h language-private.h \
../cups/transcode.h language.h pwg-private.h ../cups/cups.h file.h \
ppd-private.h ../cups/ppd.h thread-private.h snmp-private.h

633
cups/Makefile Normal file
View File

@@ -0,0 +1,633 @@
#
# "$Id: Makefile 7871 2008-08-27 21:12:43Z mike $"
#
# API library Makefile 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/".
#
# This file is subject to the Apple OS-Developed Software exception.
#
include ../Makedefs
#
# Object files...
#
LIBOBJS = \
adminutil.o \
array.o \
attr.o \
auth.o \
backchannel.o \
backend.o \
conflicts.o \
custom.o \
debug.o \
dest.o \
dest-job.o \
dest-localization.o \
dest-options.o \
dir.o \
emit.o \
encode.o \
file.o \
getdevices.o \
getifaddrs.o \
getputfile.o \
globals.o \
http.o \
http-addr.o \
http-addrlist.o \
http-support.o \
ipp.o \
ipp-support.o \
langprintf.o \
language.o \
localize.o \
mark.o \
md5.o \
md5passwd.o \
notify.o \
options.o \
page.o \
ppd.o \
ppd-cache.o \
pwg-media.o \
request.o \
sidechannel.o \
snmp.o \
snprintf.o \
string.o \
tempfile.o \
thread.o \
transcode.o \
usersys.o \
util.o
TESTOBJS = \
testadmin.o \
testarray.o \
testconflicts.o \
testcups.o \
testfile.o \
testhttp.o \
testi18n.o \
testipp.o \
testoptions.o \
testlang.o \
testppd.o \
testpwg.o \
testsnmp.o
OBJS = \
$(LIBOBJS) \
$(TESTOBJS)
#
# Header files to install...
#
HEADERS = \
adminutil.h \
array.h \
backend.h \
cups.h \
dir.h \
file.h \
http.h \
ipp.h \
language.h \
ppd.h \
raster.h \
sidechannel.h \
transcode.h \
versioning.h
HEADERSPRIV = \
array-private.h \
cups-private.h \
debug-private.h \
file-private.h \
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
#
# Targets in this directory...
#
LIBTARGETS = \
$(LIBCUPSSTATIC) \
$(LIBCUPS)
UNITTARGETS = \
testadmin \
testarray \
testconflicts \
testcups \
testfile \
testhttp \
testi18n \
testipp \
testlang \
testoptions \
testppd \
testpwg \
testsnmp
TARGETS = \
$(LIBTARGETS)
#
# Make all targets...
#
all: $(TARGETS)
#
# Make library targets...
#
libs: $(LIBTARGETS)
#
# Make unit tests...
#
unittests: $(UNITTARGETS)
#
# Remove object and target files...
#
clean:
$(RM) $(OBJS) $(TARGETS) $(UNITTARGETS)
$(RM) libcups.so libcups.sl libcups.dylib
#
# Update dependencies (without system header dependencies...)
#
depend:
$(CC) -MM $(ALL_CFLAGS) $(OBJS:.o=.c) >Dependencies
#
# Run oclint to check code coverage...
#
oclint:
oclint -o=oclint.html -html $(LIBOBJS:.o=.c) -- $(ALL_CFLAGS)
#
# Install all targets...
#
install: all install-data install-headers install-libs install-exec
#
# Install data files...
#
install-data:
#
# Install programs...
#
install-exec:
#
# Install headers...
#
install-headers:
echo Installing header files into $(INCLUDEDIR)/cups...
$(INSTALL_DIR) -m 755 $(INCLUDEDIR)/cups
for file in $(HEADERS); do \
$(INSTALL_DATA) $$file $(INCLUDEDIR)/cups; \
done
if test "x$(privateinclude)" != x; then \
echo Installing private header files into $(PRIVATEINCLUDE)...; \
$(INSTALL_DIR) -m 755 $(PRIVATEINCLUDE); \
for file in $(HEADERSPRIV); do \
$(INSTALL_DATA) $$file $(PRIVATEINCLUDE)/$$file; \
done; \
fi
#
# Install libraries...
#
install-libs: $(INSTALLSTATIC)
echo Installing libraries in $(LIBDIR)...
$(INSTALL_DIR) -m 755 $(LIBDIR)
$(INSTALL_LIB) $(LIBCUPS) $(LIBDIR)
if test $(LIBCUPS) = "libcups.so.2" -o $(LIBCUPS) = "libcups.sl.2"; then \
$(RM) $(LIBDIR)/`basename $(LIBCUPS) .2`; \
$(LN) $(LIBCUPS) $(LIBDIR)/`basename $(LIBCUPS) .2`; \
fi
if test $(LIBCUPS) = "libcups.2.dylib"; then \
$(RM) $(LIBDIR)/libcups.dylib; \
$(LN) $(LIBCUPS) $(LIBDIR)/libcups.dylib; \
fi
if test "x$(SYMROOT)" != "x"; then \
$(INSTALL_DIR) $(SYMROOT); \
cp $(LIBCUPS) $(SYMROOT); \
fi
installstatic:
$(INSTALL_DIR) -m 755 $(LIBDIR)
$(INSTALL_LIB) -m 755 $(LIBCUPSSTATIC) $(LIBDIR)
$(RANLIB) $(LIBDIR)/$(LIBCUPSSTATIC)
$(CHMOD) 555 $(LIBDIR)/$(LIBCUPSSTATIC)
#
# Uninstall object and target files...
#
uninstall:
$(RM) $(LIBDIR)/libcups.2.dylib
$(RM) $(LIBDIR)/$(LIBCUPSSTATIC)
$(RM) $(LIBDIR)/libcups.dylib
$(RM) $(LIBDIR)/libcups_s.a
$(RM) $(LIBDIR)/libcups.sl
$(RM) $(LIBDIR)/libcups.sl.2
$(RM) $(LIBDIR)/libcups.so
$(RM) $(LIBDIR)/libcups.so.2
-$(RMDIR) $(LIBDIR)
for file in $(HEADERS); do \
$(RM) $(INCLUDEDIR)/cups/$$file; \
done
-$(RMDIR) $(INCLUDEDIR)/cups
#
# libcups.so.2, libcups.sl.2
#
libcups.so.2 libcups.sl.2: $(LIBOBJS)
echo Linking $@...
$(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS) $(LIBGSSAPI) \
$(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
$(RM) `basename $@ .2`
$(LN) $@ `basename $@ .2`
#
# libcups.2.dylib
#
libcups.2.dylib: $(LIBOBJS) $(LIBCUPSORDER)
echo Creating export list for $@...
nm $(LIBOBJS) 2>/dev/null | grep "T _" | awk '{print $$3}' | \
grep -v -e '^(_cupsConnect|_cupsCharset|_cupsEncodingName|_cupsSetDefaults|_cupsSetHTTPError|_cupsUserDefault|_httpWait)$$' | \
sort >t.exp
echo Linking $@...
$(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ \
-install_name $(libdir)/$@ \
-current_version 2.10.0 \
-compatibility_version 2.0.0 \
-exported_symbols_list t.exp \
$(LIBOBJS) $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) \
$(COMMONLIBS) $(LIBZ)
$(RM) libcups.dylib t.exp
$(LN) $@ libcups.dylib
#
# libcups_s.a
#
libcups_s.a: $(LIBOBJS) libcups_s.exp
echo Creating $@...
$(DSO) $(DSOFLAGS) -Wl,-bexport:libcups_s.exp -o libcups_s.o \
$(LIBOBJS) $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) \
$(COMMONLIBS) $(LIBZ)
$(RM) $@
$(AR) $(ARFLAGS) $@ libcups_s.o
#
# libcups.la
#
libcups.la: $(LIBOBJS)
echo Linking $@...
$(CC) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS:.o=.lo) \
-rpath $(LIBDIR) -version-info 2:10 $(LIBGSSAPI) $(SSLLIBS) \
$(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
#
# libcups.a
#
libcups.a: $(LIBOBJS)
echo Archiving $@...
$(RM) $@
$(AR) $(ARFLAGS) $@ $(LIBOBJS)
$(RANLIB) $@
#
# 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)
#
# testarray (dependency on static CUPS library is intentional)
#
testarray: testarray.o $(LIBCUPSSTATIC)
echo Linking $@...
$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testarray.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
echo Running array API tests...
./testarray
#
# testconflicts (dependency on static CUPS library is intentional)
#
testconflicts: testconflicts.o $(LIBCUPSSTATIC)
echo Linking $@...
$(CC) $(LDFLAGS) -o $@ testconflicts.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
#
# testcups (dependency on static CUPS library is intentional)
#
testcups: testcups.o $(LIBCUPSSTATIC)
echo Linking $@...
$(CC) $(LDFLAGS) -o $@ testcups.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
#
# testfile (dependency on static CUPS library is intentional)
#
testfile: testfile.o $(LIBCUPSSTATIC)
echo Linking $@...
$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testfile.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
echo Running file API tests...
./testfile
#
# 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)
echo Running HTTP API tests...
./testhttp
#
# testipp (dependency on static CUPS library is intentional)
#
testipp: testipp.o $(LIBCUPSSTATIC)
echo Linking $@...
$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testipp.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
echo Running IPP API tests...
./testipp
#
# testi18n (dependency on static CUPS library is intentional)
#
testi18n: testi18n.o $(LIBCUPSSTATIC)
echo Linking $@...
$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testi18n.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
echo Running internationalization API tests...
./testi18n
#
# testlang (dependency on static CUPS library is intentional)
#
testlang: testlang.o $(LIBCUPSSTATIC)
echo Linking $@...
$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testlang.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
echo Running language API tests...
./testlang
#
# testoptions (dependency on static CUPS library is intentional)
#
testoptions: testoptions.o $(LIBCUPSSTATIC)
echo Linking $@...
$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testoptions.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
echo Running option API tests...
./testoptions
#
# testppd (dependency on static CUPS library is intentional)
#
testppd: testppd.o $(LIBCUPSSTATIC) test.ppd test2.ppd
echo Linking $@...
$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testppd.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
echo Running PPD API tests...
./testppd
#
# testpwg (dependency on static CUPS library is intentional)
#
testpwg: testpwg.o $(LIBCUPSSTATIC) test.ppd
echo Linking $@...
$(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testpwg.o $(LIBCUPSSTATIC) \
$(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ)
echo Running PWG API tests...
./testpwg test.ppd
#
# 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)
#
# Automatic API help files...
#
apihelp:
echo Generating CUPS API help files...
mxmldoc --section "Programming" \
--title "Introduction to CUPS Programming" \
--css ../doc/cups-printable.css \
--header api-overview.header --intro api-overview.shtml \
>../doc/help/api-overview.html
mxmldoc --section "Programming" --title "Array API" \
--css ../doc/cups-printable.css \
--header api-array.header --intro api-array.shtml \
api-array.xml \
array.h array.c >../doc/help/api-array.html
mxmldoc --tokens help/api-array.html api-array.xml >../doc/help/api-array.tokens
$(RM) api-array.xml
mxmldoc --section "Programming" --title "CUPS API" \
--css ../doc/cups-printable.css \
--header api-cups.header --intro api-cups.shtml \
api-cups.xml \
cups.h adminutil.c dest*.c language.c notify.c \
options.c tempfile.c usersys.c \
util.c >../doc/help/api-cups.html
mxmldoc --tokens help/api-cups.html api-cups.xml >../doc/help/api-cups.tokens
$(RM) api-cups.xml
mxmldoc --section "Programming" --title "File and Directory APIs" \
--css ../doc/cups-printable.css \
--header api-filedir.header --intro api-filedir.shtml \
api-filedir.xml \
file.h file.c dir.h dir.c >../doc/help/api-filedir.html
mxmldoc --tokens api-filedir.xml >../doc/help/api-filedir.tokens
$(RM) api-filedir.xml
mxmldoc --section "Programming" --title "PPD API (DEPRECATED)" \
--css ../doc/cups-printable.css \
--header api-ppd.header --intro api-ppd.shtml \
api-ppd.xml \
ppd.h attr.c conflicts.c custom.c emit.c localize.c mark.c page.c \
ppd.c >../doc/help/api-ppd.html
mxmldoc --tokens help/api-ppd.html api-ppd.xml >../doc/help/api-ppd.tokens
$(RM) api-ppd.xml
mxmldoc --section "Programming" --title "HTTP and IPP APIs" \
--css ../doc/cups-printable.css \
--header api-httpipp.header --intro api-httpipp.shtml \
api-httpipp.xml \
http.h ipp.h auth.c getdevices.c getputfile.c encode.c \
http.c http-addr.c http-support.c ipp.c ipp-support.c \
md5passwd.c request.c >../doc/help/api-httpipp.html
mxmldoc --tokens help/api-httpipp.html api-httpipp.xml >../doc/help/api-httpipp.tokens
$(RM) api-httpipp.xml
mxmldoc --section "Programming" \
--title "Filter and Backend Programming" \
--css ../doc/cups-printable.css \
--header api-filter.header --intro api-filter.shtml \
api-filter.xml \
backchannel.c backend.h backend.c sidechannel.c sidechannel.h \
>../doc/help/api-filter.html
mxmldoc --tokens help/api-filter.html api-filter.xml >../doc/help/api-filter.tokens
$(RM) api-filter.xml
framedhelp:
echo Generating CUPS API help files...
mxmldoc --framed api-overview \
--section "Programming" \
--title "Introduction to CUPS Programming" \
--css ../doc/cups-printable.css \
--header api-overview.header --intro api-overview.shtml
mxmldoc --framed api-array \
--section "Programming" --title "Array API" \
--css ../doc/cups-printable.css \
--header api-array.header --intro api-array.shtml \
array.h array.c
mxmldoc --framed api-cups \
--section "Programming" --title "CUPS API" \
--css ../doc/cups-printable.css \
--header api-cups.header --intro api-cups.shtml \
cups.h adminutil.c dest*.c language.c notify.c \
options.c tempfile.c usersys.c \
util.c
mxmldoc --framed api-filedir \
--section "Programming" --title "File and Directory APIs" \
--css ../doc/cups-printable.css \
--header api-filedir.header --intro api-filedir.shtml \
file.h file.c dir.h dir.c
mxmldoc --framed api-ppd \
--section "Programming" --title "PPD API (DEPRECATED)" \
--css ../doc/cups-printable.css \
--header api-ppd.header --intro api-ppd.shtml \
ppd.h attr.c conflicts.c custom.c emit.c localize.c mark.c \
page.c ppd.c
mxmldoc --framed api-httpipp \
--section "Programming" --title "HTTP and IPP APIs" \
--css ../doc/cups-printable.css \
--header api-httpipp.header --intro api-httpipp.shtml \
http.h ipp.h auth.c getdevices.c getputfile.c encode.c \
http.c http-addr.c http-support.c ipp.c ipp-support.c \
md5passwd.c request.c
mxmldoc --framed api-filter \
--section "Programming" \
--title "Filter and Backend Programming" \
--css ../doc/cups-printable.css \
--header api-filter.header --intro api-filter.shtml \
backchannel.c backend.h backend.c sidechannel.c sidechannel.h
#
# Lines of code computation...
#
sloc:
echo "libcupslite: \c"
sloccount $(LITEOBJS:.o=.c) 2>/dev/null | grep "Total Physical" | awk '{print $$9}'
echo "libcups: \c"
sloccount $(LIBOBJS:.o=.c) 2>/dev/null | grep "Total Physical" | awk '{print $$9}'
#
# Dependencies...
#
include Dependencies
#
# End of "$Id: Makefile 7871 2008-08-27 21:12:43Z mike $".
#

2341
cups/adminutil.c Normal file

File diff suppressed because it is too large Load Diff

81
cups/adminutil.h Normal file
View File

@@ -0,0 +1,81 @@
/*
* "$Id: adminutil.h 7026 2007-10-19 00:57:45Z mike $"
*
* Administration utility API definitions for CUPS.
*
* Copyright 2007-2012 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*/
#ifndef _CUPS_ADMINUTIL_H_
# define _CUPS_ADMINUTIL_H_
/*
* Include necessary headers...
*/
# include <stdio.h>
# include "cups.h"
/*
* C++ magic...
*/
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/*
* Constants...
*/
# define CUPS_SERVER_DEBUG_LOGGING "_debug_logging"
# define CUPS_SERVER_REMOTE_ADMIN "_remote_admin"
# define CUPS_SERVER_REMOTE_ANY "_remote_any"
/*# define CUPS_SERVER_REMOTE_PRINTERS "_remote_printers"*/
# define CUPS_SERVER_SHARE_PRINTERS "_share_printers"
# define CUPS_SERVER_USER_CANCEL_ANY "_user_cancel_any"
/*
* Functions...
*/
extern int cupsAdminExportSamba(const char *dest, const char *ppd,
const char *samba_server,
const char *samba_user,
const char *samba_password,
FILE *logfile) _CUPS_DEPRECATED;
extern char *cupsAdminCreateWindowsPPD(http_t *http, const char *dest,
char *buffer, int bufsize)
_CUPS_DEPRECATED;
extern int cupsAdminGetServerSettings(http_t *http,
int *num_settings,
cups_option_t **settings)
_CUPS_API_1_3;
extern int cupsAdminSetServerSettings(http_t *http,
int num_settings,
cups_option_t *settings)
_CUPS_API_1_3;
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_ADMINUTIL_H_ */
/*
* End of "$Id: adminutil.h 7026 2007-10-19 00:57:45Z mike $".
*/

34
cups/api-array.header Normal file
View File

@@ -0,0 +1,34 @@
<!--
"$Id: api-array.header 7266 2008-01-29 02:15:29Z mike $"
Array API header for CUPS.
Copyright 2008-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/".
-->
<h1 class='title'>Array API</h1>
<div class='summary'><table summary='General Information'>
<thead>
<tr>
<th>Header</th>
<th>cups/array.h</th>
</tr>
</thead>
<tbody>
<tr>
<th>Library</th>
<td>-lcups</td>
</tr>
<tr>
<th>See Also</th>
<td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a></td>
</tr>
</tbody>
</table></div>

196
cups/api-array.shtml Normal file
View File

@@ -0,0 +1,196 @@
<!--
"$Id: api-array.shtml 7616 2008-05-28 00:34:13Z mike $"
Array API introduction for CUPS.
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
file is missing or damaged, see the license at "http://www.cups.org/".
-->
<h2 class='title'><a name='OVERVIEW'>Overview</a></h2>
<p>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
<a href='#cups_array_t'><code>cups_array_t</code></a> type is used when
referring to a CUPS array.</p>
<p>The CUPS scheduler (<tt>cupsd</tt>) and many of the CUPS API
functions use the array API to efficiently manage large lists of
data.</p>
<h3><a name='MANAGING_ARRAYS'>Managing Arrays</a></h3>
<p>Arrays are created using either the
<a href='#cupsArrayNew'><code>cupsArrayNew</code></a>,
<a href='#cupsArrayNew2'><code>cupsArrayNew2</code></a>, or
<a href='#cupsArrayNew2'><code>cupsArrayNew3</code></a> functions. The
first function creates a new array with the specified callback function
and user data pointer:</p>
<pre class='example'>
#include &lt;cups/array.h&gt;
static int compare_func(void *first, void *second, void *user_data);
void *user_data;
<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew'>cupsArrayNew</a>(compare_func, user_data);
</pre>
<p>The comparison function (type
<a href="#cups_arrayfunc_t"><code>cups_arrayfunc_t</code></a>) is called
whenever an element is added to the array and can be <code>NULL</code> 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.</p>
<p>The "user_data" pointer is passed to your comparison function. Pass
<code>NULL</code> if you do not need to associate the elements in your array
with additional information.</p>
<p>The <a href='#cupsArrayNew2'><code>cupsArrayNew2</code></a> function adds
two more arguments to support hashed lookups, which can potentially provide
instantaneous ("O(1)") lookups in your array:</p>
<pre class='example'>
#include &lt;cups/array.h&gt;
#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;
<a href='#cups_array_t'>cups_array_t</a> *hash_array = <a href='#cupsArrayNew2'>cupsArrayNew2</a>(compare_func, user_data, hash_func, HASH_SIZE);
</pre>
<p>The hash function (type
<a href="#cups_ahash_func_t"><code>cups_ahash_func_t</code></a>) 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
<a href='#cupsArrayFind'><code>cupsArrayFind</code></a>. The hash size is
only limited by available memory, but generally should not be larger than
16384 to realize any performance improvement.</p>
<p>The <a href='#cupsArrayNew3'><code>cupsArrayNew3</code></a> function adds
copy and free callbacks to support basic memory management of elements:</p>
<pre class='example'>
#include &lt;cups/array.h&gt;
#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;
<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew3'>cupsArrayNew3</a>(compare_func, user_data, NULL, 0, copy_func, free_func);
<a href='#cups_array_t'>cups_array_t</a> *hash_array = <a href='#cupsArrayNew3'>cupsArrayNew3</a>(compare_func, user_data, hash_func, HASH_SIZE, copy_func, free_func);
</pre>
<p>Once you have created the array, you add elements using the
<a href='#cupsArrayAdd'><code>cupsArrayAdd</code></a>
<a href='#cupsArrayInsert'><code>cupsArrayInsert</code></a> 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,
<a href='#cupsArrayAdd'><code>cupsArrayAdd</code></a> appends the element to
the end of the array while
<a href='#cupsArrayInsert'><code>cupsArrayInsert</code></a> inserts the
element at the beginning of the array. For example, the following code
creates a sorted array of character strings:</p>
<pre class='example'>
#include &lt;cups/array.h&gt;
/* Use strcmp() to compare strings - it will ignore the user_data pointer */
<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew'>cupsArrayNew</a>((<a href='#cups_array_func_t'>cups_array_func_t</a>)strcmp, NULL);
/* Add four strings to the array */
<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "One Fish");
<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Two Fish");
<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Red Fish");
<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Blue Fish");
</pre>
<p>Elements are removed using the
<a href='#cupsArrayRemove'><code>cupsArrayRemove</code></a> function, for
example:</p>
<pre class='example'>
#include &lt;cups/array.h&gt;
/* Use strcmp() to compare strings - it will ignore the user_data pointer */
<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew'>cupsArrayNew</a>((<a href='#cups_array_func_t'>cups_array_func_t</a>)strcmp, NULL);
/* Add four strings to the array */
<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "One Fish");
<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Two Fish");
<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Red Fish");
<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Blue Fish");
/* Remove "Red Fish" */
<a href='#cupsArrayRemove'>cupsArrayRemove</a>(array, "Red Fish");
</pre>
<p>Finally, you free the memory used by the array using the
<a href='#cupsArrayDelete'><code>cupsArrayDelete</code></a> function. All
of the memory for the array and hash table (if any) is freed, however <em>CUPS
does not free the elements unless you provide copy and free functions</em>.</p>
<h3><a name='FINDING_AND_ENUMERATING'>Finding and Enumerating Elements</a></h3>
<p>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:</p>
<dl>
<dt><a href='#cupsArrayFind'><code>cupsArrayFind</code></a></dt>
<dd>Returns the first matching element.</dd>
<dt><a href='#cupsArrayFirst'><code>cupsArrayFirst</code></a></dt>
<dd>Returns the first element in the array.</dd>
<dt><a href='#cupsArrayIndex'><code>cupsArrayIndex</code></a></dt>
<dd>Returns the Nth element in the array, starting at 0.</dd>
<dt><a href='#cupsArrayLast'><code>cupsArrayLast</code></a></dt>
<dd>Returns the last element in the array.</dd>
<dt><a href='#cupsArrayNext'><code>cupsArrayNext</code></a></dt>
<dd>Returns the next element in the array.</dd>
<dt><a href='#cupsArrayPrev'><code>cupsArrayPrev</code></a></dt>
<dd>Returns the previous element in the array.</dd>
</dl>
<p>Each of these functions returns <code>NULL</code> when there is no
corresponding element. For example, a simple <code>for</code> loop using the
<a href='#cupsArrayFirst'><code>cupsArrayFirst</code></a> and
<a href='#cupsArrayNext'><code>cupsArrayNext</code></a> functions will
enumerate all of the strings in our previous example:</p>
<pre class='example'>
#include &lt;cups/array.h&gt;
/* Use strcmp() to compare strings - it will ignore the user_data pointer */
<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew'>cupsArrayNew</a>((<a href='#cups_array_func_t'>cups_array_func_t</a>)strcmp, NULL);
/* Add four strings to the array */
<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "One Fish");
<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Two Fish");
<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Red Fish");
<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Blue Fish");
/* Show all of the strings in the array */
char *s;
for (s = (char *)<a href='#cupsArrayFirst'>cupsArrayFirst</a>(array); s != NULL; s = (char *)<a href='#cupsArrayNext'>cupsArrayNext</a>(array))
puts(s);
</pre>

40
cups/api-cups.header Normal file
View File

@@ -0,0 +1,40 @@
<!--
"$Id: api-cups.header 7279 2008-01-31 01:50:44Z mike $"
CUPS API header for CUPS.
Copyright 2008-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/".
-->
<h1 class='title'>CUPS API</h1>
<div class='summary'><table summary='General Information'>
<thead>
<tr>
<th>Header</th>
<th>cups/cups.h</th>
</tr>
</thead>
<tbody>
<tr>
<th>Library</th>
<td>-lcups</td>
</tr>
<tr>
<th>See Also</th>
<td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a><br>
Programming: <a href='api-array.html' target='_top'>Array API</a><br>
Programming: <a href='api-filedir.html' target='_top'>File and Directory APIs</a><br>
Programming: <a href='api-filter.html' target='_top'>Filter and Backend Programming</a><br>
Programming: <a href='api-httpipp.html' target='_top'>HTTP and IPP APIs</a><br>
Programming: <a href='api-ppd.html' target='_top'>PPD API</a><br>
Programming: <a href='api-raster.html' target='_top'>Raster API</a></td>
</tr>
</tbody>
</table></div>

443
cups/api-cups.shtml Normal file
View File

@@ -0,0 +1,443 @@
<!--
"$Id: api-cups.shtml 7337 2008-02-22 04:44:04Z mike $"
API introduction for CUPS.
Copyright 2007-2013 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/".
-->
<h2 class='title'><a name='OVERVIEW'>Overview</a></h2>
<p>The CUPS API provides the convenience functions needed to support
applications, filters, printer drivers, and backends that need to interface
with the CUPS scheduler.</p>
<h3><a name='CLIENTS_AND_SERVERS'>Clients and Servers</a></h3>
<p>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
<code>http_t</code>. All of the examples in this document use the
<code>CUPS_HTTP_DEFAULT</code> constant, referring to the default connection
to the scheduler. The <a href='api-httpipp.html' target='_top'>HTTP and IPP
APIs</a> document provides more information on server connections.</p>
<h3><a name='PRINTERS_AND_CLASSES'>Printers and Classes</a></h3>
<p>Printers and classes (collections of printers) are accessed through
the <a href="#cups_dest_t"><code>cups_dest_t</code></a> structure which
includes the name (<code>name</code>), instance (<code>instance</code> -
a way of selecting certain saved options/settings), and the options and
attributes associated with that destination (<code>num_options</code> and
<code>options</code>). Destinations are created using the
<a href="#cupsGetDests"><code>cupsGetDests</code></a> function and freed
using the <a href='#cupsFreeDests'><code>cupsFreeDests</code></a> function.
The <a href='#cupsGetDest'><code>cupsGetDest</code></a> function finds a
specific destination for printing:</p>
<pre class='example'>
#include &lt;cups/cups.h&gt;
<a href='#cups_dest_t'>cups_dest_t</a> *dests;
int num_dests = <a href='#cupsGetDests'>cupsGetDests</a>(&amp;dests);
<a href='#cups_dest_t'>cups_dest_t</a> *dest = <a href='#cupsGetDest'>cupsGetDest</a>("name", NULL, num_dests, dests);
/* do something with dest */
<a href='#cupsFreeDests'>cupsFreeDests</a>(num_dests, dests);
</pre>
<p>Passing <code>NULL</code> to
<a href='#cupsGetDest'><code>cupsGetDest</code></a> for the destination name
will return the default destination. Similarly, passing a <code>NULL</code>
instance will return the default instance for that destination.</p>
<div class='table'><table summary='Table 1: Printer Attributes' width='80%'>
<caption>Table 1: <a name='TABLE1'>Printer Attributes</a></caption>
<thead>
<tr>
<th>Attribute Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>"auth-info-required"</td>
<td>The type of authentication required for printing to this
destination: "none", "username,password", "domain,username,password",
or "negotiate" (Kerberos)</td>
</tr>
<tr>
<td>"printer-info"</td>
<td>The human-readable description of the destination such as "My
Laser Printer".</td>
</tr>
<tr>
<td>"printer-is-accepting-jobs"</td>
<td>"true" if the destination is accepting new jobs, "false" if
not.</td>
</tr>
<tr>
<td>"printer-is-shared"</td>
<td>"true" if the destination is being shared with other computers,
"false" if not.</td>
</tr>
<tr>
<td>"printer-location"</td>
<td>The human-readable location of the destination such as "Lab 4".</td>
</tr>
<tr>
<td>"printer-make-and-model"</td>
<td>The human-readable make and model of the destination such as "HP
LaserJet 4000 Series".</td>
</tr>
<tr>
<td>"printer-state"</td>
<td>"3" if the destination is idle, "4" if the destination is printing
a job, and "5" if the destination is stopped.</td>
</tr>
<tr>
<td>"printer-state-change-time"</td>
<td>The UNIX time when the destination entered the current state.</td>
</tr>
<tr>
<td>"printer-state-reasons"</td>
<td>Additional comma-delimited state keywords for the destination
such as "media-tray-empty-error" and "toner-low-warning".</td>
</tr>
<tr>
<td>"printer-type"</td>
<td>The <a href='#cups_printer_t'><code>cups_printer_t</code></a>
value associated with the destination.</td>
</tr>
</tbody>
</table></div>
<h3><a name='OPTIONS'>Options</a></h3>
<p>Options are stored in arrays of
<a href='#cups_option_t'><code>cups_option_t</code></a> structures. Each
option has a name (<code>name</code>) and value (<code>value</code>)
associated with it. The <a href='#cups_dest_t'><code>cups_dest_t</code></a>
<code>num_options</code> and <code>options</code> members contain the
default options for a particular destination, along with several informational
attributes about the destination as shown in <a href='#TABLE1'>Table 1</a>.
The <a href='#cupsGetOption'><code>cupsGetOption</code></a> function gets
the value for the named option. For example, the following code lists the
available destinations and their human-readable descriptions:</p>
<pre class='example'>
#include &lt;cups/cups.h&gt;
<a href='#cups_dest_t'>cups_dest_t</a> *dests;
int num_dests = <a href='#cupsGetDests'>cupsGetDests</a>(&amp;dests);
<a href='#cups_dest_t'>cups_dest_t</a> *dest;
int i;
const char *value;
for (i = num_dests, dest = dests; i > 0; i --, dest ++)
if (dest->instance == NULL)
{
value = <a href='#cupsGetOption'>cupsGetOption</a>("printer-info", dest->num_options, dest->options);
printf("%s (%s)\n", dest->name, value ? value : "no description");
}
<a href='#cupsFreeDests'>cupsFreeDests</a>(num_dests, dests);
</pre>
<p>You can create your own option arrays using the
<a href='#cupsAddOption'><code>cupsAddOption</code></a> function, which
adds a single named option to an array:</p>
<pre class='example'>
#include &lt;cups/cups.h&gt;
int num_options = 0;
<a href='#cups_option_t'>cups_option_t</a> *options = NULL;
/* The returned num_options value is updated as needed */
num_options = <a href='#cupsAddOption'>cupsAddOption</a>("first", "value", num_options, &amp;options);
/* This adds a second option value */
num_options = <a href='#cupsAddOption'>cupsAddOption</a>("second", "value", num_options, &amp;options);
/* This replaces the first option we added */
num_options = <a href='#cupsAddOption'>cupsAddOption</a>("first", "new value", num_options, &amp;options);
</pre>
<p>Use a <code>for</code> loop to copy the options from a destination:</p>
<pre class='example'>
#include &lt;cups/cups.h&gt;
int i;
int num_options = 0;
<a href='#cups_option_t'>cups_option_t</a> *options = NULL;
<a href='#cups_dest_t'>cups_dest_t</a> *dest;
for (i = 0; i &lt; dest->num_options; i ++)
num_options = <a href='#cupsAddOption'>cupsAddOption</a>(dest->options[i].name, dest->options[i].value,
num_options, &amp;options);
</pre>
<p>Use the <a href='#cupsFreeOptions'><code>cupsFreeOptions</code></a>
function to free the options array when you are done using it:</p>
<pre class='example'>
<a href='#cupsFreeOptions'>cupsFreeOptions</a>(num_options, options);
</pre>
<h3><a name='PRINT_JOBS'>Print Jobs</a></h3>
<p>Print jobs are identified by a locally-unique job ID number from 1 to
2<sup>31</sup>-1 and have options and one or more files for printing to a
single destination. The <a href='#cupsPrintFile'><code>cupsPrintFile</code></a>
function creates a new job with one file. The following code prints the CUPS
test page file:</p>
<pre class='example'>
#include &lt;cups/cups.h&gt;
<a href='#cups_dest_t'>cups_dest_t</a> *dest;
int num_options;
<a href='#cups_option_t'>cups_option_t</a> *options;
int job_id;
/* Print a single file */
job_id = <a href='#cupsPrintFile'>cupsPrintFile</a>(dest->name, "/usr/share/cups/data/testprint.ps",
"Test Print", num_options, options);
</pre>
<p>The <a href='#cupsPrintFiles'><code>cupsPrintFiles</code></a> function
creates a job with multiple files. The files are provided in a
<code>char *</code> array:</p>
<pre class='example'>
#include &lt;cups/cups.h&gt;
<a href='#cups_dest_t'>cups_dest_t</a> *dest;
int num_options;
<a href='#cups_option_t'>cups_option_t</a> *options;
int job_id;
char *files[3] = { "file1.pdf", "file2.pdf", "file3.pdf" };
/* Print three files */
job_id = <a href='#cupsPrintFiles'>cupsPrintFiles</a>(dest->name, 3, files, "Test Print", num_options, options);
</pre>
<p>Finally, the <a href='#cupsCreateJob'><code>cupsCreateJob</code></a>
function creates a new job with no files in it. Files are added using the
<a href='#cupsStartDocument'><code>cupsStartDocument</code></a>,
<a href='api-httpipp.html#cupsWriteRequestData'><code>cupsWriteRequestData</code></a>,
and <a href='#cupsFinishDocument'><code>cupsFinishDocument</code></a> functions.
The following example creates a job with 10 text files for printing:</p>
<pre class='example'>
#include &lt;cups/cups.h&gt;
<a href='#cups_dest_t'>cups_dest_t</a> *dest;
int num_options;
<a href='#cups_option_t'>cups_option_t</a> *options;
int job_id;
int i;
char buffer[1024];
/* Create the job */
job_id = <a href='#cupsCreateJob'>cupsCreateJob</a>(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 &lt;= 10; i ++)
{
snprintf(buffer, sizeof(buffer), "file%d.txt", i);
<a href='#cupsStartDocument'>cupsStartDocument</a>(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 */
<a href='#cupsWriteRequestData'>cupsWriteRequestData</a>(CUPS_HTTP_DEFAULT, buffer, strlen(buffer));
<a href='#cupsFinishDocument'>cupsFinishDocument</a>(CUPS_HTTP_DEFAULT, dest->name);
}
}
</pre>
<p>Once you have created a job, you can monitor its status using the
<a href='#cupsGetJobs'><code>cupsGetJobs</code></a> function, which returns
an array of <a href='#cups_job_t'><code>cups_job_t</code></a> structures.
Each contains the job ID (<code>id</code>), destination name
(<code>dest</code>), title (<code>title</code>), and other information
associated with the job. The job array is freed using the
<a href='#cupsFreeJobs'><code>cupsFreeJobs</code></a> function. The following
example monitors a specific job ID, showing the current job state once every
5 seconds until the job is completed:</p>
<pre class='example'>
#include &lt;cups/cups.h&gt;
<a href='#cups_dest_t'>cups_dest_t</a> *dest;
int job_id;
int num_jobs;
<a href='#cups_job_t'>cups_job_t</a> *jobs;
int i;
ipp_jstate_t job_state = IPP_JOB_PENDING;
while (job_state &lt; IPP_JOB_STOPPED)
{
/* Get my jobs (1) with any state (-1) */
num_jobs = <a href='#cupsGetJobs'>cupsGetJobs</a>(&amp;jobs, dest->name, 1, -1);
/* Loop to find my job */
job_state = IPP_JOB_COMPLETED;
for (i = 0; i &lt; num_jobs; i ++)
if (jobs[i].id == job_id)
{
job_state = jobs[i].state;
break;
}
/* Free the job array */
<a href='#cupsFreeJobs'>cupsFreeJobs</a>(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 &lt; IPP_JOB_STOPPED)
sleep(5);
}
</pre>
<p>To cancel a job, use the
<a href='#cupsCancelJob'><code>cupsCancelJob</code></a> function with the
job ID:</p>
<pre class='example'>
#include &lt;cups/cups.h&gt;
<a href='#cups_dest_t'>cups_dest_t</a> *dest;
int job_id;
<a href='#cupsCancelJob'>cupsCancelJob</a>(dest->name, job_id);
</pre>
<h3><a name='ERROR_HANDLING'>Error Handling</a></h3>
<p>If any of the CUPS API printing functions returns an error, the reason for
that error can be found by calling the
<a href='#cupsLastError'><code>cupsLastError</code></a> and
<a href='#cupsLastErrorString'><code>cupsLastErrorString</code></a> functions.
<a href='#cupsLastError'><code>cupsLastError</code></a> returns the last IPP
error code
(<a href='api-httpipp.html#ipp_status_t'><code>ipp_status_t</code></a>)
that was encountered, while
<a href='#cupsLastErrorString'><code>cupsLastErrorString</code></a> 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
<a href='#cupsLastErrorString'><code>cupsLastErrorString</code></a> to show
the reason why the job could not be created:</p>
<pre class='example'>
#include &lt;cups/cups.h&gt;
int job_id;
if (job_id == 0)
puts(cupsLastErrorString());
</pre>
<h3><a name='PASSWORDS_AND_AUTHENTICATION'>Passwords and Authentication</a></h3>
<p>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.</p>
<p>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.</p>
<p>The <a href="#cupsSetPasswordCB"><code>cupsSetPasswordCB</code></a>
function is used to set a password callback in your program. Only one
function can be used at any time.</p>
<p>The <a href="#cupsSetUser"><code>cupsSetUser</code></a> function sets the
current username for authentication. This function can be called by your
password callback function to change the current username as needed.</p>
<p>The following example shows a simple password callback that gets a
username and password from the user:</p>
<pre class='example'>
#include &lt;cups/cups.h&gt;
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';
<a href='#cupsSetUser'>cupsSetUser</a>(user);
/* Use getpass() to ask for the password... */
return (getpass("Password: "));
}
<a href='#cupsSetPasswordCB'>cupsSetPasswordCB</a>(my_password_cb);
</pre>
<p>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 <a href="#cupsUser"><code>cupsUser</code></a>
function.</p>

36
cups/api-filedir.header Normal file
View File

@@ -0,0 +1,36 @@
<!--
"$Id: api-filedir.header 7279 2008-01-31 01:50:44Z mike $"
File and Directory API header for CUPS.
Copyright 2008-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/".
-->
<h1 class='title'>File and Directory APIs</h1>
<div class='summary'><table summary='General Information'>
<thead>
<tr>
<th>Headers</th>
<th>cups/file.h<br>
cups/dir.h</th>
</tr>
</thead>
<tbody>
<tr>
<th>Library</th>
<td>-lcups</td>
</tr>
<tr>
<th>See Also</th>
<td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a><br>
Programming: <a href='api-cups.html' target='_top'>CUPS API</a></td>
</tr>
</tbody>
</table></div>

31
cups/api-filedir.shtml Normal file
View File

@@ -0,0 +1,31 @@
<!--
"$Id: api-filedir.shtml 7279 2008-01-31 01:50:44Z mike $"
File and directory API introduction for CUPS.
Copyright 2007-2011 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
file is missing or damaged, see the license at "http://www.cups.org/".
-->
<h2 class='title'><a name="OVERVIEW">Overview</a></h2>
<p>The CUPS file and directory APIs provide portable interfaces
for manipulating files and listing files and directories. Unlike
stdio <code>FILE</code> streams, the <code>cupsFile</code> 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
<code>cupsFile</code> functions.</p>
<p>The <code>cupsDir</code> 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.</p>

41
cups/api-filter.header Normal file
View File

@@ -0,0 +1,41 @@
<!--
"$Id: api-filter.header 7616 2008-05-28 00:34:13Z mike $"
Filter and backend programming header for CUPS.
Copyright 2008-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/".
-->
<h1 class='title'>Filter and Backend Programming</h1>
<div class='summary'><table summary='General Information'>
<thead>
<tr>
<th>Headers</th>
<th>cups/backend.h<br>
cups/sidechannel.h</th>
</tr>
</thead>
<tbody>
<tr>
<th>Library</th>
<td>-lcups</td>
</tr>
<tr>
<th>See Also</th>
<td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a><br>
Programming: <a href='api-cups.html' target='_top'>CUPS API</a><br>
Programming: <a href='api-ppd.html' target='_top'>PPD API</a><br>
Programming: <a href='api-raster.html' target='_top'>Raster API</a><br>
Programming: <a href='postscript-driver.html' target='_top'>Developing PostScript Printer Drivers</a><br>
Programming: <a href='raster-driver.html' target='_top'>Developing Raster Printer Drivers</a><br>
Specifications: <a href='spec-design.html' target='_top'>CUPS Design Description</a></td>
</tr>
</tbody>
</table></div>

765
cups/api-filter.shtml Normal file
View File

@@ -0,0 +1,765 @@
<!--
"$Id: api-filter.shtml 7677 2008-06-19 23:22:19Z mike $"
Filter and backend programming introduction for CUPS.
Copyright 2007-2013 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/".
-->
<h2 class='title'><a name="OVERVIEW">Overview</a></h2>
<p>Filters (which include printer drivers and port monitors) and backends
are used to convert job files to a printable format and send that data to the
printer itself. All of these programs use a common interface for processing
print jobs and communicating status information to the scheduler. Each is run
with a standard set of command-line arguments:<p>
<dl class="code">
<dt>argv[1]</dt>
<dd>The job ID</dd>
<dt>argv[2]</dt>
<dd>The user printing the job</dd>
<dt>argv[3]</dt>
<dd>The job name/title</dd>
<dt>argv[4]</dt>
<dd>The number of copies to print</dd>
<dt>argv[5]</dt>
<dd>The options that were provided when the job was submitted</dd>
<dt>argv[6]</dt>
<dd>The file to print (first program only)</dd>
</dl>
<p>The scheduler runs one or more of these programs to print any given job. The
first filter reads from the print file and writes to the standard output, while
the remaining filters read from the standard input and write to the standard
output. The backend is the last filter in the chain and writes to the
device.</p>
<p>Filters are always run as a non-privileged user, typically "lp", with no
connection to the user's desktop. Backends are run either as a non-privileged
user or as root if the file permissions do not allow user or group execution.
The <a href="#PERMISSIONS">file permissions</a> section talks about this in
more detail.</p>
<h3><a name="SECURITY">Security Considerations</a></h3>
<p>It is always important to use security programming practices. Filters and
most backends are run as a non-privileged user, so the major security
consideration is resource utilization - filters should not depend on unlimited
amounts of CPU, memory, or disk space, and should protect against conditions
that could lead to excess usage of any resource like infinite loops and
unbounded recursion. In addition, filters must <em>never</em> allow the user to
specify an arbitrary file path to a separator page, template, or other file
used by the filter since that can lead to an unauthorized disclosure of
information. <em>Always</em> treat input as suspect and validate it!</p>
<p>If you are developing a backend that runs as root, make sure to check for
potential buffer overflows, integer under/overflow conditions, and file
accesses since these can lead to privilege escalations. When writing files,
always validate the file path and <em>never</em> allow a user to determine
where to store a file.</p>
<blockquote><b>Note:</b>
<p><em>Never</em> write files to a user's home directory. Aside from the
security implications, CUPS is a network print service and as such the network
user may not be the same as the local user and/or there may not be a local home
directory to write to.</p>
<p>In addition, some operating systems provide additional security mechanisms
that further limit file system access, even for backends running as root. On
OS X, for example, no backend may write to a user's home directory.</p>
</blockquote>
<h3><a name="SIGNALS">Canceled Jobs and Signal Handling</a></h3>
<p>The scheduler sends <code>SIGTERM</code> when a printing job is canceled or
held. Filters, backends, and port monitors <em>must</em> catch
<code>SIGTERM</code> and perform any cleanup necessary to produce a valid output
file or return the printer to a known good state. The recommended behavior is to
end the output on the current page, preferably on the current line or object
being printed.</p>
<p>Filters and backends may also receive <code>SIGPIPE</code> when an upstream or downstream filter/backend exits with a non-zero status. Developers should generally ignore <code>SIGPIPE</code> at the beginning of <code>main()</code> with the following function call:</p>
<pre class="example">
#include &lt;signal.h&gt;>
...
int
main(int argc, char *argv[])
{
signal(SIGPIPE, SIG_IGN);
...
}
</pre>
<h3><a name="PERMISSIONS">File Permissions</a></h3>
<p>For security reasons, CUPS will only run filters and backends that are owned
by root and do not have world or group write permissions. The recommended
permissions for filters and backends are 0555 - read and execute but no write.
Backends that must run as root should use permissions of 0500 - read and execute
by root, no access for other users. Write permissions can be enabled for the
root user only.</p>
<p>To avoid a warning message, the directory containing your filter(s) must also
be owned by root and have world and group write disabled - permissions of 0755
or 0555 are strongly encouraged.</p>
<h3><a name="TEMPFILES">Temporary Files</a></h3>
<p>Temporary files should be created in the directory specified by the
"TMPDIR" environment variable. The
<a href="#cupsTempFile2"><code>cupsTempFile2</code></a> function can be
used to safely create temporary files in this directory.</p>
<h3><a name="COPIES">Copy Generation</a></h3>
<p>The <code>argv[4]</code> argument specifies the number of copies to produce
of the input file. In general, you should only generate copies if the
<em>filename</em> argument is supplied. The only exception to this are
filters that produce device-independent PostScript output, since the PostScript
filter <var>pstops</var> is responsible for generating copies of PostScript
files.</p>
<h3><a name="EXITCODES">Exit Codes</a></h3>
<p>Filters must exit with status 0 when they successfully generate print data
or 1 when they encounter an error. Backends can return any of the
<a href="#cups_backend_t"><code>cups_backend_t</code></a> constants.</p>
<h3><a name="ENVIRONMENT">Environment Variables</a></h3>
<p>The following environment variables are defined by the printing system
when running print filters and backends:</p>
<dl class="code">
<dt>APPLE_LANGUAGE</dt>
<dd>The Apple language identifier associated with the job
(OS X only).</dd>
<dt>CHARSET</dt>
<dd>The job character set, typically "utf-8".</dd>
<dt>CLASS</dt>
<dd>When a job is submitted to a printer class, contains the name of
the destination printer class. Otherwise this environment
variable will not be set.</dd>
<dt>CONTENT_TYPE</dt>
<dd>The MIME type associated with the file (e.g.
application/postscript).</dd>
<dt>CUPS_CACHEDIR</dt>
<dd>The directory where cache files can be stored. Cache files can be
used to retain information between jobs or files in a job.</dd>
<dt>CUPS_DATADIR</dt>
<dd>The directory where (read-only) CUPS data files can be found.</dd>
<dt>CUPS_FILETYPE</dt>
<dd>The type of file being printed: "job-sheet" for a banner page and
"document" for a regular print file.</dd>
<dt>CUPS_SERVERROOT</dt>
<dd>The root directory of the server.</dd>
<dt>DEVICE_URI</dt>
<dd>The device-uri associated with the printer.</dd>
<dt>FINAL_CONTENT_TYPE</dt>
<dd>The MIME type associated with the printer (e.g.
application/vnd.cups-postscript).</dd>
<dt>LANG</dt>
<dd>The language locale associated with the job.</dd>
<dt>PPD</dt>
<dd>The full pathname of the PostScript Printer Description (PPD)
file for this printer.</dd>
<dt>PRINTER</dt>
<dd>The queue name of the class or printer.</dd>
<dt>RIP_CACHE</dt>
<dd>The recommended amount of memory to use for Raster Image
Processors (RIPs).</dd>
<dt>TMPDIR</dt>
<dd>The directory where temporary files should be created.</dd>
</dl>
<h3><a name="MESSAGES">Communicating with the Scheduler</a></h3>
<p>Filters and backends communicate with the scheduler by writing messages
to the standard error file. The scheduler reads messages from all filters in
a job and processes the message based on its prefix. For example, the following
code sets the current printer state message to "Printing page 5":</p>
<pre class="example">
int page = 5;
fprintf(stderr, "INFO: Printing page %d\n", page);
</pre>
<p>Each message is a single line of text starting with one of the following
prefix strings:</p>
<dl class="code">
<dt>ALERT: message</dt>
<dd>Sets the printer-state-message attribute and adds the specified
message to the current error log file using the "alert" log level.</dd>
<dt>ATTR: attribute=value [attribute=value]</dt>
<dd>Sets the named printer or job attribute(s). Typically this is used
to set the <code>marker-colors</code>, <code>marker-high-levels</code>,
<code>marker-levels</code>, <code>marker-low-levels</code>,
<code>marker-message</code>, <code>marker-names</code>,
<code>marker-types</code>, <code>printer-alert</code>, and
<code>printer-alert-description</code> printer attributes. Standard
<code>marker-types</code> values are listed in <a href='#TABLE1'>Table
1</a>.</dd>
<dt>CRIT: message</dt>
<dd>Sets the printer-state-message attribute and adds the specified
message to the current error log file using the "critical" log
level.</dd>
<dt>DEBUG: message</dt>
<dd>Sets the printer-state-message attribute and adds the specified
message to the current error log file using the "debug" log level.</dd>
<dt>DEBUG2: message</dt>
<dd>Sets the printer-state-message attribute and adds the specified
message to the current error log file using the "debug2" log level.</dd>
<dt>EMERG: message</dt>
<dd>Sets the printer-state-message attribute and adds the specified
message to the current error log file using the "emergency" log
level.</dd>
<dt>ERROR: message</dt>
<dd>Sets the printer-state-message attribute and adds the specified
message to the current error log file using the "error" log level.
Use "ERROR:" messages for non-persistent processing errors.</dd>
<dt>INFO: message</dt>
<dd>Sets the printer-state-message attribute. If the current log level
is set to "debug2", also adds the specified message to the current error
log file using the "info" log level.</dd>
<dt>NOTICE: message</dt>
<dd>Sets the printer-state-message attribute and adds the specified
message to the current error log file using the "notice" log level.</dd>
<dt>PAGE: page-number #-copies</dt>
<dt>PAGE: total #-pages</dt>
<dd>Adds an entry to the current page log file. The first form adds
#-copies to the job-media-sheets-completed attribute. The second
form sets the job-media-sheets-completed attribute to #-pages.</dd>
<dt>PPD: keyword=value [keyword=value ...]</dt>
<dd>Changes or adds keywords to the printer's PPD file. Typically
this is used to update installable options or default media settings
based on the printer configuration.</dd>
<dt>STATE: + printer-state-reason [printer-state-reason ...]</dt>
<dt>STATE: - printer-state-reason [printer-state-reason ...]</dt>
<dd>Sets or clears printer-state-reason keywords for the current queue.
Typically this is used to indicate persistent media, ink, toner, and
configuration conditions or errors on a printer.
<a href='#TABLE2'>Table 2</a> lists the standard state keywords -
use vendor-prefixed ("com.example.foo") keywords for custom states. See
<a href="#MANAGING_STATE">Managing Printer State in a Filter</a> for more
information.
<dt>WARNING: message</dt>
<dd>Sets the printer-state-message attribute and adds the specified
message to the current error log file using the "warning" log
level.</dd>
</dl>
<p>Messages without one of these prefixes are treated as if they began with
the "DEBUG:" prefix string.</p>
<div class='table'><table width='80%' summary='Table 1: Standard marker-types Values'>
<caption>Table 1: <a name='TABLE1'>Standard marker-types Values</a></caption>
<thead>
<tr>
<th>marker-type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>developer</td>
<td>Developer unit</td>
</tr>
<tr>
<td>fuser</td>
<td>Fuser unit</td>
</tr>
<tr>
<td>fuserCleaningPad</td>
<td>Fuser cleaning pad</td>
</tr>
<tr>
<td>fuserOil</td>
<td>Fuser oil</td>
</tr>
<tr>
<td>ink</td>
<td>Ink supply</td>
</tr>
<tr>
<td>opc</td>
<td>Photo conductor</td>
</tr>
<tr>
<td>solidWax</td>
<td>Wax supply</td>
</tr>
<tr>
<td>staples</td>
<td>Staple supply</td>
</tr>
<tr>
<td>toner</td>
<td>Toner supply</td>
</tr>
<tr>
<td>transferUnit</td>
<td>Transfer unit</td>
</tr>
<tr>
<td>wasteInk</td>
<td>Waste ink tank</td>
</tr>
<tr>
<td>wasteToner</td>
<td>Waste toner tank</td>
</tr>
<tr>
<td>wasteWax</td>
<td>Waste wax tank</td>
</tr>
</tbody>
</table></div>
<br>
<div class='table'><table width='80%' summary='Table 2: Standard State Keywords'>
<caption>Table 2: <a name='TABLE2'>Standard State Keywords</a></caption>
<thead>
<tr>
<th>Keyword</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>connecting-to-device</td>
<td>Connecting to printer but not printing yet.</td>
</tr>
<tr>
<td>cover-open</td>
<td>The printer's cover is open.</td>
</tr>
<tr>
<td>input-tray-missing</td>
<td>The paper tray is missing.</td>
</tr>
<tr>
<td>marker-supply-empty</td>
<td>The printer is out of ink.</td>
</tr>
<tr>
<td>marker-supply-low</td>
<td>The printer is almost out of ink.</td>
</tr>
<tr>
<td>marker-waste-almost-full</td>
<td>The printer's waste bin is almost full.</td>
</tr>
<tr>
<td>marker-waste-full</td>
<td>The printer's waste bin is full.</td>
</tr>
<tr>
<td>media-empty</td>
<td>The paper tray (any paper tray) is empty.</td>
</tr>
<tr>
<td>media-jam</td>
<td>There is a paper jam.</td>
</tr>
<tr>
<td>media-low</td>
<td>The paper tray (any paper tray) is almost empty.</td>
</tr>
<tr>
<td>media-needed</td>
<td>The paper tray needs to be filled (for a job that is printing).</td>
</tr>
<tr>
<td>paused</td>
<td>Stop the printer.</td>
</tr>
<tr>
<td>timed-out</td>
<td>Unable to connect to printer.</td>
</tr>
<tr>
<td>toner-empty</td>
<td>The printer is out of toner.</td>
</tr>
<tr>
<td>toner-low</td>
<td>The printer is low on toner.</td>
</tr>
</tbody>
</table></div>
<h4><a name="MANAGING_STATE">Managing Printer State in a Filter</a></h4>
<p>Filters are responsible for managing the state keywords they set using
"STATE:" messages. Typically you will update <em>all</em> of the keywords that
are used by the filter at startup, for example:</p>
<pre class="example">
if (foo_condition != 0)
fputs("STATE: +com.example.foo\n", stderr);
else
fputs("STATE: -com.example.foo\n", stderr);
if (bar_condition != 0)
fputs("STATE: +com.example.bar\n", stderr);
else
fputs("STATE: -com.example.bar\n", stderr);
</pre>
<p>Then as conditions change, your filter sends "STATE: +keyword" or "STATE:
-keyword" messages as necessary to set or clear the corresponding keyword,
respectively.</p>
<p>State keywords are often used to notify the user of issues that span across
jobs, for example "media-empty-warning" that indicates one or more paper trays
are empty. These keywords should not be cleared unless the corresponding issue
no longer exists.</p>
<p>Filters should clear job-related keywords on startup and exit so that they
do not remain set between jobs. For example, "connecting-to-device" is a job
sub-state and not an issue that applies when a job is not printing.</p>
<blockquote><b>Note:</b>
<p>"STATE:" messages often provide visible alerts to the user. For example,
on OS X setting a printer-state-reason value with an "-error" or
"-warning" suffix will cause the printer's dock item to bounce if the
corresponding reason is localized with a cupsIPPReason keyword in the
printer's PPD file.</p>
<p>When providing a vendor-prefixed keyword, <em>always</em> provide the
corresponding standard keyword (if any) to allow clients to respond to the
condition correctly. For example, if you provide a vendor-prefixed keyword
for a low cyan ink condition ("com.example.cyan-ink-low") you must also set the
"marker-supply-low-warning" keyword. In such cases you should also refrain
from localizing the vendor-prefixed keyword in the PPD file - otherwise both
the generic and vendor-specific keyword will be shown in the user
interface.</p>
</blockquote>
<h4><a name="REPORTING_SUPPLIES">Reporting Supply Levels</a></h4>
<p>CUPS tracks several "marker-*" attributes for ink/toner supply level
reporting. These attributes allow applications to display the current supply
levels for a printer without printer-specific software. <a href="#TABLE3">Table 3</a> lists the marker attributes and what they represent.</p>
<p>Filters set marker attributes by sending "ATTR:" messages to stderr. For
example, a filter supporting an inkjet printer with black and tri-color ink
cartridges would use the following to initialize the supply attributes:</p>
<pre class="example">
fputs("ATTR: marker-colors=#000000,#00FFFF#FF00FF#FFFF00\n", stderr);
fputs("ATTR: marker-low-levels=5,10\n", stderr);
fputs("ATTR: marker-names=Black,Tri-Color\n", stderr);
fputs("ATTR: marker-types=ink,ink\n", stderr);
</pre>
<p>Then periodically the filter queries the printer for its current supply
levels and updates them with a separate "ATTR:" message:</p>
<pre class="example">
int black_level, tri_level;
...
fprintf(stderr, "ATTR: marker-levels=%d,%d\n", black_level, tri_level);
</pre>
<div class='table'><table width='80%' summary='Table 3: Supply Level Attributes'>
<caption>Table 3: <a name='TABLE3'>Supply Level Attributes</a></caption>
<thead>
<tr>
<th>Attribute</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>marker-colors</td>
<td>A list of comma-separated colors; each color is either "none" or one or
more hex-encoded sRGB colors of the form "#RRGGBB".</td>
</tr>
<tr>
<td>marker-high-levels</td>
<td>A list of comma-separated "almost full" level values from 0 to 100; a
value of 100 should be used for supplies that are consumed/emptied like ink
cartridges.</td>
</tr>
<tr>
<td>marker-levels</td>
<td>A list of comma-separated level values for each supply. A value of -1
indicates the level is unavailable, -2 indicates unknown, and -3 indicates
the level is unknown but has not yet reached capacity. Values from 0 to 100
indicate the corresponding percentage.</td>
</tr>
<tr>
<td>marker-low-levels</td>
<td>A list of comma-separated "almost empty" level values from 0 to 100; a
value of 0 should be used for supplies that are filled like waste ink
tanks.</td>
</tr>
<tr>
<td>marker-message</td>
<td>A human-readable supply status message for the user like "12 pages of
ink remaining."</td>
</tr>
<tr>
<td>marker-names</td>
<td>A list of comma-separated supply names like "Cyan Ink", "Fuser",
etc.</td>
</tr>
<tr>
<td>marker-types</td>
<td>A list of comma-separated supply types; the types are listed in
<a href="#TABLE1">Table 1</a>.</td>
</tr>
</tbody>
</table></div>
<h3><a name="COMMUNICATING_BACKEND">Communicating with the Backend</a></h3>
<p>Filters can communicate with the backend via the
<a href="#cupsBackChannelRead"><code>cupsBackChannelRead</code></a> and
<a href="#cupsSideChannelDoRequest"><code>cupsSideChannelDoRequest</code></a>
functions. The
<a href="#cupsBackChannelRead"><code>cupsBackChannelRead</code></a> function
reads data that has been sent back from the device and is typically used to
obtain status and configuration information. For example, the following code
polls the backend for back-channel data:</p>
<pre class="example">
#include &lt;cups/cups.h&gt;
char buffer[8192];
ssize_t bytes;
/* Use a timeout of 0.0 seconds to poll for back-channel data */
bytes = cupsBackChannelRead(buffer, sizeof(buffer), 0.0);
</pre>
<p>Filters can also use <code>select()</code> or <code>poll()</code> on the
back-channel file descriptor (3 or <code>CUPS_BC_FD</code>) to read data only
when it is available.</p>
<p>The
<a href="#cupsSideChannelDoRequest"><code>cupsSideChannelDoRequest</code></a>
function allows you to get out-of-band status information and do synchronization
with the device. For example, the following code gets the current IEEE-1284
device ID string from the backend:</p>
<pre class="example">
#include &lt;cups/sidechannel.h&gt;
char data[2049];
int datalen;
<a href="#cups_sc_status_t">cups_sc_status_t</a> status;
/* Tell cupsSideChannelDoRequest() how big our buffer is, less 1 byte for
nul-termination... */
datalen = sizeof(data) - 1;
/* Get the IEEE-1284 device ID, waiting for up to 1 second */
status = <a href="#cupsSideChannelDoRequest">cupsSideChannelDoRequest</a>(CUPS_SC_CMD_GET_DEVICE_ID, data, &amp;datalen, 1.0);
/* Use the returned value if OK was returned and the length is non-zero */
if (status == CUPS_SC_STATUS_OK &amp;&amp; datalen > 0)
data[datalen] = '\0';
else
data[0] = '\0';
</pre>
<h4><a name="DRAIN_OUTPUT">Forcing All Output to a Printer</a></h4>
<p>The
<a href="#cupsSideChannelDoRequest"><code>cupsSideChannelDoRequest</code></a>
function allows you to tell the backend to send all pending data to the printer.
This is most often needed when sending query commands to the printer. For example:</p>
<pre class="example">
#include &lt;cups/cups.h&gt;
#include &lt;cups/sidechannel.h&gt;
char data[1024];
int datalen = sizeof(data);
<a href="#cups_sc_status_t">cups_sc_status_t</a> status;
/* Flush pending output to stdout */
fflush(stdout);
/* Drain output to backend, waiting for up to 30 seconds */
status = <a href="#cupsSideChannelDoRequest">cupsSideChannelDoRequest</a>(CUPS_SC_CMD_DRAIN_OUTPUT, data, &amp;datalen, 30.0);
/* Read the response if the output was sent */
if (status == CUPS_SC_STATUS_OK)
{
ssize_t bytes;
/* Wait up to 10.0 seconds for back-channel data */
bytes = cupsBackChannelRead(data, sizeof(data), 10.0);
/* do something with the data from the printer */
}
</pre>
<h3><a name="COMMUNICATING_FILTER">Communicating with Filters</a></h3>
<p>Backends communicate with filters using the reciprocal functions
<a href="#cupsBackChannelWrite"><code>cupsBackChannelWrite</code></a>,
<a href="#cupsSideChannelRead"><code>cupsSideChannelRead</code></a>, and
<a href="#cupsSideChannelWrite"><code>cupsSideChannelWrite</code></a>. We
recommend writing back-channel data using a timeout of 1.0 seconds:</p>
<pre class="example">
#include &lt;cups/cups.h&gt;
char buffer[8192];
ssize_t bytes;
/* Obtain data from printer/device */
...
/* Use a timeout of 1.0 seconds to give filters a chance to read */
cupsBackChannelWrite(buffer, bytes, 1.0);
</pre>
<p>The <a href="#cupsSideChannelRead"><code>cupsSideChannelRead</code></a>
function reads a side-channel command from a filter, driver, or port monitor.
Backends can either poll for commands using a <code>timeout</code> of 0.0, wait
indefinitely for commands using a <code>timeout</code> of -1.0 (probably in a
separate thread for that purpose), or use <code>select</code> or
<code>poll</code> on the <code>CUPS_SC_FD</code> file descriptor (4) to handle
input and output on several file descriptors at the same time.</p>
<p>Once a command is processed, the backend uses the
<a href="#cupsSideChannelWrite"><code>cupsSideChannelWrite</code></a> function
to send its response. For example, the following code shows how to poll for a
side-channel command and respond to it:</p>
<pre class="example">
#include &lt;cups/sidechannel.h&gt;
<a href="#cups_sc_command_t">cups_sc_command_t</a> command;
<a href="#cups_sc_status_t">cups_sc_status_t</a> status;
char data[2048];
int datalen = sizeof(data);
/* Poll for a command... */
if (!<a href="#cupsSideChannelRead">cupsSideChannelRead</a>(&amp;command, &amp;status, data, &amp;datalen, 0.0))
{
switch (command)
{
/* handle supported commands, fill data/datalen/status with values as needed */
default :
status = CUPS_SC_STATUS_NOT_IMPLEMENTED;
datalen = 0;
break;
}
/* Send a response... */
<a href="#cupsSideChannelWrite">cupsSideChannelWrite</a>(command, status, data, datalen, 1.0);
}
</pre>
<h3><a name="SNMP">Doing SNMP Queries with Network Printers</a></h3>
<p>The Simple Network Management Protocol (SNMP) allows you to get the current
status, page counter, and supply levels from most network printers. Every
piece of information is associated with an Object Identifier (OID), and
every printer has a <em>community</em> name associated with it. OIDs can be
queried directly or by "walking" over a range of OIDs with a common prefix.</p>
<p>The two CUPS SNMP functions provide a simple API for querying network
printers through the side-channel interface. Each accepts a string containing
an OID like ".1.3.6.1.2.1.43.10.2.1.4.1.1" (the standard page counter OID)
along with a timeout for the query.</p>
<p>The <a href="#cupsSideChannelSNMPGet"><code>cupsSideChannelSNMPGet</code></a>
function queries a single OID and returns the value as a string in a buffer
you supply:</p>
<pre class="example">
#include &lt;cups/sidechannel.h&gt;
char data[512];
int datalen = sizeof(data);
if (<a href="#cupsSideChannelSNMPGet">cupsSideChannelSNMPGet</a>(".1.3.6.1.2.1.43.10.2.1.4.1.1", data, &amp;datalen, 5.0)
== CUPS_SC_STATUS_OK)
{
/* Do something with the value */
printf("Page counter is: %s\n", data);
}
</pre>
<p>The
<a href="#cupsSideChannelSNMPWalk"><code>cupsSideChannelSNMPWalk</code></a>
function allows you to query a whole group of OIDs, calling a function of your
choice for each OID that is found:</p>
<pre class="example">
#include &lt;cups/sidechannel.h&gt;
void
my_callback(const char *oid, const char *data, int datalen, void *context)
{
/* Do something with the value */
printf("%s=%s\n", oid, data);
}
...
void *my_data;
<a href="#cupsSideChannelSNMPWalk">cupsSNMPSideChannelWalk</a>(".1.3.6.1.2.1.43", 5.0, my_callback, my_data);
</pre>

37
cups/api-httpipp.header Normal file
View File

@@ -0,0 +1,37 @@
<!--
"$Id: api-httpipp.header 7258 2008-01-28 00:15:05Z mike $"
HTTP and IPP API header for CUPS.
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
file is missing or damaged, see the license at "http://www.cups.org/".
-->
<h1 class='title'>HTTP and IPP APIs</h1>
<div class='summary'><table summary='General Information'>
<thead>
<tr>
<th>Header</th>
<th>cups/cups.h</th>
</tr>
</thead>
<tbody>
<tr>
<th>Library</th>
<td>-lcups</td>
</tr>
<tr>
<th>See Also</th>
<td>Programming: <a href='api-overview.html'>Introduction to CUPS Programming</a><br>
Programming: <a href='api-cups.html'>CUPS API</a><br>
References: <a href='spec-ipp.html'>CUPS Implementation of IPP</a></td>
</tr>
</tbody>
</table></div>

317
cups/api-httpipp.shtml Normal file
View File

@@ -0,0 +1,317 @@
<!--
"$Id: api-httpipp.shtml 7684 2008-06-23 16:47:38Z mike $"
HTTP and IPP API introduction 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/".
-->
<h2 class='title'><a name='OVERVIEW'>Overview</a></h2>
<p>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.</p>
<p>The HTTP APIs use an opaque structure called
<a href='#http_t'><code>http_t</code></a> to manage connections to
a particular HTTP or IPP server. The
<a href='#httpConnectEncrypt'><code>httpConnectEncrypt</code></a> function is
used to create an instance of this structure for a particular server.
The constant <code>CUPS_HTTP_DEFAULT</code> can be used with all of the
<code>cups</code> functions to refer to the default CUPS server - the functions
create a per-thread <a href='#http_t'><code>http_t</code></a> as needed.</p>
<p>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 <a href='#ipp_t'><code>ipp_t</code></a> type holds a complete request or response and is allocated using the <a href='#ippNew'><code>ippNew</code></a> or <a href='#ippNewRequest'><code>ippNewRequest</code></a> functions and freed using the <a href='#ippDelete'><code>ippDelete</code></a> function.</p>
<p>The second opaque structure is called <a href='#ipp_attribute_t'><code>ipp_attribute_t</code></a> and holds a single IPP attribute which consists of a group tag (<a href='#ippGetGroupTag'><code>ippGetGroupTag</code></a>), a value type tag (<a href='#ippGetValueTag'><code>ippGetValueTag</code></a>), the attribute name (<a href='#ippGetName'><code>ippGetName</code></a>), and 1 or more values (<a href='#ippGetCount'><code>ippGetCount</code></a>, <a href='#ippGetBoolean'><code>ippGetBoolean</code></a>, <a href='#ippGetCollection'><code>ippGetCollection</code></a>, <a href='#ippGetDate'><code>ippGetDate</code></a>, <a href='#ippGetInteger'><code>ippGetInteger</code></a>, <a href='#ippGetRange'><code>ippGetRange</code></a>, <a href='#ippGetResolution'><code>ippGetResolution</code></a>, and <a href='#ippGetString'><code>ippGetString</code></a>). Attributes are added to an <a href='#ipp_t'><code>ipp_t</code></a> pointer using one of the <code>ippAdd</code> functions. For example, use <a href='#ippAddString'><code>ippAddString</code></a> to add the "printer-uri" and "requesting-user-name" string attributes to a request:</p>
<pre class='example'>
<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(IPP_GET_JOBS);
<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, "ipp://localhost/printers/");
<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
NULL, cupsUser());
</pre>
<p>Once you have created an IPP request, use the <code>cups</code> functions to send the request to and read the response from the server. For example, the <a href='#cupsDoRequest'><code>cupsDoRequest</code></a> function can be used for simple query operations that do not involve files:</p>
<pre class='example'>
#include &lt;cups/cups.h&gt;
<a href='#ipp_t'>ipp_t</a> *<a name='get_jobs'>get_jobs</a>(void)
{
<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(IPP_GET_JOBS);
<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, "ipp://localhost/printers/");
<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
NULL, cupsUser());
return (<a href='#cupsDoRequest'>cupsDoRequest</a>(CUPS_HTTP_DEFAULT, request, "/"));
}
</pre>
<p>The <a href='#cupsDoRequest'><code>cupsDoRequest</code></a> function frees the request and returns an IPP response or <code>NULL</code> pointer if the request could not be sent to the server. Once you have a response from the server, you can either use the <a href='#ippFindAttribute'><code>ippFindAttribute</code></a> and <a href='#ippFindNextAttribute'><code>ippFindNextAttribute</code></a> functions to find specific attributes, for example:</p>
<pre class='example'>
<a href='#ipp_t'>ipp_t</a> *response;
<a href='#ipp_attribute_t'>ipp_attribute_t</a> *attr;
attr = <a href='#ippFindAttribute'>ippFindAttribute</a>(response, "printer-state", IPP_TAG_ENUM);
</pre>
<p>You can also walk the list of attributes with a simple <code>for</code> loop like this:</p>
<pre class='example'>
<a href='#ipp_t'>ipp_t</a> *response;
<a href='#ipp_attribute_t'>ipp_attribute_t</a> *attr;
for (attr = <a href='#ippFirstAttribute'>ippFirstAttribute</a>(response); attr != NULL; attr = <a href='#ippNextAttribute'>ippNextAttribute</a>(response))
if (ippGetName(attr) == NULL)
puts("--SEPARATOR--");
else
puts(ippGetName(attr));
</pre>
<p>The <code>for</code> loop approach is normally used when collecting attributes for multiple objects (jobs, printers, etc.) in a response. Attributes with <code>NULL</code> names indicate a separator between the attributes of each object. For example, the following code will list the jobs returned from our previous <a href='#get_jobs'><code>get_jobs</code></a> example code:</p>
<pre class='example'>
<a href='#ipp_t'>ipp_t</a> *response = <a href='#get_jobs'>get_jobs</a>();
if (response != NULL)
{
<a href='#ipp_attribute_t'>ipp_attribute_t</a> *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 = <a href='#ippFirstAttribute'>ippFirstAttribute</a>(response); attr != NULL; attr = <a href='#ippNextAttribute'>ippNextAttribute</a>(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") &amp;&amp; ippGetValueTag(attr) == IPP_TAG_INTEGER)
job_id = ippGetInteger(attr, 0);
else if (!strcmp(attrname, "job-name") &amp;&amp; ippGetValueTag(attr) == IPP_TAG_NAME)
job_name = ippGetString(attr, 0, NULL);
else if (!strcmp(attrname, "job-originating-user-name") &amp;&amp;
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);
}
}
</pre>
<h3><a name='CREATING_URI_STRINGS'>Creating URI Strings</a></h3>
<p>To ensure proper encoding, the
<a href='#httpAssembleURIf'><code>httpAssembleURIf</code></a> function must be
used to format a "printer-uri" string for all printer-based requests:</p>
<pre class='example'>
const char *name = "Foo";
char uri[1024];
<a href='#ipp_t'>ipp_t</a> *request;
<a href='#httpAssembleURIf'>httpAssembleURIf</a>(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, cupsServer(),
ippPort(), "/printers/%s", name);
<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
</pre>
<h3><a name='SENDING_REQUESTS_WITH_FILES'>Sending Requests with Files</a></h3>
<p>The <a href='#cupsDoFileRequest'><code>cupsDoFileRequest</code></a> and
<a href='#cupsDoIORequest'><code>cupsDoIORequest</code></a> functions are
used for requests involving files. The
<a href='#cupsDoFileRequest'><code>cupsDoFileRequest</code></a> function
attaches the named file to a request and is typically used when sending a print
file or changing a printer's PPD file:</p>
<pre class='example'>
const char *filename = "/usr/share/cups/data/testprint.ps";
const char *name = "Foo";
char uri[1024];
char resource[1024];
<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(IPP_PRINT_JOB);
<a href='#ipp_t'>ipp_t</a> *response;
/* Use httpAssembleURIf for the printer-uri string */
<a href='#httpAssembleURIf'>httpAssembleURIf</a>(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, cupsServer(),
ippPort(), "/printers/%s", name);
<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
NULL, cupsUser());
<a href='#ippAddString'>ippAddString</a>(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 = <a href='#cupsDoFileRequest'>cupsDoFileRequest</a>(CUPS_HTTP_DEFAULT, request, resource, filename);
</pre>
<p>The <a href='#cupsDoIORequest'><code>cupsDoIORequest</code></a> 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
<code>CUPS_GET_DOCUMENT</code> and <code>CUPS_GET_PPD</code>. For example,
the following code will download the PPD file for the sample HP LaserJet
printer driver:</p>
<pre class='example'>
char tempfile[1024];
int tempfd;
<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(CUPS_GET_PPD);
<a href='#ipp_t'>ipp_t</a> *response;
<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
NULL, "laserjet.ppd");
tempfd = cupsTempFd(tempfile, sizeof(tempfile));
response = <a href='#cupsDoIORequest'>cupsDoIORequest</a>(CUPS_HTTP_DEFAULT, request, "/", -1, tempfd);
</pre>
<p>The example passes <code>-1</code> 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
<code>cupsTempFd</code> function.</p>
<h3><a name='ASYNCHRONOUS_REQUEST_PROCESSING'>Asynchronous Request Processing</a></h3>
<p>The <a href='#cupsSendRequest'><code>cupsSendRequest</code></a> and
<a href='#cupsGetResponse'><code>cupsGetResponse</code></a> 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 <a href='#ippDelete'><code>ippDelete</code></a>
function.</p>
<p>File data is attached to the request using the
<a href='#cupsWriteRequestData'><code>cupsWriteRequestData</code></a>
function, while file data returned from the server is read using the
<a href='#cupsReadResponseData'><code>cupsReadResponseData</code></a>
function. We can rewrite the previous <code>CUPS_GET_PPD</code> example
to use the asynchronous functions quite easily:</p>
<pre class='example'>
char tempfile[1024];
int tempfd;
<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(CUPS_GET_PPD);
<a href='#ipp_t'>ipp_t</a> *response;
<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
NULL, "laserjet.ppd");
tempfd = cupsTempFd(tempfile, sizeof(tempfile));
if (<a href='#cupsSendRequest'>cupsSendRequest</a>(CUPS_HTTP_DEFAULT, request, "/") == HTTP_CONTINUE)
{
response = <a href='#cupsGetResponse'>cupsGetResponse</a>(CUPS_HTTP_DEFAULT, "/");
if (response != NULL)
{
ssize_t bytes;
char buffer[8192];
while ((bytes = <a href='#cupsReadResponseData'>cupsReadResponseData</a>(CUPS_HTTP_DEFAULT, buffer, sizeof(buffer))) > 0)
write(tempfd, buffer, bytes);
}
}
/* Free the request! */
<a href='#ippDelete'>ippDelete</a>(request);
</pre>
<p>The <a href='#cupsSendRequest'><code>cupsSendRequest</code></a> function
returns the initial HTTP request status, typically either
<code>HTTP_CONTINUE</code> or <code>HTTP_UNAUTHORIZED</code>. The latter status
is returned when the request requires authentication of some sort. The
<a href='#cupsDoAuthentication'><code>cupsDoAuthentication</code></a> function
must be called when your see <code>HTTP_UNAUTHORIZED</code> and the request
re-sent. We can add authentication support to our example code by using a
<code>do ... while</code> loop:</p>
<pre class='example'>
char tempfile[1024];
int tempfd;
<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(CUPS_GET_PPD);
<a href='#ipp_t'>ipp_t</a> *response;
http_status_t status;
<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
NULL, "laserjet.ppd");
tempfd = cupsTempFd(tempfile, sizeof(tempfile));
/* Loop for authentication */
do
{
status = <a href='#cupsSendRequest'>cupsSendRequest</a>(CUPS_HTTP_DEFAULT, request, "/");
if (status == HTTP_UNAUTHORIZED)
{
/* Try to authenticate, break out of the loop if that fails */
if (<a href='#cupsDoAuthentication'>cupsDoAuthentication</a>(CUPS_HTTP_DEFAULT, "POST", "/"))
break;
}
}
while (status != HTTP_CONTINUE &amp;&amp; status != HTTP_UNAUTHORIZED);
if (status == HTTP_CONTINUE)
{
response = <a href='#cupsGetResponse'>cupsGetResponse</a>(CUPS_HTTP_DEFAULT, "/");
if (response != NULL)
{
ssize_t bytes;
char buffer[8192];
while ((bytes = <a href='#cupsReadResponseData'>cupsReadResponseData</a>(CUPS_HTTP_DEFAULT, buffer, sizeof(buffer))) > 0)
write(tempfd, buffer, bytes);
}
}
/* Free the request! */
<a href='#ippDelete'>ippDelete</a>(request);
</pre>

53
cups/api-overview.header Normal file
View File

@@ -0,0 +1,53 @@
<!--
"$Id: api-cups.header 7279 2008-01-31 01:50:44Z mike $"
Introduction to CUPS programming header for CUPS.
Copyright 2008-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/".
-->
<h1 class='title'>Introduction to CUPS Programming</h1>
<div class='summary'><table summary='General Information'>
<thead>
<tr>
<th>Headers</th>
<th>cups/cups.h<br>
cups/array.h<br>
cups/backend.h<br>
cups/dir.h<br>
cups/file.h<br>
cups/ppd.h<br>
cups/raster.h<br>
cups/sidechannel.h</th>
</tr>
</thead>
<tbody>
<tr>
<th>Libraries</th>
<td>-lcups<br>
-lcupsimage</td>
</tr>
<tr>
<th>See Also</th>
<td>Programming: <a href='raster-driver.html' target='_top'>Developing Raster Printer Drivers</a><br>
Programming: <a href='postscript-driver.html' target='_top'>Developing PostScript Printer Drivers</a><br>
Programming: <a href='api-filter.html' target='_top'>Filter and Backend Programming</a><br>
Programming: <a href='ppd-compiler.html' target='_top'>Introduction to the PPD Compiler</a><br>
Programming: <a href='api-array.html' target='_top'>Array API</a><br>
Programming: <a href='api-cups.html' target='_top'>CUPS API</a><br>
Programming: <a href='api-filedir.html' target='_top'>File and Directory APIs</a><br>
Programming: <a href='api-httpipp.html' target='_top'>HTTP and IPP APIs</a><br>
Programming: <a href='api-ppd.html' target='_top'>PPD API</a><br>
Programming: <a href='api-raster.html' target='_top'>Raster API</a><br>
References: <a href='ref-ppdcfile.html' target='_top'>PPD Compiler Driver Information File Reference</a><br>
Specifications: <a href='spec-ppd.html' target='_top'>CUPS PPD Extensions</a></td>
</tr>
</tbody>
</table></div>

94
cups/api-overview.shtml Normal file
View File

@@ -0,0 +1,94 @@
<!--
"$Id: api-cups.header 7279 2008-01-31 01:50:44Z mike $"
Introduction to CUPS programming content for CUPS.
Copyright 2008-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/".
-->
<h2 class="title"><a name="OVERVIEW">Overview</a></h2>
<p>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 <var>&lt;cups/cups.h&gt;</var> header, while
"cupsimage" functions are found in the <var>&lt;cups/raster.h&gt;</var>
header.</p>
<h2 class="title"><a name="COMPILING">Compiling Programs</a></h2>
<p>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.</p>
<p>The following simple program lists the available printers on the system:</p>
<pre class="example">
#include &lt;stdio.h&gt;
#include &lt;cups/cups.h&gt;
int main(void)
{
int i;
cups_dest_t *dests, *dest;
int num_dests = cupsGetDests(&amp;dests);
for (i = num_dests, dest = dests; i &gt; 0; i --, dest ++)
{
if (dest->instance)
printf("%s/%s\n", dest->name, dest->instance);
else
puts(dest->name);
}
return (0);
}
</pre>
<h3><a name="XCODE">Compiling with Xcode</a></h3>
<p>In Xcode, choose <var>New Project...</var> from the <var>File</var> menu,
then select the <var>Standard Tool</var> project type under <var>Command Line
Utility</var>. Click <var>Next</var> and choose a project directory. Click
<var>Next</var> to create the project.</p>
<p>In the project window, double-click on the <var>Targets</var> group and
control-click on the simple target to show the context menu. Choose
<var>Existing Framework...</var> from the <var>Add</var> submenu. When the file
chooser sheet appears, press the <kbd>/</kbd> key and enter "/usr/lib". Scroll
down the file list and select the <var>libcups.dylib</var> file. Click the
<var>Add</var> button in the file chooser and attributes sheets.</p>
<p>In the project window, double-click on the <var>main.c</var> source file.
Replace the template source code with the listing above and save it. Click the
<var>Build and Go</var> button to build the sample program and run it.</p>
<h3><a name="COMMANDLINE">Compiling with GCC</a></h3>
<p>From the command-line, create a file called <var>sample.c</var> using your
favorite editor and then run the following command to compile it with GCC and
run it:</p>
<pre class="command">
gcc -o simple `cups-config --cflags` simple.c `cups-config --libs`
./simple
</pre>
<p>The <code>cups-config</code> command provides the compiler flags
("cups-config --cflags") and libraries ("cups-config --libs") needed for the
local system.</p>
<h2 class="title"><a name="WHERETOGO">Where to Go Next</a></h2>
<p>If you are developing a print filter, driver, or backend, see the
<a href="api-filter.html" target="_top">Filter and Backend Programming</a>
guide. Raster printer driver developers should also read the
<a href="api-raster.html" target="_top">Raster API</a> reference.</p>

38
cups/api-ppd.header Normal file
View File

@@ -0,0 +1,38 @@
<!--
"$Id: api-ppd.header 7616 2008-05-28 00:34:13Z mike $"
PPD API header for CUPS.
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
file is missing or damaged, see the license at "http://www.cups.org/".
-->
<h1 class='title'>PPD API (DEPRECATED)</h1>
<blockquote>The PPD API is deprecated starting in CUPS 1.6/OS X 10.8. Please use the new Job Ticket APIs in the <a href="api-cups.html">CUPS API</a> documentation. These functions will be removed in a future release of CUPS.</blockquote>
<div class='summary'><table summary='General Information'>
<thead>
<tr>
<th>Header</th>
<th>cups/ppd.h</th>
</tr>
</thead>
<tbody>
<tr>
<th>Library</th>
<td>-lcups</td>
</tr>
<tr>
<th>See Also</th>
<td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a><br>
Programming: <a href='api-cups.html' target='_top'>CUPS API</a><br>
Specifications: <a href='spec-ppd.html' target='_top'>CUPS PPD Extensions</a></td>
</tr>
</tbody>
</table></div>

219
cups/api-ppd.shtml Normal file
View File

@@ -0,0 +1,219 @@
<!--
"$Id: api-ppd.shtml 7616 2008-05-28 00:34:13Z mike $"
PPD API introduction 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/".
-->
<h2 class='title'><a name='OVERVIEW'>Overview</a></h2>
<blockquote>The PPD API is deprecated starting in CUPS 1.6/OS X 10.8. Please use the new Job Ticket APIs in the <a href="api-cups.html">CUPS API</a> documentation. These functions will be removed in a future release of CUPS.</blockquote>
<p>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
it you can obtain the data necessary to display printer options to users, mark
option choices and check for conflicting choices, and output marked choices in
PostScript output. The <a href="#ppd_file_t"><code>ppd_file_t</code></a>
structure contains all of the information in a PPD file.</p>
<blockquote><b>Note:</b>
<p>The CUPS PPD API uses the terms "option" and "choice" instead of the Adobe
terms "MainKeyword" and "OptionKeyword" to refer to specific printer options and
features. CUPS also treats option ("MainKeyword") and choice ("OptionKeyword")
values as case-insensitive strings, so option "InputSlot" and choice "Upper"
are equivalent to "inputslot" and "upper", respectively.</p>
</blockquote>
<h3><a name="LOADING">Loading a PPD File</a></h3>
<p>The <a href="#ppdOpenFile"><code>ppdOpenFile</code></a> function "opens" a
PPD file and loads it into memory. For example, the following code opens the
current printer's PPD file in a CUPS filter:</p>
<pre class="example">
#include &lt;cups/ppd.h&gt;
<a href="#ppd_file_t">ppd_file_t</a> *ppd = <a href="#ppdOpenFile">ppdOpenFile</a>(getenv("PPD"));
</pre>
<p>The return value is a pointer to a new
<a href="#ppd_file_t"><code>ppd_file_t</code></a> structure or <code>NULL</code>
if the PPD file does not exist or cannot be loaded. The
<a href="#ppdClose"><code>ppdClose</code></a> function frees the memory used
by the structure:</p>
<pre class="example">
#include &lt;cups/ppd.h&gt;
<a href="#ppd_file_t">ppd_file_t</a> *ppd;
<a href="#ppdClose">ppdClose</a>(ppd);
</pre>
<p>Once closed, pointers to the <a href="#ppd_file_t"><code>ppd_file_t</code></a>
structure and any data in it will no longer be valid.</p>
<h3><a name="OPTIONS_AND_GROUPS">Options and Groups</a></h3>
<p>PPD files support multiple options, which are stored in arrays of
<a href="#ppd_option_t"><code>ppd_option_t</code></a> and
<a href="#ppd_choice_t"><code>ppd_choice_t</code></a> structures.</p>
<p>Each option in turn is associated with a group stored in a
<a href="#ppd_group_t"><code>ppd_group_t</code></a> structure. Groups can be
specified in the PPD file; if an option is not associated with a group
then it is put in an automatically-generated "General" group. Groups can also
have sub-groups, however CUPS currently ignores sub-groups because of past
abuses of this functionality.</p>
<p>Option choices are selected by marking them using one of three functions. The
first is <a href="#ppdMarkDefaults"><code>ppdMarkDefaults</code></a> which
selects all of the default options in the PPD file:</p>
<pre class="example">
#include &lt;cups/ppd.h&gt;
<a href="#ppd_file_t">ppd_file_t</a> *ppd;
<a href="#ppdMarkDefaults">ppdMarkDefaults</a>(ppd);
</pre>
<p>The second is <a href="#ppdMarkOption"><code>ppdMarkOption</code></a>
which selects a single option choice in the PPD file. For example, the following
code selects the upper paper tray:</p>
<pre class="example">
#include &lt;cups/ppd.h&gt;
<a href="#ppd_file_t">ppd_file_t</a> *ppd;
<a href="#ppdMarkOption">ppdMarkOption</a>(ppd, "InputSlot", "Upper");
</pre>
<p>The last function is
<a href="#cupsMarkOptions"><code>cupsMarkOptions</code></a> which selects
multiple option choices in the PPD file from an array of CUPS options, mapping
IPP attributes like "media" and "sides" to their corresponding PPD options. You
typically use this function in a print filter with
<code>cupsParseOptions</code> and
<a href="#ppdMarkDefaults"><code>ppdMarkDefaults</code></a> to select all of
the option choices needed for the job, for example:</p>
<pre class="example">
#include &lt;cups/ppd.h&gt;
<a href="#ppd_file_t">ppd_file_t</a> *ppd = <a href="#ppdOpenFile">ppdOpenFile</a>(getenv("PPD"));
cups_option_t *options = NULL;
int num_options = cupsParseOptions(argv[5], 0, &amp;options);
<a href="#ppdMarkDefaults">ppdMarkDefaults</a>(ppd);
<a href="#cupsMarkOptions">cupsMarkOptions</a>(ppd, num_options, options);
cupsFreeOptions(num_options, options);
</pre>
<h3><a name="CONSTRAINTS">Constraints</a></h3>
<p>PPD files support specification of conflict conditions, called
constraints, between different options. Constraints are stored in an array of
<a href="#ppd_const_t"><code>ppd_const_t</code></a> structures which specify
the options and choices that conflict with each other. The
<a href="#ppdConflicts"><code>ppdConflicts</code></a> function tells you
how many of the selected options are incompatible. Since constraints are
normally specified in pairs, the returned value is typically an even number.</p>
<h3><a name="PAGE_SIZES">Page Sizes</a></h3>
<p>Page sizes are special options which have physical dimensions and margins
associated with them. The size information is stored in
<a href="#ppd_size_t"><code>ppd_size_t</code></a> structures and is available
by looking up the named size with the
<a href="#ppdPageSize"><code>ppdPageSize</code></a> function. The page size and
margins are returned in units called points; there are 72 points per inch. If
you pass <code>NULL</code> for the size, the currently selected size is
returned:</p>
<pre class="example">
#include &lt;cups/ppd.h&gt;
<a href="#ppd_file_t">ppd_file_t</a> *ppd;
<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, NULL);
</pre>
<p>Besides the standard page sizes listed in a PPD file, some printers
support variable or custom page sizes. Custom page sizes are supported if the
<code>variables_sizes</code> member of the
<a href="#ppd_file_t"><code>ppd_file_t</code></a> structure is non-zero.
The <code>custom_min</code>, <code>custom_max</code>, and
<code>custom_margins</code> members of the
<a href="#ppd_file_t"><code>ppd_file_t</code></a> structure define the limits
of the printable area. To get the resulting media size, use a page size string
of the form "Custom.<I>width</I>x<I>length</I>", where "width" and "length" are
in points. Custom page size names can also be specified in inches
("Custom.<i>width</i>x<i>height</i>in"), centimeters
("Custom.<i>width</i>x<i>height</i>cm"), or millimeters
("Custom.<i>width</i>x<i>height</i>mm"):</p>
<pre class="example">
#include &lt;cups/ppd.h&gt;
<a href="#ppd_file_t">ppd_file_t</a> *ppd;
/* Get an 576x720 point custom page size */
<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.576x720");
/* Get an 8x10 inch custom page size */
<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.8x10in");
/* Get a 100x200 millimeter custom page size */
<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.100x200mm");
/* Get a 12.7x34.5 centimeter custom page size */
<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.12.7x34.5cm");
</pre>
<p>If the PPD does not support variable page sizes, the
<a href="#ppdPageSize"><code>ppdPageSize</code></a> function will return
<code>NULL</code>.</p>
<h3><a name="ATTRIBUTES">Attributes</a></h3>
<p>Every PPD file is composed of one or more attributes. Most of these
attributes are used to define groups, options, choices, and page sizes,
however several informational attributes may be present which you can access
in your program or filter. Attributes normally look like one of the following
examples in a PPD file:</p>
<pre class="example">
*name: "value"
*name spec: "value"
*name spec/text: "value"
</pre>
<p>The <a href="#ppdFindAttr"><code>ppdFindAttr</code></a> and
<a href="#ppdFindNextAttr"><code>ppdFindNextAttr</code></a> functions find the
first and next instances, respectively, of the named attribute with the given
"spec" string and return a <a href="#ppd_attr_t"><code>ppd_attr_t</code></a>
structure. If you provide a NULL specifier string, all attributes with the
given name will be returned. For example, the following code lists all of the
<code>Product</code> attributes in a PPD file:</p>
<pre class="example">
#include &lt;cups/ppd.h&gt;
<a href="#ppd_file_t">ppd_file_t</a> *ppd;
<a href="#ppd_attr_t">ppd_attr_t</a> *attr;
for (attr = <a href="#ppdFindAttr">ppdFindAttr</a>(ppd, "Product", NULL);
attr != NULL;
attr = <a href="#ppdFindNextAttr">ppdFindNextAttr</a>(ppd, "Product", NULL))
puts(attr->value);
</pre>

51
cups/array-private.h Normal file
View File

@@ -0,0 +1,51 @@
/*
* "$Id: array-private.h 3448 2011-10-04 06:53:26Z msweet $"
*
* Private array definitions for CUPS.
*
* Copyright 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/".
*
* This file is subject to the Apple OS-Developed Software exception.
*/
#ifndef _CUPS_ARRAY_PRIVATE_H_
# define _CUPS_ARRAY_PRIVATE_H_
/*
* Include necessary headers...
*/
# include <cups/array.h>
/*
* C++ magic...
*/
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/*
* Functions...
*/
extern int _cupsArrayAddStrings(cups_array_t *a, const char *s)
_CUPS_API_1_5;
extern cups_array_t *_cupsArrayNewStrings(const char *s) _CUPS_API_1_5;
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_ARRAY_PRIVATE_H_ */
/*
* End of "$Id: array-private.h 3448 2011-10-04 06:53:26Z msweet $".
*/

1326
cups/array.c Normal file

File diff suppressed because it is too large Load Diff

92
cups/array.h Normal file
View File

@@ -0,0 +1,92 @@
/*
* "$Id: array.h 7266 2008-01-29 02:15:29Z mike $"
*
* Sorted array definitions for CUPS.
*
* 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*/
#ifndef _CUPS_ARRAY_H_
# define _CUPS_ARRAY_H_
/*
* Include necessary headers...
*/
# include "versioning.h"
# include <stdlib.h>
/*
* C++ magic...
*/
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/*
* Types and structures...
*/
typedef struct _cups_array_s cups_array_t;
/**** CUPS array type ****/
typedef int (*cups_array_func_t)(void *first, void *second, void *data);
/**** Array comparison function ****/
typedef int (*cups_ahash_func_t)(void *element, void *data);
/**** Array hash function ****/
typedef void *(*cups_acopy_func_t)(void *element, void *data);
/**** Array element copy function ****/
typedef void (*cups_afree_func_t)(void *element, void *data);
/**** Array element free function ****/
/*
* Functions...
*/
extern int cupsArrayAdd(cups_array_t *a, void *e) _CUPS_API_1_2;
extern void cupsArrayClear(cups_array_t *a) _CUPS_API_1_2;
extern int cupsArrayCount(cups_array_t *a) _CUPS_API_1_2;
extern void *cupsArrayCurrent(cups_array_t *a) _CUPS_API_1_2;
extern void cupsArrayDelete(cups_array_t *a) _CUPS_API_1_2;
extern cups_array_t *cupsArrayDup(cups_array_t *a) _CUPS_API_1_2;
extern void *cupsArrayFind(cups_array_t *a, void *e) _CUPS_API_1_2;
extern void *cupsArrayFirst(cups_array_t *a) _CUPS_API_1_2;
extern int cupsArrayGetIndex(cups_array_t *a) _CUPS_API_1_3;
extern int cupsArrayGetInsert(cups_array_t *a) _CUPS_API_1_3;
extern void *cupsArrayIndex(cups_array_t *a, int n) _CUPS_API_1_2;
extern int cupsArrayInsert(cups_array_t *a, void *e) _CUPS_API_1_2;
extern void *cupsArrayLast(cups_array_t *a) _CUPS_API_1_2;
extern cups_array_t *cupsArrayNew(cups_array_func_t f, void *d) _CUPS_API_1_2;
extern cups_array_t *cupsArrayNew2(cups_array_func_t f, void *d,
cups_ahash_func_t h, int hsize) _CUPS_API_1_3;
extern cups_array_t *cupsArrayNew3(cups_array_func_t f, void *d,
cups_ahash_func_t h, int hsize,
cups_acopy_func_t cf,
cups_afree_func_t ff) _CUPS_API_1_5;
extern void *cupsArrayNext(cups_array_t *a) _CUPS_API_1_2;
extern void *cupsArrayPrev(cups_array_t *a) _CUPS_API_1_2;
extern int cupsArrayRemove(cups_array_t *a, void *e) _CUPS_API_1_2;
extern void *cupsArrayRestore(cups_array_t *a) _CUPS_API_1_2;
extern int cupsArraySave(cups_array_t *a) _CUPS_API_1_2;
extern void *cupsArrayUserData(cups_array_t *a) _CUPS_API_1_2;
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_ARRAY_H_ */
/*
* End of "$Id: array.h 7266 2008-01-29 02:15:29Z mike $".
*/

335
cups/attr.c Normal file
View File

@@ -0,0 +1,335 @@
/*
* "$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 $".
*/

885
cups/auth.c Normal file
View File

@@ -0,0 +1,885 @@
/*
* "$Id: auth.c 7720 2008-07-11 22:46:21Z mike $"
*
* Authentication functions for CUPS.
*
* Copyright 2007-2013 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*
* Contents:
*
* cupsDoAuthentication() - Authenticate a request.
* _cupsSetNegotiateAuthString() - Set the Kerberos authentication string.
* cups_gss_acquire() - Kerberos credentials callback.
* cups_gss_getname() - Get CUPS service credentials for
* authentication.
* cups_gss_printf() - Show debug error messages from GSSAPI.
* cups_local_auth() - Get the local authorization certificate if
* available/applicable.
*/
/*
* Include necessary headers...
*/
#include "cups-private.h"
#include <fcntl.h>
#include <sys/stat.h>
#if defined(WIN32) || defined(__EMX__)
# include <io.h>
#else
# include <unistd.h>
#endif /* WIN32 || __EMX__ */
#if HAVE_AUTHORIZATION_H
# include <Security/Authorization.h>
# ifdef HAVE_SECBASEPRIV_H
# include <Security/SecBasePriv.h>
# else
extern const char *cssmErrorString(int error);
# endif /* HAVE_SECBASEPRIV_H */
#endif /* HAVE_AUTHORIZATION_H */
#if defined(SO_PEERCRED) && defined(AF_LOCAL)
# include <pwd.h>
#endif /* SO_PEERCRED && AF_LOCAL */
/*
* Local functions...
*/
#ifdef HAVE_GSSAPI
# ifdef HAVE_GSS_ACQUIRE_CRED_EX_F
# ifdef HAVE_GSS_GSSAPI_SPI_H
# include <GSS/gssapi_spi.h>
# else
# define GSS_AUTH_IDENTITY_TYPE_1 1
# define gss_acquire_cred_ex_f __ApplePrivate_gss_acquire_cred_ex_f
typedef struct gss_auth_identity
{
uint32_t type;
uint32_t flags;
char *username;
char *realm;
char *password;
gss_buffer_t *credentialsRef;
} gss_auth_identity_desc;
extern OM_uint32 gss_acquire_cred_ex_f(gss_status_id_t, const gss_name_t,
OM_uint32, OM_uint32, const gss_OID,
gss_cred_usage_t, gss_auth_identity_t,
void *, void (*)(void *, OM_uint32,
gss_status_id_t,
gss_cred_id_t,
gss_OID_set,
OM_uint32));
# endif /* HAVE_GSS_GSSAPI_SPI_H */
# include <dispatch/dispatch.h>
typedef struct _cups_gss_acquire_s /* Acquire callback data */
{
dispatch_semaphore_t sem; /* Synchronization semaphore */
OM_uint32 major; /* Returned status code */
gss_cred_id_t creds; /* Returned credentials */
} _cups_gss_acquire_t;
static void cups_gss_acquire(void *ctx, OM_uint32 major,
gss_status_id_t status,
gss_cred_id_t creds, gss_OID_set oids,
OM_uint32 time_rec);
# endif /* HAVE_GSS_ACQUIRE_CRED_EX_F */
static gss_name_t cups_gss_getname(http_t *http, const char *service_name);
# ifdef DEBUG
static void cups_gss_printf(OM_uint32 major_status, OM_uint32 minor_status,
const char *message);
# else
# define cups_gss_printf(major, minor, message)
# endif /* DEBUG */
#endif /* HAVE_GSSAPI */
static int cups_local_auth(http_t *http);
/*
* 'cupsDoAuthentication()' - Authenticate a request.
*
* This function should be called in response to a @code HTTP_UNAUTHORIZED@
* status, prior to resubmitting your request.
*
* @since CUPS 1.1.20/OS X 10.4@
*/
int /* O - 0 on success, -1 on error */
cupsDoAuthentication(
http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
const char *method, /* I - Request method ("GET", "POST", "PUT") */
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 */
int localauth; /* Local authentication result */
_cups_globals_t *cg; /* Global data */
DEBUG_printf(("cupsDoAuthentication(http=%p, method=\"%s\", resource=\"%s\")",
http, method, resource));
if (!http)
http = _cupsConnect();
if (!http || !method || !resource)
return (-1);
DEBUG_printf(("2cupsDoAuthentication: digest_tries=%d, userpass=\"%s\"",
http->digest_tries, http->userpass));
DEBUG_printf(("2cupsDoAuthentication: WWW-Authenticate=\"%s\"",
httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE)));
/*
* Clear the current authentication string...
*/
httpSetAuthString(http, NULL, NULL);
/*
* See if we can do local authentication...
*/
if (http->digest_tries < 3)
{
if ((localauth = cups_local_auth(http)) == 0)
{
DEBUG_printf(("2cupsDoAuthentication: authstring=\"%s\"",
http->authstring));
if (http->status == HTTP_UNAUTHORIZED)
http->digest_tries ++;
return (0);
}
else if (localauth == -1)
{
http->status = HTTP_AUTHORIZATION_CANCELED;
return (-1); /* Error or canceled */
}
}
/*
* Nope, see if we should retry the current username:password...
*/
www_auth = http->fields[HTTP_FIELD_WWW_AUTHENTICATE];
if ((http->digest_tries > 1 || !http->userpass[0]) &&
(!_cups_strncasecmp(www_auth, "Basic", 5) ||
!_cups_strncasecmp(www_auth, "Digest", 6)))
{
/*
* Nope - get a new password from the user...
*/
cg = _cupsGlobals();
if (!cg->lang_default)
cg->lang_default = cupsLangDefault();
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_AUTHORIZATION_CANCELED;
return (-1);
}
snprintf(http->userpass, sizeof(http->userpass), "%s:%s", cupsUser(),
password);
}
else if (http->status == HTTP_UNAUTHORIZED)
http->digest_tries ++;
if (http->status == HTTP_UNAUTHORIZED && http->digest_tries >= 3)
{
DEBUG_printf(("1cupsDoAuthentication: Too many authentication tries (%d)",
http->digest_tries));
http->status = HTTP_AUTHORIZATION_CANCELED;
return (-1);
}
/*
* Got a password; encode it for the server...
*/
#ifdef HAVE_GSSAPI
if (!_cups_strncasecmp(www_auth, "Negotiate", 9))
{
/*
* Kerberos authentication...
*/
if (_cupsSetNegotiateAuthString(http, method, resource))
{
http->status = HTTP_AUTHORIZATION_CANCELED;
return (-1);
}
}
else
#endif /* HAVE_GSSAPI */
if (!_cups_strncasecmp(www_auth, "Basic", 5))
{
/*
* Basic authentication...
*/
char encode[256]; /* Base64 buffer */
httpEncode64_2(encode, sizeof(encode), http->userpass,
(int)strlen(http->userpass));
httpSetAuthString(http, "Basic", encode);
}
else if (!_cups_strncasecmp(www_auth, "Digest", 6))
{
/*
* Digest authentication...
*/
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);
}
else
{
DEBUG_printf(("1cupsDoAuthentication: Unknown auth type: \"%s\"",
www_auth));
http->status = HTTP_AUTHORIZATION_CANCELED;
return (-1);
}
DEBUG_printf(("1cupsDoAuthentication: authstring=\"%s\"", http->authstring));
return (0);
}
#ifdef HAVE_GSSAPI
/*
* '_cupsSetNegotiateAuthString()' - Set the Kerberos authentication string.
*/
int /* O - 0 on success, -1 on error */
_cupsSetNegotiateAuthString(
http_t *http, /* I - Connection to server */
const char *method, /* I - Request method ("GET", "POST", "PUT") */
const char *resource) /* I - Resource path */
{
OM_uint32 minor_status, /* Minor status code */
major_status; /* Major status code */
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
/* Output token */
(void)method;
(void)resource;
# ifdef __APPLE__
/*
* If the weak-linked GSSAPI/Kerberos library is not present, don't try
* to use it...
*/
if (gss_init_sec_context == NULL)
{
DEBUG_puts("1_cupsSetNegotiateAuthString: Weak-linked GSSAPI/Kerberos "
"framework is not present");
return (-1);
}
# endif /* __APPLE__ */
if (http->gssname == GSS_C_NO_NAME)
{
http->gssname = cups_gss_getname(http, _cupsGSSServiceName());
}
if (http->gssctx != GSS_C_NO_CONTEXT)
{
gss_delete_sec_context(&minor_status, &http->gssctx, GSS_C_NO_BUFFER);
http->gssctx = GSS_C_NO_CONTEXT;
}
major_status = gss_init_sec_context(&minor_status, GSS_C_NO_CREDENTIAL,
&http->gssctx,
http->gssname, http->gssmech,
GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG,
GSS_C_INDEFINITE,
GSS_C_NO_CHANNEL_BINDINGS,
GSS_C_NO_BUFFER, &http->gssmech,
&output_token, NULL, NULL);
#ifdef HAVE_GSS_ACQUIRE_CRED_EX_F
if (major_status == GSS_S_NO_CRED)
{
/*
* Ask the user for credentials...
*/
char prompt[1024], /* Prompt for user */
userbuf[256]; /* Kerberos username */
const char *username, /* Username string */
*password; /* Password string */
_cups_gss_acquire_t data; /* Callback data */
gss_auth_identity_desc identity; /* Kerberos user identity */
_cups_globals_t *cg = _cupsGlobals();
/* Per-thread global data */
if (!cg->lang_default)
cg->lang_default = cupsLangDefault();
snprintf(prompt, sizeof(prompt),
_cupsLangString(cg->lang_default, _("Password for %s on %s? ")),
cupsUser(), http->gsshost);
if ((password = cupsGetPassword2(prompt, http, method, resource)) == NULL)
return (-1);
/*
* Try to acquire credentials...
*/
username = cupsUser();
if (!strchr(username, '@'))
{
snprintf(userbuf, sizeof(userbuf), "%s@%s", username, http->gsshost);
username = userbuf;
}
identity.type = GSS_AUTH_IDENTITY_TYPE_1;
identity.flags = 0;
identity.username = (char *)username;
identity.realm = (char *)"";
identity.password = (char *)password;
identity.credentialsRef = NULL;
data.sem = dispatch_semaphore_create(0);
data.major = 0;
data.creds = NULL;
if (data.sem)
{
major_status = gss_acquire_cred_ex_f(NULL, GSS_C_NO_NAME, 0,
GSS_C_INDEFINITE, GSS_KRB5_MECHANISM,
GSS_C_INITIATE, &identity, &data,
cups_gss_acquire);
if (major_status == GSS_S_COMPLETE)
{
dispatch_semaphore_wait(data.sem, DISPATCH_TIME_FOREVER);
major_status = data.major;
}
dispatch_release(data.sem);
if (major_status == GSS_S_COMPLETE)
{
OM_uint32 release_minor; /* Minor status from releasing creds */
major_status = gss_init_sec_context(&minor_status, data.creds,
&http->gssctx,
http->gssname, http->gssmech,
GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG,
GSS_C_INDEFINITE,
GSS_C_NO_CHANNEL_BINDINGS,
GSS_C_NO_BUFFER, &http->gssmech,
&output_token, NULL, NULL);
gss_release_cred(&release_minor, &data.creds);
}
}
}
#endif /* HAVE_GSS_ACQUIRED_CRED_EX_F */
if (GSS_ERROR(major_status))
{
cups_gss_printf(major_status, minor_status,
"_cupsSetNegotiateAuthString: Unable to initialize "
"security context");
return (-1);
}
#ifdef DEBUG
else if (major_status == GSS_S_CONTINUE_NEEDED)
cups_gss_printf(major_status, minor_status,
"_cupsSetNegotiateAuthString: Continuation needed!");
#endif /* DEBUG */
if (output_token.length > 0 && output_token.length <= 65536)
{
/*
* Allocate the authorization string since Windows KDCs can have
* arbitrarily large credentials...
*/
int authsize = 10 + /* "Negotiate " */
output_token.length * 4 / 3 + 1 + /* Base64 */
1; /* nul */
httpSetAuthString(http, NULL, NULL);
if ((http->authstring = malloc(authsize)) == NULL)
{
http->authstring = http->_authstring;
authsize = sizeof(http->_authstring);
}
strcpy(http->authstring, "Negotiate ");
httpEncode64_2(http->authstring + 10, authsize - 10, output_token.value,
output_token.length);
gss_release_buffer(&minor_status, &output_token);
}
else
{
DEBUG_printf(("1_cupsSetNegotiateAuthString: Kerberos credentials too "
"large - %d bytes!", (int)output_token.length));
gss_release_buffer(&minor_status, &output_token);
return (-1);
}
return (0);
}
# ifdef HAVE_GSS_ACQUIRE_CRED_EX_F
/*
* 'cups_gss_acquire()' - Kerberos credentials callback.
*/
static void
cups_gss_acquire(
void *ctx, /* I - Caller context */
OM_uint32 major, /* I - Major error code */
gss_status_id_t status, /* I - Status (unused) */
gss_cred_id_t creds, /* I - Credentials (if any) */
gss_OID_set oids, /* I - Mechanism OIDs (unused) */
OM_uint32 time_rec) /* I - Timestamp (unused) */
{
uint32_t min; /* Minor error code */
_cups_gss_acquire_t *data; /* Callback data */
(void)status;
(void)time_rec;
data = (_cups_gss_acquire_t *)ctx;
data->major = major;
data->creds = creds;
gss_release_oid_set(&min, &oids);
dispatch_semaphore_signal(data->sem);
}
# endif /* HAVE_GSS_ACQUIRE_CRED_EX_F */
/*
* 'cups_gss_getname()' - Get CUPS service credentials for authentication.
*/
static gss_name_t /* O - Server name */
cups_gss_getname(
http_t *http, /* I - Connection to server */
const char *service_name) /* I - Service name */
{
gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
/* Service token */
OM_uint32 major_status, /* Major status code */
minor_status; /* Minor status code */
gss_name_t server_name; /* Server name */
char buf[1024]; /* Name buffer */
DEBUG_printf(("7cups_gss_getname(http=%p, service_name=\"%s\")", http,
service_name));
/*
* Get the hostname...
*/
if (!http->gsshost[0])
{
httpGetHostname(http, http->gsshost, sizeof(http->gsshost));
if (!strcmp(http->gsshost, "localhost"))
{
if (gethostname(http->gsshost, sizeof(http->gsshost)) < 0)
{
DEBUG_printf(("1cups_gss_getname: gethostname() failed: %s",
strerror(errno)));
http->gsshost[0] = '\0';
return (NULL);
}
if (!strchr(http->gsshost, '.'))
{
/*
* The hostname is not a FQDN, so look it up...
*/
struct hostent *host; /* Host entry to get FQDN */
if ((host = gethostbyname(http->gsshost)) != NULL && host->h_name)
{
/*
* Use the resolved hostname...
*/
strlcpy(http->gsshost, host->h_name, sizeof(http->gsshost));
}
else
{
DEBUG_printf(("1cups_gss_getname: gethostbyname(\"%s\") failed.",
http->gsshost));
http->gsshost[0] = '\0';
return (NULL);
}
}
}
}
/*
* Get a service name we can use for authentication purposes...
*/
snprintf(buf, sizeof(buf), "%s@%s", service_name, http->gsshost);
DEBUG_printf(("8cups_gss_getname: Looking up \"%s\".", buf));
token.value = buf;
token.length = strlen(buf);
server_name = GSS_C_NO_NAME;
major_status = gss_import_name(&minor_status, &token,
GSS_C_NT_HOSTBASED_SERVICE,
&server_name);
if (GSS_ERROR(major_status))
{
cups_gss_printf(major_status, minor_status,
"cups_gss_getname: gss_import_name() failed");
return (NULL);
}
return (server_name);
}
# ifdef DEBUG
/*
* 'cups_gss_printf()' - Show debug error messages from GSSAPI.
*/
static void
cups_gss_printf(OM_uint32 major_status,/* I - Major status code */
OM_uint32 minor_status,/* I - Minor status code */
const char *message) /* I - Prefix for error message */
{
OM_uint32 err_major_status, /* Major status code for display */
err_minor_status; /* Minor status code for display */
OM_uint32 msg_ctx; /* Message context */
gss_buffer_desc major_status_string = GSS_C_EMPTY_BUFFER,
/* Major status message */
minor_status_string = GSS_C_EMPTY_BUFFER;
/* Minor status message */
msg_ctx = 0;
err_major_status = gss_display_status(&err_minor_status,
major_status,
GSS_C_GSS_CODE,
GSS_C_NO_OID,
&msg_ctx,
&major_status_string);
if (!GSS_ERROR(err_major_status))
gss_display_status(&err_minor_status, minor_status, GSS_C_MECH_CODE,
GSS_C_NULL_OID, &msg_ctx, &minor_status_string);
DEBUG_printf(("1%s: %s, %s", message, (char *)major_status_string.value,
(char *)minor_status_string.value));
gss_release_buffer(&err_minor_status, &major_status_string);
gss_release_buffer(&err_minor_status, &minor_status_string);
}
# endif /* DEBUG */
#endif /* HAVE_GSSAPI */
/*
* 'cups_local_auth()' - Get the local authorization certificate if
* available/applicable.
*/
static int /* O - 0 if available */
/* 1 if not available */
/* -1 error */
cups_local_auth(http_t *http) /* I - HTTP connection to server */
{
#if defined(WIN32) || defined(__EMX__)
/*
* Currently WIN32 and OS-2 do not support the CUPS server...
*/
return (1);
#else
int pid; /* Current process ID */
FILE *fp; /* Certificate file */
char trc[16], /* Try Root Certificate parameter */
filename[1024]; /* Certificate filename */
_cups_globals_t *cg = _cupsGlobals(); /* Global data */
# if defined(HAVE_AUTHORIZATION_H)
OSStatus status; /* Status */
AuthorizationItem auth_right; /* Authorization right */
AuthorizationRights auth_rights; /* Authorization rights */
AuthorizationFlags auth_flags; /* Authorization flags */
AuthorizationExternalForm auth_extrn; /* Authorization ref external */
char auth_key[1024]; /* Buffer */
char buffer[1024]; /* Buffer */
# endif /* HAVE_AUTHORIZATION_H */
DEBUG_printf(("7cups_local_auth(http=%p) hostaddr=%s, hostname=\"%s\"",
http, httpAddrString(http->hostaddr, filename, sizeof(filename)), http->hostname));
/*
* See if we are accessing localhost...
*/
if (!httpAddrLocalhost(http->hostaddr) &&
_cups_strcasecmp(http->hostname, "localhost") != 0)
{
DEBUG_puts("8cups_local_auth: Not a local connection!");
return (1);
}
# if defined(HAVE_AUTHORIZATION_H)
/*
* Delete any previous authorization reference...
*/
if (http->auth_ref)
{
AuthorizationFree(http->auth_ref, kAuthorizationFlagDefaults);
http->auth_ref = NULL;
}
if (!getenv("GATEWAY_INTERFACE") &&
httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "authkey",
auth_key, sizeof(auth_key)))
{
status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment,
kAuthorizationFlagDefaults, &http->auth_ref);
if (status != errAuthorizationSuccess)
{
DEBUG_printf(("8cups_local_auth: AuthorizationCreate() returned %d (%s)",
(int)status, cssmErrorString(status)));
return (-1);
}
auth_right.name = auth_key;
auth_right.valueLength = 0;
auth_right.value = NULL;
auth_right.flags = 0;
auth_rights.count = 1;
auth_rights.items = &auth_right;
auth_flags = kAuthorizationFlagDefaults |
kAuthorizationFlagPreAuthorize |
kAuthorizationFlagInteractionAllowed |
kAuthorizationFlagExtendRights;
status = AuthorizationCopyRights(http->auth_ref, &auth_rights,
kAuthorizationEmptyEnvironment,
auth_flags, NULL);
if (status == errAuthorizationSuccess)
status = AuthorizationMakeExternalForm(http->auth_ref, &auth_extrn);
if (status == errAuthorizationSuccess)
{
/*
* Set the authorization string and return...
*/
httpEncode64_2(buffer, sizeof(buffer), (void *)&auth_extrn,
sizeof(auth_extrn));
httpSetAuthString(http, "AuthRef", buffer);
DEBUG_printf(("8cups_local_auth: Returning authstring=\"%s\"",
http->authstring));
return (0);
}
else if (status == errAuthorizationCanceled)
return (-1);
DEBUG_printf(("9cups_local_auth: AuthorizationCopyRights() returned %d (%s)",
(int)status, cssmErrorString(status)));
/*
* Fall through to try certificates...
*/
}
# endif /* HAVE_AUTHORIZATION_H */
# if defined(SO_PEERCRED) && defined(AF_LOCAL)
/*
* See if we can authenticate using the peer credentials provided over a
* domain socket; if so, specify "PeerCred username" as the authentication
* information...
*/
if (
# ifdef HAVE_GSSAPI
strncmp(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... */
{
/*
* Verify that the current cupsUser() matches the current UID...
*/
struct passwd *pwd; /* Password information */
const char *username; /* Current username */
username = cupsUser();
if ((pwd = getpwnam(username)) != NULL && pwd->pw_uid == getuid())
{
httpSetAuthString(http, "PeerCred", username);
DEBUG_printf(("8cups_local_auth: Returning authstring=\"%s\"",
http->authstring));
return (0);
}
}
# endif /* SO_PEERCRED && AF_LOCAL */
/*
* Try opening a certificate file for this PID. If that fails,
* try the root certificate...
*/
pid = getpid();
snprintf(filename, sizeof(filename), "%s/certs/%d", cg->cups_statedir, pid);
if ((fp = fopen(filename, "r")) == NULL && pid > 0)
{
/*
* 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)));
# ifdef HAVE_GSSAPI
if (!strncmp(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)))
{
/*
* Scheduler doesn't want us to use the root certificate...
*/
return (1);
}
snprintf(filename, sizeof(filename), "%s/certs/0", cg->cups_statedir);
fp = fopen(filename, "r");
}
if (fp)
{
/*
* Read the certificate from the file...
*/
char certificate[33], /* Certificate string */
*certptr; /* Pointer to certificate string */
certptr = fgets(certificate, sizeof(certificate), fp);
fclose(fp);
if (certptr)
{
/*
* Set the authorization string and return...
*/
httpSetAuthString(http, "Local", certificate);
DEBUG_printf(("8cups_local_auth: Returning authstring=\"%s\"",
http->authstring));
return (0);
}
}
return (1);
#endif /* WIN32 || __EMX__ */
}
/*
* End of "$Id: auth.c 7720 2008-07-11 22:46:21Z mike $".
*/

199
cups/backchannel.c Normal file
View File

@@ -0,0 +1,199 @@
/*
* "$Id: backchannel.c 7616 2008-05-28 00:34:13Z mike $"
*
* Backchannel functions for CUPS.
*
* Copyright 2007-2012 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*
* Contents:
*
* cupsBackChannelRead() - Read data from the backchannel.
* cupsBackChannelWrite() - Write data to the backchannel.
* cups_setup() - Setup select()
*/
/*
* Include necessary headers...
*/
#include "cups.h"
#include <errno.h>
#ifdef WIN32
# include <io.h>
# include <fcntl.h>
#else
# include <sys/time.h>
#endif /* WIN32 */
/*
* Local functions...
*/
static void cups_setup(fd_set *set, struct timeval *tval,
double timeout);
/*
* 'cupsBackChannelRead()' - Read data from the backchannel.
*
* Reads up to "bytes" bytes from the backchannel/backend. The "timeout"
* parameter controls how many seconds to wait for the data - use 0.0 to
* return immediately if there is no data, -1.0 to wait for data indefinitely.
*
* @since CUPS 1.2/OS X 10.5@
*/
ssize_t /* O - Bytes read or -1 on error */
cupsBackChannelRead(char *buffer, /* I - Buffer to read into */
size_t bytes, /* I - Bytes to read */
double timeout) /* I - Timeout in seconds, typically 0.0 to poll */
{
fd_set input; /* Input set */
struct timeval tval; /* Timeout value */
int status; /* Select status */
/*
* Wait for input ready.
*/
do
{
cups_setup(&input, &tval, timeout);
if (timeout < 0.0)
status = select(4, &input, NULL, NULL, NULL);
else
status = select(4, &input, NULL, NULL, &tval);
}
while (status < 0 && errno != EINTR && errno != EAGAIN);
if (status < 0)
return (-1); /* Timeout! */
/*
* Read bytes from the pipe...
*/
#ifdef WIN32
return ((ssize_t)_read(3, buffer, (unsigned)bytes));
#else
return (read(3, buffer, bytes));
#endif /* WIN32 */
}
/*
* 'cupsBackChannelWrite()' - Write data to the backchannel.
*
* Writes "bytes" bytes to the backchannel/filter. The "timeout" parameter
* controls how many seconds to wait for the data to be written - use
* 0.0 to return immediately if the data cannot be written, -1.0 to wait
* indefinitely.
*
* @since CUPS 1.2/OS X 10.5@
*/
ssize_t /* O - Bytes written or -1 on error */
cupsBackChannelWrite(
const char *buffer, /* I - Buffer to write */
size_t bytes, /* I - Bytes to write */
double timeout) /* I - Timeout in seconds, typically 1.0 */
{
fd_set output; /* Output set */
struct timeval tval; /* Timeout value */
int status; /* Select status */
ssize_t count; /* Current bytes */
size_t total; /* Total bytes */
/*
* Write all bytes...
*/
total = 0;
while (total < bytes)
{
/*
* Wait for write-ready...
*/
do
{
cups_setup(&output, &tval, timeout);
if (timeout < 0.0)
status = select(4, NULL, &output, NULL, NULL);
else
status = select(4, NULL, &output, NULL, &tval);
}
while (status < 0 && errno != EINTR && errno != EAGAIN);
if (status <= 0)
return (-1); /* Timeout! */
/*
* Write bytes to the pipe...
*/
#ifdef WIN32
count = (ssize_t)_write(3, buffer, (unsigned)(bytes - total));
#else
count = write(3, buffer, bytes - total);
#endif /* WIN32 */
if (count < 0)
{
/*
* Write error - abort on fatal errors...
*/
if (errno != EINTR && errno != EAGAIN)
return (-1);
}
else
{
/*
* Write succeeded, update buffer pointer and total count...
*/
buffer += count;
total += count;
}
}
return ((ssize_t)bytes);
}
/*
* 'cups_setup()' - Setup select()
*/
static void
cups_setup(fd_set *set, /* I - Set for select() */
struct timeval *tval, /* I - Timer value */
double timeout) /* I - Timeout in seconds */
{
tval->tv_sec = (int)timeout;
tval->tv_usec = (int)(1000000.0 * (timeout - tval->tv_sec));
FD_ZERO(set);
FD_SET(3, set);
}
/*
* End of "$Id: backchannel.c 7616 2008-05-28 00:34:13Z mike $".
*/

154
cups/backend.c Normal file
View File

@@ -0,0 +1,154 @@
/*
* "$Id: backend.c 7810 2008-07-29 01:11:15Z mike $"
*
* Backend functions for CUPS.
*
* Copyright 2007-2012 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*
* Contents:
*
* cupsBackendDeviceURI() - Get the device URI for a backend.
* cupsBackendReport() - Write a device line from a backend.
* quote_string() - Write a quoted string to stdout, escaping \ and ".
*/
/*
* Include necessary headers...
*/
#include "cups-private.h"
#include "backend.h"
/*
* Local functions...
*/
static void quote_string(const char *s);
/*
* 'cupsBackendDeviceURI()' - Get the device URI for a backend.
*
* The "argv" argument is the argv argument passed to main(). This
* function returns the device URI passed in the DEVICE_URI environment
* variable or the device URI passed in argv[0], whichever is found
* first.
*
* @since CUPS 1.2/OS X 10.5@
*/
const char * /* O - Device URI or @code NULL@ */
cupsBackendDeviceURI(char **argv) /* I - Command-line arguments */
{
const char *device_uri, /* Device URI */
*auth_info_required; /* AUTH_INFO_REQUIRED env var */
_cups_globals_t *cg = _cupsGlobals(); /* Global info */
int options; /* Resolve options */
ppd_file_t *ppd; /* PPD file */
ppd_attr_t *ppdattr; /* PPD attribute */
if ((device_uri = getenv("DEVICE_URI")) == NULL)
{
if (!argv || !argv[0] || !strchr(argv[0], ':'))
return (NULL);
device_uri = argv[0];
}
options = _HTTP_RESOLVE_STDERR;
if ((auth_info_required = getenv("AUTH_INFO_REQUIRED")) != NULL &&
!strcmp(auth_info_required, "negotiate"))
options |= _HTTP_RESOLVE_FQDN;
if ((ppd = ppdOpenFile(getenv("PPD"))) != NULL)
{
if ((ppdattr = ppdFindAttr(ppd, "cupsIPPFaxOut", NULL)) != NULL &&
!_cups_strcasecmp(ppdattr->value, "true"))
options |= _HTTP_RESOLVE_FAXOUT;
ppdClose(ppd);
}
return (_httpResolveURI(device_uri, cg->resolved_uri,
sizeof(cg->resolved_uri), options, NULL, NULL));
}
/*
* 'cupsBackendReport()' - Write a device line from a backend.
*
* This function writes a single device line to stdout for a backend.
* It handles quoting of special characters in the device-make-and-model,
* device-info, device-id, and device-location strings.
*
* @since CUPS 1.4/OS X 10.6@
*/
void
cupsBackendReport(
const char *device_scheme, /* I - device-scheme string */
const char *device_uri, /* I - device-uri string */
const char *device_make_and_model, /* I - device-make-and-model string or @code NULL@ */
const char *device_info, /* I - device-info string or @code NULL@ */
const char *device_id, /* I - device-id string or @code NULL@ */
const char *device_location) /* I - device-location string or @code NULL@ */
{
if (!device_scheme || !device_uri)
return;
printf("%s %s", device_scheme, device_uri);
if (device_make_and_model && *device_make_and_model)
quote_string(device_make_and_model);
else
quote_string("unknown");
quote_string(device_info);
quote_string(device_id);
quote_string(device_location);
putchar('\n');
fflush(stdout);
}
/*
* 'quote_string()' - Write a quoted string to stdout, escaping \ and ".
*/
static void
quote_string(const char *s) /* I - String to write */
{
fputs(" \"", stdout);
if (s)
{
while (*s)
{
if (*s == '\\' || *s == '\"')
putchar('\\');
if (((*s & 255) < ' ' && *s != '\t') || *s == 0x7f)
putchar(' ');
else
putchar(*s);
s ++;
}
}
putchar('\"');
}
/*
* End of "$Id: backend.c 7810 2008-07-29 01:11:15Z mike $".
*/

78
cups/backend.h Normal file
View File

@@ -0,0 +1,78 @@
/*
* "$Id: backend.h 7810 2008-07-29 01:11:15Z mike $"
*
* Backend definitions for CUPS.
*
* 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*/
#ifndef _CUPS_BACKEND_H_
# define _CUPS_BACKEND_H_
/*
* Include necessary headers...
*/
# include "versioning.h"
/*
* C++ magic...
*/
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/*
* Constants...
*/
enum cups_backend_e /**** Backend exit codes ****/
{
CUPS_BACKEND_OK = 0, /* Job completed successfully */
CUPS_BACKEND_FAILED = 1, /* Job failed, use error-policy */
CUPS_BACKEND_AUTH_REQUIRED = 2, /* Job failed, authentication required */
CUPS_BACKEND_HOLD = 3, /* Job failed, hold job */
CUPS_BACKEND_STOP = 4, /* Job failed, stop queue */
CUPS_BACKEND_CANCEL = 5, /* Job failed, cancel job */
CUPS_BACKEND_RETRY = 6, /* Job failed, retry this job later */
CUPS_BACKEND_RETRY_CURRENT = 7 /* Job failed, retry this job immediately */
};
typedef enum cups_backend_e cups_backend_t;
/**** Backend exit codes ****/
/*
* Prototypes...
*/
extern const char *cupsBackendDeviceURI(char **argv) _CUPS_API_1_2;
extern void cupsBackendReport(const char *device_scheme,
const char *device_uri,
const char *device_make_and_model,
const char *device_info,
const char *device_id,
const char *device_location)
_CUPS_API_1_4;
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_BACKEND_H_ */
/*
* End of "$Id: backend.h 7810 2008-07-29 01:11:15Z mike $".
*/

1214
cups/conflicts.c Normal file

File diff suppressed because it is too large Load Diff

272
cups/cups-private.h Normal file
View File

@@ -0,0 +1,272 @@
/*
* "$Id: cups-private.h 9596 2011-03-11 18:26:36Z mike $"
*
* Private definitions for CUPS.
*
* Copyright 2007-2013 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/".
*
* This file is subject to the Apple OS-Developed Software exception.
*/
#ifndef _CUPS_CUPS_PRIVATE_H_
# define _CUPS_CUPS_PRIVATE_H_
/*
* Include necessary headers...
*/
# include "string-private.h"
# include "debug-private.h"
# include "ipp-private.h"
# include "http-private.h"
# include "language-private.h"
# include "pwg-private.h"
# include "ppd-private.h"
# include "thread-private.h"
# include <cups/cups.h>
# ifdef __APPLE__
# include <sys/cdefs.h>
# include <CoreFoundation/CoreFoundation.h>
# endif /* __APPLE__ */
/*
* C++ magic...
*/
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/*
* Types...
*/
typedef struct _cups_buffer_s /**** Read/write buffer ****/
{
struct _cups_buffer_s *next; /* Next buffer in list */
size_t size; /* Size of buffer */
char used, /* Is this buffer used? */
d[1]; /* Data buffer */
} _cups_buffer_t;
typedef struct _cups_globals_s /**** CUPS global state data ****/
{
/* Multiple places... */
const char *cups_datadir, /* CUPS_DATADIR environment var */
*cups_serverbin,/* CUPS_SERVERBIN environment var */
*cups_serverroot,
/* CUPS_SERVERROOT environment var */
*cups_statedir, /* CUPS_STATEDIR environment var */
*localedir; /* LOCALDIR environment var */
/* adminutil.c */
time_t cupsd_update; /* Last time we got or set cupsd.conf */
char cupsd_hostname[HTTP_MAX_HOST];
/* Hostname for connection */
int cupsd_num_settings;
/* Number of server settings */
cups_option_t *cupsd_settings;/* Server settings */
/* auth.c */
# ifdef HAVE_GSSAPI
char gss_service_name[32];
/* Kerberos service name */
# endif /* HAVE_GSSAPI */
/* backend.c */
char resolved_uri[1024];
/* Buffer for cupsBackendDeviceURI */
/* file.c */
cups_file_t *stdio_files[3];/* stdin, stdout, stderr */
/* http.c */
char http_date[256]; /* Date+time buffer */
/* http-addr.c */
unsigned ip_addr; /* Packed IPv4 address */
char *ip_ptrs[2]; /* Pointer to packed address */
struct hostent hostent; /* Host entry for IP address */
# ifdef HAVE_GETADDRINFO
char hostname[1024]; /* Hostname */
# endif /* HAVE_GETADDRINFO */
int need_res_init; /* Need to reinitialize resolver? */
/* ipp.c */
ipp_uchar_t ipp_date[11]; /* RFC-1903 date/time data */
_cups_buffer_t *cups_buffers; /* Buffer list */
/* ipp-support.c */
int ipp_port; /* IPP port number */
char ipp_unknown[255];
/* Unknown error statuses */
/* language.c */
cups_lang_t *lang_default; /* Default language */
# ifdef __APPLE__
char language[32]; /* Cached language */
# endif /* __APPLE__ */
/* ppd.c */
ppd_status_t ppd_status; /* Status of last ppdOpen*() */
int ppd_line; /* Current line number */
ppd_conform_t ppd_conform; /* Level of conformance required */
/* pwg-media.c */
cups_array_t *leg_size_lut, /* Lookup table for legacy names */
*ppd_size_lut, /* Lookup table for PPD names */
*pwg_size_lut; /* Lookup table for PWG names */
_pwg_media_t pwg_media; /* PWG media data for custom size */
char pwg_name[65]; /* PWG media name for custom size */
/* request.c */
http_t *http; /* Current server connection */
ipp_status_t last_error; /* Last IPP error */
char *last_status_message;
/* Last IPP status-message */
/* snmp.c */
char snmp_community[255];
/* Default SNMP community name */
int snmp_debug; /* Log SNMP IO to stderr? */
/* tempfile.c */
char tempfile[1024]; /* cupsTempFd/File buffer */
/* usersys.c */
http_encryption_t encryption; /* Encryption setting */
char user[65], /* User name */
server[256], /* Server address */
servername[256],/* Server hostname */
password[128]; /* Password for default callback */
cups_password_cb2_t password_cb; /* Password callback */
void *password_data; /* Password user data */
http_tls_credentials_t tls_credentials;
/* Default client credentials */
cups_client_cert_cb_t client_cert_cb; /* Client certificate callback */
void *client_cert_data;
/* Client certificate user data */
cups_server_cert_cb_t server_cert_cb; /* Server certificate callback */
void *server_cert_data;
/* Server certificate user data */
int server_version, /* Server IPP version */
any_root, /* Allow any root */
expired_certs, /* Allow expired certs */
expired_root; /* Allow expired root */
/* util.c */
char def_printer[256];
/* Default printer */
char ppd_filename[HTTP_MAX_URI];
/* PPD filename */
} _cups_globals_t;
typedef struct _cups_media_db_s /* Media database */
{
char *color, /* Media color, if any */
*key, /* Media key, if any */
*info, /* Media human-readable name, if any */
*size_name, /* Media PWG size name, if provided */
*source, /* Media source, if any */
*type; /* Media type, if any */
int width, /* Width in hundredths of millimeters */
length, /* Length in hundredths of
* millimeters */
bottom, /* Bottom margin in hundredths of
* millimeters */
left, /* Left margin in hundredths of
* millimeters */
right, /* Right margin in hundredths of
* millimeters */
top; /* Top margin in hundredths of
* millimeters */
} _cups_media_db_t;
typedef struct _cups_dconstres_s /* Constraint/resolver */
{
char *name; /* Name of resolver */
ipp_t *collection; /* Collection containing attrs */
} _cups_dconstres_t;
struct _cups_dinfo_s /* Destination capability and status
* information */
{
const char *uri; /* Printer URI */
char *resource; /* Resource path */
ipp_t *attrs; /* Printer attributes */
int num_defaults; /* Number of default options */
cups_option_t *defaults; /* Default options */
cups_array_t *constraints; /* Job constraints */
cups_array_t *resolvers; /* Job resolvers */
cups_array_t *localizations; /* Localization information */
cups_array_t *media_db; /* Media database */
_cups_media_db_t min_size, /* Minimum size */
max_size; /* Maximum size */
};
/*
* Prototypes...
*/
# 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);
# endif /* __APPLE__ */
extern char *_cupsBufferGet(size_t size);
extern void _cupsBufferRelease(char *b);
extern http_t *_cupsConnect(void);
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);
# ifdef HAVE_GSSAPI
extern const char *_cupsGSSServiceName(void);
# 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);
# ifdef HAVE_GSSAPI
extern int _cupsSetNegotiateAuthString(http_t *http,
const char *method,
const char *resource);
# endif /* HAVE_GSSAPI */
extern char *_cupsUserDefault(char *name, size_t namesize);
/*
* C++ magic...
*/
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_CUPS_PRIVATE_H_ */
/*
* End of "$Id: cups-private.h 9596 2011-03-11 18:26:36Z mike $".
*/

601
cups/cups.h Normal file
View File

@@ -0,0 +1,601 @@
/*
* "$Id: cups.h 8781 2009-08-28 17:34:54Z mike $"
*
* API definitions for CUPS.
*
* Copyright 2007-2013 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*/
#ifndef _CUPS_CUPS_H_
# define _CUPS_CUPS_H_
/*
* Include necessary headers...
*/
# include <sys/types.h>
# if defined(WIN32) && !defined(__CUPS_SSIZE_T_DEFINED)
# define __CUPS_SSIZE_T_DEFINED
# include <stddef.h>
/* 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 */
# ifdef __BLOCKS__
# include <dispatch/dispatch.h>
# endif /* __BLOCKS__ */
# include "file.h"
# include "ipp.h"
# include "language.h"
/*
* C++ magic...
*/
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/*
* Constants...
*/
# define CUPS_VERSION 1.0603
# define CUPS_VERSION_MAJOR 1
# define CUPS_VERSION_MINOR 6
# define CUPS_VERSION_PATCH 3
# define CUPS_BC_FD 3
/* Back-channel file descriptor for
* select/poll */
# define CUPS_DATE_ANY (time_t)-1
# define CUPS_EXCLUDE_NONE (const char *)0
# define CUPS_FORMAT_AUTO "application/octet-stream"
# define CUPS_FORMAT_COMMAND "application/vnd.cups-command"
# define CUPS_FORMAT_JPEG "image/jpeg"
# define CUPS_FORMAT_PDF "application/pdf"
# define CUPS_FORMAT_POSTSCRIPT "application/postscript"
# define CUPS_FORMAT_RAW "application/vnd.cups-raw"
# define CUPS_FORMAT_TEXT "text/plain"
# define CUPS_HTTP_DEFAULT (http_t *)0
# define CUPS_INCLUDE_ALL (const char *)0
# define CUPS_JOBID_ALL -1
# define CUPS_JOBID_CURRENT 0
# define CUPS_LENGTH_VARIABLE (ssize_t)0
# define CUPS_TIMEOUT_DEFAULT 0
# define CUPS_WHICHJOBS_ALL -1
# define CUPS_WHICHJOBS_ACTIVE 0
# define CUPS_WHICHJOBS_COMPLETED 1
/* Flags for cupsConnectDest and cupsEnumDests */
# define CUPS_DEST_FLAGS_NONE 0x00
/* No flags are set */
# define CUPS_DEST_FLAGS_UNCONNECTED 0x01
/* There is not connection */
# define CUPS_DEST_FLAGS_MORE 0x02
/* There are more destinations */
# define CUPS_DEST_FLAGS_REMOVED 0x04
/* The destination has gone away */
# define CUPS_DEST_FLAGS_ERROR 0x08
/* An error occurred */
# define CUPS_DEST_FLAGS_RESOLVING 0x10
/* The destination address is being
* resolved */
# define CUPS_DEST_FLAGS_CONNECTING 0x20
/* A connection is being established */
# define CUPS_DEST_FLAGS_CANCELED 0x40
/* Operation was canceled */
/* Flags for cupsGetDestMediaByName/Size */
# define CUPS_MEDIA_FLAGS_DEFAULT 0x00
/* Find the closest size supported by
* the printer */
# define CUPS_MEDIA_FLAGS_BORDERLESS 0x01
/* Find a borderless size */
# define CUPS_MEDIA_FLAGS_DUPLEX 0x02
/* Find a size compatible with 2-sided
* printing */
# define CUPS_MEDIA_FLAGS_EXACT 0x04
/* Find an exact match for the size */
# define CUPS_MEDIA_FLAGS_READY 0x08
/* If the printer supports media
* sensing, find the size amongst the
* "ready" media. */
/* Options and values */
# define CUPS_COPIES "copies"
# define CUPS_COPIES_SUPPORTED "copies-supported"
# define CUPS_FINISHINGS "finishings"
# define CUPS_FINISHINGS_SUPPORTED "finishings-supported"
# define CUPS_FINISHINGS_BIND "7"
# define CUPS_FINISHINGS_COVER "6"
# define CUPS_FINISHINGS_FOLD "10"
# define CUPS_FINISHINGS_NONE "3"
# define CUPS_FINISHINGS_PUNCH "5"
# define CUPS_FINISHINGS_STAPLE "4"
# define CUPS_FINISHINGS_TRIM "11"
# define CUPS_MEDIA "media"
# define CUPS_MEDIA_READY "media-ready"
# define CUPS_MEDIA_SUPPORTED "media-supported"
# define CUPS_MEDIA_3X5 "na_index-3x5_3x5in"
# define CUPS_MEDIA_4X6 "na_index-4x6_4x6in"
# define CUPS_MEDIA_5X7 "na_5x7_5x7in"
# define CUPS_MEDIA_8X10 "na_govt-letter_8x10in"
# define CUPS_MEDIA_A3 "iso_a3_297x420mm"
# define CUPS_MEDIA_A4 "iso_a4_210x297mm"
# define CUPS_MEDIA_A5 "iso_a5_148x210mm"
# define CUPS_MEDIA_A6 "iso_a6_105x148mm"
# define CUPS_MEDIA_ENV10 "na_number-10_4.125x9.5in"
# define CUPS_MEDIA_ENVDL "iso_dl_110x220mm"
# define CUPS_MEDIA_LEGAL "na_legal_8.5x14in"
# define CUPS_MEDIA_LETTER "na_letter_8.5x11in"
# define CUPS_MEDIA_PHOTO_L "oe_photo-l_3.5x5in"
# define CUPS_MEDIA_SUPERBA3 "na_super-b_13x19in"
# define CUPS_MEDIA_TABLOID "na_ledger_11x17in"
# define CUPS_MEDIA_SOURCE "media-source"
# define CUPS_MEDIA_SOURCE_SUPPORTED "media-source-supported"
# define CUPS_MEDIA_SOURCE_AUTO "auto"
# define CUPS_MEDIA_SOURCE_MANUAL "manual"
# define CUPS_MEDIA_TYPE "media-type"
# define CUPS_MEDIA_TYPE_SUPPORTED "media-type-supported"
# define CUPS_MEDIA_TYPE_AUTO "auto"
# define CUPS_MEDIA_TYPE_ENVELOPE "envelope"
# define CUPS_MEDIA_TYPE_LABELS "labels"
# define CUPS_MEDIA_TYPE_LETTERHEAD "stationery-letterhead"
# define CUPS_MEDIA_TYPE_PHOTO "photographic"
# define CUPS_MEDIA_TYPE_PHOTO_GLOSSY "photographic-glossy"
# define CUPS_MEDIA_TYPE_PHOTO_MATTE "photographic-matte"
# define CUPS_MEDIA_TYPE_PLAIN "stationery"
# define CUPS_MEDIA_TYPE_TRANSPARENCY "transparency"
# define CUPS_NUMBER_UP "number-up"
# define CUPS_NUMBER_UP_SUPPORTED "number-up-supported"
# define CUPS_ORIENTATION "orientation-requested"
# define CUPS_ORIENTATION_SUPPORTED "orientation-requested-supported"
# define CUPS_ORIENTATION_PORTRAIT "3"
# define CUPS_ORIENTATION_LANDSCAPE "4"
# define CUPS_PRINT_COLOR_MODE "print-color-mode"
# define CUPS_PRINT_COLOR_MODE_SUPPORTED "print-color-mode-supported"
# define CUPS_PRINT_COLOR_MODE_AUTO "auto"
# define CUPS_PRINT_COLOR_MODE_MONOCHROME "monochrome"
# define CUPS_PRINT_COLOR_MODE_COLOR "color"
# define CUPS_PRINT_QUALITY "print-quality"
# define CUPS_PRINT_QUALITY_SUPPORTED "print-quality-supported"
# define CUPS_PRINT_QUALITY_DRAFT "3"
# define CUPS_PRINT_QUALITY_NORMAL "4"
# define CUPS_PRINT_QUALITY_HIGH "5"
# define CUPS_SIDES "sides"
# define CUPS_SIDES_SUPPORTED "sides-supported"
# define CUPS_SIDES_ONE_SIDED "one-sided"
# define CUPS_SIDES_TWO_SIDED_PORTRAIT "two-sided-long-edge"
# define CUPS_SIDES_TWO_SIDED_LANDSCAPE "two-sided-short-edge"
/*
* Types and structures...
*/
typedef unsigned cups_ptype_t; /* Printer type/capability bits */
enum cups_ptype_e /* Printer type/capability bit
* constants */
{ /* Not a typedef'd enum so we can OR */
CUPS_PRINTER_LOCAL = 0x0000, /* Local printer or class */
CUPS_PRINTER_CLASS = 0x0001, /* Printer class */
CUPS_PRINTER_REMOTE = 0x0002, /* Remote printer or class */
CUPS_PRINTER_BW = 0x0004, /* Can do B&W printing */
CUPS_PRINTER_COLOR = 0x0008, /* Can do color printing */
CUPS_PRINTER_DUPLEX = 0x0010, /* Can do duplexing */
CUPS_PRINTER_STAPLE = 0x0020, /* Can staple output */
CUPS_PRINTER_COPIES = 0x0040, /* Can do copies */
CUPS_PRINTER_COLLATE = 0x0080, /* Can collage copies */
CUPS_PRINTER_PUNCH = 0x0100, /* Can punch output */
CUPS_PRINTER_COVER = 0x0200, /* Can cover output */
CUPS_PRINTER_BIND = 0x0400, /* Can bind output */
CUPS_PRINTER_SORT = 0x0800, /* Can sort output */
CUPS_PRINTER_SMALL = 0x1000, /* Can do Letter/Legal/A4 */
CUPS_PRINTER_MEDIUM = 0x2000, /* Can do Tabloid/B/C/A3/A2 */
CUPS_PRINTER_LARGE = 0x4000, /* Can do D/E/A1/A0 */
CUPS_PRINTER_VARIABLE = 0x8000, /* Can do variable sizes */
CUPS_PRINTER_IMPLICIT = 0x10000, /* Implicit class @private@
* @since Deprecated@ */
CUPS_PRINTER_DEFAULT = 0x20000, /* Default printer on network */
CUPS_PRINTER_FAX = 0x40000, /* Fax queue */
CUPS_PRINTER_REJECTING = 0x80000, /* Printer is rejecting jobs */
CUPS_PRINTER_DELETE = 0x100000, /* Delete printer
* @since CUPS 1.2/OS X 10.5@ */
CUPS_PRINTER_NOT_SHARED = 0x200000, /* Printer is not shared
* @since CUPS 1.2/OS X 10.5@ */
CUPS_PRINTER_AUTHENTICATED = 0x400000,/* Printer requires authentication
* @since CUPS 1.2/OS X 10.5@ */
CUPS_PRINTER_COMMANDS = 0x800000, /* Printer supports maintenance commands
* @since CUPS 1.2/OS X 10.5@ */
CUPS_PRINTER_DISCOVERED = 0x1000000, /* Printer was automatically discovered
* and added @private@
* @since Deprecated@ */
CUPS_PRINTER_SCANNER = 0x2000000, /* Scanner-only device
* @since CUPS 1.4/OS X 10.6@ */
CUPS_PRINTER_MFP = 0x4000000, /* Printer with scanning capabilities
* @since CUPS 1.4/OS X 10.6@ */
CUPS_PRINTER_OPTIONS = 0x6fffc /* ~(CLASS | REMOTE | IMPLICIT |
* DEFAULT | FAX | REJECTING | DELETE |
* NOT_SHARED | AUTHENTICATED |
* COMMANDS | DISCOVERED) @private@ */
};
typedef struct cups_option_s /**** Printer Options ****/
{
char *name; /* Name of option */
char *value; /* Value of option */
} cups_option_t;
typedef struct cups_dest_s /**** Destination ****/
{
char *name, /* Printer or class name */
*instance; /* Local instance name or NULL */
int is_default; /* Is this printer the default? */
int num_options; /* Number of options */
cups_option_t *options; /* Options */
} cups_dest_t;
typedef struct _cups_dinfo_s cups_dinfo_t;
/* Destination capability and status
* information @since CUPS 1.6/OS X 10.8@ */
typedef struct cups_job_s /**** Job ****/
{
int id; /* The job ID */
char *dest; /* Printer or class name */
char *title; /* Title/job name */
char *user; /* User the submitted the job */
char *format; /* Document format */
ipp_jstate_t state; /* Job state */
int size; /* Size in kilobytes */
int priority; /* Priority (1-100) */
time_t completed_time; /* Time the job was completed */
time_t creation_time; /* Time the job was created */
time_t processing_time; /* Time the job was processed */
} cups_job_t;
typedef struct cups_size_s /**** Media Size @since CUPS 1.6/OS X 10.8@ ****/
{
char media[128]; /* Media name to use */
int width, /* Width in hundredths of millimeters */
length, /* Length in hundredths of
* millimeters */
bottom, /* Bottom margin in hundredths of
* millimeters */
left, /* Left margin in hundredths of
* millimeters */
right, /* Right margin in hundredths of
* millimeters */
top; /* Top margin in hundredths of
* millimeters */
} cups_size_t;
typedef int (*cups_client_cert_cb_t)(http_t *http, void *tls,
cups_array_t *distinguished_names,
void *user_data);
/* Client credentials callback
* @since CUPS 1.5/OS X 10.7@ */
typedef int (*cups_dest_cb_t)(void *user_data, unsigned flags,
cups_dest_t *dest);
/* Destination enumeration callback
* @since CUPS 1.6/OS X 10.8@ */
# ifdef __BLOCKS__
typedef int (^cups_dest_block_t)(unsigned flags, cups_dest_t *dest);
/* Destination enumeration block
* @since CUPS 1.6/OS X 10.8@ */
# endif /* __BLOCKS__ */
typedef void (*cups_device_cb_t)(const char *device_class,
const char *device_id, const char *device_info,
const char *device_make_and_model,
const char *device_uri,
const char *device_location, void *user_data);
/* Device callback
* @since CUPS 1.4/OS X 10.6@ */
typedef const char *(*cups_password_cb_t)(const char *prompt);
/* Password callback */
typedef const char *(*cups_password_cb2_t)(const char *prompt, http_t *http,
const char *method,
const char *resource,
void *user_data);
/* New password callback
* @since CUPS 1.4/OS X 10.6@ */
typedef int (*cups_server_cert_cb_t)(http_t *http, void *tls,
cups_array_t *certs, void *user_data);
/* Server credentials callback
* @since CUPS 1.5/OS X 10.7@ */
/*
* Functions...
*/
extern int cupsCancelJob(const char *name, int job_id);
extern ipp_t *cupsDoFileRequest(http_t *http, ipp_t *request,
const char *resource,
const char *filename);
extern ipp_t *cupsDoRequest(http_t *http, ipp_t *request,
const char *resource);
extern http_encryption_t cupsEncryption(void);
extern void cupsFreeJobs(int num_jobs, cups_job_t *jobs);
extern int cupsGetClasses(char ***classes) _CUPS_DEPRECATED;
extern const char *cupsGetDefault(void);
extern int cupsGetJobs(cups_job_t **jobs, const char *name,
int myjobs, int whichjobs);
extern const char *cupsGetPPD(const char *name);
extern int cupsGetPrinters(char ***printers) _CUPS_DEPRECATED;
extern ipp_status_t cupsLastError(void);
extern int cupsPrintFile(const char *name, const char *filename,
const char *title, int num_options,
cups_option_t *options);
extern int cupsPrintFiles(const char *name, int num_files,
const char **files, const char *title,
int num_options, cups_option_t *options);
extern char *cupsTempFile(char *filename, int len) _CUPS_DEPRECATED;
extern int cupsTempFd(char *filename, int len);
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);
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);
extern int cupsAddOption(const char *name, const char *value,
int num_options, cups_option_t **options);
extern void cupsEncodeOptions(ipp_t *ipp, int num_options,
cups_option_t *options);
extern void cupsFreeOptions(int num_options,
cups_option_t *options);
extern const char *cupsGetOption(const char *name, int num_options,
cups_option_t *options);
extern int cupsParseOptions(const char *arg, int num_options,
cups_option_t **options);
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);
/**** New in CUPS 1.1.20 ****/
extern int cupsDoAuthentication(http_t *http, const char *method,
const char *resource)
_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 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)
_CUPS_API_1_1_20;
/**** New in CUPS 1.1.21 ****/
extern const char *cupsGetDefault2(http_t *http) _CUPS_API_1_1_21;
extern int cupsGetDests2(http_t *http, cups_dest_t **dests)
_CUPS_API_1_1_21;
extern int cupsGetJobs2(http_t *http, cups_job_t **jobs,
const char *name, int myjobs,
int whichjobs) _CUPS_API_1_1_21;
extern const char *cupsGetPPD2(http_t *http, const char *name)
_CUPS_API_1_1_21;
extern int cupsPrintFile2(http_t *http, const char *name,
const char *filename,
const char *title, int num_options,
cups_option_t *options) _CUPS_API_1_1_21;
extern int cupsPrintFiles2(http_t *http, const char *name,
int num_files, const char **files,
const char *title, int num_options,
cups_option_t *options)
_CUPS_API_1_1_21;
extern int cupsSetDests2(http_t *http, int num_dests,
cups_dest_t *dests) _CUPS_API_1_1_21;
/**** New in CUPS 1.2/OS X 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;
extern const char *cupsLastErrorString(void) _CUPS_API_1_2;
extern char *cupsNotifySubject(cups_lang_t *lang, ipp_t *event)
_CUPS_API_1_2;
extern char *cupsNotifyText(cups_lang_t *lang, ipp_t *event)
_CUPS_API_1_2;
extern int cupsRemoveOption(const char *name, int num_options,
cups_option_t **options) _CUPS_API_1_2;
extern cups_file_t *cupsTempFile2(char *filename, int len) _CUPS_API_1_2;
/**** New in CUPS 1.3/OS X 10.5 ****/
extern ipp_t *cupsDoIORequest(http_t *http, ipp_t *request,
const char *resource, int infile,
int outfile) _CUPS_API_1_3;
extern char *cupsGetServerPPD(http_t *http, const char *name)
_CUPS_API_1_3;
extern int cupsRemoveDest(const char *name,
const char *instance,
int num_dests, cups_dest_t **dests)
_CUPS_API_1_3;
extern void cupsSetDefaultDest(const char *name,
const char *instance,
int num_dests,
cups_dest_t *dests) _CUPS_API_1_3;
/**** New in CUPS 1.4/OS X 10.6 ****/
extern ipp_status_t cupsCancelJob2(http_t *http, const char *name,
int job_id, int purge) _CUPS_API_1_4;
extern int cupsCreateJob(http_t *http, const char *name,
const char *title, int num_options,
cups_option_t *options) _CUPS_API_1_4;
extern ipp_status_t cupsFinishDocument(http_t *http,
const char *name) _CUPS_API_1_4;
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;
extern cups_dest_t *cupsGetNamedDest(http_t *http, const char *name,
const char *instance) _CUPS_API_1_4;
extern const char *cupsGetPassword2(const char *prompt, http_t *http,
const char *method,
const char *resource) _CUPS_API_1_4;
extern http_status_t cupsGetPPD3(http_t *http, const char *name,
time_t *modtime, char *buffer,
size_t bufsize) _CUPS_API_1_4;
extern ipp_t *cupsGetResponse(http_t *http,
const char *resource) _CUPS_API_1_4;
extern ssize_t cupsReadResponseData(http_t *http, char *buffer,
size_t length) _CUPS_API_1_4;
extern http_status_t cupsSendRequest(http_t *http, ipp_t *request,
const char *resource,
size_t length) _CUPS_API_1_4;
extern void cupsSetPasswordCB2(cups_password_cb2_t cb,
void *user_data) _CUPS_API_1_4;
extern http_status_t cupsStartDocument(http_t *http, const char *name,
int job_id, const char *docname,
const char *format,
int last_document) _CUPS_API_1_4;
extern http_status_t cupsWriteRequestData(http_t *http, const char *buffer,
size_t length) _CUPS_API_1_4;
/**** New in CUPS 1.5/OS X 10.7 ****/
extern void cupsSetClientCertCB(cups_client_cert_cb_t cb,
void *user_data) _CUPS_API_1_5;
extern int cupsSetCredentials(cups_array_t *certs) _CUPS_API_1_5;
extern void cupsSetServerCertCB(cups_server_cert_cb_t cb,
void *user_data) _CUPS_API_1_5;
/**** New in CUPS 1.6/OS X 10.8 ****/
extern ipp_status_t cupsCancelDestJob(http_t *http, cups_dest_t *dest,
int job_id) _CUPS_API_1_6;
extern int cupsCheckDestSupported(http_t *http, cups_dest_t *dest,
cups_dinfo_t *info,
const char *option,
const char *value) _CUPS_API_1_6;
extern ipp_status_t cupsCloseDestJob(http_t *http, cups_dest_t *dest,
cups_dinfo_t *info, int job_id)
_CUPS_API_1_6;
extern 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)
_CUPS_API_1_6;
# ifdef __BLOCKS__
extern http_t *cupsConnectDestBlock(cups_dest_t *dest,
unsigned flags, int msec,
int *cancel, char *resource,
size_t resourcesize,
cups_dest_block_t block)
_CUPS_API_1_6;
# endif /* __BLOCKS__ */
extern int cupsCopyDest(cups_dest_t *dest, int num_dests,
cups_dest_t **dests) _CUPS_API_1_6;
extern cups_dinfo_t *cupsCopyDestInfo(http_t *http, cups_dest_t *dest)
_CUPS_API_1_6;
extern int cupsCopyDestConflicts(http_t *http, cups_dest_t *dest,
cups_dinfo_t *info,
int num_options,
cups_option_t *options,
const char *new_option,
const char *new_value,
int *num_conflicts,
cups_option_t **conflicts,
int *num_resolved,
cups_option_t **resolved)
_CUPS_API_1_6;
extern 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) _CUPS_API_1_6;
extern int cupsEnumDests(unsigned flags, int msec, int *cancel,
cups_ptype_t type, cups_ptype_t mask,
cups_dest_cb_t cb, void *user_data)
_CUPS_API_1_6;
# ifdef __BLOCKS__
extern int cupsEnumDestsBlock(unsigned flags, int msec,
int *cancel, cups_ptype_t type,
cups_ptype_t mask,
cups_dest_block_t block)
_CUPS_API_1_6;
# endif /* __BLOCKS__ */
extern ipp_status_t cupsFinishDestDocument(http_t *http,
cups_dest_t *dest,
cups_dinfo_t *info)
_CUPS_API_1_6;
extern void cupsFreeDestInfo(cups_dinfo_t *dinfo) _CUPS_API_1_6;
extern int cupsGetDestMediaByName(http_t *http, cups_dest_t *dest,
cups_dinfo_t *dinfo,
const char *media,
unsigned flags,
cups_size_t *size) _CUPS_API_1_6;
extern int cupsGetDestMediaBySize(http_t *http, cups_dest_t *dest,
cups_dinfo_t *dinfo,
int width, int length,
unsigned flags,
cups_size_t *size) _CUPS_API_1_6;
extern const char *cupsLocalizeDestOption(http_t *http, cups_dest_t *dest,
cups_dinfo_t *info,
const char *option)
_CUPS_API_1_6;
extern const char *cupsLocalizeDestValue(http_t *http, cups_dest_t *dest,
cups_dinfo_t *info,
const char *option,
const char *value)
_CUPS_API_1_6;
extern 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) _CUPS_API_1_6;
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_CUPS_H_ */
/*
* End of "$Id: cups.h 8781 2009-08-28 17:34:54Z mike $".
*/

122
cups/custom.c Normal file
View File

@@ -0,0 +1,122 @@
/*
* "$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 $".
*/

117
cups/debug-private.h Normal file
View File

@@ -0,0 +1,117 @@
/*
* "$Id$"
*
* Private debugging macros for CUPS.
*
* Copyright 2007-2012 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*/
#ifndef _CUPS_DEBUG_PRIVATE_H_
# define _CUPS_DEBUG_PRIVATE_H_
/*
* Include necessary headers...
*/
# include <cups/versioning.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
*
* 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.
*/
# 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 */
/*
* 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);
# define gettimeofday(a,b) _cups_gettimeofday(a, b)
# endif /* WIN32 */
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_DEBUG_PRIVATE_H_ */
/*
* End of "$Id$".
*/

658
cups/debug.c Normal file
View File

@@ -0,0 +1,658 @@
/*
* "$Id: debug.c 3643 2012-02-13 16:35:48Z msweet $"
*
* Debugging functions for CUPS.
*
* 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*
* Contents:
*
* debug_vsnprintf() - Format a string into a fixed size buffer.
* _cups_debug_printf() - Write a formatted line to the log.
* _cups_debug_puts() - Write a single line to the log.
* _cups_debug_set() - Enable or disable debug logging.
*/
/*
* Include necessary headers...
*/
#include "cups-private.h"
#include "thread-private.h"
#ifdef WIN32
# include <sys/timeb.h>
# include <time.h>
# include <io.h>
# define getpid (int)GetCurrentProcessId
int /* O - 0 on success, -1 on failure */
_cups_gettimeofday(struct timeval *tv, /* I - Timeval struct */
void *tz) /* I - Timezone */
{
struct _timeb timebuffer; /* Time buffer struct */
_ftime(&timebuffer);
tv->tv_sec = (long)timebuffer.time;
tv->tv_usec = timebuffer.millitm * 1000;
return 0;
}
#else
# include <sys/time.h>
# include <unistd.h>
#endif /* WIN32 */
#include <regex.h>
#include <fcntl.h>
/*
* Globals...
*/
int _cups_debug_fd = -1;
/* Debug log file descriptor */
int _cups_debug_level = 1;
/* Log level (0 to 9) */
#ifdef DEBUG
/*
* Local globals...
*/
static regex_t *debug_filter = NULL;
/* Filter expression for messages */
static int debug_init = 0; /* Did we initialize debugging? */
static _cups_mutex_t debug_mutex = _CUPS_MUTEX_INITIALIZER;
/* Mutex to control initialization */
/*
* 'debug_vsnprintf()' - Format a string into a fixed size buffer.
*/
static int /* O - Number of bytes formatted */
debug_vsnprintf(char *buffer, /* O - Output buffer */
size_t bufsize, /* O - Size of output buffer */
const char *format, /* I - printf-style format string */
va_list ap) /* I - Pointer to additional arguments */
{
char *bufptr, /* Pointer to position in buffer */
*bufend, /* Pointer to end of buffer */
size, /* Size character (h, l, L) */
type; /* Format type character */
int width, /* Width of field */
prec; /* Number of characters of precision */
char tformat[100], /* Temporary format string for sprintf() */
*tptr, /* Pointer into temporary format */
temp[1024]; /* Buffer for formatted numbers */
char *s; /* Pointer to string */
int bytes; /* Total number of bytes needed */
if (!buffer || bufsize < 2 || !format)
return (-1);
/*
* Loop through the format string, formatting as needed...
*/
bufptr = buffer;
bufend = buffer + bufsize - 1;
bytes = 0;
while (*format)
{
if (*format == '%')
{
tptr = tformat;
*tptr++ = *format++;
if (*format == '%')
{
if (bufptr < bufend)
*bufptr++ = *format;
bytes ++;
format ++;
continue;
}
else if (strchr(" -+#\'", *format))
*tptr++ = *format++;
if (*format == '*')
{
/*
* Get width from argument...
*/
format ++;
width = va_arg(ap, int);
snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", width);
tptr += strlen(tptr);
}
else
{
width = 0;
while (isdigit(*format & 255))
{
if (tptr < (tformat + sizeof(tformat) - 1))
*tptr++ = *format;
width = width * 10 + *format++ - '0';
}
}
if (*format == '.')
{
if (tptr < (tformat + sizeof(tformat) - 1))
*tptr++ = *format;
format ++;
if (*format == '*')
{
/*
* Get precision from argument...
*/
format ++;
prec = va_arg(ap, int);
snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", prec);
tptr += strlen(tptr);
}
else
{
prec = 0;
while (isdigit(*format & 255))
{
if (tptr < (tformat + sizeof(tformat) - 1))
*tptr++ = *format;
prec = prec * 10 + *format++ - '0';
}
}
}
if (*format == 'l' && format[1] == 'l')
{
size = 'L';
if (tptr < (tformat + sizeof(tformat) - 2))
{
*tptr++ = 'l';
*tptr++ = 'l';
}
format += 2;
}
else if (*format == 'h' || *format == 'l' || *format == 'L')
{
if (tptr < (tformat + sizeof(tformat) - 1))
*tptr++ = *format;
size = *format++;
}
else
size = 0;
if (!*format)
break;
if (tptr < (tformat + sizeof(tformat) - 1))
*tptr++ = *format;
type = *format++;
*tptr = '\0';
switch (type)
{
case 'E' : /* Floating point formats */
case 'G' :
case 'e' :
case 'f' :
case 'g' :
if ((width + 2) > sizeof(temp))
break;
sprintf(temp, tformat, va_arg(ap, double));
bytes += (int)strlen(temp);
if (bufptr)
{
if ((bufptr + strlen(temp)) > bufend)
{
strncpy(bufptr, temp, (size_t)(bufend - bufptr));
bufptr = bufend;
}
else
{
strcpy(bufptr, temp);
bufptr += strlen(temp);
}
}
break;
case 'B' : /* Integer formats */
case 'X' :
case 'b' :
case 'd' :
case 'i' :
case 'o' :
case 'u' :
case 'x' :
if ((width + 2) > sizeof(temp))
break;
# ifdef HAVE_LONG_LONG
if (size == 'L')
sprintf(temp, tformat, va_arg(ap, long long));
else
# endif /* HAVE_LONG_LONG */
if (size == 'l')
sprintf(temp, tformat, va_arg(ap, long));
else
sprintf(temp, tformat, va_arg(ap, int));
bytes += (int)strlen(temp);
if (bufptr)
{
if ((bufptr + strlen(temp)) > bufend)
{
strncpy(bufptr, temp, (size_t)(bufend - bufptr));
bufptr = bufend;
}
else
{
strcpy(bufptr, temp);
bufptr += strlen(temp);
}
}
break;
case 'p' : /* Pointer value */
if ((width + 2) > sizeof(temp))
break;
sprintf(temp, tformat, va_arg(ap, void *));
bytes += (int)strlen(temp);
if (bufptr)
{
if ((bufptr + strlen(temp)) > bufend)
{
strncpy(bufptr, temp, (size_t)(bufend - bufptr));
bufptr = bufend;
}
else
{
strcpy(bufptr, temp);
bufptr += strlen(temp);
}
}
break;
case 'c' : /* Character or character array */
bytes += width;
if (bufptr)
{
if (width <= 1)
*bufptr++ = va_arg(ap, int);
else
{
if ((bufptr + width) > bufend)
width = (int)(bufend - bufptr);
memcpy(bufptr, va_arg(ap, char *), (size_t)width);
bufptr += width;
}
}
break;
case 's' : /* String */
if ((s = va_arg(ap, char *)) == NULL)
s = "(null)";
/*
* Copy the C string, replacing control chars and \ with
* C character escapes...
*/
for (bufend --; *s && bufptr < bufend; s ++)
{
if (*s == '\n')
{
*bufptr++ = '\\';
*bufptr++ = 'n';
bytes += 2;
}
else if (*s == '\r')
{
*bufptr++ = '\\';
*bufptr++ = 'r';
bytes += 2;
}
else if (*s == '\t')
{
*bufptr++ = '\\';
*bufptr++ = 't';
bytes += 2;
}
else if (*s == '\\')
{
*bufptr++ = '\\';
*bufptr++ = '\\';
bytes += 2;
}
else if (*s == '\'')
{
*bufptr++ = '\\';
*bufptr++ = '\'';
bytes += 2;
}
else if (*s == '\"')
{
*bufptr++ = '\\';
*bufptr++ = '\"';
bytes += 2;
}
else if ((*s & 255) < ' ')
{
if ((bufptr + 2) >= bufend)
break;
*bufptr++ = '\\';
*bufptr++ = '0';
*bufptr++ = '0' + *s / 8;
*bufptr++ = '0' + (*s & 7);
bytes += 4;
}
else
{
*bufptr++ = *s;
bytes ++;
}
}
bufend ++;
break;
case 'n' : /* Output number of chars so far */
*(va_arg(ap, int *)) = bytes;
break;
}
}
else
{
bytes ++;
if (bufptr < bufend)
*bufptr++ = *format;
format ++;
}
}
/*
* Nul-terminate the string and return the number of characters needed.
*/
*bufptr = '\0';
return (bytes);
}
/*
* '_cups_debug_printf()' - Write a formatted line to the log.
*/
void DLLExport
_cups_debug_printf(const char *format, /* I - Printf-style format string */
...) /* I - Additional arguments as needed */
{
va_list ap; /* Pointer to arguments */
struct timeval curtime; /* Current time */
char buffer[2048]; /* Output buffer */
size_t bytes; /* Number of bytes in buffer */
int level; /* Log level in message */
/*
* See if we need to do any logging...
*/
if (!debug_init)
_cups_debug_set(getenv("CUPS_DEBUG_LOG"), getenv("CUPS_DEBUG_LEVEL"),
getenv("CUPS_DEBUG_FILTER"), 0);
if (_cups_debug_fd < 0)
return;
/*
* Filter as needed...
*/
if (isdigit(format[0]))
level = *format++ - '0';
else
level = 0;
if (level > _cups_debug_level)
return;
if (debug_filter)
{
int result; /* Filter result */
_cupsMutexLock(&debug_mutex);
result = regexec(debug_filter, format, 0, NULL, 0);
_cupsMutexUnlock(&debug_mutex);
if (result)
return;
}
/*
* Format the message...
*/
gettimeofday(&curtime, NULL);
snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d.%03d ",
(int)((curtime.tv_sec / 3600) % 24),
(int)((curtime.tv_sec / 60) % 60),
(int)(curtime.tv_sec % 60), (int)(curtime.tv_usec / 1000));
va_start(ap, format);
bytes = debug_vsnprintf(buffer + 13, sizeof(buffer) - 14, format, ap) + 13;
va_end(ap);
if (bytes >= (sizeof(buffer) - 1))
{
buffer[sizeof(buffer) - 2] = '\n';
bytes = sizeof(buffer) - 1;
}
else if (buffer[bytes - 1] != '\n')
{
buffer[bytes++] = '\n';
buffer[bytes] = '\0';
}
/*
* Write it out...
*/
write(_cups_debug_fd, buffer, bytes);
}
/*
* '_cups_debug_puts()' - Write a single line to the log.
*/
void DLLExport
_cups_debug_puts(const char *s) /* I - String to output */
{
struct timeval curtime; /* Current time */
char buffer[2048]; /* Output buffer */
size_t bytes; /* Number of bytes in buffer */
int level; /* Log level in message */
/*
* See if we need to do any logging...
*/
if (!debug_init)
_cups_debug_set(getenv("CUPS_DEBUG_LOG"), getenv("CUPS_DEBUG_LEVEL"),
getenv("CUPS_DEBUG_FILTER"), 0);
if (_cups_debug_fd < 0)
return;
/*
* Filter as needed...
*/
if (isdigit(s[0]))
level = *s++ - '0';
else
level = 0;
if (level > _cups_debug_level)
return;
if (debug_filter)
{
int result; /* Filter result */
_cupsMutexLock(&debug_mutex);
result = regexec(debug_filter, s, 0, NULL, 0);
_cupsMutexUnlock(&debug_mutex);
if (result)
return;
}
/*
* Format the message...
*/
gettimeofday(&curtime, NULL);
bytes = snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d.%03d %s",
(int)((curtime.tv_sec / 3600) % 24),
(int)((curtime.tv_sec / 60) % 60),
(int)(curtime.tv_sec % 60), (int)(curtime.tv_usec / 1000),
s);
if (bytes >= (sizeof(buffer) - 1))
{
buffer[sizeof(buffer) - 2] = '\n';
bytes = sizeof(buffer) - 1;
}
else if (buffer[bytes - 1] != '\n')
{
buffer[bytes++] = '\n';
buffer[bytes] = '\0';
}
/*
* Write it out...
*/
write(_cups_debug_fd, buffer, bytes);
}
/*
* '_cups_debug_set()' - Enable or disable debug logging.
*/
void DLLExport
_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 */
{
_cupsMutexLock(&debug_mutex);
if (!debug_init || force)
{
/*
* Restore debug settings to defaults...
*/
if (_cups_debug_fd != -1)
{
close(_cups_debug_fd);
_cups_debug_fd = -1;
}
if (debug_filter)
{
regfree((regex_t *)debug_filter);
debug_filter = NULL;
}
_cups_debug_level = 1;
/*
* Open logs, set log levels, etc.
*/
if (!logfile)
_cups_debug_fd = -1;
else if (!strcmp(logfile, "-"))
_cups_debug_fd = 2;
else
{
char buffer[1024]; /* Filename buffer */
snprintf(buffer, sizeof(buffer), logfile, getpid());
if (buffer[0] == '+')
_cups_debug_fd = open(buffer + 1, O_WRONLY | O_APPEND | O_CREAT, 0644);
else
_cups_debug_fd = open(buffer, O_WRONLY | O_TRUNC | O_CREAT, 0644);
}
if (level)
_cups_debug_level = atoi(level);
if (filter)
{
if ((debug_filter = (regex_t *)calloc(1, sizeof(regex_t))) == NULL)
fputs("Unable to allocate memory for CUPS_DEBUG_FILTER - results not "
"filtered!\n", stderr);
else if (regcomp(debug_filter, filter, REG_EXTENDED))
{
fputs("Bad regular expression in CUPS_DEBUG_FILTER - results not "
"filtered!\n", stderr);
free(debug_filter);
debug_filter = NULL;
}
}
debug_init = 1;
}
_cupsMutexUnlock(&debug_mutex);
}
#endif /* DEBUG */
/*
* End of "$Id: debug.c 3643 2012-02-13 16:35:48Z msweet $".
*/

358
cups/dest-job.c Normal file
View File

@@ -0,0 +1,358 @@
/*
* "$Id: dest-job.c 3833 2012-05-23 22:51:18Z msweet $"
*
* Destination job support for CUPS.
*
* Copyright 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*
* Contents:
*
 * cupsCancelDestJob() - Cancel a job on a destination.
* cupsCloseDestJob() - Close a job and start printing.
* cupsCreateDestJob() - Create a job on a destination.
* cupsFinishDestDocument() - Finish the current document.
* cupsStartDestDocument() - Start a new document.
*/
/*
* Include necessary headers...
*/
#include "cups-private.h"
/*
* 'cupsCancelDestJob()' - Cancel a job on a destination.
*
* The "job_id" is the number returned by cupsCreateDestJob.
*
* Returns IPP_OK on success and IPP_NOT_AUTHORIZED or IPP_FORBIDDEN on
* failure.
*
* @since CUPS 1.6/OS X 10.8@
*/
ipp_status_t
cupsCancelDestJob(http_t *http, /* I - Connection to destination */
cups_dest_t *dest, /* I - Destination */
int job_id) /* I - Job ID */
{
return (IPP_NOT_FOUND);
}
/*
* 'cupsCloseDestJob()' - Close a job and start printing.
*
* Use when the last call to cupsStartDocument passed 0 for "last_document".
* "job_id" is the job ID returned by cupsCreateDestJob. Returns @code IPP_OK@
* on success.
*
* @since CUPS 1.6/OS X 10.8@
*/
ipp_status_t /* O - IPP status code */
cupsCloseDestJob(
http_t *http, /* I - Connection to destination */
cups_dest_t *dest, /* I - Destination */
cups_dinfo_t *info, /* I - Destination information */
int job_id) /* I - Job ID */
{
int i; /* Looping var */
ipp_t *request = NULL;/* Close-Job/Send-Document request */
ipp_attribute_t *attr; /* operations-supported attribute */
DEBUG_printf(("cupsCloseDestJob(http=%p, dest=%p(%s/%s), info=%p, job_id=%d)",
http, dest, dest ? dest->name : NULL,
dest ? dest->instance : NULL, info, job_id));
/*
* Range check input...
*/
if (!http || !dest || !info || job_id <= 0)
{
_cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0);
DEBUG_puts("1cupsCloseDestJob: Bad arguments.");
return (IPP_INTERNAL_ERROR);
}
/*
* Build a Close-Job or empty Send-Document request...
*/
if ((attr = ippFindAttribute(info->attrs, "operations-supported",
IPP_TAG_ENUM)) != NULL)
{
for (i = 0; i < attr->num_values; i ++)
if (attr->values[i].integer == IPP_CLOSE_JOB)
{
request = ippNewRequest(IPP_CLOSE_JOB);
break;
}
}
if (!request)
request = ippNewRequest(IPP_SEND_DOCUMENT);
if (!request)
{
_cupsSetError(IPP_INTERNAL_ERROR, strerror(ENOMEM), 0);
DEBUG_puts("1cupsCloseDestJob: Unable to create Close-Job/Send-Document "
"request.");
return (IPP_INTERNAL_ERROR);
}
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, info->uri);
ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id",
job_id);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
NULL, cupsUser());
if (ippGetOperation(request) == IPP_SEND_DOCUMENT)
ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1);
/*
* Send the request and return the status...
*/
ippDelete(cupsDoRequest(http, request, info->resource));
DEBUG_printf(("1cupsCloseDestJob: %s (%s)", ippErrorString(cupsLastError()),
cupsLastErrorString()));
return (cupsLastError());
}
/*
* 'cupsCreateDestJob()' - Create a job on a destination.
*
* Returns @code IPP_OK@ or @code IPP_OK_SUBST@ on success, saving the job ID
* in the variable pointed to by "job_id".
*
* @since CUPS 1.6/OS X 10.8@
*/
ipp_status_t /* O - IPP status code */
cupsCreateDestJob(
http_t *http, /* I - Connection to destination */
cups_dest_t *dest, /* I - Destination */
cups_dinfo_t *info, /* I - Destination information */
int *job_id, /* O - Job ID or 0 on error */
const char *title, /* I - Job name */
int num_options, /* I - Number of job options */
cups_option_t *options) /* I - Job options */
{
ipp_t *request, /* Create-Job request */
*response; /* Create-Job response */
ipp_attribute_t *attr; /* job-id attribute */
DEBUG_printf(("cupsCreateDestJob(http=%p, dest=%p(%s/%s), info=%p, "
"job_id=%p, title=\"%s\", num_options=%d, options=%p)",
http, dest, dest ? dest->name : NULL,
dest ? dest->instance : NULL, info, job_id, title, num_options,
options));
/*
* Range check input...
*/
if (job_id)
*job_id = 0;
if (!http || !dest || !info || !job_id)
{
_cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0);
DEBUG_puts("1cupsCreateDestJob: Bad arguments.");
return (IPP_INTERNAL_ERROR);
}
/*
* Build a Create-Job request...
*/
if ((request = ippNewRequest(IPP_CREATE_JOB)) == NULL)
{
_cupsSetError(IPP_INTERNAL_ERROR, strerror(ENOMEM), 0);
DEBUG_puts("1cupsCreateDestJob: Unable to create Create-Job request.");
return (IPP_INTERNAL_ERROR);
}
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, info->uri);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
NULL, cupsUser());
if (title)
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
title);
cupsEncodeOptions2(request, num_options, options, IPP_TAG_JOB);
cupsEncodeOptions2(request, num_options, options, IPP_TAG_SUBSCRIPTION);
/*
* Send the request and get the job-id...
*/
response = cupsDoRequest(http, request, info->resource);
if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) != NULL)
{
*job_id = attr->values[0].integer;
DEBUG_printf(("1cupsCreateDestJob: job-id=%d", *job_id));
}
ippDelete(response);
/*
* Return the status code from the Create-Job request...
*/
DEBUG_printf(("1cupsCreateDestJob: %s (%s)", ippErrorString(cupsLastError()),
cupsLastErrorString()));
return (cupsLastError());
}
/*
* 'cupsFinishDestDocument()' - Finish the current document.
*
* Returns @code IPP_OK@ or @code IPP_OK_SUBST@ on success.
*
* @since CUPS 1.6/OS X 10.8@
*/
ipp_status_t /* O - Status of document submission */
cupsFinishDestDocument(
http_t *http, /* I - Connection to destination */
cups_dest_t *dest, /* I - Destination */
cups_dinfo_t *info) /* I - Destination information */
{
DEBUG_printf(("cupsFinishDestDocument(http=%p, dest=%p(%s/%s), info=%p)",
http, dest, dest ? dest->name : NULL,
dest ? dest->instance : NULL, info));
/*
* Range check input...
*/
if (!http || !dest || !info)
{
_cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0);
DEBUG_puts("1cupsFinishDestDocument: Bad arguments.");
return (IPP_INTERNAL_ERROR);
}
/*
* Get the response at the end of the document and return it...
*/
ippDelete(cupsGetResponse(http, info->resource));
DEBUG_printf(("1cupsFinishDestDocument: %s (%s)",
ippErrorString(cupsLastError()), cupsLastErrorString()));
return (cupsLastError());
}
/*
* 'cupsStartDestDocument()' - Start a new document.
*
* "job_id" is the job ID returned by cupsCreateDestJob. "docname" is the name
* of the document/file being printed, "format" is the MIME media type for the
* document (see CUPS_FORMAT_xxx constants), and "num_options" and "options"
* are the options do be applied to the document. "last_document" should be 1
* if this is the last document to be submitted in the job. Returns
* @code HTTP_CONTINUE@ on success.
*
* @since CUPS 1.6/OS X 10.8@
*/
http_status_t /* O - Status of document creation */
cupsStartDestDocument(
http_t *http, /* I - Connection to destination */
cups_dest_t *dest, /* I - Destination */
cups_dinfo_t *info, /* I - Destination information */
int job_id, /* I - Job ID */
const char *docname, /* I - Document name */
const char *format, /* I - Document format */
int num_options, /* I - Number of document options */
cups_option_t *options, /* I - Document options */
int last_document) /* I - 1 if this is the last document */
{
ipp_t *request; /* Send-Document request */
http_status_t status; /* HTTP status */
DEBUG_printf(("cupsStartDestDocument(http=%p, dest=%p(%s/%s), info=%p, "
"job_id=%d, docname=\"%s\", format=\"%s\", num_options=%d, "
"options=%p, last_document=%d)",
http, dest, dest ? dest->name : NULL,
dest ? dest->instance : NULL, info, job_id, docname, format,
num_options, options, last_document));
/*
* Range check input...
*/
if (!http || !dest || !info || job_id <= 0)
{
_cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0);
DEBUG_puts("1cupsStartDestDocument: Bad arguments.");
return (HTTP_ERROR);
}
/*
* Create a Send-Document request...
*/
if ((request = ippNewRequest(IPP_SEND_DOCUMENT)) == NULL)
{
_cupsSetError(IPP_INTERNAL_ERROR, strerror(ENOMEM), 0);
DEBUG_puts("1cupsStartDestDocument: Unable to create Send-Document "
"request.");
return (HTTP_ERROR);
}
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, info->uri);
ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job_id);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
NULL, cupsUser());
if (docname)
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name",
NULL, docname);
if (format)
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
"document-format", NULL, format);
ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", last_document);
cupsEncodeOptions2(request, num_options, options, IPP_TAG_DOCUMENT);
/*
* Send and delete the request, then return the status...
*/
status = cupsSendRequest(http, request, info->resource, CUPS_LENGTH_VARIABLE);
ippDelete(request);
return (status);
}
/*
* End of "$Id: dest-job.c 3833 2012-05-23 22:51:18Z msweet $".
*/

386
cups/dest-localization.c Normal file
View File

@@ -0,0 +1,386 @@
/*
* "$Id: dest-localization.c 3833 2012-05-23 22:51:18Z msweet $"
*
* Destination localization support for CUPS.
*
* Copyright 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*
* Contents:
*
* cupsLocalizeDestOption() - Get the localized string for a destination
* option.
* cupsLocalizeDestValue() - Get the localized string for a destination
* option+value pair.
* cups_create_localizations() - Create the localizations array for a
* destination.
* cups_read_strings() - Read a pair of strings from a .strings file.
* cups_scan_strings() - Scan a quoted string.
*/
/*
* Include necessary headers...
*/
#include "cups-private.h"
/*
* Local functions...
*/
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);
/*
* 'cupsLocalizeDestOption()' - Get the localized string for a destination
* option.
*
* The returned string is stored in the destination information and will become
* invalid if the destination information is deleted.
*
* @since CUPS 1.6/OS X 10.8@
*/
const char * /* O - Localized string */
cupsLocalizeDestOption(
http_t *http, /* I - Connection to destination */
cups_dest_t *dest, /* I - Destination */
cups_dinfo_t *dinfo, /* I - Destination information */
const char *option) /* I - Option to localize */
{
_cups_message_t key, /* Search key */
*match; /* Matching entry */
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)
return (match->str);
else
return (option);
}
/*
* 'cupsLocalizeDestValue()' - Get the localized string for a destination
* option+value pair.
*
* The returned string is stored in the destination information and will become
* invalid if the destination information is deleted.
*
* @since CUPS 1.6/OS X 10.8@
*/
const char * /* O - Localized string */
cupsLocalizeDestValue(
http_t *http, /* I - Connection to destination */
cups_dest_t *dest, /* I - Destination */
cups_dinfo_t *dinfo, /* I - Destination information */
const char *option, /* I - Option to localize */
const char *value) /* I - Value to localize */
{
_cups_message_t key, /* Search key */
*match; /* Matching entry */
char pair[256]; /* option.value pair */
if (!http || !dest || !dinfo)
return (value);
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)
return (match->str);
else
return (value);
}
/*
* 'cups_create_localizations()' - Create the localizations array for a
* destination.
*/
static void
cups_create_localizations(
http_t *http, /* I - Connection to destination */
cups_dinfo_t *dinfo) /* I - Destination informations */
{
http_t *http2; /* Connection for strings file */
http_status_t status; /* Request status */
ipp_attribute_t *attr; /* "printer-strings-uri" attribute */
char scheme[32], /* URI scheme */
userpass[256], /* Username/password info */
hostname[256], /* Hostname */
resource[1024], /* Resource */
http_hostname[256],
/* Hostname of connection */
tempfile[1024]; /* Temporary filename */
int port; /* Port number */
http_encryption_t encryption; /* Encryption to use */
cups_file_t *temp; /* Temporary file */
/*
* Create an empty message catalog...
*/
dinfo->localizations = _cupsMessageNew(NULL);
/*
* See if there are any localizations...
*/
if ((attr = ippFindAttribute(dinfo->attrs, "printer-strings-uri",
IPP_TAG_URI)) == NULL)
{
/*
* Nope...
*/
DEBUG_puts("4cups_create_localizations: No printer-strings-uri (uri) "
"value.");
return; /* Nope */
}
/*
* Pull apart the URI and determine whether we need to try a different
* server...
*/
if (httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text,
scheme, sizeof(scheme), userpass, sizeof(userpass),
hostname, sizeof(hostname), &port, resource,
sizeof(resource)) < HTTP_URI_OK)
{
DEBUG_printf(("4cups_create_localizations: Bad printer-strings-uri value "
"\"%s\".", attr->values[0].string.text));
return;
}
httpGetHostname(http, http_hostname, sizeof(http_hostname));
if (!_cups_strcasecmp(http_hostname, hostname) &&
port == _httpAddrPort(http->hostaddr))
{
/*
* Use the same connection...
*/
http2 = http;
}
else
{
/*
* Connect to the alternate host...
*/
if (!strcmp(scheme, "https"))
encryption = HTTP_ENCRYPT_ALWAYS;
else
encryption = HTTP_ENCRYPT_IF_REQUESTED;
if ((http2 = httpConnectEncrypt(hostname, port, encryption)) == NULL)
{
DEBUG_printf(("4cups_create_localizations: Unable to connect to "
"%s:%d: %s", hostname, port, cupsLastErrorString()));
return;
}
}
/*
* Get a temporary file...
*/
if ((temp = cupsTempFile2(tempfile, sizeof(tempfile))) == NULL)
{
DEBUG_printf(("4cups_create_localizations: Unable to create temporary "
"file: %s", cupsLastErrorString()));
if (http2 != http)
httpClose(http2);
return;
}
status = cupsGetFd(http2, resource, cupsFileNumber(temp));
DEBUG_printf(("4cups_create_localizations: GET %s = %s", resource,
httpStatus(status)));
if (status == HTTP_OK)
{
/*
* 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;
}
}
}
DEBUG_printf(("4cups_create_localizations: %d messages loaded.",
cupsArrayCount(dinfo->localizations)));
/*
* Cleanup...
*/
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 = ((((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);
}
/*
* End of "$Id: dest-localization.c 3833 2012-05-23 22:51:18Z msweet $".
*/

1763
cups/dest-options.c Normal file

File diff suppressed because it is too large Load Diff

3891
cups/dest.c Normal file

File diff suppressed because it is too large Load Diff

472
cups/dir.c Normal file
View File

@@ -0,0 +1,472 @@
/*
* "$Id: dir.c 7279 2008-01-31 01:50:44Z mike $"
*
* Directory routines for CUPS.
*
* This set of APIs abstracts enumeration of directory entries.
*
* Copyright 2007-2012 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* Contents:
*
* _cups_dir_time() - Convert a FILETIME value to a UNIX time value.
* cupsDirClose() - Close a directory.
* cupsDirOpen() - Open a directory.
* cupsDirRead() - Read the next directory entry.
* cupsDirRewind() - Rewind to the start of the directory.
* cupsDirClose() - Close a directory.
* cupsDirOpen() - Open a directory.
* cupsDirRead() - Read the next directory entry.
* cupsDirRewind() - Rewind to the start of the directory.
*/
/*
* Include necessary headers...
*/
#include "string-private.h"
#include "debug-private.h"
#include "dir.h"
/*
* Windows implementation...
*/
#ifdef WIN32
# include <windows.h>
/*
* Types and structures...
*/
struct _cups_dir_s /**** Directory data structure ****/
{
char directory[1024]; /* Directory filename */
HANDLE dir; /* Directory handle */
cups_dentry_t entry; /* Directory entry */
};
/*
* '_cups_dir_time()' - Convert a FILETIME value to a UNIX time value.
*/
time_t /* O - UNIX time */
_cups_dir_time(FILETIME ft) /* I - File time */
{
ULONGLONG val; /* File time in 0.1 usecs */
/*
* Convert file time (1/10 microseconds since Jan 1, 1601) to UNIX
* time (seconds since Jan 1, 1970). There are 11,644,732,800 seconds
* between them...
*/
val = ft.dwLowDateTime + ((ULONGLONG)ft.dwHighDateTime << 32);
return ((time_t)(val / 10000000 - 11644732800));
}
/*
* 'cupsDirClose()' - Close a directory.
*
* @since CUPS 1.2/OS X 10.5@
*/
void
cupsDirClose(cups_dir_t *dp) /* I - Directory pointer */
{
/*
* Range check input...
*/
if (!dp)
return;
/*
* Close an open directory handle...
*/
if (dp->dir != INVALID_HANDLE_VALUE)
FindClose(dp->dir);
/*
* Free memory used...
*/
free(dp);
}
/*
* 'cupsDirOpen()' - Open a directory.
*
* @since CUPS 1.2/OS X 10.5@
*/
cups_dir_t * /* O - Directory pointer or @code NULL@ if the directory could not be opened. */
cupsDirOpen(const char *directory) /* I - Directory name */
{
cups_dir_t *dp; /* Directory */
/*
* Range check input...
*/
if (!directory)
return (NULL);
/*
* Allocate memory for the directory structure...
*/
dp = (cups_dir_t *)calloc(1, sizeof(cups_dir_t));
if (!dp)
return (NULL);
/*
* Copy the directory name for later use...
*/
dp->dir = INVALID_HANDLE_VALUE;
strlcpy(dp->directory, directory, sizeof(dp->directory));
/*
* Return the new directory structure...
*/
return (dp);
}
/*
* 'cupsDirRead()' - Read the next directory entry.
*
* @since CUPS 1.2/OS X 10.5@
*/
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 */
/*
* Range check input...
*/
if (!dp)
return (NULL);
/*
* See if we have already started finding files...
*/
if (dp->dir == INVALID_HANDLE_VALUE)
{
/*
* No, find the first file...
*/
dp->dir = FindFirstFile(dp->directory, &entry);
if (dp->dir == INVALID_HANDLE_VALUE)
return (NULL);
}
else if (!FindNextFile(dp->dir, &entry))
return (NULL);
/*
* Copy the name over and convert the file information...
*/
strlcpy(dp->entry.filename, entry.cFileName, sizeof(dp->entry.filename));
if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
dp->entry.fileinfo.st_mode = 0755 | S_IFDIR;
else
dp->entry.fileinfo.st_mode = 0644;
dp->entry.fileinfo.st_atime = _cups_dir_time(entry.ftLastAccessTime);
dp->entry.fileinfo.st_ctime = _cups_dir_time(entry.ftCreationTime);
dp->entry.fileinfo.st_mtime = _cups_dir_time(entry.ftLastWriteTime);
dp->entry.fileinfo.st_size = entry.nFileSizeLow + ((unsigned long long)entry.nFileSizeHigh << 32);
/*
* Return the entry...
*/
return (&(dp->entry));
}
/*
* 'cupsDirRewind()' - Rewind to the start of the directory.
*
* @since CUPS 1.2/OS X 10.5@
*/
void
cupsDirRewind(cups_dir_t *dp) /* I - Directory pointer */
{
/*
* Range check input...
*/
if (!dp)
return;
/*
* Close an open directory handle...
*/
if (dp->dir != INVALID_HANDLE_VALUE)
{
FindClose(dp->dir);
dp->dir = INVALID_HANDLE_VALUE;
}
}
#else
/*
* POSIX implementation...
*/
# include <sys/types.h>
# include <dirent.h>
/*
* Types and structures...
*/
struct _cups_dir_s /**** Directory data structure ****/
{
char directory[1024]; /* Directory filename */
DIR *dir; /* Directory file */
cups_dentry_t entry; /* Directory entry */
};
/*
* 'cupsDirClose()' - Close a directory.
*
* @since CUPS 1.2/OS X 10.5@
*/
void
cupsDirClose(cups_dir_t *dp) /* I - Directory pointer */
{
DEBUG_printf(("cupsDirClose(dp=%p)", dp));
/*
* Range check input...
*/
if (!dp)
return;
/*
* Close the directory and free memory...
*/
closedir(dp->dir);
free(dp);
}
/*
* 'cupsDirOpen()' - Open a directory.
*
* @since CUPS 1.2/OS X 10.5@
*/
cups_dir_t * /* O - Directory pointer or @code NULL@ if the directory could not be opened. */
cupsDirOpen(const char *directory) /* I - Directory name */
{
cups_dir_t *dp; /* Directory */
DEBUG_printf(("cupsDirOpen(directory=\"%s\")", directory));
/*
* Range check input...
*/
if (!directory)
return (NULL);
/*
* Allocate memory for the directory structure...
*/
dp = (cups_dir_t *)calloc(1, sizeof(cups_dir_t));
if (!dp)
return (NULL);
/*
* Open the directory...
*/
dp->dir = opendir(directory);
if (!dp->dir)
{
free(dp);
return (NULL);
}
/*
* Copy the directory name for later use...
*/
strlcpy(dp->directory, directory, sizeof(dp->directory));
/*
* Return the new directory structure...
*/
return (dp);
}
/*
* 'cupsDirRead()' - Read the next directory entry.
*
* @since CUPS 1.2/OS X 10.5@
*/
cups_dentry_t * /* O - Directory entry or @code NULL@ when there are no more */
cupsDirRead(cups_dir_t *dp) /* I - Directory pointer */
{
struct dirent *entry; /* Pointer to entry */
char filename[1024]; /* Full filename */
# ifdef HAVE_PTHREAD_H
char buffer[sizeof(struct dirent) + 1024];
/* Directory entry buffer */
# endif /* HAVE_PTHREAD_H */
DEBUG_printf(("2cupsDirRead(dp=%p)", dp));
/*
* Range check input...
*/
if (!dp)
return (NULL);
/*
* Try reading an entry that is not "." or ".."...
*/
for (;;)
{
# ifdef HAVE_PTHREAD_H
/*
* Read the next entry using the reentrant version of readdir...
*/
if (readdir_r(dp->dir, (struct dirent *)buffer, &entry))
{
DEBUG_printf(("3cupsDirRead: readdir_r() failed - %s\n", strerror(errno)));
return (NULL);
}
if (!entry)
{
DEBUG_puts("3cupsDirRead: readdir_r() returned a NULL pointer!");
return (NULL);
}
DEBUG_printf(("4cupsDirRead: readdir_r() returned \"%s\"...",
entry->d_name));
# else
/*
* Read the next entry using the original version of readdir...
*/
if ((entry = readdir(dp->dir)) == NULL)
{
DEBUG_puts("3cupsDirRead: readdir() returned a NULL pointer!");
return (NULL);
}
DEBUG_printf(("4cupsDirRead: readdir() returned \"%s\"...", entry->d_name));
# endif /* HAVE_PTHREAD_H */
/*
* Skip "." and ".."...
*/
if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
continue;
/*
* Copy the name over and get the file information...
*/
strlcpy(dp->entry.filename, entry->d_name, sizeof(dp->entry.filename));
snprintf(filename, sizeof(filename), "%s/%s", dp->directory, entry->d_name);
if (stat(filename, &(dp->entry.fileinfo)))
{
DEBUG_printf(("3cupsDirRead: stat() failed for \"%s\" - %s...", filename,
strerror(errno)));
continue;
}
/*
* Return the entry...
*/
return (&(dp->entry));
}
}
/*
* 'cupsDirRewind()' - Rewind to the start of the directory.
*
* @since CUPS 1.2/OS X 10.5@
*/
void
cupsDirRewind(cups_dir_t *dp) /* I - Directory pointer */
{
DEBUG_printf(("cupsDirRewind(dp=%p)", dp));
/*
* Range check input...
*/
if (!dp)
return;
/*
* Rewind the directory...
*/
rewinddir(dp->dir);
}
#endif /* WIN32 */
/*
* End of "$Id: dir.c 7279 2008-01-31 01:50:44Z mike $".
*/

69
cups/dir.h Normal file
View File

@@ -0,0 +1,69 @@
/*
* "$Id: dir.h 7026 2007-10-19 00:57:45Z mike $"
*
* Public directory definitions for CUPS.
*
* This set of APIs abstracts enumeration of directory entries.
*
* 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*/
#ifndef _CUPS_DIR_H_
# define _CUPS_DIR_H_
/*
* Include necessary headers...
*/
# include "versioning.h"
# include <sys/stat.h>
/*
* C++ magic...
*/
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/*
* Data types...
*/
typedef struct _cups_dir_s cups_dir_t; /**** Directory type ****/
typedef struct cups_dentry_s /**** Directory entry type ****/
{
char filename[260]; /* File name */
struct stat fileinfo; /* File information */
} cups_dentry_t;
/*
* Prototypes...
*/
extern void cupsDirClose(cups_dir_t *dp) _CUPS_API_1_2;
extern cups_dir_t *cupsDirOpen(const char *directory) _CUPS_API_1_2;
extern cups_dentry_t *cupsDirRead(cups_dir_t *dp) _CUPS_API_1_2;
extern void cupsDirRewind(cups_dir_t *dp) _CUPS_API_1_2;
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_DIR_H_ */
/*
* End of "$Id: dir.h 7026 2007-10-19 00:57:45Z mike $".
*/

1229
cups/emit.c Normal file

File diff suppressed because it is too large Load Diff

664
cups/encode.c Normal file
View File

@@ -0,0 +1,664 @@
/*
* "$Id: encode.c 7696 2008-06-26 00:54:42Z mike $"
*
* Option encoding routines for CUPS.
*
* Copyright 2007-2012 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*
* Contents:
*
* cupsEncodeOptions() - Encode printer options into IPP attributes.
* cupsEncodeOptions2() - Encode printer options into IPP attributes for
* a group.
* _ippFindOption() - Find the attribute information for an option.
* compare_ipp_options() - Compare two IPP options.
*/
/*
* Include necessary headers...
*/
#include "cups-private.h"
/*
* Local list of option names and the value tags they should use...
*
* **** THIS LIST MUST BE SORTED ****
*/
static const _ipp_option_t ipp_options[] =
{
{ 1, "auth-info", IPP_TAG_TEXT, IPP_TAG_JOB },
{ 1, "auth-info-required", IPP_TAG_KEYWORD, IPP_TAG_PRINTER },
{ 0, "blackplot", IPP_TAG_BOOLEAN, IPP_TAG_JOB },
{ 0, "blackplot-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER },
{ 0, "brightness", IPP_TAG_INTEGER, IPP_TAG_JOB },
{ 0, "brightness-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 0, "columns", IPP_TAG_INTEGER, IPP_TAG_JOB },
{ 0, "columns-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 0, "compression", IPP_TAG_KEYWORD, IPP_TAG_OPERATION },
{ 0, "copies", IPP_TAG_INTEGER, IPP_TAG_JOB,
IPP_TAG_DOCUMENT },
{ 0, "copies-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 0, "device-uri", IPP_TAG_URI, IPP_TAG_PRINTER },
{ 1, "document-copies", IPP_TAG_RANGE, IPP_TAG_JOB,
IPP_TAG_DOCUMENT },
{ 0, "document-format", IPP_TAG_MIMETYPE, IPP_TAG_OPERATION },
{ 0, "document-format-default", IPP_TAG_MIMETYPE, IPP_TAG_PRINTER },
{ 1, "document-numbers", IPP_TAG_RANGE, IPP_TAG_JOB,
IPP_TAG_DOCUMENT },
{ 1, "exclude-schemes", IPP_TAG_NAME, IPP_TAG_OPERATION },
{ 1, "finishings", IPP_TAG_ENUM, IPP_TAG_JOB,
IPP_TAG_DOCUMENT },
{ 1, "finishings-default", IPP_TAG_ENUM, IPP_TAG_PRINTER },
{ 0, "fit-to-page", IPP_TAG_BOOLEAN, IPP_TAG_JOB,
IPP_TAG_DOCUMENT },
{ 0, "fit-to-page-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER },
{ 0, "fitplot", IPP_TAG_BOOLEAN, IPP_TAG_JOB },
{ 0, "fitplot-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER },
{ 0, "gamma", IPP_TAG_INTEGER, IPP_TAG_JOB },
{ 0, "gamma-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 0, "hue", IPP_TAG_INTEGER, IPP_TAG_JOB },
{ 0, "hue-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 1, "include-schemes", IPP_TAG_NAME, IPP_TAG_OPERATION },
{ 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-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-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-completed", IPP_TAG_INTEGER, IPP_TAG_ZERO }, /* never send as option */
{ 0, "job-page-limit", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 0, "job-priority", IPP_TAG_INTEGER, IPP_TAG_JOB },
{ 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 },
{ 0, "job-state", IPP_TAG_ENUM, IPP_TAG_ZERO }, /* never send as option */
{ 0, "job-state-message", IPP_TAG_TEXT, IPP_TAG_ZERO }, /* never send as option */
{ 0, "job-state-reasons", IPP_TAG_KEYWORD, IPP_TAG_ZERO }, /* never send as option */
{ 0, "job-uuid", IPP_TAG_URI, IPP_TAG_JOB },
{ 0, "landscape", IPP_TAG_BOOLEAN, IPP_TAG_JOB },
{ 1, "marker-change-time", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 1, "marker-colors", IPP_TAG_NAME, IPP_TAG_PRINTER },
{ 1, "marker-high-levels", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 1, "marker-levels", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 1, "marker-low-levels", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 0, "marker-message", IPP_TAG_TEXT, IPP_TAG_PRINTER },
{ 1, "marker-names", IPP_TAG_NAME, IPP_TAG_PRINTER },
{ 1, "marker-types", IPP_TAG_KEYWORD, IPP_TAG_PRINTER },
{ 1, "media", IPP_TAG_KEYWORD, 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 },
{ 0, "media-color", IPP_TAG_KEYWORD, IPP_TAG_JOB,
IPP_TAG_DOCUMENT },
{ 1, "media-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER },
{ 0, "media-key", IPP_TAG_KEYWORD, IPP_TAG_JOB,
IPP_TAG_DOCUMENT },
{ 0, "media-size", IPP_TAG_BEGIN_COLLECTION, 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, "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 },
{ 1, "notify-events", IPP_TAG_KEYWORD, IPP_TAG_SUBSCRIPTION },
{ 1, "notify-events-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER },
{ 0, "notify-lease-duration", IPP_TAG_INTEGER, IPP_TAG_SUBSCRIPTION },
{ 0, "notify-lease-duration-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 0, "notify-natural-language", IPP_TAG_LANGUAGE, IPP_TAG_SUBSCRIPTION },
{ 0, "notify-pull-method", IPP_TAG_KEYWORD, IPP_TAG_SUBSCRIPTION },
{ 0, "notify-recipient-uri", IPP_TAG_URI, IPP_TAG_SUBSCRIPTION },
{ 0, "notify-time-interval", IPP_TAG_INTEGER, IPP_TAG_SUBSCRIPTION },
{ 0, "notify-user-data", IPP_TAG_STRING, IPP_TAG_SUBSCRIPTION },
{ 0, "number-up", IPP_TAG_INTEGER, IPP_TAG_JOB,
IPP_TAG_DOCUMENT },
{ 0, "number-up-default", IPP_TAG_INTEGER, 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 },
{ 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-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 },
{ 0, "page-top-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 1, "pages", IPP_TAG_RANGE, IPP_TAG_JOB,
IPP_TAG_DOCUMENT },
{ 0, "penwidth", IPP_TAG_INTEGER, IPP_TAG_JOB },
{ 0, "penwidth-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 0, "port-monitor", IPP_TAG_NAME, IPP_TAG_PRINTER },
{ 0, "ppd-name", IPP_TAG_NAME, IPP_TAG_PRINTER },
{ 0, "ppi", IPP_TAG_INTEGER, IPP_TAG_JOB },
{ 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-quality", IPP_TAG_ENUM, IPP_TAG_JOB,
IPP_TAG_DOCUMENT },
{ 0, "print-quality-default", IPP_TAG_ENUM, IPP_TAG_PRINTER },
{ 1, "printer-commands", IPP_TAG_KEYWORD, IPP_TAG_PRINTER },
{ 0, "printer-error-policy", IPP_TAG_NAME, IPP_TAG_PRINTER },
{ 0, "printer-info", IPP_TAG_TEXT, 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-location", IPP_TAG_TEXT, IPP_TAG_PRINTER },
{ 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 },
{ 0, "printer-resolution", IPP_TAG_RESOLUTION, IPP_TAG_JOB,
IPP_TAG_DOCUMENT },
{ 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 },
{ 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 },
{ 0, "queued-job-count", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 0, "raw", IPP_TAG_MIMETYPE, IPP_TAG_OPERATION },
{ 1, "requested-attributes", IPP_TAG_NAME, IPP_TAG_OPERATION },
{ 1, "requesting-user-name-allowed", IPP_TAG_NAME, IPP_TAG_PRINTER },
{ 1, "requesting-user-name-denied", IPP_TAG_NAME, IPP_TAG_PRINTER },
{ 0, "resolution", IPP_TAG_RESOLUTION, IPP_TAG_JOB },
{ 0, "resolution-default", IPP_TAG_RESOLUTION, IPP_TAG_PRINTER },
{ 0, "saturation", IPP_TAG_INTEGER, IPP_TAG_JOB },
{ 0, "saturation-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 0, "scaling", IPP_TAG_INTEGER, IPP_TAG_JOB },
{ 0, "scaling-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
{ 0, "sides", IPP_TAG_KEYWORD, IPP_TAG_JOB,
IPP_TAG_DOCUMENT },
{ 0, "sides-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER },
{ 0, "time-at-completed", IPP_TAG_INTEGER, IPP_TAG_ZERO }, /* never send as option */
{ 0, "time-at-creation", IPP_TAG_INTEGER, IPP_TAG_ZERO }, /* never send as option */
{ 0, "time-at-processing", IPP_TAG_INTEGER, IPP_TAG_ZERO }, /* never send as option */
{ 0, "wrap", IPP_TAG_BOOLEAN, IPP_TAG_JOB },
{ 0, "wrap-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER },
{ 0, "x-dimension", IPP_TAG_INTEGER, IPP_TAG_JOB,
IPP_TAG_DOCUMENT },
{ 0, "y-dimension", IPP_TAG_INTEGER, IPP_TAG_JOB,
IPP_TAG_DOCUMENT }
};
/*
* Local functions...
*/
static int compare_ipp_options(_ipp_option_t *a, _ipp_option_t *b);
/*
* 'cupsEncodeOptions()' - Encode printer options into IPP attributes.
*
* This function adds operation, job, and then subscription attributes,
* in that order. Use the cupsEncodeOptions2() function to add attributes
* for a single group.
*/
void
cupsEncodeOptions(ipp_t *ipp, /* I - Request to add to */
int num_options, /* I - Number of options */
cups_option_t *options) /* I - Options */
{
DEBUG_printf(("cupsEncodeOptions(%p, %d, %p)", ipp, num_options, options));
/*
* Add the options in the proper groups & order...
*/
cupsEncodeOptions2(ipp, num_options, options, IPP_TAG_OPERATION);
cupsEncodeOptions2(ipp, num_options, options, IPP_TAG_JOB);
cupsEncodeOptions2(ipp, num_options, options, IPP_TAG_SUBSCRIPTION);
}
/*
* 'cupsEncodeOptions2()' - Encode printer options into IPP attributes for a group.
*
* This function only adds attributes for a single group. Call this
* function multiple times for each group, or use cupsEncodeOptions()
* to add the standard groups.
*
* @since CUPS 1.2/OS X 10.5@
*/
void
cupsEncodeOptions2(
ipp_t *ipp, /* I - Request to add to */
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 */
cups_option_t *option; /* Current option */
ipp_t *collection; /* Collection value */
int num_cols; /* Number of collection values */
cups_option_t *cols; /* Collection values */
DEBUG_printf(("cupsEncodeOptions2(ipp=%p, num_options=%d, options=%p, "
"group_tag=%x)", ipp, num_options, options, group_tag));
/*
* Range check input...
*/
if (!ipp || num_options < 1 || !options)
return;
/*
* Do special handling for the document-format/raw options...
*/
if (group_tag == IPP_TAG_OPERATION)
{
/*
* 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);
else if (cupsGetOption("raw", num_options, options))
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");
}
/*
* Then loop through the options...
*/
for (i = num_options, option = options; i > 0; i --, option ++)
{
_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])
continue;
/*
* Figure out the proper value and group tags for this option...
*/
if ((match = _ippFindOption(option->name)) != NULL)
{
if (match->group_tag != group_tag && match->alt_group_tag != group_tag)
continue;
value_tag = match->value_tag;
}
else
{
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 (group_tag != IPP_TAG_JOB && group_tag != IPP_TAG_DOCUMENT)
continue;
}
else if (group_tag != IPP_TAG_PRINTER)
continue;
if (!_cups_strcasecmp(option->value, "true") ||
!_cups_strcasecmp(option->value, "false"))
value_tag = IPP_TAG_BOOLEAN;
else
value_tag = IPP_TAG_NAME;
}
/*
* 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 ++;
}
}
else
count = 1;
DEBUG_printf(("2cupsEncodeOptions2: option=\"%s\", count=%d",
option->name, 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...
*/
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 = 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 = strtol(val, &s, 10);
if (*s == '-')
{
if (s[1])
attr->values[j].range.upper = 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 = strtol(val, &s, 10);
if (*s == 'x')
attr->values[j].resolution.yres = 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);
}
}
/*
* '_ippFindOption()' - Find the attribute information for an option.
*/
_ipp_option_t * /* O - Attribute information */
_ippFindOption(const char *name) /* I - Option/attribute name */
{
_ipp_option_t key; /* Search key */
/*
* Lookup the proper value and group tags for this option...
*/
key.name = name;
return ((_ipp_option_t *)bsearch(&key, ipp_options,
sizeof(ipp_options) / sizeof(ipp_options[0]),
sizeof(ipp_options[0]),
(int (*)(const void *, const void *))
compare_ipp_options));
}
/*
* 'compare_ipp_options()' - Compare two IPP options.
*/
static int /* O - Result of comparison */
compare_ipp_options(_ipp_option_t *a, /* I - First option */
_ipp_option_t *b) /* I - Second option */
{
return (strcmp(a->name, b->name));
}
/*
* End of "$Id: encode.c 7696 2008-06-26 00:54:42Z mike $".
*/

137
cups/file-private.h Normal file
View File

@@ -0,0 +1,137 @@
/*
* "$Id: file-private.h 3275 2011-05-20 07:26:13Z msweet $"
*
* Private file definitions for CUPS.
*
* Since stdio files max out at 256 files on many systems, we have to
* write similar functions without this limit. At the same time, using
* our own file functions allows us to provide transparent support of
* gzip'd print files, PPD files, etc.
*
* Copyright 2007-2011 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/".
*/
#ifndef _CUPS_FILE_PRIVATE_H_
# define _CUPS_FILE_PRIVATE_H_
/*
* Include necessary headers...
*/
# include "cups-private.h"
# include <stdio.h>
# include <stdlib.h>
# include <stdarg.h>
# include <fcntl.h>
# ifdef HAVE_LIBZ
# include <zlib.h>
# endif /* HAVE_LIBZ */
# ifdef WIN32
# include <io.h>
# include <sys/locking.h>
# endif /* WIN32 */
/*
* Some operating systems support large files via open flag O_LARGEFILE...
*/
# ifndef O_LARGEFILE
# define O_LARGEFILE 0
# endif /* !O_LARGEFILE */
/*
* Some operating systems don't define O_BINARY, which is used by Microsoft
* and IBM to flag binary files...
*/
# ifndef O_BINARY
# define O_BINARY 0
# endif /* !O_BINARY */
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/*
* Types and structures...
*/
typedef enum /**** _cupsFileCheck return values ****/
{
_CUPS_FILE_CHECK_OK = 0, /* Everything OK */
_CUPS_FILE_CHECK_MISSING = 1, /* File is missing */
_CUPS_FILE_CHECK_PERMISSIONS = 2, /* File (or parent dir) has bad perms */
_CUPS_FILE_CHECK_WRONG_TYPE = 3, /* File has wrong type */
_CUPS_FILE_CHECK_RELATIVE_PATH = 4 /* File contains a relative path */
} _cups_fc_result_t;
typedef enum /**** _cupsFileCheck file type values ****/
{
_CUPS_FILE_CHECK_FILE = 0, /* Check the file and parent directory */
_CUPS_FILE_CHECK_PROGRAM = 1, /* Check the program and parent directory */
_CUPS_FILE_CHECK_FILE_ONLY = 2, /* Check the file only */
_CUPS_FILE_CHECK_DIRECTORY = 3 /* Check the directory */
} _cups_fc_filetype_t;
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);
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_FILE_PRIVATE_H_ */
/*
* End of "$Id: file-private.h 3275 2011-05-20 07:26:13Z msweet $".
*/

2718
cups/file.c Normal file

File diff suppressed because it is too large Load Diff

116
cups/file.h Normal file
View File

@@ -0,0 +1,116 @@
/*
* "$Id: file.h 7460 2008-04-16 02:19:54Z mike $"
*
* Public file definitions for CUPS.
*
* Since stdio files max out at 256 files on many systems, we have to
* write similar functions without this limit. At the same time, using
* our own file functions allows us to provide transparent support of
* gzip'd print files, PPD files, etc.
*
* Copyright 2007-2011 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/".
*/
#ifndef _CUPS_FILE_H_
# define _CUPS_FILE_H_
/*
* Include necessary headers...
*/
# include "versioning.h"
# include <stddef.h>
# include <sys/types.h>
# 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 */
/*
* C++ magic...
*/
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/*
* CUPS file definitions...
*/
# define CUPS_FILE_NONE 0 /* No compression */
# define CUPS_FILE_GZIP 1 /* GZIP compression */
/*
* Types and structures...
*/
typedef struct _cups_file_s cups_file_t;/**** CUPS file type ****/
/*
* Prototypes...
*/
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 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 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 *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 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 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;
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;
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_FILE_H_ */
/*
* End of "$Id: file.h 7460 2008-04-16 02:19:54Z mike $".
*/

283
cups/getdevices.c Normal file
View File

@@ -0,0 +1,283 @@
/*
* "$Id: getdevices.c 3794 2012-04-23 22:44:16Z msweet $"
*
* cupsGetDevices implementation for CUPS.
*
* 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*
* Contents:
*
* cupsGetDevices() - Get available printer devices.
*/
/*
* Include necessary headers...
*/
#include "cups-private.h"
/*
* 'cupsGetDevices()' - Get available printer devices.
*
* This function sends a CUPS-Get-Devices request and streams the discovered
* devices to the specified callback function. The "timeout" parameter controls
* how long the request lasts, while the "include_schemes" and "exclude_schemes"
* parameters provide comma-delimited lists of backends to include or omit from
* the request respectively.
*
* @since CUPS 1.4/OS X 10.6@
*/
ipp_status_t /* O - Request status - @code IPP_OK@ on success. */
cupsGetDevices(
http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
int timeout, /* I - Timeout in seconds or @code CUPS_TIMEOUT_DEFAULT@ */
const char *include_schemes, /* I - Comma-separated URI schemes to include or @code CUPS_INCLUDE_ALL@ */
const char *exclude_schemes, /* I - Comma-separated URI schemes to exclude or @code CUPS_EXCLUDE_NONE@ */
cups_device_cb_t callback, /* I - Callback function */
void *user_data) /* I - User data pointer */
{
ipp_t *request, /* CUPS-Get-Devices request */
*response; /* CUPS-Get-Devices response */
ipp_attribute_t *attr; /* Current attribute */
const char *device_class, /* device-class value */
*device_id, /* device-id value */
*device_info, /* device-info value */
*device_location, /* device-location value */
*device_make_and_model, /* device-make-and-model value */
*device_uri; /* device-uri value */
int blocking; /* Current blocking-IO mode */
cups_option_t option; /* in/exclude-schemes option */
http_status_t status; /* HTTP status of request */
ipp_state_t state; /* IPP response state */
/*
* Range check input...
*/
DEBUG_printf(("cupsGetDevices(http=%p, timeout=%d, include_schemes=\"%s\", "
"exclude_schemes=\"%s\", callback=%p, user_data=%p)", http,
timeout, include_schemes, exclude_schemes, callback,
user_data));
if (!callback)
return (IPP_INTERNAL_ERROR);
if (!http)
http = _cupsConnect();
if (!http)
return (IPP_SERVICE_UNAVAILABLE);
/*
* Create a CUPS-Get-Devices request...
*/
request = ippNewRequest(CUPS_GET_DEVICES);
if (timeout > 0)
ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "timeout",
timeout);
if (include_schemes)
{
option.name = "include-schemes";
option.value = (char *)include_schemes;
cupsEncodeOptions2(request, 1, &option, IPP_TAG_OPERATION);
}
if (exclude_schemes)
{
option.name = "exclude-schemes";
option.value = (char *)exclude_schemes;
cupsEncodeOptions2(request, 1, &option, IPP_TAG_OPERATION);
}
/*
* Send the request and do any necessary authentication...
*/
do
{
DEBUG_puts("2cupsGetDevices: Sending request...");
status = cupsSendRequest(http, request, "/", ippLength(request));
DEBUG_puts("2cupsGetDevices: Waiting for response status...");
while (status == HTTP_CONTINUE)
status = httpUpdate(http);
if (status != HTTP_OK)
{
httpFlush(http);
if (status == HTTP_UNAUTHORIZED)
{
/*
* See if we can do authentication...
*/
DEBUG_puts("2cupsGetDevices: Need authorization...");
if (!cupsDoAuthentication(http, "POST", "/"))
httpReconnect(http);
else
{
status = HTTP_AUTHORIZATION_CANCELED;
break;
}
}
#ifdef HAVE_SSL
else if (status == HTTP_UPGRADE_REQUIRED)
{
/*
* Force a reconnect with encryption...
*/
DEBUG_puts("2cupsGetDevices: Need encryption...");
if (!httpReconnect(http))
httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
}
#endif /* HAVE_SSL */
}
}
while (status == HTTP_UNAUTHORIZED || status == HTTP_UPGRADE_REQUIRED);
DEBUG_printf(("2cupsGetDevices: status=%d", status));
ippDelete(request);
if (status != HTTP_OK)
{
_cupsSetHTTPError(status);
return (cupsLastError());
}
/*
* Read the response in non-blocking mode...
*/
blocking = httpGetBlocking(http);
httpBlocking(http, 0);
response = ippNew();
device_class = NULL;
device_id = NULL;
device_info = NULL;
device_location = "";
device_make_and_model = NULL;
device_uri = NULL;
attr = NULL;
DEBUG_puts("2cupsGetDevices: Reading response...");
do
{
if ((state = ippRead(http, response)) == IPP_ERROR)
break;
DEBUG_printf(("2cupsGetDevices: state=%d, response->last=%p", state,
response->last));
if (!response->attrs)
continue;
while (attr != response->last)
{
if (!attr)
attr = response->attrs;
else
attr = attr->next;
DEBUG_printf(("2cupsGetDevices: attr->name=\"%s\", attr->value_tag=%d",
attr->name, attr->value_tag));
if (!attr->name)
{
if (device_class && device_id && device_info && device_make_and_model &&
device_uri)
(*callback)(device_class, device_id, device_info,
device_make_and_model, device_uri, device_location,
user_data);
device_class = NULL;
device_id = NULL;
device_info = NULL;
device_location = "";
device_make_and_model = NULL;
device_uri = NULL;
}
else if (!strcmp(attr->name, "device-class") &&
attr->value_tag == IPP_TAG_KEYWORD)
device_class = attr->values[0].string.text;
else if (!strcmp(attr->name, "device-id") &&
attr->value_tag == IPP_TAG_TEXT)
device_id = attr->values[0].string.text;
else if (!strcmp(attr->name, "device-info") &&
attr->value_tag == IPP_TAG_TEXT)
device_info = attr->values[0].string.text;
else if (!strcmp(attr->name, "device-location") &&
attr->value_tag == IPP_TAG_TEXT)
device_location = attr->values[0].string.text;
else if (!strcmp(attr->name, "device-make-and-model") &&
attr->value_tag == IPP_TAG_TEXT)
device_make_and_model = attr->values[0].string.text;
else if (!strcmp(attr->name, "device-uri") &&
attr->value_tag == IPP_TAG_URI)
device_uri = attr->values[0].string.text;
}
}
while (state != IPP_DATA);
DEBUG_printf(("2cupsGetDevices: state=%d, response->last=%p", state,
response->last));
if (device_class && device_id && device_info && device_make_and_model &&
device_uri)
(*callback)(device_class, device_id, device_info,
device_make_and_model, device_uri, device_location, user_data);
/*
* Set the IPP status and return...
*/
httpBlocking(http, blocking);
httpFlush(http);
if (status == HTTP_ERROR)
_cupsSetError(IPP_INTERNAL_ERROR, strerror(http->error), 0);
else
{
attr = ippFindAttribute(response, "status-message", IPP_TAG_TEXT);
DEBUG_printf(("cupsGetDevices: status-code=%s, status-message=\"%s\"",
ippErrorString(response->request.status.status_code),
attr ? attr->values[0].string.text : ""));
_cupsSetError(response->request.status.status_code,
attr ? attr->values[0].string.text :
ippErrorString(response->request.status.status_code), 0);
}
ippDelete(response);
return (cupsLastError());
}
/*
* End of "$Id: getdevices.c 3794 2012-04-23 22:44:16Z msweet $".
*/

266
cups/getifaddrs.c Normal file
View File

@@ -0,0 +1,266 @@
/*
* "$Id: getifaddrs.c 6649 2007-07-11 21:46:42Z mike $"
*
* Network interface functions for CUPS.
*
* Copyright 2007-2010 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/".
*
* Contents:
*
* _cups_getifaddrs() - Get a list of network interfaces on the system.
* _cups_freeifaddrs() - Free an interface list...
*/
/*
* Include necessary headers.
*/
#include "http-private.h"
#ifndef HAVE_GETIFADDRS
/*
* '_cups_getifaddrs()' - Get a list of network interfaces on the system.
*/
int /* O - 0 on success, -1 on error */
_cups_getifaddrs(struct ifaddrs **addrs)/* O - List of interfaces */
{
int sock; /* Socket */
char buffer[65536], /* Buffer for address info */
*bufptr, /* Pointer into buffer */
*bufend; /* End of buffer */
struct ifconf conf; /* Interface configurations */
struct sockaddr addr; /* Address data */
struct ifreq *ifp; /* Interface data */
int ifpsize; /* Size of interface data */
struct ifaddrs *temp; /* Pointer to current interface */
struct ifreq request; /* Interface request */
/*
* Start with an empty list...
*/
if (addrs == NULL)
return (-1);
*addrs = NULL;
/*
* Create a UDP socket to get the interface data...
*/
memset (&addr, 0, sizeof(addr));
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
return (-1);
/*
* Try to get the list of interfaces...
*/
conf.ifc_len = sizeof(buffer);
conf.ifc_buf = buffer;
if (ioctl(sock, SIOCGIFCONF, &conf) < 0)
{
/*
* Couldn't get the list of interfaces...
*/
close(sock);
return (-1);
}
/*
* OK, got the list of interfaces, now lets step through the
* buffer to pull them out...
*/
# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
# define sockaddr_len(a) ((a)->sa_len)
# else
# define sockaddr_len(a) (sizeof(struct sockaddr))
# endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
for (bufptr = buffer, bufend = buffer + conf.ifc_len;
bufptr < bufend;
bufptr += ifpsize)
{
/*
* Get the current interface information...
*/
ifp = (struct ifreq *)bufptr;
ifpsize = sizeof(ifp->ifr_name) + sockaddr_len(&(ifp->ifr_addr));
if (ifpsize < sizeof(struct ifreq))
ifpsize = sizeof(struct ifreq);
memset(&request, 0, sizeof(request));
memcpy(request.ifr_name, ifp->ifr_name, sizeof(ifp->ifr_name));
/*
* Check the status of the interface...
*/
if (ioctl(sock, SIOCGIFFLAGS, &request) < 0)
continue;
/*
* Allocate memory for a single interface record...
*/
if ((temp = calloc(1, sizeof(struct ifaddrs))) == NULL)
{
/*
* Unable to allocate memory...
*/
close(sock);
return (-1);
}
/*
* Add this record to the front of the list and copy the name, flags,
* and network address...
*/
temp->ifa_next = *addrs;
*addrs = temp;
temp->ifa_name = strdup(ifp->ifr_name);
temp->ifa_flags = request.ifr_flags;
if ((temp->ifa_addr = calloc(1, sockaddr_len(&(ifp->ifr_addr)))) != NULL)
memcpy(temp->ifa_addr, &(ifp->ifr_addr), sockaddr_len(&(ifp->ifr_addr)));
/*
* Try to get the netmask for the interface...
*/
if (!ioctl(sock, SIOCGIFNETMASK, &request))
{
/*
* Got it, make a copy...
*/
if ((temp->ifa_netmask = calloc(1, sizeof(request.ifr_netmask))) != NULL)
memcpy(temp->ifa_netmask, &(request.ifr_netmask),
sizeof(request.ifr_netmask));
}
/*
* Then get the broadcast or point-to-point (destination) address,
* if applicable...
*/
if (temp->ifa_flags & IFF_BROADCAST)
{
/*
* Have a broadcast address, so get it!
*/
if (!ioctl(sock, SIOCGIFBRDADDR, &request))
{
/*
* Got it, make a copy...
*/
if ((temp->ifa_broadaddr =
calloc(1, sizeof(request.ifr_broadaddr))) != NULL)
memcpy(temp->ifa_broadaddr, &(request.ifr_broadaddr),
sizeof(request.ifr_broadaddr));
}
}
else if (temp->ifa_flags & IFF_POINTOPOINT)
{
/*
* Point-to-point interface; grab the remote address...
*/
if (!ioctl(sock, SIOCGIFDSTADDR, &request))
{
temp->ifa_dstaddr = malloc(sizeof(request.ifr_dstaddr));
memcpy(temp->ifa_dstaddr, &(request.ifr_dstaddr),
sizeof(request.ifr_dstaddr));
}
}
}
/*
* OK, we're done with the socket, close it and return 0...
*/
close(sock);
return (0);
}
/*
* '_cups_freeifaddrs()' - Free an interface list...
*/
void
_cups_freeifaddrs(struct ifaddrs *addrs)/* I - Interface list to free */
{
struct ifaddrs *next; /* Next interface in list */
while (addrs != NULL)
{
/*
* Make a copy of the next interface pointer...
*/
next = addrs->ifa_next;
/*
* Free data values as needed...
*/
if (addrs->ifa_name)
{
free(addrs->ifa_name);
addrs->ifa_name = NULL;
}
if (addrs->ifa_addr)
{
free(addrs->ifa_addr);
addrs->ifa_addr = NULL;
}
if (addrs->ifa_netmask)
{
free(addrs->ifa_netmask);
addrs->ifa_netmask = NULL;
}
if (addrs->ifa_dstaddr)
{
free(addrs->ifa_dstaddr);
addrs->ifa_dstaddr = NULL;
}
/*
* Free this node and continue to the next...
*/
free(addrs);
addrs = next;
}
}
#endif /* !HAVE_GETIFADDRS */
/*
* End of "$Id: getifaddrs.c 6649 2007-07-11 21:46:42Z mike $".
*/

502
cups/getputfile.c Normal file
View File

@@ -0,0 +1,502 @@
/*
* "$Id: getputfile.c 7359 2008-02-29 19:01:35Z mike $"
*
* Get/put file functions 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/".
*
* This file is subject to the Apple OS-Developed Software exception.
*
* Contents:
*
* cupsGetFd() - Get a file from the server.
* cupsGetFile() - Get a file from the server.
* cupsPutFd() - Put a file on the server.
* cupsPutFile() - Put a file on the server.
*/
/*
* Include necessary headers...
*/
#include "cups-private.h"
#include <fcntl.h>
#include <sys/stat.h>
#if defined(WIN32) || defined(__EMX__)
# include <io.h>
#else
# include <unistd.h>
#endif /* WIN32 || __EMX__ */
/*
* 'cupsGetFd()' - Get a file from the server.
*
* This function returns @code HTTP_OK@ when the file is successfully retrieved.
*
* @since CUPS 1.1.20/OS X 10.4@
*/
http_status_t /* O - HTTP status */
cupsGetFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
const char *resource, /* I - Resource name */
int fd) /* I - File descriptor */
{
int bytes; /* Number of bytes read */
char buffer[8192]; /* Buffer for file */
http_status_t status; /* HTTP status from server */
char if_modified_since[HTTP_MAX_VALUE];
/* If-Modified-Since header */
/*
* Range check input...
*/
DEBUG_printf(("cupsGetFd(http=%p, resource=\"%s\", fd=%d)", http,
resource, fd));
if (!resource || fd < 0)
{
if (http)
http->error = EINVAL;
return (HTTP_ERROR);
}
if (!http)
if ((http = _cupsConnect()) == NULL)
return (HTTP_SERVICE_UNAVAILABLE);
/*
* Then send GET requests to the HTTP server...
*/
strlcpy(if_modified_since, httpGetField(http, HTTP_FIELD_IF_MODIFIED_SINCE),
sizeof(if_modified_since));
do
{
httpClearFields(http);
httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);
httpSetField(http, HTTP_FIELD_IF_MODIFIED_SINCE, if_modified_since);
if (httpGet(http, resource))
{
if (httpReconnect(http))
{
status = HTTP_ERROR;
break;
}
else
{
status = HTTP_UNAUTHORIZED;
continue;
}
}
while ((status = httpUpdate(http)) == HTTP_CONTINUE);
if (status == HTTP_UNAUTHORIZED)
{
/*
* Flush any error message...
*/
httpFlush(http);
/*
* See if we can do authentication...
*/
if (cupsDoAuthentication(http, "GET", resource))
{
status = HTTP_AUTHORIZATION_CANCELED;
break;
}
if (httpReconnect(http))
{
status = HTTP_ERROR;
break;
}
continue;
}
#ifdef HAVE_SSL
else if (status == HTTP_UPGRADE_REQUIRED)
{
/* Flush any error message... */
httpFlush(http);
/* Reconnect... */
if (httpReconnect(http))
{
status = HTTP_ERROR;
break;
}
/* Upgrade with encryption... */
httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
/* Try again, this time with encryption enabled... */
continue;
}
#endif /* HAVE_SSL */
}
while (status == HTTP_UNAUTHORIZED || status == HTTP_UPGRADE_REQUIRED);
/*
* See if we actually got the file or an error...
*/
if (status == HTTP_OK)
{
/*
* Yes, copy the file...
*/
while ((bytes = httpRead2(http, buffer, sizeof(buffer))) > 0)
write(fd, buffer, bytes);
}
else
{
_cupsSetHTTPError(status);
httpFlush(http);
}
/*
* Return the request status...
*/
DEBUG_printf(("1cupsGetFd: Returning %d...", status));
return (status);
}
/*
* 'cupsGetFile()' - Get a file from the server.
*
* This function returns @code HTTP_OK@ when the file is successfully retrieved.
*
* @since CUPS 1.1.20/OS X 10.4@
*/
http_status_t /* O - HTTP status */
cupsGetFile(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
const char *resource, /* I - Resource name */
const char *filename) /* I - Filename */
{
int fd; /* File descriptor */
http_status_t status; /* Status */
/*
* Range check input...
*/
if (!http || !resource || !filename)
{
if (http)
http->error = EINVAL;
return (HTTP_ERROR);
}
/*
* Create the file...
*/
if ((fd = open(filename, O_WRONLY | O_EXCL | O_TRUNC)) < 0)
{
/*
* Couldn't open the file!
*/
http->error = errno;
return (HTTP_ERROR);
}
/*
* Get the file...
*/
status = cupsGetFd(http, resource, fd);
/*
* If the file couldn't be gotten, then remove the file...
*/
close(fd);
if (status != HTTP_OK)
unlink(filename);
/*
* Return the HTTP status code...
*/
return (status);
}
/*
* 'cupsPutFd()' - Put a file on the server.
*
* This function returns @code HTTP_CREATED@ when the file is stored
* successfully.
*
* @since CUPS 1.1.20/OS X 10.4@
*/
http_status_t /* O - HTTP status */
cupsPutFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
const char *resource, /* I - Resource name */
int fd) /* I - File descriptor */
{
int bytes, /* Number of bytes read */
retries; /* Number of retries */
char buffer[8192]; /* Buffer for file */
http_status_t status; /* HTTP status from server */
/*
* Range check input...
*/
DEBUG_printf(("cupsPutFd(http=%p, resource=\"%s\", fd=%d)", http,
resource, fd));
if (!resource || fd < 0)
{
if (http)
http->error = EINVAL;
return (HTTP_ERROR);
}
if (!http)
if ((http = _cupsConnect()) == NULL)
return (HTTP_SERVICE_UNAVAILABLE);
/*
* Then send PUT requests to the HTTP server...
*/
retries = 0;
do
{
DEBUG_printf(("2cupsPutFd: starting attempt, authstring=\"%s\"...",
http->authstring));
httpClearFields(http);
httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);
httpSetField(http, HTTP_FIELD_TRANSFER_ENCODING, "chunked");
httpSetExpect(http, HTTP_CONTINUE);
if (httpPut(http, resource))
{
if (httpReconnect(http))
{
status = HTTP_ERROR;
break;
}
else
{
status = HTTP_UNAUTHORIZED;
continue;
}
}
/*
* Wait up to 1 second for a 100-continue response...
*/
if (httpWait(http, 1000))
status = httpUpdate(http);
else
status = HTTP_CONTINUE;
if (status == HTTP_CONTINUE)
{
/*
* Copy the file...
*/
lseek(fd, 0, SEEK_SET);
while ((bytes = read(fd, buffer, sizeof(buffer))) > 0)
if (httpCheck(http))
{
if ((status = httpUpdate(http)) != HTTP_CONTINUE)
break;
}
else
httpWrite2(http, buffer, bytes);
}
if (status == HTTP_CONTINUE)
{
httpWrite2(http, buffer, 0);
while ((status = httpUpdate(http)) == HTTP_CONTINUE);
}
if (status == HTTP_ERROR && !retries)
{
DEBUG_printf(("2cupsPutFd: retry on status %d", status));
retries ++;
/* Flush any error message... */
httpFlush(http);
/* Reconnect... */
if (httpReconnect(http))
{
status = HTTP_ERROR;
break;
}
/* Try again... */
continue;
}
DEBUG_printf(("2cupsPutFd: status=%d", status));
if (status == HTTP_UNAUTHORIZED)
{
/*
* Flush any error message...
*/
httpFlush(http);
/*
* See if we can do authentication...
*/
if (cupsDoAuthentication(http, "PUT", resource))
{
status = HTTP_AUTHORIZATION_CANCELED;
break;
}
if (httpReconnect(http))
{
status = HTTP_ERROR;
break;
}
continue;
}
#ifdef HAVE_SSL
else if (status == HTTP_UPGRADE_REQUIRED)
{
/* Flush any error message... */
httpFlush(http);
/* Reconnect... */
if (httpReconnect(http))
{
status = HTTP_ERROR;
break;
}
/* Upgrade with encryption... */
httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
/* Try again, this time with encryption enabled... */
continue;
}
#endif /* HAVE_SSL */
}
while (status == HTTP_UNAUTHORIZED || status == HTTP_UPGRADE_REQUIRED ||
(status == HTTP_ERROR && retries < 2));
/*
* See if we actually put the file or an error...
*/
if (status != HTTP_CREATED)
{
_cupsSetHTTPError(status);
httpFlush(http);
}
DEBUG_printf(("1cupsPutFd: Returning %d...", status));
return (status);
}
/*
* 'cupsPutFile()' - Put a file on the server.
*
* This function returns @code HTTP_CREATED@ when the file is stored
* successfully.
*
* @since CUPS 1.1.20/OS X 10.4@
*/
http_status_t /* O - HTTP status */
cupsPutFile(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
const char *resource, /* I - Resource name */
const char *filename) /* I - Filename */
{
int fd; /* File descriptor */
http_status_t status; /* Status */
/*
* Range check input...
*/
if (!http || !resource || !filename)
{
if (http)
http->error = EINVAL;
return (HTTP_ERROR);
}
/*
* Open the local file...
*/
if ((fd = open(filename, O_RDONLY)) < 0)
{
/*
* Couldn't open the file!
*/
http->error = errno;
return (HTTP_ERROR);
}
/*
* Put the file...
*/
status = cupsPutFd(http, resource, fd);
close(fd);
return (status);
}
/*
* End of "$Id: getputfile.c 7359 2008-02-29 19:01:35Z mike $".
*/

384
cups/globals.c Normal file
View File

@@ -0,0 +1,384 @@
/*
* "$Id: globals.c 7870 2008-08-27 18:14:10Z mike $"
*
* Global variable access routines for CUPS.
*
* Copyright 2007-2013 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/".
*
* This file is subject to the Apple OS-Developed Software exception.
*
* Contents:
*
* _cupsGlobalLock() - Lock the global mutex.
* _cupsGlobals() - Return a pointer to thread local storage
* _cupsGlobalUnlock() - Unlock the global mutex.
* DllMain() - Main entry for library.
* cups_fix_path() - Fix a file path to use forward slashes consistently.
* cups_globals_alloc() - Allocate and initialize global data.
* cups_globals_free() - Free global data.
* cups_globals_init() - Initialize environment variables.
*/
/*
* Include necessary headers...
*/
#include "cups-private.h"
/*
* Local globals...
*/
static _cups_threadkey_t cups_globals_key = _CUPS_THREADKEY_INITIALIZER;
/* Thread local storage key */
#ifdef HAVE_PTHREAD_H
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)
static _cups_mutex_t cups_global_mutex = _CUPS_MUTEX_INITIALIZER;
/* Global critical section */
#endif /* HAVE_PTHREAD_H || WIN32 */
/*
* Local functions...
*/
#ifdef WIN32
static void cups_fix_path(char *path);
#endif /* WIN32 */
static _cups_globals_t *cups_globals_alloc(void);
#if defined(HAVE_PTHREAD_H) || defined(WIN32)
static void cups_globals_free(_cups_globals_t *g);
#endif /* HAVE_PTHREAD_H || WIN32 */
#ifdef HAVE_PTHREAD_H
static void cups_globals_init(void);
#endif /* HAVE_PTHREAD_H */
/*
* '_cupsGlobalLock()' - Lock the global mutex.
*/
void
_cupsGlobalLock(void)
{
#ifdef HAVE_PTHREAD_H
pthread_mutex_lock(&cups_global_mutex);
#elif defined(WIN32)
EnterCriticalSection(&cups_global_mutex.m_criticalSection);
#endif /* HAVE_PTHREAD_H */
}
/*
* '_cupsGlobals()' - Return a pointer to thread local storage
*/
_cups_globals_t * /* O - Pointer to global data */
_cupsGlobals(void)
{
_cups_globals_t *cg; /* Pointer to global data */
#ifdef HAVE_PTHREAD_H
/*
* Initialize the global data exactly once...
*/
pthread_once(&cups_globals_key_once, cups_globals_init);
#endif /* HAVE_PTHREAD_H */
/*
* See if we have allocated the data yet...
*/
if ((cg = (_cups_globals_t *)_cupsThreadGetData(cups_globals_key)) == NULL)
{
/*
* No, allocate memory as set the pointer for the key...
*/
if ((cg = cups_globals_alloc()) != NULL)
_cupsThreadSetData(cups_globals_key, cg);
}
/*
* Return the pointer to the data...
*/
return (cg);
}
/*
* '_cupsGlobalUnlock()' - Unlock the global mutex.
*/
void
_cupsGlobalUnlock(void)
{
#ifdef HAVE_PTHREAD_H
pthread_mutex_unlock(&cups_global_mutex);
#elif defined(WIN32)
LeaveCriticalSection(&cups_global_mutex.m_criticalSection);
#endif /* HAVE_PTHREAD_H */
}
#ifdef WIN32
/*
* 'DllMain()' - Main entry for library.
*/
BOOL WINAPI /* O - Success/failure */
DllMain(HINSTANCE hinst, /* I - DLL module handle */
DWORD reason, /* I - Reason */
LPVOID reserved) /* I - Unused */
{
_cups_globals_t *cg; /* Global data */
(void)hinst;
(void)reserved;
switch (reason)
{
case DLL_PROCESS_ATTACH : /* Called on library initialization */
InitializeCriticalSection(&cups_global_mutex.m_criticalSection);
if ((cups_globals_key = TlsAlloc()) == TLS_OUT_OF_INDEXES)
return (FALSE);
break;
case DLL_THREAD_DETACH : /* Called when a thread terminates */
if ((cg = (_cups_globals_t *)TlsGetValue(cups_globals_key)) != NULL)
cups_globals_free(cg);
break;
case DLL_PROCESS_DETACH : /* Called when library is unloaded */
if ((cg = (_cups_globals_t *)TlsGetValue(cups_globals_key)) != NULL)
cups_globals_free(cg);
TlsFree(cups_globals_key);
DeleteCriticalSection(&cups_global_mutex.m_criticalSection);
break;
default:
break;
}
return (TRUE);
}
#endif /* WIN32 */
/*
* 'cups_globals_alloc()' - Allocate and initialize global data.
*/
static _cups_globals_t * /* O - Pointer to global data */
cups_globals_alloc(void)
{
_cups_globals_t *cg = malloc(sizeof(_cups_globals_t));
/* Pointer to global data */
#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 */
if (!cg)
return (NULL);
/*
* Clear the global storage and set the default encryption and password
* callback values...
*/
memset(cg, 0, sizeof(_cups_globals_t));
cg->encryption = (http_encryption_t)-1;
cg->password_cb = (cups_password_cb2_t)_cupsGetPassword;
cg->any_root = 1;
cg->expired_certs = 1;
cg->expired_root = 1;
/*
* Then set directories as appropriate...
*/
#ifdef WIN32
if (!installdir[0])
{
/*
* Open the registry...
*/
strcpy(installdir, "C:/Program Files/cups.org");
if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\cups.org", 0, KEY_READ,
&key))
{
/*
* Grab the installation directory...
*/
char *ptr; /* Pointer into installdir */
size = sizeof(installdir);
RegQueryValueEx(key, "installdir", NULL, NULL, installdir, &size);
RegCloseKey(key);
for (ptr = installdir; *ptr;)
{
if (*ptr == '\\')
{
if (ptr[1])
*ptr++ = '/';
else
*ptr = '\0'; /* Strip trailing \ */
}
else if (*ptr == '/' && !ptr[1])
*ptr = '\0'; /* Strip trailing / */
else
ptr ++;
}
}
snprintf(confdir, sizeof(confdir), "%s/conf", installdir);
snprintf(localedir, sizeof(localedir), "%s/locale", installdir);
}
if ((cg->cups_datadir = getenv("CUPS_DATADIR")) == NULL)
cg->cups_datadir = installdir;
if ((cg->cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
cg->cups_serverbin = installdir;
if ((cg->cups_serverroot = getenv("CUPS_SERVERROOT")) == NULL)
cg->cups_serverroot = confdir;
if ((cg->cups_statedir = getenv("CUPS_STATEDIR")) == NULL)
cg->cups_statedir = confdir;
if ((cg->localedir = getenv("LOCALEDIR")) == NULL)
cg->localedir = localedir;
#else
# ifdef HAVE_GETEUID
if ((geteuid() != getuid() && getuid()) || getegid() != getgid())
# else
if (!getuid())
# endif /* HAVE_GETEUID */
{
/*
* When running setuid/setgid, don't allow environment variables to override
* the directories...
*/
cg->cups_datadir = CUPS_DATADIR;
cg->cups_serverbin = CUPS_SERVERBIN;
cg->cups_serverroot = CUPS_SERVERROOT;
cg->cups_statedir = CUPS_STATEDIR;
cg->localedir = CUPS_LOCALEDIR;
}
else
{
/*
* Allow directories to be overridden by environment variables.
*/
if ((cg->cups_datadir = getenv("CUPS_DATADIR")) == NULL)
cg->cups_datadir = CUPS_DATADIR;
if ((cg->cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
cg->cups_serverbin = CUPS_SERVERBIN;
if ((cg->cups_serverroot = getenv("CUPS_SERVERROOT")) == NULL)
cg->cups_serverroot = CUPS_SERVERROOT;
if ((cg->cups_statedir = getenv("CUPS_STATEDIR")) == NULL)
cg->cups_statedir = CUPS_STATEDIR;
if ((cg->localedir = getenv("LOCALEDIR")) == NULL)
cg->localedir = CUPS_LOCALEDIR;
}
#endif /* WIN32 */
return (cg);
}
/*
* 'cups_globals_free()' - Free global data.
*/
#if defined(HAVE_PTHREAD_H) || defined(WIN32)
static void
cups_globals_free(_cups_globals_t *cg) /* I - Pointer to global data */
{
_cups_buffer_t *buffer, /* Current read/write buffer */
*next; /* Next buffer */
if (cg->last_status_message)
_cupsStrFree(cg->last_status_message);
for (buffer = cg->cups_buffers; buffer; buffer = next)
{
next = buffer->next;
free(buffer);
}
cupsArrayDelete(cg->leg_size_lut);
cupsArrayDelete(cg->ppd_size_lut);
cupsArrayDelete(cg->pwg_size_lut);
httpClose(cg->http);
_httpFreeCredentials(cg->tls_credentials);
cupsFileClose(cg->stdio_files[0]);
cupsFileClose(cg->stdio_files[1]);
cupsFileClose(cg->stdio_files[2]);
cupsFreeOptions(cg->cupsd_num_settings, cg->cupsd_settings);
free(cg);
}
#endif /* HAVE_PTHREAD_H || WIN32 */
#ifdef HAVE_PTHREAD_H
/*
* 'cups_globals_init()' - Initialize environment variables.
*/
static void
cups_globals_init(void)
{
/*
* Register the global data for this thread...
*/
pthread_key_create(&cups_globals_key, (void (*)(void *))cups_globals_free);
}
#endif /* HAVE_PTHREAD_H */
/*
* End of "$Id: globals.c 7870 2008-08-27 18:14:10Z mike $".
*/

703
cups/http-addr.c Normal file
View File

@@ -0,0 +1,703 @@
/*
* "$Id: http-addr.c 7910 2008-09-06 00:25:17Z mike $"
*
* HTTP address 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/".
*
* Contents:
*
* httpAddrAny() - Check for the "any" address.
* httpAddrEqual() - Compare two addresses.
* httpAddrLocalhost() - Check for the local loopback address.
* httpAddrLookup() - Lookup the hostname associated with the address.
* _httpAddrPort() - Get the port number associated with an address.
* _httpAddrSetPort() - Set the port number associated with an address.
* httpAddrString() - Convert an IP address to a dotted string.
* httpGetHostByName() - Lookup a hostname or IP address, and return
* address records for the specified name.
* httpGetHostname() - Get the FQDN for the local system.
*/
/*
* Include necessary headers...
*/
#include "cups-private.h"
#ifdef HAVE_RESOLV_H
# include <resolv.h>
#endif /* HAVE_RESOLV_H */
#ifdef __APPLE__
# include <CoreFoundation/CoreFoundation.h>
# include <SystemConfiguration/SystemConfiguration.h>
#endif /* __APPLE__ */
/*
* 'httpAddrAny()' - Check for the "any" address.
*
* @since CUPS 1.2/OS X 10.5@
*/
int /* O - 1 if "any", 0 otherwise */
httpAddrAny(const http_addr_t *addr) /* I - Address to check */
{
if (!addr)
return (0);
#ifdef AF_INET6
if (addr->addr.sa_family == AF_INET6 &&
IN6_IS_ADDR_UNSPECIFIED(&(addr->ipv6.sin6_addr)))
return (1);
#endif /* AF_INET6 */
if (addr->addr.sa_family == AF_INET &&
ntohl(addr->ipv4.sin_addr.s_addr) == 0x00000000)
return (1);
return (0);
}
/*
* 'httpAddrEqual()' - Compare two addresses.
*
* @since CUPS 1.2/OS X 10.5@
*/
int /* O - 1 if equal, 0 if not */
httpAddrEqual(const http_addr_t *addr1, /* I - First address */
const http_addr_t *addr2) /* I - Second address */
{
if (!addr1 && !addr2)
return (1);
if (!addr1 || !addr2)
return (0);
if (addr1->addr.sa_family != addr2->addr.sa_family)
return (0);
#ifdef AF_LOCAL
if (addr1->addr.sa_family == AF_LOCAL)
return (!strcmp(addr1->un.sun_path, addr2->un.sun_path));
#endif /* AF_LOCAL */
#ifdef AF_INET6
if (addr1->addr.sa_family == AF_INET6)
return (!memcmp(&(addr1->ipv6.sin6_addr), &(addr2->ipv6.sin6_addr), 16));
#endif /* AF_INET6 */
return (addr1->ipv4.sin_addr.s_addr == addr2->ipv4.sin_addr.s_addr);
}
/*
* 'httpAddrLength()' - Return the length of the address in bytes.
*
* @since CUPS 1.2/OS X 10.5@
*/
int /* O - Length in bytes */
httpAddrLength(const http_addr_t *addr) /* I - Address */
{
if (!addr)
return (0);
#ifdef AF_INET6
if (addr->addr.sa_family == AF_INET6)
return (sizeof(addr->ipv6));
else
#endif /* AF_INET6 */
#ifdef AF_LOCAL
if (addr->addr.sa_family == AF_LOCAL)
return (offsetof(struct sockaddr_un, sun_path) +
strlen(addr->un.sun_path) + 1);
else
#endif /* AF_LOCAL */
if (addr->addr.sa_family == AF_INET)
return (sizeof(addr->ipv4));
else
return (0);
}
/*
* 'httpAddrLocalhost()' - Check for the local loopback address.
*
* @since CUPS 1.2/OS X 10.5@
*/
int /* O - 1 if local host, 0 otherwise */
httpAddrLocalhost(
const http_addr_t *addr) /* I - Address to check */
{
if (!addr)
return (1);
#ifdef AF_INET6
if (addr->addr.sa_family == AF_INET6 &&
IN6_IS_ADDR_LOOPBACK(&(addr->ipv6.sin6_addr)))
return (1);
#endif /* AF_INET6 */
#ifdef AF_LOCAL
if (addr->addr.sa_family == AF_LOCAL)
return (1);
#endif /* AF_LOCAL */
if (addr->addr.sa_family == AF_INET &&
(ntohl(addr->ipv4.sin_addr.s_addr) & 0xff000000) == 0x7f000000)
return (1);
return (0);
}
#ifdef __sgi
# define ADDR_CAST (struct sockaddr *)
#else
# define ADDR_CAST (char *)
#endif /* __sgi */
/*
* 'httpAddrLookup()' - Lookup the hostname associated with the address.
*
* @since CUPS 1.2/OS X 10.5@
*/
char * /* O - Host name */
httpAddrLookup(
const http_addr_t *addr, /* I - Address to lookup */
char *name, /* I - Host name buffer */
int namelen) /* I - Size of name buffer */
{
_cups_globals_t *cg = _cupsGlobals();
/* Global data */
DEBUG_printf(("httpAddrLookup(addr=%p, name=%p, namelen=%d)", addr, name,
namelen));
/*
* Range check input...
*/
if (!addr || !name || namelen <= 2)
{
if (name && namelen >= 1)
*name = '\0';
return (NULL);
}
#ifdef AF_LOCAL
if (addr->addr.sa_family == AF_LOCAL)
{
strlcpy(name, addr->un.sun_path, namelen);
return (name);
}
#endif /* AF_LOCAL */
/*
* Optimize lookups for localhost/loopback addresses...
*/
if (httpAddrLocalhost(addr))
{
strlcpy(name, "localhost", namelen);
return (name);
}
#ifdef HAVE_RES_INIT
/*
* STR #2920: Initialize resolver after failure in cups-polld
*
* If the previous lookup failed, re-initialize the resolver to prevent
* temporary network errors from persisting. This *should* be handled by
* the resolver libraries, but apparently the glibc folks do not agree.
*
* We set a flag at the end of this function if we encounter an error that
* requires reinitialization of the resolver functions. We then call
* res_init() if the flag is set on the next call here or in httpAddrLookup().
*/
if (cg->need_res_init)
{
res_init();
cg->need_res_init = 0;
}
#endif /* HAVE_RES_INIT */
#ifdef HAVE_GETNAMEINFO
{
/*
* STR #2486: httpAddrLookup() fails when getnameinfo() returns EAI_AGAIN
*
* FWIW, I think this is really a bug in the implementation of
* getnameinfo(), but falling back on httpAddrString() is easy to
* do...
*/
int error = getnameinfo(&addr->addr, httpAddrLength(addr), name, namelen,
NULL, 0, 0);
if (error)
{
if (error == EAI_FAIL)
cg->need_res_init = 1;
return (httpAddrString(addr, name, namelen));
}
}
#else
{
struct hostent *host; /* Host from name service */
# ifdef AF_INET6
if (addr->addr.sa_family == AF_INET6)
host = gethostbyaddr(ADDR_CAST &(addr->ipv6.sin6_addr),
sizeof(struct in_addr), AF_INET6);
else
# endif /* AF_INET6 */
host = gethostbyaddr(ADDR_CAST &(addr->ipv4.sin_addr),
sizeof(struct in_addr), AF_INET);
if (host == NULL)
{
/*
* No hostname, so return the raw address...
*/
if (h_errno == NO_RECOVERY)
cg->need_res_init = 1;
return (httpAddrString(addr, name, namelen));
}
strlcpy(name, host->h_name, namelen);
}
#endif /* HAVE_GETNAMEINFO */
DEBUG_printf(("1httpAddrLookup: returning \"%s\"...", name));
return (name);
}
/*
* '_httpAddrPort()' - Get the port number associated with an address.
*/
int /* O - Port number */
_httpAddrPort(http_addr_t *addr) /* I - Address */
{
if (!addr)
return (ippPort());
#ifdef AF_INET6
else if (addr->addr.sa_family == AF_INET6)
return (ntohs(addr->ipv6.sin6_port));
#endif /* AF_INET6 */
else if (addr->addr.sa_family == AF_INET)
return (ntohs(addr->ipv4.sin_port));
else
return (ippPort());
}
/*
* '_httpAddrSetPort()' - Set the port number associated with an address.
*/
void
_httpAddrSetPort(http_addr_t *addr, /* I - Address */
int port) /* I - Port */
{
if (!addr || port <= 0)
return;
#ifdef AF_INET6
if (addr->addr.sa_family == AF_INET6)
addr->ipv6.sin6_port = htons(port);
else
#endif /* AF_INET6 */
if (addr->addr.sa_family == AF_INET)
addr->ipv4.sin_port = htons(port);
}
/*
* 'httpAddrString()' - Convert an address to a numeric string.
*
* @since CUPS 1.2/OS X 10.5@
*/
char * /* O - Numeric address string */
httpAddrString(const http_addr_t *addr, /* I - Address to convert */
char *s, /* I - String buffer */
int slen) /* I - Length of string */
{
DEBUG_printf(("httpAddrString(addr=%p, s=%p, slen=%d)", addr, s, slen));
/*
* Range check input...
*/
if (!addr || !s || slen <= 2)
{
if (s && slen >= 1)
*s = '\0';
return (NULL);
}
#ifdef AF_LOCAL
if (addr->addr.sa_family == AF_LOCAL)
{
if (addr->un.sun_path[0] == '/')
strlcpy(s, addr->un.sun_path, slen);
else
strlcpy(s, "localhost", slen);
}
else
#endif /* AF_LOCAL */
if (addr->addr.sa_family == AF_INET)
{
unsigned temp; /* Temporary address */
temp = ntohl(addr->ipv4.sin_addr.s_addr);
snprintf(s, slen, "%d.%d.%d.%d", (temp >> 24) & 255,
(temp >> 16) & 255, (temp >> 8) & 255, temp & 255);
}
#ifdef AF_INET6
else if (addr->addr.sa_family == AF_INET6)
{
char *sptr, /* Pointer into string */
temps[64]; /* Temporary string for address */
# ifdef HAVE_GETNAMEINFO
if (getnameinfo(&addr->addr, httpAddrLength(addr), temps, sizeof(temps),
NULL, 0, NI_NUMERICHOST))
{
/*
* If we get an error back, then the address type is not supported
* and we should zero out the buffer...
*/
s[0] = '\0';
return (NULL);
}
else if ((sptr = strchr(temps, '%')) != NULL)
{
/*
* Convert "%zone" to "+zone" to match URI form...
*/
*sptr = '+';
}
# else
int i; /* Looping var */
unsigned temp; /* Current value */
const char *prefix; /* Prefix for address */
prefix = "";
for (sptr = temps, i = 0; i < 4 && addr->ipv6.sin6_addr.s6_addr32[i]; i ++)
{
temp = ntohl(addr->ipv6.sin6_addr.s6_addr32[i]);
snprintf(sptr, sizeof(temps) - (sptr - temps), "%s%x", prefix,
(temp >> 16) & 0xffff);
prefix = ":";
sptr += strlen(sptr);
temp &= 0xffff;
if (temp || i == 3 || addr->ipv6.sin6_addr.s6_addr32[i + 1])
{
snprintf(sptr, sizeof(temps) - (sptr - temps), "%s%x", prefix, temp);
sptr += strlen(sptr);
}
}
if (i < 4)
{
while (i < 4 && !addr->ipv6.sin6_addr.s6_addr32[i])
i ++;
if (i < 4)
{
snprintf(sptr, sizeof(temps) - (sptr - temps), "%s:", prefix);
prefix = ":";
sptr += strlen(sptr);
for (; i < 4; i ++)
{
temp = ntohl(addr->ipv6.sin6_addr.s6_addr32[i]);
if ((temp & 0xffff0000) ||
(i > 0 && addr->ipv6.sin6_addr.s6_addr32[i - 1]))
{
snprintf(sptr, sizeof(temps) - (sptr - temps), "%s%x", prefix,
(temp >> 16) & 0xffff);
sptr += strlen(sptr);
}
snprintf(sptr, sizeof(temps) - (sptr - temps), "%s%x", prefix,
temp & 0xffff);
sptr += strlen(sptr);
}
}
else if (sptr == s)
{
/*
* Empty address...
*/
strlcpy(temps, "::", sizeof(temps));
}
else
{
/*
* Empty at end...
*/
strlcpy(sptr, "::", sizeof(temps) - (sptr - temps));
}
}
# endif /* HAVE_GETNAMEINFO */
/*
* Add "[v1." and "]" around IPv6 address to convert to URI form.
*/
snprintf(s, slen, "[v1.%s]", temps);
}
#endif /* AF_INET6 */
else
strlcpy(s, "UNKNOWN", slen);
DEBUG_printf(("1httpAddrString: returning \"%s\"...", s));
return (s);
}
/*
* 'httpGetHostByName()' - Lookup a hostname or IPv4 address, and return
* address records for the specified name.
*
* @deprecated@
*/
struct hostent * /* O - Host entry */
httpGetHostByName(const char *name) /* I - Hostname or IP address */
{
const char *nameptr; /* Pointer into name */
unsigned ip[4]; /* IP address components */
_cups_globals_t *cg = _cupsGlobals();
/* Pointer to library globals */
DEBUG_printf(("httpGetHostByName(name=\"%s\")", name));
/*
* Avoid lookup delays and configuration problems when connecting
* to the localhost address...
*/
if (!strcmp(name, "localhost"))
name = "127.0.0.1";
/*
* This function is needed because some operating systems have a
* buggy implementation of gethostbyname() that does not support
* IP addresses. If the first character of the name string is a
* number, then sscanf() is used to extract the IP components.
* We then pack the components into an IPv4 address manually,
* since the inet_aton() function is deprecated. We use the
* htonl() macro to get the right byte order for the address.
*
* We also support domain sockets when supported by the underlying
* OS...
*/
#ifdef AF_LOCAL
if (name[0] == '/')
{
/*
* A domain socket address, so make an AF_LOCAL entry and return it...
*/
cg->hostent.h_name = (char *)name;
cg->hostent.h_aliases = NULL;
cg->hostent.h_addrtype = AF_LOCAL;
cg->hostent.h_length = strlen(name) + 1;
cg->hostent.h_addr_list = cg->ip_ptrs;
cg->ip_ptrs[0] = (char *)name;
cg->ip_ptrs[1] = NULL;
DEBUG_puts("1httpGetHostByName: returning domain socket address...");
return (&cg->hostent);
}
#endif /* AF_LOCAL */
for (nameptr = name; isdigit(*nameptr & 255) || *nameptr == '.'; nameptr ++);
if (!*nameptr)
{
/*
* We have an IPv4 address; break it up and provide the host entry
* to the caller.
*/
if (sscanf(name, "%u.%u.%u.%u", ip, ip + 1, ip + 2, ip + 3) != 4)
return (NULL); /* Must have 4 numbers */
if (ip[0] > 255 || ip[1] > 255 || ip[2] > 255 || ip[3] > 255)
return (NULL); /* Invalid byte ranges! */
cg->ip_addr = htonl(((((((ip[0] << 8) | ip[1]) << 8) | ip[2]) << 8) |
ip[3]));
/*
* Fill in the host entry and return it...
*/
cg->hostent.h_name = (char *)name;
cg->hostent.h_aliases = NULL;
cg->hostent.h_addrtype = AF_INET;
cg->hostent.h_length = 4;
cg->hostent.h_addr_list = cg->ip_ptrs;
cg->ip_ptrs[0] = (char *)&(cg->ip_addr);
cg->ip_ptrs[1] = NULL;
DEBUG_puts("1httpGetHostByName: returning IPv4 address...");
return (&cg->hostent);
}
else
{
/*
* Use the gethostbyname() function to get the IPv4 address for
* the name...
*/
DEBUG_puts("1httpGetHostByName: returning domain lookup address(es)...");
return (gethostbyname(name));
}
}
/*
* 'httpGetHostname()' - Get the FQDN for the connection or local system.
*
* When "http" points to a connected socket, return the hostname or
* address that was used in the call to httpConnect() or httpConnectEncrypt().
* Otherwise, return the FQDN for the local system using both gethostname()
* and gethostbyname() to get the local hostname with domain.
*
* @since CUPS 1.2/OS X 10.5@
*/
const char * /* O - FQDN for connection or system */
httpGetHostname(http_t *http, /* I - HTTP connection or NULL */
char *s, /* I - String buffer for name */
int slen) /* I - Size of buffer */
{
if (!s || slen <= 1)
return (NULL);
if (http)
{
if (http->hostname[0] == '/')
strlcpy(s, "localhost", slen);
else
strlcpy(s, http->hostname, slen);
}
else
{
/*
* Get the hostname...
*/
if (gethostname(s, slen) < 0)
strlcpy(s, "localhost", slen);
if (!strchr(s, '.'))
{
#ifdef HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME
/*
* The hostname is not a FQDN, so use the local hostname from the
* SystemConfiguration framework...
*/
SCDynamicStoreRef sc = SCDynamicStoreCreate(kCFAllocatorDefault,
CFSTR("libcups"), NULL, NULL);
/* System configuration data */
CFStringRef local = sc ? SCDynamicStoreCopyLocalHostName(sc) : NULL;
/* Local host name */
char localStr[1024]; /* Local host name C string */
if (local && CFStringGetCString(local, localStr, sizeof(localStr),
kCFStringEncodingUTF8))
{
/*
* Append ".local." to the hostname we get...
*/
snprintf(s, slen, "%s.local.", localStr);
}
if (local)
CFRelease(local);
if (sc)
CFRelease(sc);
#else
/*
* The hostname is not a FQDN, so look it up...
*/
struct hostent *host; /* Host entry to get FQDN */
if ((host = gethostbyname(s)) != NULL && host->h_name)
{
/*
* Use the resolved hostname...
*/
strlcpy(s, host->h_name, slen);
}
#endif /* HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME */
}
}
/*
* Return the hostname with as much domain info as we have...
*/
return (s);
}
/*
* End of "$Id: http-addr.c 7910 2008-09-06 00:25:17Z mike $".
*/

845
cups/http-addrlist.c Normal file
View File

@@ -0,0 +1,845 @@
/*
* "$Id: http-addrlist.c 7910 2008-09-06 00:25:17Z mike $"
*
* HTTP address list 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/".
*
* Contents:
*
* httpAddrConnect() - Connect to any of the addresses in the list.
* httpAddrConnect2() - Connect to any of the addresses in the list with a
* timeout and optional cancel.
* httpAddrFreeList() - Free an address list.
* httpAddrGetList() - Get a list of addresses for a hostname.
*/
/*
* Include necessary headers...
*/
#include "cups-private.h"
#ifdef HAVE_RESOLV_H
# include <resolv.h>
#endif /* HAVE_RESOLV_H */
#ifdef HAVE_POLL
# include <poll.h>
#endif /* HAVE_POLL */
#ifndef WIN32
# include <fcntl.h>
#endif /* WIN32 */
/*
* 'httpAddrConnect()' - Connect to any of the addresses in the list.
*
* @since CUPS 1.2/OS X 10.5@
*/
http_addrlist_t * /* O - Connected address or NULL on failure */
httpAddrConnect(
http_addrlist_t *addrlist, /* I - List of potential addresses */
int *sock) /* O - Socket */
{
DEBUG_printf(("httpAddrConnect(addrlist=%p, sock=%p)", addrlist, sock));
return (httpAddrConnect2(addrlist, sock, 30000, NULL));
}
/*
* 'httpAddrConnect2()' - Connect to any of the addresses in the list with a
* timeout and optional cancel.
*
* @since CUPS 1.6/OS X 10.8@
*/
http_addrlist_t * /* O - Connected address or NULL on failure */
httpAddrConnect2(
http_addrlist_t *addrlist, /* I - List of potential addresses */
int *sock, /* O - Socket */
int msec, /* I - Timeout in milliseconds */
int *cancel) /* I - Pointer to "cancel" variable */
{
int val; /* Socket option value */
#ifdef O_NONBLOCK
socklen_t len; /* Length of value */
http_addr_t peer; /* Peer address */
int flags, /* Socket flags */
remaining; /* Remaining timeout */
# ifdef HAVE_POLL
struct pollfd pfd; /* Polled file descriptor */
# else
fd_set input_set, /* select() input set */
output_set; /* select() output set */
struct timeval timeout; /* Timeout */
# endif /* HAVE_POLL */
int nfds; /* Result from select()/poll() */
#endif /* O_NONBLOCK */
#ifdef DEBUG
char temp[256]; /* Temporary address string */
#endif /* DEBUG */
DEBUG_printf(("httpAddrConnect2(addrlist=%p, sock=%p, msec=%d, cancel=%p)",
addrlist, sock, msec, cancel));
if (!sock)
{
errno = EINVAL;
_cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
return (NULL);
}
if (cancel && *cancel)
return (NULL);
if (msec <= 0 || getenv("CUPS_DISABLE_ASYNC_CONNECT"))
msec = INT_MAX;
/*
* Loop through each address until we connect or run out of addresses...
*/
while (addrlist)
{
if (cancel && *cancel)
return (NULL);
/*
* Create the socket...
*/
DEBUG_printf(("2httpAddrConnect2: Trying %s:%d...",
httpAddrString(&(addrlist->addr), temp, sizeof(temp)),
_httpAddrPort(&(addrlist->addr))));
if ((*sock = (int)socket(_httpAddrFamily(&(addrlist->addr)), SOCK_STREAM,
0)) < 0)
{
/*
* Don't abort yet, as this could just be an issue with the local
* system not being configured with IPv4/IPv6/domain socket enabled...
*/
addrlist = addrlist->next;
continue;
}
/*
* Set options...
*/
val = 1;
#ifdef WIN32
setsockopt(*sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&val,
sizeof(val));
#else
setsockopt(*sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
#endif /* WIN32 */
#ifdef SO_REUSEPORT
val = 1;
setsockopt(*sock, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
#endif /* SO_REUSEPORT */
#ifdef SO_NOSIGPIPE
val = 1;
setsockopt(*sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof(val));
#endif /* SO_NOSIGPIPE */
/*
* Using TCP_NODELAY improves responsiveness, especially on systems
* with a slow loopback interface...
*/
val = 1;
#ifdef WIN32
setsockopt(*sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&val,
sizeof(val));
#else
setsockopt(*sock, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
#endif /* WIN32 */
#ifdef FD_CLOEXEC
/*
* Close this socket when starting another process...
*/
fcntl(*sock, F_SETFD, FD_CLOEXEC);
#endif /* FD_CLOEXEC */
#ifdef O_NONBLOCK
/*
* Do an asynchronous connect by setting the socket non-blocking...
*/
DEBUG_printf(("httpAddrConnect2: Setting non-blocking connect()"));
flags = fcntl(*sock, F_GETFL, 0);
if (msec != INT_MAX)
{
DEBUG_puts("httpAddrConnect2: Setting non-blocking connect()");
fcntl(*sock, F_SETFL, flags | O_NONBLOCK);
}
#endif /* O_NONBLOCK */
/*
* Then connect...
*/
if (!connect(*sock, &(addrlist->addr.addr),
httpAddrLength(&(addrlist->addr))))
{
DEBUG_printf(("1httpAddrConnect2: Connected to %s:%d...",
httpAddrString(&(addrlist->addr), temp, sizeof(temp)),
_httpAddrPort(&(addrlist->addr))));
#ifdef O_NONBLOCK
fcntl(*sock, F_SETFL, flags);
#endif /* O_NONBLOCK */
return (addrlist);
}
#ifdef O_NONBLOCK
# ifdef WIN32
if (WSAGetLastError() == WSAEINPROGRESS ||
WSAGetLastError() == WSAEWOULDBLOCK)
# else
if (errno == EINPROGRESS || errno == EWOULDBLOCK)
# endif /* WIN32 */
{
DEBUG_puts("1httpAddrConnect2: Finishing async connect()");
fcntl(*sock, F_SETFL, flags);
for (remaining = msec; remaining > 0; remaining -= 250)
{
do
{
if (cancel && *cancel)
{
/*
* Close this socket and return...
*/
DEBUG_puts("1httpAddrConnect2: Canceled connect()");
# ifdef WIN32
closesocket(*sock);
# else
close(*sock);
# endif /* WIN32 */
*sock = -1;
return (NULL);
}
# ifdef HAVE_POLL
pfd.fd = *sock;
pfd.events = POLLIN | POLLOUT;
nfds = poll(&pfd, 1, remaining > 250 ? 250 : remaining);
DEBUG_printf(("1httpAddrConnect2: poll() returned %d (%d)", nfds,
errno));
# else
FD_ZERO(&input_set);
FD_SET(*sock, &input_set);
output_set = input_set;
timeout.tv_sec = 0;
timeout.tv_usec = (remaining > 250 ? 250 : remaining) * 1000;
nfds = select(*sock + 1, &input_set, &output_set, NULL, &timeout);
DEBUG_printf(("1httpAddrConnect2: select() returned %d (%d)", nfds,
errno));
# endif /* HAVE_POLL */
}
# ifdef WIN32
while (nfds < 0 && (WSAGetLastError() == WSAEINTR ||
WSAGetLastError() == WSAEWOULDBLOCK));
# else
while (nfds < 0 && (errno == EINTR || errno == EAGAIN));
# endif /* WIN32 */
if (nfds > 0)
{
len = sizeof(peer);
if (!getpeername(*sock, (struct sockaddr *)&peer, &len))
{
DEBUG_printf(("1httpAddrConnect2: Connected to %s:%d...",
httpAddrString(&peer, temp, sizeof(temp)),
_httpAddrPort(&peer)));
return (addrlist);
}
break;
}
}
}
#endif /* O_NONBLOCK */
DEBUG_printf(("1httpAddrConnect2: Unable to connect to %s:%d: %s",
httpAddrString(&(addrlist->addr), temp, sizeof(temp)),
_httpAddrPort(&(addrlist->addr)), strerror(errno)));
#ifndef WIN32
if (errno == EINPROGRESS)
errno = ETIMEDOUT;
#endif /* !WIN32 */
/*
* Close this socket and move to the next address...
*/
#ifdef WIN32
closesocket(*sock);
#else
close(*sock);
#endif /* WIN32 */
*sock = -1;
addrlist = addrlist->next;
}
if (!addrlist)
#ifdef WIN32
_cupsSetError(IPP_SERVICE_UNAVAILABLE, "Connection failed", 0);
#else
_cupsSetError(IPP_SERVICE_UNAVAILABLE, strerror(errno), 0);
#endif /* WIN32 */
return (addrlist);
}
/*
* 'httpAddrFreeList()' - Free an address list.
*
* @since CUPS 1.2/OS X 10.5@
*/
void
httpAddrFreeList(
http_addrlist_t *addrlist) /* I - Address list to free */
{
http_addrlist_t *next; /* Next address in list */
/*
* Free each address in the list...
*/
while (addrlist)
{
next = addrlist->next;
free(addrlist);
addrlist = next;
}
}
/*
* 'httpAddrGetList()' - Get a list of addresses for a hostname.
*
* @since CUPS 1.2/OS X 10.5@
*/
http_addrlist_t * /* O - List of addresses or NULL */
httpAddrGetList(const char *hostname, /* I - Hostname, IP address, or NULL for passive listen address */
int family, /* I - Address family or AF_UNSPEC */
const char *service) /* I - Service name or port number */
{
http_addrlist_t *first, /* First address in list */
*addr, /* Current address in list */
*temp; /* New address */
_cups_globals_t *cg = _cupsGlobals();
/* Global data */
#ifdef DEBUG
_cups_debug_printf("httpAddrGetList(hostname=\"%s\", family=AF_%s, "
"service=\"%s\")\n",
hostname ? hostname : "(nil)",
family == AF_UNSPEC ? "UNSPEC" :
# ifdef AF_LOCAL
family == AF_LOCAL ? "LOCAL" :
# endif /* AF_LOCAL */
# ifdef AF_INET6
family == AF_INET6 ? "INET6" :
# endif /* AF_INET6 */
family == AF_INET ? "INET" : "???", service);
#endif /* DEBUG */
#ifdef HAVE_RES_INIT
/*
* STR #2920: Initialize resolver after failure in cups-polld
*
* If the previous lookup failed, re-initialize the resolver to prevent
* temporary network errors from persisting. This *should* be handled by
* the resolver libraries, but apparently the glibc folks do not agree.
*
* We set a flag at the end of this function if we encounter an error that
* requires reinitialization of the resolver functions. We then call
* res_init() if the flag is set on the next call here or in httpAddrLookup().
*/
if (cg->need_res_init)
{
res_init();
cg->need_res_init = 0;
}
#endif /* HAVE_RES_INIT */
/*
* Lookup the address the best way we can...
*/
first = addr = NULL;
#ifdef AF_LOCAL
if (hostname && hostname[0] == '/')
{
/*
* Domain socket address...
*/
if ((first = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t))) != NULL)
{
first->addr.un.sun_family = AF_LOCAL;
strlcpy(first->addr.un.sun_path, hostname, sizeof(first->addr.un.sun_path));
}
}
else
#endif /* AF_LOCAL */
if (!hostname || _cups_strcasecmp(hostname, "localhost"))
{
#ifdef HAVE_GETADDRINFO
struct addrinfo hints, /* Address lookup hints */
*results, /* Address lookup results */
*current; /* Current result */
char ipv6[64], /* IPv6 address */
*ipv6zone; /* Pointer to zone separator */
int ipv6len; /* Length of IPv6 address */
int error; /* getaddrinfo() error */
/*
* Lookup the address as needed...
*/
memset(&hints, 0, sizeof(hints));
hints.ai_family = family;
hints.ai_flags = hostname ? 0 : AI_PASSIVE;
hints.ai_socktype = SOCK_STREAM;
if (hostname && *hostname == '[')
{
/*
* Remove brackets from numeric IPv6 address...
*/
if (!strncmp(hostname, "[v1.", 4))
{
/*
* Copy the newer address format which supports link-local addresses...
*/
strlcpy(ipv6, hostname + 4, sizeof(ipv6));
if ((ipv6len = (int)strlen(ipv6) - 1) >= 0 && ipv6[ipv6len] == ']')
{
ipv6[ipv6len] = '\0';
hostname = ipv6;
/*
* Convert "+zone" in address to "%zone"...
*/
if ((ipv6zone = strrchr(ipv6, '+')) != NULL)
*ipv6zone = '%';
}
}
else
{
/*
* Copy the regular non-link-local IPv6 address...
*/
strlcpy(ipv6, hostname + 1, sizeof(ipv6));
if ((ipv6len = (int)strlen(ipv6) - 1) >= 0 && ipv6[ipv6len] == ']')
{
ipv6[ipv6len] = '\0';
hostname = ipv6;
}
}
}
if ((error = getaddrinfo(hostname, service, &hints, &results)) == 0)
{
/*
* Copy the results to our own address list structure...
*/
for (current = results; current; current = current->ai_next)
if (current->ai_family == AF_INET || current->ai_family == AF_INET6)
{
/*
* Copy the address over...
*/
temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
if (!temp)
{
httpAddrFreeList(first);
_cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
return (NULL);
}
if (current->ai_family == AF_INET6)
memcpy(&(temp->addr.ipv6), current->ai_addr,
sizeof(temp->addr.ipv6));
else
memcpy(&(temp->addr.ipv4), current->ai_addr,
sizeof(temp->addr.ipv4));
/*
* Append the address to the list...
*/
if (!first)
first = temp;
if (addr)
addr->next = temp;
addr = temp;
}
/*
* Free the results from getaddrinfo()...
*/
freeaddrinfo(results);
}
else
{
if (error == EAI_FAIL)
cg->need_res_init = 1;
_cupsSetError(IPP_INTERNAL_ERROR, gai_strerror(error), 0);
}
#else
if (hostname)
{
int i; /* Looping vars */
unsigned ip[4]; /* IPv4 address components */
const char *ptr; /* Pointer into hostname */
struct hostent *host; /* Result of lookup */
struct servent *port; /* Port number for service */
int portnum; /* Port number */
/*
* Lookup the service...
*/
if (!service)
portnum = 0;
else if (isdigit(*service & 255))
portnum = atoi(service);
else if ((port = getservbyname(service, NULL)) != NULL)
portnum = ntohs(port->s_port);
else if (!strcmp(service, "http"))
portnum = 80;
else if (!strcmp(service, "https"))
portnum = 443;
else if (!strcmp(service, "ipp") || !strcmp(service, "ipps"))
portnum = 631;
else if (!strcmp(service, "lpd"))
portnum = 515;
else if (!strcmp(service, "socket"))
portnum = 9100;
else
return (NULL);
/*
* This code is needed because some operating systems have a
* buggy implementation of gethostbyname() that does not support
* IPv4 addresses. If the hostname string is an IPv4 address, then
* sscanf() is used to extract the IPv4 components. We then pack
* the components into an IPv4 address manually, since the
* inet_aton() function is deprecated. We use the htonl() macro
* to get the right byte order for the address.
*/
for (ptr = hostname; isdigit(*ptr & 255) || *ptr == '.'; ptr ++);
if (!*ptr)
{
/*
* We have an IPv4 address; break it up and create an IPv4 address...
*/
if (sscanf(hostname, "%u.%u.%u.%u", ip, ip + 1, ip + 2, ip + 3) == 4 &&
ip[0] <= 255 && ip[1] <= 255 && ip[2] <= 255 && ip[3] <= 255)
{
first = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
if (!first)
return (NULL);
first->addr.ipv4.sin_family = AF_INET;
first->addr.ipv4.sin_addr.s_addr = htonl(((((((ip[0] << 8) |
ip[1]) << 8) |
ip[2]) << 8) | ip[3]));
first->addr.ipv4.sin_port = htons(portnum);
}
}
else if ((host = gethostbyname(hostname)) != NULL &&
# ifdef AF_INET6
(host->h_addrtype == AF_INET || host->h_addrtype == AF_INET6))
# else
host->h_addrtype == AF_INET)
# endif /* AF_INET6 */
{
for (i = 0; host->h_addr_list[i]; i ++)
{
/*
* Copy the address over...
*/
temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
if (!temp)
{
httpAddrFreeList(first);
return (NULL);
}
# ifdef AF_INET6
if (host->h_addrtype == AF_INET6)
{
temp->addr.ipv6.sin6_family = AF_INET6;
memcpy(&(temp->addr.ipv6.sin6_addr), host->h_addr_list[i],
sizeof(temp->addr.ipv6));
temp->addr.ipv6.sin6_port = htons(portnum);
}
else
# endif /* AF_INET6 */
{
temp->addr.ipv4.sin_family = AF_INET;
memcpy(&(temp->addr.ipv4.sin_addr), host->h_addr_list[i],
sizeof(temp->addr.ipv4));
temp->addr.ipv4.sin_port = htons(portnum);
}
/*
* Append the address to the list...
*/
if (!first)
first = temp;
if (addr)
addr->next = temp;
addr = temp;
}
}
else
{
if (h_errno == NO_RECOVERY)
cg->need_res_init = 1;
_cupsSetError(IPP_INTERNAL_ERROR, hstrerror(h_errno), 0);
}
}
#endif /* HAVE_GETADDRINFO */
}
/*
* Detect some common errors and handle them sanely...
*/
if (!addr && (!hostname || !_cups_strcasecmp(hostname, "localhost")))
{
struct servent *port; /* Port number for service */
int portnum; /* Port number */
/*
* Lookup the service...
*/
if (!service)
portnum = 0;
else if (isdigit(*service & 255))
portnum = atoi(service);
else if ((port = getservbyname(service, NULL)) != NULL)
portnum = ntohs(port->s_port);
else if (!strcmp(service, "http"))
portnum = 80;
else if (!strcmp(service, "https"))
portnum = 443;
else if (!strcmp(service, "ipp") || !strcmp(service, "ipps"))
portnum = 631;
else if (!strcmp(service, "lpd"))
portnum = 515;
else if (!strcmp(service, "socket"))
portnum = 9100;
else
{
httpAddrFreeList(first);
_cupsSetError(IPP_INTERNAL_ERROR, _("Unknown service name."), 1);
return (NULL);
}
if (hostname && !_cups_strcasecmp(hostname, "localhost"))
{
/*
* Unfortunately, some users ignore all of the warnings in the
* /etc/hosts file and delete "localhost" from it. If we get here
* then we were unable to resolve the name, so use the IPv6 and/or
* IPv4 loopback interface addresses...
*/
#ifdef AF_INET6
if (family != AF_INET)
{
/*
* Add [::1] to the address list...
*/
temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
if (!temp)
{
_cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
httpAddrFreeList(first);
return (NULL);
}
temp->addr.ipv6.sin6_family = AF_INET6;
temp->addr.ipv6.sin6_port = htons(portnum);
# ifdef WIN32
temp->addr.ipv6.sin6_addr.u.Byte[15] = 1;
# else
temp->addr.ipv6.sin6_addr.s6_addr32[3] = htonl(1);
# endif /* WIN32 */
if (!first)
first = temp;
addr = temp;
}
if (family != AF_INET6)
#endif /* AF_INET6 */
{
/*
* Add 127.0.0.1 to the address list...
*/
temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
if (!temp)
{
_cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
httpAddrFreeList(first);
return (NULL);
}
temp->addr.ipv4.sin_family = AF_INET;
temp->addr.ipv4.sin_port = htons(portnum);
temp->addr.ipv4.sin_addr.s_addr = htonl(0x7f000001);
if (!first)
first = temp;
if (addr)
addr->next = temp;
}
}
else if (!hostname)
{
/*
* Provide one or more passive listening addresses...
*/
#ifdef AF_INET6
if (family != AF_INET)
{
/*
* Add [::] to the address list...
*/
temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
if (!temp)
{
_cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
httpAddrFreeList(first);
return (NULL);
}
temp->addr.ipv6.sin6_family = AF_INET6;
temp->addr.ipv6.sin6_port = htons(portnum);
if (!first)
first = temp;
addr = temp;
}
if (family != AF_INET6)
#endif /* AF_INET6 */
{
/*
* Add 0.0.0.0 to the address list...
*/
temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t));
if (!temp)
{
_cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
httpAddrFreeList(first);
return (NULL);
}
temp->addr.ipv4.sin_family = AF_INET;
temp->addr.ipv4.sin_port = htons(portnum);
if (!first)
first = temp;
if (addr)
addr->next = temp;
}
}
}
/*
* Return the address list...
*/
return (first);
}
/*
* End of "$Id: http-addrlist.c 7910 2008-09-06 00:25:17Z mike $".
*/

394
cups/http-private.h Normal file
View File

@@ -0,0 +1,394 @@
/*
* "$Id: http-private.h 7850 2008-08-20 00:07:25Z mike $"
*
* Private HTTP definitions 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/".
*
* This file is subject to the Apple OS-Developed Software exception.
*/
#ifndef _CUPS_HTTP_PRIVATE_H_
# define _CUPS_HTTP_PRIVATE_H_
/*
* Include necessary headers...
*/
# include "config.h"
# include <stddef.h>
# include <stdlib.h>
# ifdef __sun
# include <sys/select.h>
# endif /* __sun */
# include <limits.h>
# ifdef WIN32
# include <io.h>
# include <winsock2.h>
# else
# include <unistd.h>
# include <fcntl.h>
# include <sys/socket.h>
# define closesocket(f) close(f)
# endif /* WIN32 */
# ifdef HAVE_GSSAPI
# ifdef HAVE_GSS_GSSAPI_H
# include <GSS/gssapi.h>
# elif defined(HAVE_GSSAPI_GSSAPI_H)
# include <gssapi/gssapi.h>
# elif defined(HAVE_GSSAPI_H)
# include <gssapi.h>
# endif /* HAVE_GSS_GSSAPI_H */
# ifndef HAVE_GSS_C_NT_HOSTBASED_SERVICE
# define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
# endif /* !HAVE_GSS_C_NT_HOSTBASED_SERVICE */
# endif /* HAVE_GSSAPI */
# ifdef HAVE_AUTHORIZATION_H
# include <Security/Authorization.h>
# endif /* HAVE_AUTHORIZATION_H */
# if defined(__sgi) || (defined(__APPLE__) && !defined(_SOCKLEN_T))
/*
* IRIX and MacOS X 10.2.x do not define socklen_t, and in fact use an int instead of
* unsigned type for length values...
*/
typedef int socklen_t;
# endif /* __sgi || (__APPLE__ && !_SOCKLEN_T) */
# include <cups/http.h>
# include "md5-private.h"
# include "ipp-private.h"
# if defined HAVE_LIBSSL
# include <openssl/err.h>
# include <openssl/rand.h>
# include <openssl/ssl.h>
# elif defined HAVE_GNUTLS
# include <gnutls/gnutls.h>
# include <gnutls/x509.h>
# include <gcrypt.h>
# elif defined(HAVE_CDSASSL)
# include <CoreFoundation/CoreFoundation.h>
# include <Security/Security.h>
# include <Security/SecureTransport.h>
# ifdef HAVE_SECURETRANSPORTPRIV_H
# include <Security/SecureTransportPriv.h>
# endif /* HAVE_SECURETRANSPORTPRIV_H */
# ifdef HAVE_SECITEM_H
# include <Security/SecItem.h>
# endif /* HAVE_SECITEM_H */
# ifdef HAVE_SECBASEPRIV_H
# include <Security/SecBasePriv.h>
# endif /* HAVE_SECBASEPRIV_H */
# ifdef HAVE_SECCERTIFICATE_H
# include <Security/SecCertificate.h>
# include <Security/SecIdentity.h>
# endif /* HAVE_SECCERTIFICATE_H */
# ifdef HAVE_SECITEMPRIV_H
# include <Security/SecItemPriv.h>
# endif /* HAVE_SECITEMPRIV_H */
# ifdef HAVE_SECIDENTITYSEARCHPRIV_H
# include <Security/SecIdentitySearchPriv.h>
# endif /* HAVE_SECIDENTITYSEARCHPRIV_H */
# ifdef HAVE_SECPOLICYPRIV_H
# include <Security/SecPolicyPriv.h>
# endif /* HAVE_SECPOLICYPRIV_H */
# elif defined(HAVE_SSPISSL)
# include "sspi-private.h"
# endif /* HAVE_LIBSSL */
# ifndef WIN32
# include <net/if.h>
# ifdef HAVE_GETIFADDRS
# include <ifaddrs.h>
# else
# include <sys/ioctl.h>
# ifdef HAVE_SYS_SOCKIO_H
# include <sys/sockio.h>
# endif /* HAVE_SYS_SOCKIO_H */
# endif /* HAVE_GETIFADDRS */
# endif /* !WIN32 */
/*
* C++ magic...
*/
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/*
* Constants...
*/
#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? */
/*
* Types and functions for SSL support...
*/
# if defined HAVE_LIBSSL
/*
* The OpenSSL library provides its own SSL/TLS context structure for its
* IO and protocol management. However, we need to provide our own BIO
* (basic IO) implementation to do timeouts...
*/
typedef SSL *http_tls_t;
typedef void *http_tls_credentials_t;
extern BIO_METHOD *_httpBIOMethods(void);
# elif defined HAVE_GNUTLS
/*
* The GNU TLS library is more of a "bare metal" SSL/TLS library...
*/
typedef gnutls_session http_tls_t;
typedef void *http_tls_credentials_t;
extern ssize_t _httpReadGNUTLS(gnutls_transport_ptr ptr, void *data,
size_t length);
extern ssize_t _httpWriteGNUTLS(gnutls_transport_ptr ptr, const void *data,
size_t length);
# elif defined(HAVE_CDSASSL)
/*
* Darwin's Security framework provides its own SSL/TLS context structure
* 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 */
# ifndef HAVE_SECITEMPRIV_H /* Declare constants from that header... */
extern const CFTypeRef kSecClassCertificate;
extern const CFTypeRef kSecClassIdentity;
# endif /* !HAVE_SECITEMPRIV_H */
# 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;
extern OSStatus _httpReadCDSA(SSLConnectionRef connection, void *data,
size_t *dataLength);
extern OSStatus _httpWriteCDSA(SSLConnectionRef connection, const void *data,
size_t *dataLength);
# elif defined(HAVE_SSPISSL)
/*
* Windows' SSPI library gets a CUPS wrapper...
*/
typedef _sspi_struct_t * http_tls_t;
typedef void *http_tls_credentials_t;
# else
/*
* Otherwise define stub types since we have no SSL support...
*/
typedef void *http_tls_t;
typedef void *http_tls_credentials_t;
# endif /* HAVE_LIBSSL */
struct _http_s /**** HTTP connection structure. ****/
{
int fd; /* File descriptor for this socket */
int blocking; /* To block or not to block */
int error; /* Last error on read */
time_t activity; /* Time since last read/write */
http_state_t state; /* State of client */
http_status_t status; /* Status of last request */
http_version_t version; /* Protocol version */
http_keepalive_t keep_alive; /* Keep-alive supported? */
struct sockaddr_in _hostaddr; /* Address of connected host (deprecated) */
char hostname[HTTP_MAX_HOST],
/* Name of connected host */
fields[HTTP_FIELD_MAX][HTTP_MAX_VALUE];
/* Field values */
char *data; /* Pointer to data buffer */
http_encoding_t data_encoding; /* Chunked or not */
int _data_remaining;/* Number of bytes left (deprecated) */
int used; /* Number of bytes used in buffer */
char buffer[HTTP_MAX_BUFFER];
/* Buffer for incoming data */
int auth_type; /* Authentication in use */
_cups_md5_state_t md5_state; /* MD5 state */
char nonce[HTTP_MAX_VALUE];
/* Nonce value */
int nonce_count; /* Nonce count */
http_tls_t tls; /* TLS state information */
http_encryption_t encryption; /* Encryption requirements */
/**** New in CUPS 1.1.19 ****/
fd_set *input_set; /* select() set for httpWait() (deprecated) */
http_status_t expect; /* Expect: header */
char *cookie; /* Cookie value(s) */
/**** New in CUPS 1.1.20 ****/
char _authstring[HTTP_MAX_VALUE],
/* Current Authentication value (deprecated) */
userpass[HTTP_MAX_VALUE];
/* Username:password string */
int digest_tries; /* Number of tries for digest auth */
/**** New in CUPS 1.2 ****/
off_t data_remaining; /* Number of bytes left */
http_addr_t *hostaddr; /* Current host address and port */
http_addrlist_t *addrlist; /* List of valid addresses */
char wbuffer[HTTP_MAX_BUFFER];
/* Buffer for outgoing data */
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 */
gss_ctx_id_t gssctx; /* Authentication context */
gss_name_t gssname; /* Authentication server name */
# endif /* HAVE_GSSAPI */
# ifdef HAVE_AUTHORIZATION_H
AuthorizationRef auth_ref; /* Authorization ref */
# endif /* HAVE_AUTHORIZATION_H */
/**** New in CUPS 1.5 ****/
http_tls_credentials_t tls_credentials;
/* TLS credentials */
http_timeout_cb_t timeout_cb; /* Timeout callback */
void *timeout_data; /* User data pointer */
double timeout_value; /* Timeout in seconds */
int wait_value; /* httpWait value for timeout */
# ifdef HAVE_GSSAPI
char gsshost[256]; /* Hostname for Kerberos */
# endif /* HAVE_GSSAPI */
};
/*
* Some OS's don't have hstrerror(), most notably Solaris...
*/
# ifndef HAVE_HSTRERROR
extern const char *_cups_hstrerror(int error);
# define hstrerror _cups_hstrerror
# elif defined(_AIX) || defined(__osf__)
/*
* AIX and Tru64 UNIX don't provide a prototype but do provide the function...
*/
extern const char *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...
*/
#define _httpAddrFamily(addrp) (addrp)->addr.sa_family
extern int _httpAddrPort(http_addr_t *addr);
extern void _httpAddrSetPort(http_addr_t *addr, int port);
extern char *_httpAssembleUUID(const char *server, int port,
const char *name, int number,
char *buffer, size_t bufsize);
extern http_t *_httpCreate(const char *host, int port,
http_addrlist_t *addrlist,
http_encryption_t encryption,
int family);
extern http_tls_credentials_t
_httpCreateCredentials(cups_array_t *credentials);
extern char *_httpDecodeURI(char *dst, const char *src,
size_t dstsize);
extern void _httpDisconnect(http_t *http);
extern char *_httpEncodeURI(char *dst, const char *src,
size_t dstsize);
extern void _httpFreeCredentials(http_tls_credentials_t credentials);
extern ssize_t _httpPeek(http_t *http, char *buffer, size_t length);
extern const char *_httpResolveURI(const char *uri, char *resolved_uri,
size_t resolved_size, int options,
int (*cb)(void *context),
void *context);
extern int _httpUpdate(http_t *http, http_status_t *status);
extern int _httpWait(http_t *http, int msec, int usessl);
/*
* C++ magic...
*/
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_HTTP_PRIVATE_H_ */
/*
* End of "$Id: http-private.h 7850 2008-08-20 00:07:25Z mike $".
*/

2364
cups/http-support.c Normal file

File diff suppressed because it is too large Load Diff

4778
cups/http.c Normal file

File diff suppressed because it is too large Load Diff

487
cups/http.h Normal file
View File

@@ -0,0 +1,487 @@
/*
* "$Id: http.h 7026 2007-10-19 00:57:45Z mike $"
*
* Hyper-Text Transport Protocol definitions 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/".
*
* This file is subject to the Apple OS-Developed Software exception.
*/
#ifndef _CUPS_HTTP_H_
# define _CUPS_HTTP_H_
/*
* Include necessary headers...
*/
# include "versioning.h"
# include "array.h"
# include <string.h>
# include <time.h>
# include <sys/types.h>
# 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... */
typedef off_t ssize_t; /* @private@ */
# endif /* !__CUPS_SSIZE_T_DEFINED */
# include <winsock2.h>
# include <ws2tcpip.h>
# else
# ifdef __sgi
# define INET6 /* IRIX IPv6 support... */
# endif /* __sgi */
# include <unistd.h>
# include <sys/time.h>
# include <sys/socket.h>
# include <netdb.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <netinet/in_systm.h>
# include <netinet/ip.h>
# if !defined(__APPLE__) || !defined(TCP_NODELAY)
# include <netinet/tcp.h>
# endif /* !__APPLE__ || !TCP_NODELAY */
# if defined(AF_UNIX) && !defined(AF_LOCAL)
# define AF_LOCAL AF_UNIX /* Older UNIX's have old names... */
# endif /* AF_UNIX && !AF_LOCAL */
# ifdef AF_LOCAL
# include <sys/un.h>
# endif /* AF_LOCAL */
# if defined(LOCAL_PEERCRED) && !defined(SO_PEERCRED)
# define SO_PEERCRED LOCAL_PEERCRED
# endif /* LOCAL_PEERCRED && !SO_PEERCRED */
# endif /* WIN32 */
/*
* C++ magic...
*/
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/*
* Oh, the wonderful world of IPv6 compatibility. Apparently some
* implementations expose the (more logical) 32-bit address parts
* to everyone, while others only expose it to kernel code... To
* make supporting IPv6 even easier, each vendor chose different
* core structure and union names, so the same defines or code
* can't be used on all platforms.
*
* The following will likely need tweaking on new platforms that
* support IPv6 - the "s6_addr32" define maps to the 32-bit integer
* array in the in6_addr union, which is named differently on various
* platforms.
*/
#if defined(AF_INET6) && !defined(s6_addr32)
# if defined(__sun)
# 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(__osf__)
# define s6_addr32 s6_un.sa6_laddr
# elif defined(WIN32)
/*
* Windows only defines byte and 16-bit word members of the union and
* requires special casing of all raw address code...
*/
# define s6_addr32 error_need_win32_specific_code
# endif /* __sun */
#endif /* AF_INET6 && !s6_addr32 */
/*
* Limits...
*/
# define HTTP_MAX_URI 1024 /* Max length of URI string */
# define HTTP_MAX_HOST 256 /* Max length of hostname string */
# define HTTP_MAX_BUFFER 2048 /* Max length of data buffer */
# define HTTP_MAX_VALUE 256 /* Max header field value length */
/*
* Types and structures...
*/
typedef enum http_auth_e /**** HTTP authentication types ****/
{
HTTP_AUTH_NONE, /* No authentication in use */
HTTP_AUTH_BASIC, /* Basic authentication in use */
HTTP_AUTH_MD5, /* Digest authentication in use */
HTTP_AUTH_MD5_SESS, /* MD5-session authentication in use */
HTTP_AUTH_MD5_INT, /* Digest authentication in use for body */
HTTP_AUTH_MD5_SESS_INT, /* MD5-session authentication in use for body */
HTTP_AUTH_NEGOTIATE /* GSSAPI authentication in use @since CUPS 1.3/OS X 10.5@ */
} http_auth_t;
typedef enum http_encoding_e /**** HTTP transfer encoding values ****/
{
HTTP_ENCODE_LENGTH, /* Data is sent with Content-Length */
HTTP_ENCODE_CHUNKED, /* Data is chunked */
HTTP_ENCODE_FIELDS /* Sending HTTP fields */
} http_encoding_t;
typedef enum http_encryption_e /**** HTTP encryption values ****/
{
HTTP_ENCRYPT_IF_REQUESTED, /* Encrypt if requested (TLS upgrade) */
HTTP_ENCRYPT_NEVER, /* Never encrypt */
HTTP_ENCRYPT_REQUIRED, /* Encryption is required (TLS upgrade) */
HTTP_ENCRYPT_ALWAYS /* Always encrypt (SSL) */
} http_encryption_t;
typedef enum http_field_e /**** HTTP field names ****/
{
HTTP_FIELD_UNKNOWN = -1, /* Unknown field */
HTTP_FIELD_ACCEPT_LANGUAGE, /* Accept-Language field */
HTTP_FIELD_ACCEPT_RANGES, /* Accept-Ranges field */
HTTP_FIELD_AUTHORIZATION, /* Authorization field */
HTTP_FIELD_CONNECTION, /* Connection field */
HTTP_FIELD_CONTENT_ENCODING, /* Content-Encoding field */
HTTP_FIELD_CONTENT_LANGUAGE, /* Content-Language field */
HTTP_FIELD_CONTENT_LENGTH, /* Content-Length field */
HTTP_FIELD_CONTENT_LOCATION, /* Content-Location field */
HTTP_FIELD_CONTENT_MD5, /* Content-MD5 field */
HTTP_FIELD_CONTENT_RANGE, /* Content-Range field */
HTTP_FIELD_CONTENT_TYPE, /* Content-Type field */
HTTP_FIELD_CONTENT_VERSION, /* Content-Version field */
HTTP_FIELD_DATE, /* Date field */
HTTP_FIELD_HOST, /* Host field */
HTTP_FIELD_IF_MODIFIED_SINCE, /* If-Modified-Since field */
HTTP_FIELD_IF_UNMODIFIED_SINCE, /* If-Unmodified-Since field */
HTTP_FIELD_KEEP_ALIVE, /* Keep-Alive field */
HTTP_FIELD_LAST_MODIFIED, /* Last-Modified field */
HTTP_FIELD_LINK, /* Link field */
HTTP_FIELD_LOCATION, /* Location field */
HTTP_FIELD_RANGE, /* Range field */
HTTP_FIELD_REFERER, /* Referer field */
HTTP_FIELD_RETRY_AFTER, /* Retry-After field */
HTTP_FIELD_TRANSFER_ENCODING, /* Transfer-Encoding field */
HTTP_FIELD_UPGRADE, /* Upgrade field */
HTTP_FIELD_USER_AGENT, /* User-Agent field */
HTTP_FIELD_WWW_AUTHENTICATE, /* WWW-Authenticate field */
HTTP_FIELD_MAX /* Maximum field index */
} http_field_t;
typedef enum http_keepalive_e /**** HTTP keep-alive values ****/
{
HTTP_KEEPALIVE_OFF = 0, /* No keep alive support */
HTTP_KEEPALIVE_ON /* Use keep alive */
} http_keepalive_t;
typedef enum http_state_e /**** HTTP state values; states
**** are server-oriented...
****/
{
HTTP_WAITING, /* Waiting for command */
HTTP_OPTIONS, /* OPTIONS command, waiting for blank line */
HTTP_GET, /* GET command, waiting for blank line */
HTTP_GET_SEND, /* GET command, sending data */
HTTP_HEAD, /* HEAD command, waiting for blank line */
HTTP_POST, /* POST command, waiting for blank line */
HTTP_POST_RECV, /* POST command, receiving data */
HTTP_POST_SEND, /* POST command, sending data */
HTTP_PUT, /* PUT command, waiting for blank line */
HTTP_PUT_RECV, /* PUT command, receiving data */
HTTP_DELETE, /* DELETE command, waiting for blank line */
HTTP_TRACE, /* TRACE command, waiting for blank line */
HTTP_CLOSE, /* CLOSE command, waiting for blank line */
HTTP_STATUS /* Command complete, sending status */
} http_state_t;
typedef enum http_status_e /**** HTTP status codes ****/
{
HTTP_ERROR = -1, /* An error response from httpXxxx() */
HTTP_CONTINUE = 100, /* Everything OK, keep going... */
HTTP_SWITCHING_PROTOCOLS, /* HTTP upgrade to TLS/SSL */
HTTP_OK = 200, /* OPTIONS/GET/HEAD/POST/TRACE command was successful */
HTTP_CREATED, /* PUT command was successful */
HTTP_ACCEPTED, /* DELETE command was successful */
HTTP_NOT_AUTHORITATIVE, /* Information isn't authoritative */
HTTP_NO_CONTENT, /* Successful command, no new data */
HTTP_RESET_CONTENT, /* Content was reset/recreated */
HTTP_PARTIAL_CONTENT, /* Only a partial file was recieved/sent */
HTTP_MULTIPLE_CHOICES = 300, /* Multiple files match request */
HTTP_MOVED_PERMANENTLY, /* Document has moved permanently */
HTTP_MOVED_TEMPORARILY, /* Document has moved temporarily */
HTTP_SEE_OTHER, /* See this other link... */
HTTP_NOT_MODIFIED, /* File not modified */
HTTP_USE_PROXY, /* Must use a proxy to access this URI */
HTTP_BAD_REQUEST = 400, /* Bad request */
HTTP_UNAUTHORIZED, /* Unauthorized to access host */
HTTP_PAYMENT_REQUIRED, /* Payment required */
HTTP_FORBIDDEN, /* Forbidden to access this URI */
HTTP_NOT_FOUND, /* URI was not found */
HTTP_METHOD_NOT_ALLOWED, /* Method is not allowed */
HTTP_NOT_ACCEPTABLE, /* Not Acceptable */
HTTP_PROXY_AUTHENTICATION, /* Proxy Authentication is Required */
HTTP_REQUEST_TIMEOUT, /* Request timed out */
HTTP_CONFLICT, /* Request is self-conflicting */
HTTP_GONE, /* Server has gone away */
HTTP_LENGTH_REQUIRED, /* A content length or encoding is required */
HTTP_PRECONDITION, /* Precondition failed */
HTTP_REQUEST_TOO_LARGE, /* Request entity too large */
HTTP_URI_TOO_LONG, /* URI too long */
HTTP_UNSUPPORTED_MEDIATYPE, /* The requested media type is unsupported */
HTTP_REQUESTED_RANGE, /* The requested range is not satisfiable */
HTTP_EXPECTATION_FAILED, /* The expectation given in an Expect header field was not met */
HTTP_UPGRADE_REQUIRED = 426, /* Upgrade to SSL/TLS required */
HTTP_SERVER_ERROR = 500, /* Internal server error */
HTTP_NOT_IMPLEMENTED, /* Feature not implemented */
HTTP_BAD_GATEWAY, /* Bad gateway */
HTTP_SERVICE_UNAVAILABLE, /* Service is unavailable */
HTTP_GATEWAY_TIMEOUT, /* Gateway connection timed out */
HTTP_NOT_SUPPORTED, /* HTTP version not supported */
HTTP_AUTHORIZATION_CANCELED = 1000, /* User canceled authorization @since CUPS 1.4@ */
HTTP_PKI_ERROR, /* Error negotiating a secure connection @since CUPS 1.5/OS X 10.7@ */
HTTP_WEBIF_DISABLED /* Web interface is disabled @private@ */
} http_status_t;
typedef enum http_uri_status_e /**** URI separation status @since CUPS 1.2@ ****/
{
HTTP_URI_OVERFLOW = -8, /* URI buffer for httpAssembleURI is too small */
HTTP_URI_BAD_ARGUMENTS = -7, /* Bad arguments to function (error) */
HTTP_URI_BAD_RESOURCE = -6, /* Bad resource in URI (error) */
HTTP_URI_BAD_PORT = -5, /* Bad port number in URI (error) */
HTTP_URI_BAD_HOSTNAME = -4, /* Bad hostname in URI (error) */
HTTP_URI_BAD_USERNAME = -3, /* Bad username in URI (error) */
HTTP_URI_BAD_SCHEME = -2, /* Bad scheme in URI (error) */
HTTP_URI_BAD_URI = -1, /* Bad/empty URI (error) */
HTTP_URI_OK = 0, /* URI decoded OK */
HTTP_URI_MISSING_SCHEME, /* Missing scheme in URI (warning) */
HTTP_URI_UNKNOWN_SCHEME, /* Unknown scheme in URI (warning) */
HTTP_URI_MISSING_RESOURCE /* Missing resource in URI (warning) */
} http_uri_status_t;
typedef enum http_uri_coding_e /**** URI en/decode flags ****/
{
HTTP_URI_CODING_NONE = 0, /* Don't en/decode anything */
HTTP_URI_CODING_USERNAME = 1, /* En/decode the username portion */
HTTP_URI_CODING_HOSTNAME = 2, /* En/decode the hostname portion */
HTTP_URI_CODING_RESOURCE = 4, /* En/decode the resource portion */
HTTP_URI_CODING_MOST = 7, /* En/decode all but the query */
HTTP_URI_CODING_QUERY = 8, /* En/decode the query portion */
HTTP_URI_CODING_ALL = 15, /* En/decode everything */
HTTP_URI_CODING_RFC6874 = 16 /* Use RFC 6874 address format */
} http_uri_coding_t;
typedef enum http_version_e /**** HTTP version numbers ****/
{
HTTP_0_9 = 9, /* HTTP/0.9 */
HTTP_1_0 = 100, /* HTTP/1.0 */
HTTP_1_1 = 101 /* HTTP/1.1 */
} http_version_t;
typedef union _http_addr_u /**** Socket address union, which
**** makes using IPv6 and other
**** address types easier and
**** more portable. @since CUPS 1.2/OS X 10.5@
****/
{
struct sockaddr addr; /* Base structure for family value */
struct sockaddr_in ipv4; /* IPv4 address */
#ifdef AF_INET6
struct sockaddr_in6 ipv6; /* IPv6 address */
#endif /* AF_INET6 */
#ifdef AF_LOCAL
struct sockaddr_un un; /* Domain socket file */
#endif /* AF_LOCAL */
char pad[256]; /* Padding to ensure binary compatibility */
} http_addr_t;
typedef struct http_addrlist_s /**** Socket address list, which is
**** used to enumerate all of the
**** addresses that are associated
**** with a hostname. @since CUPS 1.2/OS X 10.5@
****/
{
struct http_addrlist_s *next; /* Pointer to next address in list */
http_addr_t addr; /* Address */
} http_addrlist_t;
typedef struct _http_s http_t; /**** HTTP connection type ****/
typedef struct http_credential_s /**** HTTP credential data @since CUPS 1.5/OS X 10.7@ ****/
{
void *data; /* Pointer to credential data */
size_t datalen; /* Credential length */
} http_credential_t;
typedef int (*http_timeout_cb_t)(http_t *http, void *user_data);
/**** HTTP timeout callback @since CUPS 1.5/OS X 10.7@ ****/
/*
* 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);
extern http_t *httpConnectEncrypt(const char *host, int port,
http_encryption_t encryption);
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 int httpRead(http_t *http, char *buffer, int length) _CUPS_DEPRECATED;
extern int httpReconnect(http_t *http);
extern void httpSeparate(const char *uri, char *method,
char *username, char *host, int *port,
char *resource) _CUPS_DEPRECATED;
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 int httpWrite(http_t *http, const char *buffer, int length) _CUPS_DEPRECATED;
extern char *httpEncode64(char *out, const char *in) _CUPS_DEPRECATED;
extern char *httpDecode64(char *out, const char *in) _CUPS_DEPRECATED;
extern int httpGetLength(http_t *http) _CUPS_DEPRECATED;
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]);
/**** New in CUPS 1.1.19 ****/
extern void httpClearCookie(http_t *http) _CUPS_API_1_1_19;
extern const char *httpGetCookie(http_t *http) _CUPS_API_1_1_19;
extern void httpSetCookie(http_t *http, const char *cookie) _CUPS_API_1_1_19;
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;
/**** New in CUPS 1.2/OS X 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 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 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 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;
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 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 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;
/**** New in CUPS 1.3/OS X 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;
/**** New in CUPS 1.5/OS X 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 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;
/**** New in CUPS 1.6/OS X 10.8 ****/
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;
/*
* C++ magic...
*/
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_HTTP_H_ */
/*
* End of "$Id: http.h 7026 2007-10-19 00:57:45Z mike $".
*/

78
cups/ipp-private.h Normal file
View File

@@ -0,0 +1,78 @@
/*
* "$Id: ipp-private.h 7259 2008-01-28 22:26:04Z mike $"
*
* Private IPP definitions for CUPS.
*
* 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*/
#ifndef _CUPS_IPP_PRIVATE_H_
# define _CUPS_IPP_PRIVATE_H_
/*
* Include necessary headers...
*/
# include <cups/ipp.h>
/*
* C++ magic...
*/
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/*
* Constants...
*/
# define IPP_BUF_SIZE (IPP_MAX_LENGTH + 2)
/* Size of buffer */
/*
* Structures...
*/
typedef struct /**** Attribute mapping data ****/
{
int multivalue; /* Option has multiple values? */
const char *name; /* Option/attribute name */
ipp_tag_t value_tag; /* Value tag for this attribute */
ipp_tag_t group_tag; /* Group tag for this attribute */
ipp_tag_t alt_group_tag; /* Alternate group tag for this
* attribute */
} _ipp_option_t;
/*
* Prototypes for private functions...
*/
extern _ipp_option_t *_ippFindOption(const char *name);
/*
* C++ magic...
*/
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_IPP_H_ */
/*
* End of "$Id: ipp-private.h 7259 2008-01-28 22:26:04Z mike $".
*/

1090
cups/ipp-support.c Normal file

File diff suppressed because it is too large Load Diff

5574
cups/ipp.c Normal file

File diff suppressed because it is too large Load Diff

671
cups/ipp.h Normal file
View File

@@ -0,0 +1,671 @@
/*
* "$Id: ipp.h 7847 2008-08-19 04:22:14Z mike $"
*
* Internet Printing Protocol definitions 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/".
*
* This file is subject to the Apple OS-Developed Software exception.
*/
#ifndef _CUPS_IPP_H_
# define _CUPS_IPP_H_
/*
* Include necessary headers...
*/
# include "http.h"
/*
* C++ magic...
*/
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/*
* IPP version string...
*/
# define IPP_VERSION "\002\001"
/*
* IPP registered port number...
*
* Note: Applications should never use IPP_PORT, but instead use the
* ippPort() function to allow overrides via the IPP_PORT environment
* variable and services file if needed!
*/
# define IPP_PORT 631
/*
* Common limits...
*/
# define IPP_MAX_LENGTH 32767 /* Maximum size of any single value */
# define IPP_MAX_NAME 256 /* Maximum length of common name values */
# define IPP_MAX_VALUES 8 /* Power-of-2 allocation increment */
/*
* Types and structures...
*/
typedef enum ipp_dstate_e /**** Document states ****/
{
IPP_DOCUMENT_PENDING = 3,
IPP_DOCUMENT_PROCESSING = 5,
IPP_DOCUMENT_CANCELED = 7,
IPP_DOCUMENT_ABORTED,
IPP_DOCUMENT_COMPLETED
} ipp_dstate_t;
typedef enum ipp_finish_e /**** Finishings ****/
{
IPP_FINISHINGS_NONE = 3, /* No finishing */
IPP_FINISHINGS_STAPLE, /* Staple (any location) */
IPP_FINISHINGS_PUNCH, /* Punch (any location/count) */
IPP_FINISHINGS_COVER, /* Add cover */
IPP_FINISHINGS_BIND, /* Bind */
IPP_FINISHINGS_SADDLE_STITCH, /* Staple interior */
IPP_FINISHINGS_EDGE_STITCH, /* Stitch along any side */
IPP_FINISHINGS_FOLD, /* Fold (any type) */
IPP_FINISHINGS_TRIM, /* Trim (any type) */
IPP_FINISHINGS_BALE, /* Bale (any type) */
IPP_FINISHINGS_BOOKLET_MAKER, /* Fold to make booklet */
IPP_FINISHINGS_JOB_OFFSET, /* Offset for binding (any type) */
IPP_FINISHINGS_STAPLE_TOP_LEFT = 20, /* Staple top left corner */
IPP_FINISHINGS_STAPLE_BOTTOM_LEFT, /* Staple bottom left corner */
IPP_FINISHINGS_STAPLE_TOP_RIGHT, /* Staple top right corner */
IPP_FINISHINGS_STAPLE_BOTTOM_RIGHT, /* Staple bottom right corner */
IPP_FINISHINGS_EDGE_STITCH_LEFT, /* Stitch along left side */
IPP_FINISHINGS_EDGE_STITCH_TOP, /* Stitch along top edge */
IPP_FINISHINGS_EDGE_STITCH_RIGHT, /* Stitch along right side */
IPP_FINISHINGS_EDGE_STITCH_BOTTOM, /* Stitch along bottom edge */
IPP_FINISHINGS_STAPLE_DUAL_LEFT, /* Two staples on left */
IPP_FINISHINGS_STAPLE_DUAL_TOP, /* Two staples on top */
IPP_FINISHINGS_STAPLE_DUAL_RIGHT, /* Two staples on right */
IPP_FINISHINGS_STAPLE_DUAL_BOTTOM, /* Two staples on bottom */
IPP_FINISHINGS_BIND_LEFT = 50, /* Bind on left */
IPP_FINISHINGS_BIND_TOP, /* Bind on top */
IPP_FINISHINGS_BIND_RIGHT, /* Bind on right */
IPP_FINISHINGS_BIND_BOTTOM, /* Bind on bottom */
IPP_FINISHINGS_TRIM_AFTER_PAGES = 60, /* Trim output after each page */
IPP_FINISHINGS_TRIM_AFTER_DOCUMENTS, /* Trim output after each document */
IPP_FINISHINGS_TRIM_AFTER_COPIES, /* Trim output after each copy */
IPP_FINISHINGS_TRIM_AFTER_JOB /* Trim output after job */
} ipp_finish_t;
typedef enum ipp_jcollate_e /**** Job collation types ****/
{
IPP_JOB_UNCOLLATED_SHEETS = 3,
IPP_JOB_COLLATED_DOCUMENTS,
IPP_JOB_UNCOLLATED_DOCUMENTS
} ipp_jcollate_t;
typedef enum ipp_jstate_e /**** Job states ****/
{
IPP_JOB_PENDING = 3, /* Job is waiting to be printed */
IPP_JOB_HELD, /* Job is held for printing */
IPP_JOB_PROCESSING, /* Job is currently printing */
IPP_JOB_STOPPED, /* Job has been stopped */
IPP_JOB_CANCELED, /* Job has been canceled */
IPP_JOB_ABORTED, /* Job has aborted due to error */
IPP_JOB_COMPLETED /* Job has completed successfully */
/* Legacy name for canceled state */
#define IPP_JOB_CANCELLED IPP_JOB_CANCELED
} ipp_jstate_t;
typedef enum ipp_op_e /**** IPP operations ****/
{
IPP_OP_CUPS_INVALID = -1, /* Invalid operation name for @link ippOpValue@ */
IPP_PRINT_JOB = 0x0002, /* Print a single file */
IPP_PRINT_URI, /* Print a single URL @private@ */
IPP_VALIDATE_JOB, /* Validate job options */
IPP_CREATE_JOB, /* Create an empty print job */
IPP_SEND_DOCUMENT, /* Add a file to a job */
IPP_SEND_URI, /* Add a URL to a job @private@ */
IPP_CANCEL_JOB, /* Cancel a job */
IPP_GET_JOB_ATTRIBUTES, /* Get job attributes */
IPP_GET_JOBS, /* Get a list of jobs */
IPP_GET_PRINTER_ATTRIBUTES, /* Get printer attributes */
IPP_HOLD_JOB, /* Hold a job for printing */
IPP_RELEASE_JOB, /* Release a job for printing */
IPP_RESTART_JOB, /* Reprint a job */
IPP_PAUSE_PRINTER = 0x0010, /* Stop a printer */
IPP_RESUME_PRINTER, /* Start a printer */
IPP_PURGE_JOBS, /* Cancel all jobs */
IPP_SET_PRINTER_ATTRIBUTES, /* Set printer attributes @private@ */
IPP_SET_JOB_ATTRIBUTES, /* Set job attributes */
IPP_GET_PRINTER_SUPPORTED_VALUES, /* Get supported attribute values */
IPP_CREATE_PRINTER_SUBSCRIPTION, /* Create a printer subscription @since CUPS 1.2/OS X 10.5@ */
IPP_CREATE_JOB_SUBSCRIPTION, /* Create a job subscription @since CUPS 1.2/OS X 10.5@ */
IPP_GET_SUBSCRIPTION_ATTRIBUTES, /* Get subscription attributes @since CUPS 1.2/OS X 10.5@ */
IPP_GET_SUBSCRIPTIONS, /* Get list of subscriptions @since CUPS 1.2/OS X 10.5@ */
IPP_RENEW_SUBSCRIPTION, /* Renew a printer subscription @since CUPS 1.2/OS X 10.5@ */
IPP_CANCEL_SUBSCRIPTION, /* Cancel a subscription @since CUPS 1.2/OS X 10.5@ */
IPP_GET_NOTIFICATIONS, /* Get notification events @since CUPS 1.2/OS X 10.5@ */
IPP_SEND_NOTIFICATIONS, /* Send notification events @private@ */
IPP_GET_RESOURCE_ATTRIBUTES, /* Get resource attributes @private@ */
IPP_GET_RESOURCE_DATA, /* Get resource data @private@ */
IPP_GET_RESOURCES, /* Get list of resources @private@ */
IPP_GET_PRINT_SUPPORT_FILES, /* Get printer support files @private@ */
IPP_ENABLE_PRINTER, /* Start a printer */
IPP_DISABLE_PRINTER, /* Stop a printer */
IPP_PAUSE_PRINTER_AFTER_CURRENT_JOB, /* Stop printer after the current job @private@ */
IPP_HOLD_NEW_JOBS, /* Hold new jobs @private@ */
IPP_RELEASE_HELD_NEW_JOBS, /* Release new jobs @private@ */
IPP_DEACTIVATE_PRINTER, /* Stop a printer @private@ */
IPP_ACTIVATE_PRINTER, /* Start a printer @private@ */
IPP_RESTART_PRINTER, /* Restart a printer @private@ */
IPP_SHUTDOWN_PRINTER, /* Turn a printer off @private@ */
IPP_STARTUP_PRINTER, /* Turn a printer on @private@ */
IPP_REPROCESS_JOB, /* Reprint a job @private@ */
IPP_CANCEL_CURRENT_JOB, /* Cancel the current job @private@ */
IPP_SUSPEND_CURRENT_JOB, /* Suspend the current job @private@ */
IPP_RESUME_JOB, /* Resume the current job @private@ */
IPP_PROMOTE_JOB, /* Promote a job to print sooner @private@ */
IPP_SCHEDULE_JOB_AFTER, /* Schedule a job to print after another @private@ */
IPP_CANCEL_DOCUMENT = 0x0033, /* Cancel-Document @private@ */
IPP_GET_DOCUMENT_ATTRIBUTES, /* Get-Document-Attributes @private@ */
IPP_GET_DOCUMENTS, /* Get-Documents @private@ */
IPP_DELETE_DOCUMENT, /* Delete-Document @private@ */
IPP_SET_DOCUMENT_ATTRIBUTES, /* Set-Document-Attributes @private@ */
IPP_CANCEL_JOBS, /* Cancel-Jobs */
IPP_CANCEL_MY_JOBS, /* Cancel-My-Jobs */
IPP_RESUBMIT_JOB, /* Resubmit-Job */
IPP_CLOSE_JOB, /* Close-Job */
IPP_IDENTIFY_PRINTER, /* Identify-Printer (proposed IPP JPS3) */
IPP_VALIDATE_DOCUMENT, /* Validate-Document (proposed IPP JPS3) */
IPP_PRIVATE = 0x4000, /* Reserved @private@ */
CUPS_GET_DEFAULT, /* Get the default printer */
CUPS_GET_PRINTERS, /* Get a list of printers and/or classes */
CUPS_ADD_MODIFY_PRINTER, /* Add or modify a printer */
CUPS_DELETE_PRINTER, /* Delete a printer */
CUPS_GET_CLASSES, /* Get a list of classes @deprecated@ */
CUPS_ADD_MODIFY_CLASS, /* Add or modify a class */
CUPS_DELETE_CLASS, /* Delete a class */
CUPS_ACCEPT_JOBS, /* Accept new jobs on a printer */
CUPS_REJECT_JOBS, /* Reject new jobs on a printer */
CUPS_SET_DEFAULT, /* Set the default printer */
CUPS_GET_DEVICES, /* Get a list of supported devices */
CUPS_GET_PPDS, /* Get a list of supported drivers */
CUPS_MOVE_JOB, /* Move a job to a different printer */
CUPS_AUTHENTICATE_JOB, /* Authenticate a job @since CUPS 1.2/OS X 10.5@ */
CUPS_GET_PPD, /* Get a PPD file @since CUPS 1.3/OS X 10.5@ */
CUPS_GET_DOCUMENT = 0x4027 /* Get a document file @since CUPS 1.4/OS X 10.6@ */
/* Legacy names for the add operations */
#define CUPS_ADD_PRINTER CUPS_ADD_MODIFY_PRINTER
#define CUPS_ADD_CLASS CUPS_ADD_MODIFY_CLASS
} ipp_op_t;
typedef enum ipp_orient_e /**** Orientation values ****/
{
IPP_PORTRAIT = 3, /* No rotation */
IPP_LANDSCAPE, /* 90 degrees counter-clockwise */
IPP_REVERSE_LANDSCAPE, /* 90 degrees clockwise */
IPP_REVERSE_PORTRAIT /* 180 degrees */
} ipp_orient_t;
typedef enum ipp_pstate_e /**** Printer states ****/
{
IPP_PRINTER_IDLE = 3, /* Printer is idle */
IPP_PRINTER_PROCESSING, /* Printer is working */
IPP_PRINTER_STOPPED /* Printer is stopped */
} ipp_pstate_t;
typedef enum ipp_quality_e /**** Qualities ****/
{
IPP_QUALITY_DRAFT = 3, /* Draft quality */
IPP_QUALITY_NORMAL, /* Normal quality */
IPP_QUALITY_HIGH /* High quality */
} ipp_quality_t;
typedef enum ipp_res_e /**** Resolution units ****/
{
IPP_RES_PER_INCH = 3, /* Pixels per inch */
IPP_RES_PER_CM /* Pixels per centimeter */
} ipp_res_t;
typedef enum ipp_state_e /**** IPP states ****/
{
IPP_ERROR = -1, /* An error occurred */
IPP_IDLE, /* Nothing is happening/request completed */
IPP_HEADER, /* The request header needs to be sent/received */
IPP_ATTRIBUTE, /* One or more attributes need to be sent/received */
IPP_DATA /* IPP request data needs to be sent/received */
} ipp_state_t;
typedef enum ipp_status_e /**** IPP status codes ****/
{
IPP_STATUS_CUPS_INVALID = -1, /* Invalid status name for @link ippErrorValue@ */
IPP_OK = 0x0000, /* successful-ok */
IPP_OK_SUBST, /* successful-ok-ignored-or-substituted-attributes */
IPP_OK_CONFLICT, /* successful-ok-conflicting-attributes */
IPP_OK_IGNORED_SUBSCRIPTIONS, /* successful-ok-ignored-subscriptions */
IPP_OK_IGNORED_NOTIFICATIONS, /* successful-ok-ignored-notifications @private@ */
IPP_OK_TOO_MANY_EVENTS, /* successful-ok-too-many-events */
IPP_OK_BUT_CANCEL_SUBSCRIPTION, /* successful-ok-but-cancel-subscription @private@ */
IPP_OK_EVENTS_COMPLETE, /* successful-ok-events-complete */
IPP_REDIRECTION_OTHER_SITE = 0x200, /* redirection-other-site @private@ */
CUPS_SEE_OTHER = 0x280, /* cups-see-other */
IPP_BAD_REQUEST = 0x0400, /* client-error-bad-request */
IPP_FORBIDDEN, /* client-error-forbidden */
IPP_NOT_AUTHENTICATED, /* client-error-not-authenticated */
IPP_NOT_AUTHORIZED, /* client-error-not-authorized */
IPP_NOT_POSSIBLE, /* client-error-not-possible */
IPP_TIMEOUT, /* client-error-timeout */
IPP_NOT_FOUND, /* client-error-not-found */
IPP_GONE, /* client-error-gone */
IPP_REQUEST_ENTITY, /* client-error-request-entity-too-large */
IPP_REQUEST_VALUE, /* client-error-request-value-too-long */
IPP_DOCUMENT_FORMAT, /* client-error-document-format-not-supported */
IPP_ATTRIBUTES, /* client-error-attributes-or-values-not-supported */
IPP_URI_SCHEME, /* client-error-uri-scheme-not-supported */
IPP_CHARSET, /* client-error-charset-not-supported */
IPP_CONFLICT, /* client-error-conflicting-attributes */
IPP_COMPRESSION_NOT_SUPPORTED, /* client-error-compression-not-supported */
IPP_COMPRESSION_ERROR, /* client-error-compression-error */
IPP_DOCUMENT_FORMAT_ERROR, /* client-error-document-format-error */
IPP_DOCUMENT_ACCESS_ERROR, /* client-error-document-access-error */
IPP_ATTRIBUTES_NOT_SETTABLE, /* client-error-attributes-not-settable */
IPP_IGNORED_ALL_SUBSCRIPTIONS, /* client-error-ignored-all-subscriptions */
IPP_TOO_MANY_SUBSCRIPTIONS, /* client-error-too-many-subscriptions */
IPP_IGNORED_ALL_NOTIFICATIONS, /* client-error-ignored-all-notifications @private@ */
IPP_PRINT_SUPPORT_FILE_NOT_FOUND, /* client-error-print-support-file-not-found @private@ */
IPP_DOCUMENT_PASSWORD_ERROR, /* client-error-document-password-error */
IPP_DOCUMENT_PERMISSION_ERROR, /* client-error-document-permission-error */
IPP_DOCUMENT_SECURITY_ERROR, /* client-error-document-security-error */
IPP_DOCUMENT_UNPRINTABLE_ERROR, /* client-error-document-unprintable-error */
IPP_INTERNAL_ERROR = 0x0500, /* server-error-internal-error */
IPP_OPERATION_NOT_SUPPORTED, /* server-error-operation-not-supported */
IPP_SERVICE_UNAVAILABLE, /* server-error-service-unavailable */
IPP_VERSION_NOT_SUPPORTED, /* server-error-version-not-supported */
IPP_DEVICE_ERROR, /* server-error-device-error */
IPP_TEMPORARY_ERROR, /* server-error-temporary-error */
IPP_NOT_ACCEPTING, /* server-error-not-accepting-jobs */
IPP_PRINTER_BUSY, /* server-error-busy */
IPP_ERROR_JOB_CANCELED, /* server-error-job-canceled */
IPP_MULTIPLE_JOBS_NOT_SUPPORTED, /* server-error-multiple-document-jobs-not-supported */
IPP_PRINTER_IS_DEACTIVATED, /* server-error-printer-is-deactivated */
IPP_TOO_MANY_JOBS, /* server-error-too-many-jobs */
IPP_TOO_MANY_DOCUMENTS, /* server-error-too-many-documents */
IPP_AUTHENTICATION_CANCELED = 0x1000, /* Authentication canceled by user @since CUPS 1.5/OS X 10.7@ */
IPP_PKI_ERROR, /* Error negotiating a secure connection @since CUPS 1.5/OS X 10.7@ */
IPP_UPGRADE_REQUIRED /* TLS upgrade required */
/* Legacy name for canceled status */
#define IPP_ERROR_JOB_CANCELLED IPP_ERROR_JOB_CANCELED
} ipp_status_t;
typedef enum ipp_tag_e /**** Format tags for attributes ****/
{
IPP_TAG_CUPS_INVALID = -1, /* Invalid tag name for @link ippTagValue@ */
IPP_TAG_ZERO = 0x00, /* Zero tag - used for separators */
IPP_TAG_OPERATION, /* Operation group */
IPP_TAG_JOB, /* Job group */
IPP_TAG_END, /* End-of-attributes */
IPP_TAG_PRINTER, /* Printer group */
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 */
IPP_TAG_UNSUPPORTED_VALUE = 0x10, /* Unsupported value */
IPP_TAG_DEFAULT, /* Default value */
IPP_TAG_UNKNOWN, /* Unknown value */
IPP_TAG_NOVALUE, /* No-value value */
IPP_TAG_NOTSETTABLE = 0x15, /* Not-settable value */
IPP_TAG_DELETEATTR, /* Delete-attribute value */
IPP_TAG_ADMINDEFINE, /* Admin-defined value */
IPP_TAG_INTEGER = 0x21, /* Integer value */
IPP_TAG_BOOLEAN, /* Boolean value */
IPP_TAG_ENUM, /* Enumeration value */
IPP_TAG_STRING = 0x30, /* Octet string value */
IPP_TAG_DATE, /* Date/time value */
IPP_TAG_RESOLUTION, /* Resolution value */
IPP_TAG_RANGE, /* Range value */
IPP_TAG_BEGIN_COLLECTION, /* Beginning of collection value */
IPP_TAG_TEXTLANG, /* Text-with-language value */
IPP_TAG_NAMELANG, /* Name-with-language value */
IPP_TAG_END_COLLECTION, /* End of collection value */
IPP_TAG_TEXT = 0x41, /* Text value */
IPP_TAG_NAME, /* Name value */
IPP_TAG_RESERVED_STRING, /* Reserved for future string value @private@ */
IPP_TAG_KEYWORD, /* Keyword value */
IPP_TAG_URI, /* URI value */
IPP_TAG_URISCHEME, /* URI scheme value */
IPP_TAG_CHARSET, /* Character set value */
IPP_TAG_LANGUAGE, /* Language value */
IPP_TAG_MIMETYPE, /* MIME media type value */
IPP_TAG_MEMBERNAME, /* Collection member name value */
IPP_TAG_EXTENSION = 0x7f, /* Extension point for 32-bit tags */
IPP_TAG_MASK = 0x7fffffff, /* Mask for copied attribute values @private@ */
/* The following expression is used to avoid compiler warnings with +/-0x80000000 */
IPP_TAG_COPY = -0x7fffffff-1 /* Bitflag for copied attribute values @private@ */
} ipp_tag_t;
typedef unsigned char ipp_uchar_t; /**** Unsigned 8-bit integer/character ****/
typedef struct _ipp_s ipp_t; /**** IPP request/response data ****/
typedef struct _ipp_attribute_s ipp_attribute_t;
/**** IPP attribute ****/
/**** New in CUPS 1.2/OS X 10.5 ****/
typedef ssize_t (*ipp_iocb_t)(void *context, ipp_uchar_t *buffer, size_t bytes);
/**** IPP IO Callback Function @since CUPS 1.2/OS X 10.5@ ****/
/**** New in CUPS 1.6/OS X 10.8 ****/
typedef int (*ipp_copycb_t)(void *context, ipp_t *dst, ipp_attribute_t *attr);
/*
* The following structures are PRIVATE starting with CUPS 1.6/OS X 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 cause the private IPP structures to be
* exposed in CUPS 1.6. This happens automatically on OS X when compiling for
* a deployment target of 10.7 or earlier.
*/
# if 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 */
# endif /* _CUPS_SOURCE || _CUPS_IPP_PRIVATE_H_ */
# ifdef _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/OS X 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/OS X 10.3@ */
} _ipp_value_t;
typedef _ipp_value_t ipp_value_t; /**** Convenience typedef that will be removed @private@ ****/
struct _ipp_attribute_s /**** 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/OS X 10.5@ */
/**** New in CUPS 1.4.4 ****/
int use; /* Use count @since CUPS 1.4.4/OS X 10.6.?@ */
};
# endif /* _IPP_PRIVATE_STRUCTURES */
/*
* Prototypes...
*/
extern ipp_attribute_t *ippAddBoolean(ipp_t *ipp, ipp_tag_t group,
const char *name, char value);
extern ipp_attribute_t *ippAddBooleans(ipp_t *ipp, ipp_tag_t group,
const char *name, int num_values,
const char *values);
extern ipp_attribute_t *ippAddDate(ipp_t *ipp, ipp_tag_t group,
const char *name, const ipp_uchar_t *value);
extern ipp_attribute_t *ippAddInteger(ipp_t *ipp, ipp_tag_t group,
ipp_tag_t value_tag, const char *name,
int value);
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);
extern ipp_attribute_t *ippAddRange(ipp_t *ipp, ipp_tag_t group,
const char *name, int lower, int upper);
extern ipp_attribute_t *ippAddRanges(ipp_t *ipp, ipp_tag_t group,
const char *name, int num_values,
const int *lower, const int *upper);
extern ipp_attribute_t *ippAddResolution(ipp_t *ipp, ipp_tag_t group,
const char *name, ipp_res_t units,
int xres, int yres);
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);
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);
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);
extern ipp_attribute_t *ippFindAttribute(ipp_t *ipp, const char *name,
ipp_tag_t value_tag);
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);
/**** New in CUPS 1.1.19 ****/
extern ipp_attribute_t *ippAddCollection(ipp_t *ipp, ipp_tag_t group,
const char *name, ipp_t *value) _CUPS_API_1_1_19;
extern ipp_attribute_t *ippAddCollections(ipp_t *ipp, ipp_tag_t group,
const char *name, int num_values,
const ipp_t **values) _CUPS_API_1_1_19;
extern void ippDeleteAttribute(ipp_t *ipp, ipp_attribute_t *attr) _CUPS_API_1_1_19;
extern ipp_state_t ippReadFile(int fd, ipp_t *ipp) _CUPS_API_1_1_19;
extern ipp_state_t ippWriteFile(int fd, ipp_t *ipp) _CUPS_API_1_1_19;
/**** New in CUPS 1.2/OS X 10.5 ****/
extern ipp_attribute_t *ippAddOctetString(ipp_t *ipp, ipp_tag_t group,
const char *name,
const void *data, int datalen) _CUPS_API_1_2;
extern ipp_status_t ippErrorValue(const char *name) _CUPS_API_1_2;
extern ipp_t *ippNewRequest(ipp_op_t op) _CUPS_API_1_2;
extern const char *ippOpString(ipp_op_t op) _CUPS_API_1_2;
extern ipp_op_t ippOpValue(const char *name) _CUPS_API_1_2;
extern ipp_state_t ippReadIO(void *src, ipp_iocb_t cb, int blocking,
ipp_t *parent, ipp_t *ipp) _CUPS_API_1_2;
extern ipp_state_t ippWriteIO(void *dst, ipp_iocb_t cb, int blocking,
ipp_t *parent, ipp_t *ipp) _CUPS_API_1_2;
/**** New in CUPS 1.4/OS X 10.6 ****/
extern const char *ippTagString(ipp_tag_t tag) _CUPS_API_1_4;
extern ipp_tag_t ippTagValue(const char *name) _CUPS_API_1_4;
/**** New in CUPS 1.6/OS X 10.8 ****/
extern ipp_attribute_t *ippAddOutOfBand(ipp_t *ipp, ipp_tag_t group,
ipp_tag_t value_tag, const char *name)
_CUPS_API_1_6;
extern size_t ippAttributeString(ipp_attribute_t *attr, char *buffer,
size_t bufsize) _CUPS_API_1_6;
extern ipp_attribute_t *ippCopyAttribute(ipp_t *dst, ipp_attribute_t *attr,
int quickcopy) _CUPS_API_1_6;
extern int ippCopyAttributes(ipp_t *dst, ipp_t *src,
int quickcopy, ipp_copycb_t cb,
void *context) _CUPS_API_1_6;
extern int ippDeleteValues(ipp_t *ipp, ipp_attribute_t **attr,
int element, int count) _CUPS_API_1_6;
extern const char *ippEnumString(const char *attrname, int enumvalue)
_CUPS_API_1_6;
extern int ippEnumValue(const char *attrname,
const char *enumstring) _CUPS_API_1_6;
extern ipp_attribute_t *ippFirstAttribute(ipp_t *ipp) _CUPS_API_1_6;
extern int ippGetBoolean(ipp_attribute_t *attr, int element)
_CUPS_API_1_6;
extern ipp_t *ippGetCollection(ipp_attribute_t *attr,
int element) _CUPS_API_1_6;
extern int ippGetCount(ipp_attribute_t *attr) _CUPS_API_1_6;
extern const ipp_uchar_t *ippGetDate(ipp_attribute_t *attr, int element)
_CUPS_API_1_6;
extern ipp_tag_t ippGetGroupTag(ipp_attribute_t *attr) _CUPS_API_1_6;
extern int ippGetInteger(ipp_attribute_t *attr, int element)
_CUPS_API_1_6;
extern const char *ippGetName(ipp_attribute_t *attr) _CUPS_API_1_6;
extern ipp_op_t ippGetOperation(ipp_t *ipp) _CUPS_API_1_6;
extern int ippGetRange(ipp_attribute_t *attr, int element,
int *upper) _CUPS_API_1_6;
extern int ippGetRequestId(ipp_t *ipp) _CUPS_API_1_6;
extern int ippGetResolution(ipp_attribute_t *attr, int element,
int *yres, ipp_res_t *units)
_CUPS_API_1_6;
extern ipp_state_t ippGetState(ipp_t *ipp) _CUPS_API_1_6;
extern ipp_status_t ippGetStatusCode(ipp_t *ipp) _CUPS_API_1_6;
extern const char *ippGetString(ipp_attribute_t *attr, int element,
const char **language) _CUPS_API_1_6;
extern ipp_tag_t ippGetValueTag(ipp_attribute_t *attr) _CUPS_API_1_6;
extern int ippGetVersion(ipp_t *ipp, int *minor) _CUPS_API_1_6;
extern ipp_attribute_t *ippNextAttribute(ipp_t *ipp) _CUPS_API_1_6;
extern int ippSetBoolean(ipp_t *ipp, ipp_attribute_t **attr,
int element, int boolvalue) _CUPS_API_1_6;
extern int ippSetCollection(ipp_t *ipp, ipp_attribute_t **attr,
int element, ipp_t *colvalue)
_CUPS_API_1_6;
extern int ippSetDate(ipp_t *ipp, ipp_attribute_t **attr,
int element, const ipp_uchar_t *datevalue)
_CUPS_API_1_6;
extern int ippSetGroupTag(ipp_t *ipp, ipp_attribute_t **attr,
ipp_tag_t group_tag) _CUPS_API_1_6;
extern int ippSetInteger(ipp_t *ipp, ipp_attribute_t **attr,
int element, int intvalue) _CUPS_API_1_6;
extern int ippSetName(ipp_t *ipp, ipp_attribute_t **attr,
const char *name) _CUPS_API_1_6;
extern int ippSetOperation(ipp_t *ipp, ipp_op_t op) _CUPS_API_1_6;
extern int ippSetRange(ipp_t *ipp, ipp_attribute_t **attr,
int element, int lowervalue, int uppervalue)
_CUPS_API_1_6;
extern int ippSetRequestId(ipp_t *ipp, int request_id)
_CUPS_API_1_6;
extern int ippSetResolution(ipp_t *ipp, ipp_attribute_t **attr,
int element, ipp_res_t unitsvalue,
int xresvalue, int yresvalue)
_CUPS_API_1_6;
extern int ippSetState(ipp_t *ipp, ipp_state_t state)
_CUPS_API_1_6;
extern int ippSetStatusCode(ipp_t *ipp, ipp_status_t status)
_CUPS_API_1_6;
extern int ippSetString(ipp_t *ipp, ipp_attribute_t **attr,
int element, const char *strvalue)
_CUPS_API_1_6;
extern int ippSetValueTag(ipp_t *ipp, ipp_attribute_t **attr,
ipp_tag_t value_tag) _CUPS_API_1_6;
extern int ippSetVersion(ipp_t *ipp, int major, int minor)
_CUPS_API_1_6;
/*
* C++ magic...
*/
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_IPP_H_ */
/*
* End of "$Id: ipp.h 7847 2008-08-19 04:22:14Z mike $".
*/

352
cups/langprintf.c Normal file
View File

@@ -0,0 +1,352 @@
/*
* "$Id: langprintf.c 7802 2008-07-28 18:50:45Z mike $"
*
* Localized printf/puts functions for CUPS.
*
* Copyright 2007-2011 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*
* Contents:
*
* _cupsLangPrintError() - Print a message followed by a standard error.
* _cupsLangPrintFilter() - Print a formatted filter message string to a file.
* _cupsLangPrintf() - Print a formatted message string to a file.
* _cupsLangPuts() - Print a static message string to a file.
* _cupsSetLocale() - Set the current locale and transcode the
* command-line.
*/
/*
* Include necessary headers...
*/
#include "cups-private.h"
/*
* '_cupsLangPrintError()' - Print a message followed by a standard error.
*/
void
_cupsLangPrintError(const char *prefix, /* I - Non-localized message prefix */
const char *message)/* I - Message */
{
int bytes; /* Number of bytes formatted */
int last_errno; /* Last error */
char buffer[2048], /* Message buffer */
*bufptr, /* Pointer into buffer */
output[8192]; /* Output buffer */
_cups_globals_t *cg; /* Global data */
/*
* Range check...
*/
if (!message)
return;
/*
* Save the errno value...
*/
last_errno = errno;
/*
* Get the message catalog...
*/
cg = _cupsGlobals();
if (!cg->lang_default)
cg->lang_default = cupsLangDefault();
/*
* Format the message...
*/
if (prefix)
{
snprintf(buffer, sizeof(buffer), "%s:", prefix);
bufptr = buffer + strlen(buffer);
}
else
bufptr = buffer;
snprintf(bufptr, sizeof(buffer) - (bufptr - buffer),
/* TRANSLATORS: Message is "subject: error" */
_cupsLangString(cg->lang_default, _("%s: %s")),
_cupsLangString(cg->lang_default, message), strerror(last_errno));
strlcat(buffer, "\n", sizeof(buffer));
/*
* Convert and write to stderr...
*/
bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output),
cg->lang_default->encoding);
if (bytes > 0)
fwrite(output, 1, bytes, stderr);
}
/*
* '_cupsLangPrintFilter()' - Print a formatted filter message string to a file.
*/
int /* O - Number of bytes written */
_cupsLangPrintFilter(
FILE *fp, /* I - File to write to */
const char *prefix, /* I - Non-localized message prefix */
const char *message, /* I - Message string to use */
...) /* I - Additional arguments as needed */
{
int bytes; /* Number of bytes formatted */
char temp[2048], /* Temporary format buffer */
buffer[2048], /* Message buffer */
output[8192]; /* Output buffer */
va_list ap; /* Pointer to additional arguments */
_cups_globals_t *cg; /* Global data */
/*
* Range check...
*/
if (!fp || !message)
return (-1);
cg = _cupsGlobals();
if (!cg->lang_default)
cg->lang_default = cupsLangDefault();
/*
* Format the string...
*/
va_start(ap, message);
snprintf(temp, sizeof(temp), "%s: %s\n", prefix,
_cupsLangString(cg->lang_default, message));
vsnprintf(buffer, sizeof(buffer), temp, ap);
va_end(ap);
/*
* Transcode to the destination charset...
*/
bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output),
cg->lang_default->encoding);
/*
* Write the string and return the number of bytes written...
*/
if (bytes > 0)
return ((int)fwrite(output, 1, bytes, fp));
else
return (bytes);
}
/*
* '_cupsLangPrintf()' - Print a formatted message string to a file.
*/
int /* O - Number of bytes written */
_cupsLangPrintf(FILE *fp, /* I - File to write to */
const char *message, /* I - Message string to use */
...) /* I - Additional arguments as needed */
{
int bytes; /* Number of bytes formatted */
char buffer[2048], /* Message buffer */
output[8192]; /* Output buffer */
va_list ap; /* Pointer to additional arguments */
_cups_globals_t *cg; /* Global data */
/*
* Range check...
*/
if (!fp || !message)
return (-1);
cg = _cupsGlobals();
if (!cg->lang_default)
cg->lang_default = cupsLangDefault();
/*
* Format the string...
*/
va_start(ap, message);
vsnprintf(buffer, sizeof(buffer) - 1,
_cupsLangString(cg->lang_default, message), ap);
va_end(ap);
strlcat(buffer, "\n", sizeof(buffer));
/*
* Transcode to the destination charset...
*/
bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output),
cg->lang_default->encoding);
/*
* Write the string and return the number of bytes written...
*/
if (bytes > 0)
return ((int)fwrite(output, 1, bytes, fp));
else
return (bytes);
}
/*
* '_cupsLangPuts()' - Print a static message string to a file.
*/
int /* O - Number of bytes written */
_cupsLangPuts(FILE *fp, /* I - File to write to */
const char *message) /* I - Message string to use */
{
int bytes; /* Number of bytes formatted */
char output[8192]; /* Message buffer */
_cups_globals_t *cg; /* Global data */
/*
* Range check...
*/
if (!fp || !message)
return (-1);
cg = _cupsGlobals();
if (!cg->lang_default)
cg->lang_default = cupsLangDefault();
/*
* Transcode to the destination charset...
*/
bytes = cupsUTF8ToCharset(output,
(cups_utf8_t *)_cupsLangString(cg->lang_default,
message),
sizeof(output) - 4, cg->lang_default->encoding);
bytes += cupsUTF8ToCharset(output + bytes, (cups_utf8_t *)"\n",
sizeof(output) - bytes,
cg->lang_default->encoding);
/*
* Write the string and return the number of bytes written...
*/
if (bytes > 0)
return ((int)fwrite(output, 1, bytes, fp));
else
return (bytes);
}
/*
* '_cupsSetLocale()' - Set the current locale and transcode the command-line.
*/
void
_cupsSetLocale(char *argv[]) /* IO - Command-line arguments */
{
int i; /* Looping var */
char buffer[8192]; /* Command-line argument buffer */
_cups_globals_t *cg; /* Global data */
#ifdef LC_TIME
const char *lc_time; /* Current LC_TIME value */
char new_lc_time[255], /* New LC_TIME value */
*charset; /* Pointer to character set */
#endif /* LC_TIME */
/*
* Set the locale so that times, etc. are displayed properly.
*
* Unfortunately, while we need the localized time value, we *don't*
* want to use the localized charset for the time value, so we need
* to set LC_TIME to the locale name with .UTF-8 on the end (if
* the locale includes a character set specifier...)
*/
setlocale(LC_ALL, "");
#ifdef LC_TIME
if ((lc_time = setlocale(LC_TIME, NULL)) == NULL)
lc_time = setlocale(LC_ALL, NULL);
if (lc_time)
{
strlcpy(new_lc_time, lc_time, sizeof(new_lc_time));
if ((charset = strchr(new_lc_time, '.')) == NULL)
charset = new_lc_time + strlen(new_lc_time);
strlcpy(charset, ".UTF-8", sizeof(new_lc_time) - (charset - new_lc_time));
}
else
strcpy(new_lc_time, "C");
setlocale(LC_TIME, new_lc_time);
#endif /* LC_TIME */
/*
* Initialize the default language info...
*/
cg = _cupsGlobals();
if (!cg->lang_default)
cg->lang_default = cupsLangDefault();
/*
* Transcode the command-line arguments from the locale charset to
* UTF-8...
*/
if (cg->lang_default->encoding != CUPS_US_ASCII &&
cg->lang_default->encoding != CUPS_UTF8)
{
for (i = 1; argv[i]; i ++)
{
/*
* Try converting from the locale charset to UTF-8...
*/
if (cupsCharsetToUTF8((cups_utf8_t *)buffer, argv[i], sizeof(buffer),
cg->lang_default->encoding) < 0)
continue;
/*
* Save the new string if it differs from the original...
*/
if (strcmp(buffer, argv[i]))
argv[i] = strdup(buffer);
}
}
}
/*
* End of "$Id: langprintf.c 7802 2008-07-28 18:50:45Z mike $".
*/

86
cups/language-private.h Normal file
View File

@@ -0,0 +1,86 @@
/*
* "$Id$"
*
* Private localization support for CUPS.
*
* 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*/
#ifndef _CUPS_LANGUAGE_PRIVATE_H_
# define _CUPS_LANGUAGE_PRIVATE_H_
/*
* Include necessary headers...
*/
# include <stdio.h>
# include <cups/transcode.h>
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/*
* Macro for localized text...
*/
# define _(x) x
/*
* Types...
*/
typedef struct _cups_message_s /**** Message catalog entry ****/
{
char *id, /* Original string */
*str; /* Localized string */
} _cups_message_t;
/*
* Prototypes...
*/
# ifdef __APPLE__
extern const char *_cupsAppleLanguage(const char *locale, char *language,
size_t langsize);
# 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[]);
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_LANGUAGE_PRIVATE_H_ */
/*
* End of "$Id$".
*/

1567
cups/language.c Normal file

File diff suppressed because it is too large Load Diff

115
cups/language.h Normal file
View File

@@ -0,0 +1,115 @@
/*
* "$Id: language.h 6649 2007-07-11 21:46:42Z mike $"
*
* Multi-language support for CUPS.
*
* 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*/
#ifndef _CUPS_LANGUAGE_H_
# define _CUPS_LANGUAGE_H_
/*
* Include necessary headers...
*/
# include <locale.h>
# include "array.h"
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/*
* Types...
*/
typedef enum cups_encoding_e /**** Language Encodings ****/
{
CUPS_AUTO_ENCODING = -1, /* Auto-detect the encoding @private@ */
CUPS_US_ASCII, /* US ASCII */
CUPS_ISO8859_1, /* ISO-8859-1 */
CUPS_ISO8859_2, /* ISO-8859-2 */
CUPS_ISO8859_3, /* ISO-8859-3 */
CUPS_ISO8859_4, /* ISO-8859-4 */
CUPS_ISO8859_5, /* ISO-8859-5 */
CUPS_ISO8859_6, /* ISO-8859-6 */
CUPS_ISO8859_7, /* ISO-8859-7 */
CUPS_ISO8859_8, /* ISO-8859-8 */
CUPS_ISO8859_9, /* ISO-8859-9 */
CUPS_ISO8859_10, /* ISO-8859-10 */
CUPS_UTF8, /* UTF-8 */
CUPS_ISO8859_13, /* ISO-8859-13 */
CUPS_ISO8859_14, /* ISO-8859-14 */
CUPS_ISO8859_15, /* ISO-8859-15 */
CUPS_WINDOWS_874, /* CP-874 */
CUPS_WINDOWS_1250, /* CP-1250 */
CUPS_WINDOWS_1251, /* CP-1251 */
CUPS_WINDOWS_1252, /* CP-1252 */
CUPS_WINDOWS_1253, /* CP-1253 */
CUPS_WINDOWS_1254, /* CP-1254 */
CUPS_WINDOWS_1255, /* CP-1255 */
CUPS_WINDOWS_1256, /* CP-1256 */
CUPS_WINDOWS_1257, /* CP-1257 */
CUPS_WINDOWS_1258, /* CP-1258 */
CUPS_KOI8_R, /* KOI-8-R */
CUPS_KOI8_U, /* KOI-8-U */
CUPS_ISO8859_11, /* ISO-8859-11 */
CUPS_ISO8859_16, /* ISO-8859-16 */
CUPS_MAC_ROMAN, /* MacRoman */
CUPS_ENCODING_SBCS_END = 63, /* End of single-byte encodings @private@ */
CUPS_WINDOWS_932, /* Japanese JIS X0208-1990 */
CUPS_WINDOWS_936, /* Simplified Chinese GB 2312-80 */
CUPS_WINDOWS_949, /* Korean KS C5601-1992 */
CUPS_WINDOWS_950, /* Traditional Chinese Big Five */
CUPS_WINDOWS_1361, /* Korean Johab */
CUPS_ENCODING_DBCS_END = 127, /* End of double-byte encodings @private@ */
CUPS_EUC_CN, /* EUC Simplified Chinese */
CUPS_EUC_JP, /* EUC Japanese */
CUPS_EUC_KR, /* EUC Korean */
CUPS_EUC_TW, /* EUC Traditional Chinese */
CUPS_JIS_X0213, /* JIS X0213 aka Shift JIS */
CUPS_ENCODING_VBCS_END = 191 /* End of variable-length encodings @private@ */
} cups_encoding_t;
typedef struct cups_lang_s /**** Language Cache Structure ****/
{
struct cups_lang_s *next; /* Next language in cache */
int used; /* Number of times this entry has been used. */
cups_encoding_t encoding; /* Text encoding */
char language[16]; /* Language/locale name */
cups_array_t *strings; /* Message strings @private@ */
} cups_lang_t;
/*
* 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);
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_LANGUAGE_H_ */
/*
* End of "$Id: language.h 6649 2007-07-11 21:46:42Z mike $".
*/

382
cups/libcups2.def Normal file
View File

@@ -0,0 +1,382 @@
LIBRARY libcups2
VERSION 2.9
EXPORTS
_cupsBufferGet
_cupsBufferRelease
_cupsGet1284Values
_cupsGetDests
_cupsGetPassword
_cupsGlobals
_cupsLangPrintError
_cupsLangPrintf
_cupsLangPuts
_cupsLangString
_cupsMD5Append
_cupsMD5Finish
_cupsMD5Init
_cupsMessageFree
_cupsMessageLoad
_cupsMessageLookup
_cupsMutexLock
_cupsMutexUnlock
_cupsNextDelay
_cupsSetError
_cupsSetLocale
_cupsStrAlloc
_cupsStrFlush
_cupsStrFormatd
_cupsStrFree
_cupsStrRetain
_cupsStrScand
_cupsStrStatistics
_cups_strcasecmp
_cups_strncasecmp
_cups_strcpy
_cups_strlcat
_cups_strlcpy
_httpAddrPort
_httpAddrSetPort
_httpAssembleUUID
_httpCreate
_httpEncodeURI
_httpPeek
_httpResolveURI
_httpWait
_ippFindOption
_ppdCacheCreateWithFile
_ppdCacheCreateWithPPD
_ppdCacheDestroy
_ppdCacheGetBin
_ppdCacheGetInputSlot
_ppdCacheGetMediaType
_ppdCacheGetOutputBin
_ppdCacheGetPageSize
_ppdCacheGetSize
_ppdCacheGetSource
_ppdCacheGetType
_ppdCacheWriteFile
_ppdFreeLanguages
_ppdGetEncoding
_ppdGetLanguages
_ppdHashName
_ppdLocalizedAttr
_ppdNormalizeMakeAndModel
_ppdOpen
_ppdOpenFile
_ppdParseOptions
_pwgGenerateSize
_pwgInitSize
_pwgMediaForLegacy
_pwgMediaForPPD
_pwgMediaForPWG
_pwgMediaForSize
_pwgMediaTypeForType
_pwgPageSizeForMedia
cupsAddDest
cupsAddOption
cupsAdminCreateWindowsPPD
cupsAdminExportSamba
cupsArrayAdd
cupsArrayClear
cupsArrayCount
cupsArrayCurrent
cupsArrayDelete
cupsArrayDup
cupsArrayFind
cupsArrayFirst
cupsArrayGetIndex
cupsArrayGetInsert
cupsArrayIndex
cupsArrayInsert
cupsArrayLast
cupsArrayNew
cupsArrayNew2
cupsArrayNew3
cupsArrayNext
cupsArrayPrev
cupsArrayRemove
cupsArrayRestore
cupsArraySave
cupsArrayUserData
cupsCancelJob
cupsCharsetToUTF8
cupsDirClose
cupsDirOpen
cupsDirRead
cupsDirRewind
cupsDoAuthentication
cupsDoFileRequest
cupsDoIORequest
cupsDoRequest
cupsEncodeOptions
cupsEncodeOptions2
cupsEncryption
cupsFileClose
cupsFileCompression
cupsFileEOF
cupsFileFind
cupsFileFlush
cupsFileGetChar
cupsFileGetConf
cupsFileGetLine
cupsFileGets
cupsFileLock
cupsFileNumber
cupsFileOpen
cupsFileOpenFd
cupsFilePeekChar
cupsFilePrintf
cupsFilePutChar
cupsFilePuts
cupsFileRead
cupsFileRewind
cupsFileSeek
cupsFileStderr
cupsFileStdin
cupsFileStdout
cupsFileTell
cupsFileUnlock
cupsFileWrite
cupsFreeDests
cupsFreeJobs
cupsFreeOptions
cupsGetClasses
cupsGetDefault
cupsGetDefault2
cupsGetDest
cupsGetDests
cupsGetDests2
cupsGetFd
cupsGetFile
cupsGetJobs
cupsGetJobs2
cupsGetOption
cupsGetPPD
cupsGetPPD2
cupsGetPassword
cupsGetPrinters
cupsGetResponse
cupsLangDefault
cupsLangEncoding
cupsLangFlush
cupsLangFree
cupsLangGet
cupsLastError
cupsLastErrorString
cupsMarkOptions
cupsNotifySubject
cupsNotifyText
cupsParseOptions
cupsPrintFile
cupsPrintFile2
cupsPrintFiles
cupsPrintFiles2
cupsPutFd
cupsPutFile
cupsRemoveOption
cupsResolveConflicts
cupsSendRequest
cupsServer
cupsSetClientCertCB
cupsSetCredentials
cupsSetDests
cupsSetDests2
cupsSetEncryption
cupsSetPasswordCB
cupsSetServer
cupsSetServerCertCB
cupsSetUser
cupsTempFd
cupsTempFile
cupsTempFile2
cupsUTF32ToUTF8
cupsUTF8ToCharset
cupsUTF8ToUTF32
cupsUser
cupsWriteRequestData
httpAddCredential
httpAddrAny
httpAddrConnect
httpAddrEqual
httpAddrFreeList
httpAddrGetList
httpAddrLength
httpAddrLocalhost
httpAddrLookup
httpAddrString
httpAssembleURI
httpAssembleURIf
httpBlocking
httpCheck
httpClearCookie
httpClearFields
httpClose
httpConnect
httpConnectEncrypt
httpCopyCredentials
httpDecode64
httpDecode64_2
httpDelete
httpEncode64
httpEncode64_2
httpEncryption
httpError
httpFlush
httpFlushWrite
httpFreeCredentials
httpGet
httpGetBlocking
httpGetCookie
httpGetDateString
httpGetDateString2
httpGetDateTime
httpGetFd
httpGetField
httpGetHostByName
httpGetHostname
httpGetLength
httpGetLength2
httpGetStatus
httpGetSubField
httpGetSubField2
httpGets
httpHead
httpInitialize
httpMD5
httpMD5Final
httpMD5String
httpOptions
httpPost
httpPrintf
httpPut
httpRead
httpRead2
httpReconnect
httpSeparate
httpSeparate2
httpSeparateURI
httpSetCookie
httpSetCredentials
httpSetExpect
httpSetField
httpSetLength
httpSetTimeout
httpStatus
httpTrace
httpUpdate
httpWait
httpWrite
httpWrite2
ippAddBoolean
ippAddBooleans
ippAddCollection
ippAddCollections
ippAddDate
ippAddInteger
ippAddIntegers
ippAddOctetString
ippAddOutOfBand
ippAddRange
ippAddRanges
ippAddResolution
ippAddResolutions
ippAddSeparator
ippAddString
ippAddStrings
ippAttributeString
ippCopyAttribute
ippCopyAttributes
ippDateToTime
ippDelete
ippDeleteAttribute
ippDeleteValues
ippEnumString
ippEnumValue
ippErrorString
ippErrorValue
ippFindAttribute
ippFindNextAttribute
ippFirstAttribute
ippGetBoolean
ippGetCollection
ippGetCount
ippGetDate
ippGetGroupTag
ippGetInteger
ippGetName
ippGetOperation
ippGetRange
ippGetRequestId
ippGetResolution
ippGetState
ippGetStatusCode
ippGetString
ippGetValueTag
ippGetVersion
ippLength
ippNew
ippNewRequest
ippNextAttribute
ippOpString
ippOpValue
ippPort
ippRead
ippReadFile
ippReadIO
ippSetPort
ippSetBoolean
ippSetCollection
ippSetDate
ippSetGroupTag
ippSetInteger
ippSetName
ippSetOperation
ippSetRange
ippSetRequestId
ippSetResolution
ippSetState
ippSetStatusCode
ippSetString
ippSetValueTag
ippSetVersion
ippTagString
ippTagValue
ippTimeToDate
ippWrite
ippWriteFile
ippWriteIO
ppdClose
ppdCollect
ppdCollect2
ppdConflicts
ppdEmit
ppdEmitAfterOrder
ppdEmitFd
ppdEmitJCL
ppdEmitJCLEnd
ppdEmitString
ppdErrorString
ppdFindAttr
ppdFindChoice
ppdFindCustomOption
ppdFindCustomParam
ppdFindMarkedChoice
ppdFindNextAttr
ppdFindOption
ppdFirstCustomParam
ppdFirstOption
ppdIsMarked
ppdLastError
ppdLocalize
ppdMarkDefaults
ppdMarkOption
ppdNextCustomParam
ppdNextOption
ppdOpen
ppdOpen2
ppdOpenFd
ppdOpenFile
ppdPageLength
ppdPageSize
ppdPageWidth
ppdSetConformance

75
cups/libcups2.rc Normal file
View File

@@ -0,0 +1,75 @@
// Microsoft Visual C++ generated resource script.
//
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
#include "WinVersRes.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION MASTER_PROD_VERS
PRODUCTVERSION MASTER_PROD_VERS
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", MASTER_COMPANY_NAME
VALUE "FileDescription", "CUPS Library"
VALUE "FileVersion", MASTER_PROD_VERS_STR
VALUE "InternalName", "libcups2.dll"
VALUE "LegalCopyright", MASTER_LEGAL_COPYRIGHT
VALUE "OriginalFilename", "libcups2.dll"
VALUE "ProductName", MASTER_PROD_NAME
VALUE "ProductVersion", MASTER_PROD_VERS_STR
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

85
cups/libcups_s.exp Normal file
View File

@@ -0,0 +1,85 @@
_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

779
cups/localize.c Normal file
View File

@@ -0,0 +1,779 @@
/*
* "$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 $".
*/

1101
cups/mark.c Normal file

File diff suppressed because it is too large Load Diff

79
cups/md5-private.h Normal file
View File

@@ -0,0 +1,79 @@
/*
* "$Id$"
*
* Private MD5 definitions for CUPS.
*
* Copyright 2007-2010 by Apple Inc.
* Copyright 2005 by Easy Software Products
*
* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* 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.
*
* L. Peter Deutsch
* ghost@aladdin.com
*/
/*
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321.
It is derived directly from the text of the RFC and not from the
reference implementation.
The original and principal author of md5.h is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
added conditionalization for C++ compilation from Martin
Purschke <purschke@bnl.gov>.
1999-05-03 lpd Original version.
*/
#ifndef _CUPS_MD5_PRIVATE_H_
# define _CUPS_MD5_PRIVATE_H_
/* Define the state of the MD5 Algorithm. */
typedef struct _cups_md5_state_s {
unsigned int count[2]; /* message length in bits, lsw first */
unsigned int abcd[4]; /* digest buffer */
unsigned char buf[64]; /* accumulate block */
} _cups_md5_state_t;
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/* Initialize the algorithm. */
void _cupsMD5Init(_cups_md5_state_t *pms);
/* Append a string to the message. */
void _cupsMD5Append(_cups_md5_state_t *pms, const unsigned char *data, int nbytes);
/* Finish the message and return the digest. */
void _cupsMD5Finish(_cups_md5_state_t *pms, unsigned char digest[16]);
# ifdef __cplusplus
} /* end extern "C" */
# endif /* __cplusplus */
#endif /* !_CUPS_MD5_PRIVATE_H_ */
/*
* End of "$Id$".
*/

346
cups/md5.c Normal file
View File

@@ -0,0 +1,346 @@
/*
* "$Id: md5.c 9042 2010-03-24 00:45:34Z mike $"
*
* Private MD5 implementation for CUPS.
*
* Copyright 2007-2010 by Apple Inc.
* Copyright 2005 by Easy Software Products
*
* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* 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.
*
* L. Peter Deutsch
* ghost@aladdin.com
*/
/*
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321.
It is derived directly from the text of the RFC and not from the
reference implementation.
The original and principal author of md5.c is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
1999-05-03 lpd Original version.
*/
#include "md5-private.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
static void
_cups_md5_process(_cups_md5_state_t *pms, const unsigned char *data /*[64]*/)
{
unsigned int
a = pms->abcd[0], b = pms->abcd[1],
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
/*
* On big-endian machines, we must arrange the bytes in the right
* order. (This also works on machines of unknown byte order.)
*/
unsigned int X[16];
const unsigned char *xp = data;
int i;
for (i = 0; i < 16; ++i, xp += 4)
X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
#else /* !ARCH_IS_BIG_ENDIAN */
/*
* On little-endian machines, we can process properly aligned data
* without copying it.
*/
unsigned int xbuf[16];
const unsigned int *X;
if (!((data - (const unsigned char *)0) & 3)) {
/* data are properly aligned */
X = (const unsigned int *)data;
} else {
/* not aligned */
memcpy(xbuf, data, 64);
X = xbuf;
}
#endif
#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)\
t = a + F(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 7, T1);
SET(d, a, b, c, 1, 12, T2);
SET(c, d, a, b, 2, 17, T3);
SET(b, c, d, a, 3, 22, T4);
SET(a, b, c, d, 4, 7, T5);
SET(d, a, b, c, 5, 12, T6);
SET(c, d, a, b, 6, 17, T7);
SET(b, c, d, a, 7, 22, T8);
SET(a, b, c, d, 8, 7, T9);
SET(d, a, b, c, 9, 12, T10);
SET(c, d, a, b, 10, 17, T11);
SET(b, c, d, a, 11, 22, T12);
SET(a, b, c, d, 12, 7, T13);
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
/* 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)\
t = a + G(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 1, 5, T17);
SET(d, a, b, c, 6, 9, T18);
SET(c, d, a, b, 11, 14, T19);
SET(b, c, d, a, 0, 20, T20);
SET(a, b, c, d, 5, 5, T21);
SET(d, a, b, c, 10, 9, T22);
SET(c, d, a, b, 15, 14, T23);
SET(b, c, d, a, 4, 20, T24);
SET(a, b, c, d, 9, 5, T25);
SET(d, a, b, c, 14, 9, T26);
SET(c, d, a, b, 3, 14, T27);
SET(b, c, d, a, 8, 20, T28);
SET(a, b, c, d, 13, 5, T29);
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
/* 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)\
t = a + H(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 5, 4, T33);
SET(d, a, b, c, 8, 11, T34);
SET(c, d, a, b, 11, 16, T35);
SET(b, c, d, a, 14, 23, T36);
SET(a, b, c, d, 1, 4, T37);
SET(d, a, b, c, 4, 11, T38);
SET(c, d, a, b, 7, 16, T39);
SET(b, c, d, a, 10, 23, T40);
SET(a, b, c, d, 13, 4, T41);
SET(d, a, b, c, 0, 11, T42);
SET(c, d, a, b, 3, 16, T43);
SET(b, c, d, a, 6, 23, T44);
SET(a, b, c, d, 9, 4, T45);
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
/* 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)\
t = a + I(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 6, T49);
SET(d, a, b, c, 7, 10, T50);
SET(c, d, a, b, 14, 15, T51);
SET(b, c, d, a, 5, 21, T52);
SET(a, b, c, d, 12, 6, T53);
SET(d, a, b, c, 3, 10, T54);
SET(c, d, a, b, 10, 15, T55);
SET(b, c, d, a, 1, 21, T56);
SET(a, b, c, d, 8, 6, T57);
SET(d, a, b, c, 15, 10, T58);
SET(c, d, a, b, 6, 15, T59);
SET(b, c, d, a, 13, 21, T60);
SET(a, b, c, d, 4, 6, T61);
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
/* Then perform the following additions. (That is increment each
of the four registers by the value it had before this block
was started.) */
pms->abcd[0] += a;
pms->abcd[1] += b;
pms->abcd[2] += c;
pms->abcd[3] += d;
}
void
_cupsMD5Init(_cups_md5_state_t *pms)
{
pms->count[0] = pms->count[1] = 0;
pms->abcd[0] = 0x67452301;
pms->abcd[1] = 0xefcdab89;
pms->abcd[2] = 0x98badcfe;
pms->abcd[3] = 0x10325476;
}
void
_cupsMD5Append(_cups_md5_state_t *pms, const unsigned char *data, int nbytes)
{
const unsigned char *p = data;
int left = nbytes;
int offset = (pms->count[0] >> 3) & 63;
unsigned int nbits = (unsigned int)(nbytes << 3);
if (nbytes <= 0)
return;
/* Update the message length. */
pms->count[1] += nbytes >> 29;
pms->count[0] += nbits;
if (pms->count[0] < nbits)
pms->count[1]++;
/* Process an initial partial block. */
if (offset) {
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
memcpy(pms->buf + offset, p, copy);
if (offset + copy < 64)
return;
p += copy;
left -= copy;
_cups_md5_process(pms, pms->buf);
}
/* Process full blocks. */
for (; left >= 64; p += 64, left -= 64)
_cups_md5_process(pms, p);
/* Process a final partial block. */
if (left)
memcpy(pms->buf, p, left);
}
void
_cupsMD5Finish(_cups_md5_state_t *pms, unsigned char digest[16])
{
static const unsigned char pad[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
unsigned char data[8];
int i;
/* Save the length before padding. */
for (i = 0; i < 8; ++i)
data[i] = (unsigned char)(pms->count[i >> 2] >> ((i & 3) << 3));
/* Pad to 56 bytes mod 64. */
_cupsMD5Append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
/* Append the length. */
_cupsMD5Append(pms, data, 8);
for (i = 0; i < 16; ++i)
digest[i] = (unsigned char)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}
/*
* End of "$Id: md5.c 9042 2010-03-24 00:45:34Z mike $".
*/

142
cups/md5passwd.c Normal file
View File

@@ -0,0 +1,142 @@
/*
* "$Id: md5passwd.c 6649 2007-07-11 21:46:42Z mike $"
*
* MD5 password support for CUPS.
*
* Copyright 2007-2010 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*
* Contents:
*
* httpMD5() - Compute the MD5 sum of the username:group:password.
* httpMD5Nonce() - Combine the MD5 sum of the username, group, and password
* with the server-supplied nonce value.
* httpMD5String() - Convert an MD5 sum to a character string.
*/
/*
* Include necessary headers...
*/
#include "http-private.h"
#include "string-private.h"
/*
* 'httpMD5()' - Compute the MD5 sum of the username:group:password.
*/
char * /* O - MD5 sum */
httpMD5(const char *username, /* I - User name */
const char *realm, /* I - Realm 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 */
/*
* Compute the MD5 sum of the user name, group name, and password.
*/
snprintf(line, sizeof(line), "%s:%s:%s", username, realm, passwd);
_cupsMD5Init(&state);
_cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line));
_cupsMD5Finish(&state, sum);
/*
* Return the sum...
*/
return (httpMD5String(sum, md5));
}
/*
* 'httpMD5Final()' - Combine the MD5 sum of the username, group, and password
* with the server-supplied nonce value, method, and
* request-uri.
*/
char * /* O - New sum */
httpMD5Final(const char *nonce, /* I - Server nonce value */
const char *method, /* I - METHOD (GET, POST, etc.) */
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 */
/*
* First compute the MD5 sum of the method and resource...
*/
snprintf(line, sizeof(line), "%s:%s", method, resource);
_cupsMD5Init(&state);
_cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line));
_cupsMD5Finish(&state, sum);
httpMD5String(sum, a2);
/*
* Then combine A1 (MD5 of username, realm, and password) with the nonce
* and A2 (method + resource) values to get the final MD5 sum for the
* request...
*/
snprintf(line, sizeof(line), "%s:%s:%s", md5, nonce, a2);
_cupsMD5Init(&state);
_cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line));
_cupsMD5Finish(&state, sum);
return (httpMD5String(sum, md5));
}
/*
* 'httpMD5String()' - Convert an MD5 sum to a character string.
*/
char * /* O - MD5 sum in hex */
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);
}
/*
* End of "$Id: md5passwd.c 6649 2007-07-11 21:46:42Z mike $".
*/

202
cups/notify.c Normal file
View File

@@ -0,0 +1,202 @@
/*
* "$Id: notify.c 7337 2008-02-22 04:44:04Z mike $"
*
* Notification routines for CUPS.
*
* Copyright 2007-2012 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*
* Contents:
*
* cupsNotifySubject() - Return the subject for the given notification
* message.
* cupsNotifyText() - Return the text for the given notification message.
*/
/*
* Include necessary headers...
*/
#include "cups-private.h"
/*
* 'cupsNotifySubject()' - Return the subject for the given notification message.
*
* The returned string must be freed by the caller using @code free@.
*
* @since CUPS 1.2/OS X 10.5@
*/
char * /* O - Subject string or @code NULL@ */
cupsNotifySubject(cups_lang_t *lang, /* I - Language data */
ipp_t *event) /* I - Event data */
{
char buffer[1024]; /* Subject buffer */
const char *prefix, /* Prefix on subject */
*state; /* Printer/job state string */
ipp_attribute_t *job_id, /* notify-job-id */
*job_name, /* job-name */
*job_state, /* job-state */
*printer_name, /* printer-name */
*printer_state, /* printer-state */
*printer_uri, /* notify-printer-uri */
*subscribed; /* notify-subscribed-event */
/*
* Range check input...
*/
if (!event || !lang)
return (NULL);
/*
* Get the required attributes...
*/
job_id = ippFindAttribute(event, "notify-job-id", IPP_TAG_INTEGER);
job_name = ippFindAttribute(event, "job-name", IPP_TAG_NAME);
job_state = ippFindAttribute(event, "job-state", IPP_TAG_ENUM);
printer_name = ippFindAttribute(event, "printer-name", IPP_TAG_NAME);
printer_state = ippFindAttribute(event, "printer-state", IPP_TAG_ENUM);
printer_uri = ippFindAttribute(event, "notify-printer-uri", IPP_TAG_URI);
subscribed = ippFindAttribute(event, "notify-subscribed-event",
IPP_TAG_KEYWORD);
if (job_id && printer_name && printer_uri && job_state)
{
/*
* Job event...
*/
prefix = _cupsLangString(lang, _("Print Job:"));
switch (job_state->values[0].integer)
{
case IPP_JOB_PENDING :
state = _cupsLangString(lang, _("pending"));
break;
case IPP_JOB_HELD :
state = _cupsLangString(lang, _("held"));
break;
case IPP_JOB_PROCESSING :
state = _cupsLangString(lang, _("processing"));
break;
case IPP_JOB_STOPPED :
state = _cupsLangString(lang, _("stopped"));
break;
case IPP_JOB_CANCELED :
state = _cupsLangString(lang, _("canceled"));
break;
case IPP_JOB_ABORTED :
state = _cupsLangString(lang, _("aborted"));
break;
case IPP_JOB_COMPLETED :
state = _cupsLangString(lang, _("completed"));
break;
default :
state = _cupsLangString(lang, _("unknown"));
break;
}
snprintf(buffer, sizeof(buffer), "%s %s-%d (%s) %s",
prefix,
printer_name->values[0].string.text,
job_id->values[0].integer,
job_name ? job_name->values[0].string.text :
_cupsLangString(lang, _("untitled")),
state);
}
else if (printer_uri && printer_name && printer_state)
{
/*
* Printer event...
*/
prefix = _cupsLangString(lang, _("Printer:"));
switch (printer_state->values[0].integer)
{
case IPP_PRINTER_IDLE :
state = _cupsLangString(lang, _("idle"));
break;
case IPP_PRINTER_PROCESSING :
state = _cupsLangString(lang, _("processing"));
break;
case IPP_PRINTER_STOPPED :
state = _cupsLangString(lang, _("stopped"));
break;
default :
state = _cupsLangString(lang, _("unknown"));
break;
}
snprintf(buffer, sizeof(buffer), "%s %s %s",
prefix,
printer_name->values[0].string.text,
state);
}
else if (subscribed)
strlcpy(buffer, subscribed->values[0].string.text, sizeof(buffer));
else
return (NULL);
/*
* Duplicate and return the subject string...
*/
return (strdup(buffer));
}
/*
* 'cupsNotifyText()' - Return the text for the given notification message.
*
* The returned string must be freed by the caller using @code free@.
*
* @since CUPS 1.2/OS X 10.5@
*/
char * /* O - Message text or @code NULL@ */
cupsNotifyText(cups_lang_t *lang, /* I - Language data */
ipp_t *event) /* I - Event data */
{
ipp_attribute_t *notify_text; /* notify-text */
/*
* Range check input...
*/
if (!event || !lang)
return (NULL);
/*
* Get the notify-text attribute from the server...
*/
if ((notify_text = ippFindAttribute(event, "notify-text",
IPP_TAG_TEXT)) == NULL)
return (NULL);
/*
* Return a copy...
*/
return (strdup(notify_text->values[0].string.text));
}
/*
* End of "$Id: notify.c 7337 2008-02-22 04:44:04Z mike $".
*/

711
cups/options.c Normal file
View File

@@ -0,0 +1,711 @@
/*
* "$Id: options.c 8181 2008-12-10 17:29:57Z mike $"
*
* Option routines for CUPS.
*
* Copyright 2007-2012 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*
* Contents:
*
* cupsAddOption() - Add an option to an option array.
* cupsFreeOptions() - Free all memory used by options.
* cupsGetOption() - Get an option value.
* cupsParseOptions() - Parse options from a command-line argument.
* cupsRemoveOption() - Remove an option from an option array.
* _cupsGet1284Values() - Get 1284 device ID keys and values.
* cups_compare_options() - Compare two options.
* cups_find_option() - Find an option using a binary search.
*/
/*
* Include necessary headers...
*/
#include "cups-private.h"
/*
* Local functions...
*/
static int cups_compare_options(cups_option_t *a, cups_option_t *b);
static int cups_find_option(const char *name, int num_options,
cups_option_t *option, int prev, int *rdiff);
/*
* 'cupsAddOption()' - Add an option to an option array.
*
* New option arrays can be initialized simply by passing 0 for the
* "num_options" parameter.
*/
int /* O - Number of options */
cupsAddOption(const char *name, /* I - Name of option */
const char *value, /* I - Value of option */
int num_options,/* I - Number of options */
cups_option_t **options) /* IO - Pointer to options */
{
cups_option_t *temp; /* Pointer to new option */
int insert, /* Insertion point */
diff; /* Result of search */
DEBUG_printf(("2cupsAddOption(name=\"%s\", value=\"%s\", num_options=%d, "
"options=%p)", name, value, num_options, options));
if (!name || !name[0] || !value || !options || num_options < 0)
{
DEBUG_printf(("3cupsAddOption: Returning %d", num_options));
return (num_options);
}
/*
* Look for an existing option with the same name...
*/
if (num_options == 0)
{
insert = 0;
diff = 1;
}
else
{
insert = cups_find_option(name, num_options, *options, num_options - 1,
&diff);
if (diff > 0)
insert ++;
}
if (diff)
{
/*
* No matching option name...
*/
DEBUG_printf(("4cupsAddOption: New option inserted at index %d...",
insert));
if (num_options == 0)
temp = (cups_option_t *)malloc(sizeof(cups_option_t));
else
temp = (cups_option_t *)realloc(*options, sizeof(cups_option_t) *
(num_options + 1));
if (temp == NULL)
{
DEBUG_puts("3cupsAddOption: Unable to expand option array, returning 0");
return (0);
}
*options = temp;
if (insert < num_options)
{
DEBUG_printf(("4cupsAddOption: Shifting %d options...",
(int)(num_options - insert)));
memmove(temp + insert + 1, temp + insert,
(num_options - insert) * sizeof(cups_option_t));
}
temp += insert;
temp->name = _cupsStrAlloc(name);
num_options ++;
}
else
{
/*
* Match found; free the old value...
*/
DEBUG_printf(("4cupsAddOption: Option already exists at index %d...",
insert));
temp = *options + insert;
_cupsStrFree(temp->value);
}
temp->value = _cupsStrAlloc(value);
DEBUG_printf(("3cupsAddOption: Returning %d", num_options));
return (num_options);
}
/*
* 'cupsFreeOptions()' - Free all memory used by options.
*/
void
cupsFreeOptions(
int num_options, /* I - Number of options */
cups_option_t *options) /* I - Pointer to options */
{
int i; /* Looping var */
DEBUG_printf(("cupsFreeOptions(num_options=%d, options=%p)", num_options,
options));
if (num_options <= 0 || !options)
return;
for (i = 0; i < num_options; i ++)
{
_cupsStrFree(options[i].name);
_cupsStrFree(options[i].value);
}
free(options);
}
/*
* 'cupsGetOption()' - Get an option value.
*/
const char * /* O - Option value or @code NULL@ */
cupsGetOption(const char *name, /* I - Name of option */
int num_options,/* I - Number of options */
cups_option_t *options) /* I - Options */
{
int diff, /* Result of comparison */
match; /* Matching index */
DEBUG_printf(("2cupsGetOption(name=\"%s\", num_options=%d, options=%p)",
name, num_options, options));
if (!name || num_options <= 0 || !options)
{
DEBUG_puts("3cupsGetOption: Returning NULL");
return (NULL);
}
match = cups_find_option(name, num_options, options, -1, &diff);
if (!diff)
{
DEBUG_printf(("3cupsGetOption: Returning \"%s\"", options[match].value));
return (options[match].value);
}
DEBUG_puts("3cupsGetOption: Returning NULL");
return (NULL);
}
/*
* 'cupsParseOptions()' - Parse options from a command-line argument.
*
* This function converts space-delimited name/value pairs according
* to the PAPI text option ABNF specification. Collection values
* ("name={a=... b=... c=...}") are stored with the curley brackets
* intact - use @code cupsParseOptions@ on the value to extract the
* collection attributes.
*/
int /* O - Number of options found */
cupsParseOptions(
const char *arg, /* I - Argument to parse */
int num_options, /* I - Number of options */
cups_option_t **options) /* O - Options found */
{
char *copyarg, /* Copy of input string */
*ptr, /* Pointer into string */
*name, /* Pointer to name */
*value, /* Pointer to value */
sep, /* Separator character */
quote; /* Quote character */
DEBUG_printf(("cupsParseOptions(arg=\"%s\", num_options=%d, options=%p)",
arg, num_options, options));
/*
* Range check input...
*/
if (!arg)
{
DEBUG_printf(("1cupsParseOptions: Returning %d", num_options));
return (num_options);
}
if (!options || num_options < 0)
{
DEBUG_puts("1cupsParseOptions: Returning 0");
return (0);
}
/*
* Make a copy of the argument string and then divide it up...
*/
if ((copyarg = strdup(arg)) == NULL)
{
DEBUG_puts("1cupsParseOptions: Unable to copy arg string");
DEBUG_printf(("1cupsParseOptions: Returning %d", num_options));
return (num_options);
}
if (*copyarg == '{')
{
/*
* Remove surrounding {} so we can parse "{name=value ... name=value}"...
*/
if ((ptr = copyarg + strlen(copyarg) - 1) > copyarg && *ptr == '}')
{
*ptr = '\0';
ptr = copyarg + 1;
}
else
ptr = copyarg;
}
else
ptr = copyarg;
/*
* Skip leading spaces...
*/
while (_cups_isspace(*ptr))
ptr ++;
/*
* Loop through the string...
*/
while (*ptr != '\0')
{
/*
* Get the name up to a SPACE, =, or end-of-string...
*/
name = ptr;
while (!strchr("\f\n\r\t\v =", *ptr) && *ptr)
ptr ++;
/*
* Avoid an empty name...
*/
if (ptr == name)
break;
/*
* Skip trailing spaces...
*/
while (_cups_isspace(*ptr))
*ptr++ = '\0';
if ((sep = *ptr) == '=')
*ptr++ = '\0';
DEBUG_printf(("2cupsParseOptions: name=\"%s\"", name));
if (sep != '=')
{
/*
* Boolean option...
*/
if (!_cups_strncasecmp(name, "no", 2))
num_options = cupsAddOption(name + 2, "false", num_options,
options);
else
num_options = cupsAddOption(name, "true", num_options, options);
continue;
}
/*
* Remove = and parse the value...
*/
value = ptr;
while (*ptr && !_cups_isspace(*ptr))
{
if (*ptr == ',')
ptr ++;
else if (*ptr == '\'' || *ptr == '\"')
{
/*
* Quoted string constant...
*/
quote = *ptr;
_cups_strcpy(ptr, ptr + 1);
while (*ptr != quote && *ptr)
{
if (*ptr == '\\' && ptr[1])
_cups_strcpy(ptr, ptr + 1);
ptr ++;
}
if (*ptr)
_cups_strcpy(ptr, ptr + 1);
}
else if (*ptr == '{')
{
/*
* Collection value...
*/
int depth;
for (depth = 0; *ptr; ptr ++)
{
if (*ptr == '{')
depth ++;
else if (*ptr == '}')
{
depth --;
if (!depth)
{
ptr ++;
break;
}
}
else if (*ptr == '\\' && ptr[1])
_cups_strcpy(ptr, ptr + 1);
}
}
else
{
/*
* Normal space-delimited string...
*/
while (*ptr && !_cups_isspace(*ptr))
{
if (*ptr == '\\' && ptr[1])
_cups_strcpy(ptr, ptr + 1);
ptr ++;
}
}
}
if (*ptr != '\0')
*ptr++ = '\0';
DEBUG_printf(("2cupsParseOptions: value=\"%s\"", value));
/*
* Skip trailing whitespace...
*/
while (_cups_isspace(*ptr))
ptr ++;
/*
* Add the string value...
*/
num_options = cupsAddOption(name, value, num_options, options);
}
/*
* Free the copy of the argument we made and return the number of options
* found.
*/
free(copyarg);
DEBUG_printf(("1cupsParseOptions: Returning %d", num_options));
return (num_options);
}
/*
* 'cupsRemoveOption()' - Remove an option from an option array.
*
* @since CUPS 1.2/OS X 10.5@
*/
int /* O - New number of options */
cupsRemoveOption(
const char *name, /* I - Option name */
int num_options, /* I - Current number of options */
cups_option_t **options) /* IO - Options */
{
int i; /* Looping var */
cups_option_t *option; /* Current option */
DEBUG_printf(("2cupsRemoveOption(name=\"%s\", num_options=%d, options=%p)",
name, num_options, options));
/*
* Range check input...
*/
if (!name || num_options < 1 || !options)
{
DEBUG_printf(("3cupsRemoveOption: Returning %d", num_options));
return (num_options);
}
/*
* Loop for the option...
*/
for (i = num_options, option = *options; i > 0; i --, option ++)
if (!_cups_strcasecmp(name, option->name))
break;
if (i)
{
/*
* Remove this option from the array...
*/
DEBUG_puts("4cupsRemoveOption: Found option, removing it...");
num_options --;
i --;
_cupsStrFree(option->name);
_cupsStrFree(option->value);
if (i > 0)
memmove(option, option + 1, i * sizeof(cups_option_t));
}
/*
* Return the new number of options...
*/
DEBUG_printf(("3cupsRemoveOption: Returning %d", num_options));
return (num_options);
}
/*
* '_cupsGet1284Values()' - Get 1284 device ID keys and values.
*
* The returned dictionary is a CUPS option array that can be queried with
* cupsGetOption and freed with cupsFreeOptions.
*/
int /* O - Number of key/value pairs */
_cupsGet1284Values(
const char *device_id, /* I - IEEE-1284 device ID string */
cups_option_t **values) /* O - Array of key/value pairs */
{
int num_values; /* Number of values */
char key[256], /* Key string */
value[256], /* Value string */
*ptr; /* Pointer into key/value */
/*
* Range check input...
*/
if (values)
*values = NULL;
if (!device_id || !values)
return (0);
/*
* Parse the 1284 device ID value into keys and values. The format is
* repeating sequences of:
*
* [whitespace]key:value[whitespace];
*/
num_values = 0;
while (*device_id)
{
while (_cups_isspace(*device_id))
device_id ++;
if (!*device_id)
break;
for (ptr = key; *device_id && *device_id != ':'; device_id ++)
if (ptr < (key + sizeof(key) - 1))
*ptr++ = *device_id;
if (!*device_id)
break;
while (ptr > key && _cups_isspace(ptr[-1]))
ptr --;
*ptr = '\0';
device_id ++;
while (_cups_isspace(*device_id))
device_id ++;
if (!*device_id)
break;
for (ptr = value; *device_id && *device_id != ';'; device_id ++)
if (ptr < (value + sizeof(value) - 1))
*ptr++ = *device_id;
if (!*device_id)
break;
while (ptr > value && _cups_isspace(ptr[-1]))
ptr --;
*ptr = '\0';
device_id ++;
num_values = cupsAddOption(key, value, num_values, values);
}
return (num_values);
}
/*
* 'cups_compare_options()' - Compare two options.
*/
static int /* O - Result of comparison */
cups_compare_options(cups_option_t *a, /* I - First option */
cups_option_t *b) /* I - Second option */
{
return (_cups_strcasecmp(a->name, b->name));
}
/*
* 'cups_find_option()' - Find an option using a binary search.
*/
static int /* O - Index of match */
cups_find_option(
const char *name, /* I - Option name */
int num_options, /* I - Number of options */
cups_option_t *options, /* I - Options */
int prev, /* I - Previous index */
int *rdiff) /* O - Difference of match */
{
int left, /* Low mark for binary search */
right, /* High mark for binary search */
current, /* Current index */
diff; /* Result of comparison */
cups_option_t key; /* Search key */
DEBUG_printf(("7cups_find_option(name=\"%s\", num_options=%d, options=%p, "
"prev=%d, rdiff=%p)", name, num_options, options, prev,
rdiff));
#ifdef DEBUG
for (left = 0; left < num_options; left ++)
DEBUG_printf(("9cups_find_option: options[%d].name=\"%s\", .value=\"%s\"",
left, options[left].name, options[left].value));
#endif /* DEBUG */
key.name = (char *)name;
if (prev >= 0)
{
/*
* Start search on either side of previous...
*/
if ((diff = cups_compare_options(&key, options + prev)) == 0 ||
(diff < 0 && prev == 0) ||
(diff > 0 && prev == (num_options - 1)))
{
*rdiff = diff;
return (prev);
}
else if (diff < 0)
{
/*
* Start with previous on right side...
*/
left = 0;
right = prev;
}
else
{
/*
* Start wih previous on left side...
*/
left = prev;
right = num_options - 1;
}
}
else
{
/*
* Start search in the middle...
*/
left = 0;
right = num_options - 1;
}
do
{
current = (left + right) / 2;
diff = cups_compare_options(&key, options + current);
if (diff == 0)
break;
else if (diff < 0)
right = current;
else
left = current;
}
while ((right - left) > 1);
if (diff != 0)
{
/*
* Check the last 1 or 2 elements...
*/
if ((diff = cups_compare_options(&key, options + left)) <= 0)
current = left;
else
{
diff = cups_compare_options(&key, options + right);
current = right;
}
}
/*
* Return the closest destination and the difference...
*/
*rdiff = diff;
return (current);
}
/*
* End of "$Id: options.c 8181 2008-12-10 17:29:57Z mike $".
*/

396
cups/page.c Normal file
View File

@@ -0,0 +1,396 @@
/*
* "$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 $".
*/

2635
cups/ppd-cache.c Normal file

File diff suppressed because it is too large Load Diff

215
cups/ppd-private.h Normal file
View File

@@ -0,0 +1,215 @@
/*
* "$Id: ppd-private.h 3683 2012-02-16 22:03:53Z msweet $"
*
* Private PPD definitions for CUPS.
*
* Copyright 2007-2011 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.
*/
#ifndef _CUPS_PPD_PRIVATE_H_
# define _CUPS_PPD_PRIVATE_H_
/*
* Include necessary headers...
*/
# include <cups/cups.h>
# include <cups/ppd.h>
# include "pwg-private.h"
/*
* C++ magic...
*/
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/*
* Constants...
*/
# define _PPD_CACHE_VERSION 3 /* Version number in cache file */
/*
* Types and structures...
*/
typedef enum _ppd_localization_e /**** Selector for _ppdOpen ****/
{
_PPD_LOCALIZATION_DEFAULT, /* Load only the default localization */
_PPD_LOCALIZATION_ICC_PROFILES, /* Load only the color profile localization */
_PPD_LOCALIZATION_NONE, /* Load no localizations */
_PPD_LOCALIZATION_ALL /* Load all localizations */
} _ppd_localization_t;
typedef enum _ppd_parse_e /**** Selector for _ppdParseOptions ****/
{
_PPD_PARSE_OPTIONS, /* Parse only the options */
_PPD_PARSE_PROPERTIES, /* Parse only the properties */
_PPD_PARSE_ALL /* Parse everything */
} _ppd_parse_t;
typedef struct _ppd_cups_uiconst_s /**** Constraint from cupsUIConstraints ****/
{
ppd_option_t *option; /* Constrained option */
ppd_choice_t *choice; /* Constrained choice or @code NULL@ */
int installable; /* Installable option? */
} _ppd_cups_uiconst_t;
typedef struct _ppd_cups_uiconsts_s /**** cupsUIConstraints ****/
{
char resolver[PPD_MAX_NAME]; /* Resolver name */
int installable, /* Constrained against any installable options? */
num_constraints; /* Number of constraints */
_ppd_cups_uiconst_t *constraints; /* Constraints */
} _ppd_cups_uiconsts_t;
typedef enum _pwg_print_color_mode_e /**** PWG print-color-mode indices ****/
{
_PWG_PRINT_COLOR_MODE_MONOCHROME = 0, /* print-color-mode=monochrome */
_PWG_PRINT_COLOR_MODE_COLOR, /* print-color-mode=color */
/* Other proposed values are not supported by CUPS yet. */
_PWG_PRINT_COLOR_MODE_MAX
} _pwg_print_color_mode_t;
typedef enum _pwg_print_quality_e /**** PWG print-quality values ****/
{
_PWG_PRINT_QUALITY_DRAFT = 0, /* print-quality=3 */
_PWG_PRINT_QUALITY_NORMAL, /* print-quality=4 */
_PWG_PRINT_QUALITY_HIGH, /* print-quality=5 */
_PWG_PRINT_QUALITY_MAX
} _pwg_print_quality_t;
typedef struct _pwg_finishings_s /**** PWG finishings mapping data ****/
{
ipp_finish_t value; /* finishings value */
int num_options; /* Number of options to apply */
cups_option_t *options; /* Options to apply */
} _pwg_finishings_t;
struct _ppd_cache_s /**** PPD cache and PWG conversion data ****/
{
int num_bins; /* Number of output bins */
_pwg_map_t *bins; /* Output bins */
int num_sizes; /* Number of media sizes */
_pwg_size_t *sizes; /* Media sizes */
int custom_max_width, /* Maximum custom width in 2540ths */
custom_max_length, /* Maximum custom length in 2540ths */
custom_min_width, /* Minimum custom width in 2540ths */
custom_min_length; /* Minimum custom length in 2540ths */
char *custom_max_keyword, /* Maximum custom size PWG keyword */
*custom_min_keyword, /* Minimum custom size PWG keyword */
custom_ppd_size[41]; /* Custom PPD size name */
_pwg_size_t custom_size; /* Custom size record */
char *source_option; /* PPD option for media source */
int num_sources; /* Number of media sources */
_pwg_map_t *sources; /* Media sources */
int num_types; /* Number of media types */
_pwg_map_t *types; /* Media types */
int num_presets[_PWG_PRINT_COLOR_MODE_MAX][_PWG_PRINT_QUALITY_MAX];
/* Number of print-color-mode/print-quality options */
cups_option_t *presets[_PWG_PRINT_COLOR_MODE_MAX][_PWG_PRINT_QUALITY_MAX];
/* print-color-mode/print-quality options */
char *sides_option, /* PPD option for sides */
*sides_1sided, /* Choice for one-sided */
*sides_2sided_long, /* Choice for two-sided-long-edge */
*sides_2sided_short; /* Choice for two-sided-short-edge */
char *product; /* Product value */
cups_array_t *filters, /* cupsFilter/cupsFilter2 values */
*prefilters; /* cupsPreFilter values */
int single_file; /* cupsSingleFile value */
cups_array_t *finishings; /* cupsIPPFinishings values */
int max_copies; /* cupsMaxCopies value */
};
/*
* Prototypes...
*/
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);
extern const char *_ppdCacheGetBin(_ppd_cache_t *pc,
const char *output_bin);
extern int _ppdCacheGetFinishingOptions(_ppd_cache_t *pc, ipp_t *job,
ipp_finish_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);
extern const char *_ppdCacheGetInputSlot(_ppd_cache_t *pc, ipp_t *job,
const char *keyword);
extern const char *_ppdCacheGetMediaType(_ppd_cache_t *pc, ipp_t *job,
const char *keyword);
extern const char *_ppdCacheGetOutputBin(_ppd_cache_t *pc,
const char *keyword);
extern const char *_ppdCacheGetPageSize(_ppd_cache_t *pc, ipp_t *job,
const char *keyword, int *exact);
extern _pwg_size_t *_ppdCacheGetSize(_ppd_cache_t *pc,
const char *page_size);
extern const char *_ppdCacheGetSource(_ppd_cache_t *pc,
const char *input_slot);
extern const char *_ppdCacheGetType(_ppd_cache_t *pc,
const char *media_type);
extern int _ppdCacheWriteFile(_ppd_cache_t *pc,
const char *filename, ipp_t *attrs);
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 unsigned _ppdHashName(const char *name);
extern ppd_attr_t *_ppdLocalizedAttr(ppd_file_t *ppd, const char *keyword,
const char *spec, const char *ll_CC);
extern char *_ppdNormalizeMakeAndModel(const char *make_and_model,
char *buffer,
size_t bufsize);
extern ppd_file_t *_ppdOpen(cups_file_t *fp,
_ppd_localization_t localization);
extern ppd_file_t *_ppdOpenFile(const char *filename,
_ppd_localization_t localization);
extern int _ppdParseOptions(const char *s, int num_options,
cups_option_t **options,
_ppd_parse_t which);
extern const char *_pwgInputSlotForSource(const char *media_source,
char *name, size_t namesize);
extern const char *_pwgMediaTypeForType(const char *media_type,
char *name, size_t namesize);
extern const char *_pwgPageSizeForMedia(_pwg_media_t *media,
char *name, size_t namesize);
/*
* C++ magic...
*/
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_PPD_PRIVATE_H_ */
/*
* End of "$Id: ppd-private.h 3683 2012-02-16 22:03:53Z msweet $".
*/

3398
cups/ppd.c Normal file

File diff suppressed because it is too large Load Diff

480
cups/ppd.h Normal file
View File

@@ -0,0 +1,480 @@
/*
* "$Id: ppd.h 7791 2008-07-24 00:55:30Z mike $"
*
* 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.
*
* 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.
*/
#ifndef _CUPS_PPD_H_
# define _CUPS_PPD_H_
/*
* Include necessary headers...
*/
# include <stdio.h>
# include "cups.h"
# include "array.h"
# include "file.h"
/*
* C++ magic...
*/
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/*
* Define _PPD_DEPRECATED to silence the warnings about PPD functions being
* deprecated...
*/
# ifndef _PPD_DEPRECATED
# if defined(__APPLE__)
# if defined(MAC_OS_X_VERSION_10_8) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_8
/* Building for OS X 10.7 and earlier */
# define _PPD_DEPRECATED
# elif !defined(MAC_OS_X_VERSION_10_8)
/* Building for OS X 10.7 and earlier */
# define _PPD_DEPRECATED
# else
# define _PPD_DEPRECATED _CUPS_DEPRECATED
# endif /* MAC_OS_X_VERSION_10_8 && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_8 */
# else
# define _PPD_DEPRECATED _CUPS_DEPRECATED
# endif /* __APPLE__ */
# endif /* !_PPD_DEPRECATED */
/*
* PPD version...
*/
# define PPD_VERSION 4.3 /* Kept in sync with Adobe version number */
/*
* PPD size limits (defined in Adobe spec)
*/
# define PPD_MAX_NAME 41 /* Maximum size of name + 1 for nul */
# define PPD_MAX_TEXT 81 /* Maximum size of text + 1 for nul */
# define PPD_MAX_LINE 256 /* Maximum size of line + 1 for nul */
/*
* Types and structures...
*/
typedef enum ppd_ui_e /**** UI Types ****/
{
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 ****/
{
PPD_ORDER_ANY, /* Option code can be anywhere in the file */
PPD_ORDER_DOCUMENT, /* ... must be in the DocumentSetup section */
PPD_ORDER_EXIT, /* ... must be sent prior to the document */
PPD_ORDER_JCL, /* ... must be sent as a JCL command */
PPD_ORDER_PAGE, /* ... must be in the PageSetup section */
PPD_ORDER_PROLOG /* ... must be in the Prolog section */
} ppd_section_t;
typedef enum ppd_cs_e /**** Colorspaces ****/
{
PPD_CS_CMYK = -4, /* CMYK colorspace */
PPD_CS_CMY, /* CMY colorspace */
PPD_CS_GRAY = 1, /* Grayscale colorspace */
PPD_CS_RGB = 3, /* RGB colorspace */
PPD_CS_RGBK, /* RGBK (K = gray) colorspace */
PPD_CS_N /* DeviceN colorspace */
} ppd_cs_t;
typedef enum ppd_status_e /**** Status Codes @since CUPS 1.1.19/OS X 10.3@ ****/
{
PPD_OK = 0, /* OK */
PPD_FILE_OPEN_ERROR, /* Unable to open PPD file */
PPD_NULL_FILE, /* NULL PPD file pointer */
PPD_ALLOC_ERROR, /* Memory allocation error */
PPD_MISSING_PPDADOBE4, /* Missing PPD-Adobe-4.x header */
PPD_MISSING_VALUE, /* Missing value string */
PPD_INTERNAL_ERROR, /* Internal error */
PPD_BAD_OPEN_GROUP, /* Bad OpenGroup */
PPD_NESTED_OPEN_GROUP, /* OpenGroup without a CloseGroup first */
PPD_BAD_OPEN_UI, /* Bad OpenUI/JCLOpenUI */
PPD_NESTED_OPEN_UI, /* OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first */
PPD_BAD_ORDER_DEPENDENCY, /* Bad OrderDependency */
PPD_BAD_UI_CONSTRAINTS, /* Bad UIConstraints */
PPD_MISSING_ASTERISK, /* Missing asterisk in column 0 */
PPD_LINE_TOO_LONG, /* Line longer than 255 chars */
PPD_ILLEGAL_CHARACTER, /* Illegal control character */
PPD_ILLEGAL_MAIN_KEYWORD, /* Illegal main keyword string */
PPD_ILLEGAL_OPTION_KEYWORD, /* Illegal option keyword string */
PPD_ILLEGAL_TRANSLATION, /* Illegal translation string */
PPD_ILLEGAL_WHITESPACE, /* Illegal whitespace character */
PPD_BAD_CUSTOM_PARAM, /* Bad custom parameter */
PPD_MISSING_OPTION_KEYWORD, /* Missing option keyword */
PPD_BAD_VALUE, /* Bad value string */
PPD_MISSING_CLOSE_GROUP, /* Missing CloseGroup */
PPD_MAX_STATUS /* @private@ */
} ppd_status_t;
enum ppd_conform_e /**** Conformance Levels @since CUPS 1.1.19/OS X 10.3@ ****/
{
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/OS X 10.3@ ****/
typedef struct ppd_attr_s /**** PPD Attribute Structure @since CUPS 1.1.19/OS X 10.3@ ****/
{
char name[PPD_MAX_NAME]; /* Name of attribute (cupsXYZ) */
char spec[PPD_MAX_NAME]; /* Specifier string, if any */
char text[PPD_MAX_TEXT]; /* Human-readable text, if any */
char *value; /* Value string */
} ppd_attr_t;
typedef struct ppd_option_s ppd_option_t;
/**** Options ****/
typedef struct ppd_choice_s /**** Option choices ****/
{
char marked; /* 0 if not selected, 1 otherwise */
char choice[PPD_MAX_NAME]; /* Computer-readable option name */
char text[PPD_MAX_TEXT]; /* Human-readable option name */
char *code; /* Code to send for this option */
ppd_option_t *option; /* Pointer to parent option structure */
} ppd_choice_t;
struct ppd_option_s /**** Options ****/
{
char conflicted; /* 0 if no conflicts exist, 1 otherwise */
char keyword[PPD_MAX_NAME]; /* Option keyword name ("PageSize", etc.) */
char defchoice[PPD_MAX_NAME];/* Default option choice */
char text[PPD_MAX_TEXT]; /* Human-readable text */
ppd_ui_t ui; /* Type of UI option */
ppd_section_t section; /* Section for command */
float order; /* Order number */
int num_choices; /* Number of option choices */
ppd_choice_t *choices; /* Option choices */
};
typedef struct ppd_group_s /**** Groups ****/
{
/**** Group text strings are limited to 39 chars + nul in order to
**** preserve binary compatibility and allow applications to get
**** the group's keyword name.
****/
char text[PPD_MAX_TEXT - PPD_MAX_NAME];
/* Human-readable group name */
char name[PPD_MAX_NAME]; /* Group name @since CUPS 1.1.18/OS X 10.3@ */
int num_options; /* Number of options */
ppd_option_t *options; /* Options */
int num_subgroups; /* Number of sub-groups */
struct ppd_group_s *subgroups; /* Sub-groups (max depth = 1) */
} ppd_group_t;
typedef struct ppd_const_s /**** Constraints ****/
{
char option1[PPD_MAX_NAME]; /* First keyword */
char choice1[PPD_MAX_NAME]; /* First option/choice (blank for all) */
char option2[PPD_MAX_NAME]; /* Second keyword */
char choice2[PPD_MAX_NAME]; /* Second option/choice (blank for all) */
} ppd_const_t;
typedef struct ppd_size_s /**** Page Sizes ****/
{
int marked; /* Page size selected? */
char name[PPD_MAX_NAME]; /* Media size option */
float width; /* Width of media in points */
float length; /* Length of media in points */
float left; /* Left printable margin in points */
float bottom; /* Bottom printable margin in points */
float right; /* Right printable margin in points */
float top; /* Top printable margin in points */
} ppd_size_t;
typedef struct ppd_emul_s /**** Emulators ****/
{
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 ****/
{
char resolution[PPD_MAX_NAME];
/* Resolution or "-" */
char media_type[PPD_MAX_NAME];
/* Media type or "-" */
float density; /* Ink density to use */
float gamma; /* Gamma correction to use */
float matrix[3][3]; /* Transform matrix */
} ppd_profile_t;
/**** New in CUPS 1.2/OS X 10.5 ****/
typedef enum ppd_cptype_e /**** Custom Parameter Type @since CUPS 1.2/OS X 10.5@ ****/
{
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) */
PPD_CUSTOM_PASSCODE, /* String of (hidden) numbers */
PPD_CUSTOM_PASSWORD, /* String of (hidden) characters */
PPD_CUSTOM_POINTS, /* Measurement value in points */
PPD_CUSTOM_REAL, /* Real number value */
PPD_CUSTOM_STRING /* String of characters */
} ppd_cptype_t;
typedef union ppd_cplimit_u /**** Custom Parameter Limit @since CUPS 1.2/OS X 10.5@ ****/
{
float custom_curve; /* Gamma value */
int custom_int; /* Integer value */
float custom_invcurve; /* Gamma value */
int custom_passcode; /* Passcode length */
int custom_password; /* Password length */
float custom_points; /* Measurement value */
float custom_real; /* Real value */
int custom_string; /* String length */
} ppd_cplimit_t;
typedef union ppd_cpvalue_u /**** Custom Parameter Value @since CUPS 1.2/OS X 10.5@ ****/
{
float custom_curve; /* Gamma value */
int custom_int; /* Integer value */
float custom_invcurve; /* Gamma value */
char *custom_passcode; /* Passcode value */
char *custom_password; /* Password value */
float custom_points; /* Measurement value */
float custom_real; /* Real value */
char *custom_string; /* String value */
} ppd_cpvalue_t;
typedef struct ppd_cparam_s /**** Custom Parameter @since CUPS 1.2/OS X 10.5@ ****/
{
char name[PPD_MAX_NAME]; /* Parameter name */
char text[PPD_MAX_TEXT]; /* Human-readable text */
int order; /* Order (0 to N) */
ppd_cptype_t type; /* Parameter type */
ppd_cplimit_t minimum, /* Minimum value */
maximum; /* Maximum value */
ppd_cpvalue_t current; /* Current value */
} ppd_cparam_t;
typedef struct ppd_coption_s /**** Custom Option @since CUPS 1.2/OS X 10.5@ ****/
{
char keyword[PPD_MAX_NAME]; /* Name of option that is being extended... */
ppd_option_t *option; /* Option that is being extended... */
int marked; /* Extended option is marked */
cups_array_t *params; /* Parameters */
} ppd_coption_t;
typedef struct _ppd_cache_s _ppd_cache_t;
/**** PPD cache and mapping data @since CUPS 1.5/OS X 10.7@ @private@ ****/
typedef struct ppd_file_s /**** PPD File ****/
{
int language_level; /* Language level of device */
int color_device; /* 1 = color device, 0 = grayscale */
int variable_sizes; /* 1 = supports variable sizes, 0 = doesn't */
int accurate_screens; /* 1 = supports accurate screens, 0 = not */
int contone_only; /* 1 = continuous tone only, 0 = not */
int landscape; /* -90 or 90 */
int model_number; /* Device-specific model number */
int manual_copies; /* 1 = Copies done manually, 0 = hardware */
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 */
char *jcl_begin; /* Start JCL commands */
char *jcl_ps; /* Enter PostScript interpreter */
char *jcl_end; /* End JCL commands */
char *lang_encoding; /* Language encoding */
char *lang_version; /* Language version (English, Spanish, etc.) */
char *modelname; /* Model name (general) */
char *ttrasterizer; /* Truetype rasterizer */
char *manufacturer; /* Manufacturer name */
char *product; /* Product name (from PS RIP/interpreter) */
char *nickname; /* Nickname (specific) */
char *shortnickname; /* Short version of nickname */
int num_groups; /* Number of UI groups */
ppd_group_t *groups; /* UI groups */
int num_sizes; /* Number of page sizes */
ppd_size_t *sizes; /* Page sizes */
float custom_min[2]; /* Minimum variable page size */
float custom_max[2]; /* Maximum variable page size */
float custom_margins[4]; /* Margins around page */
int num_consts; /* Number of UI/Non-UI constraints */
ppd_const_t *consts; /* UI/Non-UI constraints */
int num_fonts; /* Number of pre-loaded fonts */
char **fonts; /* Pre-loaded fonts */
int num_profiles; /* Number of sRGB color profiles @deprecated@ */
ppd_profile_t *profiles; /* sRGB color profiles @deprecated@ */
int num_filters; /* Number of filters */
char **filters; /* Filter strings... */
/**** New in CUPS 1.1 ****/
int flip_duplex; /* 1 = Flip page for back sides @deprecated@ */
/**** New in CUPS 1.1.19 ****/
char *protocols; /* Protocols (BCP, TBCP) string @since CUPS 1.1.19/OS X 10.3@ */
char *pcfilename; /* PCFileName string @since CUPS 1.1.19/OS X 10.3@ */
int num_attrs; /* Number of attributes @since CUPS 1.1.19/OS X 10.3@ @private@ */
int cur_attr; /* Current attribute @since CUPS 1.1.19/OS X 10.3@ @private@ */
ppd_attr_t **attrs; /* Attributes @since CUPS 1.1.19/OS X 10.3@ @private@ */
/**** New in CUPS 1.2/OS X 10.5 ****/
cups_array_t *sorted_attrs; /* Attribute lookup array @since CUPS 1.2/OS X 10.5@ @private@ */
cups_array_t *options; /* Option lookup array @since CUPS 1.2/OS X 10.5@ @private@ */
cups_array_t *coptions; /* Custom options array @since CUPS 1.2/OS X 10.5@ @private@ */
/**** New in CUPS 1.3/OS X 10.5 ****/
cups_array_t *marked; /* Marked choices @since CUPS 1.3/OS X 10.5@ @private@ */
/**** New in CUPS 1.4/OS X 10.6 ****/
cups_array_t *cups_uiconstraints; /* cupsUIConstraints @since CUPS 1.4/OS X 10.6@ @private@ */
/**** New in CUPS 1.5 ****/
_ppd_cache_t *cache; /* PPD cache and mapping data @since CUPS 1.5/OS X 10.7@ @private@ */
} ppd_file_t;
/*
* Prototypes...
*/
extern int cupsMarkOptions(ppd_file_t *ppd, int num_options,
cups_option_t *options);
extern void ppdClose(ppd_file_t *ppd);
extern int ppdCollect(ppd_file_t *ppd, ppd_section_t section,
ppd_choice_t ***choices);
extern int ppdConflicts(ppd_file_t *ppd);
extern int ppdEmit(ppd_file_t *ppd, FILE *fp,
ppd_section_t section);
extern int ppdEmitFd(ppd_file_t *ppd, int fd,
ppd_section_t section);
extern int ppdEmitJCL(ppd_file_t *ppd, FILE *fp, int job_id,
const char *user, const char *title);
extern ppd_choice_t *ppdFindChoice(ppd_option_t *o, const char *option);
extern ppd_choice_t *ppdFindMarkedChoice(ppd_file_t *ppd,
const char *keyword);
extern ppd_option_t *ppdFindOption(ppd_file_t *ppd, const char *keyword);
extern int ppdIsMarked(ppd_file_t *ppd, const char *keyword,
const char *option);
extern void ppdMarkDefaults(ppd_file_t *ppd);
extern int ppdMarkOption(ppd_file_t *ppd, const char *keyword,
const char *option);
extern ppd_file_t *ppdOpen(FILE *fp);
extern ppd_file_t *ppdOpenFd(int fd);
extern ppd_file_t *ppdOpenFile(const char *filename);
extern float ppdPageLength(ppd_file_t *ppd, const char *name);
extern ppd_size_t *ppdPageSize(ppd_file_t *ppd, const char *name);
extern float ppdPageWidth(ppd_file_t *ppd, const char *name);
/**** New in CUPS 1.1.19 ****/
extern const char *ppdErrorString(ppd_status_t status) _PPD_DEPRECATED;
extern ppd_attr_t *ppdFindAttr(ppd_file_t *ppd, const char *name,
const char *spec) _PPD_DEPRECATED;
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;
/**** New in CUPS 1.1.20 ****/
extern void ppdSetConformance(ppd_conform_t c) _PPD_DEPRECATED;
/**** New in CUPS 1.2 ****/
extern int ppdCollect2(ppd_file_t *ppd, ppd_section_t section,
float min_order, ppd_choice_t ***choices)
_PPD_DEPRECATED;
extern int ppdEmitAfterOrder(ppd_file_t *ppd, FILE *fp,
ppd_section_t section, int limit,
float min_order) _PPD_DEPRECATED;
extern int ppdEmitJCLEnd(ppd_file_t *ppd, FILE *fp) _PPD_DEPRECATED;
extern char *ppdEmitString(ppd_file_t *ppd, ppd_section_t section,
float min_order) _PPD_DEPRECATED;
extern ppd_coption_t *ppdFindCustomOption(ppd_file_t *ppd,
const char *keyword) _PPD_DEPRECATED;
extern ppd_cparam_t *ppdFindCustomParam(ppd_coption_t *opt,
const char *name) _PPD_DEPRECATED;
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;
/**** New in CUPS 1.3/OS X 10.5 ****/
extern const char *ppdLocalizeIPPReason(ppd_file_t *ppd,
const char *reason,
const char *scheme,
char *buffer,
size_t bufsize) _PPD_DEPRECATED;
/**** New in CUPS 1.4/OS X 10.6 ****/
extern int cupsGetConflicts(ppd_file_t *ppd, const char *option,
const char *choice,
cups_option_t **options)
_PPD_DEPRECATED;
extern int cupsResolveConflicts(ppd_file_t *ppd,
const char *option,
const char *choice,
int *num_options,
cups_option_t **options)
_PPD_DEPRECATED;
extern int ppdInstallableConflict(ppd_file_t *ppd,
const char *option,
const char *choice)
_PPD_DEPRECATED;
extern ppd_attr_t *ppdLocalizeAttr(ppd_file_t *ppd, const char *keyword,
const char *spec) _PPD_DEPRECATED;
extern const char *ppdLocalizeMarkerName(ppd_file_t *ppd,
const char *name)
_PPD_DEPRECATED;
extern int ppdPageSizeLimits(ppd_file_t *ppd,
ppd_size_t *minimum,
ppd_size_t *maximum) _PPD_DEPRECATED;
/*
* C++ magic...
*/
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_PPD_H_ */
/*
* End of "$Id: ppd.h 7791 2008-07-24 00:55:30Z mike $".
*/

928
cups/pwg-media.c Normal file
View File

@@ -0,0 +1,928 @@
/*
* "$Id: pwg-media.c 10979 2013-05-13 17:39:19Z msweet $"
*
* PWG media name API implementation for CUPS.
*
* Copyright 2009-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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*
* Contents:
*
*/
/*
* Include necessary headers...
*/
#include "cups-private.h"
#include <math.h>
/*
* Local macros...
*/
#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)}
/*
* Local functions...
*/
static int pwg_compare_legacy(_pwg_media_t *a, _pwg_media_t *b);
static int pwg_compare_pwg(_pwg_media_t *a, _pwg_media_t *b);
static int pwg_compare_ppd(_pwg_media_t *a, _pwg_media_t *b);
/*
* Local globals...
*/
static _pwg_media_t const cups_pwg_media[] =
{ /* Media size lookup table */
/* North American Standard Sheet Media Sizes */
_PWG_MEDIA_IN("na_index-3x5_3x5in", NULL, "3x5", 3, 5),
_PWG_MEDIA_IN("na_personal_3.625x6.5in", NULL, "EnvPersonal", 3.625, 6.5),
_PWG_MEDIA_IN("na_monarch_3.875x7.5in", "monarch-envelope", "EnvMonarch", 3.875, 7.5),
_PWG_MEDIA_IN("na_number-9_3.875x8.875in", "na-number-9-envelope", "Env9", 3.875, 8.875),
_PWG_MEDIA_IN("na_index-4x6_4x6in", NULL, "4x6", 4, 6),
_PWG_MEDIA_IN("na_number-10_4.125x9.5in", "na-number-10-envelope", "Env10", 4.125, 9.5),
_PWG_MEDIA_IN("na_a2_4.375x5.75in", NULL, "EnvA2", 4.375, 5.75),
_PWG_MEDIA_IN("na_number-11_4.5x10.375in", NULL, "Env11", 4.5, 10.375),
_PWG_MEDIA_IN("na_number-12_4.75x11in", NULL, "Env12", 4.75, 11),
_PWG_MEDIA_IN("na_5x7_5x7in", NULL, "5x7", 5, 7),
_PWG_MEDIA_IN("na_index-5x8_5x8in", NULL, "5x8", 5, 8),
_PWG_MEDIA_IN("na_number-14_5x11.5in", NULL, "Env14", 5, 11.5),
_PWG_MEDIA_IN("na_invoice_5.5x8.5in", "invoice", "Statement", 5.5, 8.5),
_PWG_MEDIA_IN("na_index-4x6-ext_6x8in", NULL, NULL, 6, 8),
_PWG_MEDIA_IN("na_6x9_6x9in", "na-6x9-envelope", "6x9", 6, 9),
_PWG_MEDIA_IN("na_c5_6.5x9.5in", NULL, "6.5x9.5", 6.5, 9.5),
_PWG_MEDIA_IN("na_7x9_7x9in", "na-7x9-envelope", "7x9", 7, 9),
_PWG_MEDIA_IN("na_executive_7.25x10.5in", "executive", "Executive", 7.25, 10.5),
_PWG_MEDIA_IN("na_govt-letter_8x10in", "na-8x10", "8x10", 8, 10),
_PWG_MEDIA_IN("na_govt-legal_8x13in", NULL, "8x13", 8, 13),
_PWG_MEDIA_IN("na_quarto_8.5x10.83in", "quarto", "Quarto", 8.5, 10.83),
_PWG_MEDIA_IN("na_letter_8.5x11in", "na-letter", "Letter", 8.5, 11),
_PWG_MEDIA_IN("na_fanfold-eur_8.5x12in", NULL, "FanFoldGerman", 8.5, 12),
_PWG_MEDIA_IN("na_letter-plus_8.5x12.69in", NULL, "LetterPlus", 8.5, 12.69),
_PWG_MEDIA_IN("na_foolscap_8.5x13in", NULL, "FanFoldGermanLegal", 8.5, 13),
_PWG_MEDIA_IN("na_legal_8.5x14in", "na-legal", "Legal", 8.5, 14),
_PWG_MEDIA_IN("na_super-a_8.94x14in", NULL, "SuperA", 8.94, 14),
_PWG_MEDIA_IN("na_9x11_9x11in", "na-9x11-envelope", "9x11", 9, 11),
_PWG_MEDIA_IN("na_arch-a_9x12in", "arch-a", "ARCHA", 9, 12),
_PWG_MEDIA_IN("na_letter-extra_9.5x12in", NULL, "LetterExtra", 9.5, 12),
_PWG_MEDIA_IN("na_legal-extra_9.5x15in", NULL, "LegalExtra", 9.5, 15),
_PWG_MEDIA_IN("na_10x11_10x11in", NULL, "10x11", 10, 11),
_PWG_MEDIA_IN("na_10x13_10x13in", "na-10x13-envelope", "10x13", 10, 13),
_PWG_MEDIA_IN("na_10x14_10x14in", "na-10x14-envelope", "10x14", 10, 14),
_PWG_MEDIA_IN("na_10x15_10x15in", "na-10x15-envelope", "10x15", 10, 15),
_PWG_MEDIA_IN("na_11x12_11x12in", NULL, "11x12", 11, 12),
_PWG_MEDIA_IN("na_edp_11x14in", NULL, "11x14", 11, 14),
_PWG_MEDIA_IN("na_fanfold-us_11x14.875in", NULL, NULL, 11, 14.875),
_PWG_MEDIA_IN("na_11x15_11x15in", NULL, "11x15", 11, 15),
_PWG_MEDIA_IN("na_ledger_11x17in", "tabloid", "Tabloid", 11, 17),
_PWG_MEDIA_IN("na_eur-edp_12x14in", NULL, NULL, 12, 14),
_PWG_MEDIA_IN("na_arch-b_12x18in", "arch-b", "ARCHB", 12, 18),
_PWG_MEDIA_IN("na_12x19_12x19in", NULL, "12x19", 12, 19),
_PWG_MEDIA_IN("na_b-plus_12x19.17in", NULL, "SuperB", 12, 19.17),
_PWG_MEDIA_IN("na_super-b_13x19in", "super-b", "13x19", 13, 19),
_PWG_MEDIA_IN("na_c_17x22in", "c", "AnsiC", 17, 22),
_PWG_MEDIA_IN("na_arch-c_18x24in", "arch-c", "ARCHC", 18, 24),
_PWG_MEDIA_IN("na_d_22x34in", "d", "AnsiD", 22, 34),
_PWG_MEDIA_IN("na_arch-d_24x36in", "arch-d", "ARCHD", 24, 36),
_PWG_MEDIA_IN("asme_f_28x40in", "f", NULL, 28, 40),
_PWG_MEDIA_IN("na_wide-format_30x42in", NULL, NULL, 30, 42),
_PWG_MEDIA_IN("na_e_34x44in", "e", "AnsiE", 34, 44),
_PWG_MEDIA_IN("na_arch-e_36x48in", "arch-e", "ARCHE", 36, 48),
_PWG_MEDIA_IN("na_f_44x68in", NULL, "AnsiF", 44, 68),
/* Chinese Standard Sheet Media Inch Sizes */
_PWG_MEDIA_IN("roc_16k_7.75x10.75in", NULL, "roc16k", 7.75, 10.75),
_PWG_MEDIA_IN("roc_8k_10.75x15.5in", NULL, "roc8k", 10.75, 15.5),
/* ISO Standard Sheet Media Sizes */
_PWG_MEDIA_MM("iso_a10_26x37mm", "iso-a10", "A10", 26, 37),
_PWG_MEDIA_MM("iso_a9_37x52mm", "iso-a9", "A9", 37, 52),
_PWG_MEDIA_MM("iso_a8_52x74mm", "iso-a8", "A8", 52, 74),
_PWG_MEDIA_MM("iso_a7_74x105mm", "iso-a7", "A7", 74, 105),
_PWG_MEDIA_MM("iso_a6_105x148mm", "iso-a6", "A6", 105, 148),
_PWG_MEDIA_MM("iso_a5_148x210mm", "iso-a5", "A5", 148, 210),
_PWG_MEDIA_MM("iso_a5-extra_174x235mm", NULL, "A5Extra", 174, 235),
_PWG_MEDIA_MM("iso_a4_210x297mm", "iso-a4", "A4", 210, 297),
_PWG_MEDIA_MM("iso_a4-tab_225x297mm", NULL, "A4Tab", 225, 297),
_PWG_MEDIA_MM("iso_a4-extra_235.5x322.3mm", NULL, "A4Extra", 235.5, 322.3),
_PWG_MEDIA_MM("iso_a3_297x420mm", "iso-a3", "A3", 297, 420),
_PWG_MEDIA_MM("iso_a4x3_297x630mm", "iso-a4x3", NULL, 297, 630),
_PWG_MEDIA_MM("iso_a4x4_297x841mm", "iso-a4x4", NULL, 297, 841),
_PWG_MEDIA_MM("iso_a4x5_297x1051mm", "iso-a4x5", NULL, 297, 1051),
_PWG_MEDIA_MM("iso_a4x6_297x1261mm", "iso-a4x6", NULL, 297, 1261),
_PWG_MEDIA_MM("iso_a4x7_297x1471mm", "iso-a4x7", NULL, 297, 1471),
_PWG_MEDIA_MM("iso_a4x8_297x1682mm", "iso-a4x8", NULL, 297, 1682),
_PWG_MEDIA_MM("iso_a4x9_297x1892mm", "iso-a4x9", NULL, 297, 1892),
_PWG_MEDIA_MM("iso_a3-extra_322x445mm", "iso-a3-extra", "A3Extra", 322, 445),
_PWG_MEDIA_MM("iso_a2_420x594mm", "iso-a2", "A2", 420, 594),
_PWG_MEDIA_MM("iso_a3x3_420x891mm", "iso-a3x3", NULL, 420, 891),
_PWG_MEDIA_MM("iso_a3x4_420x1189mm", "iso-a3x4", NULL, 420, 1189),
_PWG_MEDIA_MM("iso_a3x5_420x1486mm", "iso-a3x5", NULL, 420, 1486),
_PWG_MEDIA_MM("iso_a3x6_420x1783mm", "iso-a3x6", NULL, 420, 1783),
_PWG_MEDIA_MM("iso_a3x7_420x2080mm", "iso-a3x7", NULL, 420, 2080),
_PWG_MEDIA_MM("iso_a1_594x841mm", "iso-a1", "A1", 594, 841),
_PWG_MEDIA_MM("iso_a2x3_594x1261mm", "iso-a2x3", NULL, 594, 1261),
_PWG_MEDIA_MM("iso_a2x4_594x1682mm", "iso-a2x4", NULL, 594, 1682),
_PWG_MEDIA_MM("iso_a2x5_594x2102mm", "iso-a2x5", NULL, 594, 2102),
_PWG_MEDIA_MM("iso_a0_841x1189mm", "iso-a0", "A0", 841, 1189),
_PWG_MEDIA_MM("iso_a1x3_841x1783mm", "iso-a1x3", NULL, 841, 1783),
_PWG_MEDIA_MM("iso_a1x4_841x2378mm", "iso-a1x4", NULL, 841, 2378),
_PWG_MEDIA_MM("iso_2a0_1189x1682mm", NULL, NULL, 1189, 1682),
_PWG_MEDIA_MM("iso_a0x3_1189x2523mm", NULL, NULL, 1189, 2523),
_PWG_MEDIA_MM("iso_b10_31x44mm", "iso-b10", "ISOB10", 31, 44),
_PWG_MEDIA_MM("iso_b9_44x62mm", "iso-b9", "ISOB9", 44, 62),
_PWG_MEDIA_MM("iso_b8_62x88mm", "iso-b8", "ISOB8", 62, 88),
_PWG_MEDIA_MM("iso_b7_88x125mm", "iso-b7", "ISOB7", 88, 125),
_PWG_MEDIA_MM("iso_b6_125x176mm", "iso-b6", "ISOB6", 125, 176),
_PWG_MEDIA_MM("iso_b6c4_125x324mm", NULL, NULL, 125, 324),
_PWG_MEDIA_MM("iso_b5_176x250mm", "iso-b5", "ISOB5", 176, 250),
_PWG_MEDIA_MM("iso_b5-extra_201x276mm", NULL, "ISOB5Extra", 201, 276),
_PWG_MEDIA_MM("iso_b4_250x353mm", "iso-b4", "ISOB4", 250, 353),
_PWG_MEDIA_MM("iso_b3_353x500mm", "iso-b3", "ISOB3", 353, 500),
_PWG_MEDIA_MM("iso_b2_500x707mm", "iso-b2", "ISOB2", 500, 707),
_PWG_MEDIA_MM("iso_b1_707x1000mm", "iso-b1", "ISOB1", 707, 1000),
_PWG_MEDIA_MM("iso_b0_1000x1414mm", "iso-b0", "ISOB0", 1000, 1414),
_PWG_MEDIA_MM("iso_c10_28x40mm", "iso-c10", NULL, 28, 40),
_PWG_MEDIA_MM("iso_c9_40x57mm", "iso-c9", NULL, 40, 57),
_PWG_MEDIA_MM("iso_c8_57x81mm", "iso-c8", NULL, 57, 81),
_PWG_MEDIA_MM("iso_c7_81x114mm", "iso-c7", "EnvC7", 81, 114),
_PWG_MEDIA_MM("iso_c7c6_81x162mm", NULL, NULL, 81, 162),
_PWG_MEDIA_MM("iso_c6_114x162mm", "iso-c6", "EnvC6", 114, 162),
_PWG_MEDIA_MM("iso_c6c5_114x229mm", NULL, "EnvC65", 114, 229),
_PWG_MEDIA_MM("iso_c5_162x229mm", "iso-c5", "EnvC5", 162, 229),
_PWG_MEDIA_MM("iso_c4_229x324mm", "iso-c4", "EnvC4", 229, 324),
_PWG_MEDIA_MM("iso_c3_324x458mm", "iso-c3", "EnvC3", 324, 458),
_PWG_MEDIA_MM("iso_c2_458x648mm", "iso-c2", "EnvC2", 458, 648),
_PWG_MEDIA_MM("iso_c1_648x917mm", "iso-c1", "EnvC1", 648, 917),
_PWG_MEDIA_MM("iso_c0_917x1297mm", "iso-c0", "EnvC0", 917, 1297),
_PWG_MEDIA_MM("iso_dl_110x220mm", "iso-designated", "EnvDL", 110, 220),
_PWG_MEDIA_MM("iso_ra2_430x610mm", "iso-ra2", NULL, 430, 610),
_PWG_MEDIA_MM("iso_sra2_450x640mm", "iso-sra2", NULL, 450, 640),
_PWG_MEDIA_MM("iso_ra1_610x860mm", "iso-ra1", NULL, 610, 860),
_PWG_MEDIA_MM("iso_sra1_640x900mm", "iso-sra1", NULL, 640, 900),
_PWG_MEDIA_MM("iso_ra0_860x1220mm", "iso-ra0", NULL, 860, 1220),
_PWG_MEDIA_MM("iso_sra0_900x1280mm", "iso-sra0", NULL, 900, 1280),
/* Japanese Standard Sheet Media Sizes */
_PWG_MEDIA_MM("jis_b10_32x45mm", "jis-b10", "B10", 32, 45),
_PWG_MEDIA_MM("jis_b9_45x64mm", "jis-b9", "B9", 45, 64),
_PWG_MEDIA_MM("jis_b8_64x91mm", "jis-b8", "B8", 64, 91),
_PWG_MEDIA_MM("jis_b7_91x128mm", "jis-b7", "B7", 91, 128),
_PWG_MEDIA_MM("jis_b6_128x182mm", "jis-b6", "B6", 128, 182),
_PWG_MEDIA_MM("jis_b5_182x257mm", "jis-b5", "B5", 182, 257),
_PWG_MEDIA_MM("jis_b4_257x364mm", "jis-b4", "B4", 257, 364),
_PWG_MEDIA_MM("jis_b3_364x515mm", "jis-b3", "B3", 364, 515),
_PWG_MEDIA_MM("jis_b2_515x728mm", "jis-b2", "B2", 515, 728),
_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, NULL, 216, 330),
_PWG_MEDIA_MM("jpn_chou4_90x205mm", NULL, "EnvChou4", 90, 205),
_PWG_MEDIA_MM("jpn_hagaki_100x148mm", NULL, "Postcard", 100, 148),
_PWG_MEDIA_MM("jpn_you4_105x235mm", NULL, "EnvYou4", 105, 235),
_PWG_MEDIA_MM("jpn_you6_98x190mm", NULL, "EnvYou6", 98, 190),
_PWG_MEDIA_MM("jpn_chou2_111.1x146mm", NULL, NULL, 111.1, 146),
_PWG_MEDIA_MM("jpn_chou3_120x235mm", NULL, "EnvChou3", 120, 235),
_PWG_MEDIA_MM("jpn_oufuku_148x200mm", NULL, "DoublePostcardRotated", 148, 200),
_PWG_MEDIA_MM("jpn_kahu_240x322.1mm", NULL, NULL, 240, 322.1),
_PWG_MEDIA_MM("jpn_kaku2_240x332mm", NULL, "EnvKaku2", 240, 332),
/* Chinese Standard Sheet Media Sizes */
_PWG_MEDIA_MM("prc_32k_97x151mm", NULL, "PRC32K", 97, 151),
_PWG_MEDIA_MM("prc_1_102x165mm", NULL, "EnvPRC1", 102, 165),
_PWG_MEDIA_MM("prc_2_102x176mm", NULL, "EnvPRC2", 102, 176),
_PWG_MEDIA_MM("prc_4_110x208mm", NULL, "EnvPRC4", 110, 208),
_PWG_MEDIA_MM("prc_5_110x220mm", NULL, "EnvPRC5", 110, 220),
_PWG_MEDIA_MM("prc_8_120x309mm", NULL, "EnvPRC8", 120, 309),
_PWG_MEDIA_MM("prc_6_120x320mm", NULL, NULL, 120, 320),
_PWG_MEDIA_MM("prc_3_125x176mm", NULL, "EnvPRC3", 125, 176),
_PWG_MEDIA_MM("prc_16k_146x215mm", NULL, "PRC16K", 146, 215),
_PWG_MEDIA_MM("prc_7_160x230mm", NULL, "EnvPRC7", 160, 230),
_PWG_MEDIA_MM("om_juuro-ku-kai_198x275mm", NULL, NULL, 198, 275),
_PWG_MEDIA_MM("om_pa-kai_267x389mm", NULL, NULL, 267, 389),
_PWG_MEDIA_MM("om_dai-pa-kai_275x395mm", NULL, NULL, 275, 395),
_PWG_MEDIA_MM("prc_10_324x458mm", NULL, "EnvPRC10", 324, 458),
/* Other English Standard Sheet Media Sizes */
_PWG_MEDIA_IN("oe_photo-l_3.5x5in", NULL, "3.5x5", 3.5, 5),
/* Other Metric Standard Sheet Media Sizes */
_PWG_MEDIA_MM("om_small-photo_100x150mm", NULL, "om_small-photo", 100, 150),
_PWG_MEDIA_MM("om_italian_110x230mm", NULL, "EnvItalian", 110, 230),
_PWG_MEDIA_MM("om_postfix_114x229mm", NULL, NULL, 114, 229),
_PWG_MEDIA_MM("om_large-photo_200x300", NULL, "om_large-photo", 200, 300),
_PWG_MEDIA_MM("om_folio_210x330mm", "folio", "Folio", 210, 330),
_PWG_MEDIA_MM("om_folio-sp_215x315mm", NULL, "FolioSP", 215, 315),
_PWG_MEDIA_MM("om_invite_220x220mm", NULL, "EnvInvite", 220, 220)
};
/*
* '_pwgFormatInches()' - Convert and format PWG units as inches.
*/
char * /* O - String */
_pwgFormatInches(char *buf, /* I - Buffer */
size_t bufsize, /* I - Size of buffer */
int val) /* I - Value in hundredths of millimeters */
{
int thousandths, /* Thousandths of inches */
integer, /* Integer portion */
fraction; /* Fractional portion */
/*
* Convert hundredths of millimeters to thousandths of inches and round to
* the nearest thousandth.
*/
thousandths = (val * 1000 + 1270) / 2540;
integer = thousandths / 1000;
fraction = thousandths % 1000;
/*
* Format as a pair of integers (avoids locale stuff), avoiding trailing
* zeros...
*/
if (fraction == 0)
snprintf(buf, bufsize, "%d", integer);
else if (fraction % 10)
snprintf(buf, bufsize, "%d.%03d", integer, fraction);
else if (fraction % 100)
snprintf(buf, bufsize, "%d.%02d", integer, fraction / 10);
else
snprintf(buf, bufsize, "%d.%01d", integer, fraction / 100);
return (buf);
}
/*
* '_pwgFormatMillimeters()' - Convert and format PWG units as millimeters.
*/
char * /* O - String */
_pwgFormatMillimeters(char *buf, /* I - Buffer */
size_t bufsize, /* I - Size of buffer */
int val) /* I - Value in hundredths of millimeters */
{
int integer, /* Integer portion */
fraction; /* Fractional portion */
/*
* Convert hundredths of millimeters to integer and fractional portions.
*/
integer = val / 100;
fraction = val % 100;
/*
* Format as a pair of integers (avoids locale stuff), avoiding trailing
* zeros...
*/
if (fraction == 0)
snprintf(buf, bufsize, "%d", integer);
else if (fraction % 10)
snprintf(buf, bufsize, "%d.%02d", integer, fraction);
else
snprintf(buf, bufsize, "%d.%01d", integer, fraction / 10);
return (buf);
}
/*
* '_pwgGenerateSize()' - Generate a PWG size keyword.
*/
void
_pwgGenerateSize(char *keyword, /* I - Keyword buffer */
size_t keysize, /* I - Size of keyword buffer */
const char *prefix, /* I - Prefix for PWG size or NULL */
const char *name, /* I - Size name or NULL */
int width, /* I - Width of page in 2540ths */
int length) /* I - Length of page in 2540ths */
{
const char *units; /* Units to report */
char usize[12 + 1 + 12 + 3], /* Unit size: NNNNNNNNNNNNxNNNNNNNNNNNNuu */
*uptr; /* Pointer into unit size */
char *(*format)(char *, size_t, int);
/* Formatting function */
if ((width % 635) == 0 && (length % 635) == 0)
{
/*
* Use inches since the size is a multiple of 1/4 inch.
*/
units = "in";
format = _pwgFormatInches;
if (!prefix)
prefix = "oe";
}
else
{
/*
* Use millimeters since the size is not a multiple of 1/4 inch.
*/
units = "mm";
format = _pwgFormatMillimeters;
if (!prefix)
prefix = "om";
}
uptr = usize;
(*format)(uptr, sizeof(usize) - (uptr - usize), width);
uptr += strlen(uptr);
*uptr++ = 'x';
(*format)(uptr, sizeof(usize) - (uptr - usize), length);
uptr += strlen(uptr);
/*
* Safe because usize can hold up to 12 + 1 + 12 + 4 bytes.
*/
memcpy(uptr, units, 3);
if (!name)
name = usize;
/*
* Format the name...
*/
snprintf(keyword, keysize, "%s_%s_%s", prefix, name, usize);
}
/*
* '_pwgInitSize()' - Initialize a PWG size using IPP job template attributes.
*/
int /* O - 1 if size was initialize, 0 otherwise */
_pwgInitSize(_pwg_size_t *size, /* I - Size to initialize */
ipp_t *job, /* I - Job template attributes */
int *margins_set) /* O - 1 if margins were set, 0 otherwise */
{
ipp_attribute_t *media, /* media attribute */
*media_bottom_margin, /* media-bottom-margin member attribute */
*media_col, /* media-col attribute */
*media_left_margin, /* media-left-margin member attribute */
*media_right_margin, /* media-right-margin member attribute */
*media_size, /* media-size member attribute */
*media_top_margin, /* media-top-margin member attribute */
*x_dimension, /* x-dimension member attribute */
*y_dimension; /* y-dimension member attribute */
_pwg_media_t *pwg; /* PWG media value */
/*
* Range check input...
*/
if (!size || !job || !margins_set)
return (0);
/*
* Look for media-col and then media...
*/
memset(size, 0, sizeof(_pwg_size_t));
*margins_set = 0;
if ((media_col = ippFindAttribute(job, "media-col",
IPP_TAG_BEGIN_COLLECTION)) != NULL)
{
/*
* Got media-col, look for media-size member attribute...
*/
if ((media_size = ippFindAttribute(media_col->values[0].collection,
"media-size",
IPP_TAG_BEGIN_COLLECTION)) != NULL)
{
/*
* Got media-size, look for x-dimension and y-dimension member
* attributes...
*/
x_dimension = ippFindAttribute(media_size->values[0].collection,
"x-dimension", IPP_TAG_INTEGER);
y_dimension = ippFindAttribute(media_size->values[0].collection,
"y-dimension", IPP_TAG_INTEGER);
if (x_dimension && y_dimension)
{
size->width = x_dimension->values[0].integer;
size->length = y_dimension->values[0].integer;
}
else if (!x_dimension)
{
_cupsSetError(IPP_INTERNAL_ERROR,
_("Missing x-dimension in media-size."), 1);
return (0);
}
else if (!y_dimension)
{
_cupsSetError(IPP_INTERNAL_ERROR,
_("Missing y-dimension in media-size."), 1);
return (0);
}
}
else
{
_cupsSetError(IPP_INTERNAL_ERROR, _("Missing media-size in media-col."),
1);
return (0);
}
/* media-*-margin */
media_bottom_margin = ippFindAttribute(media_col->values[0].collection,
"media-bottom-margin",
IPP_TAG_INTEGER);
media_left_margin = ippFindAttribute(media_col->values[0].collection,
"media-left-margin",
IPP_TAG_INTEGER);
media_right_margin = ippFindAttribute(media_col->values[0].collection,
"media-right-margin",
IPP_TAG_INTEGER);
media_top_margin = ippFindAttribute(media_col->values[0].collection,
"media-top-margin",
IPP_TAG_INTEGER);
if (media_bottom_margin && media_left_margin && media_right_margin &&
media_top_margin)
{
*margins_set = 1;
size->bottom = media_bottom_margin->values[0].integer;
size->left = media_left_margin->values[0].integer;
size->right = media_right_margin->values[0].integer;
size->top = media_top_margin->values[0].integer;
}
}
else
{
if ((media = ippFindAttribute(job, "media", IPP_TAG_NAME)) == NULL)
if ((media = ippFindAttribute(job, "media", IPP_TAG_KEYWORD)) == NULL)
if ((media = ippFindAttribute(job, "PageSize", IPP_TAG_NAME)) == NULL)
media = ippFindAttribute(job, "PageRegion", IPP_TAG_NAME);
if (media)
{
const char *name = media->values[0].string.text;
/* Name string */
if ((pwg = _pwgMediaForPWG(name)) == NULL)
{
/*
* Not a PWG name, try a legacy name...
*/
if ((pwg = _pwgMediaForLegacy(name)) == NULL)
{
/*
* Not a legacy name, try a PPD name...
*/
const char *suffix; /* Suffix on media string */
pwg = _pwgMediaForPPD(name);
if (pwg &&
(suffix = name + strlen(name) - 10 /* .FullBleed */) > name &&
!_cups_strcasecmp(suffix, ".FullBleed"))
{
/*
* Indicate that margins are set with the default values of 0.
*/
*margins_set = 1;
}
}
}
if (pwg)
{
size->width = pwg->width;
size->length = pwg->length;
}
else
{
_cupsSetError(IPP_INTERNAL_ERROR, _("Unsupported media value."), 1);
return (0);
}
}
else
{
_cupsSetError(IPP_INTERNAL_ERROR, _("Missing media or media-col."), 1);
return (0);
}
}
return (1);
}
/*
* '_pwgMediaForLegacy()' - Find a PWG media size by ISO/IPP legacy name.
*/
_pwg_media_t * /* O - Matching size or NULL */
_pwgMediaForLegacy(
const char *legacy) /* I - Legacy size name */
{
_pwg_media_t key; /* Search key */
_cups_globals_t *cg = _cupsGlobals(); /* Global data */
/*
* Range check input...
*/
if (!legacy)
return (NULL);
/*
* Build the lookup table for PWG names as needed...
*/
if (!cg->leg_size_lut)
{
int i; /* Looping var */
_pwg_media_t *size; /* Current size */
cg->leg_size_lut = cupsArrayNew((cups_array_func_t)pwg_compare_legacy,
NULL);
for (i = (int)(sizeof(cups_pwg_media) / sizeof(cups_pwg_media[0])),
size = (_pwg_media_t *)cups_pwg_media;
i > 0;
i --, size ++)
if (size->legacy)
cupsArrayAdd(cg->leg_size_lut, size);
}
/*
* Lookup the name...
*/
key.legacy = legacy;
return ((_pwg_media_t *)cupsArrayFind(cg->leg_size_lut, &key));
}
/*
* '_pwgMediaForPPD()' - Find a PWG media size by Adobe PPD name.
*/
_pwg_media_t * /* O - Matching size or NULL */
_pwgMediaForPPD(const char *ppd) /* I - PPD size name */
{
_pwg_media_t key, /* Search key */
*size; /* Matching size */
_cups_globals_t *cg = _cupsGlobals(); /* Global data */
/*
* Range check input...
*/
if (!ppd)
return (NULL);
/*
* Build the lookup table for PWG names as needed...
*/
if (!cg->ppd_size_lut)
{
int i; /* Looping var */
cg->ppd_size_lut = cupsArrayNew((cups_array_func_t)pwg_compare_ppd, NULL);
for (i = (int)(sizeof(cups_pwg_media) / sizeof(cups_pwg_media[0])),
size = (_pwg_media_t *)cups_pwg_media;
i > 0;
i --, size ++)
if (size->ppd)
cupsArrayAdd(cg->ppd_size_lut, size);
}
/*
* Lookup the name...
*/
key.ppd = ppd;
if ((size = (_pwg_media_t *)cupsArrayFind(cg->ppd_size_lut, &key)) == NULL)
{
/*
* See if the name is of the form:
*
* [Custom.]WIDTHxLENGTH[.FullBleed] - Size in points/inches [borderless]
* [Custom.]WIDTHxLENGTHcm[.FullBleed] - Size in centimeters [borderless]
* [Custom.]WIDTHxLENGTHft[.FullBleed] - Size in feet [borderless]
* [Custom.]WIDTHxLENGTHin[.FullBleed] - Size in inches [borderless]
* [Custom.]WIDTHxLENGTHm[.FullBleed] - Size in meters [borderless]
* [Custom.]WIDTHxLENGTHmm[.FullBleed] - Size in millimeters [borderless]
* [Custom.]WIDTHxLENGTHpt[.FullBleed] - Size in points [borderless]
*/
double w, l, /* Width and length of page */
factor; /* Unit scaling factor */
char *ptr; /* Pointer into name */
struct lconv *loc; /* Locale data */
int custom; /* Custom page size? */
if (!_cups_strncasecmp(ppd, "Custom.", 7))
{
custom = 1;
factor = 2540.0 / 72.0;
ptr = (char *)ppd + 7;
}
else
{
custom = 0;
factor = 2540.0;
ptr = (char *)ppd;
}
loc = localeconv();
w = _cupsStrScand(ptr, &ptr, loc);
if (ptr && ptr > ppd && *ptr == 'x')
{
l = _cupsStrScand(ptr + 1, &ptr, loc);
if (ptr &&
(!*ptr ||
!_cups_strcasecmp(ptr, "FullBleed") ||
!_cups_strcasecmp(ptr, ".FullBleed") ||
!_cups_strcasecmp(ptr, "cm") ||
!_cups_strcasecmp(ptr, "cm.FullBleed") ||
!_cups_strcasecmp(ptr, "ft") ||
!_cups_strcasecmp(ptr, "ft.FullBleed") ||
!_cups_strcasecmp(ptr, "in") ||
!_cups_strcasecmp(ptr, "in.FullBleed") ||
!_cups_strcasecmp(ptr, "m") ||
!_cups_strcasecmp(ptr, "m.FullBleed") ||
!_cups_strcasecmp(ptr, "mm") ||
!_cups_strcasecmp(ptr, "mm.FullBleed") ||
!_cups_strcasecmp(ptr, "pt") ||
!_cups_strcasecmp(ptr, "pt.FullBleed")))
{
size = &(cg->pwg_media);
if (!_cups_strncasecmp(ptr, "cm", 2))
factor = 1000.0;
else if (!_cups_strncasecmp(ptr, "ft", 2))
factor = 2540.0 * 12.0;
else if (!_cups_strncasecmp(ptr, "in", 2))
factor = 2540.0;
else if (!_cups_strncasecmp(ptr, "mm", 2))
factor = 100.0;
else if (*ptr == 'm' || *ptr == 'M')
factor = 100000.0;
else if (!_cups_strncasecmp(ptr, "pt", 2))
factor = 2540.0 / 72.0;
/*
* Not a standard size; convert it to a PWG custom name of the form:
*
* [oe|om]_WIDTHxHEIGHTuu_WIDTHxHEIGHTuu
*/
size->width = (int)(w * factor);
size->length = (int)(l * factor);
size->pwg = cg->pwg_name;
_pwgGenerateSize(cg->pwg_name, sizeof(cg->pwg_name),
custom ? "custom" : NULL, custom ? ppd + 7 : NULL,
size->width, size->length);
}
}
}
return (size);
}
/*
* '_pwgMediaForPWG()' - Find a PWG media size by 5101.1 self-describing name.
*/
_pwg_media_t * /* O - Matching size or NULL */
_pwgMediaForPWG(const char *pwg) /* I - PWG size name */
{
char *ptr; /* Pointer into name */
_pwg_media_t key, /* Search key */
*size; /* Matching size */
_cups_globals_t *cg = _cupsGlobals(); /* Global data */
/*
* Range check input...
*/
if (!pwg)
return (NULL);
/*
* Build the lookup table for PWG names as needed...
*/
if (!cg->pwg_size_lut)
{
int i; /* Looping var */
cg->pwg_size_lut = cupsArrayNew((cups_array_func_t)pwg_compare_pwg, NULL);
for (i = (int)(sizeof(cups_pwg_media) / sizeof(cups_pwg_media[0])),
size = (_pwg_media_t *)cups_pwg_media;
i > 0;
i --, size ++)
cupsArrayAdd(cg->pwg_size_lut, size);
}
/*
* Lookup the name...
*/
key.pwg = pwg;
if ((size = (_pwg_media_t *)cupsArrayFind(cg->pwg_size_lut, &key)) == NULL &&
(ptr = (char *)strchr(pwg, '_')) != NULL &&
(ptr = (char *)strchr(ptr + 1, '_')) != NULL)
{
/*
* Try decoding the self-describing name of the form:
*
* class_name_WWWxHHHin
* class_name_WWWxHHHmm
*/
double w, l; /* Width and length of page */
struct lconv *loc; /* Locale data */
ptr ++;
loc = localeconv();
w = _cupsStrScand(ptr, &ptr, loc);
if (ptr && *ptr == 'x')
{
l = _cupsStrScand(ptr + 1, &ptr, loc);
if (ptr && (!strcmp(ptr, "in") || !strcmp(ptr, "mm")))
{
size = &(cg->pwg_media);
if (!strcmp(ptr, "mm"))
{
size->width = (int)(w * 100 + 0.5);
size->length = (int)(l * 100 + 0.5);
}
else
{
size->width = (int)(w * 2540 + 0.5);
size->length = (int)(l * 2540 + 0.5);
}
strlcpy(cg->pwg_name, pwg, sizeof(cg->pwg_name));
size->pwg = cg->pwg_name;
}
}
}
return (size);
}
/*
* '_pwgMediaForSize()' - Get the PWG media name for a given size.
*/
_pwg_media_t * /* O - PWG media name */
_pwgMediaForSize(int width, /* I - Width in 2540ths */
int length) /* I - Length in 2540ths */
{
int i; /* Looping var */
_pwg_media_t *media, /* Current media */
*best_media = NULL; /* Best match */
int dw, dl, /* Difference in width and length */
best_dw = 999, /* Best difference in width and length */
best_dl = 999;
_cups_globals_t *cg = _cupsGlobals(); /* Global data */
/*
* Range check input...
*/
if (width <= 0 || length <= 0)
return (NULL);
/*
* Look for a standard size...
*/
for (i = (int)(sizeof(cups_pwg_media) / sizeof(cups_pwg_media[0])),
media = (_pwg_media_t *)cups_pwg_media;
i > 0;
i --, media ++)
{
/*
* Adobe uses a size matching algorithm with an epsilon of 5 points, which
* is just about 176/2540ths...
*/
dw = abs(media->width - width);
dl = abs(media->length - length);
if (!dw && !dl)
return (media);
else if (dw < 176 && dl < 176)
{
if (dw <= best_dw && dl <= best_dl)
{
best_media = media;
best_dw = dw;
best_dl = dl;
}
}
}
if (best_media)
return (best_media);
/*
* Not a standard size; convert it to a PWG custom name of the form:
*
* custom_WIDTHxHEIGHTuu_WIDTHxHEIGHTuu
*/
_pwgGenerateSize(cg->pwg_name, sizeof(cg->pwg_name), "custom", NULL, width,
length);
cg->pwg_media.pwg = cg->pwg_name;
cg->pwg_media.width = width;
cg->pwg_media.length = length;
return (&(cg->pwg_media));
}
/*
* 'pwg_compare_legacy()' - Compare two sizes using the legacy names.
*/
static int /* O - Result of comparison */
pwg_compare_legacy(_pwg_media_t *a, /* I - First size */
_pwg_media_t *b) /* I - Second size */
{
return (strcmp(a->legacy, b->legacy));
}
/*
* 'pwg_compare_ppd()' - Compare two sizes using the PPD names.
*/
static int /* O - Result of comparison */
pwg_compare_ppd(_pwg_media_t *a, /* I - First size */
_pwg_media_t *b) /* I - Second size */
{
return (strcmp(a->ppd, b->ppd));
}
/*
* 'pwg_compare_pwg()' - Compare two sizes using the PWG names.
*/
static int /* O - Result of comparison */
pwg_compare_pwg(_pwg_media_t *a, /* I - First size */
_pwg_media_t *b) /* I - Second size */
{
return (strcmp(a->pwg, b->pwg));
}
/*
* End of "$Id: pwg-media.c 10979 2013-05-13 17:39:19Z msweet $".
*/

104
cups/pwg-private.h Normal file
View File

@@ -0,0 +1,104 @@
/*
* "$Id: pwg-private.h 3833 2012-05-23 22:51:18Z msweet $"
*
* Private PWG media API definitions for CUPS.
*
* Copyright 2009-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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*/
#ifndef _CUPS_PWG_PRIVATE_H_
# define _CUPS_PWG_PRIVATE_H_
/*
* Include necessary headers...
*/
# include <cups/cups.h>
/*
* C++ magic...
*/
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/*
* Macros...
*/
/* Convert from points to 2540ths */
# define _PWG_FROMPTS(n) (int)(((n) * 2540 + 36) / 72)
/* Convert from 2540ths to points */
# define _PWG_TOPTS(n) ((n) * 72.0 / 2540.0)
/*
* Types and structures...
*/
typedef struct _pwg_map_s /**** Map element - PPD to/from PWG */
{
char *pwg, /* PWG media keyword */
*ppd; /* PPD option keyword */
} _pwg_map_t;
typedef struct _pwg_media_s /**** Common media size data ****/
{
const char *pwg, /* PWG 5101.1 "self describing" name */
*legacy, /* IPP/ISO legacy name */
*ppd; /* Standard Adobe PPD name */
int width, /* Width in 2540ths */
length; /* Length in 2540ths */
} _pwg_media_t;
typedef struct _pwg_size_s /**** Size element - PPD to/from PWG */
{
_pwg_map_t map; /* Map element */
int width, /* Width in 2540ths */
length, /* Length in 2540ths */
left, /* Left margin in 2540ths */
bottom, /* Bottom margin in 2540ths */
right, /* Right margin in 2540ths */
top; /* Top margin in 2540ths */
} _pwg_size_t;
/*
* Functions...
*/
extern char *_pwgFormatInches(char *buf, size_t bufsize, int val);
extern char *_pwgFormatMillimeters(char *buf, size_t bufsize,
int val);
extern void _pwgGenerateSize(char *keyword, size_t keysize,
const char *prefix,
const char *name,
int width, int length);
extern int _pwgInitSize(_pwg_size_t *size, ipp_t *job,
int *margins_set);
extern _pwg_media_t *_pwgMediaForLegacy(const char *legacy);
extern _pwg_media_t *_pwgMediaForPPD(const char *ppd);
extern _pwg_media_t *_pwgMediaForPWG(const char *pwg);
extern _pwg_media_t *_pwgMediaForSize(int width, int length);
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_PWG_PRIVATE_H_ */
/*
* End of "$Id: pwg-private.h 3833 2012-05-23 22:51:18Z msweet $".
*/

66
cups/raster-private.h Normal file
View File

@@ -0,0 +1,66 @@
/*
* "$Id: raster-private.h 3794 2012-04-23 22:44:16Z msweet $"
*
* Private image library definitions for CUPS.
*
* Copyright 2007-2011 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*/
#ifndef _CUPS_RASTER_PRIVATE_H_
# define _CUPS_RASTER_PRIVATE_H_
/*
* Include necessary headers...
*/
# include "raster.h"
# include <cups/cups.h>
# include <cups/debug-private.h>
# include <cups/string-private.h>
# ifdef WIN32
# include <io.h>
# include <winsock2.h> /* for htonl() definition */
# else
# include <unistd.h>
# include <fcntl.h>
# endif /* WIN32 */
/*
* min/max macros...
*/
# ifndef max
# define max(a,b) ((a) > (b) ? (a) : (b))
# endif /* !max */
# ifndef min
# define min(a,b) ((a) < (b) ? (a) : (b))
# endif /* !min */
/*
* 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);
#endif /* !_CUPS_RASTER_PRIVATE_H_ */
/*
* End of "$Id: raster-private.h 3794 2012-04-23 22:44:16Z msweet $".
*/

405
cups/raster.h Normal file
View File

@@ -0,0 +1,405 @@
/*
* "$Id: raster.h 3794 2012-04-23 22:44:16Z msweet $"
*
* Raster file definitions for CUPS.
*
* Copyright 2007-2012 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*/
#ifndef _CUPS_RASTER_H_
# define _CUPS_RASTER_H_
/*
* Include necessary headers...
*/
# include "cups.h"
# include "ppd.h"
# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */
/*
* Every non-PostScript printer driver that supports raster images
* should use the application/vnd.cups-raster image file format.
* Since both the PostScript RIP (pstoraster, based on GNU/GPL
* Ghostscript) and Image RIP (imagetoraster, located in the filter
* directory) use it, using this format saves you a lot of work.
* Also, the PostScript RIP passes any printer options that are in
* a PS file to your driver this way as well...
*/
/*
* Constants...
*/
# define CUPS_RASTER_SYNC 0x52615333 /* RaS3 */
# define CUPS_RASTER_REVSYNC 0x33536152 /* 3SaR */
# define CUPS_RASTER_SYNCv1 0x52615374 /* RaSt */
# define CUPS_RASTER_REVSYNCv1 0x74536152 /* tSaR */
# define CUPS_RASTER_SYNCv2 0x52615332 /* RaS2 */
# define CUPS_RASTER_REVSYNCv2 0x32536152 /* 2SaR */
# define CUPS_RASTER_SYNC_PWG CUPS_RASTER_SYNCv2
/*
* The following definition can be used to determine if the
* colorimetric colorspaces (CIEXYZ, CIELAB, and ICCn) are
* defined...
*/
# define CUPS_RASTER_HAVE_COLORIMETRIC 1
/*
* The following definition can be used to determine if the
* device colorspaces (DEVICEn) are defined...
*/
# define CUPS_RASTER_HAVE_DEVICE 1
/*
* The following definition can be used to determine if PWG Raster is supported.
*/
# define CUPS_RASTER_HAVE_PWGRASTER 1
/*
* Types...
*/
typedef enum cups_adv_e /**** AdvanceMedia attribute values ****/
{
CUPS_ADVANCE_NONE = 0, /* Never advance the roll */
CUPS_ADVANCE_FILE = 1, /* Advance the roll after this file */
CUPS_ADVANCE_JOB = 2, /* Advance the roll after this job */
CUPS_ADVANCE_SET = 3, /* Advance the roll after this set */
CUPS_ADVANCE_PAGE = 4 /* Advance the roll after this page */
} cups_adv_t;
typedef enum cups_bool_e /**** Boolean type ****/
{
CUPS_FALSE = 0, /* Logical false */
CUPS_TRUE = 1 /* Logical true */
} cups_bool_t;
typedef enum cups_cspace_e /**** cupsColorSpace attribute values ****/
{
CUPS_CSPACE_W = 0, /* Luminance (DeviceGray, gamma 2.2 by default) */
CUPS_CSPACE_RGB = 1, /* Red, green, blue (DeviceRGB, sRGB by default) */
CUPS_CSPACE_RGBA = 2, /* Red, green, blue, alpha (DeviceRGB, sRGB by default) */
CUPS_CSPACE_K = 3, /* Black (DeviceK) */
CUPS_CSPACE_CMY = 4, /* Cyan, magenta, yellow (DeviceCMY) */
CUPS_CSPACE_YMC = 5, /* Yellow, magenta, cyan @deprecated@ */
CUPS_CSPACE_CMYK = 6, /* Cyan, magenta, yellow, black (DeviceCMYK) */
CUPS_CSPACE_YMCK = 7, /* Yellow, magenta, cyan, black @deprecated@ */
CUPS_CSPACE_KCMY = 8, /* Black, cyan, magenta, yellow @deprecated@ */
CUPS_CSPACE_KCMYcm = 9, /* Black, cyan, magenta, yellow, light-cyan, light-magenta @deprecated@ */
CUPS_CSPACE_GMCK = 10, /* Gold, magenta, yellow, black @deprecated@ */
CUPS_CSPACE_GMCS = 11, /* Gold, magenta, yellow, silver @deprecated@ */
CUPS_CSPACE_WHITE = 12, /* White ink (as black) @deprecated@ */
CUPS_CSPACE_GOLD = 13, /* Gold foil @deprecated@ */
CUPS_CSPACE_SILVER = 14, /* Silver foil @deprecated@ */
CUPS_CSPACE_CIEXYZ = 15, /* CIE XYZ @since CUPS 1.1.19/OS X 10.3@ */
CUPS_CSPACE_CIELab = 16, /* CIE Lab @since CUPS 1.1.19/OS X 10.3@ */
CUPS_CSPACE_RGBW = 17, /* Red, green, blue, white (DeviceRGB, sRGB by default) @since CUPS 1.2/OS X 10.5@ */
CUPS_CSPACE_SW = 18, /* Luminance (gamma 2.2) @since CUPS 1.4.5@ */
CUPS_CSPACE_SRGB = 19, /* Red, green, blue (sRGB) @since CUPS 1.4.5@ */
CUPS_CSPACE_ADOBERGB = 20, /* Red, green, blue (Adobe RGB) @since CUPS 1.4.5@ */
CUPS_CSPACE_ICC1 = 32, /* ICC-based, 1 color @since CUPS 1.1.19/OS X 10.3@ */
CUPS_CSPACE_ICC2 = 33, /* ICC-based, 2 colors @since CUPS 1.1.19/OS X 10.3@ */
CUPS_CSPACE_ICC3 = 34, /* ICC-based, 3 colors @since CUPS 1.1.19/OS X 10.3@ */
CUPS_CSPACE_ICC4 = 35, /* ICC-based, 4 colors @since CUPS 1.1.19/OS X 10.3@ */
CUPS_CSPACE_ICC5 = 36, /* ICC-based, 5 colors @since CUPS 1.1.19/OS X 10.3@ */
CUPS_CSPACE_ICC6 = 37, /* ICC-based, 6 colors @since CUPS 1.1.19/OS X 10.3@ */
CUPS_CSPACE_ICC7 = 38, /* ICC-based, 7 colors @since CUPS 1.1.19/OS X 10.3@ */
CUPS_CSPACE_ICC8 = 39, /* ICC-based, 8 colors @since CUPS 1.1.19/OS X 10.3@ */
CUPS_CSPACE_ICC9 = 40, /* ICC-based, 9 colors @since CUPS 1.1.19/OS X 10.3@ */
CUPS_CSPACE_ICCA = 41, /* ICC-based, 10 colors @since CUPS 1.1.19/OS X 10.3@ */
CUPS_CSPACE_ICCB = 42, /* ICC-based, 11 colors @since CUPS 1.1.19/OS X 10.3@ */
CUPS_CSPACE_ICCC = 43, /* ICC-based, 12 colors @since CUPS 1.1.19/OS X 10.3@ */
CUPS_CSPACE_ICCD = 44, /* ICC-based, 13 colors @since CUPS 1.1.19/OS X 10.3@ */
CUPS_CSPACE_ICCE = 45, /* ICC-based, 14 colors @since CUPS 1.1.19/OS X 10.3@ */
CUPS_CSPACE_ICCF = 46, /* ICC-based, 15 colors @since CUPS 1.1.19/OS X 10.3@ */
CUPS_CSPACE_DEVICE1 = 48, /* DeviceN, 1 color @since CUPS 1.4.5@ */
CUPS_CSPACE_DEVICE2 = 49, /* DeviceN, 2 colors @since CUPS 1.4.5@ */
CUPS_CSPACE_DEVICE3 = 50, /* DeviceN, 3 colors @since CUPS 1.4.5@ */
CUPS_CSPACE_DEVICE4 = 51, /* DeviceN, 4 colors @since CUPS 1.4.5@ */
CUPS_CSPACE_DEVICE5 = 52, /* DeviceN, 5 colors @since CUPS 1.4.5@ */
CUPS_CSPACE_DEVICE6 = 53, /* DeviceN, 6 colors @since CUPS 1.4.5@ */
CUPS_CSPACE_DEVICE7 = 54, /* DeviceN, 7 colors @since CUPS 1.4.5@ */
CUPS_CSPACE_DEVICE8 = 55, /* DeviceN, 8 colors @since CUPS 1.4.5@ */
CUPS_CSPACE_DEVICE9 = 56, /* DeviceN, 9 colors @since CUPS 1.4.5@ */
CUPS_CSPACE_DEVICEA = 57, /* DeviceN, 10 colors @since CUPS 1.4.5@ */
CUPS_CSPACE_DEVICEB = 58, /* DeviceN, 11 colors @since CUPS 1.4.5@ */
CUPS_CSPACE_DEVICEC = 59, /* DeviceN, 12 colors @since CUPS 1.4.5@ */
CUPS_CSPACE_DEVICED = 60, /* DeviceN, 13 colors @since CUPS 1.4.5@ */
CUPS_CSPACE_DEVICEE = 61, /* DeviceN, 14 colors @since CUPS 1.4.5@ */
CUPS_CSPACE_DEVICEF = 62 /* DeviceN, 15 colors @since CUPS 1.4.5@ */
} cups_cspace_t;
typedef enum cups_cut_e /**** CutMedia attribute values ****/
{
CUPS_CUT_NONE = 0, /* Never cut the roll */
CUPS_CUT_FILE = 1, /* Cut the roll after this file */
CUPS_CUT_JOB = 2, /* Cut the roll after this job */
CUPS_CUT_SET = 3, /* Cut the roll after this set */
CUPS_CUT_PAGE = 4 /* Cut the roll after this page */
} cups_cut_t;
typedef enum cups_edge_e /**** LeadingEdge attribute values ****/
{
CUPS_EDGE_TOP = 0, /* Leading edge is the top of the page */
CUPS_EDGE_RIGHT = 1, /* Leading edge is the right of the page */
CUPS_EDGE_BOTTOM = 2, /* Leading edge is the bottom of the page */
CUPS_EDGE_LEFT = 3 /* Leading edge is the left of the page */
} cups_edge_t;
typedef enum cups_jog_e /**** Jog attribute values ****/
{
CUPS_JOG_NONE = 0, /* Never move pages */
CUPS_JOG_FILE = 1, /* Move pages after this file */
CUPS_JOG_JOB = 2, /* Move pages after this job */
CUPS_JOG_SET = 3 /* Move pages after this set */
} cups_jog_t;
enum cups_mode_e /**** cupsRasterOpen modes ****/
{
CUPS_RASTER_READ = 0, /* Open stream for reading */
CUPS_RASTER_WRITE = 1, /* Open stream for writing */
CUPS_RASTER_WRITE_COMPRESSED = 2, /* Open stream for compressed writing @since CUPS 1.3/OS X 10.5@ */
CUPS_RASTER_WRITE_PWG = 3 /* Open stream for compressed writing in PWG mode @since CUPS 1.5/OS X 10.7@ */
};
typedef enum cups_mode_e cups_mode_t; /**** cupsRasterOpen modes ****/
typedef enum cups_order_e /**** cupsColorOrder attribute values ****/
{
CUPS_ORDER_CHUNKED = 0, /* CMYK CMYK CMYK ... */
CUPS_ORDER_BANDED = 1, /* CCC MMM YYY KKK ... */
CUPS_ORDER_PLANAR = 2 /* CCC ... MMM ... YYY ... KKK ... */
} cups_order_t;
typedef enum cups_orient_e /**** Orientation attribute values ****/
{
CUPS_ORIENT_0 = 0, /* Don't rotate the page */
CUPS_ORIENT_90 = 1, /* Rotate the page counter-clockwise */
CUPS_ORIENT_180 = 2, /* Turn the page upside down */
CUPS_ORIENT_270 = 3 /* Rotate the page clockwise */
} cups_orient_t;
/*
* The page header structure contains the standard PostScript page device
* dictionary, along with some CUPS-specific parameters that are provided
* by the RIPs...
*
* The API supports a "version 1" (from CUPS 1.0 and 1.1) and a "version 2"
* (from CUPS 1.2 and higher) page header, for binary compatibility.
*/
typedef struct cups_page_header_s /**** Version 1 page header @deprecated@ ****/
{
/**** Standard Page Device Dictionary String Values ****/
char MediaClass[64]; /* MediaClass string */
char MediaColor[64]; /* MediaColor string */
char MediaType[64]; /* MediaType string */
char OutputType[64]; /* OutputType string */
/**** Standard Page Device Dictionary Integer Values ****/
unsigned AdvanceDistance; /* AdvanceDistance value in points */
cups_adv_t AdvanceMedia; /* AdvanceMedia value (@link cups_adv_t@) */
cups_bool_t Collate; /* Collated copies value */
cups_cut_t CutMedia; /* CutMedia value (@link cups_cut_t@) */
cups_bool_t Duplex; /* Duplexed (double-sided) value */
unsigned HWResolution[2]; /* Resolution in dots-per-inch */
unsigned ImagingBoundingBox[4]; /* Pixel region that is painted (points, left, bottom, right, top) */
cups_bool_t InsertSheet; /* InsertSheet value */
cups_jog_t Jog; /* Jog value (@link cups_jog_t@) */
cups_edge_t LeadingEdge; /* LeadingEdge value (@link cups_edge_t@) */
unsigned Margins[2]; /* Lower-lefthand margins in points */
cups_bool_t ManualFeed; /* ManualFeed value */
unsigned MediaPosition; /* MediaPosition value */
unsigned MediaWeight; /* MediaWeight value in grams/m^2 */
cups_bool_t MirrorPrint; /* MirrorPrint value */
cups_bool_t NegativePrint; /* NegativePrint value */
unsigned NumCopies; /* Number of copies to produce */
cups_orient_t Orientation; /* Orientation value (@link cups_orient_t@) */
cups_bool_t OutputFaceUp; /* OutputFaceUp value */
unsigned PageSize[2]; /* Width and length of page in points */
cups_bool_t Separations; /* Separations value */
cups_bool_t TraySwitch; /* TraySwitch value */
cups_bool_t Tumble; /* Tumble value */
/**** CUPS Page Device Dictionary Values ****/
unsigned cupsWidth; /* Width of page image in pixels */
unsigned cupsHeight; /* Height of page image in pixels */
unsigned cupsMediaType; /* Media type code */
unsigned cupsBitsPerColor; /* Number of bits for each color */
unsigned cupsBitsPerPixel; /* Number of bits for each pixel */
unsigned cupsBytesPerLine; /* Number of bytes per line */
cups_order_t cupsColorOrder; /* Order of colors */
cups_cspace_t cupsColorSpace; /* True colorspace */
unsigned cupsCompression; /* Device compression to use */
unsigned cupsRowCount; /* Rows per band */
unsigned cupsRowFeed; /* Feed between bands */
unsigned cupsRowStep; /* Spacing between lines */
} cups_page_header_t;
/**** New in CUPS 1.2 ****/
typedef struct cups_page_header2_s /**** Version 2 page header @since CUPS 1.2/OS X 10.5@ ****/
{
/**** Standard Page Device Dictionary String Values ****/
char MediaClass[64]; /* MediaClass string */
char MediaColor[64]; /* MediaColor string */
char MediaType[64]; /* MediaType string */
char OutputType[64]; /* OutputType string */
/**** Standard Page Device Dictionary Integer Values ****/
unsigned AdvanceDistance; /* AdvanceDistance value in points */
cups_adv_t AdvanceMedia; /* AdvanceMedia value (@link cups_adv_t@) */
cups_bool_t Collate; /* Collated copies value */
cups_cut_t CutMedia; /* CutMedia value (@link cups_cut_t@) */
cups_bool_t Duplex; /* Duplexed (double-sided) value */
unsigned HWResolution[2]; /* Resolution in dots-per-inch */
unsigned ImagingBoundingBox[4]; /* Pixel region that is painted (points, left, bottom, right, top) */
cups_bool_t InsertSheet; /* InsertSheet value */
cups_jog_t Jog; /* Jog value (@link cups_jog_t@) */
cups_edge_t LeadingEdge; /* LeadingEdge value (@link cups_edge_t@) */
unsigned Margins[2]; /* Lower-lefthand margins in points */
cups_bool_t ManualFeed; /* ManualFeed value */
unsigned MediaPosition; /* MediaPosition value */
unsigned MediaWeight; /* MediaWeight value in grams/m^2 */
cups_bool_t MirrorPrint; /* MirrorPrint value */
cups_bool_t NegativePrint; /* NegativePrint value */
unsigned NumCopies; /* Number of copies to produce */
cups_orient_t Orientation; /* Orientation value (@link cups_orient_t@) */
cups_bool_t OutputFaceUp; /* OutputFaceUp value */
unsigned PageSize[2]; /* Width and length of page in points */
cups_bool_t Separations; /* Separations value */
cups_bool_t TraySwitch; /* TraySwitch value */
cups_bool_t Tumble; /* Tumble value */
/**** CUPS Page Device Dictionary Values ****/
unsigned cupsWidth; /* Width of page image in pixels */
unsigned cupsHeight; /* Height of page image in pixels */
unsigned cupsMediaType; /* Media type code */
unsigned cupsBitsPerColor; /* Number of bits for each color */
unsigned cupsBitsPerPixel; /* Number of bits for each pixel */
unsigned cupsBytesPerLine; /* Number of bytes per line */
cups_order_t cupsColorOrder; /* Order of colors */
cups_cspace_t cupsColorSpace; /* True colorspace */
unsigned cupsCompression; /* Device compression to use */
unsigned cupsRowCount; /* Rows per band */
unsigned cupsRowFeed; /* Feed between bands */
unsigned cupsRowStep; /* Spacing between lines */
/**** Version 2 Dictionary Values ****/
unsigned cupsNumColors; /* Number of color compoents @since CUPS 1.2/OS X 10.5@ */
float cupsBorderlessScalingFactor;
/* Scaling that was applied to page data @since CUPS 1.2/OS X 10.5@ */
float cupsPageSize[2]; /* Floating point PageSize (scaling *
* factor not applied) @since CUPS 1.2/OS X 10.5@ */
float cupsImagingBBox[4]; /* Floating point ImagingBoundingBox
* (scaling factor not applied, left,
* bottom, right, top) @since CUPS 1.2/OS X 10.5@ */
unsigned cupsInteger[16]; /* User-defined integer values @since CUPS 1.2/OS X 10.5@ */
float cupsReal[16]; /* User-defined floating-point values @since CUPS 1.2/OS X 10.5@ */
char cupsString[16][64]; /* User-defined string values @since CUPS 1.2/OS X 10.5@ */
char cupsMarkerType[64]; /* Ink/toner type @since CUPS 1.2/OS X 10.5@ */
char cupsRenderingIntent[64];/* Color rendering intent @since CUPS 1.2/OS X 10.5@ */
char cupsPageSizeName[64]; /* PageSize name @since CUPS 1.2/OS X 10.5@ */
} cups_page_header2_t;
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
*
* This function is specified when
* creating a raster stream with
* @link cupsRasterOpenIO@ and handles
* generic reading and writing of raster
* data. It must return -1 on error or
* the number of bytes specified by
* "length" on success.
****/
/*
* 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;
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;
extern unsigned cupsRasterWritePixels(cups_raster_t *r,
unsigned char *p, unsigned len);
/**** 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) _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);
# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_CUPS_RASTER_H_ */
/*
* End of "$Id: raster.h 3794 2012-04-23 22:44:16Z msweet $".
*/

1168
cups/request.c Normal file

File diff suppressed because it is too large Load Diff

642
cups/sidechannel.c Normal file
View File

@@ -0,0 +1,642 @@
/*
* "$Id: sidechannel.c 7720 2008-07-11 22:46:21Z mike $"
*
* Side-channel API code for CUPS.
*
* Copyright 2007-2012 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
* file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*
* Contents:
*
* cupsSideChannelDoRequest() - Send a side-channel command to a backend and
* wait for a response.
* cupsSideChannelRead() - Read a side-channel message.
* cupsSideChannelSNMPGet() - Query a SNMP OID's value.
* cupsSideChannelSNMPWalk() - Query multiple SNMP OID values.
* cupsSideChannelWrite() - Write a side-channel message.
*/
/*
* Include necessary headers...
*/
#include "sidechannel.h"
#include "cups-private.h"
#ifdef WIN32
# include <io.h>
#else
# include <unistd.h>
#endif /* WIN32 */
#ifdef __hpux
# include <sys/time.h>
#elif !defined(WIN32)
# include <sys/select.h>
#endif /* __hpux */
#ifndef WIN32
# include <sys/time.h>
#endif /* !WIN32 */
#ifdef HAVE_POLL
# include <poll.h>
#endif /* HAVE_POLL */
/*
* Buffer size for side-channel requests...
*/
#define _CUPS_SC_MAX_DATA 65535
#define _CUPS_SC_MAX_BUFFER 65540
/*
* 'cupsSideChannelDoRequest()' - Send a side-channel command to a backend and wait for a response.
*
* This function is normally only called by filters, drivers, or port
* monitors in order to communicate with the backend used by the current
* printer. Programs must be prepared to handle timeout or "not
* implemented" status codes, which indicate that the backend or device
* do not support the specified side-channel command.
*
* The "datalen" parameter must be initialized to the size of the buffer
* pointed to by the "data" parameter. cupsSideChannelDoRequest() will
* update the value to contain the number of data bytes in the buffer.
*
* @since CUPS 1.3/OS X 10.5@
*/
cups_sc_status_t /* O - Status of command */
cupsSideChannelDoRequest(
cups_sc_command_t command, /* I - Command to send */
char *data, /* O - Response data buffer pointer */
int *datalen, /* IO - Size of data buffer on entry, number of bytes in buffer on return */
double timeout) /* I - Timeout in seconds */
{
cups_sc_status_t status; /* Status of command */
cups_sc_command_t rcommand; /* Response command */
if (cupsSideChannelWrite(command, CUPS_SC_STATUS_NONE, NULL, 0, timeout))
return (CUPS_SC_STATUS_TIMEOUT);
if (cupsSideChannelRead(&rcommand, &status, data, datalen, timeout))
return (CUPS_SC_STATUS_TIMEOUT);
if (rcommand != command)
return (CUPS_SC_STATUS_BAD_MESSAGE);
return (status);
}
/*
* 'cupsSideChannelRead()' - Read a side-channel message.
*
* This function is normally only called by backend programs to read
* commands from a filter, driver, or port monitor program. The
* caller must be prepared to handle incomplete or invalid messages
* and return the corresponding status codes.
*
* The "datalen" parameter must be initialized to the size of the buffer
* pointed to by the "data" parameter. cupsSideChannelDoRequest() will
* update the value to contain the number of data bytes in the buffer.
*
* @since CUPS 1.3/OS X 10.5@
*/
int /* O - 0 on success, -1 on error */
cupsSideChannelRead(
cups_sc_command_t *command, /* O - Command code */
cups_sc_status_t *status, /* O - Status code */
char *data, /* O - Data buffer pointer */
int *datalen, /* IO - Size of data buffer on entry, number of bytes in buffer on return */
double timeout) /* I - Timeout in seconds */
{
char *buffer; /* Message buffer */
int bytes; /* Bytes read */
int templen; /* Data length from message */
int nfds; /* Number of file descriptors */
#ifdef HAVE_POLL
struct pollfd pfd; /* Poll structure for poll() */
#else /* select() */
fd_set input_set; /* Input set for select() */
struct timeval stimeout; /* Timeout value for select() */
#endif /* HAVE_POLL */
DEBUG_printf(("cupsSideChannelRead(command=%p, status=%p, data=%p, "
"datalen=%p(%d), timeout=%.3f)", command, status, data,
datalen, datalen ? *datalen : -1, timeout));
/*
* Range check input...
*/
if (!command || !status)
return (-1);
/*
* See if we have pending data on the side-channel socket...
*/
#ifdef HAVE_POLL
pfd.fd = CUPS_SC_FD;
pfd.events = POLLIN;
while ((nfds = poll(&pfd, 1,
timeout < 0.0 ? -1 : (long)(timeout * 1000))) < 0 &&
(errno == EINTR || errno == EAGAIN))
;
#else /* select() */
FD_ZERO(&input_set);
FD_SET(CUPS_SC_FD, &input_set);
stimeout.tv_sec = (int)timeout;
stimeout.tv_usec = (int)(timeout * 1000000) % 1000000;
while ((nfds = select(CUPS_SC_FD + 1, &input_set, NULL, NULL,
timeout < 0.0 ? NULL : &stimeout)) < 0 &&
(errno == EINTR || errno == EAGAIN))
;
#endif /* HAVE_POLL */
if (nfds < 1)
{
*command = CUPS_SC_CMD_NONE;
*status = nfds==0 ? CUPS_SC_STATUS_TIMEOUT : CUPS_SC_STATUS_IO_ERROR;
return (-1);
}
/*
* Read a side-channel message for the format:
*
* Byte(s) Description
* ------- -------------------------------------------
* 0 Command code
* 1 Status code
* 2-3 Data length (network byte order)
* 4-N Data
*/
if ((buffer = _cupsBufferGet(_CUPS_SC_MAX_BUFFER)) == NULL)
{
*command = CUPS_SC_CMD_NONE;
*status = CUPS_SC_STATUS_TOO_BIG;
return (-1);
}
while ((bytes = read(CUPS_SC_FD, buffer, _CUPS_SC_MAX_BUFFER)) < 0)
if (errno != EINTR && errno != EAGAIN)
{
DEBUG_printf(("1cupsSideChannelRead: Read error: %s", strerror(errno)));
_cupsBufferRelease(buffer);
*command = CUPS_SC_CMD_NONE;
*status = CUPS_SC_STATUS_IO_ERROR;
return (-1);
}
/*
* Watch for EOF or too few bytes...
*/
if (bytes < 4)
{
DEBUG_printf(("1cupsSideChannelRead: Short read of %d bytes", bytes));
_cupsBufferRelease(buffer);
*command = CUPS_SC_CMD_NONE;
*status = CUPS_SC_STATUS_BAD_MESSAGE;
return (-1);
}
/*
* Validate the command code in the message...
*/
if (buffer[0] < CUPS_SC_CMD_SOFT_RESET ||
buffer[0] >= CUPS_SC_CMD_MAX)
{
DEBUG_printf(("1cupsSideChannelRead: Bad command %d!", buffer[0]));
_cupsBufferRelease(buffer);
*command = CUPS_SC_CMD_NONE;
*status = CUPS_SC_STATUS_BAD_MESSAGE;
return (-1);
}
*command = (cups_sc_command_t)buffer[0];
/*
* Validate the data length in the message...
*/
templen = ((buffer[2] & 255) << 8) | (buffer[3] & 255);
if (templen > 0 && (!data || !datalen))
{
/*
* Either the response is bigger than the provided buffer or the
* response is bigger than we've read...
*/
*status = CUPS_SC_STATUS_TOO_BIG;
}
else if (!datalen || templen > *datalen || templen > (bytes - 4))
{
/*
* Either the response is bigger than the provided buffer or the
* response is bigger than we've read...
*/
*status = CUPS_SC_STATUS_TOO_BIG;
}
else
{
/*
* The response data will fit, copy it over and provide the actual
* length...
*/
*status = (cups_sc_status_t)buffer[1];
*datalen = templen;
memcpy(data, buffer + 4, templen);
}
_cupsBufferRelease(buffer);
DEBUG_printf(("1cupsSideChannelRead: Returning status=%d", *status));
return (0);
}
/*
* 'cupsSideChannelSNMPGet()' - Query a SNMP OID's value.
*
* This function asks the backend to do a SNMP OID query on behalf of the
* filter, port monitor, or backend using the default community name.
*
* "oid" contains a numeric OID consisting of integers separated by periods,
* for example ".1.3.6.1.2.1.43". Symbolic names from SNMP MIBs are not
* supported and must be converted to their numeric forms.
*
* On input, "data" and "datalen" provide the location and size of the
* buffer to hold the OID value as a string. HEX-String (binary) values are
* converted to hexadecimal strings representing the binary data, while
* NULL-Value and unknown OID types are returned as the empty string.
* The returned "datalen" does not include the trailing nul.
*
* @code CUPS_SC_STATUS_NOT_IMPLEMENTED@ is returned by backends that do not
* support SNMP queries. @code CUPS_SC_STATUS_NO_RESPONSE@ is returned when
* the printer does not respond to the SNMP query.
*
* @since CUPS 1.4/OS X 10.6@
*/
cups_sc_status_t /* O - Query status */
cupsSideChannelSNMPGet(
const char *oid, /* I - OID to query */
char *data, /* I - Buffer for OID value */
int *datalen, /* IO - Size of OID buffer on entry, size of value on return */
double timeout) /* I - Timeout in seconds */
{
cups_sc_status_t status; /* Status of command */
cups_sc_command_t rcommand; /* Response command */
char *real_data; /* Real data buffer for response */
int real_datalen, /* Real length of data buffer */
real_oidlen; /* Length of returned OID string */
DEBUG_printf(("cupsSideChannelSNMPGet(oid=\"%s\", data=%p, datalen=%p(%d), "
"timeout=%.3f)", oid, data, datalen, datalen ? *datalen : -1,
timeout));
/*
* Range check input...
*/
if (!oid || !*oid || !data || !datalen || *datalen < 2)
return (CUPS_SC_STATUS_BAD_MESSAGE);
*data = '\0';
/*
* Send the request to the backend and wait for a response...
*/
if (cupsSideChannelWrite(CUPS_SC_CMD_SNMP_GET, CUPS_SC_STATUS_NONE, oid,
(int)strlen(oid) + 1, timeout))
return (CUPS_SC_STATUS_TIMEOUT);
if ((real_data = _cupsBufferGet(_CUPS_SC_MAX_BUFFER)) == NULL)
return (CUPS_SC_STATUS_TOO_BIG);
real_datalen = _CUPS_SC_MAX_BUFFER;
if (cupsSideChannelRead(&rcommand, &status, real_data, &real_datalen, timeout))
{
_cupsBufferRelease(real_data);
return (CUPS_SC_STATUS_TIMEOUT);
}
if (rcommand != CUPS_SC_CMD_SNMP_GET)
{
_cupsBufferRelease(real_data);
return (CUPS_SC_STATUS_BAD_MESSAGE);
}
if (status == CUPS_SC_STATUS_OK)
{
/*
* Parse the response of the form "oid\0value"...
*/
real_oidlen = strlen(real_data) + 1;
real_datalen -= real_oidlen;
if ((real_datalen + 1) > *datalen)
{
_cupsBufferRelease(real_data);
return (CUPS_SC_STATUS_TOO_BIG);
}
memcpy(data, real_data + real_oidlen, real_datalen);
data[real_datalen] = '\0';
*datalen = real_datalen;
}
_cupsBufferRelease(real_data);
return (status);
}
/*
* 'cupsSideChannelSNMPWalk()' - Query multiple SNMP OID values.
*
* This function asks the backend to do multiple SNMP OID queries on behalf
* of the filter, port monitor, or backend using the default community name.
* All OIDs under the "parent" OID are queried and the results are sent to
* the callback function you provide.
*
* "oid" contains a numeric OID consisting of integers separated by periods,
* for example ".1.3.6.1.2.1.43". Symbolic names from SNMP MIBs are not
* supported and must be converted to their numeric forms.
*
* "timeout" specifies the timeout for each OID query. The total amount of
* time will depend on the number of OID values found and the time required
* for each query.
*
* "cb" provides a function to call for every value that is found. "context"
* is an application-defined pointer that is sent to the callback function
* along with the OID and current data. The data passed to the callback is the
* same as returned by @link cupsSideChannelSNMPGet@.
*
* @code CUPS_SC_STATUS_NOT_IMPLEMENTED@ is returned by backends that do not
* support SNMP queries. @code CUPS_SC_STATUS_NO_RESPONSE@ is returned when
* the printer does not respond to the first SNMP query.
*
* @since CUPS 1.4/OS X 10.6@
*/
cups_sc_status_t /* O - Status of first query of @code CUPS_SC_STATUS_OK@ on success */
cupsSideChannelSNMPWalk(
const char *oid, /* I - First numeric OID to query */
double timeout, /* I - Timeout for each query in seconds */
cups_sc_walk_func_t cb, /* I - Function to call with each value */
void *context) /* I - Application-defined pointer to send to callback */
{
cups_sc_status_t status; /* Status of command */
cups_sc_command_t rcommand; /* Response command */
char *real_data; /* Real data buffer for response */
int real_datalen, /* Real length of data buffer */
real_oidlen, /* Length of returned OID string */
oidlen; /* Length of first OID */
const char *current_oid; /* Current OID */
char last_oid[2048]; /* Last OID */
DEBUG_printf(("cupsSideChannelSNMPWalk(oid=\"%s\", timeout=%.3f, cb=%p, "
"context=%p)", oid, timeout, cb, context));
/*
* Range check input...
*/
if (!oid || !*oid || !cb)
return (CUPS_SC_STATUS_BAD_MESSAGE);
if ((real_data = _cupsBufferGet(_CUPS_SC_MAX_BUFFER)) == NULL)
return (CUPS_SC_STATUS_TOO_BIG);
/*
* Loop until the OIDs don't match...
*/
current_oid = oid;
oidlen = (int)strlen(oid);
last_oid[0] = '\0';
do
{
/*
* Send the request to the backend and wait for a response...
*/
if (cupsSideChannelWrite(CUPS_SC_CMD_SNMP_GET_NEXT, CUPS_SC_STATUS_NONE,
current_oid, (int)strlen(current_oid) + 1, timeout))
{
_cupsBufferRelease(real_data);
return (CUPS_SC_STATUS_TIMEOUT);
}
real_datalen = _CUPS_SC_MAX_BUFFER;
if (cupsSideChannelRead(&rcommand, &status, real_data, &real_datalen,
timeout))
{
_cupsBufferRelease(real_data);
return (CUPS_SC_STATUS_TIMEOUT);
}
if (rcommand != CUPS_SC_CMD_SNMP_GET_NEXT)
{
_cupsBufferRelease(real_data);
return (CUPS_SC_STATUS_BAD_MESSAGE);
}
if (status == CUPS_SC_STATUS_OK)
{
/*
* Parse the response of the form "oid\0value"...
*/
if (strncmp(real_data, oid, oidlen) || real_data[oidlen] != '.' ||
!strcmp(real_data, last_oid))
{
/*
* Done with this set of OIDs...
*/
_cupsBufferRelease(real_data);
return (CUPS_SC_STATUS_OK);
}
if (real_datalen < sizeof(real_data))
real_data[real_datalen] = '\0';
real_oidlen = strlen(real_data) + 1;
real_datalen -= real_oidlen;
/*
* Call the callback with the OID and data...
*/
(*cb)(real_data, real_data + real_oidlen, real_datalen, context);
/*
* Update the current OID...
*/
current_oid = real_data;
strlcpy(last_oid, current_oid, sizeof(last_oid));
}
}
while (status == CUPS_SC_STATUS_OK);
_cupsBufferRelease(real_data);
return (status);
}
/*
* 'cupsSideChannelWrite()' - Write a side-channel message.
*
* This function is normally only called by backend programs to send
* responses to a filter, driver, or port monitor program.
*
* @since CUPS 1.3/OS X 10.5@
*/
int /* O - 0 on success, -1 on error */
cupsSideChannelWrite(
cups_sc_command_t command, /* I - Command code */
cups_sc_status_t status, /* I - Status code */
const char *data, /* I - Data buffer pointer */
int datalen, /* I - Number of bytes of data */
double timeout) /* I - Timeout in seconds */
{
char *buffer; /* Message buffer */
int bytes; /* Bytes written */
#ifdef HAVE_POLL
struct pollfd pfd; /* Poll structure for poll() */
#else /* select() */
fd_set output_set; /* Output set for select() */
struct timeval stimeout; /* Timeout value for select() */
#endif /* HAVE_POLL */
/*
* Range check input...
*/
if (command < CUPS_SC_CMD_SOFT_RESET || command >= CUPS_SC_CMD_MAX ||
datalen < 0 || datalen > _CUPS_SC_MAX_DATA || (datalen > 0 && !data))
return (-1);
/*
* See if we can safely write to the side-channel socket...
*/
#ifdef HAVE_POLL
pfd.fd = CUPS_SC_FD;
pfd.events = POLLOUT;
if (timeout < 0.0)
{
if (poll(&pfd, 1, -1) < 1)
return (-1);
}
else if (poll(&pfd, 1, (long)(timeout * 1000)) < 1)
return (-1);
#else /* select() */
FD_ZERO(&output_set);
FD_SET(CUPS_SC_FD, &output_set);
if (timeout < 0.0)
{
if (select(CUPS_SC_FD + 1, NULL, &output_set, NULL, NULL) < 1)
return (-1);
}
else
{
stimeout.tv_sec = (int)timeout;
stimeout.tv_usec = (int)(timeout * 1000000) % 1000000;
if (select(CUPS_SC_FD + 1, NULL, &output_set, NULL, &stimeout) < 1)
return (-1);
}
#endif /* HAVE_POLL */
/*
* Write a side-channel message in the format:
*
* Byte(s) Description
* ------- -------------------------------------------
* 0 Command code
* 1 Status code
* 2-3 Data length (network byte order) <= 16384
* 4-N Data
*/
if ((buffer = _cupsBufferGet(datalen + 4)) == NULL)
return (-1);
buffer[0] = command;
buffer[1] = status;
buffer[2] = datalen >> 8;
buffer[3] = datalen & 255;
bytes = 4;
if (datalen > 0)
{
memcpy(buffer + 4, data, datalen);
bytes += datalen;
}
while (write(CUPS_SC_FD, buffer, bytes) < 0)
if (errno != EINTR && errno != EAGAIN)
{
_cupsBufferRelease(buffer);
return (-1);
}
_cupsBufferRelease(buffer);
return (0);
}
/*
* End of "$Id: sidechannel.c 7720 2008-07-11 22:46:21Z mike $".
*/

Some files were not shown because too many files have changed in this diff Show More