mirror of
https://github.com/MopriaAlliance/CUPS-for-Android.git
synced 2026-08-07 12:33:41 +08:00
adding CUPS code
This commit is contained in:
82
Android.mk
Normal file
82
Android.mk
Normal 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
217
CHANGES-1.0.txt
Normal 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
3462
CHANGES-1.1.txt
Normal file
File diff suppressed because it is too large
Load Diff
1261
CHANGES-1.2.txt
Normal file
1261
CHANGES-1.2.txt
Normal file
File diff suppressed because it is too large
Load Diff
856
CHANGES-1.3.txt
Normal file
856
CHANGES-1.3.txt
Normal 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
843
CHANGES-1.4.txt
Normal 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
312
CHANGES-1.5.txt
Normal 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
225
CHANGES.txt
Normal 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
51
CREDITS.txt
Normal 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
213
INSTALL.txt
Normal 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
971
LICENSE.txt
Normal 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
262
Makedefs.in
Normal 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
336
Makefile
Normal 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
163
README.txt
Normal 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
750
config.h
Normal 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
747
config.h.in
Normal 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
97
configure.in
Normal 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
146
cups-config.in
Executable 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
260
cups/Dependencies
Normal 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
633
cups/Makefile
Normal 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
2341
cups/adminutil.c
Normal file
File diff suppressed because it is too large
Load Diff
81
cups/adminutil.h
Normal file
81
cups/adminutil.h
Normal 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
34
cups/api-array.header
Normal 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
196
cups/api-array.shtml
Normal 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 <cups/array.h>
|
||||||
|
|
||||||
|
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 <cups/array.h>
|
||||||
|
|
||||||
|
#define HASH_SIZE 512 /* Size of hash table */
|
||||||
|
|
||||||
|
static int compare_func(void *first, void *second, void *user_data);
|
||||||
|
static int hash_func(void *element, void *user_data);
|
||||||
|
|
||||||
|
void *user_data;
|
||||||
|
<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 <cups/array.h>
|
||||||
|
|
||||||
|
#define HASH_SIZE 512 /* Size of hash table */
|
||||||
|
|
||||||
|
static int compare_func(void *first, void *second, void *user_data);
|
||||||
|
static void *copy_func(void *element, void *user_data);
|
||||||
|
static void free_func(void *element, void *user_data);
|
||||||
|
static int hash_func(void *element, void *user_data);
|
||||||
|
|
||||||
|
void *user_data;
|
||||||
|
<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 <cups/array.h>
|
||||||
|
|
||||||
|
/* 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 <cups/array.h>
|
||||||
|
|
||||||
|
/* 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 <cups/array.h>
|
||||||
|
|
||||||
|
/* 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
40
cups/api-cups.header
Normal 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
443
cups/api-cups.shtml
Normal 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 <cups/cups.h>
|
||||||
|
|
||||||
|
<a href='#cups_dest_t'>cups_dest_t</a> *dests;
|
||||||
|
int num_dests = <a href='#cupsGetDests'>cupsGetDests</a>(&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 <cups/cups.h>
|
||||||
|
|
||||||
|
<a href='#cups_dest_t'>cups_dest_t</a> *dests;
|
||||||
|
int num_dests = <a href='#cupsGetDests'>cupsGetDests</a>(&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 <cups/cups.h>
|
||||||
|
|
||||||
|
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, &options);
|
||||||
|
|
||||||
|
/* This adds a second option value */
|
||||||
|
num_options = <a href='#cupsAddOption'>cupsAddOption</a>("second", "value", num_options, &options);
|
||||||
|
|
||||||
|
/* This replaces the first option we added */
|
||||||
|
num_options = <a href='#cupsAddOption'>cupsAddOption</a>("first", "new value", num_options, &options);
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>Use a <code>for</code> loop to copy the options from a destination:</p>
|
||||||
|
|
||||||
|
<pre class='example'>
|
||||||
|
#include <cups/cups.h>
|
||||||
|
|
||||||
|
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 < dest->num_options; i ++)
|
||||||
|
num_options = <a href='#cupsAddOption'>cupsAddOption</a>(dest->options[i].name, dest->options[i].value,
|
||||||
|
num_options, &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 <cups/cups.h>
|
||||||
|
|
||||||
|
<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 <cups/cups.h>
|
||||||
|
|
||||||
|
<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 <cups/cups.h>
|
||||||
|
|
||||||
|
<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 <= 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 <cups/cups.h>
|
||||||
|
|
||||||
|
<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 < IPP_JOB_STOPPED)
|
||||||
|
{
|
||||||
|
/* Get my jobs (1) with any state (-1) */
|
||||||
|
num_jobs = <a href='#cupsGetJobs'>cupsGetJobs</a>(&jobs, dest->name, 1, -1);
|
||||||
|
|
||||||
|
/* Loop to find my job */
|
||||||
|
job_state = IPP_JOB_COMPLETED;
|
||||||
|
|
||||||
|
for (i = 0; i < num_jobs; i ++)
|
||||||
|
if (jobs[i].id == job_id)
|
||||||
|
{
|
||||||
|
job_state = jobs[i].state;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the job array */
|
||||||
|
<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 < 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 <cups/cups.h>
|
||||||
|
|
||||||
|
<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 <cups/cups.h>
|
||||||
|
|
||||||
|
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 <cups/cups.h>
|
||||||
|
|
||||||
|
const char *
|
||||||
|
my_password_cb(const char *prompt)
|
||||||
|
{
|
||||||
|
char user[65];
|
||||||
|
|
||||||
|
|
||||||
|
puts(prompt);
|
||||||
|
|
||||||
|
/* Get a username from the user */
|
||||||
|
printf("Username: ");
|
||||||
|
if (fgets(user, sizeof(user), stdin) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
/* Strip the newline from the string and set the user */
|
||||||
|
user[strlen(user) - 1] = '\0';
|
||||||
|
|
||||||
|
<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
36
cups/api-filedir.header
Normal 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
31
cups/api-filedir.shtml
Normal 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
41
cups/api-filter.header
Normal 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
765
cups/api-filter.shtml
Normal 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 <signal.h>>
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
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 <cups/cups.h>
|
||||||
|
|
||||||
|
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 <cups/sidechannel.h>
|
||||||
|
|
||||||
|
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, &datalen, 1.0);
|
||||||
|
|
||||||
|
/* Use the returned value if OK was returned and the length is non-zero */
|
||||||
|
if (status == CUPS_SC_STATUS_OK && 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 <cups/cups.h>
|
||||||
|
#include <cups/sidechannel.h>
|
||||||
|
|
||||||
|
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, &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 <cups/cups.h>
|
||||||
|
|
||||||
|
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 <cups/sidechannel.h>
|
||||||
|
|
||||||
|
<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>(&command, &status, data, &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 <cups/sidechannel.h>
|
||||||
|
|
||||||
|
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, &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 <cups/sidechannel.h>
|
||||||
|
|
||||||
|
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
37
cups/api-httpipp.header
Normal 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
317
cups/api-httpipp.shtml
Normal 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 <cups/cups.h>
|
||||||
|
|
||||||
|
|
||||||
|
<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") && ippGetValueTag(attr) == IPP_TAG_INTEGER)
|
||||||
|
job_id = ippGetInteger(attr, 0);
|
||||||
|
else if (!strcmp(attrname, "job-name") && ippGetValueTag(attr) == IPP_TAG_NAME)
|
||||||
|
job_name = ippGetString(attr, 0, NULL);
|
||||||
|
else if (!strcmp(attrname, "job-originating-user-name") &&
|
||||||
|
ippGetValueTag(attr) == IPP_TAG_NAME)
|
||||||
|
job_originating_user_name = ippGetString(attr, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (job_id > 0)
|
||||||
|
{
|
||||||
|
if (job_name == NULL)
|
||||||
|
job_name = "(withheld)";
|
||||||
|
|
||||||
|
if (job_originating_user_name == NULL)
|
||||||
|
job_originating_user_name = "(withheld)";
|
||||||
|
|
||||||
|
printf("%5d %-16s %s\n", job_id, job_originating_user_name, job_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</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 && 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
53
cups/api-overview.header
Normal 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
94
cups/api-overview.shtml
Normal 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><cups/cups.h></var> header, while
|
||||||
|
"cupsimage" functions are found in the <var><cups/raster.h></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 <stdio.h>
|
||||||
|
#include <cups/cups.h>
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
cups_dest_t *dests, *dest;
|
||||||
|
int num_dests = cupsGetDests(&dests);
|
||||||
|
|
||||||
|
for (i = num_dests, dest = dests; i > 0; i --, dest ++)
|
||||||
|
{
|
||||||
|
if (dest->instance)
|
||||||
|
printf("%s/%s\n", dest->name, dest->instance);
|
||||||
|
else
|
||||||
|
puts(dest->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
</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
38
cups/api-ppd.header
Normal 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
219
cups/api-ppd.shtml
Normal 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 <cups/ppd.h>
|
||||||
|
|
||||||
|
<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 <cups/ppd.h>
|
||||||
|
|
||||||
|
<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 <cups/ppd.h>
|
||||||
|
|
||||||
|
<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 <cups/ppd.h>
|
||||||
|
|
||||||
|
<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 <cups/ppd.h>
|
||||||
|
|
||||||
|
<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, &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 <cups/ppd.h>
|
||||||
|
|
||||||
|
<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 <cups/ppd.h>
|
||||||
|
|
||||||
|
<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 <cups/ppd.h>
|
||||||
|
|
||||||
|
<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
51
cups/array-private.h
Normal 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
1326
cups/array.c
Normal file
File diff suppressed because it is too large
Load Diff
92
cups/array.h
Normal file
92
cups/array.h
Normal 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
335
cups/attr.c
Normal 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
885
cups/auth.c
Normal 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
199
cups/backchannel.c
Normal 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
154
cups/backend.c
Normal 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
78
cups/backend.h
Normal 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
1214
cups/conflicts.c
Normal file
File diff suppressed because it is too large
Load Diff
272
cups/cups-private.h
Normal file
272
cups/cups-private.h
Normal 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
601
cups/cups.h
Normal 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
122
cups/custom.c
Normal 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
117
cups/debug-private.h
Normal 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
658
cups/debug.c
Normal 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
358
cups/dest-job.c
Normal 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
386
cups/dest-localization.c
Normal 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
1763
cups/dest-options.c
Normal file
File diff suppressed because it is too large
Load Diff
3891
cups/dest.c
Normal file
3891
cups/dest.c
Normal file
File diff suppressed because it is too large
Load Diff
472
cups/dir.c
Normal file
472
cups/dir.c
Normal 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
69
cups/dir.h
Normal 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
1229
cups/emit.c
Normal file
File diff suppressed because it is too large
Load Diff
664
cups/encode.c
Normal file
664
cups/encode.c
Normal 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
137
cups/file-private.h
Normal 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
2718
cups/file.c
Normal file
File diff suppressed because it is too large
Load Diff
116
cups/file.h
Normal file
116
cups/file.h
Normal 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
283
cups/getdevices.c
Normal 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
266
cups/getifaddrs.c
Normal 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
502
cups/getputfile.c
Normal 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
384
cups/globals.c
Normal 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
703
cups/http-addr.c
Normal 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
845
cups/http-addrlist.c
Normal 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
394
cups/http-private.h
Normal 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
2364
cups/http-support.c
Normal file
File diff suppressed because it is too large
Load Diff
4778
cups/http.c
Normal file
4778
cups/http.c
Normal file
File diff suppressed because it is too large
Load Diff
487
cups/http.h
Normal file
487
cups/http.h
Normal 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
78
cups/ipp-private.h
Normal 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
1090
cups/ipp-support.c
Normal file
File diff suppressed because it is too large
Load Diff
5574
cups/ipp.c
Normal file
5574
cups/ipp.c
Normal file
File diff suppressed because it is too large
Load Diff
671
cups/ipp.h
Normal file
671
cups/ipp.h
Normal 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
352
cups/langprintf.c
Normal 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
86
cups/language-private.h
Normal 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
1567
cups/language.c
Normal file
File diff suppressed because it is too large
Load Diff
115
cups/language.h
Normal file
115
cups/language.h
Normal 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
382
cups/libcups2.def
Normal 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
75
cups/libcups2.rc
Normal 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
85
cups/libcups_s.exp
Normal 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
779
cups/localize.c
Normal 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
1101
cups/mark.c
Normal file
File diff suppressed because it is too large
Load Diff
79
cups/md5-private.h
Normal file
79
cups/md5-private.h
Normal 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
346
cups/md5.c
Normal 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
142
cups/md5passwd.c
Normal 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
202
cups/notify.c
Normal 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
711
cups/options.c
Normal 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
396
cups/page.c
Normal 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
2635
cups/ppd-cache.c
Normal file
File diff suppressed because it is too large
Load Diff
215
cups/ppd-private.h
Normal file
215
cups/ppd-private.h
Normal 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
3398
cups/ppd.c
Normal file
File diff suppressed because it is too large
Load Diff
480
cups/ppd.h
Normal file
480
cups/ppd.h
Normal 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
928
cups/pwg-media.c
Normal 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
104
cups/pwg-private.h
Normal 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
66
cups/raster-private.h
Normal 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
405
cups/raster.h
Normal 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
1168
cups/request.c
Normal file
File diff suppressed because it is too large
Load Diff
642
cups/sidechannel.c
Normal file
642
cups/sidechannel.c
Normal 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
Reference in New Issue
Block a user