Comparar commits
1 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 1810112997 |
@@ -0,0 +1,81 @@
|
||||
CGI - CUPS v1.1.19 - 05/27/2003
|
||||
-------------------------------
|
||||
|
||||
This file describes the experimental scripting/CGI support
|
||||
provided by CUPS starting with CUPS 1.1.19.
|
||||
|
||||
WARNING: CGI support is not complete; you may run into problems
|
||||
and limitations in the implementation of CGI in CUPS that are
|
||||
not present in full-featured web servers like Apache.
|
||||
|
||||
|
||||
OVERVIEW OF CGI SUPPORT IN CUPS
|
||||
|
||||
CUPS has traditionally provided a dynamic web interface through
|
||||
four CGI programs that are executed when users open special
|
||||
directories on the CUPS server. Each CGI performs
|
||||
administration, class, job, and printer functions as directed by
|
||||
the user, but the actual programs that are run and functions
|
||||
that are available are limited to those that were originally
|
||||
designed into the scheduler.
|
||||
|
||||
Starting with CUPS 1.1.19, support is now available for CGI
|
||||
programs and specific scripting languages, currently Java, Perl,
|
||||
PHP, and Python. The interpreters for these languages are
|
||||
currently configured at compile time. Future versions may
|
||||
expand the interface to allow for generic support of scripting
|
||||
languages similar to the Apache "AddHandler" directive, but with
|
||||
external programs instead of modules.
|
||||
|
||||
The following MIME types are reserved for the CGI support in
|
||||
CUPS (the names have been chosen to mirror those used by
|
||||
Apache):
|
||||
|
||||
application/x-http-cgi CGI script/program
|
||||
application/x-http-java Java program
|
||||
application/x-http-perl Perl script
|
||||
application/x-http-php PHP script
|
||||
application/x-http-python Python script
|
||||
|
||||
In order to enable the corresponding type, you must create a new
|
||||
/etc/cups/cgi.types file which maps the filename extensions to
|
||||
the appropriate MIME type, for example:
|
||||
|
||||
application/x-http-cgi cgi
|
||||
application/x-http-php php
|
||||
|
||||
CGI scripts/programs (application/x-http-cgi) also must have
|
||||
execution permissions to be treated as a CGI script or program.
|
||||
|
||||
|
||||
LIMITATIONS
|
||||
|
||||
CUPS implements most of the CGI/1.1 specification, with the
|
||||
following limitations:
|
||||
|
||||
- No Location: redirection support.
|
||||
- No PATH_INFO or PATH_TRANSLATED support.
|
||||
- Limited HTTP field support; only the Content-Length
|
||||
(CONTENT_LENGTH), Cookie (HTTP_COOKIE), and User-Agent
|
||||
(HTTP_USER_AGENT) fields are placed in environment
|
||||
variables at this time.
|
||||
|
||||
|
||||
REPORTING PROBLEMS
|
||||
|
||||
If you have problems, READ THE DOCUMENTATION FIRST! If the
|
||||
documentation does not solve your problems please send an email
|
||||
to "cups-support@cups.org". Include your operating system and
|
||||
version, compiler and version, and any errors or problems you've
|
||||
run into. The "/var/log/cups/error_log" file 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.
|
||||
|
||||
Please note that the "cups-support@cups.org" email address goes
|
||||
to the CUPS developers; they are busy people, so your email may
|
||||
go unanswered for days or weeks. In general, only general build
|
||||
or distribution problems will actually get answered - for
|
||||
end-user support see the "README.txt" for a summary of the
|
||||
resources available.
|
||||
@@ -1,6 +1,653 @@
|
||||
CHANGES.txt - 12/18/2002
|
||||
CHANGES.txt - 11/07/2003
|
||||
------------------------
|
||||
|
||||
CHANGES IN CUPS V1.1.20rc6
|
||||
|
||||
- "lp -i jobid -H restart" would often return an error
|
||||
even though the job restarted successfully (STR #362)
|
||||
- The scheduler did not check for invalid allow/deny
|
||||
addresses such as "11.22.33.44/24". It now masks off
|
||||
the extra address bits and logs a warning message in
|
||||
the error_log file (STR #337)
|
||||
- The cupstestppd utility now checks for missing
|
||||
ImageableArea and PaperDimension attributes for each
|
||||
defined PageSize (STR #365)
|
||||
- The IPP code did not wait for a reply indefinitely on
|
||||
HTTP connections in "blocking" mode (STR #377)
|
||||
- The web interfaces did not rewrite the default printer
|
||||
URI properly (STR #369 and #299)
|
||||
- The LPD backend passed the C and L commands in the
|
||||
wrong order (STR #378)
|
||||
- The Dymo label printer driver did not set the label
|
||||
length properly (STR #373)
|
||||
- The scheduler did not support job IDs higher than
|
||||
99999 (STR #371)
|
||||
- The Visual C++ project files did not work (STR #366)
|
||||
- The scheduler's cupsLangSeek() function did not reset
|
||||
the "EOF" flag, preventing compressed files from being
|
||||
typed properly in some cases (STR #368)
|
||||
- The cupsLangGet() cache was only used if the locale
|
||||
name provided an explicit character set name (STR
|
||||
#354)
|
||||
- The CUPS API convenience functions did not call
|
||||
cupsLangFree() when they were done with the
|
||||
localization data (STR #354)
|
||||
- The scheduler did not return the
|
||||
job-hold-until-supported or job-hold-until-default
|
||||
attributes (STR #356)
|
||||
- The cupsaddsmb program did not support the new CUPS
|
||||
driver for Windows (STR #357)
|
||||
|
||||
|
||||
CHANGES IN CUPS V1.1.20rc5
|
||||
|
||||
- The scheduler did not initialize the browse socket
|
||||
file descriptor properly when only SLP browsing was
|
||||
enabled (STR #259)
|
||||
- The scheduler accessed the job attributes before they
|
||||
were set (STR #347, fix to STR #335)
|
||||
- The cupsCancelJob() function did not return 0 when the
|
||||
job could not be canceled (STR #340)
|
||||
|
||||
|
||||
CHANGES IN CUPS V1.1.20rc4
|
||||
|
||||
- The scheduler did not move the incoming job attributes
|
||||
in the operation group to the job group (STR #335)
|
||||
- The cupsDoFileRequest() function did not check for an
|
||||
early HTTP response while sending the file (STR #314)
|
||||
- The web interfaces did not quote #, ?, or . in printer
|
||||
names, which caused some problems with the generated
|
||||
URLs (STR #320)
|
||||
- CUPS couldn't be completely compiled with the -dDEBUG
|
||||
option (STR #331)
|
||||
|
||||
|
||||
CHANGES IN CUPS V1.1.20rc3
|
||||
|
||||
- More SLP changes (STR #259)
|
||||
- Revamped the child signal handling code to completely
|
||||
avoid deadlock issues on Solaris (STR #325)
|
||||
- The lpadmin command displayed an incorrect error
|
||||
message when the "-u" option was provided with no
|
||||
arguments (STR #313)
|
||||
- The web admin interface did not display an error
|
||||
message if the PPD file could not be loaded (STR #308)
|
||||
- The ppdEmit() functions did not use the correct
|
||||
orientation value position for custom page sizes (STR
|
||||
#292)
|
||||
|
||||
|
||||
CHANGES IN CUPS V1.1.20rc2
|
||||
|
||||
- The serial backend set the IXANY option on the port
|
||||
for XON/XOFF flow control; this caused problems with
|
||||
printers that returned status info but were not ready
|
||||
for more print data (STR #287)
|
||||
- The scheduler didn't support scripted index files
|
||||
(index.php, index.pl, etc. - STR #290)
|
||||
- The scheduler did not correctly localize script files
|
||||
with "GET" variables (STR #268)
|
||||
- Changes in job classification are now logged (STR
|
||||
#289)
|
||||
- Fixed a few more SLP-related bugs (STR #259)
|
||||
- Updated the user/group configure checks for MacOS X
|
||||
10.3 (STR #270)
|
||||
- Fixed an offset bug in the PDF filter (STR #284)
|
||||
- The cupsDoRequest() and cupsDoFileRequest() functions
|
||||
did not map several HTTP status codes to their IPP
|
||||
counterparts. This made detecting certain conditions
|
||||
very difficult (STR #277)
|
||||
- Config, spool, and status files are now owned by the
|
||||
scheduler user (usually root) with read permission for
|
||||
the filter group (STR #283)
|
||||
- The HP-GL/2 filter did not support the SI command,
|
||||
some values for the AD and SD commands, and did not
|
||||
rotate labels properly via the DI command (STR #282)
|
||||
- The fax support did not update/set the job-hold-until
|
||||
attribute when a fax job fails (STR #269)
|
||||
- The cupsLangGet() function didn't support locales of
|
||||
the form "ll.charset" (STR #271)
|
||||
- The scheduler did not use the charset when getting the
|
||||
language localization for a request; this caused extra
|
||||
disk IO for every request (STR #271)
|
||||
- The scheduler did not support requests with more than
|
||||
one language specified (STR #267)
|
||||
|
||||
|
||||
CHANGES IN CUPS V1.1.20rc1
|
||||
|
||||
- The scheduler now waits up to 60 seconds before
|
||||
restarting to allow active jobs to complete printing
|
||||
and pending requests to be processed (STR #226)
|
||||
- The web interface did not work on systems where time_t
|
||||
is 64 bits (STR #262)
|
||||
- Added backend tweeks and content-length check from Red
|
||||
Hat (STR #253)
|
||||
- The USB backend now uses the 8255 constants instead of
|
||||
the standard constants when reporting printer status
|
||||
bits on Linux (STR #254)
|
||||
- Added new cupsDoAuthentication(), cupsGetFd(),
|
||||
cupsGetFile(), cupsPutFd(), and cupsPutFile() functions
|
||||
to the CUPS API (STR #112)
|
||||
- The PDF filter always scaled and offset pages; this
|
||||
caused problems under MacOS X, so now the "fitplot"
|
||||
option controls whether PDF files are scaled to fit
|
||||
within the printable area of the page (STR #250)
|
||||
- The LPD backend did not support the port number in a
|
||||
URI (STR #247)
|
||||
- Some filters didn't properly support boolean options
|
||||
(STR #249)
|
||||
- Landscape PDF files were not always offset by the
|
||||
correct amount when rotating (STR #243)
|
||||
- The scheduler could hang in a call to localtime() when
|
||||
logging messages from the signal handler (STR #242)
|
||||
- The PDF filter no longer prints form widgets; this
|
||||
duplicates the behavior of Acrobat Reader (STR #241)
|
||||
- cupsGetPPD() didn't handle a late termination of a
|
||||
HTTP connection with the server (STR #220)
|
||||
- ppdOpen() did not correctly check for "*PPD-Adobe-4."
|
||||
on the first line of a PPD file. This caused incorrect
|
||||
PASS results for some PPD files (STR #233)
|
||||
- cupsEncodeOptions() did not allow boolean options to
|
||||
use "yes" and "on" for true values (STR #227)
|
||||
- The pstops filter only sent the TBCP exit sequence if
|
||||
it was defined in the JCLEnd attribute in the PPD file
|
||||
(STR #224)
|
||||
- Support for more than 1024 files was broken on Solaris
|
||||
9 (STR #217)
|
||||
- The setgroups() calls now pass in 1 group (the
|
||||
configured group) instead of 0 for compatibility with
|
||||
BSD and Darwin (STR #213)
|
||||
- The scheduler's built-in broadcast throttling was
|
||||
ineffective since incoming packets would cause the
|
||||
next group of outgoing packets to be sent immediately
|
||||
rather than waiting for the next time slot (STR #211)
|
||||
- Added a new ppdSetConformance() function to set the
|
||||
conformance requirements for PPD files. Currently only
|
||||
two levels are defined, PPD_CONFORM_RELAXED and
|
||||
PPD_CONFORM_STRICT, and the default is the relaxed
|
||||
level (STR #212)
|
||||
- The IPP backend did not correctly execute the
|
||||
pictwpstops filter on OSX (STR #210)
|
||||
- The LPD backend did not set the banner class when the
|
||||
"banner=yes" option was specified in the device URI
|
||||
(STR #209)
|
||||
- The imagetoraster filter did not support all of the
|
||||
page device attributes (STR #208)
|
||||
- The pdftops filter incorrectly auto-rotated pages when
|
||||
the user already had specified the proper orientation
|
||||
(STR #207)
|
||||
- Fixed AIX shared library support (STR #201)
|
||||
- Added support for live testing with Valgrind (STR
|
||||
#193)
|
||||
- The CGI programs now collect the list of needed
|
||||
attributes for the class, job, and printer template
|
||||
files (STR #192)
|
||||
- The scheduler now passes the first port that is bound
|
||||
to the local loopback or "any" addresses to the CGI
|
||||
programs rather than the port that the browser
|
||||
connected to (STR #103)
|
||||
- The cupstestppd program now checks for bad
|
||||
JobPatchFile attributes and incorrect versions of the
|
||||
Manufacturer attribute for HP printers (STR #155)
|
||||
- The filter makefile incorrectly installed
|
||||
libcupsimage.a in the filter directory (STR #180)
|
||||
- The scheduler did not verify that the job history
|
||||
files define the job-priority and
|
||||
job-originating-user-name attributes (STR #178)
|
||||
- The pstops filter didn't handle poorly-formed binary
|
||||
PostScript files that had CTRL-D's in them (STR #156)
|
||||
- The ppdOpen*() and cupsLangGet() functions did not
|
||||
make a copy of the old locale strings when using the
|
||||
POSIX locale when reading files, which apparently
|
||||
caused problems with some implementations of the
|
||||
standard C library. (STR #159)
|
||||
- The pdftops filter did not work properly with some
|
||||
embedded Type1C fonts (STR #177)
|
||||
- Updated the pdftops filter to be based upon Xpdf
|
||||
2.02pl1 (STR #191)
|
||||
- The scheduler did not reset the group list when
|
||||
running CGI and filter processes (STR #185)
|
||||
- The scheduler no longer calls malloc and free from the
|
||||
signal handlers (STR #190)
|
||||
- The USB backend now uses the manufacturer and model
|
||||
strings if the description string is not available
|
||||
(STR #174)
|
||||
- The ppdOpen functions still supported the
|
||||
VariablePaperSize attribute, which was removed in v4.0
|
||||
of the PPD spec. This caused problems with PPD files
|
||||
that relocated the PageSize option to a non-standard
|
||||
group (STR #158)
|
||||
- The cups.list file referenced MAN1EXT, MAN3EXT, and
|
||||
MAN5EXT, but none of those were actually defined (STR
|
||||
#147)
|
||||
- Chunked requests could cause a Denial of Service if
|
||||
the connection is terminated before the first byte of
|
||||
chunk data is sent/received (STR #143)
|
||||
- Printers with special characters in their names were
|
||||
not accessible from the web interface (STR #120)
|
||||
- The lpstat command now shows the correct interface
|
||||
script or PPD file, if any, for a print queue (STR #89)
|
||||
- The lpstat command now shows the printer-state-message
|
||||
and printer-state-reasons attributes whenever they are
|
||||
not blank (STR #152)
|
||||
- The French and German option-conflict.tmpl template
|
||||
files did not get installed (STR #148)
|
||||
- The cups.list.in file did not work when compiling
|
||||
without shared libraries (STR #149)
|
||||
- The DSOFLAGS included the LDFLAGS, which causes
|
||||
problems on at least HP-UX (STR #150)
|
||||
- The fax printer support did not keep track of the fax
|
||||
capability bit (STR #144)
|
||||
- The appleLangDefault() function could leak a small
|
||||
amount of memory (STR #145)
|
||||
- The ppdOpen() functions now mirror all normal
|
||||
attributes to the attribute list; previously only
|
||||
certain unassigned attributes would be added (STR
|
||||
#139)
|
||||
- The ppdEmitJCL() function wrote JCL commands to stdout
|
||||
instead of the passed file pointer (STR #142)
|
||||
- The httpGets() function could, in certain states,
|
||||
block waiting for data (STR #132)
|
||||
- The cupsEmitJCL() function not outputs an empty @PJL
|
||||
command after the PJL language escape to work around
|
||||
bugs in certain PJL implementations (STR #131)
|
||||
- The cupsEmit*() functions didn't set the orientation
|
||||
value properly (STR #127)
|
||||
- The cups.spec file didn't list the rc2.d init
|
||||
directory or the cupstestppd file (STR #134)
|
||||
|
||||
|
||||
CHANGES IN CUPS V1.1.19
|
||||
|
||||
- The GNU TLS code incorrectly used
|
||||
gnutls_check_pending() instead of
|
||||
gnutls_record_check_pending() (STR #128)
|
||||
- The ppdEmit() functions output "PageSize Custom"
|
||||
instead of "CustomPageSize True" in the DSC comments.
|
||||
Also, the custom page size code did not use the
|
||||
ParamCustomPageSize attributes (STR #127)
|
||||
- The cupstestppd command did not list the conflicting
|
||||
options (STR #123)
|
||||
- The lpq command did not ensure that there was
|
||||
whitespace between the fields in the job listing (STR
|
||||
#117)
|
||||
- The German web templates had errors (STR #119)
|
||||
- The configure script didn't specify the static
|
||||
libraries properly when configuring with the
|
||||
--disable-shared option (STR #104)
|
||||
- The cups.list file used file dependencies for package
|
||||
formats other than portable, RPM, and Debian (STR #98)
|
||||
- cupsLangGet() didn't use its language cache (STR #97)
|
||||
- "lpq -P" would segfault instead of showing a usage
|
||||
message (STR #94)
|
||||
- Fixed compiler warnings in pdftops filter (STR #96)
|
||||
|
||||
|
||||
CHANGES IN CUPS V1.1.19rc5
|
||||
|
||||
- Jobs with banner pages that were printed to implicit
|
||||
classes would get double banner pages for each
|
||||
file/banner in the job (STR #68)
|
||||
- The mime.convs file was missing the filter definition
|
||||
for Windows BMP (image/x-bitmap) files (STR #85)
|
||||
- The scheduler allowed some READ-ONLY job attributes to
|
||||
be set, which could cause the scheduler to fail on the
|
||||
next restart (STR #82)
|
||||
- The lp and lpr commands did not report when the
|
||||
scheduler was not responding; instead, the user would
|
||||
incorrectly see a "no default destination" error (STR
|
||||
#70)
|
||||
- cupsLangGet() could fail on OSX due to a corrupt
|
||||
language preference (STR #78)
|
||||
- Added more checks for HTTP request timeouts.
|
||||
- The scheduler dropped the first non-alpha character
|
||||
after an open brace when doing attribute substitutions
|
||||
in banner pages (STR #77)
|
||||
- The scheduler child might send SIGUSR1 to the parent
|
||||
before the signal handler was installed; this didn't
|
||||
prevent the scheduler from starting but produced an
|
||||
annoying error message (STR #45)
|
||||
|
||||
|
||||
CHANGES IN CUPS V1.1.19rc4
|
||||
|
||||
- The lp command did not accept "-" for printing from
|
||||
the standard input as required by POSIX 1003.1 (STR
|
||||
#59)
|
||||
- Added the job-originating-host-name information for
|
||||
the page_log file documentation in the SAM (STR #31)
|
||||
- The German web interface templates did not use the
|
||||
right paths for job operations (STR #54)
|
||||
- The scheduler would consume all available CPU if
|
||||
started with a pending job in the queue (STR #35)
|
||||
- The polling daemon allocated an extra localization
|
||||
buffer but did not free it, causing cups-polld to
|
||||
eventually use all available memory (STR #40)
|
||||
|
||||
|
||||
CHANGES IN CUPS V1.1.19rc3
|
||||
|
||||
- The scheduler could get in an infinite loop cancelling
|
||||
jobs using "cancel -u user dest" (STR #48)
|
||||
- The "cancel -u user" command did nothing (it should
|
||||
cancel all jobs on all printers owned by the named
|
||||
user - STR #48)
|
||||
- The scheduler would write 0-length job control files
|
||||
(STR #46)
|
||||
- Updated the French man pages (translation provided by
|
||||
Gilles QUERRET)
|
||||
- The scheduler would delete all printers from
|
||||
printers.conf if a job was active when a HUP signal
|
||||
was handled (STR #47)
|
||||
- The cups-polld program would leak memory if it was
|
||||
unable to send browse packets to the loopback
|
||||
interface (STR #40)
|
||||
- The scheduler did not put the
|
||||
job-originating-host-name attribute in the job
|
||||
attributes group.
|
||||
- The text filter did not default to wrapping text as
|
||||
defined by the IPP implementation document.
|
||||
- Scan backends first, PPDs second (STR #37)
|
||||
- Updated the Netatalk documentation in the SAM (STR #38
|
||||
and #39)
|
||||
- The test suite sent text files to a non-PS print queue,
|
||||
which requires ESP Ghostscript (provided separately).
|
||||
Now send the JPEG test file (STR #33)
|
||||
- The test suite did not show the estimated disk space
|
||||
requirements (STR #33)
|
||||
- The test suite did not set the MaxLogSize directive to
|
||||
0 to prevent log file rotation (STR #33)
|
||||
- The test suite still setup the old CUPS Ghostscript
|
||||
symlinks (STR #33)
|
||||
- The pstops filter did not report the correct number of
|
||||
copies for the page_log file when printing collated
|
||||
copies to a printer that doesn't support them in
|
||||
hardware (STR #32)
|
||||
- cupsLangGet() needs to set the CTYPE locale to "C"
|
||||
(POSIX) to avoid erroneous tolower/toupper values (fix
|
||||
suggested by Bjoern Jacke)
|
||||
- Fixed a typo in the cups.list.in file.
|
||||
- Updated all of the Western European locales to default
|
||||
to ISO-8859-15 (for Euro support, suggested by Bjoern
|
||||
Jacke)
|
||||
- Updated the German message catalog (update provided by
|
||||
Bjoern Jacke)
|
||||
|
||||
|
||||
CHANGES IN CUPS V1.1.19rc2
|
||||
|
||||
- cupsLangGet() now sets the encoding field based on the
|
||||
trailing charset in the locale name, and doesn't look
|
||||
for a message catalog in a specific locale.charset
|
||||
directory. This fixes STR #26 and is more in line
|
||||
with the CUPS 1.2 implementation.
|
||||
- The configure script now aborts if the "ar" command or
|
||||
compilers cannot be found.
|
||||
- The static cupsimage library was not built by default.
|
||||
- The path for the "ln" command was hardcoded in
|
||||
Makedefs.in instead of being checked at configure time
|
||||
(STR #28).
|
||||
- Banner pages containing unescaped { characters would
|
||||
not work.
|
||||
- The printer-state-time collection attribute was
|
||||
encoded as an enumeration instead of an integer.
|
||||
- The printer-is-accepting-jobs collection attribute was
|
||||
was not added to the collection value.
|
||||
- The printer-state-sequence-number collection attribute
|
||||
was not added to the collection value.
|
||||
- Fixed typo and const mismatch in IPP backend.
|
||||
- Updated the man pages for the new configuration
|
||||
directives.
|
||||
- Updated the SAM for MacOS 10.2, the CUPS drivers for
|
||||
windows, the available LPD backend options, and the
|
||||
new configuration directives.
|
||||
- The imagetops filter didn't position images properly
|
||||
on the page (STR #18)
|
||||
- The configure script didn't add CPPFLAGS to the
|
||||
compiler options or LDFLAGS to the DSO options (STR
|
||||
#13)
|
||||
- The scheduler would try to write a debug log message
|
||||
when starting a job that contained a NULL string.
|
||||
Since not all versions of snprintf() support NULL
|
||||
string pointers this caused some problems (STR #20)
|
||||
- The testipp program now supports reading of IPP
|
||||
message files such as those used for the job history
|
||||
in /var/spool/cups.
|
||||
|
||||
|
||||
CHANGES IN CUPS V1.1.19rc1
|
||||
|
||||
- Added CUPS support files for Java, Perl, and PHP
|
||||
(located in the "scripting" subdirectory...)
|
||||
- The scheduler now supports fast-reloads of the
|
||||
cupsd.conf file when it is updated via HTTP.
|
||||
- The scheduler always changed the ownership of log
|
||||
files; it now only does so if they are not in the /dev
|
||||
directory (i.e. don't want to change the ownership and
|
||||
permissions of /dev/null...)
|
||||
- Added libpaper support (patch from Jeff Licquia)
|
||||
- Added a new istring() rule for MIME types files that
|
||||
does a case-insensitive comparison of strings.
|
||||
- The cups-lpd mini-daemon now sends jobs to the default
|
||||
queue when an empty queue name (or "lp" and there is
|
||||
no "lp" queue) is sent.
|
||||
- The scheduler now supports fax queues identified by a
|
||||
"*cupsFax: True" attribute in the PPD file. When a job
|
||||
can't be sent, it is held for 5 minutes by default
|
||||
while other jobs are attempted. The FaxRetryLimit and
|
||||
FaxRetryInterval directives control the number of
|
||||
retries and the time between retries.
|
||||
- The scheduler now preserves the default options of PPD
|
||||
files when modifying/upgrading an existing PPD file.
|
||||
When installing a new printer, the scheduler sets the
|
||||
default media size to Letter or A4 as appropriate for
|
||||
your locale.
|
||||
- The scheduler no longer limits the number of
|
||||
BrowseAddress, BrowsePoll, BrowseRelay, Listen, Port,
|
||||
SSLListen, and SSLPort directives to 10.
|
||||
- The scheduler now supports print files that have been
|
||||
compressed using gzip.
|
||||
- The scheduler used the stdio functions to read any job
|
||||
ticket information in a PostScript print job. Since
|
||||
some platforms limit the number of stdio files to 256,
|
||||
job ticket information was ignored when the server had
|
||||
a large number of clients connected to the system.
|
||||
- Filters and backends may now report the total number
|
||||
of pages ("PAGE: total NNN") to the scheduler.
|
||||
- The LPD backend now supports timeout and
|
||||
sanitize_title options (default to 300 and yes,
|
||||
respectively) and has some additional changes to
|
||||
reduce the chances of multiple copies being printed
|
||||
when only one copy was requested.
|
||||
- Fixed a polygon drawing bug in the HP-GL/2 filter.
|
||||
- Added a robots.txt file to the standard install to
|
||||
prevent search engines from indexing the CUPS server.
|
||||
- Added support for STATE: messages
|
||||
(printer-state-reasons), printer-state-history, and
|
||||
printer-state-time to the scheduler.
|
||||
- When using RunAsUser, the scheduler would initially
|
||||
start any previously queued (pending) jobs with
|
||||
RunAsUser disabled - all backends would be running as
|
||||
root.
|
||||
- If a backend failed for a printer, CUPS would
|
||||
incorrectly requeue the job for printing again.
|
||||
- Added support for IPP collections and files.
|
||||
- Added experimental support for generic CGI scripts and
|
||||
programs, Java, Perl, PHP, and Python to the
|
||||
scheduler. See the file "CGI.txt" for more
|
||||
information.
|
||||
- The CUPS API now supports HTTP cookies and the Expect:
|
||||
field.
|
||||
- The cancel command now correctly supports the "-u
|
||||
user" option to cancel all jobs for the named user.
|
||||
- The Purge-Jobs operation now supports the my-jobs
|
||||
boolean attribute and a new purge-jobs boolean
|
||||
attribute to control whether job history data is
|
||||
purged from the scheduler; the default is false for
|
||||
my-jobs and true for purge-jobs to match the original
|
||||
implementation.
|
||||
- The scheduler would not timeout printers when only
|
||||
using SLP browsing.
|
||||
- If the scheduler was unable to execute a filter, it
|
||||
would try to restart the job indefinitely until the
|
||||
filter could be executed.
|
||||
- When writing BSD printcap files, the scheduler now
|
||||
includes the rm and rp attributes, allowing the file
|
||||
to be exported to LPD clients. [Patch from Dominic
|
||||
Kubla]
|
||||
- The scheduler optimization to reference IPP attribute
|
||||
data instead of performing a full copy caused problems
|
||||
when the referenced data was deleted before it was
|
||||
sent. It now only references attributes that change
|
||||
only when the scheduler is restarted. The change also
|
||||
reduced the memory footprint of a printer object to
|
||||
2k.
|
||||
- The scheduler now holds signals while logging messages
|
||||
to avoid potential deadlock issues when handling
|
||||
signals on Solaris 8.
|
||||
- The lpadmin command now allows printer access control
|
||||
by group name as well as user name.
|
||||
- "lpoptions -l" got in an infinite loop if no default
|
||||
printer was available.
|
||||
- The scheduler now logs the job-originating-host-name
|
||||
attribute in the page_log file, and uses "-" for any
|
||||
empty fields (patch from Dominik Kubla).
|
||||
- The pdftops filter now scales PDF pages within the
|
||||
printable area of the page.
|
||||
- The pstops filter didn't include the page-label and
|
||||
classification boxes when printing EPS or non-
|
||||
conformant PS files.
|
||||
- The imagetops filter didn't always correctly position
|
||||
the image on the page when printing in landscape
|
||||
orientation.
|
||||
- The ppdEmit() functions now support the
|
||||
RequiresPageRegion attribute when sending InputSlot
|
||||
and ManualFeed commands.
|
||||
- The PPD loading code now supports standard options
|
||||
outside of OpenUI/CloseUI as required by the PPD spec.
|
||||
- The cupstestppd program has been upgraded to provide a
|
||||
concise PASS/FAIL report, additional detailed
|
||||
conformance testing, and support for gzip'd PPD files.
|
||||
- The PPD loading code is now much more strict when
|
||||
loading a PPD file, and tracks more format errors.
|
||||
- The scheduler ignored child signals when gathering the
|
||||
list of available devices, when it should have been
|
||||
using the default signal handler.
|
||||
- The cupsEncodeOptions() function could encode an
|
||||
option with a NULL last string.
|
||||
- The socket backend could report the wrong number of
|
||||
backchannel bytes if an error occurred on the link.
|
||||
- The cups-polld program now only sleeps after getting
|
||||
all printers and classes. This allows for longer
|
||||
intervals without excessive delays before classes show
|
||||
up...
|
||||
- Added a new httpWait() function to support waiting for
|
||||
data for a specific number of milliseconds.
|
||||
- httpGets() now times out after 1 second on
|
||||
non-blocking HTTP connections.
|
||||
- The scheduler no longer accepts rangeOfInteger values
|
||||
that are out of order (e.g. 5-1)
|
||||
- The sides attribute was incorrectly sent as a name
|
||||
value; it is a keyword value.
|
||||
- The IPP backend now detects if the destination queue
|
||||
has gone away and reports an error.
|
||||
- The scheduler and HTTP API now allocate their select()
|
||||
sets to support larger numbers of clients on systems
|
||||
that support it.
|
||||
- The scheduler now sets the CFProcessPath environment
|
||||
variable under MacOS X.
|
||||
- The cupsLangDefault() function now uses the
|
||||
CoreFoundation localization API under MacOS X.
|
||||
- The httpSeparate() function didn't handle file URIs of
|
||||
the form "file:///path" properly.
|
||||
- The lpadmin command now supports a "protocol" option
|
||||
for specifying the binary communications protocol to
|
||||
use when printing binary PostScript data.
|
||||
- The scheduler did not properly parse the SystemGroup
|
||||
directive, so only the first group would be used.
|
||||
- Revamped how strings are stored in the scheduler,
|
||||
providing a substantial improvement in memory usage
|
||||
for systems with large numbers of printers.
|
||||
- The PostScript filter now supports binary PostScript
|
||||
files and files beginning with the PJL language escape
|
||||
sequence.
|
||||
- The PPD API now provides additional information from
|
||||
the PPD file.
|
||||
- The USB backend didn't compile on Solaris Intel.
|
||||
- The cupstestppd utility now supports the "-q" option
|
||||
(quiet) for use in scripts, etc.
|
||||
- Merged several weight-reducing changes into the CUPS
|
||||
baseline donated by Apple.
|
||||
- Added preliminary support for CDSA; patch provided by
|
||||
Apple.
|
||||
- Implicit classes are now created from identical
|
||||
printer classes on the network.
|
||||
- The lp command now supports a "-H restart" option to
|
||||
restart previously printed jobs. This functionality
|
||||
only works if you have enabled the PreserveJobFiles
|
||||
option.
|
||||
- The scheduler now supports URIs in HTTP request lines
|
||||
to conform to the HTTP/1.1 specification.
|
||||
- The time-at-xyz attributes were not recognized in
|
||||
banner files if prefixed by a question mark, e.g.
|
||||
"{?time-at-creation}".
|
||||
- Added support for pre-filtering application/pictwps
|
||||
files on MacOS clients before sending them to a server
|
||||
via IPP.
|
||||
- The scheduler now allows file:/dev/null device URIs
|
||||
even if FileDevices is set to No.
|
||||
- CUPS uses strerror() for hostname resolution errors,
|
||||
when it should have used hstrerror().
|
||||
- The USB backend no longer tries to guess the serial
|
||||
number of a device from the USB devices file; this
|
||||
means that printers that don't report their serial
|
||||
numbers in the device ID string will not be
|
||||
individually selectable.
|
||||
- The pstops filter didn't handle page ranges properly
|
||||
when a page contained an embedded document.
|
||||
- Added a translation of the web interface to German.
|
||||
- When printing using the OutputOrder=Reverse option
|
||||
with duplexing, the output order is now truly
|
||||
reversed; the order of sub-pages when printing N-up is
|
||||
the same.
|
||||
- The pstops filter did not always output the extra
|
||||
blank page when printing a document with an odd number
|
||||
of pages with duplexing enabled.
|
||||
- The ippAddXYZ functions no longer allow the
|
||||
application to add less than 1 value.
|
||||
- Fixed a URL rewrite bug in the web interface - local
|
||||
access was sometimes redirected away from localhost...
|
||||
- The ppdOpen() functions could get in an infinite loop
|
||||
if the PPD file contained a keyword or text that was
|
||||
too large for the buffer.
|
||||
- Added preliminary support for GNU TLS; patch provided
|
||||
by Jeff Licquia.
|
||||
- Now timeout IPP attribute reads after 1 second inside
|
||||
an attribute definition.
|
||||
- Now timeout connections that have been shutdown (due
|
||||
to errors) after 30 seconds instead of the Timeout
|
||||
setting (300 seconds by default). This provides
|
||||
faster recovery from DoS attacks.
|
||||
- A denial-of-service attack warning message was being
|
||||
written to the log files by the scheduler for every
|
||||
detection. This caused a DoS of its own in some
|
||||
situations. The warning message is now written no more
|
||||
than once per minute.
|
||||
- Fixed the CIE colorspace support code in the image and
|
||||
PS RIPs.
|
||||
- The job-quota-period, job-page-limit, and job-k-limit
|
||||
attributes were not flagged as integers, so setting
|
||||
quotas would not work.
|
||||
- Added an additional response check in the scheduler to
|
||||
more quickly recover from denial-of-service attacks.
|
||||
- The cupstestppd file was incorrectly installed in the
|
||||
/usr/sbin directory instead of /usr/bin.
|
||||
- The EPM list file did not include the cupstestppd
|
||||
program or man page files.
|
||||
|
||||
|
||||
CHANGES IN CUPS V1.1.18
|
||||
|
||||
- Fixed a bug in the Set-Job-Attributes code in the
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
CREDITS.txt - 12/12/2002
|
||||
CREDITS.txt - 04/26/2003
|
||||
------------------------
|
||||
|
||||
Few projects are completed by one person, and CUPS is no exception. We'd
|
||||
@@ -11,6 +11,7 @@ like to thank the following individuals for their contributions:
|
||||
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.
|
||||
@@ -23,6 +24,7 @@ like to thank the following individuals for their contributions:
|
||||
Ulrich Oldendorf - German locale.
|
||||
Giulio Orsero - Bug fixes and testing.
|
||||
Kurt Pfeifle - Bug fixes, beta testing, evangelism.
|
||||
Gilles QUERRET - French man pages.
|
||||
Petter Reinholdtsen - HP-UX compiler stuff.
|
||||
Stuart Stevens - HP JetDirect IPP information.
|
||||
Andrea Suatoni - IRIX desktop integration and testing.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
ENCRYPTION - CUPS v1.1.7 - 02/21/2001
|
||||
-------------------------------------
|
||||
ENCRYPTION - CUPS v1.1.19 - 05/27/2003
|
||||
--------------------------------------
|
||||
|
||||
This file describes the encryption support provided by CUPS.
|
||||
|
||||
@@ -17,15 +17,16 @@ LEGAL STUFF
|
||||
|
||||
BEFORE USING THE ENCRYPTION SUPPORT, PLEASE VERIFY THAT IT IS
|
||||
LEGAL TO DO SO IN YOUR COUNTRY. CUPS by itself doesn't include
|
||||
any encryption code, but it can link against the OpenSSL library
|
||||
which does.
|
||||
any encryption code, but it can link against the OpenSSL, GNU
|
||||
TLS, or CDSA libraries which do.
|
||||
|
||||
|
||||
OVERVIEW OF ENCRYPTION SUPPORT IN CUPS
|
||||
|
||||
CUPS supports SSL/2.0, SSL/3.0, and TLS/1.0 encryption using
|
||||
keys as large as 128-bits. Encryption support is provided via
|
||||
the OpenSSL library and some new hooks in the CUPS code.
|
||||
the OpenSSL, GNU TLS, or CDSA libraries and some new hooks in
|
||||
the CUPS code.
|
||||
|
||||
CUPS provides support for dedicated (https) and "upgrade" (TLS)
|
||||
encryption of sessions. The "HTTP Upgrade" method is described
|
||||
@@ -79,19 +80,22 @@ to /etc/cups/cupsd.conf.
|
||||
|
||||
BEFORE YOU BEGIN
|
||||
|
||||
You'll need the OpenSSL library from:
|
||||
You'll need the OpenSSL, GNU TLS, or CDSA libraries from:
|
||||
|
||||
http://www.openssl.org
|
||||
http://www.openssl.org/
|
||||
http://www.gnutls.org/
|
||||
http://www.intel.com/labs/archive/cdsa.htm
|
||||
|
||||
|
||||
CONFIGURING WITH ENCRYPTION SUPPORT
|
||||
|
||||
Once you have the OpenSSL library installed, you'll need to
|
||||
configure CUPS to use it with the "--enable-ssl" option:
|
||||
Once you have the OpenSSL, GNU TLS, or CDSA libraries installed,
|
||||
you'll need to configure CUPS to use it with the "--enable-ssl"
|
||||
option:
|
||||
|
||||
./configure --enable-ssl
|
||||
|
||||
If the OpenSSL stuff is not in a standard location, make sure to
|
||||
If the library stuff is not in a standard location, make sure to
|
||||
define the CFLAGS, CXXFLAGS, and LDFLAGS environment variables
|
||||
with the appropriate compiler and linker options first.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
INSTALL - CUPS v1.1.17 - 12/02/2002
|
||||
INSTALL - CUPS v1.1.19 - 05/27/2003
|
||||
-----------------------------------
|
||||
|
||||
This file describes how to compile and install CUPS from source
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
INSTALL_fr - CUPS v1.1.19 - 04/08/2003
|
||||
--------------------------------------
|
||||
|
||||
Vous cherchez des instructions d'installation ? Lisez le fichier
|
||||
INSTALL.txt (anglais) et/ou reportez vous au "Manuel de
|
||||
l'administrateur" (en français) situé dans le sous-répertoire
|
||||
"doc/fr"
|
||||
|
||||
Vous trouverez deux autres manuels en français dans ce
|
||||
sous-répertoire :
|
||||
|
||||
- Aperçu de CUPS
|
||||
- Manuel de l'utilisateur
|
||||
|
||||
Une fois CUPS installé, si vous configurez votre navigateur
|
||||
"web" pour que la langue de base soit le français, vous
|
||||
disposerez également d'une interface "web" en français pour
|
||||
l'administration et d'utilistation de CUPS.
|
||||
|
||||
@@ -26,22 +26,22 @@
|
||||
# Programs...
|
||||
#
|
||||
|
||||
AR = @AR@
|
||||
AWK = @AWK@
|
||||
CC = @LIBTOOL@ @CC@
|
||||
CXX = @LIBTOOL@ @CXX@
|
||||
DSO = @DSO@
|
||||
HTMLDOC = @HTMLDOC@
|
||||
INSTALL = @INSTALL@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LN = /bin/ln -sf
|
||||
MV = @MV@
|
||||
NROFF = @NROFF@
|
||||
RANLIB = @RANLIB@
|
||||
RM = @RM@ -f
|
||||
SED = @SED@
|
||||
SHELL = /bin/sh
|
||||
STRIP = @STRIP@
|
||||
AR = @AR@
|
||||
AWK = @AWK@
|
||||
CC = @LIBTOOL@ @CC@
|
||||
CXX = @LIBTOOL@ @CXX@
|
||||
DSO = @DSO@
|
||||
HTMLDOC = @HTMLDOC@
|
||||
INSTALL = @INSTALL@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LN = @LN@ -sf
|
||||
MV = @MV@
|
||||
NROFF = @NROFF@
|
||||
RANLIB = @RANLIB@
|
||||
RM = @RM@ -f
|
||||
SED = @SED@
|
||||
SHELL = /bin/sh
|
||||
STRIP = @STRIP@
|
||||
|
||||
#
|
||||
# Installation programs...
|
||||
@@ -65,14 +65,15 @@ CUPS_GROUP = @CUPS_GROUP@
|
||||
# Libraries...
|
||||
#
|
||||
|
||||
LIBCUPS = @LIBCUPS@
|
||||
LIBCUPSIMAGE = @LIBCUPSIMAGE@
|
||||
LIBJPEG = @LIBJPEG@
|
||||
LIBMALLOC = @LIBMALLOC@
|
||||
LIBPNG = @LIBPNG@
|
||||
LIBSLP = @LIBSLP@
|
||||
LIBTIFF = @LIBTIFF@
|
||||
LIBZ = @LIBZ@
|
||||
LIBCUPS = @LIBCUPS@
|
||||
LIBCUPSIMAGE = @LIBCUPSIMAGE@
|
||||
LIBJPEG = @LIBJPEG@
|
||||
LIBMALLOC = @LIBMALLOC@
|
||||
LIBPAPER = @LIBPAPER@
|
||||
LIBPNG = @LIBPNG@
|
||||
LIBSLP = @LIBSLP@
|
||||
LIBTIFF = @LIBTIFF@
|
||||
LIBZ = @LIBZ@
|
||||
|
||||
#
|
||||
# Program options...
|
||||
@@ -82,23 +83,25 @@ LIBZ = @LIBZ@
|
||||
# extra debug info)
|
||||
#
|
||||
|
||||
ARFLAGS = @ARFLAGS@
|
||||
BACKLIBS = @BACKLIBS@
|
||||
CFLAGS = $(RC_CFLAGS) @CFLAGS@ -I.. $(OPTIONS)
|
||||
CXXFLAGS = $(RC_CFLAGS) @CXXFLAGS@ -I.. $(OPTIONS)
|
||||
CXXLIBS = @CXXLIBS@
|
||||
DSOFLAGS = @DSOFLAGS@
|
||||
DSOLIBS = @DSOLIBS@
|
||||
IMGLIBS = @IMGLIBS@ -lm
|
||||
LDFLAGS = -L../cups -L../filter $(RC_CFLAGS) @LDFLAGS@ $(OPTIM)
|
||||
LINKCUPS = @LINKCUPS@
|
||||
LINKCUPSIMAGE = @LINKCUPSIMAGE@
|
||||
LIBS = $(LINKCUPS) $(NETLIBS) @LIBS@
|
||||
NETLIBS = @NETLIBS@
|
||||
OPTIM = @OPTIM@
|
||||
OPTIONS =
|
||||
PAMLIBS = @PAMLIBS@
|
||||
SSLLIBS = @SSLLIBS@
|
||||
ARFLAGS = @ARFLAGS@
|
||||
BACKLIBS = @BACKLIBS@
|
||||
CFLAGS = $(RC_CFLAGS) $(SSLFLAGS) @CPPFLAGS@ @CFLAGS@ -I.. $(OPTIONS)
|
||||
COMMONLIBS = @COMMONLIBS@
|
||||
CXXFLAGS = $(RC_CFLAGS) @CPPFLAGS@ @CXXFLAGS@ -I.. $(OPTIONS)
|
||||
CXXLIBS = @CXXLIBS@
|
||||
DSOFLAGS = @DSOFLAGS@
|
||||
DSOLIBS = @DSOLIBS@ $(COMMONLIBS)
|
||||
IMGLIBS = @IMGLIBS@ -lm
|
||||
LDFLAGS = -L../cups -L../filter $(RC_CFLAGS) @LDFLAGS@ $(OPTIM)
|
||||
LINKCUPS = @LINKCUPS@
|
||||
LINKCUPSIMAGE = @LINKCUPSIMAGE@
|
||||
LIBS = $(LINKCUPS) $(NETLIBS) @LIBS@ $(COMMONLIBS)
|
||||
NETLIBS = @NETLIBS@
|
||||
OPTIM = @OPTIM@
|
||||
OPTIONS =
|
||||
PAMLIBS = @PAMLIBS@
|
||||
SSLFLAGS = @SSLFLAGS@
|
||||
SSLLIBS = @SSLLIBS@
|
||||
|
||||
#
|
||||
# Directories...
|
||||
@@ -174,10 +177,11 @@ MAN8DIR = @MAN8DIR@
|
||||
-$(NROFF) -man $< >$@
|
||||
.man.z:
|
||||
echo Formatting $<...
|
||||
$(RM) $@ t.z
|
||||
-$(NROFF) -man $< >t
|
||||
pack -f t
|
||||
$(MV) t.z $@
|
||||
$(RM) $@ $@.tmp $@.tmp.z
|
||||
-$(NROFF) -man $< >$@.tmp
|
||||
pack -f $@.tmp
|
||||
$(MV) $@.tmp.z $@
|
||||
|
||||
|
||||
#
|
||||
# End of "$Id$"
|
||||
|
||||
@@ -105,7 +105,7 @@ install: installhdrs
|
||||
if test "x$(INITDIR)" = "x" -a "x$(INITDDIR)" != "x"; then \
|
||||
$(INSTALL_DIR) $(BUILDROOT)$(INITDDIR); \
|
||||
if test "$(INITDDIR)" = "/System/Library/StartupItems/PrintingServices"; then \
|
||||
$(INSTALL_SCRIPT) cups.sh $(BUILDROOT)$(INITDDIR)/PrintingServices; \
|
||||
$(INSTALL_SCRIPT) cups.osx $(BUILDROOT)$(INITDDIR)/PrintingServices; \
|
||||
$(INSTALL_DATA) cups.plist $(BUILDROOT)$(INITDDIR)/StartupParameters.plist; \
|
||||
$(INSTALL_DIR) $(BUILDROOT)$(INITDDIR)/Resources/English.lproj; \
|
||||
$(INSTALL_DATA) cups.strings $(BUILDROOT)$(INITDDIR)/Resources/English.lproj/Localizable.strings; \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
README - CUPS v1.1.17 - 12/02/2002
|
||||
README - CUPS v1.1.19 - 05/27/2003
|
||||
----------------------------------
|
||||
|
||||
Looking for compile instructions? Read the file "INSTALL.txt"
|
||||
@@ -254,11 +254,7 @@ trademark property of Easy Software Products.
|
||||
|
||||
The MD5 Digest code is Copyright 1999 Aladdin Enterprises.
|
||||
|
||||
The PostScript RIP software (pstoraster) is based on the GNU
|
||||
Ghostscript 5.50 core, Copyright 1986-1998 by Aladdin
|
||||
Enterprises.
|
||||
|
||||
The PDF filter (pdftops) is based on the Xpdf 1.01 software,
|
||||
The PDF filter (pdftops) is based on the Xpdf software,
|
||||
Copyright 1996-2002 by Derek B. Noonburg.
|
||||
|
||||
This software is based in part on the work of the Independent
|
||||
@@ -283,6 +279,5 @@ For commercial licensing information, please contact:
|
||||
WWW: http://www.cups.org
|
||||
|
||||
Note that commercial licensors may also require a license from
|
||||
Artifex Software Inc. which handles commercial licensing of the
|
||||
Ghostscript software, and from Derek B. Noonburg who developed
|
||||
the Xpdf software used to print PDF files.
|
||||
Derek B. Noonburg who developed the Xpdf software used to print
|
||||
PDF files.
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
README_fr - CUPS v1.1.19 - 04/08/2003
|
||||
-------------------------------------
|
||||
|
||||
Vous cherchez des instructions d'installation ? Lisez le fichier
|
||||
INSTALL.txt (anglais) et/ou reportez vous au "Manuel de
|
||||
l'administrateur" (en français) situé dans le sous-répertoire
|
||||
"doc/fr"
|
||||
|
||||
Vous trouverez deux autres manuels en français dans ce
|
||||
sous-répertoire :
|
||||
|
||||
- Aperçu de CUPS
|
||||
- Manuel de l'utilisateur
|
||||
|
||||
Une fois CUPS installé, si vous configurez votre navigateur
|
||||
"web" pour que la langue de base soit le français, vous
|
||||
disposerez également d'une interface "web" en français pour
|
||||
l'administration et d'utilistation de CUPS.
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
betest
|
||||
ipp
|
||||
lpd
|
||||
usb
|
||||
parallel
|
||||
betest
|
||||
scsi
|
||||
serial
|
||||
socket
|
||||
usb
|
||||
|
||||
@@ -7,6 +7,8 @@ lpd.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
|
||||
lpd.o: ../cups/ppd.h ../cups/string.h ../config.h
|
||||
parallel.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
|
||||
parallel.o: ../cups/ppd.h ../cups/string.h ../config.h
|
||||
scsi.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
|
||||
scsi.o: ../cups/ppd.h ../cups/string.h ../config.h
|
||||
serial.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
|
||||
serial.o: ../cups/ppd.h ../cups/string.h ../config.h
|
||||
socket.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
* password_cb() - Disable the password prompt for
|
||||
* cupsDoFileRequest().
|
||||
* report_printer_state() - Report the printer state.
|
||||
* run_pictwps_filter() - Convert PICT files to PostScript when printing
|
||||
* remotely.
|
||||
* sigterm_handler() - Handle 'terminate' signals that stop the backend.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -40,10 +43,22 @@
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <cups/http-private.h>
|
||||
#include <cups/cups.h>
|
||||
#include <cups/language.h>
|
||||
#include <cups/string.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
|
||||
/*
|
||||
* Globals...
|
||||
*/
|
||||
|
||||
static char tmpfilename[1024] = ""; /* Temporary spool file name */
|
||||
#ifdef __APPLE__
|
||||
static char pstmpname[1024] = ""; /* Temporary PostScript file name */
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
|
||||
/*
|
||||
@@ -53,6 +68,11 @@
|
||||
const char *password_cb(const char *);
|
||||
int report_printer_state(ipp_t *ipp);
|
||||
|
||||
#ifdef __APPLE__
|
||||
int run_pictwps_filter(char **argv, const char *filename);
|
||||
#endif /* __APPLE__ */
|
||||
static void sigterm_handler(int sig);
|
||||
|
||||
|
||||
/*
|
||||
* Local globals...
|
||||
@@ -79,8 +99,8 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
char method[255], /* Method in URI */
|
||||
hostname[1024], /* Hostname */
|
||||
username[255], /* Username info */
|
||||
resource[1024], /* Resource info (printer name) */
|
||||
filename[1024]; /* File to print */
|
||||
resource[1024]; /* Resource info (printer name) */
|
||||
char *filename; /* File to print */
|
||||
int port; /* Port number (not used) */
|
||||
char uri[HTTP_MAX_URI];/* Updated URI without user/pass */
|
||||
ipp_status_t ipp_status; /* Status of IPP request */
|
||||
@@ -90,6 +110,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
*supported; /* get-printer-attributes response */
|
||||
ipp_attribute_t *job_id_attr; /* job-id attribute */
|
||||
int job_id; /* job-id value */
|
||||
ipp_attribute_t *job_sheets; /* job-media-sheets-completed attribute */
|
||||
ipp_attribute_t *job_state; /* job-state attribute */
|
||||
ipp_attribute_t *copies_sup; /* copies-supported attribute */
|
||||
ipp_attribute_t *charset_sup; /* charset-supported attribute */
|
||||
@@ -107,6 +128,20 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
|
||||
int version; /* IPP version */
|
||||
int reasons; /* Number of printer-state-reasons shown */
|
||||
static const char * const pattrs[] =
|
||||
{ /* Printer attributes we want */
|
||||
"copies-supported",
|
||||
"charset-supported",
|
||||
"document-format-supported",
|
||||
"printer-is-accepting-jobs",
|
||||
"printer-state",
|
||||
"printer-state-reasons",
|
||||
};
|
||||
static const char * const jattrs[] =
|
||||
{ /* Job attributes we want */
|
||||
"job-media-sheets-completed",
|
||||
"job-state"
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
@@ -116,17 +151,24 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
setbuf(stderr, NULL);
|
||||
|
||||
/*
|
||||
* Ignore SIGPIPE signals...
|
||||
* Ignore SIGPIPE and catch SIGTERM signals...
|
||||
*/
|
||||
|
||||
#ifdef HAVE_SIGSET
|
||||
sigset(SIGPIPE, SIG_IGN);
|
||||
sigset(SIGTERM, sigterm_handler);
|
||||
#elif defined(HAVE_SIGACTION)
|
||||
memset(&action, 0, sizeof(action));
|
||||
action.sa_handler = SIG_IGN;
|
||||
sigaction(SIGPIPE, &action, NULL);
|
||||
|
||||
sigemptyset(&action.sa_mask);
|
||||
sigaddset(&action.sa_mask, SIGTERM);
|
||||
action.sa_handler = sigterm_handler;
|
||||
sigaction(SIGTERM, &action, NULL);
|
||||
#else
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
signal(SIGTERM, sigterm_handler);
|
||||
#endif /* HAVE_SIGSET */
|
||||
|
||||
/*
|
||||
@@ -152,6 +194,18 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the content type...
|
||||
*/
|
||||
|
||||
if (argc > 6)
|
||||
content_type = getenv("CONTENT_TYPE");
|
||||
else
|
||||
content_type = "application/vnd.cups-raw";
|
||||
|
||||
if (content_type == NULL)
|
||||
content_type = "application/octet-stream";
|
||||
|
||||
/*
|
||||
* If we have 7 arguments, print the file named on the command-line.
|
||||
* Otherwise, copy stdin to a temporary file and print the temporary
|
||||
@@ -169,7 +223,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
int bytes; /* Number of bytes read */
|
||||
|
||||
|
||||
if ((fd = cupsTempFd(filename, sizeof(filename))) < 0)
|
||||
if ((fd = cupsTempFd(tmpfilename, sizeof(tmpfilename))) < 0)
|
||||
{
|
||||
perror("ERROR: unable to create temporary file");
|
||||
return (1);
|
||||
@@ -180,14 +234,15 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
{
|
||||
perror("ERROR: unable to write to temporary file");
|
||||
close(fd);
|
||||
unlink(filename);
|
||||
unlink(tmpfilename);
|
||||
return (1);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
filename = tmpfilename;
|
||||
}
|
||||
else
|
||||
strlcpy(filename, argv[6], sizeof(filename));
|
||||
filename = argv[6];
|
||||
|
||||
/*
|
||||
* Extract the hostname and printer name from the URI...
|
||||
@@ -231,7 +286,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
fprintf(stderr, "INFO: Unable to queue job on %s, queuing on next printer in class...\n",
|
||||
hostname);
|
||||
|
||||
if (argc == 6)
|
||||
if (argc == 6 || strcmp(filename, argv[6]))
|
||||
unlink(filename);
|
||||
|
||||
/*
|
||||
@@ -250,6 +305,12 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
hostname);
|
||||
sleep(30);
|
||||
}
|
||||
else if (h_errno)
|
||||
{
|
||||
fprintf(stderr, "INFO: Unable to lookup host \'%s\' - %s\n",
|
||||
hostname, hstrerror(h_errno));
|
||||
sleep(30);
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("ERROR: Unable to connect to IPP host");
|
||||
@@ -303,6 +364,10 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
|
||||
NULL, uri);
|
||||
|
||||
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
|
||||
"requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]),
|
||||
NULL, pattrs);
|
||||
|
||||
/*
|
||||
* Do the request...
|
||||
*/
|
||||
@@ -334,9 +399,21 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
version = 0;
|
||||
httpReconnect(http);
|
||||
}
|
||||
else if (ipp_status == IPP_NOT_FOUND)
|
||||
{
|
||||
fputs("ERROR: Destination printer does not exist!\n", stderr);
|
||||
|
||||
if (supported)
|
||||
ippDelete(supported);
|
||||
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "ERROR: Unable to get printer status (%s)!\n",
|
||||
ippErrorString(ipp_status));
|
||||
sleep(10);
|
||||
}
|
||||
|
||||
if (supported)
|
||||
ippDelete(supported);
|
||||
@@ -403,7 +480,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
ippDelete(supported);
|
||||
httpClose(http);
|
||||
|
||||
if (argc == 6)
|
||||
if (argc == 6 || strcmp(filename, argv[6]))
|
||||
unlink(filename);
|
||||
|
||||
/*
|
||||
@@ -416,28 +493,6 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that we are "connected" to the port, ignore SIGTERM so that we
|
||||
* can finish out any page data the driver sends (e.g. to eject the
|
||||
* current page... Only ignore SIGTERM if we are printing data from
|
||||
* stdin (otherwise you can't cancel raw jobs...)
|
||||
*/
|
||||
|
||||
if (argc < 7)
|
||||
{
|
||||
#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
|
||||
sigset(SIGTERM, SIG_IGN);
|
||||
#elif defined(HAVE_SIGACTION)
|
||||
memset(&action, 0, sizeof(action));
|
||||
|
||||
sigemptyset(&action.sa_mask);
|
||||
action.sa_handler = SIG_IGN;
|
||||
sigaction(SIGTERM, &action, NULL);
|
||||
#else
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
#endif /* HAVE_SIGSET */
|
||||
}
|
||||
|
||||
/*
|
||||
* See if the printer supports multiple copies...
|
||||
*/
|
||||
@@ -532,10 +587,36 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
options = NULL;
|
||||
num_options = cupsParseOptions(argv[5], 0, &options);
|
||||
|
||||
if (argc > 6)
|
||||
content_type = getenv("CONTENT_TYPE");
|
||||
else
|
||||
content_type = "application/vnd.cups-raw";
|
||||
#ifdef __APPLE__
|
||||
if (content_type != NULL && strcasecmp(content_type, "application/pictwps") == 0)
|
||||
{
|
||||
if (format_sup != NULL)
|
||||
{
|
||||
for (i = 0; i < format_sup->num_values; i ++)
|
||||
if (strcasecmp(content_type, format_sup->values[i].string.text) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (format_sup == NULL || i >= format_sup->num_values)
|
||||
{
|
||||
/*
|
||||
* Remote doesn't support "application/pictwps" (i.e. it's not MacOS X)
|
||||
* so convert the document to PostScript...
|
||||
*/
|
||||
|
||||
if (run_pictwps_filter(argv, filename))
|
||||
return (1);
|
||||
|
||||
filename = pstmpname;
|
||||
|
||||
/*
|
||||
* Change the MIME type to application/postscript...
|
||||
*/
|
||||
|
||||
content_type = "application/postscript";
|
||||
}
|
||||
}
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
if (content_type != NULL && format_sup != NULL)
|
||||
{
|
||||
@@ -660,8 +741,9 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
|
||||
NULL, argv[2]);
|
||||
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
|
||||
"requested-attributes", NULL, "job-state");
|
||||
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
|
||||
"requested-attributes", sizeof(jattrs) / sizeof(jattrs[0]),
|
||||
NULL, jattrs);
|
||||
|
||||
/*
|
||||
* Do the request...
|
||||
@@ -700,17 +782,26 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((job_state = ippFindAttribute(response, "job-state", IPP_TAG_ENUM)) != NULL)
|
||||
{
|
||||
/*
|
||||
* Stop polling if the job is finished or pending-held...
|
||||
*/
|
||||
|
||||
if (job_state->values[0].integer > IPP_JOB_PROCESSING ||
|
||||
job_state->values[0].integer == IPP_JOB_HELD)
|
||||
if (response != NULL)
|
||||
{
|
||||
if ((job_sheets = ippFindAttribute(response, "job-media-sheets-completed",
|
||||
IPP_TAG_INTEGER)) != NULL)
|
||||
fprintf(stderr, "PAGE: total %d\n", job_sheets->values[0].integer);
|
||||
|
||||
if ((job_state = ippFindAttribute(response, "job-state",
|
||||
IPP_TAG_ENUM)) != NULL)
|
||||
{
|
||||
ippDelete(response);
|
||||
break;
|
||||
/*
|
||||
* Stop polling if the job is finished or pending-held...
|
||||
*/
|
||||
|
||||
if (job_state->values[0].integer > IPP_JOB_PROCESSING ||
|
||||
job_state->values[0].integer == IPP_JOB_HELD)
|
||||
{
|
||||
ippDelete(response);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -774,11 +865,16 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
ippDelete(supported);
|
||||
|
||||
/*
|
||||
* Close and remove the temporary file if necessary...
|
||||
* Remove the temporary file(s) if necessary...
|
||||
*/
|
||||
|
||||
if (argc < 7)
|
||||
unlink(filename);
|
||||
if (tmpfilename[0])
|
||||
unlink(tmpfilename);
|
||||
|
||||
#ifdef __APPLE__
|
||||
if (pstmpname[0])
|
||||
unlink(pstmpname);
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
/*
|
||||
* Return the queue status...
|
||||
@@ -814,74 +910,86 @@ report_printer_state(ipp_t *ipp) /* I - IPP response */
|
||||
int i; /* Looping var */
|
||||
int count; /* Count of reasons shown... */
|
||||
ipp_attribute_t *reasons; /* printer-state-reasons */
|
||||
const char *reason; /* Current reason */
|
||||
const char *message; /* Message to show */
|
||||
char unknown[1024]; /* Unknown message string */
|
||||
const char *prefix; /* Prefix for STATE: line */
|
||||
char state[1024]; /* State string */
|
||||
|
||||
|
||||
if ((reasons = ippFindAttribute(ipp, "printer-state-reasons",
|
||||
IPP_TAG_KEYWORD)) == NULL)
|
||||
return (0);
|
||||
|
||||
state[0] = '\0';
|
||||
prefix = "STATE: ";
|
||||
|
||||
for (i = 0, count = 0; i < reasons->num_values; i ++)
|
||||
{
|
||||
reason = reasons->values[i].string.text;
|
||||
|
||||
strlcat(state, prefix, sizeof(state));
|
||||
strlcat(state, reason, sizeof(state));
|
||||
|
||||
prefix = ",";
|
||||
message = NULL;
|
||||
|
||||
if (strncmp(reasons->values[i].string.text, "media-needed", 12) == 0)
|
||||
if (strncmp(reason, "media-needed", 12) == 0)
|
||||
message = "Media tray needs to be filled.";
|
||||
else if (strncmp(reasons->values[i].string.text, "media-jam", 9) == 0)
|
||||
else if (strncmp(reason, "media-jam", 9) == 0)
|
||||
message = "Media jam!";
|
||||
else if (strncmp(reasons->values[i].string.text, "moving-to-paused", 16) == 0 ||
|
||||
strncmp(reasons->values[i].string.text, "paused", 6) == 0 ||
|
||||
strncmp(reasons->values[i].string.text, "shutdown", 8) == 0)
|
||||
else if (strncmp(reason, "moving-to-paused", 16) == 0 ||
|
||||
strncmp(reason, "paused", 6) == 0 ||
|
||||
strncmp(reason, "shutdown", 8) == 0)
|
||||
message = "Printer off-line.";
|
||||
else if (strncmp(reasons->values[i].string.text, "toner-low", 9) == 0)
|
||||
else if (strncmp(reason, "toner-low", 9) == 0)
|
||||
message = "Toner low.";
|
||||
else if (strncmp(reasons->values[i].string.text, "toner-empty", 11) == 0)
|
||||
else if (strncmp(reason, "toner-empty", 11) == 0)
|
||||
message = "Out of toner!";
|
||||
else if (strncmp(reasons->values[i].string.text, "cover-open", 10) == 0)
|
||||
else if (strncmp(reason, "cover-open", 10) == 0)
|
||||
message = "Cover open.";
|
||||
else if (strncmp(reasons->values[i].string.text, "interlock-open", 14) == 0)
|
||||
else if (strncmp(reason, "interlock-open", 14) == 0)
|
||||
message = "Interlock open.";
|
||||
else if (strncmp(reasons->values[i].string.text, "door-open", 9) == 0)
|
||||
else if (strncmp(reason, "door-open", 9) == 0)
|
||||
message = "Door open.";
|
||||
else if (strncmp(reasons->values[i].string.text, "input-tray-missing", 18) == 0)
|
||||
else if (strncmp(reason, "input-tray-missing", 18) == 0)
|
||||
message = "Media tray missing!";
|
||||
else if (strncmp(reasons->values[i].string.text, "media-low", 9) == 0)
|
||||
else if (strncmp(reason, "media-low", 9) == 0)
|
||||
message = "Media tray almost empty.";
|
||||
else if (strncmp(reasons->values[i].string.text, "media-empty", 11) == 0)
|
||||
else if (strncmp(reason, "media-empty", 11) == 0)
|
||||
message = "Media tray empty!";
|
||||
else if (strncmp(reasons->values[i].string.text, "output-tray-missing", 19) == 0)
|
||||
else if (strncmp(reason, "output-tray-missing", 19) == 0)
|
||||
message = "Output tray missing!";
|
||||
else if (strncmp(reasons->values[i].string.text, "output-area-almost-full", 23) == 0)
|
||||
else if (strncmp(reason, "output-area-almost-full", 23) == 0)
|
||||
message = "Output bin almost full.";
|
||||
else if (strncmp(reasons->values[i].string.text, "output-area-full", 16) == 0)
|
||||
else if (strncmp(reason, "output-area-full", 16) == 0)
|
||||
message = "Output bin full!";
|
||||
else if (strncmp(reasons->values[i].string.text, "marker-supply-low", 17) == 0)
|
||||
else if (strncmp(reason, "marker-supply-low", 17) == 0)
|
||||
message = "Ink/toner almost empty.";
|
||||
else if (strncmp(reasons->values[i].string.text, "marker-supply-empty", 19) == 0)
|
||||
else if (strncmp(reason, "marker-supply-empty", 19) == 0)
|
||||
message = "Ink/toner empty!";
|
||||
else if (strncmp(reasons->values[i].string.text, "marker-waste-almost-full", 24) == 0)
|
||||
else if (strncmp(reason, "marker-waste-almost-full", 24) == 0)
|
||||
message = "Ink/toner waste bin almost full.";
|
||||
else if (strncmp(reasons->values[i].string.text, "marker-waste-full", 17) == 0)
|
||||
else if (strncmp(reason, "marker-waste-full", 17) == 0)
|
||||
message = "Ink/toner waste bin full!";
|
||||
else if (strncmp(reasons->values[i].string.text, "fuser-over-temp", 15) == 0)
|
||||
else if (strncmp(reason, "fuser-over-temp", 15) == 0)
|
||||
message = "Fuser temperature high!";
|
||||
else if (strncmp(reasons->values[i].string.text, "fuser-under-temp", 16) == 0)
|
||||
else if (strncmp(reason, "fuser-under-temp", 16) == 0)
|
||||
message = "Fuser temperature low!";
|
||||
else if (strncmp(reasons->values[i].string.text, "opc-near-eol", 12) == 0)
|
||||
else if (strncmp(reason, "opc-near-eol", 12) == 0)
|
||||
message = "OPC almost at end-of-life.";
|
||||
else if (strncmp(reasons->values[i].string.text, "opc-life-over", 13) == 0)
|
||||
else if (strncmp(reason, "opc-life-over", 13) == 0)
|
||||
message = "OPC at end-of-life!";
|
||||
else if (strncmp(reasons->values[i].string.text, "developer-low", 13) == 0)
|
||||
else if (strncmp(reason, "developer-low", 13) == 0)
|
||||
message = "Developer almost empty.";
|
||||
else if (strncmp(reasons->values[i].string.text, "developer-empty", 15) == 0)
|
||||
else if (strncmp(reason, "developer-empty", 15) == 0)
|
||||
message = "Developer empty!";
|
||||
else if (strstr(reasons->values[i].string.text, "error") != NULL)
|
||||
else if (strstr(reason, "error") != NULL)
|
||||
{
|
||||
message = unknown;
|
||||
|
||||
snprintf(unknown, sizeof(unknown), "Unknown printer error (%s)!",
|
||||
reasons->values[i].string.text);
|
||||
reason);
|
||||
}
|
||||
|
||||
if (message)
|
||||
@@ -896,10 +1004,207 @@ report_printer_state(ipp_t *ipp) /* I - IPP response */
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s\n", state);
|
||||
|
||||
return (count);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __APPLE__
|
||||
/*
|
||||
* 'run_pictwps_filter()' - Convert PICT files to PostScript when printing
|
||||
* remotely.
|
||||
*
|
||||
* This step is required because the PICT format is not documented and
|
||||
* subject to change, so developing a filter for other OS's is infeasible.
|
||||
* Also, fonts required by the PICT file need to be embedded on the
|
||||
* client side (which has the fonts), so we run the filter to get a
|
||||
* PostScript file for printing...
|
||||
*/
|
||||
|
||||
int /* O - Exit status of filter */
|
||||
run_pictwps_filter(char **argv, /* I - Command-line arguments */
|
||||
const char *filename) /* I - Filename */
|
||||
{
|
||||
struct stat fileinfo; /* Print file information */
|
||||
const char *ppdfile; /* PPD file for destination printer */
|
||||
int pid; /* Child process ID */
|
||||
int fd; /* Temporary file descriptor */
|
||||
int status; /* Exit status of filter */
|
||||
const char *printer; /* PRINTER env var */
|
||||
static char ppdenv[1024]; /* PPD environment variable */
|
||||
|
||||
|
||||
/*
|
||||
* First get the PPD file for the printer...
|
||||
*/
|
||||
|
||||
printer = getenv("PRINTER");
|
||||
if (!printer)
|
||||
{
|
||||
fputs("ERROR: PRINTER environment variable not defined!\n", stderr);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if ((ppdfile = cupsGetPPD(printer)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n",
|
||||
printer, ippErrorString(cupsLastError()));
|
||||
/*return (-1);*/
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(ppdenv, sizeof(ppdenv), "PPD=%s", ppdfile);
|
||||
putenv(ppdenv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Then create a temporary file for printing...
|
||||
*/
|
||||
|
||||
if ((fd = cupsTempFd(pstmpname, sizeof(pstmpname))) < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Unable to create temporary file - %s.\n",
|
||||
strerror(errno));
|
||||
if (ppdfile)
|
||||
unlink(ppdfile);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the owner of the spool file - it is owned by the user we want to run
|
||||
* as...
|
||||
*/
|
||||
|
||||
if (argv[6])
|
||||
stat(argv[6], &fileinfo);
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Use the OSX defaults, as an up-stream filter created the PICT
|
||||
* file...
|
||||
*/
|
||||
|
||||
fileinfo.st_uid = 1;
|
||||
fileinfo.st_gid = 80;
|
||||
}
|
||||
|
||||
if (ppdfile)
|
||||
chown(ppdfile, fileinfo.st_uid, fileinfo.st_gid);
|
||||
|
||||
fchown(fd, fileinfo.st_uid, fileinfo.st_gid);
|
||||
|
||||
/*
|
||||
* Finally, run the filter to convert the file...
|
||||
*/
|
||||
|
||||
if ((pid = fork()) == 0)
|
||||
{
|
||||
/*
|
||||
* Child process for pictwpstops... Redirect output of pictwpstops to a
|
||||
* file...
|
||||
*/
|
||||
|
||||
close(1);
|
||||
dup(fd);
|
||||
close(fd);
|
||||
|
||||
if (!getuid())
|
||||
{
|
||||
/*
|
||||
* Change to an unpriviledged user...
|
||||
*/
|
||||
|
||||
setgid(fileinfo.st_gid);
|
||||
setuid(fileinfo.st_uid);
|
||||
}
|
||||
|
||||
execlp("pictwpstops", printer, argv[1], argv[2], argv[3], argv[4], argv[5],
|
||||
filename, NULL);
|
||||
perror("ERROR: Unable to exec pictwpstops");
|
||||
return (errno);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
if (pid < 0)
|
||||
{
|
||||
/*
|
||||
* Error!
|
||||
*/
|
||||
|
||||
perror("ERROR: Unable to fork pictwpstops");
|
||||
unlink(filename);
|
||||
if (ppdfile)
|
||||
unlink(ppdfile);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now wait for the filter to complete...
|
||||
*/
|
||||
|
||||
if (wait(&status) < 0)
|
||||
{
|
||||
perror("ERROR: Unable to wait for pictwpstops");
|
||||
close(fd);
|
||||
unlink(filename);
|
||||
if (ppdfile)
|
||||
unlink(ppdfile);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (ppdfile)
|
||||
unlink(ppdfile);
|
||||
|
||||
close(fd);
|
||||
|
||||
if (status)
|
||||
{
|
||||
if (status >= 256)
|
||||
fprintf(stderr, "ERROR: pictwpstops exited with status %d!\n",
|
||||
status / 256);
|
||||
else
|
||||
fprintf(stderr, "ERROR: pictwpstops exited on signal %d!\n",
|
||||
status);
|
||||
|
||||
unlink(filename);
|
||||
return (status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return with no errors..
|
||||
*/
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
|
||||
/*
|
||||
* 'sigterm_handler()' - Handle 'terminate' signals that stop the backend.
|
||||
*/
|
||||
|
||||
static void
|
||||
sigterm_handler(int sig) /* I - Signal */
|
||||
{
|
||||
(void)sig; /* remove compiler warnings... */
|
||||
|
||||
/*
|
||||
* Remove the temporary file(s) if necessary...
|
||||
*/
|
||||
|
||||
if (tmpfilename[0])
|
||||
unlink(tmpfilename);
|
||||
|
||||
#ifdef __APPLE__
|
||||
if (pstmpname[0])
|
||||
unlink(pstmpname);
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id$".
|
||||
|
||||
@@ -25,11 +25,13 @@
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* main() - Send a file to the printer or server.
|
||||
* lpd_command() - Send an LPR command sequence and wait for a reply.
|
||||
* lpd_queue() - Queue a file using the Line Printer Daemon protocol.
|
||||
* lpd_timeout() - Handle timeout alarms...
|
||||
* lpd_write() - Write a buffer of data to an LPD server.
|
||||
* main() - Send a file to the printer or server.
|
||||
* lpd_command() - Send an LPR command sequence and wait for a reply.
|
||||
* lpd_queue() - Queue a file using the Line Printer Daemon protocol.
|
||||
* lpd_timeout() - Handle timeout alarms...
|
||||
* lpd_write() - Write a buffer of data to an LPD server.
|
||||
* rresvport() - A simple implementation of rresvport().
|
||||
* sigterm_handler() - Handle 'terminate' signals that stop the backend.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -41,6 +43,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <cups/http-private.h>
|
||||
#include <cups/string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
@@ -57,6 +60,13 @@
|
||||
#endif /* WIN32 */
|
||||
|
||||
|
||||
/*
|
||||
* Globals...
|
||||
*/
|
||||
|
||||
static char tmpfilename[1024] = ""; /* Temporary spool file name */
|
||||
|
||||
|
||||
/*
|
||||
* The order for control and data files in LPD requests...
|
||||
*/
|
||||
@@ -76,13 +86,15 @@ extern int rresvport(int *port);
|
||||
* Local functions...
|
||||
*/
|
||||
|
||||
static int lpd_command(int lpd_fd, char *format, ...);
|
||||
static int lpd_queue(char *hostname, char *printer, char *filename,
|
||||
int fromstdin, char *user, char *title, int copies,
|
||||
static int lpd_command(int lpd_fd, int timeout, char *format, ...);
|
||||
static int lpd_queue(const char *hostname, int port, const char *printer,
|
||||
const char *filename,
|
||||
const char *user, const char *title, int copies,
|
||||
int banner, int format, int order, int reserve,
|
||||
int manual_copies);
|
||||
int manual_copies, int timeout);
|
||||
static void lpd_timeout(int sig);
|
||||
static int lpd_write(int lpd_fd, char *buffer, int length);
|
||||
static void sigterm_handler(int sig);
|
||||
|
||||
|
||||
/*
|
||||
@@ -93,31 +105,32 @@ static int lpd_write(int lpd_fd, char *buffer, int length);
|
||||
* printer-uri job-id user title copies options [file]
|
||||
*/
|
||||
|
||||
int /* O - Exit status */
|
||||
main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
int /* O - Exit status */
|
||||
main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
{
|
||||
char method[255], /* Method in URI */
|
||||
hostname[1024], /* Hostname */
|
||||
username[255], /* Username info (not used) */
|
||||
resource[1024], /* Resource info (printer name) */
|
||||
*options, /* Pointer to options */
|
||||
name[255], /* Name of option */
|
||||
value[255], /* Value of option */
|
||||
*ptr, /* Pointer into name or value */
|
||||
filename[1024], /* File to print */
|
||||
title[256]; /* Title string */
|
||||
int port; /* Port number (not used) */
|
||||
int status; /* Status of LPD job */
|
||||
int banner; /* Print banner page? */
|
||||
int format; /* Print format */
|
||||
int order; /* Order of control/data files */
|
||||
int reserve; /* Reserve priviledged port? */
|
||||
int manual_copies, /* Do manual copies? */
|
||||
copies; /* Number of copies */
|
||||
char method[255], /* Method in URI */
|
||||
hostname[1024], /* Hostname */
|
||||
username[255], /* Username info (not used) */
|
||||
resource[1024], /* Resource info (printer name) */
|
||||
*options, /* Pointer to options */
|
||||
name[255], /* Name of option */
|
||||
value[255], /* Value of option */
|
||||
*ptr, /* Pointer into name or value */
|
||||
*filename, /* File to print */
|
||||
title[256]; /* Title string */
|
||||
int port; /* Port number (not used) */
|
||||
int status; /* Status of LPD job */
|
||||
int banner; /* Print banner page? */
|
||||
int format; /* Print format */
|
||||
int order; /* Order of control/data files */
|
||||
int reserve; /* Reserve priviledged port? */
|
||||
int sanitize_title; /* Sanitize title string? */
|
||||
int manual_copies, /* Do manual copies? */
|
||||
timeout, /* Timeout */
|
||||
copies; /* Number of copies */
|
||||
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
|
||||
struct sigaction action;
|
||||
/* Actions for POSIX signals */
|
||||
struct sigaction action; /* Actions for POSIX signals */
|
||||
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
|
||||
|
||||
|
||||
@@ -128,17 +141,24 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
setbuf(stderr, NULL);
|
||||
|
||||
/*
|
||||
* Ignore SIGPIPE signals...
|
||||
* Ignore SIGPIPE and catch SIGTERM signals...
|
||||
*/
|
||||
|
||||
#ifdef HAVE_SIGSET
|
||||
sigset(SIGPIPE, SIG_IGN);
|
||||
sigset(SIGTERM, sigterm_handler);
|
||||
#elif defined(HAVE_SIGACTION)
|
||||
memset(&action, 0, sizeof(action));
|
||||
action.sa_handler = SIG_IGN;
|
||||
sigaction(SIGPIPE, &action, NULL);
|
||||
|
||||
sigemptyset(&action.sa_mask);
|
||||
sigaddset(&action.sa_mask, SIGTERM);
|
||||
action.sa_handler = sigterm_handler;
|
||||
sigaction(SIGTERM, &action, NULL);
|
||||
#else
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
signal(SIGTERM, sigterm_handler);
|
||||
#endif /* HAVE_SIGSET */
|
||||
|
||||
/*
|
||||
@@ -174,7 +194,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
int bytes; /* Number of bytes read */
|
||||
|
||||
|
||||
if ((fd = cupsTempFd(filename, sizeof(filename))) < 0)
|
||||
if ((fd = cupsTempFd(tmpfilename, sizeof(tmpfilename))) < 0)
|
||||
{
|
||||
perror("ERROR: unable to create temporary file");
|
||||
return (1);
|
||||
@@ -185,14 +205,15 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
{
|
||||
perror("ERROR: unable to write to temporary file");
|
||||
close(fd);
|
||||
unlink(filename);
|
||||
unlink(tmpfilename);
|
||||
return (1);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
filename = tmpfilename;
|
||||
}
|
||||
else
|
||||
strlcpy(filename, argv[6], sizeof(filename));
|
||||
filename = argv[6];
|
||||
|
||||
/*
|
||||
* Extract the hostname and printer name from the URI...
|
||||
@@ -204,11 +225,13 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
* See if there are any options...
|
||||
*/
|
||||
|
||||
banner = 0;
|
||||
format = 'l';
|
||||
order = ORDER_CONTROL_DATA;
|
||||
reserve = 0;
|
||||
manual_copies = 1;
|
||||
banner = 0;
|
||||
format = 'l';
|
||||
order = ORDER_CONTROL_DATA;
|
||||
reserve = 0;
|
||||
manual_copies = 1;
|
||||
timeout = 300;
|
||||
sanitize_title = 1;
|
||||
|
||||
if ((options = strchr(resource, '?')) != NULL)
|
||||
{
|
||||
@@ -304,7 +327,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
else if (strcasecmp(name, "manual_copies") == 0)
|
||||
{
|
||||
/*
|
||||
* Set port reservation mode...
|
||||
* Set manual copies...
|
||||
*/
|
||||
|
||||
manual_copies = !value[0] ||
|
||||
@@ -312,6 +335,26 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
strcasecmp(value, "yes") == 0 ||
|
||||
strcasecmp(value, "true") == 0;
|
||||
}
|
||||
else if (strcasecmp(name, "sanitize_title") == 0)
|
||||
{
|
||||
/*
|
||||
* Set sanitize title...
|
||||
*/
|
||||
|
||||
sanitize_title = !value[0] ||
|
||||
strcasecmp(value, "on") == 0 ||
|
||||
strcasecmp(value, "yes") == 0 ||
|
||||
strcasecmp(value, "true") == 0;
|
||||
}
|
||||
else if (strcasecmp(name, "timeout") == 0)
|
||||
{
|
||||
/*
|
||||
* Set the timeout...
|
||||
*/
|
||||
|
||||
if (atoi(value) > 0)
|
||||
timeout = atoi(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,9 +364,17 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
|
||||
strlcpy(title, argv[3], sizeof(title));
|
||||
|
||||
for (ptr = title; *ptr; ptr ++)
|
||||
if (!isalnum(*ptr) && !isspace(*ptr))
|
||||
*ptr = '_';
|
||||
if (sanitize_title)
|
||||
{
|
||||
/*
|
||||
* Sanitize the title string so that we don't cause problems on
|
||||
* the remote end...
|
||||
*/
|
||||
|
||||
for (ptr = title; *ptr; ptr ++)
|
||||
if (!isalnum(*ptr) && !isspace(*ptr))
|
||||
*ptr = '_';
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue the job...
|
||||
@@ -342,24 +393,24 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
copies = atoi(argv[4]);
|
||||
}
|
||||
|
||||
status = lpd_queue(hostname, resource + 1, filename, 0,
|
||||
status = lpd_queue(hostname, port, resource + 1, filename,
|
||||
argv[2] /* user */, title, copies,
|
||||
banner, format, order, reserve, manual_copies);
|
||||
banner, format, order, reserve, manual_copies, timeout);
|
||||
|
||||
if (!status)
|
||||
fprintf(stderr, "PAGE: 1 %d\n", atoi(argv[4]));
|
||||
}
|
||||
else
|
||||
status = lpd_queue(hostname, resource + 1, filename, 1,
|
||||
status = lpd_queue(hostname, port, resource + 1, filename,
|
||||
argv[2] /* user */, title, 1,
|
||||
banner, format, order, reserve, 1);
|
||||
banner, format, order, reserve, 1, timeout);
|
||||
|
||||
/*
|
||||
* Remove the temporary file if necessary...
|
||||
*/
|
||||
|
||||
if (argc < 7)
|
||||
unlink(filename);
|
||||
if (tmpfilename[0])
|
||||
unlink(tmpfilename);
|
||||
|
||||
/*
|
||||
* Return the queue status...
|
||||
@@ -375,6 +426,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
|
||||
static int /* O - Status of command */
|
||||
lpd_command(int fd, /* I - Socket connection to LPD host */
|
||||
int timeout, /* I - Seconds to wait for a response */
|
||||
char *format, /* I - printf()-style format string */
|
||||
...) /* I - Additional args as necessary */
|
||||
{
|
||||
@@ -400,10 +452,11 @@ lpd_command(int fd, /* I - Socket connection to LPD host */
|
||||
|
||||
fprintf(stderr, "DEBUG: Sending command string (%d bytes)...\n", bytes);
|
||||
|
||||
alarm(30);
|
||||
|
||||
if (lpd_write(fd, buf, bytes) < bytes)
|
||||
{
|
||||
perror("ERROR: Unable to send LPD command");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read back the status from the command and return it...
|
||||
@@ -411,10 +464,14 @@ lpd_command(int fd, /* I - Socket connection to LPD host */
|
||||
|
||||
fprintf(stderr, "DEBUG: Reading command status...\n");
|
||||
|
||||
alarm(30);
|
||||
alarm(timeout);
|
||||
|
||||
if (recv(fd, &status, 1, 0) < 1)
|
||||
{
|
||||
fprintf(stderr, "WARNING: Remote host did not respond with command "
|
||||
"status byte after %d seconds!\n", timeout);
|
||||
status = errno;
|
||||
}
|
||||
|
||||
alarm(0);
|
||||
|
||||
@@ -428,25 +485,26 @@ lpd_command(int fd, /* I - Socket connection to LPD host */
|
||||
* 'lpd_queue()' - Queue a file using the Line Printer Daemon protocol.
|
||||
*/
|
||||
|
||||
static int /* O - Zero on success, non-zero on failure */
|
||||
lpd_queue(char *hostname, /* I - Host to connect to */
|
||||
char *printer, /* I - Printer/queue name */
|
||||
char *filename, /* I - File to print */
|
||||
int fromstdin, /* I - Printing from stdin? */
|
||||
char *user, /* I - Requesting user */
|
||||
char *title, /* I - Job title */
|
||||
int copies, /* I - Number of copies */
|
||||
int banner, /* I - Print LPD banner? */
|
||||
int format, /* I - Format specifier */
|
||||
int order, /* I - Order of data/control files */
|
||||
int reserve, /* I - Reserve ports? */
|
||||
int manual_copies) /* I - Do copies by hand... */
|
||||
static int /* O - Zero on success, non-zero on failure */
|
||||
lpd_queue(const char *hostname, /* I - Host to connect to */
|
||||
int port, /* I - Port to connect on */
|
||||
const char *printer, /* I - Printer/queue name */
|
||||
const char *filename, /* I - File to print */
|
||||
const char *user, /* I - Requesting user */
|
||||
const char *title, /* I - Job title */
|
||||
int copies, /* I - Number of copies */
|
||||
int banner, /* I - Print LPD banner? */
|
||||
int format, /* I - Format specifier */
|
||||
int order, /* I - Order of data/control files */
|
||||
int reserve, /* I - Reserve ports? */
|
||||
int manual_copies, /* I - Do copies by hand... */
|
||||
int timeout) /* I - Timeout... */
|
||||
{
|
||||
FILE *fp; /* Job file */
|
||||
char localhost[255]; /* Local host name */
|
||||
int error; /* Error number */
|
||||
struct stat filestats; /* File statistics */
|
||||
int port; /* LPD connection port */
|
||||
int lport; /* LPD connection local port */
|
||||
int fd; /* LPD socket */
|
||||
char control[10240], /* LPD control 'file' */
|
||||
*cptr; /* Pointer into control file string */
|
||||
@@ -491,7 +549,7 @@ lpd_queue(char *hostname, /* I - Host to connect to */
|
||||
if ((hostaddr = httpGetHostByName(hostname)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Unable to locate printer \'%s\' - %s\n",
|
||||
hostname, strerror(errno));
|
||||
hostname, hstrerror(h_errno));
|
||||
return (1);
|
||||
}
|
||||
|
||||
@@ -501,9 +559,9 @@ lpd_queue(char *hostname, /* I - Host to connect to */
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
memcpy(&(addr.sin_addr), hostaddr->h_addr, hostaddr->h_length);
|
||||
addr.sin_family = hostaddr->h_addrtype;
|
||||
addr.sin_port = htons(515); /* LPD/printer service */
|
||||
addr.sin_port = htons(port);
|
||||
|
||||
for (port = 732;;)
|
||||
for (lport = 732;;)
|
||||
{
|
||||
if (getuid() || !reserve)
|
||||
{
|
||||
@@ -517,16 +575,16 @@ lpd_queue(char *hostname, /* I - Host to connect to */
|
||||
return (1);
|
||||
}
|
||||
|
||||
port = 515;
|
||||
lport = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* We're running as root and want to comply with RFC 1179. Reserve a
|
||||
* priviledged port between 721 and 732...
|
||||
* priviledged lport between 721 and 732...
|
||||
*/
|
||||
|
||||
if ((fd = rresvport(&port)) < 0)
|
||||
if ((fd = rresvport(&lport)) < 0)
|
||||
{
|
||||
perror("ERROR: Unable to reserve port");
|
||||
sleep(30);
|
||||
@@ -563,29 +621,9 @@ lpd_queue(char *hostname, /* I - Host to connect to */
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stderr, "INFO: Connected from port %d...\n", port);
|
||||
|
||||
/*
|
||||
* Now that we are "connected" to the port, ignore SIGTERM so that we
|
||||
* can finish out any page data the driver sends (e.g. to eject the
|
||||
* current page... Only ignore SIGTERM if we are printing data from
|
||||
* stdin (otherwise you can't cancel raw jobs...)
|
||||
*/
|
||||
|
||||
if (fromstdin)
|
||||
{
|
||||
#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
|
||||
sigset(SIGTERM, SIG_IGN);
|
||||
#elif defined(HAVE_SIGACTION)
|
||||
memset(&action, 0, sizeof(action));
|
||||
|
||||
sigemptyset(&action.sa_mask);
|
||||
action.sa_handler = SIG_IGN;
|
||||
sigaction(SIGTERM, &action, NULL);
|
||||
#else
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
#endif /* HAVE_SIGSET */
|
||||
}
|
||||
fprintf(stderr, "INFO: Connected to %s...\n", hostname);
|
||||
fprintf(stderr, "DEBUG: Connected on ports %d (local %d)...\n", port,
|
||||
lport);
|
||||
|
||||
/*
|
||||
* Next, open the print file and figure out its size...
|
||||
@@ -610,17 +648,21 @@ lpd_queue(char *hostname, /* I - Host to connect to */
|
||||
* literal output...
|
||||
*/
|
||||
|
||||
lpd_command(fd, "\002%s\n", printer); /* Receive print job(s) */
|
||||
if (lpd_command(fd, timeout, "\002%s\n",
|
||||
printer)) /* Receive print job(s) */
|
||||
return (1);
|
||||
|
||||
gethostname(localhost, sizeof(localhost));
|
||||
localhost[31] = '\0'; /* RFC 1179, Section 7.2 - host name < 32 chars */
|
||||
|
||||
snprintf(control, sizeof(control), "H%s\nP%s\nJ%s\n", localhost, user, title);
|
||||
snprintf(control, sizeof(control), "H%s\nP%s\nJ%s\n", localhost, user,
|
||||
title);
|
||||
cptr = control + strlen(control);
|
||||
|
||||
if (banner)
|
||||
{
|
||||
snprintf(cptr, sizeof(control) - (cptr - control), "L%s\n", user);
|
||||
snprintf(cptr, sizeof(control) - (cptr - control), "C%s\nL%s\n",
|
||||
localhost, user);
|
||||
cptr += strlen(cptr);
|
||||
}
|
||||
|
||||
@@ -640,14 +682,13 @@ lpd_queue(char *hostname, /* I - Host to connect to */
|
||||
|
||||
if (order == ORDER_CONTROL_DATA)
|
||||
{
|
||||
lpd_command(fd, "\002%d cfA%03.3d%s\n", strlen(control), getpid() % 1000,
|
||||
localhost);
|
||||
if (lpd_command(fd, timeout, "\002%d cfA%03.3d%s\n", strlen(control),
|
||||
getpid() % 1000, localhost))
|
||||
return (1);
|
||||
|
||||
fprintf(stderr, "INFO: Sending control file (%lu bytes)\n",
|
||||
(unsigned long)strlen(control));
|
||||
|
||||
alarm(30);
|
||||
|
||||
if (lpd_write(fd, control, strlen(control) + 1) < (strlen(control) + 1))
|
||||
{
|
||||
status = errno;
|
||||
@@ -655,10 +696,14 @@ lpd_queue(char *hostname, /* I - Host to connect to */
|
||||
}
|
||||
else
|
||||
{
|
||||
alarm(30);
|
||||
alarm(timeout);
|
||||
|
||||
if (read(fd, &status, 1) < 1)
|
||||
{
|
||||
fprintf(stderr, "WARNING: Remote host did not respond with control "
|
||||
"status byte after %d seconds!\n", timeout);
|
||||
status = errno;
|
||||
}
|
||||
|
||||
alarm(0);
|
||||
}
|
||||
@@ -678,8 +723,10 @@ lpd_queue(char *hostname, /* I - Host to connect to */
|
||||
* Send the print file...
|
||||
*/
|
||||
|
||||
lpd_command(fd, "\003%u dfA%03.3d%s\n", (unsigned)filestats.st_size,
|
||||
getpid() % 1000, localhost);
|
||||
if (lpd_command(fd, timeout, "\003%u dfA%03.3d%s\n",
|
||||
(unsigned)filestats.st_size, getpid() % 1000,
|
||||
localhost))
|
||||
return (1);
|
||||
|
||||
fprintf(stderr, "INFO: Sending data file (%u bytes)\n",
|
||||
(unsigned)filestats.st_size);
|
||||
@@ -707,13 +754,27 @@ lpd_queue(char *hostname, /* I - Host to connect to */
|
||||
if (tbytes < filestats.st_size)
|
||||
status = errno;
|
||||
else if (lpd_write(fd, "", 1) < 1)
|
||||
{
|
||||
perror("ERROR: Unable to send trailing nul to printer");
|
||||
status = errno;
|
||||
}
|
||||
else
|
||||
{
|
||||
alarm(30);
|
||||
/*
|
||||
* Read the status byte from the printer; if we can't read the byte
|
||||
* back now, we should set status to "errno", however at this point
|
||||
* we know the printer got the whole file and we don't necessarily
|
||||
* want to requeue it over and over...
|
||||
*/
|
||||
|
||||
alarm(timeout);
|
||||
|
||||
if (recv(fd, &status, 1, 0) < 1)
|
||||
status = errno;
|
||||
{
|
||||
fprintf(stderr, "WARNING: Remote host did not respond with data "
|
||||
"status byte after %d seconds!\n", timeout);
|
||||
status = 0;
|
||||
}
|
||||
|
||||
alarm(0);
|
||||
}
|
||||
@@ -727,14 +788,13 @@ lpd_queue(char *hostname, /* I - Host to connect to */
|
||||
|
||||
if (status == 0 && order == ORDER_DATA_CONTROL)
|
||||
{
|
||||
lpd_command(fd, "\002%d cfA%03.3d%s\n", strlen(control), getpid() % 1000,
|
||||
localhost);
|
||||
if (lpd_command(fd, timeout, "\002%d cfA%03.3d%s\n", strlen(control),
|
||||
getpid() % 1000, localhost))
|
||||
return (1);
|
||||
|
||||
fprintf(stderr, "INFO: Sending control file (%lu bytes)\n",
|
||||
(unsigned long)strlen(control));
|
||||
|
||||
alarm(30);
|
||||
|
||||
if (lpd_write(fd, control, strlen(control) + 1) < (strlen(control) + 1))
|
||||
{
|
||||
status = errno;
|
||||
@@ -742,10 +802,14 @@ lpd_queue(char *hostname, /* I - Host to connect to */
|
||||
}
|
||||
else
|
||||
{
|
||||
alarm(30);
|
||||
alarm(timeout);
|
||||
|
||||
if (read(fd, &status, 1) < 1)
|
||||
if (read(fd, &status, 1) < 1)
|
||||
{
|
||||
fprintf(stderr, "WARNING: Remote host did not respond with control "
|
||||
"status byte after %d seconds!\n", timeout);
|
||||
status = errno;
|
||||
}
|
||||
|
||||
alarm(0);
|
||||
}
|
||||
@@ -768,24 +832,9 @@ lpd_queue(char *hostname, /* I - Host to connect to */
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Restore the SIGTERM handler if we are waiting for a retry...
|
||||
* Waiting for a retry...
|
||||
*/
|
||||
|
||||
if (fromstdin)
|
||||
{
|
||||
#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
|
||||
sigset(SIGTERM, SIG_DFL);
|
||||
#elif defined(HAVE_SIGACTION)
|
||||
memset(&action, 0, sizeof(action));
|
||||
|
||||
sigemptyset(&action.sa_mask);
|
||||
action.sa_handler = SIG_DFL;
|
||||
sigaction(SIGTERM, &action, NULL);
|
||||
#else
|
||||
signal(SIGTERM, SIG_DFL);
|
||||
#endif /* HAVE_SIGSET */
|
||||
}
|
||||
|
||||
sleep(30);
|
||||
}
|
||||
}
|
||||
@@ -796,7 +845,7 @@ lpd_queue(char *hostname, /* I - Host to connect to */
|
||||
*/
|
||||
|
||||
static void
|
||||
lpd_timeout(int sig) /* I - Signal number */
|
||||
lpd_timeout(int sig) /* I - Signal number */
|
||||
{
|
||||
(void)sig;
|
||||
|
||||
@@ -810,13 +859,13 @@ lpd_timeout(int sig) /* I - Signal number */
|
||||
* 'lpd_write()' - Write a buffer of data to an LPD server.
|
||||
*/
|
||||
|
||||
static int /* O - Number of bytes written or -1 on error */
|
||||
lpd_write(int lpd_fd, /* I - LPD socket */
|
||||
char *buffer, /* I - Buffer to write */
|
||||
int length) /* I - Number of bytes to write */
|
||||
static int /* O - Number of bytes written or -1 on error */
|
||||
lpd_write(int lpd_fd, /* I - LPD socket */
|
||||
char *buffer, /* I - Buffer to write */
|
||||
int length) /* I - Number of bytes to write */
|
||||
{
|
||||
int bytes, /* Number of bytes written */
|
||||
total; /* Total number of bytes written */
|
||||
int bytes, /* Number of bytes written */
|
||||
total; /* Total number of bytes written */
|
||||
|
||||
|
||||
total = 0;
|
||||
@@ -841,11 +890,11 @@ lpd_write(int lpd_fd, /* I - LPD socket */
|
||||
* 'rresvport()' - A simple implementation of rresvport().
|
||||
*/
|
||||
|
||||
int /* O - Socket or -1 on error */
|
||||
rresvport(int *port) /* IO - Port number to bind to */
|
||||
int /* O - Socket or -1 on error */
|
||||
rresvport(int *port) /* IO - Port number to bind to */
|
||||
{
|
||||
struct sockaddr_in addr; /* Socket address */
|
||||
int fd; /* Socket file descriptor */
|
||||
struct sockaddr_in addr; /* Socket address */
|
||||
int fd; /* Socket file descriptor */
|
||||
|
||||
|
||||
/*
|
||||
@@ -923,6 +972,27 @@ rresvport(int *port) /* IO - Port number to bind to */
|
||||
}
|
||||
#endif /* !HAVE_RRESVPORT */
|
||||
|
||||
|
||||
/*
|
||||
* 'sigterm_handler()' - Handle 'terminate' signals that stop the backend.
|
||||
*/
|
||||
|
||||
static void
|
||||
sigterm_handler(int sig) /* I - Signal */
|
||||
{
|
||||
(void)sig; /* remove compiler warnings... */
|
||||
|
||||
/*
|
||||
* Remove the temporary file if necessary...
|
||||
*/
|
||||
|
||||
if (tmpfilename[0])
|
||||
unlink(tmpfilename);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id$".
|
||||
*/
|
||||
|
||||
@@ -281,6 +281,9 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
bufptr += wbytes;
|
||||
}
|
||||
|
||||
if (wbytes < 0)
|
||||
break;
|
||||
|
||||
if (argc > 6)
|
||||
fprintf(stderr, "INFO: Sending print file, %lu bytes...\n",
|
||||
(unsigned long)tbytes);
|
||||
|
||||
@@ -83,8 +83,7 @@ print_device(const char *resource, /* I - SCSI device */
|
||||
int bytes; /* Number of bytes */
|
||||
int try; /* Current try */
|
||||
dsreq_t scsi_req; /* SCSI request */
|
||||
char scsi_cmd[6], /* SCSI command data */
|
||||
scsi_sense[32]; /* SCSI sense data */
|
||||
char scsi_cmd[6]; /* SCSI command data */
|
||||
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
|
||||
struct sigaction action; /* Actions for POSIX signals */
|
||||
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
|
||||
|
||||
@@ -386,23 +386,23 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
|
||||
if (strcasecmp(value, "none") == 0)
|
||||
{
|
||||
opts.c_iflag &= ~(IXON | IXOFF | IXANY);
|
||||
opts.c_iflag &= ~(IXON | IXOFF);
|
||||
opts.c_cflag &= ~CRTSCTS;
|
||||
}
|
||||
else if (strcasecmp(value, "soft") == 0)
|
||||
{
|
||||
opts.c_iflag |= IXON | IXOFF | IXANY;
|
||||
opts.c_iflag |= IXON | IXOFF;
|
||||
opts.c_cflag &= ~CRTSCTS;
|
||||
}
|
||||
else if (strcasecmp(value, "hard") == 0 ||
|
||||
strcasecmp(value, "rtscts") == 0)
|
||||
{
|
||||
opts.c_iflag &= ~(IXON | IXOFF | IXANY);
|
||||
opts.c_iflag &= ~(IXON | IXOFF);
|
||||
opts.c_cflag |= CRTSCTS;
|
||||
}
|
||||
else if (strcasecmp(value, "dtrdsr") == 0)
|
||||
{
|
||||
opts.c_iflag &= ~(IXON | IXOFF | IXANY);
|
||||
opts.c_iflag &= ~(IXON | IXOFF);
|
||||
opts.c_cflag &= ~CRTSCTS;
|
||||
|
||||
dtrdsr = 1;
|
||||
@@ -508,6 +508,9 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
bufptr += wbytes;
|
||||
}
|
||||
|
||||
if (wbytes < 0)
|
||||
break;
|
||||
|
||||
if (argc > 6)
|
||||
fprintf(stderr, "INFO: Sending print file, %lu bytes...\n",
|
||||
(unsigned long)tbytes);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <cups/http-private.h>
|
||||
#include <cups/string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
@@ -54,6 +55,13 @@
|
||||
#endif /* WIN32 */
|
||||
|
||||
|
||||
/*
|
||||
* Local functions...
|
||||
*/
|
||||
|
||||
void print_backchannel(const unsigned char *buffer, int nbytes);
|
||||
|
||||
|
||||
/*
|
||||
* 'main()' - Send a file to the printer or server.
|
||||
*
|
||||
@@ -62,9 +70,9 @@
|
||||
* printer-uri job-id user title copies options [file]
|
||||
*/
|
||||
|
||||
int /* O - Exit status */
|
||||
main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
int /* O - Exit status */
|
||||
main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
{
|
||||
char method[255], /* Method in URI */
|
||||
hostname[1024], /* Hostname */
|
||||
@@ -79,8 +87,8 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
struct sockaddr_in addr; /* Socket address */
|
||||
struct hostent *hostaddr; /* Host address */
|
||||
int wbytes; /* Number of bytes written */
|
||||
size_t nbytes, /* Number of bytes read */
|
||||
tbytes; /* Total number of bytes written */
|
||||
int nbytes; /* Number of bytes read */
|
||||
size_t tbytes; /* Total number of bytes written */
|
||||
char buffer[8192], /* Output buffer */
|
||||
*bufptr; /* Pointer into buffer */
|
||||
struct timeval timeout; /* Timeout for select() */
|
||||
@@ -167,7 +175,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
if ((hostaddr = httpGetHostByName(hostname)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Unable to locate printer \'%s\' - %s\n",
|
||||
hostname, strerror(errno));
|
||||
hostname, hstrerror(h_errno));
|
||||
return (1);
|
||||
}
|
||||
|
||||
@@ -273,6 +281,9 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
bufptr += wbytes;
|
||||
}
|
||||
|
||||
if (wbytes < 0)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Check for possible data coming back from the printer...
|
||||
*/
|
||||
@@ -282,19 +293,18 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
|
||||
FD_ZERO(&input);
|
||||
FD_SET(fd, &input);
|
||||
#ifdef __hpux
|
||||
if (select(fd + 1, (int *)&input, NULL, NULL, &timeout) > 0)
|
||||
#else
|
||||
if (select(fd + 1, &input, NULL, NULL, &timeout) > 0)
|
||||
#endif /* __hpux */
|
||||
{
|
||||
/*
|
||||
* Grab the data coming back and spit it out to stderr...
|
||||
*/
|
||||
|
||||
if ((nbytes = recv(fd, buffer, sizeof(buffer), 0)) > 0)
|
||||
fprintf(stderr, "INFO: Received %lu bytes of back-channel data!\n",
|
||||
(unsigned long)nbytes);
|
||||
{
|
||||
fprintf(stderr, "INFO: Received %d bytes of back-channel data!\n",
|
||||
nbytes);
|
||||
print_backchannel((unsigned char *)buffer, nbytes);
|
||||
}
|
||||
}
|
||||
else if (argc > 6)
|
||||
fprintf(stderr, "INFO: Sending print file, %lu bytes...\n",
|
||||
@@ -333,9 +343,12 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
*/
|
||||
|
||||
if ((nbytes = recv(fd, buffer, sizeof(buffer), 0)) > 0)
|
||||
fprintf(stderr, "INFO: Received %lu bytes of back-channel data!\n",
|
||||
(unsigned long)nbytes);
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "INFO: Received %d bytes of back-channel data!\n",
|
||||
nbytes);
|
||||
print_backchannel((unsigned char *)buffer, nbytes);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
@@ -362,6 +375,44 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'print_backchannel()' - Print the contents of a back-channel buffer.
|
||||
*/
|
||||
|
||||
void
|
||||
print_backchannel(const unsigned char *buffer, /* I - Data buffer */
|
||||
int nbytes) /* I - Number of bytes */
|
||||
{
|
||||
char line[255], /* Formatted line */
|
||||
*lineptr; /* Pointer into line */
|
||||
|
||||
|
||||
for (lineptr = line; nbytes > 0; buffer ++, nbytes --)
|
||||
{
|
||||
if (*buffer < 0x20 || *buffer >= 0x7f)
|
||||
{
|
||||
snprintf(lineptr, sizeof(line) - (lineptr - line), "<%02X>", *buffer);
|
||||
lineptr += strlen(lineptr);
|
||||
}
|
||||
else
|
||||
*lineptr++ = *buffer;
|
||||
|
||||
if ((lineptr - line) > 72)
|
||||
{
|
||||
*lineptr = '\0';
|
||||
fprintf(stderr, "DEBUG: DATA: %s\n", line);
|
||||
lineptr = line;
|
||||
}
|
||||
}
|
||||
|
||||
if (lineptr > line)
|
||||
{
|
||||
*lineptr = '\0';
|
||||
fprintf(stderr, "DEBUG: DATA: %s\n", line);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id$".
|
||||
*/
|
||||
|
||||
@@ -60,7 +60,11 @@
|
||||
#endif /* __linux */
|
||||
|
||||
#ifdef __sun
|
||||
# include <sys/ecppio.h>
|
||||
# ifdef __sparc
|
||||
# include <sys/ecppio.h>
|
||||
# else
|
||||
# include <sys/ecppsys.h>
|
||||
# endif /* __sparc */
|
||||
#endif /* __sun */
|
||||
|
||||
|
||||
@@ -226,26 +230,30 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
#endif /* HAVE_SIGSET */
|
||||
}
|
||||
|
||||
#ifdef __linux
|
||||
#if defined(__linux) && defined(LP_POUTPA)
|
||||
/*
|
||||
* Show the printer status before we send the file; normally, we'd
|
||||
* do this while we write data to the printer, however at least some
|
||||
* Linux kernels have buggy USB drivers which don't like to be
|
||||
* queried while sending data to the printer...
|
||||
*
|
||||
* Also, we're using the 8255 constants instead of the ones that are
|
||||
* supposed to be used, as it appears that the USB driver also doesn't
|
||||
* follow standards...
|
||||
*/
|
||||
|
||||
if (ioctl(fd, LPGETSTATUS, &status) == 0)
|
||||
{
|
||||
fprintf(stderr, "DEBUG: LPGETSTATUS returned a port status of %02X...\n", status);
|
||||
|
||||
if (status & LP_NOPA)
|
||||
if (!(status & LP_POUTPA))
|
||||
fputs("WARNING: Media tray empty!\n", stderr);
|
||||
else if (status & LP_ERR)
|
||||
else if (!(status & LP_PERRORP))
|
||||
fputs("WARNING: Printer fault!\n", stderr);
|
||||
else if (status & LP_OFFL)
|
||||
else if (!(status & LP_PSELECD))
|
||||
fputs("WARNING: Printer off-line.\n", stderr);
|
||||
}
|
||||
#endif /* __linux */
|
||||
#endif /* __linux && LP_POUTPA */
|
||||
|
||||
/*
|
||||
* Finally, send the print file...
|
||||
@@ -288,6 +296,9 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||
bufptr += wbytes;
|
||||
}
|
||||
|
||||
if (wbytes < 0)
|
||||
break;
|
||||
|
||||
if (argc > 6)
|
||||
fprintf(stderr, "INFO: Sending print file, %lu bytes...\n",
|
||||
(unsigned long)tbytes);
|
||||
@@ -323,11 +334,9 @@ decode_device_id(int port, /* I - Port number */
|
||||
char *attr, /* 1284 attribute */
|
||||
*delim, /* 1284 delimiter */
|
||||
*uriptr, /* Pointer into URI */
|
||||
line[1024]; /* Line from devices file */
|
||||
FILE *fp; /* /proc/bus/usb/devices file */
|
||||
int current; /* Current printer port */
|
||||
char serial_number[1024], /* Serial number string */
|
||||
temp[1024]; /* Temporary string */
|
||||
*mfg, /* Manufacturer string */
|
||||
*mdl, /* Model string */
|
||||
serial_number[1024]; /* Serial number string */
|
||||
|
||||
|
||||
/*
|
||||
@@ -339,6 +348,16 @@ decode_device_id(int port, /* I - Port number */
|
||||
else if ((attr = strstr(device_id, "DESCRIPTION:")) != NULL)
|
||||
attr += 12;
|
||||
|
||||
if ((mfg = strstr(device_id, "MANUFACTURER:")) != NULL)
|
||||
mfg += 13;
|
||||
else if ((mfg = strstr(device_id, "MFG:")) != NULL)
|
||||
mfg += 4;
|
||||
|
||||
if ((mdl = strstr(device_id, "MODEL:")) != NULL)
|
||||
mdl += 6;
|
||||
else if ((mdl = strstr(device_id, "MDL:")) != NULL)
|
||||
mdl += 4;
|
||||
|
||||
if (attr)
|
||||
{
|
||||
if (strncasecmp(attr, "Hewlett-Packard ", 16) == 0)
|
||||
@@ -354,8 +373,31 @@ decode_device_id(int port, /* I - Port number */
|
||||
if ((delim = strchr(make_model, ';')) != NULL)
|
||||
*delim = '\0';
|
||||
}
|
||||
else if (mfg && mdl)
|
||||
{
|
||||
/*
|
||||
* Build a make-model string from the manufacturer and model attributes...
|
||||
*/
|
||||
|
||||
strlcpy(make_model, mfg, mmsize);
|
||||
|
||||
if ((delim = strchr(make_model, ';')) != NULL)
|
||||
*delim = '\0';
|
||||
|
||||
strlcat(make_model, " ", mmsize);
|
||||
strlcat(make_model, mdl, mmsize);
|
||||
|
||||
if ((delim = strchr(make_model, ';')) != NULL)
|
||||
*delim = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Use "Unknown" as the printer make and model...
|
||||
*/
|
||||
|
||||
strlcpy(make_model, "Unknown", mmsize);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for the serial number field...
|
||||
@@ -373,42 +415,9 @@ decode_device_id(int port, /* I - Port number */
|
||||
if ((delim = strchr(serial_number, ';')) != NULL)
|
||||
*delim = '\0';
|
||||
}
|
||||
else if ((fp = fopen("/proc/bus/usb/devices", "r")) != NULL)
|
||||
{
|
||||
else
|
||||
serial_number[0] = '\0';
|
||||
|
||||
for (current = 0; fgets(line, sizeof(line), fp) != NULL;)
|
||||
{
|
||||
if (line[0] == 'S' && (attr = strstr(line, "SerialNumber=")) != NULL)
|
||||
{
|
||||
/*
|
||||
* Copy serial number from line...
|
||||
*/
|
||||
|
||||
strlcpy(temp, attr + 13, sizeof(temp));
|
||||
if ((delim = strchr(temp, '\n')) != NULL)
|
||||
*delim = '\0';
|
||||
}
|
||||
else if (line[0] == 'I' && strstr(line, "Driver=usblp") != NULL &&
|
||||
strstr(line, "Prot=02") != NULL)
|
||||
{
|
||||
/*
|
||||
* Found printer device; if current == port, then use it!
|
||||
*/
|
||||
|
||||
if (current == port)
|
||||
{
|
||||
strlcpy(serial_number, temp, sizeof(serial_number));
|
||||
break;
|
||||
}
|
||||
|
||||
current ++;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate the device URI from the make_model and serial number strings.
|
||||
*/
|
||||
@@ -507,7 +516,7 @@ list_devices(void)
|
||||
if (length > (sizeof(device_id) - 2))
|
||||
length = sizeof(device_id) - 2;
|
||||
|
||||
memcpy(device_id, device_id + 2, length);
|
||||
memmove(device_id, device_id + 2, length);
|
||||
device_id[length] = '\0';
|
||||
}
|
||||
else
|
||||
@@ -666,7 +675,7 @@ open_device(const char *uri) /* I - Device URI */
|
||||
{
|
||||
length = (((unsigned)device_id[0] & 255) << 8) +
|
||||
((unsigned)device_id[1] & 255);
|
||||
memcpy(device_id, device_id + 2, length);
|
||||
memmove(device_id, device_id + 2, length);
|
||||
device_id[length] = '\0';
|
||||
}
|
||||
else
|
||||
@@ -685,7 +694,15 @@ open_device(const char *uri) /* I - Device URI */
|
||||
device_uri, sizeof(device_uri));
|
||||
|
||||
if (strcmp(uri, device_uri) == 0)
|
||||
return (fd); /* Yes, return this file descriptor... */
|
||||
{
|
||||
/*
|
||||
* Yes, return this file descriptor...
|
||||
*/
|
||||
|
||||
fprintf(stderr, "DEBUG: Printer using device file \"%s\"...\n", device);
|
||||
|
||||
return (fd);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
# DO NOT DELETE
|
||||
|
||||
lpc.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
|
||||
lpc.o: ../cups/ppd.h ../cups/language.h ../cups/debug.h
|
||||
lpc.o: ../cups/ppd.h ../cups/language.h ../cups/debug.h ../cups/string.h
|
||||
lpc.o: ../config.h
|
||||
lpq.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h
|
||||
lpq.o: ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/language.h
|
||||
lpq.o: ../cups/debug.h
|
||||
lpr.o: ../config.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
|
||||
lpr.o: ../cups/ppd.h
|
||||
lpr.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h
|
||||
lpr.o: ../cups/http.h ../cups/md5.h ../cups/ppd.h
|
||||
lprm.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
|
||||
lprm.o: ../cups/ppd.h ../cups/language.h
|
||||
lprm.o: ../cups/ppd.h ../cups/language.h ../cups/string.h ../config.h
|
||||
|
||||
@@ -100,7 +100,7 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
*/
|
||||
|
||||
while (isspace(line[0]))
|
||||
strcpy(line, line + 1);
|
||||
cups_strcpy(line, line + 1);
|
||||
|
||||
for (params = line; *params != '\0'; params ++)
|
||||
if (isspace(*params))
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
* main() - Parse options and commands.
|
||||
* show_jobs() - Show jobs.
|
||||
* show_printer() - Show printer status.
|
||||
* usage() - Show program usage.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -51,6 +52,7 @@
|
||||
static int show_jobs(http_t *, const char *, const char *, const int,
|
||||
const int);
|
||||
static void show_printer(http_t *, const char *);
|
||||
static void usage(void);
|
||||
|
||||
|
||||
/*
|
||||
@@ -71,9 +73,9 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
longstatus; /* Show file details */
|
||||
int num_dests; /* Number of destinations */
|
||||
cups_dest_t *dests; /* Destinations */
|
||||
#ifdef HAVE_LIBSSL
|
||||
#ifdef HAVE_SSL
|
||||
http_encryption_t encryption; /* Encryption? */
|
||||
#endif /* HAVE_LIBSSL */
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
|
||||
/*
|
||||
@@ -111,7 +113,7 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
switch (argv[i][1])
|
||||
{
|
||||
case 'E' : /* Encrypt */
|
||||
#ifdef HAVE_LIBSSL
|
||||
#ifdef HAVE_SSL
|
||||
encryption = HTTP_ENCRYPT_REQUIRED;
|
||||
|
||||
if (http)
|
||||
@@ -119,7 +121,7 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
#else
|
||||
fprintf(stderr, "%s: Sorry, no encryption support compiled in!\n",
|
||||
argv[0]);
|
||||
#endif /* HAVE_LIBSSL */
|
||||
#endif /* HAVE_SSL */
|
||||
break;
|
||||
|
||||
case 'P' : /* Printer */
|
||||
@@ -128,6 +130,15 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
else
|
||||
{
|
||||
i ++;
|
||||
|
||||
if (i >= argc)
|
||||
{
|
||||
httpClose(http);
|
||||
cupsFreeDests(num_dests, dests);
|
||||
|
||||
usage();
|
||||
}
|
||||
|
||||
dest = argv[i];
|
||||
}
|
||||
|
||||
@@ -155,10 +166,11 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
break;
|
||||
|
||||
default :
|
||||
fputs("Usage: lpq [-P dest] [-l] [+interval]\n", stderr);
|
||||
httpClose(http);
|
||||
cupsFreeDests(num_dests, dests);
|
||||
return (1);
|
||||
cupsFreeDests(num_dests, dests);
|
||||
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (isdigit(argv[i][0]))
|
||||
@@ -427,15 +439,15 @@ show_jobs(http_t *http, /* I - HTTP connection to server */
|
||||
else
|
||||
strlcpy(namestr, jobname, sizeof(namestr));
|
||||
|
||||
printf("%s: %-34.34s[job %d localhost]\n", jobuser, rankstr, jobid);
|
||||
printf(" %-40.40s%d bytes\n", namestr, jobsize);
|
||||
printf("%s: %-33.33s [job %d localhost]\n", jobuser, rankstr, jobid);
|
||||
printf(" %-39.39s %d bytes\n", namestr, jobsize);
|
||||
}
|
||||
else
|
||||
#ifdef __osf__
|
||||
printf("%-6s %-10.10s %-4d %-10d %-27.27s %d bytes\n", rankstr, jobuser,
|
||||
jobpriority, jobid, jobname, jobsize);
|
||||
#else
|
||||
printf("%-7s %-8.8s%-8d%-32.32s%d bytes\n", rankstr, jobuser,
|
||||
printf("%-7s %-7.7s %-7d %-31.31s %d bytes\n", rankstr, jobuser,
|
||||
jobid, jobname, jobsize);
|
||||
#endif /* __osf */
|
||||
|
||||
@@ -544,6 +556,18 @@ show_printer(http_t *http, /* I - HTTP connection to server */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'usage()' - Show program usage.
|
||||
*/
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fputs("Usage: lpq [-P dest] [-l] [+interval]\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id$".
|
||||
*/
|
||||
|
||||
@@ -104,12 +104,12 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
switch (ch = argv[i][1])
|
||||
{
|
||||
case 'E' : /* Encrypt */
|
||||
#ifdef HAVE_LIBSSL
|
||||
#ifdef HAVE_SSL
|
||||
cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
|
||||
#else
|
||||
fprintf(stderr, "%s: Sorry, no encryption support compiled in!\n",
|
||||
argv[0]);
|
||||
#endif /* HAVE_LIBSSL */
|
||||
#endif /* HAVE_SSL */
|
||||
break;
|
||||
|
||||
case '1' : /* TROFF font set 1 */
|
||||
@@ -307,23 +307,25 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
if (num_dests == 0)
|
||||
num_dests = cupsGetDests(&dests);
|
||||
|
||||
for (j = 0, dest = dests; j < num_dests; j ++, dest ++)
|
||||
if (dest->is_default)
|
||||
{
|
||||
printer = dests[j].name;
|
||||
if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) != NULL)
|
||||
{
|
||||
printer = dest->name;
|
||||
|
||||
for (j = 0; j < dest->num_options; j ++)
|
||||
if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
|
||||
num_options = cupsAddOption(dest->options[j].name,
|
||||
dest->options[j].value,
|
||||
num_options, &options);
|
||||
break;
|
||||
}
|
||||
for (j = 0; j < dest->num_options; j ++)
|
||||
if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
|
||||
num_options = cupsAddOption(dest->options[j].name,
|
||||
dest->options[j].value,
|
||||
num_options, &options);
|
||||
}
|
||||
}
|
||||
|
||||
if (printer == NULL)
|
||||
{
|
||||
fputs("lpr: error - no default destination available.\n", stderr);
|
||||
if (cupsLastError() >= IPP_BAD_REQUEST)
|
||||
fputs("lpr: error - scheduler not responding!\n", stderr);
|
||||
else
|
||||
fputs("lpr: error - no default destination available.\n", stderr);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
@@ -98,14 +98,14 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
switch (argv[i][1])
|
||||
{
|
||||
case 'E' : /* Encrypt */
|
||||
#ifdef HAVE_LIBSSL
|
||||
#ifdef HAVE_SSL
|
||||
encryption = HTTP_ENCRYPT_REQUIRED;
|
||||
|
||||
httpEncryption(http, encryption);
|
||||
#else
|
||||
fprintf(stderr, "%s: Sorry, no encryption support compiled in!\n",
|
||||
argv[0]);
|
||||
#endif /* HAVE_LIBSSL */
|
||||
#endif /* HAVE_SSL */
|
||||
break;
|
||||
|
||||
case 'P' : /* Cancel jobs on a printer */
|
||||
|
||||
@@ -233,7 +233,7 @@ do_am_class(http_t *http, /* I - HTTP connection */
|
||||
|
||||
if ((response = cupsDoRequest(http, request, "/")) != NULL)
|
||||
{
|
||||
ippSetCGIVars(response, NULL, NULL);
|
||||
ippSetCGIVars(response, NULL, NULL, NULL, 0);
|
||||
ippDelete(response);
|
||||
}
|
||||
|
||||
@@ -548,7 +548,7 @@ do_am_printer(http_t *http, /* I - HTTP connection */
|
||||
*/
|
||||
|
||||
if (oldinfo)
|
||||
ippSetCGIVars(oldinfo, NULL, NULL);
|
||||
ippSetCGIVars(oldinfo, NULL, NULL, NULL, 0);
|
||||
|
||||
cgiCopyTemplateLang(stdout, TEMPLATES, "modify-printer.tmpl", getenv("LANG"));
|
||||
}
|
||||
@@ -610,7 +610,7 @@ do_am_printer(http_t *http, /* I - HTTP connection */
|
||||
|
||||
if ((response = cupsDoRequest(http, request, "/")) != NULL)
|
||||
{
|
||||
ippSetCGIVars(response, NULL, NULL);
|
||||
ippSetCGIVars(response, NULL, NULL, NULL, 0);
|
||||
ippDelete(response);
|
||||
}
|
||||
|
||||
@@ -776,7 +776,7 @@ do_am_printer(http_t *http, /* I - HTTP connection */
|
||||
|
||||
strlcpy(make, var, sizeof(make));
|
||||
|
||||
ippSetCGIVars(response, "ppd-make", make);
|
||||
ippSetCGIVars(response, "ppd-make", make, NULL, 0);
|
||||
cgiCopyTemplateLang(stdout, TEMPLATES, "choose-model.tmpl",
|
||||
getenv("LANG"));
|
||||
}
|
||||
@@ -916,6 +916,7 @@ do_config_printer(http_t *http, /* I - HTTP connection */
|
||||
ppd_file_t *ppd; /* PPD file */
|
||||
ppd_group_t *group; /* Option group */
|
||||
ppd_option_t *option; /* Option */
|
||||
ppd_attr_t *protocol; /* cupsProtocol attribute */
|
||||
|
||||
|
||||
/*
|
||||
@@ -960,7 +961,12 @@ do_config_printer(http_t *http, /* I - HTTP connection */
|
||||
return;
|
||||
}
|
||||
|
||||
ppd = ppdOpenFile(filename);
|
||||
if ((ppd = ppdOpenFile(filename)) == NULL)
|
||||
{
|
||||
cgiSetVariable("ERROR", ippErrorString(IPP_DEVICE_ERROR));
|
||||
cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (cgiGetVariable("job_sheets_start") != NULL ||
|
||||
cgiGetVariable("job_sheets_end") != NULL)
|
||||
@@ -1153,6 +1159,45 @@ do_config_printer(http_t *http, /* I - HTTP connection */
|
||||
ippDelete(response);
|
||||
}
|
||||
|
||||
/*
|
||||
* Binary protocol support...
|
||||
*/
|
||||
|
||||
if (ppd->protocols && strstr(ppd->protocols, "BCP"))
|
||||
{
|
||||
protocol = ppdFindAttr(ppd, "cupsProtocol", NULL);
|
||||
|
||||
cgiSetVariable("GROUP", "PS Binary Protocol");
|
||||
cgiCopyTemplateLang(stdout, TEMPLATES, "option-header.tmpl",
|
||||
getenv("LANG"));
|
||||
|
||||
cgiSetSize("CHOICES", 2);
|
||||
cgiSetSize("TEXT", 2);
|
||||
cgiSetArray("CHOICES", 0, "None");
|
||||
cgiSetArray("TEXT", 0, "None");
|
||||
|
||||
if (strstr(ppd->protocols, "TBCP"))
|
||||
{
|
||||
cgiSetArray("CHOICES", 1, "TBCP");
|
||||
cgiSetArray("TEXT", 1, "TBCP");
|
||||
}
|
||||
else
|
||||
{
|
||||
cgiSetArray("CHOICES", 1, "BCP");
|
||||
cgiSetArray("TEXT", 1, "BCP");
|
||||
}
|
||||
|
||||
cgiSetVariable("KEYWORD", "protocol");
|
||||
cgiSetVariable("KEYTEXT", "PS Binary Protocol");
|
||||
cgiSetVariable("DEFCHOICE", protocol ? protocol->value : "None");
|
||||
|
||||
cgiCopyTemplateLang(stdout, TEMPLATES, "option-pickone.tmpl",
|
||||
getenv("LANG"));
|
||||
|
||||
cgiCopyTemplateLang(stdout, TEMPLATES, "option-trailer.tmpl",
|
||||
getenv("LANG"));
|
||||
}
|
||||
|
||||
cgiCopyTemplateLang(stdout, TEMPLATES, "config-printer2.tmpl",
|
||||
getenv("LANG"));
|
||||
}
|
||||
@@ -1176,7 +1221,9 @@ do_config_printer(http_t *http, /* I - HTTP connection */
|
||||
|
||||
while (get_line(line, sizeof(line), in) != NULL)
|
||||
{
|
||||
if (strncmp(line, "*Default", 8) != 0)
|
||||
if (!strncmp(line, "*cupsProtocol:", 14) && cgiGetVariable("protocol"))
|
||||
continue;
|
||||
else if (strncmp(line, "*Default", 8))
|
||||
fprintf(out, "%s\n", line);
|
||||
else
|
||||
{
|
||||
@@ -1204,6 +1251,9 @@ do_config_printer(http_t *http, /* I - HTTP connection */
|
||||
}
|
||||
}
|
||||
|
||||
if ((var = cgiGetVariable("protocol")) != NULL)
|
||||
fprintf(out, "*cupsProtocol: %s\n", cgiGetVariable("protocol"));
|
||||
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
close(outfd);
|
||||
|
||||
@@ -37,21 +37,25 @@
|
||||
* 'main()' - Main entry for CGI.
|
||||
*/
|
||||
|
||||
int /* O - Exit status */
|
||||
main(int argc, /* I - Number of command-line arguments */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
int /* O - Exit status */
|
||||
main(int argc, /* I - Number of command-line arguments */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
{
|
||||
cups_lang_t *language; /* Language information */
|
||||
char *pclass; /* Printer class name */
|
||||
http_t *http; /* Connection to the server */
|
||||
ipp_t *request, /* IPP request */
|
||||
*response; /* IPP response */
|
||||
ipp_attribute_t *attr; /* IPP attribute */
|
||||
ipp_status_t status; /* Operation status... */
|
||||
char uri[HTTP_MAX_URI];
|
||||
/* Printer URI */
|
||||
const char *which_jobs; /* Which jobs to show */
|
||||
const char *op; /* Operation to perform, if any */
|
||||
cups_lang_t *language; /* Language information */
|
||||
char *pclass; /* Printer class name */
|
||||
http_t *http; /* Connection to the server */
|
||||
ipp_t *request, /* IPP request */
|
||||
*response; /* IPP response */
|
||||
ipp_attribute_t *attr; /* IPP attribute */
|
||||
ipp_status_t status; /* Operation status... */
|
||||
char uri[HTTP_MAX_URI]; /* Printer URI */
|
||||
const char *which_jobs; /* Which jobs to show */
|
||||
const char *op; /* Operation to perform, if any */
|
||||
static const char *def_attrs[] = /* Attributes for default printer */
|
||||
{
|
||||
"printer-name",
|
||||
"printer-uri-supported"
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
@@ -113,6 +117,10 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
|
||||
"attributes-natural-language", NULL, language->language);
|
||||
|
||||
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
|
||||
"requested-attributes",
|
||||
sizeof(def_attrs) / sizeof(def_attrs[0]), NULL, def_attrs);
|
||||
|
||||
if ((response = cupsDoRequest(http, request, "/")) != NULL)
|
||||
{
|
||||
if ((attr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME)) != NULL)
|
||||
@@ -120,38 +128,12 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
|
||||
if ((attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI)) != NULL)
|
||||
{
|
||||
char method[HTTP_MAX_URI],
|
||||
username[HTTP_MAX_URI],
|
||||
hostname[HTTP_MAX_URI],
|
||||
resource[HTTP_MAX_URI],
|
||||
uri[HTTP_MAX_URI];
|
||||
int port; /* URI data */
|
||||
const char *server; /* Name of server */
|
||||
char url[HTTP_MAX_URI]; /* New URL */
|
||||
|
||||
|
||||
/*
|
||||
* Map localhost access to localhost...
|
||||
*/
|
||||
|
||||
server = getenv("SERVER_NAME");
|
||||
|
||||
httpSeparate(attr->values[0].string.text, method, username,
|
||||
hostname, &port, resource);
|
||||
|
||||
if (strcasecmp(hostname, server) == 0 &&
|
||||
(strcmp(getenv("REMOTE_HOST"), "127.0.0.1") == 0 ||
|
||||
strcmp(getenv("REMOTE_HOST"), "localhost") == 0 ||
|
||||
strcmp(getenv("REMOTE_HOST"), server) == 0))
|
||||
strcpy(hostname, "localhost");
|
||||
|
||||
/*
|
||||
* Rewrite URI with HTTP address...
|
||||
*/
|
||||
|
||||
snprintf(uri, sizeof(uri), "http://%s:%d%s", hostname, port,
|
||||
resource);
|
||||
|
||||
cgiSetVariable("DEFAULT_URI", uri);
|
||||
cgiSetVariable("DEFAULT_URI",
|
||||
ippRewriteURL(attr->values[0].string.text,
|
||||
url, sizeof(url)));
|
||||
}
|
||||
|
||||
ippDelete(response);
|
||||
@@ -202,13 +184,15 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
uri);
|
||||
}
|
||||
|
||||
ippGetAttributes(request, TEMPLATES, "classes.tmpl", getenv("LANG"));
|
||||
|
||||
/*
|
||||
* Do the request and get back a response...
|
||||
*/
|
||||
|
||||
if ((response = cupsDoRequest(http, request, "/")) != NULL)
|
||||
{
|
||||
ippSetCGIVars(response, NULL, NULL);
|
||||
ippSetCGIVars(response, NULL, NULL, NULL, 0);
|
||||
ippDelete(response);
|
||||
}
|
||||
|
||||
@@ -253,13 +237,15 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "which-jobs",
|
||||
NULL, which_jobs);
|
||||
|
||||
ippGetAttributes(request, TEMPLATES, "jobs.tmpl", getenv("LANG"));
|
||||
|
||||
/*
|
||||
* Do the request and get back a response...
|
||||
*/
|
||||
|
||||
if ((response = cupsDoRequest(http, request, "/")) != NULL)
|
||||
{
|
||||
ippSetCGIVars(response, NULL, NULL);
|
||||
ippSetCGIVars(response, NULL, NULL, NULL, 0);
|
||||
ippDelete(response);
|
||||
|
||||
cgiCopyTemplateLang(stdout, TEMPLATES, "jobs.tmpl", getenv("LANG"));
|
||||
@@ -320,7 +306,7 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
CUPS_DATADIR "/data/testprint.ps")) != NULL)
|
||||
{
|
||||
status = response->request.status.status_code;
|
||||
ippSetCGIVars(response, NULL, NULL);
|
||||
ippSetCGIVars(response, NULL, NULL, NULL, 0);
|
||||
|
||||
ippDelete(response);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,10 @@
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* ippGetAttributes() - Get the list of attributes that are needed
|
||||
* by the template file.
|
||||
* ippGetTemplateDir() - Get the templates directory...
|
||||
* ippRewriteURL() - Rewrite a printer URI into a web browser URL...
|
||||
* ippSetServerVersion() - Set the server name and CUPS version...
|
||||
* ippSetCGIVars() - Set CGI variables from an IPP response.
|
||||
*/
|
||||
@@ -35,6 +38,127 @@
|
||||
#include "ipp-var.h"
|
||||
|
||||
|
||||
/*
|
||||
* 'ippGetAttributes()' - Get the list of attributes that are needed
|
||||
* by the template file.
|
||||
*/
|
||||
|
||||
void
|
||||
ippGetAttributes(ipp_t *request, /* I - IPP request */
|
||||
const char *directory, /* I - Directory */
|
||||
const char *tmpl, /* I - Base filename */
|
||||
const char *lang) /* I - Language */
|
||||
{
|
||||
int num_attrs; /* Number of attributes */
|
||||
char *attrs[1000]; /* Attributes */
|
||||
int i; /* Looping var */
|
||||
char filename[1024], /* Filename */
|
||||
locale[16]; /* Locale name */
|
||||
FILE *in; /* Input file */
|
||||
int ch; /* Character from file */
|
||||
char name[255], /* Name of variable */
|
||||
*nameptr; /* Pointer into name */
|
||||
|
||||
|
||||
/*
|
||||
* Convert the language to a locale name...
|
||||
*/
|
||||
|
||||
if (lang != NULL)
|
||||
{
|
||||
for (i = 0; lang[i] && i < 15; i ++)
|
||||
if (isalnum(lang[i]))
|
||||
locale[i] = tolower(lang[i]);
|
||||
else
|
||||
locale[i] = '_';
|
||||
|
||||
locale[i] = '\0';
|
||||
}
|
||||
else
|
||||
locale[0] = '\0';
|
||||
|
||||
/*
|
||||
* See if we have a template file for this language...
|
||||
*/
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/%s/%s", directory, locale, tmpl);
|
||||
if (access(filename, 0))
|
||||
{
|
||||
locale[2] = '\0';
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/%s/%s", directory, locale, tmpl);
|
||||
if (access(filename, 0))
|
||||
snprintf(filename, sizeof(filename), "%s/%s", directory, tmpl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the template file...
|
||||
*/
|
||||
|
||||
if ((in = fopen(filename, "r")) == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Loop through the file adding attribute names as needed...
|
||||
*/
|
||||
|
||||
num_attrs = 0;
|
||||
|
||||
while ((ch = getc(in)) != EOF)
|
||||
if (ch == '\\')
|
||||
getc(in);
|
||||
else if (ch == '{' && num_attrs < (sizeof(attrs) / sizeof(attrs[0])))
|
||||
{
|
||||
/*
|
||||
* Grab the name...
|
||||
*/
|
||||
|
||||
for (nameptr = name; (ch = getc(in)) != EOF;)
|
||||
if (strchr("}]<>=! \t\n", ch))
|
||||
break;
|
||||
else if (nameptr > name && ch == '?')
|
||||
break;
|
||||
else if (nameptr < (name + sizeof(name) - 1))
|
||||
{
|
||||
if (ch == '_')
|
||||
*nameptr++ = '-';
|
||||
else
|
||||
*nameptr++ = ch;
|
||||
}
|
||||
|
||||
*nameptr = '\0';
|
||||
|
||||
/*
|
||||
* Possibly add it to the list of attributes...
|
||||
*/
|
||||
|
||||
for (i = 0; i < num_attrs; i ++)
|
||||
if (!strcmp(attrs[i], name))
|
||||
break;
|
||||
|
||||
if (i >= num_attrs)
|
||||
{
|
||||
attrs[num_attrs] = strdup(name);
|
||||
num_attrs ++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have attributes, add a requested-attributes attribute to the
|
||||
* request...
|
||||
*/
|
||||
|
||||
if (num_attrs > 0)
|
||||
{
|
||||
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
|
||||
"requested-attributes", num_attrs, NULL, (const char **)attrs);
|
||||
|
||||
for (i = 0; i < num_attrs; i ++)
|
||||
free(attrs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'ippGetTemplateDir()' - Get the templates directory...
|
||||
*/
|
||||
@@ -62,6 +186,123 @@ ippGetTemplateDir(void)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'ippRewriteURL()' - Rewrite a printer URI into a web browser URL...
|
||||
*/
|
||||
|
||||
char * /* O - New URL */
|
||||
ippRewriteURL(const char *uri, /* I - Current URI */
|
||||
char *url, /* O - New URL */
|
||||
int urlsize) /* I - Size of URL buffer */
|
||||
{
|
||||
char method[HTTP_MAX_URI],
|
||||
userpass[HTTP_MAX_URI],
|
||||
hostname[HTTP_MAX_URI],
|
||||
rawresource[HTTP_MAX_URI],
|
||||
resource[HTTP_MAX_URI],
|
||||
/* URI components... */
|
||||
*rawptr, /* Pointer into rawresource */
|
||||
*resptr; /* Pointer into resource */
|
||||
int port; /* Port number */
|
||||
static int ishttps = -1; /* Using encryption? */
|
||||
static const char *server; /* Name of server */
|
||||
static char servername[1024];
|
||||
/* Local server name */
|
||||
static const char hexchars[] = "0123456789ABCDEF";
|
||||
/* Hexadecimal conversion characters */
|
||||
|
||||
|
||||
/*
|
||||
* Check if we have been called before...
|
||||
*/
|
||||
|
||||
if (ishttps < 0)
|
||||
{
|
||||
/*
|
||||
* No, initialize static vars for the conversion...
|
||||
*
|
||||
* First get the server name associated with the client interface as
|
||||
* well as the locally configured hostname. We'll check *both* of
|
||||
* these to see if the printer URL is local...
|
||||
*/
|
||||
|
||||
server = getenv("SERVER_NAME");
|
||||
gethostname(servername, sizeof(servername));
|
||||
|
||||
/*
|
||||
* Then flag whether we are using SSL on this connection...
|
||||
*/
|
||||
|
||||
ishttps = getenv("HTTPS") != NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the URI to a URL...
|
||||
*/
|
||||
|
||||
httpSeparate(uri, method, userpass, hostname, &port, rawresource);
|
||||
|
||||
if (strcmp(method, "ipp") == 0 ||
|
||||
strcmp(method, "http") == 0)
|
||||
{
|
||||
/*
|
||||
* Rewrite the resource string so it doesn't contain any
|
||||
* illegal chars...
|
||||
*/
|
||||
|
||||
for (rawptr = rawresource, resptr = resource; *rawptr;)
|
||||
if ((*rawptr & 128) || *rawptr == '%' || *rawptr == ' ' ||
|
||||
*rawptr == '#' || *rawptr == '?' ||
|
||||
*rawptr == '.') /* For MSIE */
|
||||
{
|
||||
if (resptr < (resource + sizeof(resource) - 3))
|
||||
{
|
||||
*resptr++ = '%';
|
||||
*resptr++ = hexchars[(*rawptr >> 4) & 15];
|
||||
*resptr++ = hexchars[*rawptr & 15];
|
||||
}
|
||||
}
|
||||
else if (resptr < (resource + sizeof(resource) - 1))
|
||||
*resptr++ = *rawptr++;
|
||||
|
||||
*resptr = '\0';
|
||||
|
||||
/*
|
||||
* Map local access to a local URI...
|
||||
*/
|
||||
|
||||
if (strcasecmp(hostname, server) == 0 ||
|
||||
strcasecmp(hostname, servername) == 0)
|
||||
{
|
||||
/*
|
||||
* Make URI relative to the current server...
|
||||
*/
|
||||
|
||||
strlcpy(url, resource, urlsize);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Rewrite URI with HTTP/HTTPS scheme...
|
||||
*/
|
||||
|
||||
if (userpass[0])
|
||||
snprintf(url, urlsize, "%s://%s@%s:%d%s",
|
||||
ishttps ? "https" : "http",
|
||||
userpass, hostname, port, resource);
|
||||
else
|
||||
snprintf(url, urlsize, "%s://%s:%d%s",
|
||||
ishttps ? "https" : "http",
|
||||
hostname, port, resource);
|
||||
}
|
||||
}
|
||||
else
|
||||
strlcpy(url, uri, urlsize);
|
||||
|
||||
return (url);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'ippSetServerVersion()' - Set the server name and CUPS version...
|
||||
*/
|
||||
@@ -86,36 +327,42 @@ ippSetServerVersion(void)
|
||||
void
|
||||
ippSetCGIVars(ipp_t *response, /* I - Response data to be copied... */
|
||||
const char *filter_name, /* I - Filter name */
|
||||
const char *filter_value) /* I - Filter value */
|
||||
const char *filter_value, /* I - Filter value */
|
||||
const char *prefix, /* I - Prefix for name or NULL */
|
||||
int parent_el) /* I - Parent element number */
|
||||
{
|
||||
int element; /* Element in CGI array */
|
||||
ipp_attribute_t *attr, /* Attribute in response... */
|
||||
*filter; /* Filtering attribute */
|
||||
int i; /* Looping var */
|
||||
char name[1024], /* Name of attribute */
|
||||
*nameptr, /* Pointer into name */
|
||||
value[16384], /* Value(s) */
|
||||
*valptr; /* Pointer into value */
|
||||
char method[HTTP_MAX_URI],
|
||||
username[HTTP_MAX_URI],
|
||||
hostname[HTTP_MAX_URI],
|
||||
resource[HTTP_MAX_URI],
|
||||
uri[HTTP_MAX_URI];
|
||||
int port; /* URI data */
|
||||
int ishttps; /* Using encryption? */
|
||||
const char *server; /* Name of server */
|
||||
struct tm *date; /* Date information */
|
||||
|
||||
|
||||
ippSetServerVersion();
|
||||
DEBUG_printf(("<P>ippSetCGIVars(response=%p, filter_name=\"%s\", filter_value=\"%s\", prefix=\"%s\")\n",
|
||||
response, filter_name, filter_value, prefix));
|
||||
|
||||
/*
|
||||
* Set common CGI template variables...
|
||||
*/
|
||||
|
||||
server = getenv("SERVER_NAME");
|
||||
ishttps = getenv("HTTPS") != NULL;
|
||||
if (!prefix)
|
||||
ippSetServerVersion();
|
||||
|
||||
for (attr = response->attrs;
|
||||
attr && attr->group_tag == IPP_TAG_OPERATION;
|
||||
attr = attr->next);
|
||||
/*
|
||||
* Loop through the attributes and set them for the template...
|
||||
*/
|
||||
|
||||
for (element = 0; attr != NULL; attr = attr->next, element ++)
|
||||
attr = response->attrs;
|
||||
|
||||
if (!prefix)
|
||||
while (attr && attr->group_tag == IPP_TAG_OPERATION)
|
||||
attr = attr->next;
|
||||
|
||||
for (element = parent_el; attr != NULL; attr = attr->next, element ++)
|
||||
{
|
||||
/*
|
||||
* Copy attributes to a separator...
|
||||
@@ -154,20 +401,28 @@ ippSetCGIVars(ipp_t *response, /* I - Response data to be copied... */
|
||||
if (attr->name == NULL)
|
||||
continue;
|
||||
|
||||
for (i = 0; attr->name[i]; i ++)
|
||||
if (attr->name[i] == '-')
|
||||
name[i] = '_';
|
||||
else
|
||||
name[i] = attr->name[i];
|
||||
if (prefix)
|
||||
{
|
||||
snprintf(name, sizeof(name), "%s.", prefix);
|
||||
nameptr = name + strlen(name);
|
||||
}
|
||||
else
|
||||
nameptr = name;
|
||||
|
||||
name[i] = '\0';
|
||||
for (i = 0; attr->name[i] && nameptr < (name + sizeof(name) - 1); i ++)
|
||||
if (attr->name[i] == '-')
|
||||
*nameptr++ = '_';
|
||||
else
|
||||
*nameptr++ = attr->name[i];
|
||||
|
||||
*nameptr = '\0';
|
||||
|
||||
/*
|
||||
* Add "job_printer_name" variable if we have a "job_printer_uri"
|
||||
* attribute...
|
||||
*/
|
||||
|
||||
if (strcmp(name, "job_printer_uri") == 0)
|
||||
if (!strcmp(name, "job_printer_uri"))
|
||||
{
|
||||
if ((valptr = strrchr(attr->values[0].string.text, '/')) == NULL)
|
||||
valptr = "unknown";
|
||||
@@ -197,7 +452,11 @@ ippSetCGIVars(ipp_t *response, /* I - Response data to be copied... */
|
||||
case IPP_TAG_ENUM :
|
||||
if (strncmp(name, "time_at_", 8) == 0)
|
||||
{
|
||||
date = localtime((time_t *)&(attr->values[i].integer));
|
||||
time_t t; /* Temporary time value */
|
||||
|
||||
t = (time_t)attr->values[i].integer;
|
||||
date = localtime(&t);
|
||||
|
||||
strftime(valptr, sizeof(value) - (valptr - value),
|
||||
CUPS_STRFTIME_FORMAT, date);
|
||||
}
|
||||
@@ -232,43 +491,13 @@ ippSetCGIVars(ipp_t *response, /* I - Response data to be copied... */
|
||||
case IPP_TAG_URI :
|
||||
if (strchr(attr->values[i].string.text, ':') != NULL)
|
||||
{
|
||||
httpSeparate(attr->values[i].string.text, method, username,
|
||||
hostname, &port, resource);
|
||||
/*
|
||||
* Rewrite URIs...
|
||||
*/
|
||||
|
||||
if (strcmp(method, "ipp") == 0 ||
|
||||
strcmp(method, "http") == 0)
|
||||
{
|
||||
/*
|
||||
* Map localhost access to localhost and local port...
|
||||
*/
|
||||
|
||||
if (strcasecmp(hostname, server) == 0)
|
||||
{
|
||||
/*
|
||||
* Make URI relative to the current server...
|
||||
*/
|
||||
|
||||
strlcpy(uri, resource, sizeof(uri));
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Rewrite URI with HTTP address...
|
||||
*/
|
||||
|
||||
if (username[0])
|
||||
snprintf(uri, sizeof(uri), "%s://%s@%s:%d%s",
|
||||
ishttps ? "https" : "http",
|
||||
username, hostname, port, resource);
|
||||
else
|
||||
snprintf(uri, sizeof(uri), "%s://%s:%d%s",
|
||||
ishttps ? "https" : "http",
|
||||
hostname, port, resource);
|
||||
}
|
||||
|
||||
strlcat(valptr, uri, sizeof(value) - (valptr - value));
|
||||
break;
|
||||
}
|
||||
ippRewriteURL(attr->values[i].string.text, valptr,
|
||||
sizeof(value) - (valptr - value));
|
||||
break;
|
||||
}
|
||||
|
||||
case IPP_TAG_STRING :
|
||||
@@ -277,10 +506,17 @@ ippSetCGIVars(ipp_t *response, /* I - Response data to be copied... */
|
||||
case IPP_TAG_KEYWORD :
|
||||
case IPP_TAG_CHARSET :
|
||||
case IPP_TAG_LANGUAGE :
|
||||
case IPP_TAG_MIMETYPE :
|
||||
strlcat(valptr, attr->values[i].string.text,
|
||||
sizeof(value) - (valptr - value));
|
||||
break;
|
||||
|
||||
case IPP_TAG_BEGIN_COLLECTION :
|
||||
snprintf(value, sizeof(value), "%s%d", name, i + 1);
|
||||
ippSetCGIVars(attr->values[i].collection, filter_name,
|
||||
filter_value, value, element);
|
||||
break;
|
||||
|
||||
default :
|
||||
break; /* anti-compiler-warning-code */
|
||||
}
|
||||
@@ -290,12 +526,19 @@ ippSetCGIVars(ipp_t *response, /* I - Response data to be copied... */
|
||||
* Add the element...
|
||||
*/
|
||||
|
||||
cgiSetArray(name, element, value);
|
||||
if (attr->value_tag != IPP_TAG_BEGIN_COLLECTION)
|
||||
{
|
||||
cgiSetArray(name, element, value);
|
||||
|
||||
DEBUG_printf(("<P>%s[%d]=\"%s\"\n", name, element, value));
|
||||
}
|
||||
}
|
||||
|
||||
if (attr == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG_puts("<P>Leaving ippSetCGIVars()...");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
* Include necessary headers...
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <cups/cups.h>
|
||||
#include <cups/debug.h>
|
||||
#include <cups/language.h>
|
||||
@@ -45,9 +44,13 @@
|
||||
* Prototype...
|
||||
*/
|
||||
|
||||
extern void ippGetAttributes(ipp_t *request, const char *directory,
|
||||
const char *tmpl, const char *lang);
|
||||
extern char *ippGetTemplateDir(void);
|
||||
extern char *ippRewriteURL(const char *, char *, int);
|
||||
extern void ippSetServerVersion(void);
|
||||
extern void ippSetCGIVars(ipp_t *, const char *, const char *);
|
||||
extern void ippSetCGIVars(ipp_t *, const char *, const char *,
|
||||
const char *, int);
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -45,16 +45,16 @@ static void do_job_op(http_t *http, cups_lang_t *language, ipp_op_t op);
|
||||
* 'main()' - Main entry for CGI.
|
||||
*/
|
||||
|
||||
int /* O - Exit status */
|
||||
main(int argc, /* I - Number of command-line arguments */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
int /* O - Exit status */
|
||||
main(int argc, /* I - Number of command-line arguments */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
{
|
||||
cups_lang_t *language; /* Language information */
|
||||
http_t *http; /* Connection to the server */
|
||||
const char *which_jobs; /* Which jobs to show */
|
||||
ipp_t *request, /* IPP request */
|
||||
*response; /* IPP response */
|
||||
const char *op; /* Operation name */
|
||||
cups_lang_t *language; /* Language information */
|
||||
http_t *http; /* Connection to the server */
|
||||
const char *which_jobs; /* Which jobs to show */
|
||||
ipp_t *request, /* IPP request */
|
||||
*response; /* IPP response */
|
||||
const char *op; /* Operation name */
|
||||
|
||||
|
||||
/*
|
||||
@@ -139,13 +139,15 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "which-jobs",
|
||||
NULL, which_jobs);
|
||||
|
||||
ippGetAttributes(request, TEMPLATES, "jobs.tmpl", getenv("LANG"));
|
||||
|
||||
/*
|
||||
* Do the request and get back a response...
|
||||
*/
|
||||
|
||||
if ((response = cupsDoRequest(http, request, "/")) != NULL)
|
||||
{
|
||||
ippSetCGIVars(response, NULL, NULL);
|
||||
ippSetCGIVars(response, NULL, NULL, NULL, 0);
|
||||
ippDelete(response);
|
||||
|
||||
cgiCopyTemplateLang(stdout, TEMPLATES, "jobs.tmpl", getenv("LANG"));
|
||||
|
||||
@@ -37,22 +37,26 @@
|
||||
* 'main()' - Main entry for CGI.
|
||||
*/
|
||||
|
||||
int /* O - Exit status */
|
||||
main(int argc, /* I - Number of command-line arguments */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
int /* O - Exit status */
|
||||
main(int argc, /* I - Number of command-line arguments */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
{
|
||||
cups_lang_t *language; /* Language information */
|
||||
char *printer; /* Printer name */
|
||||
http_t *http; /* Connection to the server */
|
||||
ipp_t *request, /* IPP request */
|
||||
*response; /* IPP response */
|
||||
ipp_attribute_t *attr; /* IPP attribute */
|
||||
ipp_status_t status; /* Operation status... */
|
||||
char uri[HTTP_MAX_URI];
|
||||
/* Printer URI */
|
||||
const char *which_jobs; /* Which jobs to show */
|
||||
const char *op; /* Operation to perform, if any */
|
||||
|
||||
cups_lang_t *language; /* Language information */
|
||||
char *printer; /* Printer name */
|
||||
http_t *http; /* Connection to the server */
|
||||
ipp_t *request, /* IPP request */
|
||||
*response; /* IPP response */
|
||||
ipp_attribute_t *attr; /* IPP attribute */
|
||||
ipp_status_t status; /* Operation status... */
|
||||
char uri[HTTP_MAX_URI]; /* Printer URI */
|
||||
const char *which_jobs; /* Which jobs to show */
|
||||
const char *op; /* Operation to perform, if any */
|
||||
static const char *def_attrs[] = /* Attributes for default printer */
|
||||
{
|
||||
"printer-name",
|
||||
"printer-uri-supported"
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Get any form variables...
|
||||
@@ -77,7 +81,8 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
* Tell the client to expect HTML...
|
||||
*/
|
||||
|
||||
printf("Content-Type: text/html;charset=%s\n\n", cupsLangEncoding(language));
|
||||
printf("Content-Type: text/html;charset=%s\r\n\r\n",
|
||||
cupsLangEncoding(language));
|
||||
|
||||
/*
|
||||
* See if we need to show a list of printers or the status of a
|
||||
@@ -113,6 +118,10 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
|
||||
"attributes-natural-language", NULL, language->language);
|
||||
|
||||
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
|
||||
"requested-attributes",
|
||||
sizeof(def_attrs) / sizeof(def_attrs[0]), NULL, def_attrs);
|
||||
|
||||
if ((response = cupsDoRequest(http, request, "/")) != NULL)
|
||||
{
|
||||
if ((attr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME)) != NULL)
|
||||
@@ -120,38 +129,12 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
|
||||
if ((attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI)) != NULL)
|
||||
{
|
||||
char method[HTTP_MAX_URI],
|
||||
username[HTTP_MAX_URI],
|
||||
hostname[HTTP_MAX_URI],
|
||||
resource[HTTP_MAX_URI],
|
||||
uri[HTTP_MAX_URI];
|
||||
int port; /* URI data */
|
||||
const char *server; /* Name of server */
|
||||
char url[HTTP_MAX_URI]; /* New URL */
|
||||
|
||||
|
||||
/*
|
||||
* Map localhost access to localhost...
|
||||
*/
|
||||
|
||||
server = getenv("SERVER_NAME");
|
||||
|
||||
httpSeparate(attr->values[0].string.text, method, username,
|
||||
hostname, &port, resource);
|
||||
|
||||
if (strcasecmp(hostname, server) == 0 &&
|
||||
(strcmp(getenv("REMOTE_HOST"), "127.0.0.1") == 0 ||
|
||||
strcmp(getenv("REMOTE_HOST"), "localhost") == 0 ||
|
||||
strcmp(getenv("REMOTE_HOST"), server) == 0))
|
||||
strcpy(hostname, "localhost");
|
||||
|
||||
/*
|
||||
* Rewrite URI with HTTP address...
|
||||
*/
|
||||
|
||||
snprintf(uri, sizeof(uri), "http://%s:%d%s", hostname, port,
|
||||
resource);
|
||||
|
||||
cgiSetVariable("DEFAULT_URI", uri);
|
||||
cgiSetVariable("DEFAULT_URI",
|
||||
ippRewriteURL(attr->values[0].string.text,
|
||||
url, sizeof(url)));
|
||||
}
|
||||
|
||||
ippDelete(response);
|
||||
@@ -202,15 +185,23 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
uri);
|
||||
}
|
||||
|
||||
ippGetAttributes(request, TEMPLATES, "printers.tmpl", getenv("LANG"));
|
||||
|
||||
/*
|
||||
* Do the request and get back a response...
|
||||
*/
|
||||
|
||||
if ((response = cupsDoRequest(http, request, "/")) != NULL)
|
||||
{
|
||||
ippSetCGIVars(response, NULL, NULL);
|
||||
ippSetCGIVars(response, NULL, NULL, NULL, 0);
|
||||
ippDelete(response);
|
||||
}
|
||||
else if (printer)
|
||||
fprintf(stderr, "ERROR: Get-Printer-Attributes request failed - %s (%x)\n",
|
||||
ippErrorString(cupsLastError()), cupsLastError());
|
||||
else
|
||||
fprintf(stderr, "ERROR: CUPS-Get-Printers request failed - %s (%x)\n",
|
||||
ippErrorString(cupsLastError()), cupsLastError());
|
||||
|
||||
/*
|
||||
* Write the report...
|
||||
@@ -253,17 +244,22 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "which-jobs",
|
||||
NULL, which_jobs);
|
||||
|
||||
ippGetAttributes(request, TEMPLATES, "jobs.tmpl", getenv("LANG"));
|
||||
|
||||
/*
|
||||
* Do the request and get back a response...
|
||||
*/
|
||||
|
||||
if ((response = cupsDoRequest(http, request, "/")) != NULL)
|
||||
{
|
||||
ippSetCGIVars(response, NULL, NULL);
|
||||
ippSetCGIVars(response, NULL, NULL, NULL, 0);
|
||||
ippDelete(response);
|
||||
|
||||
cgiCopyTemplateLang(stdout, TEMPLATES, "jobs.tmpl", getenv("LANG"));
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "ERROR: Get-Jobs request failed - %s (%x)\n",
|
||||
ippErrorString(cupsLastError()), cupsLastError());
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -320,7 +316,7 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
CUPS_DATADIR "/data/testprint.ps")) != NULL)
|
||||
{
|
||||
status = response->request.status.status_code;
|
||||
ippSetCGIVars(response, NULL, NULL);
|
||||
ippSetCGIVars(response, NULL, NULL, NULL, 0);
|
||||
|
||||
ippDelete(response);
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ cgi_copy(FILE *out, /* I - Output file */
|
||||
outptr = outval;
|
||||
}
|
||||
}
|
||||
if ((value = cgiGetArray(name + 1, element)) != NULL)
|
||||
else if ((value = cgiGetArray(name + 1, element)) != NULL)
|
||||
outptr = value;
|
||||
else
|
||||
{
|
||||
@@ -332,7 +332,7 @@ cgi_copy(FILE *out, /* I - Output file */
|
||||
* Test for existance...
|
||||
*/
|
||||
|
||||
result = cgiGetArray(name, element) != NULL && outval[0];
|
||||
result = cgiGetArray(name, element) != NULL && outptr[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
cupsd.conf
|
||||
pam.conf
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# "$Id: client.conf 3041 2002-12-17 19:00:27Z swdev $"
|
||||
# "$Id: client.conf 3705 2003-05-09 19:14:44Z mike $"
|
||||
#
|
||||
# Sample client configuration file for the Common UNIX Printing System
|
||||
# (CUPS).
|
||||
@@ -34,7 +34,9 @@
|
||||
#
|
||||
# ServerName: the hostname of your server. By default CUPS will use the
|
||||
# hostname of the system or the value of the CUPS_SERVER environment
|
||||
# variable.
|
||||
# variable. ONLY ONE SERVER NAME MAY BE SPECIFIED AT A TIME. To use
|
||||
# more than one server you must use a local scheduler with browsing
|
||||
# and possibly polling.
|
||||
#
|
||||
|
||||
#ServerName myhost.domain.com
|
||||
@@ -61,5 +63,5 @@
|
||||
|
||||
|
||||
#
|
||||
# End of "$Id: client.conf 3041 2002-12-17 19:00:27Z swdev $".
|
||||
# End of "$Id: client.conf 3705 2003-05-09 19:14:44Z mike $".
|
||||
#
|
||||
|
||||
@@ -218,6 +218,28 @@ LogLevel info
|
||||
|
||||
#MaxJobs 500
|
||||
|
||||
#
|
||||
# MaxJobsPerPrinter: maximum number of active jobs per printer. The default
|
||||
# is 0 for no limit.
|
||||
#
|
||||
|
||||
#MaxJobsPerPrinter 0
|
||||
|
||||
#
|
||||
# MaxJobsPerUser: maximum number of active jobs per user. The default
|
||||
# is 0 for no limit.
|
||||
#
|
||||
|
||||
#MaxJobsPerUser 0
|
||||
|
||||
#
|
||||
# MaxPrinterHistory: controls the maximum number of history collections
|
||||
# in the printer-state-history attribute. Set to 0 to disable history
|
||||
# data.
|
||||
#
|
||||
|
||||
#MaxPrinterHistory 10
|
||||
|
||||
#
|
||||
# Printcap: the name of the printcap file. Default is /etc/printcap.
|
||||
# Leave blank to disable printcap file generation.
|
||||
@@ -274,6 +296,25 @@ LogLevel info
|
||||
#ServerRoot @CUPS_SERVERROOT@
|
||||
|
||||
|
||||
########
|
||||
######## Fax Support
|
||||
########
|
||||
|
||||
#
|
||||
# FaxRetryLimit: the number of times a fax job is retried.
|
||||
# The default is 5 times.
|
||||
#
|
||||
|
||||
#FaxRetryLimit 5
|
||||
|
||||
#
|
||||
# FaxRetryInterval: the number of seconds between fax job retries.
|
||||
# The default is 300 seconds/5 minutes.
|
||||
#
|
||||
|
||||
#FaxRetryInterval 300
|
||||
|
||||
|
||||
########
|
||||
######## Encryption Support
|
||||
########
|
||||
@@ -441,7 +482,7 @@ Port 631
|
||||
# NOTE: If you choose to use SLPv2, it is *strongly* recommended that
|
||||
# you have at least one SLP Directory Agent (DA) on your
|
||||
# network. Otherwise, browse updates can take several seconds,
|
||||
# during which the scheduler will not response to client
|
||||
# during which the scheduler will not respond to client
|
||||
# requests.
|
||||
#
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# "$Id: mime.convs 3041 2002-12-17 19:00:27Z swdev $"
|
||||
# "$Id: mime.convs 3709 2003-05-12 17:38:18Z mike $"
|
||||
#
|
||||
# MIME converts file for the Common UNIX Printing System (CUPS).
|
||||
#
|
||||
@@ -55,6 +55,7 @@ image/gif application/vnd.cups-postscript 66 imagetops
|
||||
image/png application/vnd.cups-postscript 66 imagetops
|
||||
image/jpeg application/vnd.cups-postscript 66 imagetops
|
||||
image/tiff application/vnd.cups-postscript 66 imagetops
|
||||
image/x-bitmap application/vnd.cups-postscript 66 imagetops
|
||||
image/x-photocd application/vnd.cups-postscript 66 imagetops
|
||||
image/x-portable-anymap application/vnd.cups-postscript 66 imagetops
|
||||
image/x-portable-bitmap application/vnd.cups-postscript 66 imagetops
|
||||
@@ -63,7 +64,7 @@ image/x-portable-pixmap application/vnd.cups-postscript 66 imagetops
|
||||
image/x-sgi-rgb application/vnd.cups-postscript 66 imagetops
|
||||
image/x-xbitmap application/vnd.cups-postscript 66 imagetops
|
||||
image/x-xpixmap application/vnd.cups-postscript 66 imagetops
|
||||
image/x-xwindowdump application/vnd.cups-postscript 66 imagetops
|
||||
#image/x-xwindowdump application/vnd.cups-postscript 66 imagetops
|
||||
image/x-sun-raster application/vnd.cups-postscript 66 imagetops
|
||||
|
||||
|
||||
@@ -86,6 +87,7 @@ image/gif application/vnd.cups-raster 100 imagetoraster
|
||||
image/png application/vnd.cups-raster 100 imagetoraster
|
||||
image/jpeg application/vnd.cups-raster 100 imagetoraster
|
||||
image/tiff application/vnd.cups-raster 100 imagetoraster
|
||||
image/x-bitmap application/vnd.cups-raster 100 imagetoraster
|
||||
image/x-photocd application/vnd.cups-raster 100 imagetoraster
|
||||
image/x-portable-anymap application/vnd.cups-raster 100 imagetoraster
|
||||
image/x-portable-bitmap application/vnd.cups-raster 100 imagetoraster
|
||||
@@ -94,7 +96,7 @@ image/x-portable-pixmap application/vnd.cups-raster 100 imagetoraster
|
||||
image/x-sgi-rgb application/vnd.cups-raster 100 imagetoraster
|
||||
image/x-xbitmap application/vnd.cups-raster 100 imagetoraster
|
||||
image/x-xpixmap application/vnd.cups-raster 100 imagetoraster
|
||||
image/x-xwindowdump application/vnd.cups-raster 100 imagetoraster
|
||||
#image/x-xwindowdump application/vnd.cups-raster 100 imagetoraster
|
||||
image/x-sun-raster application/vnd.cups-raster 100 imagetoraster
|
||||
|
||||
# pstoraster is now part of ESP Ghostscript...
|
||||
@@ -112,5 +114,5 @@ image/x-sun-raster application/vnd.cups-raster 100 imagetoraster
|
||||
#application/octet-stream application/vnd.cups-raw 0 -
|
||||
|
||||
#
|
||||
# End of "$Id: mime.convs 3041 2002-12-17 19:00:27Z swdev $".
|
||||
# End of "$Id: mime.convs 3709 2003-05-12 17:38:18Z mike $".
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# "$Id: mime.types 3041 2002-12-17 19:00:27Z swdev $"
|
||||
# "$Id: mime.types 3564 2003-04-07 18:03:28Z mike $"
|
||||
#
|
||||
# MIME types file for the Common UNIX Printing System (CUPS).
|
||||
#
|
||||
@@ -41,6 +41,8 @@
|
||||
# printable(offset,length) True if bytes are printable 8-bit chars
|
||||
# (CR, NL, TAB, BS, 32-126, 128-254)
|
||||
# string(offset,"string") True if bytes are identical to string
|
||||
# istring(offset,"string") True if bytes are identical to
|
||||
# case-insensitive string
|
||||
# char(offset,value) True if byte is identical
|
||||
# short(offset,value) True if 16-bit integer is identical
|
||||
# int(offset,value) True if 32-bit integer is identical
|
||||
@@ -68,9 +70,13 @@
|
||||
# Application-generated files...
|
||||
#
|
||||
|
||||
application/msword doc string(0,<D0CF11E0A1B11AE1>)
|
||||
#application/msword doc string(0,<D0CF11E0A1B11AE1>)
|
||||
application/pdf pdf string(0,%PDF)
|
||||
application/postscript ai eps ps string(0,%!) string(0,<04>%!)
|
||||
application/postscript ai eps ps string(0,%!) string(0,<04>%!) \
|
||||
contains(0,128,<1B>%-12345X) + \
|
||||
(contains(0,1024,"LANGUAGE=POSTSCRIPT") \
|
||||
contains(0,1024,"LANGUAGE = Postscript") \
|
||||
contains(0,1024,"LANGUAGE = POSTSCRIPT"))
|
||||
application/vnd.hp-HPGL hpgl string(0,<1B>&)\
|
||||
string(0,<1B>E<1B>%0B) \
|
||||
string(0,<1B>%-1B) string(0,<201B>)\
|
||||
@@ -101,7 +107,7 @@ image/x-portable-pixmap ppm string(0,P3) string(0,P6)
|
||||
image/x-sgi-rgb rgb sgi bw icon short(0,474)
|
||||
image/x-xbitmap xbm
|
||||
image/x-xpixmap xpm ascii(0,1024) + string(3,"XPM")
|
||||
image/x-xwindowdump xwd string(4,<00000007>)
|
||||
#image/x-xwindowdump xwd string(4,<00000007>)
|
||||
image/x-sun-raster ras string(0,<59a66a95>)
|
||||
|
||||
#image/fpx fpx
|
||||
@@ -114,7 +120,7 @@ image/x-bitmap bmp string(0,BM) && !printable(2,14)
|
||||
#
|
||||
|
||||
text/html html htm printable(0,1024) +\
|
||||
(string(0,"<HTML>") string(0,"<!DOCTYPE"))
|
||||
(istring(0,"<HTML>") istring(0,"<!DOCTYPE"))
|
||||
application/x-cshell csh printable(0,1024) + string(0,#!) +\
|
||||
(contains(2,80,/csh) contains(2,80,/tcsh))
|
||||
application/x-perl pl printable(0,1024) + string(0,#!) +\
|
||||
@@ -131,10 +137,7 @@ text/plain txt printable(0,1024)
|
||||
|
||||
application/vnd.cups-command string(0,'#CUPS-COMMAND')
|
||||
application/vnd.cups-form string(0,"<CUPSFORM>")
|
||||
application/vnd.cups-postscript contains(0,128,<1B>%-12345X) + \
|
||||
(contains(0,1024,"LANGUAGE=POSTSCRIPT") \
|
||||
contains(0,1024,"LANGUAGE = Postscript") \
|
||||
contains(0,1024,"LANGUAGE = POSTSCRIPT"))
|
||||
application/vnd.cups-postscript
|
||||
application/vnd.cups-raster string(0,"RaSt") string(0,"tSaR")
|
||||
application/vnd.cups-raw (string(0,<1B>E) + !string(2,<1B>%0B)) \
|
||||
string(0,<1B>@) \
|
||||
@@ -154,5 +157,5 @@ application/vnd.cups-raw (string(0,<1B>E) + !string(2,<1B>%0B)) \
|
||||
#application/octet-stream
|
||||
|
||||
#
|
||||
# End of "$Id: mime.types 3041 2002-12-17 19:00:27Z swdev $".
|
||||
# End of "$Id: mime.types 3564 2003-04-07 18:03:28Z mike $".
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
dnl
|
||||
dnl "$Id: cups-common.m4 3041 2002-12-17 19:00:27Z swdev $"
|
||||
dnl "$Id: cups-common.m4 3993 2003-11-07 20:18:02Z mike $"
|
||||
dnl
|
||||
dnl Common configuration stuff for the Common UNIX Printing System (CUPS).
|
||||
dnl
|
||||
@@ -28,6 +28,11 @@ AC_PREREQ(2.50)
|
||||
dnl Set the name of the config header file...
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
||||
dnl Version number information...
|
||||
CUPS_VERSION="1.1.20rc6"
|
||||
AC_SUBST(CUPS_VERSION)
|
||||
AC_DEFINE_UNQUOTED(CUPS_SVERSION, "CUPS v$CUPS_VERSION")
|
||||
|
||||
dnl Default compiler flags...
|
||||
CFLAGS="${CFLAGS:=}"
|
||||
CPPFLAGS="${CPPFLAGS:=}"
|
||||
@@ -47,6 +52,7 @@ fi
|
||||
AC_PROG_RANLIB
|
||||
AC_PATH_PROG(AR,ar)
|
||||
AC_PATH_PROG(HTMLDOC,htmldoc)
|
||||
AC_PATH_PROG(LN,ln)
|
||||
AC_PATH_PROG(MV,mv)
|
||||
AC_PATH_PROG(NROFF,nroff)
|
||||
if test "$NROFF" = ""; then
|
||||
@@ -61,6 +67,16 @@ AC_PATH_PROG(RM,rm)
|
||||
AC_PATH_PROG(SED,sed)
|
||||
AC_PATH_PROG(STRIP,strip)
|
||||
|
||||
if test "x$AR" = x; then
|
||||
AC_MSG_ERROR([Unable to find required library archive command.])
|
||||
fi
|
||||
if test "x$CC" = x; then
|
||||
AC_MSG_ERROR([Unable to find required C compiler command.])
|
||||
fi
|
||||
if test "x$CXX" = x; then
|
||||
AC_MSG_ERROR([Unable to find required C++ compiler command.])
|
||||
fi
|
||||
|
||||
dnl Architecture checks...
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
@@ -84,6 +100,19 @@ fi
|
||||
|
||||
AC_SUBST(LIBMALLOC)
|
||||
|
||||
dnl Check for libpaper support...
|
||||
AC_ARG_ENABLE(libpaper, [ --enable-libpaper turn on libpaper support, default=no])
|
||||
|
||||
if test x$enable_libpaper = xyes; then
|
||||
AC_CHECK_LIB(paper,systempapername,
|
||||
AC_DEFINE(HAVE_LIBPAPER)
|
||||
LIBPAPER="-lpaper",
|
||||
LIBPAPER="")
|
||||
else
|
||||
LIBPAPER=""
|
||||
fi
|
||||
AC_SUBST(LIBPAPER)
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_DIRENT
|
||||
@@ -157,18 +186,21 @@ esac
|
||||
|
||||
AC_SUBST(ARFLAGS)
|
||||
|
||||
dnl Libraries for the backends...
|
||||
dnl Extra platform-specific libraries...
|
||||
case $uname in
|
||||
Darwin*)
|
||||
BACKLIBS="-framework CoreFoundation -framework IOKit"
|
||||
BACKLIBS="-framework IOKit"
|
||||
COMMONLIBS="-framework CoreFoundation"
|
||||
;;
|
||||
*)
|
||||
BACKLIBS=""
|
||||
COMMONLIBS=""
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(BACKLIBS)
|
||||
AC_SUBST(COMMONLIBS)
|
||||
|
||||
dnl
|
||||
dnl End of "$Id: cups-common.m4 3041 2002-12-17 19:00:27Z swdev $".
|
||||
dnl End of "$Id: cups-common.m4 3993 2003-11-07 20:18:02Z mike $".
|
||||
dnl
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
dnl
|
||||
dnl "$Id: cups-compiler.m4 3041 2002-12-17 19:00:27Z swdev $"
|
||||
dnl "$Id: cups-compiler.m4 3874 2003-08-20 18:27:48Z mike $"
|
||||
dnl
|
||||
dnl Common configuration stuff for the Common UNIX Printing System (CUPS).
|
||||
dnl
|
||||
@@ -133,7 +133,16 @@ else
|
||||
fi
|
||||
|
||||
if test "x$with_optim" = x; then
|
||||
OPTIM="-fullwarn $OPTIM"
|
||||
# Show most warnings, but suppress the
|
||||
# ones about arguments not being used,
|
||||
# string constants assigned to const
|
||||
# char *'s, etc. We only set the warning
|
||||
# options on IRIX 6.2 and higher because
|
||||
# of limitations in the older SGI compiler
|
||||
# tools.
|
||||
if test $uversion -ge 62; then
|
||||
OPTIM="-fullwarn -woff 1183,1209,1349,3201 $OPTIM"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
SunOS*)
|
||||
@@ -147,7 +156,9 @@ else
|
||||
fi
|
||||
|
||||
if test "x$with_optim" = x; then
|
||||
OPTIM="$OPTIM -xarch=generic"
|
||||
# Specify "generic" SPARC output and suppress
|
||||
# all of Sun's questionable warning messages...
|
||||
OPTIM="-w $OPTIM -xarch=generic"
|
||||
fi
|
||||
|
||||
if test $PICFLAG = 1; then
|
||||
@@ -180,6 +191,16 @@ else
|
||||
esac
|
||||
fi
|
||||
|
||||
if test $uname = HP-UX; then
|
||||
# HP-UX 10.20 (at least) needs this definition to get the
|
||||
# h_errno global...
|
||||
OPTIM="$OPTIM -D_XOPEN_SOURCE_EXTENDED"
|
||||
|
||||
# HP-UX 11.00 (at least) needs this definition to get the
|
||||
# u_short type used by the IP headers...
|
||||
OPTIM="$OPTIM -D_INCLUDE_HPUX_SOURCE"
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl End of "$Id: cups-compiler.m4 3041 2002-12-17 19:00:27Z swdev $".
|
||||
dnl End of "$Id: cups-compiler.m4 3874 2003-08-20 18:27:48Z mike $".
|
||||
dnl
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
dnl
|
||||
dnl "$Id: cups-network.m4 3041 2002-12-17 19:00:27Z swdev $"
|
||||
dnl "$Id: cups-network.m4 3888 2003-08-28 15:16:08Z mike $"
|
||||
dnl
|
||||
dnl Networking stuff for the Common UNIX Printing System (CUPS).
|
||||
dnl
|
||||
@@ -29,13 +29,31 @@ if test "$uname" != "IRIX"; then
|
||||
AC_CHECK_LIB(nsl,gethostbyaddr,NETLIBS="$NETLIBS -lnsl")
|
||||
fi
|
||||
|
||||
AC_CHECK_FUNCS(rresvport getifaddrs)
|
||||
AC_CHECK_FUNCS(rresvport getifaddrs hstrerror)
|
||||
|
||||
AC_CHECK_MEMBER(struct sockaddr.sa_len,,,[#include <sys/socket.h>])
|
||||
AC_CHECK_HEADER(sys/sockio.h,AC_DEFINE(HAVE_SYS_SOCKIO_H))
|
||||
|
||||
AC_SUBST(NETLIBS)
|
||||
|
||||
if test "$uname" = "SunOS"; then
|
||||
case "$uversion" in
|
||||
55* | 56*)
|
||||
maxfiles=1024
|
||||
;;
|
||||
*)
|
||||
maxfiles=4096
|
||||
;;
|
||||
esac
|
||||
else
|
||||
maxfiles=4096
|
||||
fi
|
||||
|
||||
AC_ARG_WITH(maxfiles, [ --with-maxfiles=N set maximum number of file descriptors for scheduler ],
|
||||
maxfiles=$withval)
|
||||
|
||||
AC_DEFINE_UNQUOTED(CUPS_MAX_FDS, $maxfiles)
|
||||
|
||||
dnl
|
||||
dnl End of "$Id: cups-network.m4 3041 2002-12-17 19:00:27Z swdev $".
|
||||
dnl End of "$Id: cups-network.m4 3888 2003-08-28 15:16:08Z mike $".
|
||||
dnl
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
dnl
|
||||
dnl "$Id: cups-openssl.m4 3041 2002-12-17 19:00:27Z swdev $"
|
||||
dnl "$Id: cups-openssl.m4 3940 2003-09-17 19:35:22Z mike $"
|
||||
dnl
|
||||
dnl OpenSSL stuff for the Common UNIX Printing System (CUPS).
|
||||
dnl OpenSSL/GNUTLS stuff for the Common UNIX Printing System (CUPS).
|
||||
dnl
|
||||
dnl Copyright 1997-2003 by Easy Software Products, all rights reserved.
|
||||
dnl
|
||||
@@ -23,6 +23,9 @@ dnl WWW: http://www.cups.org
|
||||
dnl
|
||||
|
||||
AC_ARG_ENABLE(ssl, [ --enable-ssl turn on SSL/TLS support, default=yes])
|
||||
AC_ARG_ENABLE(openssl, [ --enable-openssl use OpenSSL for SSL/TLS support, default=yes])
|
||||
AC_ARG_ENABLE(gnutls, [ --enable-gnutls use GNU TLS for SSL/TLS support, default=yes])
|
||||
AC_ARG_ENABLE(cdsassl, [ --enable-cdsassl use CDSA for SSL/TLS support, default=yes])
|
||||
AC_ARG_WITH(openssl-libs, [ --with-openssl-libs set directory for OpenSSL library],
|
||||
LDFLAGS="-L$withval $LDFLAGS"
|
||||
DSOFLAGS="-L$withval $DSOFLAGS",)
|
||||
@@ -31,38 +34,73 @@ AC_ARG_WITH(openssl-includes, [ --with-openssl-includes set directory for OpenS
|
||||
CXXFLAGS="-I$withval $CXXFLAGS"
|
||||
CPPFLAGS="-I$withval $CPPFLAGS",)
|
||||
|
||||
SSLFLAGS=""
|
||||
SSLLIBS=""
|
||||
|
||||
if test x$enable_ssl != xno; then
|
||||
AC_CHECK_HEADER(openssl/ssl.h,
|
||||
dnl Save the current libraries so the crypto stuff isn't always
|
||||
dnl included...
|
||||
SAVELIBS="$LIBS"
|
||||
dnl Check for the OpenSSL library first, which has precedence over
|
||||
dnl CDSA and GNUTLS...
|
||||
if test "x${SSLLIBS}" = "x" -a "x${enable_openssl}" != "xno"; then
|
||||
AC_CHECK_HEADER(openssl/ssl.h,
|
||||
dnl Save the current libraries so the crypto stuff isn't always
|
||||
dnl included...
|
||||
SAVELIBS="$LIBS"
|
||||
|
||||
dnl Some ELF systems can't resolve all the symbols in libcrypto
|
||||
dnl if libcrypto was linked against RSAREF, and fail to link the
|
||||
dnl test program correctly, even though a correct installation
|
||||
dnl of OpenSSL exists. So we test the linking three times in
|
||||
dnl case the RSAREF libraries are needed.
|
||||
dnl Some ELF systems can't resolve all the symbols in libcrypto
|
||||
dnl if libcrypto was linked against RSAREF, and fail to link the
|
||||
dnl test program correctly, even though a correct installation
|
||||
dnl of OpenSSL exists. So we test the linking three times in
|
||||
dnl case the RSAREF libraries are needed.
|
||||
|
||||
for libcrypto in \
|
||||
"-lcrypto" \
|
||||
"-lcrypto -lrsaref" \
|
||||
"-lcrypto -lRSAglue -lrsaref"
|
||||
do
|
||||
AC_CHECK_LIB(ssl,SSL_new,
|
||||
[SSLLIBS="-lssl $libcrypto"
|
||||
AC_DEFINE(HAVE_LIBSSL)],,
|
||||
$libcrypto)
|
||||
for libcrypto in \
|
||||
"-lcrypto" \
|
||||
"-lcrypto -lrsaref" \
|
||||
"-lcrypto -lRSAglue -lrsaref"
|
||||
do
|
||||
AC_CHECK_LIB(ssl,SSL_new,
|
||||
[SSLFLAGS="-DOPENSSL_DISABLE_OLD_DES_SUPPORT"
|
||||
SSLLIBS="-lssl $libcrypto"
|
||||
AC_DEFINE(HAVE_SSL)
|
||||
AC_DEFINE(HAVE_LIBSSL)],,
|
||||
$libcrypto)
|
||||
|
||||
if test "x${SSLLIBS}" != "x"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test "x${SSLLIBS}" != "x"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
LIBS="$SAVELIBS")
|
||||
LIBS="$SAVELIBS")
|
||||
fi
|
||||
|
||||
dnl If OpenSSL wasn't found, look for CDSA...
|
||||
if test "x${SSLLIBS}" = "x" -a "x${enable_cdsassl}" != "xno"; then
|
||||
if test $uname = Darwin; then
|
||||
AC_CHECK_HEADER(Security/SecureTransport.h,
|
||||
[SSLLIBS="-framework CoreFoundation -framework Security"
|
||||
AC_DEFINE(HAVE_SSL)
|
||||
AC_DEFINE(HAVE_CDSASSL)])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl Then look for GNU TLS...
|
||||
if test "x${SSLLIBS}" = "x" -a "x${enable_gnutls}" != "xno"; then
|
||||
AC_CHECK_HEADER(gnutls/gnutls.h,
|
||||
dnl Save the current libraries so the crypto stuff isn't always
|
||||
dnl included...
|
||||
SAVELIBS="$LIBS"
|
||||
|
||||
TEST_GNUTLS_LIBS=`libgnutls-config --libs`
|
||||
AC_CHECK_LIB(gnutls, gnutls_init,
|
||||
[SSLLIBS=$TEST_GNUTLS_LIBS
|
||||
AC_DEFINE(HAVE_SSL)
|
||||
AC_DEFINE(HAVE_GNUTLS)],,
|
||||
$TEST_GNUTLS_LIBS)
|
||||
|
||||
LIBS="$SAVELIBS")
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(SSLFLAGS)
|
||||
AC_SUBST(SSLLIBS)
|
||||
|
||||
EXPORT_SSLLIBS="$SSLLIBS"
|
||||
@@ -70,5 +108,5 @@ AC_SUBST(EXPORT_SSLLIBS)
|
||||
|
||||
|
||||
dnl
|
||||
dnl End of "$Id: cups-openssl.m4 3041 2002-12-17 19:00:27Z swdev $".
|
||||
dnl End of "$Id: cups-openssl.m4 3940 2003-09-17 19:35:22Z mike $".
|
||||
dnl
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
dnl
|
||||
dnl "$Id: cups-opsys.m4 3041 2002-12-17 19:00:27Z swdev $"
|
||||
dnl "$Id: cups-opsys.m4 3929 2003-09-15 20:32:12Z mike $"
|
||||
dnl
|
||||
dnl Operating system stuff for the Common UNIX Printing System (CUPS).
|
||||
dnl
|
||||
@@ -55,28 +55,29 @@ AC_ARG_WITH(cups-user, [ --with-cups-user set default user for CUPS],
|
||||
AC_ARG_WITH(cups-group, [ --with-cups-group set default group for CUPS],
|
||||
CUPS_GROUP="$withval",
|
||||
AC_MSG_CHECKING(for default print group)
|
||||
if test x$uname = xDarwin; then
|
||||
CUPS_GROUP="admin"
|
||||
AC_MSG_RESULT(Darwin, using "$CUPS_GROUP")
|
||||
else
|
||||
if test -f /etc/group; then
|
||||
CUPS_GROUP=""
|
||||
for group in sys system root; do
|
||||
if test "`grep \^${group}: /etc/group`" != ""; then
|
||||
CUPS_GROUP="$group"
|
||||
AC_MSG_RESULT($group)
|
||||
break;
|
||||
fi
|
||||
done
|
||||
|
||||
if test x$CUPS_GROUP = x; then
|
||||
CUPS_GROUP="${GROUP:=nobody}"
|
||||
AC_MSG_RESULT(not found, using "$CUPS_GROUP")
|
||||
fi
|
||||
if test -f /etc/group; then
|
||||
if test x$uname = xDarwin; then
|
||||
GROUP_LIST="lp admin"
|
||||
else
|
||||
CUPS_GROUP="${GROUP:=nobody}"
|
||||
AC_MSG_RESULT(no group file, using "$CUPS_GROUP")
|
||||
GROUP_LIST="sys system root"
|
||||
fi
|
||||
|
||||
CUPS_GROUP=""
|
||||
for group in $GROUP_LIST; do
|
||||
if test "`grep \^${group}: /etc/group`" != ""; then
|
||||
CUPS_GROUP="$group"
|
||||
AC_MSG_RESULT($group)
|
||||
break;
|
||||
fi
|
||||
done
|
||||
|
||||
if test x$CUPS_GROUP = x; then
|
||||
CUPS_GROUP="${GROUP:=nobody}"
|
||||
AC_MSG_RESULT(not found, using "$CUPS_GROUP")
|
||||
fi
|
||||
else
|
||||
CUPS_GROUP="${GROUP:=nobody}"
|
||||
AC_MSG_RESULT(no group file, using "$CUPS_GROUP")
|
||||
fi)
|
||||
|
||||
AC_SUBST(CUPS_USER)
|
||||
@@ -86,5 +87,5 @@ AC_DEFINE_UNQUOTED(CUPS_DEFAULT_USER, "$CUPS_USER")
|
||||
AC_DEFINE_UNQUOTED(CUPS_DEFAULT_GROUP, "$CUPS_GROUP")
|
||||
|
||||
dnl
|
||||
dnl "$Id: cups-opsys.m4 3041 2002-12-17 19:00:27Z swdev $"
|
||||
dnl "$Id: cups-opsys.m4 3929 2003-09-15 20:32:12Z mike $"
|
||||
dnl
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
dnl
|
||||
dnl "$Id: cups-scripting.m4 3472 2003-03-14 17:04:09Z mike $"
|
||||
dnl
|
||||
dnl Scripting configuration stuff for the Common UNIX Printing System (CUPS).
|
||||
dnl
|
||||
dnl Copyright 1997-2003 by Easy Software Products, all rights reserved.
|
||||
dnl
|
||||
dnl These coded instructions, statements, and computer programs are the
|
||||
dnl property of Easy Software Products and are protected by Federal
|
||||
dnl copyright law. Distribution and use rights are outlined in the file
|
||||
dnl "LICENSE.txt" which should have been included with this file. If this
|
||||
dnl file is missing or damaged please contact Easy Software Products
|
||||
dnl at:
|
||||
dnl
|
||||
dnl Attn: CUPS Licensing Information
|
||||
dnl Easy Software Products
|
||||
dnl 44141 Airport View Drive, Suite 204
|
||||
dnl Hollywood, Maryland 20636-3111 USA
|
||||
dnl
|
||||
dnl Voice: (301) 373-9603
|
||||
dnl EMail: cups-info@cups.org
|
||||
dnl WWW: http://www.cups.org
|
||||
dnl
|
||||
|
||||
dnl Do we have Java?
|
||||
AC_ARG_WITH(java, [ --with-java set Java interpreter for web interfaces ],
|
||||
CUPS_JAVA="$withval",
|
||||
CUPS_JAVA="")
|
||||
|
||||
if test "x$CUPS_JAVA" = x; then
|
||||
AC_PATH_PROG(JAVA,java)
|
||||
CUPS_JAVA="$JAVA"
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED(CUPS_JAVA, "$CUPS_JAVA")
|
||||
|
||||
if test "x$CUPS_JAVA" != x; then
|
||||
AC_DEFINE(HAVE_JAVA)
|
||||
fi
|
||||
|
||||
dnl Do we have Perl?
|
||||
AC_ARG_WITH(perl, [ --with-perl set Perl interpreter for web interfaces ],
|
||||
CUPS_PERL="$withval",
|
||||
CUPS_PERL="")
|
||||
|
||||
if test "x$CUPS_PERL" = x; then
|
||||
AC_PATH_PROG(PERL,perl)
|
||||
CUPS_PERL="$PERL"
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED(CUPS_PERL, "$CUPS_PERL")
|
||||
|
||||
if test "x$CUPS_PERL" != x; then
|
||||
AC_DEFINE(HAVE_PERL)
|
||||
fi
|
||||
|
||||
dnl Do we have PHP?
|
||||
AC_ARG_WITH(php, [ --with-php set PHP interpreter for web interfaces ],
|
||||
CUPS_PHP="$withval",
|
||||
CUPS_PHP="")
|
||||
|
||||
if test "x$CUPS_PHP" = x; then
|
||||
AC_PATH_PROG(PHP,php)
|
||||
CUPS_PHP="$PHP"
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED(CUPS_PHP, "$CUPS_PHP")
|
||||
|
||||
if test "x$CUPS_PHP" != x; then
|
||||
AC_DEFINE(HAVE_PHP)
|
||||
fi
|
||||
|
||||
dnl Do we have Python?
|
||||
AC_ARG_WITH(python, [ --with-python set Python interpreter for web interfaces ],
|
||||
CUPS_PYTHON="$withval",
|
||||
CUPS_PYTHON="")
|
||||
|
||||
if test "x$CUPS_PYTHON" = x; then
|
||||
AC_PATH_PROG(PYTHON,python)
|
||||
CUPS_PYTHON="$PYTHON"
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED(CUPS_PYTHON, "$CUPS_PYTHON")
|
||||
|
||||
if test "x$CUPS_PYTHON" != x; then
|
||||
AC_DEFINE(HAVE_PYTHON)
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl End of "$Id: cups-scripting.m4 3472 2003-03-14 17:04:09Z mike $".
|
||||
dnl
|
||||
@@ -1,5 +1,5 @@
|
||||
dnl
|
||||
dnl "$Id: cups-sharedlibs.m4 3041 2002-12-17 19:00:27Z swdev $"
|
||||
dnl "$Id: cups-sharedlibs.m4 3826 2003-07-23 20:07:35Z mike $"
|
||||
dnl
|
||||
dnl Shared library support for the Common UNIX Printing System (CUPS).
|
||||
dnl
|
||||
@@ -45,7 +45,7 @@ if test x$enable_shared != xno; then
|
||||
LIBCUPS="libcups.so.2"
|
||||
LIBCUPSIMAGE="libcupsimage.so.2"
|
||||
DSO="\$(CC)"
|
||||
DSOFLAGS="$DSOFLAGS -Wl,-rpath,\$(libdir),-set_version,sgi2.4,-soname,\$@ -shared \$(OPTIM)"
|
||||
DSOFLAGS="$DSOFLAGS -Wl,-rpath,\$(libdir),-set_version,sgi2.5,-soname,\$@ -shared \$(OPTIM)"
|
||||
;;
|
||||
OSF1* | Linux* | *BSD*)
|
||||
LIBCUPS="libcups.so.2"
|
||||
@@ -63,7 +63,7 @@ if test x$enable_shared != xno; then
|
||||
LIBCUPS="libcups_s.a"
|
||||
LIBCUPSIMAGE="libcupsimage_s.a"
|
||||
DSO="\$(CC)"
|
||||
DSOFLAGS="$DSOFLAGS -Wl,-bexpall,-bM:SRE,-bnoentry"
|
||||
DSOFLAGS="$DSOFLAGS -Wl,-bexpall,-bM:SRE,-bnoentry,-blibpath:\$(libdir)"
|
||||
;;
|
||||
*)
|
||||
echo "Warning: shared libraries may not be supported. Trying -shared"
|
||||
@@ -87,8 +87,8 @@ AC_SUBST(LIBCUPS)
|
||||
AC_SUBST(LIBCUPSIMAGE)
|
||||
|
||||
if test x$enable_shared = xno; then
|
||||
LINKCUPS="-lcups \$(SSLLIBS)"
|
||||
LINKCUPSIMAGE="-lcupsimage"
|
||||
LINKCUPS="../cups/libcups.a \$(SSLLIBS)"
|
||||
LINKCUPSIMAGE="../filter/libcupsimage.a"
|
||||
else
|
||||
if test $uname = AIX; then
|
||||
LINKCUPS="-lcups_s"
|
||||
@@ -103,6 +103,8 @@ AC_SUBST(LINKCUPS)
|
||||
AC_SUBST(LINKCUPSIMAGE)
|
||||
|
||||
dnl Update libraries for DSOs...
|
||||
EXPORT_LDFLAGS=""
|
||||
|
||||
if test "$DSO" != ":"; then
|
||||
# When using DSOs the image libraries are linked to libcupsimage.so
|
||||
# rather than to the executables. This makes things smaller if you
|
||||
@@ -119,21 +121,25 @@ if test "$DSO" != ":"; then
|
||||
# HP-UX
|
||||
DSOFLAGS="+s +b $libdir $DSOFLAGS"
|
||||
LDFLAGS="$LDFLAGS -Wl,+s,+b,$libdir"
|
||||
EXPORT_LDFLAGS="-Wl,+s,+b,$libdir"
|
||||
;;
|
||||
SunOS*)
|
||||
# Solaris
|
||||
DSOFLAGS="-R$libdir $DSOFLAGS"
|
||||
LDFLAGS="$LDFLAGS -R$libdir"
|
||||
EXPORT_LDFLAGS="-R$libdir"
|
||||
;;
|
||||
*BSD*)
|
||||
# *BSD
|
||||
DSOFLAGS="-Wl,-R$libdir $DSOFLAGS"
|
||||
LDFLAGS="$LDFLAGS -Wl,-R$libdir"
|
||||
EXPORT_LDFLAGS="-Wl,-R$libdir"
|
||||
;;
|
||||
Linux*)
|
||||
# Linux
|
||||
DSOFLAGS="-Wl,-rpath,$libdir $DSOFLAGS"
|
||||
LDFLAGS="$LDFLAGS -Wl,-rpath,$libdir"
|
||||
EXPORT_LDFLAGS="-Wl,-rpath,$libdir"
|
||||
;;
|
||||
esac
|
||||
else
|
||||
@@ -143,7 +149,8 @@ fi
|
||||
|
||||
AC_SUBST(DSOLIBS)
|
||||
AC_SUBST(IMGLIBS)
|
||||
AC_SUBST(EXPORT_LDFLAGS)
|
||||
|
||||
dnl
|
||||
dnl End of "$Id: cups-sharedlibs.m4 3041 2002-12-17 19:00:27Z swdev $".
|
||||
dnl End of "$Id: cups-sharedlibs.m4 3826 2003-07-23 20:07:35Z mike $".
|
||||
dnl
|
||||
|
||||
@@ -24,11 +24,14 @@
|
||||
* WWW: http://www.cups.org
|
||||
*/
|
||||
|
||||
#ifndef _CUPS_CONFIG_H_
|
||||
#define _CUPS_CONFIG_H_
|
||||
|
||||
/*
|
||||
* Version of software...
|
||||
*/
|
||||
|
||||
#define CUPS_SVERSION "CUPS v1.1.18"
|
||||
#define CUPS_SVERSION "CUPS v1.1.19rc3"
|
||||
|
||||
|
||||
/*
|
||||
@@ -39,6 +42,13 @@
|
||||
#define CUPS_DEFAULT_GROUP "sys"
|
||||
|
||||
|
||||
/*
|
||||
* Maximum number of file descriptors to support.
|
||||
*/
|
||||
|
||||
#define CUPS_MAX_FDS 4096
|
||||
|
||||
|
||||
/*
|
||||
* Where are files stored?
|
||||
*/
|
||||
@@ -172,10 +182,13 @@
|
||||
|
||||
|
||||
/*
|
||||
* Do we have the OpenSSL library?
|
||||
* Which encryption libraries do we have?
|
||||
*/
|
||||
|
||||
#undef HAVE_CDSASSL
|
||||
#undef HAVE_GNUTLS
|
||||
#undef HAVE_LIBSSL
|
||||
#undef HAVE_SSL
|
||||
|
||||
|
||||
/*
|
||||
@@ -185,6 +198,13 @@
|
||||
#undef HAVE_LIBSLP
|
||||
|
||||
|
||||
/*
|
||||
* Do we have libpaper?
|
||||
*/
|
||||
|
||||
#undef HAVE_LIBPAPER
|
||||
|
||||
|
||||
/*
|
||||
* Do we have <sys/ioctl.h>?
|
||||
*/
|
||||
@@ -221,6 +241,13 @@
|
||||
#undef HAVE_GETIFADDRS
|
||||
|
||||
|
||||
/*
|
||||
* Do we have hstrerror()?
|
||||
*/
|
||||
|
||||
#undef HAVE_HSTRERROR
|
||||
|
||||
|
||||
/*
|
||||
* Do we have the <sys/sockio.h> header file?
|
||||
*/
|
||||
@@ -235,6 +262,22 @@
|
||||
#undef HAVE_STRUCT_SOCKADDR_SA_LEN
|
||||
|
||||
|
||||
/*
|
||||
* 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"
|
||||
|
||||
|
||||
#endif /* !_CUPS_CONFIG_H_ */
|
||||
|
||||
/*
|
||||
* End of "$Id$".
|
||||
*/
|
||||
|
||||
@@ -39,6 +39,8 @@ sinclude(config-scripts/cups-openslp.m4)
|
||||
sinclude(config-scripts/cups-openssl.m4)
|
||||
sinclude(config-scripts/cups-pam.m4)
|
||||
|
||||
sinclude(config-scripts/cups-scripting.m4)
|
||||
|
||||
AC_OUTPUT(Makedefs cups.list cups.sh cups-config conf/cupsd.conf conf/pam.conf)
|
||||
|
||||
chmod +x cups-config
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
# WWW: http://www.cups.org
|
||||
#
|
||||
|
||||
VERSION="1.1.18"
|
||||
VERSION="@CUPS_VERSION@"
|
||||
APIVERSION="1.1"
|
||||
|
||||
prefix=@prefix@
|
||||
@@ -39,8 +39,8 @@ cups_serverroot=@CUPS_SERVERROOT@
|
||||
|
||||
# flags for C++ compiler:
|
||||
CFLAGS=""
|
||||
LDFLAGS=""
|
||||
LIBS="@EXPORT_SSLLIBS@ @NETLIBS@"
|
||||
LDFLAGS="@EXPORT_LDFLAGS@"
|
||||
LIBS="@EXPORT_SSLLIBS@ @NETLIBS@ @COMMONLIBS@"
|
||||
IMGLIBS="@EXPORT_LIBTIFF@ @EXPORT_LIBJPEG@ @EXPORT_LIBPNG@ @EXPORT_LIBZ@"
|
||||
|
||||
if test $includedir != /usr/include; then
|
||||
|
||||
@@ -3,106 +3,7 @@ Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "cups"=.\cups\cups.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "enumports"=.\visualc\enumports.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "fltk"="..\fltk-1.1\visualc\fltk.lib.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "fltkimages"="..\fltk-1.1\visualc\fltkimages.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "gui"=.\gui\gui.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "printers"=.\gui\printers.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name cups
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name fltk
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name gui
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name fltkimages
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name zlib
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "restartspooler"=.\visualc\restartspooler.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "zlib"="..\htmldoc-1.8\visualc\zlib.dsp" - Package Owner=<4>
|
||||
Project: "cups"=".\cups\cups.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
|
||||
@@ -29,12 +29,26 @@
|
||||
%vendor Easy Software Products
|
||||
%license LICENSE.txt
|
||||
%readme README.txt
|
||||
%version 1.1.18
|
||||
%provides cupsys
|
||||
%version @CUPS_VERSION@
|
||||
%description The Common UNIX Printing System provides a portable printing
|
||||
%description layer for UNIX® operating systems. It has been developed by
|
||||
%description Easy Software Products to promote a standard printing solution
|
||||
%description for all UNIX vendors and users. CUPS provides the System V and
|
||||
%description Berkeley command-line interfaces.
|
||||
%provides cups-devel
|
||||
%provides cups-libs
|
||||
%provides cupsys
|
||||
%provides cupsys-bsd
|
||||
%provides cupsys-client
|
||||
%provides cupsys-devel
|
||||
%provides libcups1
|
||||
%provides libcups.so.2
|
||||
%provides libcupsys2
|
||||
%provides libcupsys2-dev
|
||||
|
||||
%format rpm deb portable
|
||||
%provides @LIBCUPS@
|
||||
%provides @LIBCUPSIMAGE@
|
||||
%format all
|
||||
|
||||
#
|
||||
# GNU variables...
|
||||
@@ -89,6 +103,8 @@ $CAT8EXT=@CAT8EXT@
|
||||
$MAN8EXT=@MAN8EXT@
|
||||
$MAN8DIR=@MAN8DIR@
|
||||
|
||||
$DSOLIBS=@DSOLIBS@
|
||||
|
||||
# Make sure the MD5 password file is now owned by CUPS_USER...
|
||||
%postinstall if test -f $SERVERROOT/passwd.md5; then
|
||||
%postinstall chown $CUPS_USER $SERVERROOT/passwd.md5
|
||||
@@ -123,15 +139,16 @@ d 0555 root sys $SERVERBIN/daemon -
|
||||
f 0555 root sys $SERVERBIN/daemon/cups-lpd scheduler/cups-lpd
|
||||
f 0555 root sys $SERVERBIN/daemon/cups-polld scheduler/cups-polld
|
||||
d 0555 root sys $SERVERBIN/filter -
|
||||
f 0555 root sys $SERVERBIN/filter/pdftops pdftops/pdftops
|
||||
f 0555 root sys $SERVERBIN/filter/gziptoany filter/gziptoany
|
||||
f 0555 root sys $SERVERBIN/filter/hpgltops filter/hpgltops
|
||||
f 0555 root sys $SERVERBIN/filter/imagetops filter/imagetops
|
||||
f 0555 root sys $SERVERBIN/filter/imagetoraster filter/imagetoraster
|
||||
f 0555 root sys $SERVERBIN/filter/pdftops pdftops/pdftops
|
||||
f 0555 root sys $SERVERBIN/filter/pstops filter/pstops
|
||||
f 0555 root sys $SERVERBIN/filter/texttops filter/texttops
|
||||
f 0555 root sys $SERVERBIN/filter/rastertodymo filter/rastertodymo
|
||||
f 0555 root sys $SERVERBIN/filter/rastertoepson filter/rastertoepson
|
||||
f 0555 root sys $SERVERBIN/filter/rastertohp filter/rastertohp
|
||||
f 0555 root sys $SERVERBIN/filter/hpgltops filter/hpgltops
|
||||
f 0555 root sys $SERVERBIN/filter/imagetoraster filter/imagetoraster
|
||||
f 0555 root sys $SERVERBIN/filter/texttops filter/texttops
|
||||
|
||||
# Admin commands
|
||||
l 0555 root sys $BINDIR/disable $SBINDIR/accept
|
||||
@@ -153,6 +170,7 @@ l 0555 root sys /usr/etc/lpc $SBINDIR/lpc
|
||||
|
||||
# User commands
|
||||
f 0555 root sys $BINDIR/cancel systemv/cancel
|
||||
f 0555 root sys $BINDIR/cupstestppd systemv/cupstestppd
|
||||
f 0555 root sys $BINDIR/lp systemv/lp
|
||||
f 0555 root sys $BINDIR/lpoptions systemv/lpoptions
|
||||
f 4555 $CUPS_USER sys $BINDIR/lppasswd systemv/lppasswd
|
||||
@@ -168,6 +186,7 @@ l 0555 root sys /usr/bsd/lprm $BINDIR/lprm
|
||||
%system all
|
||||
|
||||
# DSOs
|
||||
%if DSOLIBS
|
||||
%system hpux
|
||||
f 0555 root sys $LIBDIR/libcups.sl.2 cups/libcups.sl.2
|
||||
l 0555 root sys $LIBDIR/libcups.sl libcups.sl.2
|
||||
@@ -187,6 +206,7 @@ l 0555 root sys $LIBDIR/libcups.so libcups.so.2
|
||||
f 0555 root sys $LIBDIR/libcupsimage.so.2 filter/libcupsimage.so.2
|
||||
l 0555 root sys $LIBDIR/libcupsimage.so libcupsimage.so.2
|
||||
%system all
|
||||
%endif
|
||||
|
||||
# Directories
|
||||
d 0755 root sys $LOGDIR -
|
||||
@@ -199,14 +219,14 @@ f 0444 root sys $LOCALEDIR/be/cups_be locale/be/cups_be
|
||||
f 0444 root sys $LOCALEDIR/cs/cups_cs locale/cs/cups_cs
|
||||
f 0444 root sys $LOCALEDIR/de/cups_de locale/de/cups_de
|
||||
f 0444 root sys $LOCALEDIR/en/cups_en locale/en/cups_en
|
||||
f 0444 root sys $LOCALEDIR/en_US/cups_en_US locale/en_US/cups_en_US
|
||||
f 0444 root sys $LOCALEDIR/es/cups_es locale/es/cups_es
|
||||
f 0444 root sys $LOCALEDIR/fr/cups_fr locale/fr/cups_fr
|
||||
f 0444 root sys $LOCALEDIR/it/cups_it locale/it/cups_it
|
||||
f 0444 root sys $LOCALEDIR/ru_RU.cp1251/cups_ru_RU.cp1251 locale/ru_RU.cp1251/cups_ru_RU.cp1251
|
||||
f 0444 root sys $LOCALEDIR/ru_RU.koi8r/cups_ru_RU.koi8r locale/ru_RU.koi8r/cups_ru_RU.koi8r
|
||||
f 0444 root sys $LOCALEDIR/ru_RU/cups_ru_RU locale/ru_RU/cups_ru_RU
|
||||
f 0444 root sys $LOCALEDIR/sv/cups_sv locale/sv/cups_sv
|
||||
f 0444 root sys $LOCALEDIR/uk/cups_uk locale/uk/cups_uk
|
||||
f 0444 root sys $LOCALEDIR/uk_UA.cp1251/cups_uk_UA.cp1251 locale/uk_UA.cp1251/cups_uk_UA.cp1251
|
||||
f 0444 root sys $LOCALEDIR/uk_UA/cups_uk_UA locale/uk_UA/cups_uk_UA
|
||||
f 0444 root sys $LOCALEDIR/zh_CN/cups_zh_CN locale/zh_CN/cups_zh_CN
|
||||
|
||||
d 0555 root sys $DATADIR -
|
||||
@@ -260,6 +280,9 @@ f 0444 root sys $DATADIR/model ppd/*.ppd
|
||||
d 0555 root sys $DATADIR/templates -
|
||||
c 0444 root sys $DATADIR/templates templates/*.tmpl
|
||||
|
||||
d 0555 root sys $DATADIR/templates/de -
|
||||
c 0444 root sys $DATADIR/templates/de templates/de/*.tmpl
|
||||
|
||||
d 0555 root sys $DATADIR/templates/fr -
|
||||
c 0444 root sys $DATADIR/templates/fr templates/fr/*.tmpl
|
||||
|
||||
@@ -272,17 +295,20 @@ c 0600 root sys $SERVERROOT conf/*.conf
|
||||
c 0600 root sys $SERVERROOT/mime.convs conf/mime.convs
|
||||
c 0600 root sys $SERVERROOT/mime.types conf/mime.types
|
||||
|
||||
%system linux
|
||||
%if PAMDIR
|
||||
d 0555 root sys $PAMDIR -
|
||||
|
||||
%system linux
|
||||
# Linux almost always supports PAM...
|
||||
c 0644 root sys $PAMDIR/cups conf/pam.conf
|
||||
|
||||
%system irix
|
||||
# IRIX doesn't normally support PAM, but the freeware project
|
||||
# includes a version of PAM that can be used...
|
||||
%system irix
|
||||
d 0555 root sys $PAMDIR -
|
||||
c 0644 root sys $PAMDIR/cups conf/pam.irix
|
||||
|
||||
%system all
|
||||
%endif
|
||||
|
||||
# Developer files
|
||||
f 0555 root sys $BINDIR/cups-config cups-config
|
||||
@@ -297,12 +323,18 @@ f 0444 root sys $INCLUDEDIR/cups/ppd.h cups/ppd.h
|
||||
f 0444 root sys $INCLUDEDIR/cups/raster.h filter/raster.h
|
||||
|
||||
f 0444 root sys $LIBDIR/libcups.a cups/libcups.a
|
||||
f 0444 root sys $LIBDIR/libcupsimage.a filter/libcupsimage.a
|
||||
|
||||
# Documentation files
|
||||
d 0555 root sys $DOCDIR -
|
||||
f 0444 root sys $DOCDIR doc/*.css
|
||||
f 0444 root sys $DOCDIR doc/*.html
|
||||
f 0444 root sys $DOCDIR doc/*.pdf
|
||||
f 0444 root sys $DOCDIR/robots.txt doc/robots.txt
|
||||
d 0555 root sys $DOCDIR/de -
|
||||
f 0444 root sys $DOCDIR/de doc/de/*.css
|
||||
f 0444 root sys $DOCDIR/de doc/de/*.html
|
||||
f 0444 root sys $DOCDIR/de doc/de/*.pdf
|
||||
d 0555 root sys $DOCDIR/fr -
|
||||
f 0444 root sys $DOCDIR/fr doc/fr/*.css
|
||||
f 0444 root sys $DOCDIR/fr doc/fr/*.html
|
||||
@@ -324,6 +356,7 @@ d 0555 root sys $PMANDIR/cat3 -
|
||||
d 0555 root sys $PMANDIR/man3 -
|
||||
|
||||
f 0444 root sys $MANDIR/cat1/backend.$CAT1EXT man/backend.$CAT1EXT
|
||||
f 0444 root sys $MANDIR/cat1/cupstestppd.$CAT1EXT man/cupstestppd.$CAT1EXT
|
||||
f 0444 root sys $MANDIR/cat1/filter.$CAT1EXT man/filter.$CAT1EXT
|
||||
f 0444 root sys $MANDIR/cat1/lpoptions.$CAT1EXT man/lpoptions.$CAT1EXT
|
||||
f 0444 root sys $MANDIR/cat1/lppasswd.$CAT1EXT man/lppasswd.$CAT1EXT
|
||||
@@ -355,24 +388,25 @@ f 0444 root sys $AMANDIR/cat$MAN8DIR/lpc.$CAT8EXT man/lpc.$CAT8EXT
|
||||
f 0444 root sys $AMANDIR/cat$MAN8DIR/lpinfo.$CAT8EXT man/lpinfo.$CAT8EXT
|
||||
f 0444 root sys $AMANDIR/cat$MAN8DIR/lpmove.$CAT8EXT man/lpmove.$CAT8EXT
|
||||
|
||||
f 0444 root sys $MANDIR/man1/backend.$MAN1EXT man/backend.man
|
||||
f 0444 root sys $MANDIR/man1/filter.$MAN1EXT man/filter.man
|
||||
f 0444 root sys $MANDIR/man1/lpoptions.$MAN1EXT man/lpoptions.man
|
||||
f 0444 root sys $MANDIR/man1/lppasswd.$MAN1EXT man/lppasswd.man
|
||||
f 0444 root sys $MANDIR/man1/lpq.$MAN1EXT man/lpq.man
|
||||
f 0444 root sys $MANDIR/man1/lprm.$MAN1EXT man/lprm.man
|
||||
f 0444 root sys $MANDIR/man1/lpr.$MAN1EXT man/lpr.man
|
||||
f 0444 root sys $MANDIR/man1/lpstat.$MAN1EXT man/lpstat.man
|
||||
f 0444 root sys $MANDIR/man1/lp.$MAN1EXT man/lp.man
|
||||
l 0444 root sys $MANDIR/man1/cancel.$MAN1EXT lp.$MAN1EXT
|
||||
f 0444 root sys $MANDIR/man1/backend.1 man/backend.man
|
||||
f 0444 root sys $MANDIR/man1/cupstestppd.1 man/cupstestppd.man
|
||||
f 0444 root sys $MANDIR/man1/filter.1 man/filter.man
|
||||
f 0444 root sys $MANDIR/man1/lpoptions.1 man/lpoptions.man
|
||||
f 0444 root sys $MANDIR/man1/lppasswd.1 man/lppasswd.man
|
||||
f 0444 root sys $MANDIR/man1/lpq.1 man/lpq.man
|
||||
f 0444 root sys $MANDIR/man1/lprm.1 man/lprm.man
|
||||
f 0444 root sys $MANDIR/man1/lpr.1 man/lpr.man
|
||||
f 0444 root sys $MANDIR/man1/lpstat.1 man/lpstat.man
|
||||
f 0444 root sys $MANDIR/man1/lp.1 man/lp.man
|
||||
l 0444 root sys $MANDIR/man1/cancel.1 lp.1
|
||||
|
||||
f 0444 root sys $PMANDIR/man3/cups-config.$MAN3EXT man/cups-config.man
|
||||
f 0444 root sys $PMANDIR/man3/cups-config.3 man/cups-config.man
|
||||
|
||||
f 0444 root sys $MANDIR/man5/classes.conf.$MAN5EXT man/classes.conf.man
|
||||
f 0444 root sys $MANDIR/man5/cupsd.conf.$MAN5EXT man/cupsd.conf.man
|
||||
f 0444 root sys $MANDIR/man5/mime.convs.$MAN5EXT man/mime.convs.man
|
||||
f 0444 root sys $MANDIR/man5/mime.types.$MAN5EXT man/mime.types.man
|
||||
f 0444 root sys $MANDIR/man5/printers.conf.$MAN5EXT man/printers.conf.man
|
||||
f 0444 root sys $MANDIR/man5/classes.conf.5 man/classes.conf.man
|
||||
f 0444 root sys $MANDIR/man5/cupsd.conf.5 man/cupsd.conf.man
|
||||
f 0444 root sys $MANDIR/man5/mime.convs.5 man/mime.convs.man
|
||||
f 0444 root sys $MANDIR/man5/mime.types.5 man/mime.types.man
|
||||
f 0444 root sys $MANDIR/man5/printers.conf.5 man/printers.conf.man
|
||||
|
||||
f 0444 root sys $AMANDIR/man$MAN8DIR/accept.$MAN8EXT man/accept.man
|
||||
l 0444 root sys $AMANDIR/man$MAN8DIR/reject.$MAN8EXT accept.$MAN8EXT
|
||||
@@ -431,24 +465,24 @@ f 0444 root sys $AMANDIR/fr/cat$MAN8DIR/lpc.$CAT8EXT man/lpc.$CAT8EXT
|
||||
f 0444 root sys $AMANDIR/fr/cat$MAN8DIR/lpinfo.$CAT8EXT man/lpinfo.$CAT8EXT
|
||||
f 0444 root sys $AMANDIR/fr/cat$MAN8DIR/lpmove.$CAT8EXT man/lpmove.$CAT8EXT
|
||||
|
||||
f 0444 root sys $MANDIR/fr/man1/backend.$MAN1EXT man/backend.man
|
||||
f 0444 root sys $MANDIR/fr/man1/filter.$MAN1EXT man/filter.man
|
||||
f 0444 root sys $MANDIR/fr/man1/lpoptions.$MAN1EXT man/lpoptions.man
|
||||
f 0444 root sys $MANDIR/fr/man1/lppasswd.$MAN1EXT man/lppasswd.man
|
||||
f 0444 root sys $MANDIR/fr/man1/lpq.$MAN1EXT man/lpq.man
|
||||
f 0444 root sys $MANDIR/fr/man1/lprm.$MAN1EXT man/lprm.man
|
||||
f 0444 root sys $MANDIR/fr/man1/lpr.$MAN1EXT man/lpr.man
|
||||
f 0444 root sys $MANDIR/fr/man1/lpstat.$MAN1EXT man/lpstat.man
|
||||
f 0444 root sys $MANDIR/fr/man1/lp.$MAN1EXT man/lp.man
|
||||
l 0444 root sys $MANDIR/fr/man1/cancel.$MAN1EXT lp.$MAN1EXT
|
||||
f 0444 root sys $MANDIR/fr/man1/backend.1 man/backend.man
|
||||
f 0444 root sys $MANDIR/fr/man1/filter.1 man/filter.man
|
||||
f 0444 root sys $MANDIR/fr/man1/lpoptions.1 man/lpoptions.man
|
||||
f 0444 root sys $MANDIR/fr/man1/lppasswd.1 man/lppasswd.man
|
||||
f 0444 root sys $MANDIR/fr/man1/lpq.1 man/lpq.man
|
||||
f 0444 root sys $MANDIR/fr/man1/lprm.1 man/lprm.man
|
||||
f 0444 root sys $MANDIR/fr/man1/lpr.1 man/lpr.man
|
||||
f 0444 root sys $MANDIR/fr/man1/lpstat.1 man/lpstat.man
|
||||
f 0444 root sys $MANDIR/fr/man1/lp.1 man/lp.man
|
||||
l 0444 root sys $MANDIR/fr/man1/cancel.1 lp.1
|
||||
|
||||
f 0444 root sys $PMANDIR/fr/man3/cups-config.$MAN3EXT man/cups-config.man
|
||||
f 0444 root sys $PMANDIR/fr/man3/cups-config.3 man/cups-config.man
|
||||
|
||||
f 0444 root sys $MANDIR/fr/man5/classes.conf.$MAN5EXT man/classes.conf.man
|
||||
f 0444 root sys $MANDIR/fr/man5/cupsd.conf.$MAN5EXT man/cupsd.conf.man
|
||||
f 0444 root sys $MANDIR/fr/man5/mime.convs.$MAN5EXT man/mime.convs.man
|
||||
f 0444 root sys $MANDIR/fr/man5/mime.types.$MAN5EXT man/mime.types.man
|
||||
f 0444 root sys $MANDIR/fr/man5/printers.conf.$MAN5EXT man/printers.conf.man
|
||||
f 0444 root sys $MANDIR/fr/man5/classes.conf.5 man/classes.conf.man
|
||||
f 0444 root sys $MANDIR/fr/man5/cupsd.conf.5 man/cupsd.conf.man
|
||||
f 0444 root sys $MANDIR/fr/man5/mime.convs.5 man/mime.convs.man
|
||||
f 0444 root sys $MANDIR/fr/man5/mime.types.5 man/mime.types.man
|
||||
f 0444 root sys $MANDIR/fr/man5/printers.conf.5 man/printers.conf.man
|
||||
|
||||
f 0444 root sys $AMANDIR/fr/man$MAN8DIR/accept.$MAN8EXT man/accept.man
|
||||
l 0444 root sys $AMANDIR/fr/man$MAN8DIR/reject.$MAN8EXT accept.$MAN8EXT
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#!/bin/sh
|
||||
|
||||
##
|
||||
# PrintingServices - a.k.a. CUPS
|
||||
##
|
||||
|
||||
. /etc/rc.common
|
||||
|
||||
StartService ()
|
||||
{
|
||||
if [ "${CUPS:=-YES-}" = "-YES-" ]; then
|
||||
ConsoleMessage "Starting printing services"
|
||||
/usr/sbin/cupsd
|
||||
fi
|
||||
}
|
||||
|
||||
StopService ()
|
||||
{
|
||||
# Until cupsd has a pid file...
|
||||
pid=`ps ax | awk '{if (match($5, ".*/cupsd$") || $5 == "cupsd") print $1}'`
|
||||
if test "$pid" != ""; then
|
||||
ConsoleMessage "Stopping printing services"
|
||||
kill "${pid}"
|
||||
fi
|
||||
}
|
||||
|
||||
RestartService ()
|
||||
{
|
||||
# Until cupsd has a pid file...
|
||||
pid=`ps ax | awk '{if (match($5, ".*/cupsd$") || $5 == "cupsd") print $1}'`
|
||||
if test "x$pid" != x; then
|
||||
ConsoleMessage "Restarting printing services"
|
||||
kill -HUP "${pid}"
|
||||
else
|
||||
StartService
|
||||
fi
|
||||
}
|
||||
|
||||
RunService "$1"
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
Description = "Printing Services";
|
||||
Provides = ("Printing");
|
||||
Provides = ("PrintingServices");
|
||||
Requires = ("Resolver");
|
||||
Uses = ("Network Time");
|
||||
OrderPreference = "Late";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# "$Id: cups.spec 3041 2002-12-17 19:00:27Z swdev $"
|
||||
# "$Id: cups.spec 3993 2003-11-07 20:18:02Z mike $"
|
||||
#
|
||||
# RPM "spec" file for the Common UNIX Printing System (CUPS).
|
||||
#
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
Summary: Common Unix Printing System
|
||||
Name: cups
|
||||
Version: 1.1.18
|
||||
Version: 1.1.20rc6
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: System Environment/Daemons
|
||||
@@ -46,6 +46,10 @@ Provides: libcupsimage.so.2
|
||||
%package devel
|
||||
Summary: Common Unix Printing System - development environment
|
||||
Group: Development/Libraries
|
||||
|
||||
%package libs
|
||||
Summary: Common Unix Printing System - shared libraries
|
||||
Group: System Environment/Libraries
|
||||
Provides: libcups1
|
||||
|
||||
%description
|
||||
@@ -59,6 +63,10 @@ The Common UNIX Printing System provides a portable printing layer for
|
||||
UNIX® operating systems. This is the development package for creating
|
||||
additional printer drivers and other CUPS services.
|
||||
|
||||
%description libs
|
||||
The Common UNIX Printing System provides a portable printing layer for
|
||||
UNIX® operating systems. This package contains the CUPS shared libraries.
|
||||
|
||||
%prep
|
||||
%setup
|
||||
|
||||
@@ -127,26 +135,31 @@ rm -rf $RPM_BUILD_ROOT
|
||||
# RC dirs are a pain under Linux... Uncomment the appropriate ones if you
|
||||
# don't use Red Hat or Mandrake...
|
||||
|
||||
# OLD RedHat/Mandrake
|
||||
/etc/rc.d/init.d/*
|
||||
/etc/rc.d/rc0.d/*
|
||||
/etc/rc.d/rc2.d/*
|
||||
/etc/rc.d/rc3.d/*
|
||||
/etc/rc.d/rc5.d/*
|
||||
|
||||
#/etc/init.d/*
|
||||
#/etc/rc0.d/*
|
||||
#/etc/rc3.d/*
|
||||
#/etc/rc5.d/*
|
||||
|
||||
#/sbin/rc.d/*
|
||||
#/sbin/rc.d/rc0.d/*
|
||||
#/sbin/rc.d/rc2.d/*
|
||||
#/sbin/rc.d/rc3.d/*
|
||||
#/sbin/rc.d/rc5.d/*
|
||||
|
||||
# NEW RedHat/Mandrake
|
||||
#/etc/init.d/*
|
||||
#/etc/rc0.d/*
|
||||
#/etc/rc2.d/*
|
||||
#/etc/rc3.d/*
|
||||
#/etc/rc5.d/*
|
||||
|
||||
/usr/bin/cancel
|
||||
/usr/bin/cupstestppd
|
||||
/usr/bin/disable
|
||||
/usr/bin/enable
|
||||
/usr/bin/lp*
|
||||
/usr/lib/*.so*
|
||||
%dir /usr/lib/cups
|
||||
/usr/lib/cups/*
|
||||
/usr/sbin/*
|
||||
@@ -202,6 +215,9 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%dir /usr/share/man/fr/man3
|
||||
/usr/share/man/fr/man3/*
|
||||
|
||||
%files libs
|
||||
/usr/lib/*.so*
|
||||
|
||||
#
|
||||
# End of "$Id: cups.spec 3041 2002-12-17 19:00:27Z swdev $".
|
||||
# End of "$Id: cups.spec 3993 2003-11-07 20:18:02Z mike $".
|
||||
#
|
||||
|
||||
@@ -8,4 +8,6 @@ libcups_s.a
|
||||
libcups.2.dylib
|
||||
libcups.dylib
|
||||
testhttp
|
||||
testipp
|
||||
testlang
|
||||
testppd
|
||||
|
||||
@@ -1,26 +1,31 @@
|
||||
# DO NOT DELETE
|
||||
|
||||
dest.o: cups.h ipp.h http.h md5.h ppd.h language.h string.h ../config.h
|
||||
attr.o: ppd.h debug.h string.h ../config.h
|
||||
auth.o: cups.h ipp.h http.h string.h ../config.h md5.h ppd.h language.h
|
||||
auth.o: debug.h
|
||||
dest.o: cups.h ipp.h http.h string.h ../config.h md5.h ppd.h language.h
|
||||
emit.o: ppd.h string.h ../config.h
|
||||
encode.o: cups.h ipp.h http.h md5.h ppd.h string.h ../config.h debug.h
|
||||
http.o: string.h ../config.h http.h md5.h debug.h
|
||||
encode.o: cups.h ipp.h http.h string.h ../config.h md5.h ppd.h debug.h
|
||||
getputfile.o: cups.h ipp.h http.h string.h ../config.h md5.h ppd.h language.h
|
||||
getputfile.o: debug.h
|
||||
http.o: http-private.h ../config.h http.h string.h md5.h debug.h
|
||||
http-addr.o: string.h ../config.h http.h md5.h
|
||||
http-support.o: string.h ../config.h http.h md5.h ipp.h
|
||||
ipp.o: string.h ../config.h language.h ipp.h http.h md5.h debug.h
|
||||
ipp.o: string.h ../config.h ipp.h http.h md5.h debug.h
|
||||
ipp-support.o: string.h ../config.h language.h ipp.h http.h md5.h debug.h
|
||||
language.o: string.h ../config.h language.h cups_C.h
|
||||
language.o: string.h ../config.h language.h debug.h cups_C.h
|
||||
mark.o: ppd.h string.h ../config.h debug.h
|
||||
md5.o: md5.h string.h ../config.h
|
||||
md5passwd.o: http.h md5.h string.h ../config.h
|
||||
options.o: cups.h ipp.h http.h md5.h ppd.h string.h ../config.h debug.h
|
||||
md5passwd.o: http.h string.h ../config.h md5.h
|
||||
options.o: cups.h ipp.h http.h string.h ../config.h md5.h ppd.h debug.h
|
||||
page.o: ppd.h string.h ../config.h
|
||||
ppd.o: ppd.h string.h ../config.h language.h debug.h
|
||||
snprintf.o: string.h ../config.h
|
||||
string.o: string.h ../config.h
|
||||
tempfile.o: cups.h ipp.h http.h md5.h ppd.h string.h ../config.h debug.h
|
||||
usersys.o: cups.h ipp.h http.h md5.h ppd.h string.h ../config.h
|
||||
util.o: cups.h ipp.h http.h md5.h ppd.h language.h string.h ../config.h
|
||||
tempfile.o: cups.h ipp.h http.h string.h ../config.h md5.h ppd.h debug.h
|
||||
usersys.o: cups.h ipp.h http.h string.h ../config.h md5.h ppd.h
|
||||
util.o: cups.h ipp.h http.h string.h ../config.h md5.h ppd.h language.h
|
||||
util.o: debug.h
|
||||
testhttp.o: http.h md5.h
|
||||
testhttp.o: http.h string.h ../config.h md5.h
|
||||
testipp.o: ../cups/string.h ../config.h string.h ipp.h http.h md5.h
|
||||
testlang.o: language.h
|
||||
testppd.o: cups.h ipp.h http.h md5.h ppd.h string.h ../config.h
|
||||
|
||||
@@ -30,11 +30,11 @@ include ../Makedefs
|
||||
# Object files...
|
||||
#
|
||||
|
||||
LIBOBJS = dest.o emit.o encode.o http.o http-addr.o http-support.o \
|
||||
ipp.o ipp-support.o language.o mark.o md5.o md5passwd.o \
|
||||
options.o page.o ppd.o snprintf.o string.o tempfile.o \
|
||||
usersys.o util.o
|
||||
OBJS = $(LIBOBJS) testhttp.o testlang.o
|
||||
LIBOBJS = attr.o auth.o dest.o emit.o encode.o getputfile.o \
|
||||
http.o http-addr.o http-support.o ipp.o ipp-support.o \
|
||||
language.o mark.o md5.o md5passwd.o options.o page.o \
|
||||
ppd.o snprintf.o string.o tempfile.o usersys.o util.o
|
||||
OBJS = $(LIBOBJS) testhttp.o testipp.o testlang.o
|
||||
|
||||
|
||||
#
|
||||
@@ -48,7 +48,8 @@ HEADERS = cups.h http.h ipp.h language.h md5.h ppd.h
|
||||
# Targets in this directory...
|
||||
#
|
||||
|
||||
TARGETS = $(LIBCUPS) libcups.a
|
||||
TARGETS = $(LIBCUPS) libcups.a \
|
||||
testhttp testipp testlang
|
||||
|
||||
|
||||
#
|
||||
@@ -108,7 +109,7 @@ installhdrs:
|
||||
|
||||
libcups.so.2 libcups.sl.2: $(LIBOBJS) ../Makedefs
|
||||
echo Linking $@...
|
||||
$(DSO) $(DSOFLAGS) -o $@ $(LIBOBJS) $(SSLLIBS)
|
||||
$(DSO) $(DSOFLAGS) -o $@ $(LIBOBJS) $(SSLLIBS) $(COMMONLIBS)
|
||||
$(RM) `basename $@ .2`
|
||||
$(LN) $@ `basename $@ .2`
|
||||
|
||||
@@ -121,9 +122,9 @@ libcups.2.dylib: $(LIBOBJS) ../Makedefs
|
||||
echo Linking $@...
|
||||
$(DSO) $(DSOFLAGS) -o $@ \
|
||||
-install_name $(libdir)/$@ \
|
||||
-current_version 2.0.4 \
|
||||
-current_version 2.5.0 \
|
||||
-compatibility_version 2.0.0 \
|
||||
$(LIBOBJS) $(SSLLIBS)
|
||||
$(LIBOBJS) $(SSLLIBS) $(COMMONLIBS)
|
||||
$(RM) libcups.dylib
|
||||
$(LN) $@ libcups.dylib
|
||||
|
||||
@@ -136,7 +137,7 @@ libcups_s.a: $(LIBOBJS) ../Makedefs
|
||||
echo Creating $@...
|
||||
$(RM) libcups_s.exp
|
||||
(echo _ipp_add_attr; echo _ipp_free_attr) >libcups_s.exp
|
||||
$(DSO) $(DSOFLAGS) -Wl,-bexport:libcups_s.exp -o libcups_s.o $(LIBOBJS) $(SSLLIBS) -lm
|
||||
$(DSO) $(DSOFLAGS) -Wl,-bexport:libcups_s.exp -o libcups_s.o $(LIBOBJS) $(SSLLIBS) $(COMMONLIBS) -lm
|
||||
$(RM) $@
|
||||
$(AR) $(ARFLAGS) $@ libcups_s.o
|
||||
|
||||
@@ -148,7 +149,7 @@ libcups_s.a: $(LIBOBJS) ../Makedefs
|
||||
libcups.la: $(LIBOBJS) ../Makedefs
|
||||
echo Linking $@...
|
||||
$(DSO) $(DSOFLAGS) -o $@ $(LIBOBJS:.o=.lo) -rpath $(LIBDIR) \
|
||||
-version-info 2:4 $(SSLLIBS)
|
||||
-version-info 2:5 $(SSLLIBS) $(COMMONLIBS)
|
||||
|
||||
|
||||
#
|
||||
@@ -178,7 +179,16 @@ cups_C.h: ../locale/C/cups_C
|
||||
|
||||
testhttp: testhttp.o libcups.a
|
||||
echo Linking $@...
|
||||
$(CC) $(LDFLAGS) -o $@ testhttp.o libcups.a $(NETLIBS) $(SSLLIBS)
|
||||
$(CC) $(LDFLAGS) -o $@ testhttp.o libcups.a $(NETLIBS) $(SSLLIBS) $(COMMONLIBS)
|
||||
|
||||
|
||||
#
|
||||
# testipp (dependency on static CUPS library is intentional)
|
||||
#
|
||||
|
||||
testipp: testipp.o libcups.a
|
||||
echo Linking $@...
|
||||
$(CC) $(LDFLAGS) -o $@ testipp.o libcups.a $(NETLIBS) $(SSLLIBS) $(COMMONLIBS)
|
||||
|
||||
|
||||
#
|
||||
@@ -187,7 +197,7 @@ testhttp: testhttp.o libcups.a
|
||||
|
||||
testlang: testlang.o libcups.a
|
||||
echo Linking $@...
|
||||
$(CC) $(LDFLAGS) -o $@ testlang.o libcups.a $(NETLIBS) $(SSLLIBS)
|
||||
$(CC) $(LDFLAGS) -o $@ testlang.o libcups.a $(NETLIBS) $(SSLLIBS) $(COMMONLIBS)
|
||||
|
||||
|
||||
#
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* "$Id$"
|
||||
*
|
||||
* PPD model-specific attribute routines for the Common UNIX Printing System
|
||||
* (CUPS).
|
||||
*
|
||||
* Copyright 1997-2003 by Easy Software Products.
|
||||
*
|
||||
* These coded instructions, statements, and computer programs are the
|
||||
* property of Easy Software Products and are protected by Federal
|
||||
* copyright law. Distribution and use rights are outlined in the file
|
||||
* "LICENSE.txt" which should have been included with this file. If this
|
||||
* file is missing or damaged please contact Easy Software Products
|
||||
* at:
|
||||
*
|
||||
* Attn: CUPS Licensing Information
|
||||
* Easy Software Products
|
||||
* 44141 Airport View Drive, Suite 204
|
||||
* Hollywood, Maryland 20636-3111 USA
|
||||
*
|
||||
* Voice: (301) 373-9600
|
||||
* EMail: cups-info@cups.org
|
||||
* WWW: http://www.cups.org
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* ppdFindAttr() - Find the first matching attribute...
|
||||
* ppdFindNextAttr() - Find the next matching attribute...
|
||||
*/
|
||||
|
||||
/*
|
||||
* Include necessary headers...
|
||||
*/
|
||||
|
||||
#include "ppd.h"
|
||||
#include "debug.h"
|
||||
#include "string.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/*
|
||||
* Private function...
|
||||
*/
|
||||
|
||||
extern int _ppd_attr_compare(ppd_attr_t **a, ppd_attr_t **b);
|
||||
|
||||
|
||||
/*
|
||||
* 'ppdFindAttr()' - Find the first matching attribute...
|
||||
*/
|
||||
|
||||
ppd_attr_t * /* O - Attribute or 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 NULL */
|
||||
{
|
||||
ppd_attr_t key, /* Search key */
|
||||
*keyptr, /* Pointer to key */
|
||||
**match; /* Matching attribute */
|
||||
|
||||
|
||||
/*
|
||||
* Range check input...
|
||||
*/
|
||||
|
||||
if (ppd == NULL || name == NULL || ppd->num_attrs == 0)
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
* Do a binary search for a matching attribute...
|
||||
*/
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
strncpy(key.name, name, sizeof(key.name) - 1);
|
||||
if (spec)
|
||||
strncpy(key.spec, spec, sizeof(key.spec) - 1);
|
||||
|
||||
keyptr = &key;
|
||||
|
||||
match = bsearch(&keyptr, ppd->attrs, ppd->num_attrs, sizeof(ppd_attr_t *),
|
||||
(int (*)(const void *, const void *))_ppd_attr_compare);
|
||||
|
||||
if (match == NULL)
|
||||
{
|
||||
/*
|
||||
* No match!
|
||||
*/
|
||||
|
||||
ppd->cur_attr = -1;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (match > ppd->attrs && spec == NULL)
|
||||
{
|
||||
/*
|
||||
* Find the first attribute with the same name...
|
||||
*/
|
||||
|
||||
while (match > ppd->attrs)
|
||||
{
|
||||
if (strcmp(match[-1]->name, name) != 0)
|
||||
break;
|
||||
|
||||
match --;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the current attribute and return its value...
|
||||
*/
|
||||
|
||||
ppd->cur_attr = match - ppd->attrs;
|
||||
|
||||
return (*match);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'ppdFindNextAttr()' - Find the next matching attribute...
|
||||
*/
|
||||
|
||||
ppd_attr_t * /* O - Attribute or 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 NULL */
|
||||
{
|
||||
ppd_attr_t **match; /* Matching attribute */
|
||||
|
||||
|
||||
/*
|
||||
* Range check input...
|
||||
*/
|
||||
|
||||
if (ppd == NULL || name == NULL || ppd->num_attrs == 0 || ppd->cur_attr < 0)
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
* See if there are more attributes to return...
|
||||
*/
|
||||
|
||||
ppd->cur_attr ++;
|
||||
|
||||
if (ppd->cur_attr >= ppd->num_attrs)
|
||||
{
|
||||
/*
|
||||
* Nope...
|
||||
*/
|
||||
|
||||
ppd->cur_attr = -1;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the next attribute to see if it is a match...
|
||||
*/
|
||||
|
||||
match = ppd->attrs + ppd->cur_attr;
|
||||
|
||||
if (strcmp((*match)->name, name) != 0 ||
|
||||
(spec != NULL && strcmp((*match)->spec, spec) != 0))
|
||||
{
|
||||
/*
|
||||
* Nope...
|
||||
*/
|
||||
|
||||
ppd->cur_attr = -1;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the next attribute's value...
|
||||
*/
|
||||
|
||||
return (*match);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id$".
|
||||
*/
|
||||
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* "$Id$"
|
||||
*
|
||||
* Authentication functions for the Common UNIX Printing System (CUPS).
|
||||
*
|
||||
* Copyright 1997-2003 by Easy Software Products.
|
||||
*
|
||||
* These coded instructions, statements, and computer programs are the
|
||||
* property of Easy Software Products and are protected by Federal
|
||||
* copyright law. Distribution and use rights are outlined in the file
|
||||
* "LICENSE.txt" which should have been included with this file. If this
|
||||
* file is missing or damaged please contact Easy Software Products
|
||||
* at:
|
||||
*
|
||||
* Attn: CUPS Licensing Information
|
||||
* Easy Software Products
|
||||
* 44141 Airport View Drive, Suite 204
|
||||
* Hollywood, Maryland 20636-3111 USA
|
||||
*
|
||||
* Voice: (301) 373-9603
|
||||
* EMail: cups-info@cups.org
|
||||
* WWW: http://www.cups.org
|
||||
*
|
||||
* This file is subject to the Apple OS-Developed Software exception.
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* cupsDoAuthentication() - Authenticate a request...
|
||||
* cups_local_auth() - Get the local authorization certificate if
|
||||
* available/applicable...
|
||||
*/
|
||||
|
||||
/*
|
||||
* Include necessary headers...
|
||||
*/
|
||||
|
||||
#include "cups.h"
|
||||
#include "ipp.h"
|
||||
#include "language.h"
|
||||
#include "string.h"
|
||||
#include "debug.h"
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#if defined(WIN32) || defined(__EMX__)
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif /* WIN32 || __EMX__ */
|
||||
|
||||
|
||||
/*
|
||||
* Local functions...
|
||||
*/
|
||||
|
||||
static int cups_local_auth(http_t *http);
|
||||
|
||||
|
||||
/*
|
||||
* 'cupsDoAuthentication()' - Authenticate a request...
|
||||
*/
|
||||
|
||||
int /* O - 0 on success, -1 on error */
|
||||
cupsDoAuthentication(http_t *http, /* I - HTTP connection to server */
|
||||
const char *method,/* I - Request method (GET, POST, PUT) */
|
||||
const char *resource)
|
||||
/* I - Resource path */
|
||||
{
|
||||
const char *password; /* Password string */
|
||||
char prompt[1024], /* Prompt for user */
|
||||
realm[HTTP_MAX_VALUE], /* realm="xyz" string */
|
||||
nonce[HTTP_MAX_VALUE], /* nonce="xyz" string */
|
||||
encode[512]; /* Encoded username:password */
|
||||
|
||||
|
||||
/*
|
||||
* Clear the current authentication string...
|
||||
*/
|
||||
|
||||
http->authstring[0] = '\0';
|
||||
|
||||
/*
|
||||
* See if we can do local authentication...
|
||||
*/
|
||||
|
||||
if (!cups_local_auth(http))
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Nope, see if we should retry the current digest password...
|
||||
*/
|
||||
|
||||
if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Basic", 5) == 0 ||
|
||||
http->digest_tries > 1 || !http->userpass[0])
|
||||
{
|
||||
/*
|
||||
* Nope - get a new password from the user...
|
||||
*/
|
||||
|
||||
snprintf(prompt, sizeof(prompt), "Password for %s on %s? ", cupsUser(),
|
||||
http->hostname);
|
||||
|
||||
http->digest_tries = 0;
|
||||
http->userpass[0] = '\0';
|
||||
|
||||
if ((password = cupsGetPassword(prompt)) == NULL)
|
||||
return (-1);
|
||||
|
||||
if (!password[0])
|
||||
return (-1);
|
||||
|
||||
snprintf(http->userpass, sizeof(http->userpass), "%s:%s", cupsUser(),
|
||||
password);
|
||||
}
|
||||
else
|
||||
http->digest_tries ++;
|
||||
|
||||
/*
|
||||
* Got a password; encode it for the server...
|
||||
*/
|
||||
|
||||
if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Basic", 5) == 0)
|
||||
{
|
||||
/*
|
||||
* Basic authentication...
|
||||
*/
|
||||
|
||||
httpEncode64(encode, http->userpass);
|
||||
snprintf(http->authstring, sizeof(http->authstring), "Basic %s", encode);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Digest authentication...
|
||||
*/
|
||||
|
||||
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, "POST", resource, encode);
|
||||
snprintf(http->authstring, sizeof(http->authstring),
|
||||
"Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", "
|
||||
"response=\"%s\"", cupsUser(), realm, nonce, encode);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'cups_local_auth()' - Get the local authorization certificate if
|
||||
* available/applicable...
|
||||
*/
|
||||
|
||||
static int /* O - 0 if available, -1 if not */
|
||||
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 filename[1024], /* Certificate filename */
|
||||
certificate[33]; /* Certificate string */
|
||||
const char *root; /* Server root directory */
|
||||
|
||||
|
||||
DEBUG_printf(("cups_local_auth(http=%p) hostaddr=%08x, hostname=\"%s\"\n",
|
||||
http, ntohl(http->hostaddr.sin_addr.s_addr), http->hostname));
|
||||
|
||||
/*
|
||||
* See if we are accessing localhost...
|
||||
*/
|
||||
|
||||
if (ntohl(http->hostaddr.sin_addr.s_addr) != 0x7f000001 &&
|
||||
strcasecmp(http->hostname, "localhost") != 0)
|
||||
{
|
||||
DEBUG_puts("cups_local_auth: Not a local connection!");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try opening a certificate file for this PID. If that fails,
|
||||
* try the root certificate...
|
||||
*/
|
||||
|
||||
if ((root = getenv("CUPS_SERVERROOT")) == NULL)
|
||||
root = CUPS_SERVERROOT;
|
||||
|
||||
pid = getpid();
|
||||
snprintf(filename, sizeof(filename), "%s/certs/%d", root, pid);
|
||||
if ((fp = fopen(filename, "r")) == NULL && pid > 0)
|
||||
{
|
||||
DEBUG_printf(("cups_local_auth: Unable to open file %s: %s\n",
|
||||
filename, strerror(errno)));
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/certs/0", root);
|
||||
fp = fopen(filename, "r");
|
||||
}
|
||||
|
||||
if (fp == NULL)
|
||||
{
|
||||
DEBUG_printf(("cups_local_auth: Unable to open file %s: %s\n",
|
||||
filename, strerror(errno)));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the certificate from the file...
|
||||
*/
|
||||
|
||||
fgets(certificate, sizeof(certificate), fp);
|
||||
fclose(fp);
|
||||
|
||||
/*
|
||||
* Set the authorization string and return...
|
||||
*/
|
||||
|
||||
snprintf(http->authstring, sizeof(http->authstring), "Local %s", certificate);
|
||||
|
||||
DEBUG_printf(("cups_local_auth: Returning authstring = \"%s\"\n",
|
||||
http->authstring));
|
||||
|
||||
return (0);
|
||||
#endif /* WIN32 || __EMX__ */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id$".
|
||||
*/
|
||||
@@ -85,6 +85,10 @@ LIB32=link.exe -lib
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\auth.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\dest.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -97,6 +101,10 @@ SOURCE=.\encode.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\getputfile.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\http-addr.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -121,10 +129,6 @@ SOURCE=.\language.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\oemlicense\license.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\mark.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -48,10 +48,10 @@ extern "C" {
|
||||
* Constants...
|
||||
*/
|
||||
|
||||
# define CUPS_VERSION 1.0118
|
||||
# define CUPS_VERSION 1.0120
|
||||
# define CUPS_VERSION_MAJOR 1
|
||||
# define CUPS_VERSION_MINOR 1
|
||||
# define CUPS_VERSION_PATCH 18
|
||||
# define CUPS_VERSION_PATCH 20
|
||||
# define CUPS_DATE_ANY -1
|
||||
|
||||
|
||||
@@ -81,7 +81,8 @@ enum /* Not a typedef'd enum so we can OR */
|
||||
CUPS_PRINTER_VARIABLE = 0x8000, /* Can do variable sizes */
|
||||
CUPS_PRINTER_IMPLICIT = 0x10000, /* Implicit class */
|
||||
CUPS_PRINTER_DEFAULT = 0x20000, /* Default printer on network */
|
||||
CUPS_PRINTER_OPTIONS = 0xfffc /* ~(CLASS | REMOTE | IMPLICIT) */
|
||||
CUPS_PRINTER_FAX = 0x40000, /* Fax queue */
|
||||
CUPS_PRINTER_OPTIONS = 0x6fffc /* ~(CLASS | REMOTE | IMPLICIT) */
|
||||
};
|
||||
|
||||
typedef struct /**** Printer Options ****/
|
||||
@@ -169,6 +170,17 @@ 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);
|
||||
extern http_status_t cupsGetFile(http_t *http, const char *resource,
|
||||
const char *filename);
|
||||
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);
|
||||
extern http_status_t cupsPutFd(http_t *http, const char *resource, int fd);
|
||||
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif /* __cplusplus */
|
||||
|
||||
@@ -668,7 +668,7 @@ cups_get_sdests(ipp_op_t op, /* I - get-printers or get-classes */
|
||||
cups_lang_t *language; /* Default language */
|
||||
const char *name; /* printer-name attribute */
|
||||
char job_sheets[1024]; /* job-sheets option */
|
||||
static const char *pattrs[] = /* Attributes we're interested in */
|
||||
static const char * const pattrs[] = /* Attributes we're interested in */
|
||||
{
|
||||
"printer-name",
|
||||
"job-sheets-default"
|
||||
@@ -703,6 +703,8 @@ cups_get_sdests(ipp_op_t op, /* I - get-printers or get-classes */
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
|
||||
"attributes-natural-language", NULL, language->language);
|
||||
|
||||
cupsLangFree(language);
|
||||
|
||||
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
|
||||
"requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]),
|
||||
NULL, pattrs);
|
||||
|
||||
@@ -196,26 +196,85 @@ ppdEmit(ppd_file_t *ppd, /* I - PPD file record */
|
||||
* Send DSC comments with option...
|
||||
*/
|
||||
|
||||
if (fprintf(fp, "%%%%BeginFeature: *%s %s\n",
|
||||
((ppd_option_t *)choices[i]->option)->keyword,
|
||||
choices[i]->choice) < 0)
|
||||
{
|
||||
free(choices);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if ((strcasecmp(((ppd_option_t *)choices[i]->option)->keyword, "PageSize") == 0 ||
|
||||
strcasecmp(((ppd_option_t *)choices[i]->option)->keyword, "PageRegion") == 0) &&
|
||||
strcasecmp(choices[i]->choice, "Custom") == 0)
|
||||
{
|
||||
/*
|
||||
* Variable size; write out standard size options (this should
|
||||
* eventually be changed to use the parameter positions defined
|
||||
* in the PPD file...)
|
||||
* Variable size; write out standard size options, using the
|
||||
* parameter positions defined in the PPD file...
|
||||
*/
|
||||
|
||||
ppd_attr_t *attr; /* PPD attribute */
|
||||
int pos, /* Position of custom value */
|
||||
values[5], /* Values for custom command */
|
||||
orientation; /* Orientation to use */
|
||||
|
||||
|
||||
fputs("%%BeginFeature: *CustomPageSize True\n", fp);
|
||||
|
||||
size = ppdPageSize(ppd, "Custom");
|
||||
fprintf(fp, "%.0f %.0f 0 0 0\n", size->width, size->length);
|
||||
|
||||
memset(values, 0, sizeof(values));
|
||||
|
||||
if ((attr = ppdFindAttr(ppd, "ParamCustomPageSize", "Width")) != NULL)
|
||||
{
|
||||
pos = atoi(attr->value) - 1;
|
||||
|
||||
if (pos < 0 || pos > 4)
|
||||
pos = 0;
|
||||
}
|
||||
else
|
||||
pos = 0;
|
||||
|
||||
values[pos] = (int)size->width;
|
||||
|
||||
if ((attr = ppdFindAttr(ppd, "ParamCustomPageSize", "Height")) != NULL)
|
||||
{
|
||||
pos = atoi(attr->value) - 1;
|
||||
|
||||
if (pos < 0 || pos > 4)
|
||||
pos = 1;
|
||||
}
|
||||
else
|
||||
pos = 1;
|
||||
|
||||
values[pos] = (int)size->length;
|
||||
|
||||
if (size->width < size->length)
|
||||
orientation = 1;
|
||||
else
|
||||
orientation = 0;
|
||||
|
||||
if ((attr = ppdFindAttr(ppd, "ParamCustomPageSize",
|
||||
"Orientation")) != NULL)
|
||||
{
|
||||
int min_orient, max_orient; /* Minimum and maximum orientations */
|
||||
|
||||
|
||||
if (sscanf(attr->value, "%d%*s%d%d", &pos, &min_orient,
|
||||
&max_orient) != 3)
|
||||
pos = 4;
|
||||
else
|
||||
{
|
||||
pos --;
|
||||
|
||||
if (pos < 0 || pos > 4)
|
||||
pos = 4;
|
||||
|
||||
if (orientation > max_orient)
|
||||
orientation = max_orient;
|
||||
else if (orientation < min_orient)
|
||||
orientation = min_orient;
|
||||
}
|
||||
}
|
||||
else
|
||||
pos = 4;
|
||||
|
||||
values[pos] = orientation;
|
||||
|
||||
fprintf(fp, "%d %d %d %d %d\n", values[0], values[1],
|
||||
values[2], values[3], values[4]);
|
||||
|
||||
if (choices[i]->code == NULL)
|
||||
{
|
||||
@@ -228,6 +287,13 @@ ppdEmit(ppd_file_t *ppd, /* I - PPD file record */
|
||||
fputs(ppd_custom_code, fp);
|
||||
}
|
||||
}
|
||||
else if (fprintf(fp, "%%%%BeginFeature: *%s %s\n",
|
||||
((ppd_option_t *)choices[i]->option)->keyword,
|
||||
choices[i]->choice) < 0)
|
||||
{
|
||||
free(choices);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (choices[i]->code != NULL && choices[i]->code[0] != '\0')
|
||||
{
|
||||
@@ -274,7 +340,8 @@ ppdEmitFd(ppd_file_t *ppd, /* I - PPD file record */
|
||||
ppd_section_t section) /* I - Section to write */
|
||||
{
|
||||
int i, /* Looping var */
|
||||
count; /* Number of choices */
|
||||
count, /* Number of choices */
|
||||
custom_size; /* Non-zero if this option is a custom size */
|
||||
ppd_choice_t **choices; /* Choices */
|
||||
ppd_size_t *size; /* Custom page size */
|
||||
char buf[1024]; /* Output buffer for feature */
|
||||
@@ -311,9 +378,22 @@ ppdEmitFd(ppd_file_t *ppd, /* I - PPD file record */
|
||||
* Send DSC comments with option...
|
||||
*/
|
||||
|
||||
snprintf(buf, sizeof(buf), "%%%%BeginFeature: *%s %s\n",
|
||||
((ppd_option_t *)choices[i]->option)->keyword,
|
||||
choices[i]->choice);
|
||||
if ((strcasecmp(((ppd_option_t *)choices[i]->option)->keyword, "PageSize") == 0 ||
|
||||
strcasecmp(((ppd_option_t *)choices[i]->option)->keyword, "PageRegion") == 0) &&
|
||||
strcasecmp(choices[i]->choice, "Custom") == 0)
|
||||
{
|
||||
custom_size = 1;
|
||||
|
||||
strcpy(buf, "%%BeginFeature: *CustomPageSize True\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
custom_size = 0;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%%%%BeginFeature: *%s %s\n",
|
||||
((ppd_option_t *)choices[i]->option)->keyword,
|
||||
choices[i]->choice);
|
||||
}
|
||||
|
||||
if (write(fd, buf, strlen(buf)) < 1)
|
||||
{
|
||||
@@ -321,19 +401,81 @@ ppdEmitFd(ppd_file_t *ppd, /* I - PPD file record */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if ((strcasecmp(((ppd_option_t *)choices[i]->option)->keyword, "PageSize") == 0 ||
|
||||
strcasecmp(((ppd_option_t *)choices[i]->option)->keyword, "PageRegion") == 0) &&
|
||||
strcasecmp(choices[i]->choice, "Custom") == 0)
|
||||
if (custom_size)
|
||||
{
|
||||
/*
|
||||
* Variable size; write out standard size options (this should
|
||||
* eventually be changed to use the parameter positions defined
|
||||
* in the PPD file...)
|
||||
* Variable size; write out standard size options, using the
|
||||
* parameter positions defined in the PPD file...
|
||||
*/
|
||||
|
||||
ppd_attr_t *attr; /* PPD attribute */
|
||||
int pos, /* Position of custom value */
|
||||
values[5], /* Values for custom command */
|
||||
orientation; /* Orientation to use */
|
||||
|
||||
|
||||
size = ppdPageSize(ppd, "Custom");
|
||||
snprintf(buf, sizeof(buf), "%.0f %.0f 0 0 0\n", size->width,
|
||||
size->length);
|
||||
|
||||
memset(values, 0, sizeof(values));
|
||||
|
||||
if ((attr = ppdFindAttr(ppd, "ParamCustomPageSize", "Width")) != NULL)
|
||||
{
|
||||
pos = atoi(attr->value) - 1;
|
||||
|
||||
if (pos < 0 || pos > 4)
|
||||
pos = 0;
|
||||
}
|
||||
else
|
||||
pos = 0;
|
||||
|
||||
values[pos] = (int)size->width;
|
||||
|
||||
if ((attr = ppdFindAttr(ppd, "ParamCustomPageSize", "Height")) != NULL)
|
||||
{
|
||||
pos = atoi(attr->value) - 1;
|
||||
|
||||
if (pos < 0 || pos > 4)
|
||||
pos = 1;
|
||||
}
|
||||
else
|
||||
pos = 1;
|
||||
|
||||
values[pos] = (int)size->length;
|
||||
|
||||
if (size->width < size->length)
|
||||
orientation = 1;
|
||||
else
|
||||
orientation = 0;
|
||||
|
||||
if ((attr = ppdFindAttr(ppd, "ParamCustomPageSize",
|
||||
"Orientation")) != NULL)
|
||||
{
|
||||
int min_orient, max_orient; /* Minimum and maximum orientations */
|
||||
|
||||
|
||||
if (sscanf(attr->value, "%d%*s%d%d", &pos, &min_orient,
|
||||
&max_orient) != 3)
|
||||
pos = 4;
|
||||
else
|
||||
{
|
||||
pos --;
|
||||
|
||||
if (pos < 0 || pos > 4)
|
||||
pos = 4;
|
||||
|
||||
if (orientation > max_orient)
|
||||
orientation = max_orient;
|
||||
else if (orientation < min_orient)
|
||||
orientation = min_orient;
|
||||
}
|
||||
}
|
||||
else
|
||||
pos = 4;
|
||||
|
||||
values[pos] = orientation;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%d %d %d %d %d\n", values[0], values[1],
|
||||
values[2], values[3], values[4]);
|
||||
|
||||
if (write(fd, buf, strlen(buf)) < 1)
|
||||
{
|
||||
@@ -400,7 +542,8 @@ ppdEmitJCL(ppd_file_t *ppd, /* I - PPD file record */
|
||||
const char *user, /* I - Username */
|
||||
const char *title) /* I - Title */
|
||||
{
|
||||
const char *ptr; /* Pointer into JCL string */
|
||||
char *ptr; /* Pointer into JCL string */
|
||||
char temp[81]; /* Local title string */
|
||||
|
||||
|
||||
/*
|
||||
@@ -419,9 +562,13 @@ ppdEmitJCL(ppd_file_t *ppd, /* I - PPD file record */
|
||||
/*
|
||||
* This printer uses HP PJL commands for output; filter the output
|
||||
* so that we only have a single "@PJL JOB" command in the header...
|
||||
*
|
||||
* To avoid bugs in the PJL implementation of certain vendors' products
|
||||
* (Xerox in particular), we add a dummy "@PJL" command at the beginning
|
||||
* of the PJL commands to initialize PJL processing.
|
||||
*/
|
||||
|
||||
fputs("\033%-12345X", fp);
|
||||
fputs("\033%-12345X@PJL\n", fp);
|
||||
for (ptr = ppd->jcl_begin + 9; *ptr;)
|
||||
if (strncmp(ptr, "@PJL JOB", 8) == 0)
|
||||
{
|
||||
@@ -460,18 +607,29 @@ ppdEmitJCL(ppd_file_t *ppd, /* I - PPD file record */
|
||||
if ((ptr = strrchr(title, '/')) != NULL)
|
||||
title = ptr + 1;
|
||||
|
||||
/*
|
||||
* Replace double quotes with single quotes so that the title
|
||||
* does not cause a PJL syntax error.
|
||||
*/
|
||||
|
||||
strlcpy(temp, title, sizeof(temp));
|
||||
|
||||
for (ptr = temp; *ptr; ptr ++)
|
||||
if (*ptr == '\"')
|
||||
*ptr = '\'';
|
||||
|
||||
/*
|
||||
* Send PJL JOB command before we enter PostScript mode...
|
||||
*/
|
||||
|
||||
fprintf(fp, "@PJL JOB NAME = \"%s\" DISPLAY = \"%d %s %s\"\n", title,
|
||||
job_id, user, title);
|
||||
fprintf(fp, "@PJL JOB NAME = \"%s\" DISPLAY = \"%d %s %s\"\n", temp,
|
||||
job_id, user, temp);
|
||||
}
|
||||
else
|
||||
fputs(ppd->jcl_begin, stdout);
|
||||
fputs(ppd->jcl_begin, fp);
|
||||
|
||||
ppdEmit(ppd, stdout, PPD_ORDER_JCL);
|
||||
fputs(ppd->jcl_ps, stdout);
|
||||
ppdEmit(ppd, fp, PPD_ORDER_JCL);
|
||||
fputs(ppd->jcl_ps, fp);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -485,8 +643,10 @@ static void
|
||||
ppd_handle_media(ppd_file_t *ppd)
|
||||
{
|
||||
ppd_choice_t *manual_feed, /* ManualFeed choice, if any */
|
||||
*input_slot; /* InputSlot choice, if any */
|
||||
*input_slot, /* InputSlot choice, if any */
|
||||
*page; /* PageSize/PageRegion */
|
||||
ppd_size_t *size; /* Current media size */
|
||||
ppd_attr_t *rpr; /* RequiresPageRegion value */
|
||||
|
||||
|
||||
/*
|
||||
@@ -502,6 +662,14 @@ ppd_handle_media(ppd_file_t *ppd)
|
||||
manual_feed = ppdFindMarkedChoice(ppd, "ManualFeed");
|
||||
input_slot = ppdFindMarkedChoice(ppd, "InputSlot");
|
||||
|
||||
if (input_slot != NULL)
|
||||
rpr = ppdFindAttr(ppd, "RequiresPageRegion", input_slot->choice);
|
||||
else
|
||||
rpr = NULL;
|
||||
|
||||
if (!rpr)
|
||||
rpr = ppdFindAttr(ppd, "RequiresPageRegion", "All");
|
||||
|
||||
if (strcasecmp(size->name, "Custom") == 0 ||
|
||||
(manual_feed == NULL && input_slot == NULL) ||
|
||||
(manual_feed != NULL && strcasecmp(manual_feed->choice, "False") == 0) ||
|
||||
@@ -522,6 +690,22 @@ ppd_handle_media(ppd_file_t *ppd)
|
||||
*/
|
||||
|
||||
ppdMarkOption(ppd, "PageRegion", size->name);
|
||||
|
||||
if ((rpr && rpr->value && !strcmp(rpr->value, "False")) ||
|
||||
(!rpr && !ppd->num_filters))
|
||||
{
|
||||
/*
|
||||
* Either the PPD file specifies no PageRegion code or the PPD file
|
||||
* not for a CUPS raster driver and thus defaults to no PageRegion
|
||||
* code... Unmark the PageRegion choice so that we don't output the
|
||||
* code...
|
||||
*/
|
||||
|
||||
page = ppdFindMarkedChoice(ppd, "PageRegion");
|
||||
|
||||
if (page)
|
||||
page->marked = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ typedef struct
|
||||
ipp_tag_t value_tag;
|
||||
} ipp_option_t;
|
||||
|
||||
static ipp_option_t ipp_options[] =
|
||||
static const ipp_option_t ipp_options[] =
|
||||
{
|
||||
{ "blackplot", IPP_TAG_BOOLEAN },
|
||||
{ "brightness", IPP_TAG_INTEGER },
|
||||
@@ -59,8 +59,12 @@ static ipp_option_t ipp_options[] =
|
||||
{ "fitplot", IPP_TAG_BOOLEAN },
|
||||
{ "gamma", IPP_TAG_INTEGER },
|
||||
{ "hue", IPP_TAG_INTEGER },
|
||||
{ "job-k-limit", IPP_TAG_INTEGER },
|
||||
{ "job-page-limit", IPP_TAG_INTEGER },
|
||||
{ "job-priority", IPP_TAG_INTEGER },
|
||||
{ "job-quota-period", IPP_TAG_INTEGER },
|
||||
{ "landscape", IPP_TAG_BOOLEAN },
|
||||
{ "media", IPP_TAG_KEYWORD },
|
||||
{ "mirror", IPP_TAG_BOOLEAN },
|
||||
{ "natural-scaling", IPP_TAG_INTEGER },
|
||||
{ "number-up", IPP_TAG_INTEGER },
|
||||
@@ -77,6 +81,7 @@ static ipp_option_t ipp_options[] =
|
||||
{ "print-quality", IPP_TAG_ENUM },
|
||||
{ "saturation", IPP_TAG_INTEGER },
|
||||
{ "scaling", IPP_TAG_INTEGER },
|
||||
{ "sides", IPP_TAG_KEYWORD },
|
||||
{ "wrap", IPP_TAG_BOOLEAN }
|
||||
};
|
||||
|
||||
@@ -255,7 +260,7 @@ cupsEncodeOptions(ipp_t *ipp, /* I - Request to add to */
|
||||
* Scan the value string for values...
|
||||
*/
|
||||
|
||||
for (j = 0; *val != '\0' || j == 0; val = sep, j ++)
|
||||
for (j = 0; j < count; val = sep, j ++)
|
||||
{
|
||||
/*
|
||||
* Find the end of this value and mark it if needed...
|
||||
@@ -285,7 +290,9 @@ cupsEncodeOptions(ipp_t *ipp, /* I - Request to add to */
|
||||
break;
|
||||
|
||||
case IPP_TAG_BOOLEAN :
|
||||
if (strcasecmp(val, "true") == 0)
|
||||
if (!strcasecmp(val, "true") ||
|
||||
!strcasecmp(val, "on") ||
|
||||
!strcasecmp(val, "yes"))
|
||||
{
|
||||
/*
|
||||
* Boolean value - true...
|
||||
|
||||
@@ -0,0 +1,435 @@
|
||||
/*
|
||||
* "$Id$"
|
||||
*
|
||||
* Get/put file functions for the Common UNIX Printing System (CUPS).
|
||||
*
|
||||
* Copyright 1997-2003 by Easy Software Products.
|
||||
*
|
||||
* These coded instructions, statements, and computer programs are the
|
||||
* property of Easy Software Products and are protected by Federal
|
||||
* copyright law. Distribution and use rights are outlined in the file
|
||||
* "LICENSE.txt" which should have been included with this file. If this
|
||||
* file is missing or damaged please contact Easy Software Products
|
||||
* at:
|
||||
*
|
||||
* Attn: CUPS Licensing Information
|
||||
* Easy Software Products
|
||||
* 44141 Airport View Drive, Suite 204
|
||||
* Hollywood, Maryland 20636-3111 USA
|
||||
*
|
||||
* Voice: (301) 373-9603
|
||||
* EMail: cups-info@cups.org
|
||||
* WWW: http://www.cups.org
|
||||
*
|
||||
* 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.h"
|
||||
#include "ipp.h"
|
||||
#include "language.h"
|
||||
#include "string.h"
|
||||
#include "debug.h"
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.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.
|
||||
*/
|
||||
|
||||
http_status_t /* O - Status */
|
||||
cupsGetFd(http_t *http, /* I - HTTP connection to server */
|
||||
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 */
|
||||
|
||||
|
||||
/*
|
||||
* Range check input...
|
||||
*/
|
||||
|
||||
if (!http || !resource || fd < 0)
|
||||
{
|
||||
if (http)
|
||||
http->error = EINVAL;
|
||||
|
||||
return (HTTP_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Then send GET requests to the HTTP server...
|
||||
*/
|
||||
|
||||
do
|
||||
{
|
||||
httpClearFields(http);
|
||||
httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);
|
||||
|
||||
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))
|
||||
break;
|
||||
|
||||
httpReconnect(http);
|
||||
|
||||
continue;
|
||||
}
|
||||
else if (status == HTTP_ERROR)
|
||||
{
|
||||
#ifdef WIN32
|
||||
if (http->error != WSAENETDOWN && http->error != WSAENETUNREACH)
|
||||
#else
|
||||
if (http->error != ENETDOWN && http->error != ENETUNREACH)
|
||||
#endif /* WIN32 */
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
#ifdef HAVE_LIBSSL
|
||||
else if (status == HTTP_UPGRADE_REQUIRED)
|
||||
{
|
||||
/*
|
||||
* Flush any error message...
|
||||
*/
|
||||
|
||||
httpFlush(http);
|
||||
|
||||
/*
|
||||
* Upgrade with encryption...
|
||||
*/
|
||||
|
||||
httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
|
||||
|
||||
/*
|
||||
* Try again, this time with encryption enabled...
|
||||
*/
|
||||
|
||||
continue;
|
||||
}
|
||||
#endif /* HAVE_LIBSSL */
|
||||
}
|
||||
while (status == HTTP_UNAUTHORIZED || status == HTTP_UPGRADE_REQUIRED ||
|
||||
status == HTTP_ERROR);
|
||||
|
||||
/*
|
||||
* See if we actually got the file or an error...
|
||||
*/
|
||||
|
||||
if (status == HTTP_OK)
|
||||
{
|
||||
/*
|
||||
* Yes, copy the file...
|
||||
*/
|
||||
|
||||
while ((bytes = httpRead(http, buffer, sizeof(buffer))) > 0)
|
||||
write(fd, buffer, bytes);
|
||||
}
|
||||
else
|
||||
httpFlush(http);
|
||||
|
||||
/*
|
||||
* Return the request status...
|
||||
*/
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'cupsGetFile()' - Get a file from the server.
|
||||
*/
|
||||
|
||||
http_status_t /* O - Status */
|
||||
cupsGetFile(http_t *http, /* I - HTTP connection to server */
|
||||
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.
|
||||
*/
|
||||
|
||||
http_status_t /* O - Status */
|
||||
cupsPutFd(http_t *http, /* I - HTTP connection to server */
|
||||
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 */
|
||||
|
||||
|
||||
/*
|
||||
* Range check input...
|
||||
*/
|
||||
|
||||
if (!http || !resource || fd < 0)
|
||||
{
|
||||
if (http)
|
||||
http->error = EINVAL;
|
||||
|
||||
return (HTTP_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Then send PUT requests to the HTTP server...
|
||||
*/
|
||||
|
||||
do
|
||||
{
|
||||
httpClearFields(http);
|
||||
httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);
|
||||
httpSetField(http, HTTP_FIELD_TRANSFER_ENCODING, "chunked");
|
||||
|
||||
if (httpPut(http, resource))
|
||||
{
|
||||
if (httpReconnect(http))
|
||||
{
|
||||
status = HTTP_ERROR;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = HTTP_UNAUTHORIZED;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the file...
|
||||
*/
|
||||
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
|
||||
status = HTTP_CONTINUE;
|
||||
|
||||
while ((bytes = read(fd, buffer, sizeof(buffer))) > 0)
|
||||
if (httpCheck(http))
|
||||
{
|
||||
if ((status = httpUpdate(http)) != HTTP_CONTINUE)
|
||||
break;
|
||||
}
|
||||
else
|
||||
httpWrite(http, buffer, bytes);
|
||||
|
||||
if (status == HTTP_CONTINUE)
|
||||
{
|
||||
httpWrite(http, buffer, 0);
|
||||
|
||||
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, "PUT", resource))
|
||||
break;
|
||||
|
||||
httpReconnect(http);
|
||||
|
||||
continue;
|
||||
}
|
||||
else if (status == HTTP_ERROR)
|
||||
{
|
||||
#ifdef WIN32
|
||||
if (http->error != WSAENETDOWN && http->error != WSAENETUNREACH)
|
||||
#else
|
||||
if (http->error != ENETDOWN && http->error != ENETUNREACH)
|
||||
#endif /* WIN32 */
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
#ifdef HAVE_LIBSSL
|
||||
else if (status == HTTP_UPGRADE_REQUIRED)
|
||||
{
|
||||
/* Flush any error message... */
|
||||
httpFlush(http);
|
||||
|
||||
/* Upgrade with encryption... */
|
||||
httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
|
||||
|
||||
/* Try again, this time with encryption enabled... */
|
||||
continue;
|
||||
}
|
||||
#endif /* HAVE_LIBSSL */
|
||||
}
|
||||
while (status == HTTP_UNAUTHORIZED || status == HTTP_UPGRADE_REQUIRED ||
|
||||
status == HTTP_ERROR);
|
||||
|
||||
/*
|
||||
* See if we actually put the file or an error...
|
||||
*/
|
||||
|
||||
if (status != HTTP_CREATED)
|
||||
httpFlush(http);
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'cupsPutFile()' - Put a file on the server.
|
||||
*/
|
||||
|
||||
http_status_t /* O - Status */
|
||||
cupsPutFile(http_t *http, /* I - HTTP connection to server */
|
||||
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$".
|
||||
*/
|
||||
@@ -55,16 +55,17 @@ httpGetHostByName(const char *name) /* I - Hostname or IP address */
|
||||
static char *packed_ptr[2]; /* Pointer to packed address */
|
||||
static struct hostent host_ip; /* Host entry for IP address */
|
||||
|
||||
|
||||
#if defined(__APPLE__)
|
||||
/* OS X hack to avoid it's ocassional long delay in lookupd */
|
||||
static char sLoopback[] = "127.0.0.1";
|
||||
static const char sLoopback[] = "127.0.0.1";
|
||||
if (strcmp(name, "localhost") == 0)
|
||||
name = sLoopback;
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
/*
|
||||
* This function is needed because some operating systems have a
|
||||
* buggy implementation of httpGetHostByName() that does not support
|
||||
* 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,
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* "$Id$"
|
||||
*
|
||||
* Private HTTP definitions for the Common UNIX Printing System (CUPS).
|
||||
*
|
||||
* Copyright 1997-2003 by Easy Software Products, all rights reserved.
|
||||
*
|
||||
* These coded instructions, statements, and computer programs are the
|
||||
* property of Easy Software Products and are protected by Federal
|
||||
* copyright law. Distribution and use rights are outlined in the file
|
||||
* "LICENSE.txt" which should have been included with this file. If this
|
||||
* file is missing or damaged please contact Easy Software Products
|
||||
* at:
|
||||
*
|
||||
* Attn: CUPS Licensing Information
|
||||
* Easy Software Products
|
||||
* 44141 Airport View Drive, Suite 204
|
||||
* Hollywood, Maryland 20636-3111 USA
|
||||
*
|
||||
* Voice: (301) 373-9603
|
||||
* EMail: cups-info@cups.org
|
||||
* WWW: http://www.cups.org
|
||||
*
|
||||
* 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"
|
||||
|
||||
# ifdef __sun
|
||||
/*
|
||||
* Define FD_SETSIZE to CUPS_MAX_FDS on Solaris to get the correct version of
|
||||
* select() for large numbers of file descriptors.
|
||||
*/
|
||||
|
||||
# define FD_SETSIZE CUPS_MAX_FDS
|
||||
# include <sys/select.h>
|
||||
# endif /* __sun */
|
||||
|
||||
# include "http.h"
|
||||
|
||||
# if defined HAVE_LIBSSL
|
||||
/*
|
||||
* The OpenSSL library provides its own SSL/TLS context structure for its
|
||||
* IO and protocol management...
|
||||
*/
|
||||
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/rand.h>
|
||||
# include <openssl/ssl.h>
|
||||
|
||||
typedef SSL http_tls_t;
|
||||
|
||||
# elif defined HAVE_GNUTLS
|
||||
/*
|
||||
* The GNU TLS library is more of a "bare metal" SSL/TLS library...
|
||||
*/
|
||||
# include <gnutls/gnutls.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gnutls_session session; /* GNU TLS session object */
|
||||
void *credentials; /* GNU TLS credentials object */
|
||||
} http_tls_t;
|
||||
|
||||
# elif defined(HAVE_CDSASSL)
|
||||
/*
|
||||
* Darwin's Security framework provides its own SSL/TLS context structure
|
||||
* for its IO and protocol management...
|
||||
*/
|
||||
|
||||
# include <Security/SecureTransport.h>
|
||||
|
||||
typedef SSLConnectionRef http_tls_t;
|
||||
|
||||
# endif /* HAVE_LIBSSL */
|
||||
|
||||
/*
|
||||
* 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)
|
||||
/*
|
||||
* AIX doesn't provide a prototype but does provide the function...
|
||||
*/
|
||||
extern const char *hstrerror(int error);
|
||||
# endif /* !HAVE_HSTRERROR */
|
||||
|
||||
#endif /* !_CUPS_HTTP_PRIVATE_H_ */
|
||||
|
||||
/*
|
||||
* End of "$Id$".
|
||||
*/
|
||||
@@ -25,9 +25,10 @@
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* httpSeparate() - Separate a Universal Resource Identifier into its
|
||||
* components.
|
||||
* httpStatus() - Return a short string describing a HTTP status code.
|
||||
* httpSeparate() - Separate a Universal Resource Identifier into its
|
||||
* components.
|
||||
* httpStatus() - Return a short string describing a HTTP status code.
|
||||
* cups_hstrerror() - hstrerror() emulation function for Solaris and others...
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -162,8 +163,7 @@ httpSeparate(const char *uri, /* I - Universal Resource Identifier */
|
||||
* Grab the username, if any...
|
||||
*/
|
||||
|
||||
while (*uri == '/')
|
||||
uri ++;
|
||||
uri += 2;
|
||||
|
||||
if ((slash = strchr(uri, '/')) == NULL)
|
||||
slash = uri + strlen(uri);
|
||||
@@ -226,6 +226,8 @@ httpSeparate(const char *uri, /* I - Universal Resource Identifier */
|
||||
*port = 443;
|
||||
else if (strcasecmp(method, "ipp") == 0)
|
||||
*port = ippPort();
|
||||
else if (strcasecmp(method, "lpd") == 0)
|
||||
*port = 515;
|
||||
else if (strcasecmp(method, "socket") == 0) /* Not registered yet... */
|
||||
*port = 9100;
|
||||
else
|
||||
@@ -312,6 +314,32 @@ httpStatus(http_status_t status) /* I - HTTP status code */
|
||||
}
|
||||
|
||||
|
||||
#ifndef HAVE_HSTRERROR
|
||||
/*
|
||||
* 'cups_hstrerror()' - hstrerror() emulation function for Solaris and others...
|
||||
*/
|
||||
|
||||
const char * /* O - Error string */
|
||||
cups_hstrerror(int error) /* I - Error number */
|
||||
{
|
||||
static const char * const errors[] = /* Error strings */
|
||||
{
|
||||
"OK",
|
||||
"Host not found.",
|
||||
"Try again.",
|
||||
"Unrecoverable lookup error.",
|
||||
"No data associated with name."
|
||||
};
|
||||
|
||||
|
||||
if (error < 0 || error > 4)
|
||||
return ("Unknown hostname lookup error.");
|
||||
else
|
||||
return (errors[error]);
|
||||
}
|
||||
#endif /* !HAVE_HSTRERROR */
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id$".
|
||||
*/
|
||||
|
||||
@@ -281,6 +281,16 @@ typedef struct
|
||||
int nonce_count; /* Nonce count */
|
||||
void *tls; /* TLS state information */
|
||||
http_encryption_t encryption; /* Encryption requirements */
|
||||
/**** New in CUPS 1.1.19 ****/
|
||||
fd_set *input_set; /* select() set for httpWait() */
|
||||
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 */
|
||||
userpass[HTTP_MAX_VALUE];
|
||||
/* Username:password string */
|
||||
int digest_tries; /* Number of tries for digest auth */
|
||||
} http_t;
|
||||
|
||||
|
||||
@@ -338,6 +348,12 @@ extern char *httpMD5Final(const char *, const char *, const char *,
|
||||
char [33]);
|
||||
extern char *httpMD5String(const md5_byte_t *, char [33]);
|
||||
|
||||
/**** New in CUPS 1.1.19 ****/
|
||||
extern void httpClearCookie(http_t *http);
|
||||
#define httpGetCookie(http) ((http)->cookie)
|
||||
extern void httpSetCookie(http_t *http, const char *cookie);
|
||||
extern int httpWait(http_t *http, int msec);
|
||||
|
||||
|
||||
/*
|
||||
* C++ magic...
|
||||
|
||||
@@ -61,8 +61,8 @@ const char * /* O - Text string */
|
||||
ippErrorString(ipp_status_t error) /* I - Error status */
|
||||
{
|
||||
static char unknown[255]; /* Unknown error statuses */
|
||||
static const char *status_oks[] = /* "OK" status codes */
|
||||
{
|
||||
static const char * const status_oks[] =
|
||||
{ /* "OK" status codes */
|
||||
"successful-ok",
|
||||
"successful-ok-ignored-or-substituted-attributes",
|
||||
"successful-ok-conflicting-attributes",
|
||||
@@ -71,7 +71,7 @@ ippErrorString(ipp_status_t error) /* I - Error status */
|
||||
"successful-ok-too-many-events",
|
||||
"successful-ok-but-cancel-subscription"
|
||||
},
|
||||
*status_400s[] = /* Client errors */
|
||||
* const status_400s[] = /* Client errors */
|
||||
{
|
||||
"client-error-bad-request",
|
||||
"client-error-forbidden",
|
||||
@@ -98,7 +98,7 @@ ippErrorString(ipp_status_t error) /* I - Error status */
|
||||
"client-error-ignored-all-notifications",
|
||||
"client-error-print-support-file-not-found"
|
||||
},
|
||||
*status_500s[] = /* Server errors */
|
||||
* const status_500s[] = /* Server errors */
|
||||
{
|
||||
"server-error-internal-error",
|
||||
"server-error-operation-not-supported",
|
||||
|
||||
@@ -51,9 +51,11 @@ extern "C" {
|
||||
# define IPP_VERSION "\001\001"
|
||||
|
||||
/*
|
||||
* IPP registered port number... This is the default value - applications
|
||||
* should use the ippPort() function so that you can customize things in
|
||||
* /etc/services if needed!
|
||||
* 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
|
||||
@@ -305,6 +307,10 @@ typedef enum /**** IPP status codes... ****/
|
||||
|
||||
typedef unsigned char ipp_uchar_t;/**** Unsigned 8-bit integer/character ****/
|
||||
|
||||
/**** New in CUPS 1.1.19 ****/
|
||||
typedef int (*ipp_iocb_t)(void *, ipp_uchar_t *, int);
|
||||
/**** IPP IO Callback Function ****/
|
||||
|
||||
typedef union /**** Request Header ****/
|
||||
{
|
||||
struct /* Any Header */
|
||||
@@ -327,8 +333,18 @@ typedef union /**** Request Header ****/
|
||||
ipp_status_t status_code; /* Status code */
|
||||
int request_id; /* Request ID */
|
||||
} status;
|
||||
|
||||
/**** New in CUPS 1.1.19 ****/
|
||||
struct /* Event Header */
|
||||
{
|
||||
ipp_uchar_t version[2]; /* Protocol version number */
|
||||
int status_code; /* Status code */
|
||||
int request_id; /* Request ID */
|
||||
} event;
|
||||
} ipp_request_t;
|
||||
|
||||
/**** New in CUPS 1.1.19 ****/
|
||||
typedef struct ipp_str ipp_t;
|
||||
|
||||
typedef union /**** Attribute Value ****/
|
||||
{
|
||||
@@ -362,6 +378,9 @@ typedef union /**** Attribute Value ****/
|
||||
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 */
|
||||
} ipp_value_t;
|
||||
|
||||
typedef struct ipp_attribute_s /**** Attribute ****/
|
||||
@@ -374,7 +393,7 @@ typedef struct ipp_attribute_s /**** Attribute ****/
|
||||
ipp_value_t values[1]; /* Values */
|
||||
} ipp_attribute_t;
|
||||
|
||||
typedef struct /**** Request State ****/
|
||||
struct ipp_str /**** IPP Request/Response/Notification ****/
|
||||
{
|
||||
ipp_state_t state; /* State of request */
|
||||
ipp_request_t request; /* Request header */
|
||||
@@ -382,7 +401,7 @@ typedef struct /**** Request State ****/
|
||||
*last, /* Last attribute in list */
|
||||
*current; /* Current attribute (for read/write) */
|
||||
ipp_tag_t curtag; /* Current attribute group tag */
|
||||
} ipp_t;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
@@ -400,7 +419,7 @@ extern ipp_attribute_t *ippAddResolution(ipp_t *ipp, ipp_tag_t group, const char
|
||||
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 type, const char *name, const char *charset, const char *value);
|
||||
extern ipp_attribute_t *ippAddStrings(ipp_t *ipp, ipp_tag_t group, ipp_tag_t type, const char *name, int num_values, const char *charset, const char **values);
|
||||
extern ipp_attribute_t *ippAddStrings(ipp_t *ipp, ipp_tag_t group, ipp_tag_t type, const char *name, int num_values, const char *charset, 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);
|
||||
@@ -416,6 +435,20 @@ 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);
|
||||
extern ipp_attribute_t *ippAddCollections(ipp_t *ipp, ipp_tag_t group, const char *name, int num_values, const ipp_t **values);
|
||||
extern void ippDeleteAttribute(ipp_t *ipp, ipp_attribute_t *attr);
|
||||
extern ipp_state_t ippReadFile(int fd, ipp_t *ipp);
|
||||
extern ipp_state_t ippReadIO(void *src, ipp_iocb_t cb, int blocking, ipp_t *parent, ipp_t *ipp);
|
||||
extern ipp_state_t ippWriteFile(int fd, ipp_t *ipp);
|
||||
extern ipp_state_t ippWriteIO(void *dst, ipp_iocb_t cb, int blocking, ipp_t *parent, ipp_t *ipp);
|
||||
|
||||
|
||||
/*
|
||||
* "Private" functions used internally by CUPS...
|
||||
*/
|
||||
|
||||
extern ipp_attribute_t *_ipp_add_attr(ipp_t *, int);
|
||||
extern void _ipp_free_attr(ipp_attribute_t *);
|
||||
|
||||
|
||||
@@ -25,11 +25,15 @@
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* cupsLangEncoding() - Return the character encoding (us-ascii, etc.)
|
||||
* for the given language.
|
||||
* cupsLangFlush() - Flush all language data out of the cache.
|
||||
* cupsLangFree() - Free language data.
|
||||
* cupsLangGet() - Get a language.
|
||||
* cupsLangEncoding() - Return the character encoding (us-ascii, etc.)
|
||||
* for the given language.
|
||||
* cupsLangFlush() - Flush all language data out of the cache.
|
||||
* cupsLangFree() - Free language data.
|
||||
* cupsLangGet() - Get a language.
|
||||
* _cupsRestoreLocale() - Restore the original locale...
|
||||
* _cupsSaveLocale() - Set the locale and save a copy of the old locale...
|
||||
* appleLangDefault() - Get the default locale string.
|
||||
* cups_cache_lookup() - Lookup a language in the cache...
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -39,18 +43,39 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#ifdef WIN32
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif /* WIN32 */
|
||||
#include "string.h"
|
||||
#include "language.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
/*
|
||||
* Local functions...
|
||||
*/
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <CoreFoundation/CoreFoundation.h>
|
||||
static const char *appleLangDefault(void);
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
static cups_lang_t *cups_cache_lookup(const char *name,
|
||||
cups_encoding_t encoding);
|
||||
|
||||
|
||||
/*
|
||||
* Local globals...
|
||||
*/
|
||||
|
||||
static cups_lang_t *lang_cache = NULL; /* Language string cache */
|
||||
static char *lang_blank = ""; /* Blank constant string */
|
||||
static char *lang_encodings[] = /* Encoding strings */
|
||||
{
|
||||
static cups_lang_t *lang_cache = NULL;
|
||||
/* Language string cache */
|
||||
static const char lang_blank[] = "";
|
||||
/* Blank constant string */
|
||||
static const char * const lang_encodings[] =
|
||||
{ /* Encoding strings */
|
||||
"us-ascii",
|
||||
"iso-8859-1",
|
||||
"iso-8859-2",
|
||||
@@ -79,8 +104,8 @@ static char *lang_encodings[] = /* Encoding strings */
|
||||
"koi8-r",
|
||||
"koi8-u"
|
||||
};
|
||||
static char *lang_default[] = /* Default POSIX locale */
|
||||
{
|
||||
static const char * const lang_default[] =
|
||||
{ /* Default POSIX locale */
|
||||
#include "cups_C.h"
|
||||
NULL
|
||||
};
|
||||
@@ -95,9 +120,9 @@ char * /* O - Character encoding */
|
||||
cupsLangEncoding(cups_lang_t *lang) /* I - Language data */
|
||||
{
|
||||
if (lang == NULL)
|
||||
return (lang_encodings[0]);
|
||||
return ((char*)lang_encodings[0]);
|
||||
else
|
||||
return (lang_encodings[lang->encoding]);
|
||||
return ((char*)lang_encodings[lang->encoding]);
|
||||
}
|
||||
|
||||
|
||||
@@ -108,20 +133,34 @@ cupsLangEncoding(cups_lang_t *lang) /* I - Language data */
|
||||
void
|
||||
cupsLangFlush(void)
|
||||
{
|
||||
int i; /* Looping var */
|
||||
cups_lang_t *lang, /* Current language */
|
||||
*next; /* Next language */
|
||||
int i; /* Looping var */
|
||||
cups_lang_t *lang, /* Current language */
|
||||
*next; /* Next language */
|
||||
|
||||
|
||||
/*
|
||||
* Free all languages in the cache...
|
||||
*/
|
||||
|
||||
for (lang = lang_cache; lang != NULL; lang = next)
|
||||
{
|
||||
/*
|
||||
* Free all messages...
|
||||
*/
|
||||
|
||||
for (i = 0; i < CUPS_MSG_MAX; i ++)
|
||||
if (lang->messages[i] != NULL && lang->messages[i] != lang_blank)
|
||||
free(lang->messages[i]);
|
||||
|
||||
/*
|
||||
* Then free the language structure itself...
|
||||
*/
|
||||
|
||||
next = lang->next;
|
||||
free(lang);
|
||||
}
|
||||
|
||||
lang_cache = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -143,136 +182,250 @@ cupsLangFree(cups_lang_t *lang) /* I - Language to free */
|
||||
* 'cupsLangGet()' - Get a language.
|
||||
*/
|
||||
|
||||
cups_lang_t * /* O - Language data */
|
||||
cupsLangGet(const char *language) /* I - Language or locale */
|
||||
cups_lang_t * /* O - Language data */
|
||||
cupsLangGet(const char *language) /* I - Language or locale */
|
||||
{
|
||||
int i, count; /* Looping vars */
|
||||
char langname[32], /* Requested language name */
|
||||
*langptr, /* Pointer into language name */
|
||||
real[32], /* Real language name */
|
||||
*realptr, /* Pointer into real language name */
|
||||
filename[1024], /* Filename for language locale file */
|
||||
*localedir; /* Directory for locale files */
|
||||
FILE *fp; /* Language locale file pointer */
|
||||
char line[1024]; /* Line from file */
|
||||
cups_msg_t msg; /* Message number */
|
||||
char *text; /* Message text */
|
||||
cups_lang_t *lang; /* Current language... */
|
||||
int i, count; /* Looping vars */
|
||||
char langname[16], /* Requested language name */
|
||||
country[16], /* Country code */
|
||||
charset[16], /* Character set */
|
||||
*ptr, /* Pointer into language/ */
|
||||
real[48], /* Real language name */
|
||||
filename[1024], /* Filename for language locale file */
|
||||
*localedir; /* Directory for locale files */
|
||||
cups_encoding_t encoding; /* Encoding to use */
|
||||
FILE *fp; /* Language locale file pointer */
|
||||
char line[1024]; /* Line from file */
|
||||
cups_msg_t msg; /* Message number */
|
||||
char *text; /* Message text */
|
||||
cups_lang_t *lang; /* Current language... */
|
||||
char *oldlocale; /* Old locale name */
|
||||
static const char * const locale_encodings[] =
|
||||
{ /* Locale charset names */
|
||||
"ASCII",
|
||||
"ISO8859-1",
|
||||
"ISO8859-2",
|
||||
"ISO8859-3",
|
||||
"ISO8859-4",
|
||||
"ISO8859-5",
|
||||
"ISO8859-6",
|
||||
"ISO8859-7",
|
||||
"ISO8859-8",
|
||||
"ISO8859-9",
|
||||
"ISO8859-10",
|
||||
"UTF-8",
|
||||
"ISO8859-13",
|
||||
"ISO8859-14",
|
||||
"ISO8859-15",
|
||||
"CP874",
|
||||
"CP1250",
|
||||
"CP1251",
|
||||
"CP1252",
|
||||
"CP1253",
|
||||
"CP1254",
|
||||
"CP1255",
|
||||
"CP1256",
|
||||
"CP1257",
|
||||
"CP1258",
|
||||
"KOI8R",
|
||||
"KOI8U"
|
||||
};
|
||||
|
||||
|
||||
#ifdef __APPLE__
|
||||
/*
|
||||
* Convert the language string passed in to a locale string. "C" is the
|
||||
* standard POSIX locale and is copied unchanged. Otherwise the
|
||||
* language string is converted from ll-cc (language-country) to ll_cc
|
||||
* to match the file naming convention used by all POSIX-compliant
|
||||
* operating systems.
|
||||
* Apple's setlocale doesn't give us the user's localization
|
||||
* preference so we have to look it up this way...
|
||||
*/
|
||||
|
||||
if (language == NULL || language[0] == '\0' ||
|
||||
if (language == NULL)
|
||||
language = appleLangDefault();
|
||||
#elif defined(LC_MESSAGES)
|
||||
if (language == NULL)
|
||||
{
|
||||
/*
|
||||
* First see if the locale has been set; if it is still "C" or
|
||||
* "POSIX", set the locale to the default...
|
||||
*/
|
||||
|
||||
language = setlocale(LC_MESSAGES, NULL);
|
||||
|
||||
if (!strcmp(language, "C") || !strcmp(language, "POSIX"))
|
||||
language = setlocale(LC_MESSAGES, "");
|
||||
}
|
||||
#else
|
||||
if (language == NULL)
|
||||
{
|
||||
/*
|
||||
* First see if the locale has been set; if it is still "C" or
|
||||
* "POSIX", set the locale to the default...
|
||||
*/
|
||||
|
||||
language = setlocale(LC_ALL, NULL);
|
||||
|
||||
if (!strcmp(language, "C") || !strcmp(language, "POSIX"))
|
||||
language = setlocale(LC_ALL, "");
|
||||
}
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
/*
|
||||
* Set the locale back to POSIX while we do string ops, since
|
||||
* apparently some buggy C libraries break ctype() for non-I18N
|
||||
* chars...
|
||||
*/
|
||||
|
||||
#if defined(__APPLE__)
|
||||
/* The ctype bug isn't in Apple's libc */
|
||||
#elif !defined(LC_CTYPE)
|
||||
oldlocale = _cupsSaveLocale(LC_ALL, "C");
|
||||
#else
|
||||
oldlocale = _cupsSaveLocale(LC_CTYPE, "C");
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
/*
|
||||
* Parse the language string passed in to a locale string. "C" is the
|
||||
* standard POSIX locale and is copied unchanged. Otherwise the
|
||||
* language string is converted from ll-cc[.charset] (language-country)
|
||||
* to ll_CC[.CHARSET] to match the file naming convention used by all
|
||||
* POSIX-compliant operating systems. Invalid language names are mapped
|
||||
* to the POSIX locale.
|
||||
*/
|
||||
|
||||
country[0] = '\0';
|
||||
charset[0] = '\0';
|
||||
|
||||
if (language == NULL || !language[0] ||
|
||||
strcmp(language, "POSIX") == 0)
|
||||
strcpy(langname, "C");
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Copy the locale string over safely...
|
||||
* Copy the parts of the locale string over safely...
|
||||
*/
|
||||
|
||||
strlcpy(langname, language, sizeof(langname));
|
||||
}
|
||||
for (ptr = langname; *language; language ++)
|
||||
if (*language == '_' || *language == '-' || *language == '.')
|
||||
break;
|
||||
else if (ptr < (langname + sizeof(langname) - 1))
|
||||
*ptr++ = tolower(*language);
|
||||
|
||||
*ptr = '\0';
|
||||
|
||||
if (*language == '_' || *language == '-')
|
||||
{
|
||||
/*
|
||||
* Copy the country code...
|
||||
*/
|
||||
|
||||
for (language ++, ptr = country; *language; language ++)
|
||||
if (*language == '.')
|
||||
break;
|
||||
else if (ptr < (country + sizeof(country) - 1))
|
||||
*ptr++ = toupper(*language);
|
||||
|
||||
*ptr = '\0';
|
||||
}
|
||||
|
||||
if (*language == '.')
|
||||
{
|
||||
/*
|
||||
* Copy the encoding...
|
||||
*/
|
||||
|
||||
for (language ++, ptr = charset; *language; language ++)
|
||||
if (ptr < (charset + sizeof(charset) - 1))
|
||||
*ptr++ = toupper(*language);
|
||||
|
||||
*ptr = '\0';
|
||||
}
|
||||
|
||||
if (strlen(langname) < 2)
|
||||
strcpy(real, "C");
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Convert the language name to a normalized form, e.g.:
|
||||
*
|
||||
* ll[_CC[.charset]]
|
||||
* Force a POSIX locale for an invalid language name...
|
||||
*/
|
||||
|
||||
real[0] = tolower(langname[0]);
|
||||
real[1] = tolower(langname[1]);
|
||||
realptr = real + 2;
|
||||
langptr = langname + 2;
|
||||
|
||||
if (*langptr == '_' || *langptr == '-')
|
||||
if (strlen(langname) != 2)
|
||||
{
|
||||
/*
|
||||
* Add country code...
|
||||
*/
|
||||
|
||||
*realptr++ = '_';
|
||||
langptr ++;
|
||||
|
||||
*realptr++ = toupper(*langptr++);
|
||||
*realptr++ = toupper(*langptr++);
|
||||
strcpy(langname, "C");
|
||||
country[0] = '\0';
|
||||
charset[0] = '\0';
|
||||
}
|
||||
|
||||
if (*langptr == '.')
|
||||
{
|
||||
/*
|
||||
* Add charset...
|
||||
*/
|
||||
|
||||
*langptr++ = '\0';
|
||||
*realptr++ = '.';
|
||||
|
||||
while (*langptr)
|
||||
{
|
||||
if ((realptr - real) < (sizeof(real) - 1) &&
|
||||
*langptr != '-' && *langptr != '_')
|
||||
*realptr++ = tolower(*langptr++);
|
||||
else
|
||||
langptr ++;
|
||||
}
|
||||
}
|
||||
|
||||
*realptr = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* See if we already have this language loaded...
|
||||
* Restore the locale...
|
||||
*/
|
||||
|
||||
for (lang = lang_cache; lang != NULL; lang = lang->next)
|
||||
if (strcmp(lang->language, langname) == 0)
|
||||
{
|
||||
lang->used ++;
|
||||
|
||||
return (lang);
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
/* The ctype bug isn't in Apple's libc */
|
||||
#elif !defined(LC_CTYPE)
|
||||
_cupsRestoreLocale(LC_ALL, oldlocale);
|
||||
#else
|
||||
_cupsRestoreLocale(LC_CTYPE, oldlocale);
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
/*
|
||||
* Next try to open a locale file; we will try the charset-localized
|
||||
* file first, then the country-localized file, and finally look for
|
||||
* a generic language file. If all else fails we will use the POSIX
|
||||
* locale.
|
||||
* Figure out the desired encoding...
|
||||
*/
|
||||
|
||||
encoding = CUPS_AUTO_ENCODING;
|
||||
|
||||
if (charset[0])
|
||||
{
|
||||
for (i = 0; i < (int)(sizeof(locale_encodings) / sizeof(locale_encodings[0])); i ++)
|
||||
if (!strcasecmp(charset, locale_encodings[i]))
|
||||
{
|
||||
encoding = (cups_encoding_t)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now find the message catalog for this locale...
|
||||
*/
|
||||
|
||||
if ((localedir = getenv("LOCALEDIR")) == NULL)
|
||||
localedir = CUPS_LOCALEDIR;
|
||||
|
||||
for (fp = NULL; fp == NULL;)
|
||||
{
|
||||
snprintf(filename, sizeof(filename), "%s/%s/cups_%s", localedir,
|
||||
real, real);
|
||||
/*
|
||||
* See if we already have this language/country loaded...
|
||||
*/
|
||||
|
||||
if ((fp = fopen(filename, "r")) == NULL)
|
||||
snprintf(real, sizeof(real), "%s_%s", langname, country);
|
||||
|
||||
if ((lang = cups_cache_lookup(real, encoding)) != NULL)
|
||||
return (lang);
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/%s/cups_%s", localedir, real, real);
|
||||
|
||||
if (!country[0] || access(filename, 0))
|
||||
{
|
||||
/*
|
||||
* Country localization not available, look for generic localization...
|
||||
*/
|
||||
|
||||
if ((lang = cups_cache_lookup(langname, encoding)) != NULL)
|
||||
return (lang);
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/%s/cups_%s", localedir,
|
||||
langname, langname);
|
||||
|
||||
if (access(filename, 0))
|
||||
{
|
||||
if ((realptr = strchr(real, '.')) != NULL)
|
||||
*realptr = '\0';
|
||||
else if ((realptr = strchr(real, '_')) != NULL)
|
||||
*realptr = '\0';
|
||||
else
|
||||
break;
|
||||
/*
|
||||
* No generic localization, so use POSIX...
|
||||
*/
|
||||
|
||||
strcpy(real, "C");
|
||||
snprintf(filename, sizeof(filename), "%s/C/cups_C", localedir);
|
||||
}
|
||||
else
|
||||
strcpy(real, langname);
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, we have an open messages file; the first line will contain the
|
||||
* language encoding (us-ascii, iso-8859-1, etc.), and the rest will
|
||||
* be messages consisting of:
|
||||
* Open the messages file; the first line contains the default
|
||||
* language encoding (us-ascii, iso-8859-1, etc.), and the rest are
|
||||
* messages consisting of:
|
||||
*
|
||||
* #### SP message text
|
||||
*
|
||||
@@ -287,6 +440,11 @@ cupsLangGet(const char *language) /* I - Language or locale */
|
||||
* All leading whitespace is deleted.
|
||||
*/
|
||||
|
||||
if (strcmp(real, "C"))
|
||||
fp = fopen(filename, "r");
|
||||
else
|
||||
fp = NULL;
|
||||
|
||||
if (fp == NULL)
|
||||
strlcpy(line, lang_default[0], sizeof(line));
|
||||
else if (fgets(line, sizeof(line), fp) == NULL)
|
||||
@@ -337,7 +495,7 @@ cupsLangGet(const char *language) /* I - Language or locale */
|
||||
if (lang->messages[i] != NULL && lang->messages[i] != lang_blank)
|
||||
free(lang->messages[i]);
|
||||
|
||||
lang->messages[i] = lang_blank;
|
||||
lang->messages[i] = (char*)lang_blank;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -345,14 +503,21 @@ cupsLangGet(const char *language) /* I - Language or locale */
|
||||
*/
|
||||
|
||||
lang->used ++;
|
||||
strlcpy(lang->language, langname, sizeof(lang->language));
|
||||
strlcpy(lang->language, real, sizeof(lang->language));
|
||||
|
||||
for (i = 0; i < (sizeof(lang_encodings) / sizeof(lang_encodings[0])); i ++)
|
||||
if (strcmp(lang_encodings[i], line) == 0)
|
||||
{
|
||||
lang->encoding = (cups_encoding_t)i;
|
||||
break;
|
||||
}
|
||||
if (encoding != CUPS_AUTO_ENCODING)
|
||||
lang->encoding = encoding;
|
||||
else
|
||||
{
|
||||
lang->encoding = CUPS_US_ASCII;
|
||||
|
||||
for (i = 0; i < (sizeof(lang_encodings) / sizeof(lang_encodings[0])); i ++)
|
||||
if (strcmp(lang_encodings[i], line) == 0)
|
||||
{
|
||||
lang->encoding = (cups_encoding_t)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the strings from the file...
|
||||
@@ -422,6 +587,329 @@ cupsLangGet(const char *language) /* I - Language or locale */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* '_cupsRestoreLocale()' - Restore the original locale...
|
||||
*/
|
||||
|
||||
void
|
||||
_cupsRestoreLocale(int category, /* I - Category */
|
||||
char *oldlocale) /* I - Old locale or NULL */
|
||||
{
|
||||
DEBUG_printf(("_cupsRestoreLocale(category=%d, oldlocale=\"%s\")\n",
|
||||
category, oldlocale));
|
||||
|
||||
if (oldlocale)
|
||||
{
|
||||
/*
|
||||
* Reset the locale and free the locale string...
|
||||
*/
|
||||
|
||||
setlocale(category, oldlocale);
|
||||
free(oldlocale);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* '_cupsSaveLocale()' - Set the locale and save a copy of the old locale...
|
||||
*/
|
||||
|
||||
char * /* O - Old locale or NULL */
|
||||
_cupsSaveLocale(int category, /* I - Category */
|
||||
const char *locale) /* I - New locale or NULL */
|
||||
{
|
||||
char *oldlocale; /* Old locale */
|
||||
|
||||
|
||||
DEBUG_printf(("_cupsSaveLocale(category=%d, locale=\"%s\")\n",
|
||||
category, locale));
|
||||
|
||||
/*
|
||||
* Get the old locale and copy it...
|
||||
*/
|
||||
|
||||
if ((oldlocale = setlocale(category, NULL)) != NULL)
|
||||
oldlocale = strdup(oldlocale);
|
||||
|
||||
DEBUG_printf((" oldlocale=\"%s\"\n", oldlocale ? oldlocale : "(null)"));
|
||||
|
||||
/*
|
||||
* Set the new locale...
|
||||
*/
|
||||
|
||||
setlocale(category, locale);
|
||||
|
||||
/*
|
||||
* Return a copy of the old locale...
|
||||
*/
|
||||
|
||||
return (oldlocale);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __APPLE__
|
||||
/*
|
||||
* Code & data to translate OSX's language names to their ISO 639-1 locale.
|
||||
*
|
||||
* The first version uses the new CoreFoundation API added in 10.3 (Panther),
|
||||
* the second is for 10.2 (Jaguar).
|
||||
*/
|
||||
|
||||
# ifdef HAVE_CF_LOCALE_ID
|
||||
/*
|
||||
* 'appleLangDefault()' - Get the default locale string.
|
||||
*/
|
||||
|
||||
static const char * /* O - Locale string */
|
||||
appleLangDefault(void)
|
||||
{
|
||||
CFPropertyListRef localizationList;
|
||||
/* List of localization data */
|
||||
CFStringRef languageName; /* Current name */
|
||||
CFStringRef localeName; /* Canonical from of name */
|
||||
static char language[32] = "";
|
||||
/* Cached language */
|
||||
|
||||
|
||||
/*
|
||||
* Only do the lookup and translation the first time.
|
||||
*/
|
||||
|
||||
if (!language[0])
|
||||
{
|
||||
localizationList =
|
||||
CFPreferencesCopyAppValue(CFSTR("AppleLanguages"),
|
||||
kCFPreferencesCurrentApplication);
|
||||
|
||||
if (localizationList != NULL)
|
||||
{
|
||||
if (CFGetTypeID(localizationList) == CFArrayGetTypeID() &&
|
||||
CFArrayGetCount(localizationList) > 0)
|
||||
{
|
||||
languageName = CFArrayGetValueAtIndex(localizationList, 0);
|
||||
|
||||
if (languageName != NULL &&
|
||||
CFGetTypeID(languageName) == CFStringGetTypeID())
|
||||
{
|
||||
localeName = CFLocaleCreateCanonicalLocaleIdentifierFromString(
|
||||
kCFAllocatorDefault, languageName);
|
||||
|
||||
if (localeName != NULL)
|
||||
{
|
||||
CFStringGetCString(localeName, language, sizeof(language),
|
||||
kCFStringEncodingASCII);
|
||||
CFRelease(localeName);
|
||||
|
||||
if (!strcmp(language, "en"))
|
||||
strlcpy(language, "en_US.UTF-8", sizeof(language));
|
||||
else if (strchr(language, '.') == NULL)
|
||||
strlcat(language, ".UTF-8", sizeof(language));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(localizationList);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we didn't find the language, default to en_US...
|
||||
*/
|
||||
|
||||
if (!language[0])
|
||||
strlcpy(language, "en_US.UTF-8", sizeof(language));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the cached locale...
|
||||
*/
|
||||
|
||||
return (language);
|
||||
}
|
||||
# else
|
||||
/*
|
||||
* Code & data to translate OSX 10.2's language names to their ISO 639-1
|
||||
* locale.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char * const name; /* Language name */
|
||||
const char * const locale; /* Locale name */
|
||||
} apple_name_locale_t;
|
||||
|
||||
static const apple_name_locale_t apple_name_locale[] =
|
||||
{
|
||||
{ "English" , "en_US.UTF-8" }, { "French" , "fr.UTF-8" },
|
||||
{ "German" , "de.UTF-8" }, { "Italian" , "it.UTF-8" },
|
||||
{ "Dutch" , "nl.UTF-8" }, { "Swedish" , "sv.UTF-8" },
|
||||
{ "Spanish" , "es.UTF-8" }, { "Danish" , "da.UTF-8" },
|
||||
{ "Portuguese" , "pt.UTF-8" }, { "Norwegian" , "no.UTF-8" },
|
||||
{ "Hebrew" , "he.UTF-8" }, { "Japanese" , "ja.UTF-8" },
|
||||
{ "Arabic" , "ar.UTF-8" }, { "Finnish" , "fi.UTF-8" },
|
||||
{ "Greek" , "el.UTF-8" }, { "Icelandic" , "is.UTF-8" },
|
||||
{ "Maltese" , "mt.UTF-8" }, { "Turkish" , "tr.UTF-8" },
|
||||
{ "Croatian" , "hr.UTF-8" }, { "Chinese" , "zh.UTF-8" },
|
||||
{ "Urdu" , "ur.UTF-8" }, { "Hindi" , "hi.UTF-8" },
|
||||
{ "Thai" , "th.UTF-8" }, { "Korean" , "ko.UTF-8" },
|
||||
{ "Lithuanian" , "lt.UTF-8" }, { "Polish" , "pl.UTF-8" },
|
||||
{ "Hungarian" , "hu.UTF-8" }, { "Estonian" , "et.UTF-8" },
|
||||
{ "Latvian" , "lv.UTF-8" }, { "Sami" , "se.UTF-8" },
|
||||
{ "Faroese" , "fo.UTF-8" }, { "Farsi" , "fa.UTF-8" },
|
||||
{ "Russian" , "ru.UTF-8" }, { "Chinese" , "zh.UTF-8" },
|
||||
{ "Dutch" , "nl.UTF-8" }, { "Irish" , "ga.UTF-8" },
|
||||
{ "Albanian" , "sq.UTF-8" }, { "Romanian" , "ro.UTF-8" },
|
||||
{ "Czech" , "cs.UTF-8" }, { "Slovak" , "sk.UTF-8" },
|
||||
{ "Slovenian" , "sl.UTF-8" }, { "Yiddish" , "yi.UTF-8" },
|
||||
{ "Serbian" , "sr.UTF-8" }, { "Macedonian" , "mk.UTF-8" },
|
||||
{ "Bulgarian" , "bg.UTF-8" }, { "Ukrainian" , "uk.UTF-8" },
|
||||
{ "Byelorussian", "be.UTF-8" }, { "Uzbek" , "uz.UTF-8" },
|
||||
{ "Kazakh" , "kk.UTF-8" }, { "Azerbaijani", "az.UTF-8" },
|
||||
{ "Azerbaijani" , "az.UTF-8" }, { "Armenian" , "hy.UTF-8" },
|
||||
{ "Georgian" , "ka.UTF-8" }, { "Moldavian" , "mo.UTF-8" },
|
||||
{ "Kirghiz" , "ky.UTF-8" }, { "Tajiki" , "tg.UTF-8" },
|
||||
{ "Turkmen" , "tk.UTF-8" }, { "Mongolian" , "mn.UTF-8" },
|
||||
{ "Mongolian" , "mn.UTF-8" }, { "Pashto" , "ps.UTF-8" },
|
||||
{ "Kurdish" , "ku.UTF-8" }, { "Kashmiri" , "ks.UTF-8" },
|
||||
{ "Sindhi" , "sd.UTF-8" }, { "Tibetan" , "bo.UTF-8" },
|
||||
{ "Nepali" , "ne.UTF-8" }, { "Sanskrit" , "sa.UTF-8" },
|
||||
{ "Marathi" , "mr.UTF-8" }, { "Bengali" , "bn.UTF-8" },
|
||||
{ "Assamese" , "as.UTF-8" }, { "Gujarati" , "gu.UTF-8" },
|
||||
{ "Punjabi" , "pa.UTF-8" }, { "Oriya" , "or.UTF-8" },
|
||||
{ "Malayalam" , "ml.UTF-8" }, { "Kannada" , "kn.UTF-8" },
|
||||
{ "Tamil" , "ta.UTF-8" }, { "Telugu" , "te.UTF-8" },
|
||||
{ "Sinhalese" , "si.UTF-8" }, { "Burmese" , "my.UTF-8" },
|
||||
{ "Khmer" , "km.UTF-8" }, { "Lao" , "lo.UTF-8" },
|
||||
{ "Vietnamese" , "vi.UTF-8" }, { "Indonesian" , "id.UTF-8" },
|
||||
{ "Tagalog" , "tl.UTF-8" }, { "Malay" , "ms.UTF-8" },
|
||||
{ "Malay" , "ms.UTF-8" }, { "Amharic" , "am.UTF-8" },
|
||||
{ "Tigrinya" , "ti.UTF-8" }, { "Oromo" , "om.UTF-8" },
|
||||
{ "Somali" , "so.UTF-8" }, { "Swahili" , "sw.UTF-8" },
|
||||
{ "Kinyarwanda" , "rw.UTF-8" }, { "Rundi" , "rn.UTF-8" },
|
||||
{ "Nyanja" , "" }, { "Malagasy" , "mg.UTF-8" },
|
||||
{ "Esperanto" , "eo.UTF-8" }, { "Welsh" , "cy.UTF-8" },
|
||||
{ "Basque" , "eu.UTF-8" }, { "Catalan" , "ca.UTF-8" },
|
||||
{ "Latin" , "la.UTF-8" }, { "Quechua" , "qu.UTF-8" },
|
||||
{ "Guarani" , "gn.UTF-8" }, { "Aymara" , "ay.UTF-8" },
|
||||
{ "Tatar" , "tt.UTF-8" }, { "Uighur" , "ug.UTF-8" },
|
||||
{ "Dzongkha" , "dz.UTF-8" }, { "Javanese" , "jv.UTF-8" },
|
||||
{ "Sundanese" , "su.UTF-8" }, { "Galician" , "gl.UTF-8" },
|
||||
{ "Afrikaans" , "af.UTF-8" }, { "Breton" , "br.UTF-8" },
|
||||
{ "Inuktitut" , "iu.UTF-8" }, { "Scottish" , "gd.UTF-8" },
|
||||
{ "Manx" , "gv.UTF-8" }, { "Irish" , "ga.UTF-8" },
|
||||
{ "Tongan" , "to.UTF-8" }, { "Greek" , "el.UTF-8" },
|
||||
{ "Greenlandic" , "kl.UTF-8" }, { "Azerbaijani", "az.UTF-8" }
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* 'appleLangDefault()' - Get the default locale string.
|
||||
*/
|
||||
|
||||
static const char * /* O - Locale string */
|
||||
appleLangDefault(void)
|
||||
{
|
||||
int i; /* Looping var */
|
||||
CFPropertyListRef localizationList;
|
||||
/* List of localization data */
|
||||
CFStringRef localizationName;
|
||||
/* Current name */
|
||||
char buff[256]; /* Temporary buffer */
|
||||
static const char *language = NULL;
|
||||
/* Cached language */
|
||||
|
||||
|
||||
/*
|
||||
* Only do the lookup and translation the first time.
|
||||
*/
|
||||
|
||||
if (language == NULL)
|
||||
{
|
||||
localizationList =
|
||||
CFPreferencesCopyAppValue(CFSTR("AppleLanguages"),
|
||||
kCFPreferencesCurrentApplication);
|
||||
|
||||
if (localizationList != NULL)
|
||||
{
|
||||
if (CFGetTypeID(localizationList) == CFArrayGetTypeID() &&
|
||||
CFArrayGetCount(localizationList) > 0)
|
||||
{
|
||||
localizationName = CFArrayGetValueAtIndex(localizationList, 0);
|
||||
|
||||
if (localizationName != NULL &&
|
||||
CFGetTypeID(localizationName) == CFStringGetTypeID())
|
||||
{
|
||||
CFIndex length = CFStringGetLength(localizationName);
|
||||
|
||||
if (length <= sizeof(buff) &&
|
||||
CFStringGetCString(localizationName, buff, sizeof(buff),
|
||||
kCFStringEncodingASCII))
|
||||
{
|
||||
buff[sizeof(buff) - 1] = '\0';
|
||||
|
||||
for (i = 0;
|
||||
i < sizeof(apple_name_locale) / sizeof(apple_name_locale[0]);
|
||||
i++)
|
||||
{
|
||||
if (strcasecmp(buff, apple_name_locale[i].name) == 0)
|
||||
{
|
||||
language = apple_name_locale[i].locale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(localizationList);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we didn't find the language, default to en_US...
|
||||
*/
|
||||
|
||||
if (language == NULL)
|
||||
language = apple_name_locale[0].locale;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the cached locale...
|
||||
*/
|
||||
|
||||
return (language);
|
||||
}
|
||||
# endif /* HAVE_CF_LOCALE_ID */
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
|
||||
/*
|
||||
* 'cups_cache_lookup()' - Lookup a language in the cache...
|
||||
*/
|
||||
|
||||
static cups_lang_t * /* O - Language data or NULL */
|
||||
cups_cache_lookup(const char *name,/* I - Name of locale */
|
||||
cups_encoding_t encoding)
|
||||
/* I - Encoding of locale */
|
||||
{
|
||||
cups_lang_t *lang; /* Current language */
|
||||
|
||||
|
||||
/*
|
||||
* Loop through the cache and return a match if found...
|
||||
*/
|
||||
|
||||
for (lang = lang_cache; lang != NULL; lang = lang->next)
|
||||
if (!strcmp(lang->language, name) &&
|
||||
(encoding == CUPS_AUTO_ENCODING || encoding == lang->encoding))
|
||||
{
|
||||
lang->used ++;
|
||||
|
||||
return (lang);
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id$".
|
||||
*/
|
||||
|
||||
@@ -161,6 +161,7 @@ typedef enum /**** Message Indices ****/
|
||||
|
||||
typedef enum /**** Language Encodings ****/
|
||||
{
|
||||
CUPS_AUTO_ENCODING = -1,
|
||||
CUPS_US_ASCII,
|
||||
CUPS_ISO8859_1,
|
||||
CUPS_ISO8859_2,
|
||||
@@ -205,18 +206,17 @@ typedef struct cups_lang_str /**** Language Cache Structure ****/
|
||||
* Prototypes...
|
||||
*/
|
||||
|
||||
# if defined(WIN32) || defined(__EMX__) || defined(__APPLE__)
|
||||
# define cupsLangDefault() cupsLangGet(setlocale(LC_ALL, ""))
|
||||
# else
|
||||
# define cupsLangDefault() cupsLangGet(setlocale(LC_MESSAGES, ""))
|
||||
# endif /* WIN32 || __EMX__ || __APPLE__ */
|
||||
|
||||
# define cupsLangDefault() cupsLangGet(NULL)
|
||||
extern 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);
|
||||
# define cupsLangString(lang,msg) (lang)->messages[(msg)]
|
||||
|
||||
/**** New in CUPS 1.1.20 ****/
|
||||
extern void _cupsRestoreLocale(int category, char *oldlocale);
|
||||
extern char *_cupsSaveLocale(int category, const char *locale);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif /* __cplusplus */
|
||||
|
||||
@@ -125,7 +125,7 @@ httpMD5String(const md5_byte_t *sum, /* I - MD5 sum data */
|
||||
{
|
||||
int i; /* Looping var */
|
||||
char *md5ptr; /* Pointer into MD5 string */
|
||||
static char *hex = "0123456789abcdef";
|
||||
static const char hex[] = "0123456789abcdef";
|
||||
/* Hex digits */
|
||||
|
||||
|
||||
|
||||
@@ -242,7 +242,12 @@ cupsParseOptions(const char *arg, /* I - Argument to parse */
|
||||
value = ptr;
|
||||
|
||||
while (*ptr != '\'' && *ptr != '\0')
|
||||
{
|
||||
if (*ptr == '\\')
|
||||
cups_strcpy(ptr, ptr + 1);
|
||||
|
||||
ptr ++;
|
||||
}
|
||||
|
||||
if (*ptr != '\0')
|
||||
*ptr++ = '\0';
|
||||
@@ -257,7 +262,42 @@ cupsParseOptions(const char *arg, /* I - Argument to parse */
|
||||
value = ptr;
|
||||
|
||||
while (*ptr != '\"' && *ptr != '\0')
|
||||
{
|
||||
if (*ptr == '\\')
|
||||
cups_strcpy(ptr, ptr + 1);
|
||||
|
||||
ptr ++;
|
||||
}
|
||||
|
||||
if (*ptr != '\0')
|
||||
*ptr++ = '\0';
|
||||
}
|
||||
else if (*ptr == '{')
|
||||
{
|
||||
/*
|
||||
* Collection value...
|
||||
*/
|
||||
|
||||
int depth;
|
||||
|
||||
value = ptr;
|
||||
|
||||
for (depth = 1; *ptr; ptr ++)
|
||||
if (*ptr == '{')
|
||||
depth ++;
|
||||
else if (*ptr == '}')
|
||||
{
|
||||
depth --;
|
||||
if (!depth)
|
||||
{
|
||||
ptr ++;
|
||||
|
||||
if (*ptr != ',')
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (*ptr == '\\')
|
||||
cups_strcpy(ptr, ptr + 1);
|
||||
|
||||
if (*ptr != '\0')
|
||||
*ptr++ = '\0';
|
||||
@@ -271,7 +311,12 @@ cupsParseOptions(const char *arg, /* I - Argument to parse */
|
||||
value = ptr;
|
||||
|
||||
while (!isspace(*ptr) && *ptr != '\0')
|
||||
ptr ++;
|
||||
{
|
||||
if (*ptr == '\\')
|
||||
cups_strcpy(ptr, ptr + 1);
|
||||
|
||||
ptr ++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -73,7 +73,7 @@ extern "C" {
|
||||
* Types and structures...
|
||||
*/
|
||||
|
||||
typedef enum /**** UI types ****/
|
||||
typedef enum /**** UI Types ****/
|
||||
{
|
||||
PPD_UI_BOOLEAN, /* True or False option */
|
||||
PPD_UI_PICKONE, /* Pick one from a list */
|
||||
@@ -100,6 +100,47 @@ typedef enum /**** Colorspaces ****/
|
||||
PPD_CS_N /* DeviceN colorspace */
|
||||
} ppd_cs_t;
|
||||
|
||||
typedef enum /**** Status Codes ****/
|
||||
{
|
||||
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_status_t;
|
||||
|
||||
typedef enum /**** Conformance Levels ****/
|
||||
{
|
||||
PPD_CONFORM_RELAXED, /* Relax whitespace and control char */
|
||||
PPD_CONFORM_STRICT /* Require strict conformance */
|
||||
} ppd_conform_t;
|
||||
|
||||
typedef struct /**** PPD Attribute Structure ****/
|
||||
{
|
||||
char name[PPD_MAX_NAME],
|
||||
/* Name of attribute (cupsXYZ) */
|
||||
spec[PPD_MAX_NAME],
|
||||
/* Specifier string, if any */
|
||||
text[PPD_MAX_TEXT],
|
||||
/* Human-readable text, if any */
|
||||
*value; /* Value string */
|
||||
} ppd_attr_t;
|
||||
|
||||
typedef struct /**** Option choices ****/
|
||||
{
|
||||
char marked, /* 0 if not selected, 1 otherwise */
|
||||
@@ -129,8 +170,14 @@ typedef struct /**** Options ****/
|
||||
|
||||
typedef struct ppd_group_str /**** Groups ****/
|
||||
{
|
||||
char text[PPD_MAX_TEXT];
|
||||
/**** 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 */
|
||||
name[PPD_MAX_NAME];
|
||||
/* Group name */
|
||||
int num_options; /* Number of options */
|
||||
ppd_option_t *options; /* Options */
|
||||
int num_subgroups; /* Number of sub-groups */
|
||||
@@ -223,7 +270,16 @@ typedef struct /**** Files ****/
|
||||
ppd_profile_t *profiles; /* sRGB color profiles */
|
||||
int num_filters; /* Number of filters */
|
||||
char **filters; /* Filter strings... */
|
||||
|
||||
/**** New in CUPS 1.1 ****/
|
||||
int flip_duplex; /* 1 = Flip page for back sides */
|
||||
|
||||
/**** New in CUPS 1.1.19 ****/
|
||||
char *protocols, /* Protocols (BCP, TBCP) string */
|
||||
*pcfilename; /* PCFileName string */
|
||||
int num_attrs, /* Number of attributes */
|
||||
cur_attr; /* Current attribute */
|
||||
ppd_attr_t **attrs; /* Attributes */
|
||||
} ppd_file_t;
|
||||
|
||||
|
||||
@@ -241,14 +297,14 @@ 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_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 ppd_file_t *ppdOpen(FILE *fp);
|
||||
extern ppd_file_t *ppdOpenFd(int fd);
|
||||
extern ppd_file_t *ppdOpenFile(const char *filename);
|
||||
@@ -256,6 +312,18 @@ 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);
|
||||
extern ppd_attr_t *ppdFindAttr(ppd_file_t *ppd, const char *name,
|
||||
const char *spec);
|
||||
extern ppd_attr_t *ppdFindNextAttr(ppd_file_t *ppd, const char *name,
|
||||
const char *spec);
|
||||
extern ppd_status_t ppdLastError(int *line);
|
||||
|
||||
/**** New in CUPS 1.1.20 ****/
|
||||
extern void ppdSetConformance(ppd_conform_t c);
|
||||
|
||||
|
||||
/*
|
||||
* C++ magic...
|
||||
*/
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* cups_strcpy() - Copy a string allowing for overlapping strings.
|
||||
* cups_strdup() - Duplicate a string.
|
||||
* cups_strcasecmp() - Do a case-insensitive comparison.
|
||||
* cups_strncasecmp() - Do a case-insensitive comparison on up to N chars.
|
||||
@@ -39,6 +40,21 @@
|
||||
#include "string.h"
|
||||
|
||||
|
||||
/*
|
||||
* 'cups_strcpy()' - Copy a string allowing for overlapping strings.
|
||||
*/
|
||||
|
||||
void
|
||||
cups_strcpy(char *dst, /* I - Destination string */
|
||||
const char *src) /* I - Source string */
|
||||
{
|
||||
while (*src)
|
||||
*dst++ = *src++;
|
||||
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'cups_strdup()' - Duplicate a string.
|
||||
*/
|
||||
|
||||
@@ -73,6 +73,8 @@ extern "C" {
|
||||
* Prototypes...
|
||||
*/
|
||||
|
||||
extern void cups_strcpy(char *dst, const char *src);
|
||||
|
||||
# ifndef HAVE_STRDUP
|
||||
extern char *cups_strdup(const char *);
|
||||
# define strdup cups_strdup
|
||||
|
||||
@@ -58,14 +58,14 @@ cupsTempFd(char *filename, /* I - Pointer to buffer */
|
||||
{
|
||||
int fd; /* File descriptor for temp file */
|
||||
int tries; /* Number of tries */
|
||||
const char *tmpdir; /* TMPDIR environment var */
|
||||
#ifdef WIN32
|
||||
char tmpdir[1024]; /* Windows temporary directory */
|
||||
char tmppath[1024]; /* Windows temporary directory */
|
||||
DWORD curtime; /* Current time */
|
||||
#else
|
||||
char *tmpdir; /* TMPDIR environment var */
|
||||
struct timeval curtime; /* Current time */
|
||||
#endif /* WIN32 */
|
||||
static char buf[1024] = ""; /* Buffer if you pass in NULL and 0 */
|
||||
static char *buf = NULL; /* Buffer if you pass in NULL and 0 */
|
||||
|
||||
|
||||
/*
|
||||
@@ -74,8 +74,14 @@ cupsTempFd(char *filename, /* I - Pointer to buffer */
|
||||
|
||||
if (filename == NULL)
|
||||
{
|
||||
if (buf == NULL)
|
||||
buf = calloc(1024, sizeof(char));
|
||||
|
||||
if (buf == NULL)
|
||||
return (-1);
|
||||
|
||||
filename = buf;
|
||||
len = sizeof(buf);
|
||||
len = 1024;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -83,7 +89,11 @@ cupsTempFd(char *filename, /* I - Pointer to buffer */
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
GetTempPath(sizeof(tmpdir), tmpdir);
|
||||
if ((tmpdir = getenv("TEMP")) == NULL)
|
||||
{
|
||||
GetTempPath(sizeof(tmppath), tmppath);
|
||||
tmpdir = tmppath;
|
||||
}
|
||||
#else
|
||||
if ((tmpdir = getenv("TMPDIR")) == NULL)
|
||||
{
|
||||
@@ -139,11 +149,14 @@ cupsTempFd(char *filename, /* I - Pointer to buffer */
|
||||
* stomp on an existing file or someone's symlink crack...
|
||||
*/
|
||||
|
||||
#ifdef O_NOFOLLOW
|
||||
#ifdef WIN32
|
||||
fd = open(filename, _O_CREAT | _O_RDWR | _O_TRUNC | _O_BINARY,
|
||||
_S_IREAD | _S_IWRITE);
|
||||
#elif defined(O_NOFOLLOW)
|
||||
fd = open(filename, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
|
||||
#else
|
||||
fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||
#endif /* O_NOFOLLOW */
|
||||
#endif /* WIN32 */
|
||||
|
||||
if (fd < 0 && errno != EEXIST)
|
||||
break;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "http.h"
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,521 @@
|
||||
/*
|
||||
* "$Id$"
|
||||
*
|
||||
* IPP test program for the Common UNIX Printing System (CUPS).
|
||||
*
|
||||
* Copyright 1997-2003 by Easy Software Products.
|
||||
*
|
||||
* These coded instructions, statements, and computer programs are the
|
||||
* property of Easy Software Products and are protected by Federal
|
||||
* copyright law. Distribution and use rights are outlined in the file
|
||||
* "LICENSE.txt" which should have been included with this file. If this
|
||||
* file is missing or damaged please contact Easy Software Products
|
||||
* at:
|
||||
*
|
||||
* Attn: CUPS Licensing Information
|
||||
* Easy Software Products
|
||||
* 44141 Airport View Drive, Suite 204
|
||||
* Hollywood, Maryland 20636-3111 USA
|
||||
*
|
||||
* Voice: (301) 373-9603
|
||||
* EMail: cups-info@cups.org
|
||||
* WWW: http://www.cups.org
|
||||
*
|
||||
* This file is subject to the Apple OS-Developed Software exception.
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* main() - Main entry.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Include necessary headers...
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <cups/string.h>
|
||||
#include <errno.h>
|
||||
#include "ipp.h"
|
||||
#ifdef WIN32
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# include <fcntl.h>
|
||||
#endif /* WIN32 */
|
||||
|
||||
|
||||
/*
|
||||
* Local globals...
|
||||
*/
|
||||
|
||||
int rpos; /* Current position in buffer */
|
||||
ipp_uchar_t wbuffer[8192]; /* Write buffer */
|
||||
int wused; /* Number of bytes in buffer */
|
||||
ipp_uchar_t collection[] = /* Collection buffer */
|
||||
{
|
||||
0x01, 0x01, /* IPP version */
|
||||
0x00, 0x02, /* Print-Job operation */
|
||||
0x00, 0x00, 0x00, 0x01, /* Request ID */
|
||||
IPP_TAG_OPERATION,
|
||||
IPP_TAG_CHARSET,
|
||||
0x00, 0x12, /* Name length + name */
|
||||
'a','t','t','r','i','b','u','t','e','s','-',
|
||||
'c','h','a','r','s','e','t',
|
||||
0x00, 0x05, /* Value length + value */
|
||||
'u','t','f','-','8',
|
||||
IPP_TAG_LANGUAGE,
|
||||
0x00, 0x1b, /* Name length + name */
|
||||
'a','t','t','r','i','b','u','t','e','s','-',
|
||||
'n','a','t','u','r','a','l','-','l','a','n',
|
||||
'g','u','a','g','e',
|
||||
0x00, 0x02, /* Value length + value */
|
||||
'e','n',
|
||||
IPP_TAG_URI,
|
||||
0x00, 0x0b, /* Name length + name */
|
||||
'p','r','i','n','t','e','r','-','u','r','i',
|
||||
0x00, 0x1c, /* Value length + value */
|
||||
'i','p','p',':','/','/','l','o','c','a','l',
|
||||
'h','o','s','t','/','p','r','i','n','t','e',
|
||||
'r','s','/','f','o','o',
|
||||
IPP_TAG_JOB, /* job group tag */
|
||||
IPP_TAG_BEGIN_COLLECTION, /* begCollection tag */
|
||||
0x00, 0x09, /* Name length + name */
|
||||
'm', 'e', 'd', 'i', 'a', '-', 'c', 'o', 'l',
|
||||
0x00, 0x00, /* No value */
|
||||
IPP_TAG_MEMBERNAME, /* memberAttrName tag */
|
||||
0x00, 0x00, /* No name */
|
||||
0x00, 0x0b, /* Value length + value */
|
||||
'm', 'e', 'd', 'i', 'a', '-', 'c', 'o', 'l', 'o', 'r',
|
||||
IPP_TAG_KEYWORD, /* keyword tag */
|
||||
0x00, 0x00, /* No name */
|
||||
0x00, 0x04, /* Value length + value */
|
||||
'b', 'l', 'u', 'e',
|
||||
IPP_TAG_END_COLLECTION, /* endCollection tag */
|
||||
0x00, 0x00, /* No name */
|
||||
0x00, 0x00, /* No value */
|
||||
IPP_TAG_END /* end tag */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Local functions...
|
||||
*/
|
||||
|
||||
void hex_dump(ipp_uchar_t *buffer, int bytes);
|
||||
void print_attributes(ipp_t *ipp, int indent);
|
||||
int read_cb(void *data, ipp_uchar_t *buffer, int bytes);
|
||||
int write_cb(void *data, ipp_uchar_t *buffer, int bytes);
|
||||
|
||||
|
||||
/*
|
||||
* 'main()' - Main entry.
|
||||
*/
|
||||
|
||||
int /* O - Exit status */
|
||||
main(int argc, /* I - Number of command-line arguments */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
{
|
||||
ipp_t *col; /* Collection */
|
||||
ipp_t *request; /* Request */
|
||||
ipp_state_t state; /* State */
|
||||
int length; /* Length of data */
|
||||
int fd; /* File descriptor */
|
||||
int i; /* Looping var */
|
||||
|
||||
|
||||
request = ippNew();
|
||||
request->request.op.version[0] = 0x01;
|
||||
request->request.op.version[1] = 0x01;
|
||||
request->request.op.operation_id = IPP_PRINT_JOB;
|
||||
request->request.op.request_id = 1;
|
||||
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
|
||||
"attributes-charset", NULL, "utf-8");
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
|
||||
"attributes-natural-language", NULL, "en");
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
|
||||
"printer-uri", NULL, "ipp://localhost/printers/foo");
|
||||
|
||||
col = ippNew();
|
||||
ippAddString(col, IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-color", NULL, "blue");
|
||||
ippAddCollection(request, IPP_TAG_JOB, "media-col", col);
|
||||
|
||||
length = ippLength(request);
|
||||
if (length != sizeof(collection))
|
||||
printf("ERROR ippLength didn't compute the correct length (%d instead of %d bytes!)\n",
|
||||
length, sizeof(collection));
|
||||
|
||||
wused = 0;
|
||||
while ((state = ippWriteIO(wbuffer, write_cb, 1, NULL, request)) != IPP_DATA)
|
||||
if (state == IPP_ERROR)
|
||||
break;
|
||||
|
||||
if (state != IPP_DATA)
|
||||
puts("ERROR writing collection attribute!");
|
||||
|
||||
printf("%d bytes written:\n", wused);
|
||||
hex_dump(wbuffer, wused);
|
||||
|
||||
if (wused != sizeof(collection))
|
||||
{
|
||||
printf("ERROR expected %d bytes!\n", sizeof(collection));
|
||||
hex_dump(collection, sizeof(collection));
|
||||
}
|
||||
else if (memcmp(wbuffer, collection, wused))
|
||||
{
|
||||
puts("ERROR output does not match baseline!");
|
||||
hex_dump(collection, sizeof(collection));
|
||||
}
|
||||
|
||||
ippDelete(col);
|
||||
ippDelete(request);
|
||||
|
||||
request = ippNew();
|
||||
rpos = 0;
|
||||
|
||||
while ((state = ippReadIO(wbuffer, read_cb, 1, NULL, request)) != IPP_DATA)
|
||||
if (state == IPP_ERROR)
|
||||
break;
|
||||
|
||||
if (state != IPP_DATA)
|
||||
puts("ERROR reading collection attribute!");
|
||||
|
||||
printf("%d bytes read.\n", rpos);
|
||||
|
||||
puts("Core IPP tests passed.");
|
||||
|
||||
for (i = 1; i < argc; i ++)
|
||||
{
|
||||
if ((fd = open(argv[i], O_RDONLY)) < 0)
|
||||
{
|
||||
printf("Unable to open \"%s\" - %s\n", argv[i], strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
request = ippNew();
|
||||
while ((state = ippReadFile(fd, request)) == IPP_ATTRIBUTE);
|
||||
|
||||
if (state != IPP_DATA)
|
||||
printf("Error reading IPP message from \"%s\"!\n", argv[i]);
|
||||
else
|
||||
{
|
||||
printf("\n%s:\n", argv[i]);
|
||||
print_attributes(request, 4);
|
||||
}
|
||||
|
||||
ippDelete(request);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'hex_dump()' - Produce a hex dump of a buffer.
|
||||
*/
|
||||
|
||||
void
|
||||
hex_dump(ipp_uchar_t *buffer, /* I - Buffer to dump */
|
||||
int bytes) /* I - Number of bytes */
|
||||
{
|
||||
int i, j; /* Looping vars */
|
||||
int ch; /* Current ASCII char */
|
||||
|
||||
|
||||
/*
|
||||
* Show lines of 16 bytes at a time...
|
||||
*/
|
||||
|
||||
for (i = 0; i < bytes; i += 16)
|
||||
{
|
||||
/*
|
||||
* Show the offset...
|
||||
*/
|
||||
|
||||
printf("%04x ", i);
|
||||
|
||||
/*
|
||||
* Then up to 16 bytes in hex...
|
||||
*/
|
||||
|
||||
for (j = 0; j < 16; j ++)
|
||||
if ((i + j) < bytes)
|
||||
printf(" %02x", buffer[i + j]);
|
||||
else
|
||||
printf(" ");
|
||||
|
||||
/*
|
||||
* Then the ASCII representation of the bytes...
|
||||
*/
|
||||
|
||||
putchar(' ');
|
||||
putchar(' ');
|
||||
|
||||
for (j = 0; j < 16 && (i + j) < bytes; j ++)
|
||||
{
|
||||
ch = buffer[i + j] & 127;
|
||||
|
||||
if (ch < ' ' || ch == 127)
|
||||
putchar('.');
|
||||
else
|
||||
putchar(ch);
|
||||
}
|
||||
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'print_attributes()' - Print the attributes in a request...
|
||||
*/
|
||||
|
||||
void
|
||||
print_attributes(ipp_t *ipp, /* I - IPP request */
|
||||
int indent) /* I - Indentation */
|
||||
{
|
||||
int i; /* Looping var */
|
||||
ipp_tag_t group; /* Current group */
|
||||
ipp_attribute_t *attr; /* Current attribute */
|
||||
ipp_value_t *val; /* Current value */
|
||||
static const char * const tags[] = /* Value/group tag strings */
|
||||
{
|
||||
"reserved-00",
|
||||
"operation-attributes-tag",
|
||||
"job-attributes-tag",
|
||||
"end-of-attributes-tag",
|
||||
"printer-attributes-tag",
|
||||
"unsupported-attributes-tag",
|
||||
"subscription-attributes-tag",
|
||||
"event-attributes-tag",
|
||||
"reserved-08",
|
||||
"reserved-09",
|
||||
"reserved-0A",
|
||||
"reserved-0B",
|
||||
"reserved-0C",
|
||||
"reserved-0D",
|
||||
"reserved-0E",
|
||||
"reserved-0F",
|
||||
"unsupported",
|
||||
"default",
|
||||
"unknown",
|
||||
"no-value",
|
||||
"reserved-14",
|
||||
"not-settable",
|
||||
"delete-attr",
|
||||
"admin-define",
|
||||
"reserved-18",
|
||||
"reserved-19",
|
||||
"reserved-1A",
|
||||
"reserved-1B",
|
||||
"reserved-1C",
|
||||
"reserved-1D",
|
||||
"reserved-1E",
|
||||
"reserved-1F",
|
||||
"reserved-20",
|
||||
"integer",
|
||||
"boolean",
|
||||
"enum",
|
||||
"reserved-24",
|
||||
"reserved-25",
|
||||
"reserved-26",
|
||||
"reserved-27",
|
||||
"reserved-28",
|
||||
"reserved-29",
|
||||
"reserved-2a",
|
||||
"reserved-2b",
|
||||
"reserved-2c",
|
||||
"reserved-2d",
|
||||
"reserved-2e",
|
||||
"reserved-2f",
|
||||
"octetString",
|
||||
"dateTime",
|
||||
"resolution",
|
||||
"rangeOfInteger",
|
||||
"begCollection",
|
||||
"textWithLanguage",
|
||||
"nameWithLanguage",
|
||||
"endCollection",
|
||||
"reserved-38",
|
||||
"reserved-39",
|
||||
"reserved-3a",
|
||||
"reserved-3b",
|
||||
"reserved-3c",
|
||||
"reserved-3d",
|
||||
"reserved-3e",
|
||||
"reserved-3f",
|
||||
"reserved-40",
|
||||
"textWithoutLanguage",
|
||||
"nameWithoutLanguage",
|
||||
"reserved-43",
|
||||
"keyword",
|
||||
"uri",
|
||||
"uriScheme",
|
||||
"charset",
|
||||
"naturalLanguage",
|
||||
"mimeMediaType",
|
||||
"memberName"
|
||||
};
|
||||
|
||||
|
||||
for (group = IPP_TAG_ZERO, attr = ipp->attrs; attr; attr = attr->next)
|
||||
{
|
||||
if (attr->group_tag == IPP_TAG_ZERO || !attr->name)
|
||||
{
|
||||
group = IPP_TAG_ZERO;
|
||||
putchar('\n');
|
||||
continue;
|
||||
}
|
||||
|
||||
if (group != attr->group_tag)
|
||||
{
|
||||
group = attr->group_tag;
|
||||
|
||||
putchar('\n');
|
||||
for (i = 2; i < indent; i ++)
|
||||
putchar(' ');
|
||||
|
||||
printf("%s:\n\n", tags[group]);
|
||||
}
|
||||
|
||||
for (i = 0; i < indent; i ++)
|
||||
putchar(' ');
|
||||
|
||||
printf("%s (%s):", attr->name, tags[attr->value_tag]);
|
||||
|
||||
switch (attr->value_tag)
|
||||
{
|
||||
case IPP_TAG_ENUM :
|
||||
case IPP_TAG_INTEGER :
|
||||
for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
|
||||
printf(" %d", val->integer);
|
||||
putchar('\n');
|
||||
break;
|
||||
|
||||
case IPP_TAG_BOOLEAN :
|
||||
for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
|
||||
printf(" %s", val->boolean ? "true" : "false");
|
||||
putchar('\n');
|
||||
break;
|
||||
|
||||
case IPP_TAG_RANGE :
|
||||
for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
|
||||
printf(" %d-%d", val->range.lower, val->range.upper);
|
||||
putchar('\n');
|
||||
break;
|
||||
|
||||
case IPP_TAG_DATE :
|
||||
{
|
||||
time_t vtime; /* Date/Time value */
|
||||
struct tm *vdate; /* Date info */
|
||||
char vstring[256]; /* Formatted time */
|
||||
|
||||
for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
|
||||
{
|
||||
vtime = ippDateToTime(val->date);
|
||||
vdate = localtime(&vtime);
|
||||
strftime(vstring, sizeof(vstring), "%c", vdate);
|
||||
printf(" (%s)", vstring);
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
break;
|
||||
|
||||
case IPP_TAG_RESOLUTION :
|
||||
for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
|
||||
printf(" %dx%d%s", val->resolution.xres, val->resolution.yres,
|
||||
val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpc");
|
||||
putchar('\n');
|
||||
break;
|
||||
|
||||
case IPP_TAG_STRING :
|
||||
case IPP_TAG_TEXTLANG :
|
||||
case IPP_TAG_NAMELANG :
|
||||
case IPP_TAG_TEXT :
|
||||
case IPP_TAG_NAME :
|
||||
case IPP_TAG_KEYWORD :
|
||||
case IPP_TAG_URI :
|
||||
case IPP_TAG_URISCHEME :
|
||||
case IPP_TAG_CHARSET :
|
||||
case IPP_TAG_LANGUAGE :
|
||||
case IPP_TAG_MIMETYPE :
|
||||
for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
|
||||
printf(" \"%s\"", val->string.text);
|
||||
putchar('\n');
|
||||
break;
|
||||
|
||||
case IPP_TAG_BEGIN_COLLECTION :
|
||||
putchar('\n');
|
||||
|
||||
for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
|
||||
print_attributes(val->collection, indent + 4);
|
||||
break;
|
||||
|
||||
default :
|
||||
putchar('\n');
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'read_cb()' - Read data from a buffer.
|
||||
*/
|
||||
|
||||
int /* O - Number of bytes read */
|
||||
read_cb(void *data, /* I - Data */
|
||||
ipp_uchar_t *buffer, /* O - Buffer to read */
|
||||
int bytes) /* I - Number of bytes to read */
|
||||
{
|
||||
int count; /* Number of bytes */
|
||||
|
||||
|
||||
/*
|
||||
* Copy bytes from the data buffer to the read buffer...
|
||||
*/
|
||||
|
||||
for (count = bytes; count > 0 && rpos < wused; count --, rpos ++)
|
||||
*buffer++ = wbuffer[rpos];
|
||||
|
||||
/*
|
||||
* Return the number of bytes read...
|
||||
*/
|
||||
|
||||
return (bytes - count);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'write_cb()' - Write data into a buffer.
|
||||
*/
|
||||
|
||||
int /* O - Number of bytes written */
|
||||
write_cb(void *data, /* I - Data */
|
||||
ipp_uchar_t *buffer, /* I - Buffer to write */
|
||||
int bytes) /* I - Number of bytes to write */
|
||||
{
|
||||
int count; /* Number of bytes */
|
||||
|
||||
|
||||
/*
|
||||
* Loop until all bytes are written...
|
||||
*/
|
||||
|
||||
for (count = bytes; count > 0 && wused < sizeof(wbuffer); count --, wused ++)
|
||||
wbuffer[wused] = *buffer++;
|
||||
|
||||
/*
|
||||
* Return the number of bytes written...
|
||||
*/
|
||||
|
||||
return (bytes - count);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id$".
|
||||
*/
|
||||
@@ -45,7 +45,8 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
{
|
||||
cups_lang_t *language; /* Message catalog */
|
||||
static const char *charsets[] = /* Character sets */
|
||||
cups_lang_t *language2; /* Message catalog */
|
||||
static const char * const charsets[] =/* Character sets */
|
||||
{
|
||||
"us-ascii",
|
||||
"iso-8859-1",
|
||||
@@ -78,9 +79,18 @@ main(int argc, /* I - Number of command-line arguments */
|
||||
|
||||
|
||||
if (argc == 1)
|
||||
language = cupsLangDefault();
|
||||
{
|
||||
language = cupsLangDefault();
|
||||
language2 = cupsLangDefault();
|
||||
}
|
||||
else
|
||||
language = cupsLangGet(argv[1]);
|
||||
{
|
||||
language = cupsLangGet(argv[1]);
|
||||
language2 = cupsLangGet(argv[1]);
|
||||
}
|
||||
|
||||
if (language != language2)
|
||||
puts("**** ERROR: Language cache did not work! ****");
|
||||
|
||||
printf("Language = \"%s\"\n", language->language);
|
||||
printf("Encoding = \"%s\"\n", charsets[language->encoding]);
|
||||
|
||||
@@ -80,7 +80,7 @@ cupsEncryption(void)
|
||||
FILE *fp; /* client.conf file */
|
||||
char *encryption; /* CUPS_ENCRYPTION variable */
|
||||
const char *home; /* Home directory of user */
|
||||
static char line[1024]; /* Line from file */
|
||||
char line[1024]; /* Line from file */
|
||||
|
||||
|
||||
/*
|
||||
@@ -196,7 +196,7 @@ cupsServer(void)
|
||||
FILE *fp; /* client.conf file */
|
||||
char *server; /* Pointer to server name */
|
||||
const char *home; /* Home directory of user */
|
||||
static char line[1024]; /* Line from file */
|
||||
char line[1024]; /* Line from file */
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -37,8 +37,6 @@
|
||||
* cupsPrintFile() - Print a file to a printer or class.
|
||||
* cupsPrintFiles() - Print one or more files to a printer or class.
|
||||
* cups_connect() - Connect to the specified host...
|
||||
* cups_local_auth() - Get the local authorization certificate if
|
||||
* available/applicable...
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -46,7 +44,6 @@
|
||||
*/
|
||||
|
||||
#include "cups.h"
|
||||
#include "ipp.h"
|
||||
#include "language.h"
|
||||
#include "string.h"
|
||||
#include "debug.h"
|
||||
@@ -68,9 +65,6 @@
|
||||
|
||||
static http_t *cups_server = NULL; /* Current server connection */
|
||||
static ipp_status_t last_error = IPP_OK; /* Last IPP error */
|
||||
static char authstring[HTTP_MAX_VALUE] = "";
|
||||
/* Authorization string */
|
||||
static char pwdstring[33] = ""; /* Last password string */
|
||||
|
||||
|
||||
/*
|
||||
@@ -78,16 +72,15 @@ static char pwdstring[33] = ""; /* Last password string */
|
||||
*/
|
||||
|
||||
static char *cups_connect(const char *name, char *printer, char *hostname);
|
||||
static int cups_local_auth(http_t *http);
|
||||
|
||||
|
||||
/*
|
||||
* 'cupsCancelJob()' - Cancel a print job.
|
||||
*/
|
||||
|
||||
int /* O - 1 on success, 0 on failure */
|
||||
cupsCancelJob(const char *name, /* I - Name of printer or class */
|
||||
int job) /* I - Job ID */
|
||||
int /* O - 1 on success, 0 on failure */
|
||||
cupsCancelJob(const char *name, /* I - Name of printer or class */
|
||||
int job) /* I - Job ID */
|
||||
{
|
||||
char printer[HTTP_MAX_URI], /* Printer name */
|
||||
hostname[HTTP_MAX_URI], /* Hostname */
|
||||
@@ -103,6 +96,7 @@ cupsCancelJob(const char *name, /* I - Name of printer or class */
|
||||
|
||||
if (!cups_connect(name, printer, hostname))
|
||||
{
|
||||
DEBUG_puts("Unable to connect to server!");
|
||||
last_error = IPP_SERVICE_UNAVAILABLE;
|
||||
return (0);
|
||||
}
|
||||
@@ -132,6 +126,8 @@ cupsCancelJob(const char *name, /* I - Name of printer or class */
|
||||
"attributes-natural-language", NULL,
|
||||
language != NULL ? language->language : "C");
|
||||
|
||||
cupsLangFree(language);
|
||||
|
||||
snprintf(uri, sizeof(uri), "ipp://%s:%d/printers/%s", hostname, ippPort(), printer);
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
|
||||
NULL, uri);
|
||||
@@ -145,18 +141,10 @@ cupsCancelJob(const char *name, /* I - Name of printer or class */
|
||||
* Do the request...
|
||||
*/
|
||||
|
||||
if ((response = cupsDoRequest(cups_server, request, "/jobs/")) == NULL)
|
||||
{
|
||||
last_error = IPP_BAD_REQUEST;
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
last_error = response->request.status.status_code;
|
||||
if ((response = cupsDoRequest(cups_server, request, "/jobs/")) != NULL)
|
||||
ippDelete(response);
|
||||
|
||||
return (1);
|
||||
}
|
||||
return (last_error < IPP_REDIRECTION_OTHER_SITE);
|
||||
}
|
||||
|
||||
|
||||
@@ -177,15 +165,12 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */
|
||||
struct stat fileinfo; /* File information */
|
||||
int bytes; /* Number of bytes read/written */
|
||||
char buffer[32768]; /* Output buffer */
|
||||
const char *password; /* Password string */
|
||||
char realm[HTTP_MAX_VALUE], /* realm="xyz" string */
|
||||
nonce[HTTP_MAX_VALUE], /* nonce="xyz" string */
|
||||
plain[255], /* Plaintext username:password */
|
||||
encode[512]; /* Encoded username:password */
|
||||
char prompt[1024]; /* Prompt string */
|
||||
int digest_tries; /* Number of tries with Digest */
|
||||
|
||||
|
||||
DEBUG_printf(("cupsDoFileRequest(%p, %p, \'%s\', \'%s\')\n",
|
||||
http, request, resource ? resource : "(null)",
|
||||
filename ? filename : "(null)"));
|
||||
|
||||
if (http == NULL || request == NULL || resource == NULL)
|
||||
{
|
||||
if (request != NULL)
|
||||
@@ -195,9 +180,6 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
DEBUG_printf(("cupsDoFileRequest(%p, %p, \'%s\', \'%s\')\n",
|
||||
http, request, resource, filename ? filename : "(null)"));
|
||||
|
||||
/*
|
||||
* See if we have a file to send...
|
||||
*/
|
||||
@@ -248,9 +230,8 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */
|
||||
* Loop until we can send the request without authorization problems.
|
||||
*/
|
||||
|
||||
response = NULL;
|
||||
status = HTTP_ERROR;
|
||||
digest_tries = 0;
|
||||
response = NULL;
|
||||
status = HTTP_ERROR;
|
||||
|
||||
while (response == NULL)
|
||||
{
|
||||
@@ -269,9 +250,9 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */
|
||||
httpClearFields(http);
|
||||
httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, length);
|
||||
httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/ipp");
|
||||
httpSetField(http, HTTP_FIELD_AUTHORIZATION, authstring);
|
||||
httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);
|
||||
|
||||
DEBUG_printf(("cupsDoFileRequest: authstring=\"%s\"\n", authstring));
|
||||
DEBUG_printf(("cupsDoFileRequest: authstring=\"%s\"\n", http->authstring));
|
||||
|
||||
/*
|
||||
* Try the request...
|
||||
@@ -309,8 +290,13 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */
|
||||
rewind(file);
|
||||
|
||||
while ((bytes = fread(buffer, 1, sizeof(buffer), file)) > 0)
|
||||
{
|
||||
if (httpCheck(http))
|
||||
break;
|
||||
|
||||
if (httpWrite(http, buffer, bytes) < bytes)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -332,71 +318,16 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */
|
||||
*/
|
||||
|
||||
httpFlush(http);
|
||||
|
||||
/*
|
||||
* See if we can do authentication...
|
||||
*/
|
||||
|
||||
if (cupsDoAuthentication(http, "POST", resource))
|
||||
break;
|
||||
|
||||
httpReconnect(http);
|
||||
|
||||
/*
|
||||
* See if we can do local authentication...
|
||||
*/
|
||||
|
||||
if (cups_local_auth(http))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* See if we should retry the current digest password...
|
||||
*/
|
||||
|
||||
if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Basic", 5) == 0 ||
|
||||
digest_tries > 1 || !pwdstring[0])
|
||||
{
|
||||
/*
|
||||
* Nope - get a password from the user...
|
||||
*/
|
||||
|
||||
snprintf(prompt, sizeof(prompt), "Password for %s on %s? ", cupsUser(),
|
||||
http->hostname);
|
||||
|
||||
if ((password = cupsGetPassword(prompt)) == NULL)
|
||||
break;
|
||||
if (!password[0])
|
||||
break;
|
||||
|
||||
strlcpy(pwdstring, password, sizeof(pwdstring));
|
||||
|
||||
digest_tries = 0;
|
||||
}
|
||||
else
|
||||
digest_tries ++;
|
||||
|
||||
/*
|
||||
* Got a password; encode it for the server...
|
||||
*/
|
||||
|
||||
if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Basic", 5) == 0)
|
||||
{
|
||||
/*
|
||||
* Basic authentication...
|
||||
*/
|
||||
|
||||
snprintf(plain, sizeof(plain), "%s:%s", cupsUser(), pwdstring);
|
||||
httpEncode64(encode, plain);
|
||||
snprintf(authstring, sizeof(authstring), "Basic %s", encode);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Digest authentication...
|
||||
*/
|
||||
|
||||
httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "realm", realm);
|
||||
httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "nonce", nonce);
|
||||
|
||||
httpMD5(cupsUser(), realm, pwdstring, encode);
|
||||
httpMD5Final(nonce, "POST", resource, encode);
|
||||
snprintf(authstring, sizeof(authstring),
|
||||
"Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", "
|
||||
"response=\"%s\"", cupsUser(), realm, nonce, encode);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
else if (status == HTTP_ERROR)
|
||||
@@ -410,7 +341,7 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */
|
||||
else
|
||||
break;
|
||||
}
|
||||
#ifdef HAVE_LIBSSL
|
||||
#ifdef HAVE_SSL
|
||||
else if (status == HTTP_UPGRADE_REQUIRED)
|
||||
{
|
||||
/*
|
||||
@@ -431,7 +362,7 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */
|
||||
|
||||
continue;
|
||||
}
|
||||
#endif /* HAVE_LIBSSL */
|
||||
#endif /* HAVE_SSL */
|
||||
else if (status != HTTP_OK)
|
||||
{
|
||||
DEBUG_printf(("cupsDoFileRequest: error %d...\n", status));
|
||||
@@ -459,6 +390,7 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */
|
||||
* Delete the response...
|
||||
*/
|
||||
|
||||
DEBUG_puts("IPP read error!");
|
||||
ippDelete(response);
|
||||
response = NULL;
|
||||
|
||||
@@ -489,12 +421,45 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */
|
||||
|
||||
if (response)
|
||||
last_error = response->request.status.status_code;
|
||||
else if (status == HTTP_NOT_FOUND)
|
||||
last_error = IPP_NOT_FOUND;
|
||||
else if (status == HTTP_UNAUTHORIZED)
|
||||
last_error = IPP_NOT_AUTHORIZED;
|
||||
else if (status != HTTP_OK)
|
||||
last_error = IPP_SERVICE_UNAVAILABLE;
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case HTTP_NOT_FOUND :
|
||||
last_error = IPP_NOT_FOUND;
|
||||
break;
|
||||
|
||||
case HTTP_UNAUTHORIZED :
|
||||
last_error = IPP_NOT_AUTHORIZED;
|
||||
break;
|
||||
|
||||
case HTTP_FORBIDDEN :
|
||||
last_error = IPP_FORBIDDEN;
|
||||
break;
|
||||
|
||||
case HTTP_BAD_REQUEST :
|
||||
last_error = IPP_BAD_REQUEST;
|
||||
break;
|
||||
|
||||
case HTTP_REQUEST_TOO_LARGE :
|
||||
last_error = IPP_REQUEST_VALUE;
|
||||
break;
|
||||
|
||||
case HTTP_NOT_IMPLEMENTED :
|
||||
last_error = IPP_OPERATION_NOT_SUPPORTED;
|
||||
break;
|
||||
|
||||
case HTTP_NOT_SUPPORTED :
|
||||
last_error = IPP_VERSION_NOT_SUPPORTED;
|
||||
break;
|
||||
|
||||
default :
|
||||
DEBUG_printf(("HTTP error %d mapped to IPP_SERVICE_UNAVAILABLE!\n",
|
||||
status));
|
||||
last_error = IPP_SERVICE_UNAVAILABLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (response);
|
||||
}
|
||||
@@ -505,10 +470,10 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */
|
||||
*/
|
||||
|
||||
void
|
||||
cupsFreeJobs(int num_jobs,/* I - Number of jobs */
|
||||
cups_job_t *jobs) /* I - Jobs */
|
||||
cupsFreeJobs(int num_jobs, /* I - Number of jobs */
|
||||
cups_job_t *jobs) /* I - Jobs */
|
||||
{
|
||||
int i; /* Looping var */
|
||||
int i; /* Looping var */
|
||||
|
||||
|
||||
if (num_jobs <= 0 || jobs == NULL)
|
||||
@@ -530,15 +495,15 @@ cupsFreeJobs(int num_jobs,/* I - Number of jobs */
|
||||
* 'cupsGetClasses()' - Get a list of printer classes.
|
||||
*/
|
||||
|
||||
int /* O - Number of classes */
|
||||
cupsGetClasses(char ***classes) /* O - Classes */
|
||||
int /* O - Number of classes */
|
||||
cupsGetClasses(char ***classes) /* O - Classes */
|
||||
{
|
||||
int n; /* Number of classes */
|
||||
ipp_t *request, /* IPP Request */
|
||||
*response; /* IPP Response */
|
||||
ipp_attribute_t *attr; /* Current attribute */
|
||||
cups_lang_t *language; /* Default language */
|
||||
char **temp; /* Temporary pointer */
|
||||
int n; /* Number of classes */
|
||||
ipp_t *request, /* IPP Request */
|
||||
*response; /* IPP Response */
|
||||
ipp_attribute_t *attr; /* Current attribute */
|
||||
cups_lang_t *language; /* Default language */
|
||||
char **temp; /* Temporary pointer */
|
||||
|
||||
|
||||
if (classes == NULL)
|
||||
@@ -553,6 +518,7 @@ cupsGetClasses(char ***classes) /* O - Classes */
|
||||
|
||||
if (!cups_connect("default", NULL, NULL))
|
||||
{
|
||||
DEBUG_puts("Unable to connect to server!");
|
||||
last_error = IPP_SERVICE_UNAVAILABLE;
|
||||
return (0);
|
||||
}
|
||||
@@ -579,6 +545,8 @@ cupsGetClasses(char ***classes) /* O - Classes */
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
|
||||
"attributes-natural-language", NULL, language->language);
|
||||
|
||||
cupsLangFree(language);
|
||||
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
|
||||
"requested-attributes", NULL, "printer-name");
|
||||
|
||||
@@ -638,15 +606,15 @@ cupsGetClasses(char ***classes) /* O - Classes */
|
||||
* 'cupsGetDefault()' - Get the default printer or class.
|
||||
*/
|
||||
|
||||
const char * /* O - Default printer or NULL */
|
||||
const char * /* O - Default printer or NULL */
|
||||
cupsGetDefault(void)
|
||||
{
|
||||
ipp_t *request, /* IPP Request */
|
||||
*response; /* IPP Response */
|
||||
ipp_attribute_t *attr; /* Current attribute */
|
||||
cups_lang_t *language; /* Default language */
|
||||
const char *var; /* Environment variable */
|
||||
static char def_printer[256];/* Default printer */
|
||||
ipp_t *request, /* IPP Request */
|
||||
*response; /* IPP Response */
|
||||
ipp_attribute_t *attr; /* Current attribute */
|
||||
cups_lang_t *language; /* Default language */
|
||||
const char *var; /* Environment variable */
|
||||
static char def_printer[256]; /* Default printer */
|
||||
|
||||
|
||||
/*
|
||||
@@ -667,6 +635,7 @@ cupsGetDefault(void)
|
||||
|
||||
if (!cups_connect("default", NULL, NULL))
|
||||
{
|
||||
DEBUG_puts("Unable to connect to server!");
|
||||
last_error = IPP_SERVICE_UNAVAILABLE;
|
||||
return (NULL);
|
||||
}
|
||||
@@ -692,6 +661,8 @@ cupsGetDefault(void)
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
|
||||
"attributes-natural-language", NULL, language->language);
|
||||
|
||||
cupsLangFree(language);
|
||||
|
||||
/*
|
||||
* Do the request and get back a response...
|
||||
*/
|
||||
@@ -744,7 +715,7 @@ cupsGetJobs(cups_job_t **jobs, /* O - Job data */
|
||||
*title, /* job-name */
|
||||
*user; /* job-originating-user-name */
|
||||
char uri[HTTP_MAX_URI]; /* URI for jobs */
|
||||
static const char *attrs[] = /* Requested attributes */
|
||||
static const char * const attrs[] = /* Requested attributes */
|
||||
{
|
||||
"job-id",
|
||||
"job-priority",
|
||||
@@ -772,6 +743,7 @@ cupsGetJobs(cups_job_t **jobs, /* O - Job data */
|
||||
|
||||
if (!cups_connect("default", NULL, NULL))
|
||||
{
|
||||
DEBUG_puts("Unable to connect to server!");
|
||||
last_error = IPP_SERVICE_UNAVAILABLE;
|
||||
return (0);
|
||||
}
|
||||
@@ -802,6 +774,8 @@ cupsGetJobs(cups_job_t **jobs, /* O - Job data */
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
|
||||
"attributes-natural-language", NULL, language->language);
|
||||
|
||||
cupsLangFree(language);
|
||||
|
||||
if (mydest)
|
||||
snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", mydest);
|
||||
else
|
||||
@@ -986,31 +960,27 @@ cupsGetPPD(const char *name) /* I - Printer name */
|
||||
ipp_attribute_t *attr; /* Current attribute */
|
||||
cups_lang_t *language; /* Local language */
|
||||
int fd; /* PPD file */
|
||||
int bytes; /* Number of bytes read */
|
||||
char buffer[8192]; /* Buffer for file */
|
||||
char printer[HTTP_MAX_URI], /* Printer name */
|
||||
char uri[HTTP_MAX_URI], /* Printer URI */
|
||||
printer[HTTP_MAX_URI], /* Printer name */
|
||||
method[HTTP_MAX_URI], /* Method/scheme name */
|
||||
username[HTTP_MAX_URI], /* Username:password */
|
||||
hostname[HTTP_MAX_URI], /* Hostname */
|
||||
resource[HTTP_MAX_URI]; /* Resource name */
|
||||
int port; /* Port number */
|
||||
const char *password; /* Password string */
|
||||
char realm[HTTP_MAX_VALUE], /* realm="xyz" string */
|
||||
nonce[HTTP_MAX_VALUE], /* nonce="xyz" string */
|
||||
plain[255], /* Plaintext username:password */
|
||||
encode[512]; /* Encoded username:password */
|
||||
http_status_t status; /* HTTP status from server */
|
||||
char prompt[1024]; /* Prompt string */
|
||||
int digest_tries; /* Number of tries with Digest */
|
||||
static char filename[HTTP_MAX_URI]; /* Local filename */
|
||||
static const char *requested_attrs[] =/* Requested attributes */
|
||||
{
|
||||
static const char * const requested_attrs[] =
|
||||
{ /* Requested attributes */
|
||||
"printer-uri-supported",
|
||||
"printer-type",
|
||||
"member-uris"
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Range check input...
|
||||
*/
|
||||
|
||||
if (name == NULL)
|
||||
{
|
||||
last_error = IPP_INTERNAL_ERROR;
|
||||
@@ -1023,6 +993,7 @@ cupsGetPPD(const char *name) /* I - Printer name */
|
||||
|
||||
if (!cups_connect(name, printer, hostname))
|
||||
{
|
||||
DEBUG_puts("Unable to connect to server!");
|
||||
last_error = IPP_SERVICE_UNAVAILABLE;
|
||||
return (NULL);
|
||||
}
|
||||
@@ -1050,9 +1021,11 @@ cupsGetPPD(const char *name) /* I - Printer name */
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
|
||||
"attributes-natural-language", NULL, language->language);
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "ipp://localhost/printers/%s", printer);
|
||||
cupsLangFree(language);
|
||||
|
||||
snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
|
||||
"printer-uri", NULL, buffer);
|
||||
"printer-uri", NULL, uri);
|
||||
|
||||
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
|
||||
"requested-attributes",
|
||||
@@ -1108,14 +1081,12 @@ cupsGetPPD(const char *name) /* I - Printer name */
|
||||
* Remap local hostname to localhost...
|
||||
*/
|
||||
|
||||
gethostname(buffer, sizeof(buffer));
|
||||
gethostname(uri, sizeof(uri));
|
||||
|
||||
if (strcasecmp(buffer, hostname) == 0)
|
||||
if (strcasecmp(uri, hostname) == 0)
|
||||
strcpy(hostname, "localhost");
|
||||
}
|
||||
|
||||
cupsLangFree(language);
|
||||
|
||||
if (!printer[0])
|
||||
{
|
||||
last_error = IPP_NOT_FOUND;
|
||||
@@ -1133,6 +1104,7 @@ cupsGetPPD(const char *name) /* I - Printer name */
|
||||
if ((cups_server = httpConnectEncrypt(hostname, ippPort(),
|
||||
cupsEncryption())) == NULL)
|
||||
{
|
||||
DEBUG_puts("Unable to connect to server!");
|
||||
last_error = IPP_SERVICE_UNAVAILABLE;
|
||||
return (NULL);
|
||||
}
|
||||
@@ -1161,129 +1133,9 @@ cupsGetPPD(const char *name) /* I - Printer name */
|
||||
|
||||
snprintf(resource, sizeof(resource), "/printers/%s.ppd", printer);
|
||||
|
||||
digest_tries = 0;
|
||||
status = cupsGetFd(cups_server, resource, fd);
|
||||
|
||||
do
|
||||
{
|
||||
httpClearFields(cups_server);
|
||||
httpSetField(cups_server, HTTP_FIELD_HOST, hostname);
|
||||
httpSetField(cups_server, HTTP_FIELD_AUTHORIZATION, authstring);
|
||||
|
||||
if (httpGet(cups_server, resource))
|
||||
{
|
||||
if (httpReconnect(cups_server))
|
||||
{
|
||||
status = HTTP_ERROR;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = HTTP_UNAUTHORIZED;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
while ((status = httpUpdate(cups_server)) == HTTP_CONTINUE);
|
||||
|
||||
if (status == HTTP_UNAUTHORIZED)
|
||||
{
|
||||
DEBUG_puts("cupsGetPPD: unauthorized...");
|
||||
|
||||
/*
|
||||
* Flush any error message...
|
||||
*/
|
||||
|
||||
httpFlush(cups_server);
|
||||
|
||||
/*
|
||||
* See if we can do local authentication...
|
||||
*/
|
||||
|
||||
if (cups_local_auth(cups_server))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* See if we should retry the current digest password...
|
||||
*/
|
||||
|
||||
if (strncmp(cups_server->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Basic", 5) == 0 ||
|
||||
digest_tries > 1 || !pwdstring[0])
|
||||
{
|
||||
/*
|
||||
* Nope - get a password from the user...
|
||||
*/
|
||||
|
||||
snprintf(prompt, sizeof(prompt), "Password for %s on %s? ", cupsUser(),
|
||||
cups_server->hostname);
|
||||
|
||||
if ((password = cupsGetPassword(prompt)) == NULL)
|
||||
break;
|
||||
if (!password[0])
|
||||
break;
|
||||
|
||||
strlcpy(pwdstring, password, sizeof(pwdstring));
|
||||
|
||||
digest_tries = 0;
|
||||
}
|
||||
else
|
||||
digest_tries ++;
|
||||
|
||||
/*
|
||||
* Got a password; encode it for the server...
|
||||
*/
|
||||
|
||||
if (strncmp(cups_server->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Basic", 5) == 0)
|
||||
{
|
||||
/*
|
||||
* Basic authentication...
|
||||
*/
|
||||
|
||||
snprintf(plain, sizeof(plain), "%s:%s", cupsUser(), pwdstring);
|
||||
httpEncode64(encode, plain);
|
||||
snprintf(authstring, sizeof(authstring), "Basic %s", encode);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Digest authentication...
|
||||
*/
|
||||
|
||||
httpGetSubField(cups_server, HTTP_FIELD_WWW_AUTHENTICATE, "realm", realm);
|
||||
httpGetSubField(cups_server, HTTP_FIELD_WWW_AUTHENTICATE, "nonce", nonce);
|
||||
|
||||
httpMD5(cupsUser(), realm, pwdstring, encode);
|
||||
httpMD5Final(nonce, "GET", resource, encode);
|
||||
snprintf(authstring, sizeof(authstring),
|
||||
"Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", "
|
||||
"response=\"%s\"", cupsUser(), realm, nonce, encode);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
#ifdef HAVE_LIBSSL
|
||||
else if (status == HTTP_UPGRADE_REQUIRED)
|
||||
{
|
||||
/*
|
||||
* Flush any error message...
|
||||
*/
|
||||
|
||||
httpFlush(cups_server);
|
||||
|
||||
/*
|
||||
* Upgrade with encryption...
|
||||
*/
|
||||
|
||||
httpEncryption(cups_server, HTTP_ENCRYPT_REQUIRED);
|
||||
|
||||
/*
|
||||
* Try again, this time with encryption enabled...
|
||||
*/
|
||||
|
||||
continue;
|
||||
}
|
||||
#endif /* HAVE_LIBSSL */
|
||||
}
|
||||
while (status == HTTP_UNAUTHORIZED || status == HTTP_UPGRADE_REQUIRED);
|
||||
close(fd);
|
||||
|
||||
/*
|
||||
* See if we actually got the file or an error...
|
||||
@@ -1297,6 +1149,7 @@ cupsGetPPD(const char *name) /* I - Printer name */
|
||||
last_error = IPP_NOT_FOUND;
|
||||
break;
|
||||
case HTTP_ERROR :
|
||||
DEBUG_puts("Mapping HTTP error to IPP_SERVICE_UNAVAILABLE");
|
||||
last_error = IPP_SERVICE_UNAVAILABLE;
|
||||
break;
|
||||
case HTTP_UNAUTHORIZED :
|
||||
@@ -1315,14 +1168,9 @@ cupsGetPPD(const char *name) /* I - Printer name */
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, we need to copy the file...
|
||||
* Return the PPD file...
|
||||
*/
|
||||
|
||||
while ((bytes = httpRead(cups_server, buffer, sizeof(buffer))) > 0)
|
||||
write(fd, buffer, bytes);
|
||||
|
||||
close(fd);
|
||||
|
||||
return (filename);
|
||||
}
|
||||
|
||||
@@ -1334,12 +1182,12 @@ cupsGetPPD(const char *name) /* I - Printer name */
|
||||
int /* O - Number of printers */
|
||||
cupsGetPrinters(char ***printers) /* O - Printers */
|
||||
{
|
||||
int n; /* Number of printers */
|
||||
ipp_t *request, /* IPP Request */
|
||||
*response; /* IPP Response */
|
||||
ipp_attribute_t *attr; /* Current attribute */
|
||||
cups_lang_t *language; /* Default language */
|
||||
char **temp; /* Temporary pointer */
|
||||
int n; /* Number of printers */
|
||||
ipp_t *request, /* IPP Request */
|
||||
*response; /* IPP Response */
|
||||
ipp_attribute_t *attr; /* Current attribute */
|
||||
cups_lang_t *language; /* Default language */
|
||||
char **temp; /* Temporary pointer */
|
||||
|
||||
|
||||
if (printers == NULL)
|
||||
@@ -1354,6 +1202,7 @@ cupsGetPrinters(char ***printers) /* O - Printers */
|
||||
|
||||
if (!cups_connect("default", NULL, NULL))
|
||||
{
|
||||
DEBUG_puts("Unable to connect to server!");
|
||||
last_error = IPP_SERVICE_UNAVAILABLE;
|
||||
return (0);
|
||||
}
|
||||
@@ -1380,6 +1229,8 @@ cupsGetPrinters(char ***printers) /* O - Printers */
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
|
||||
"attributes-natural-language", NULL, language->language);
|
||||
|
||||
cupsLangFree(language);
|
||||
|
||||
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
|
||||
"requested-attributes", NULL, "printer-name");
|
||||
|
||||
@@ -1439,7 +1290,7 @@ cupsGetPrinters(char ***printers) /* O - Printers */
|
||||
* 'cupsLastError()' - Return the last IPP error that occurred.
|
||||
*/
|
||||
|
||||
ipp_status_t /* O - IPP error code */
|
||||
ipp_status_t /* O - IPP error code */
|
||||
cupsLastError(void)
|
||||
{
|
||||
return (last_error);
|
||||
@@ -1473,7 +1324,8 @@ cupsPrintFiles(const char *name, /* I - Printer or class name */
|
||||
int num_files, /* I - Number of files */
|
||||
const char **files, /* I - File(s) to print */
|
||||
const char *title, /* I - Title of job */
|
||||
int num_options,/* I - Number of options */
|
||||
int num_options,
|
||||
/* I - Number of options */
|
||||
cups_option_t *options) /* I - Options */
|
||||
{
|
||||
int i; /* Looping var */
|
||||
@@ -1502,6 +1354,7 @@ cupsPrintFiles(const char *name, /* I - Printer or class name */
|
||||
{
|
||||
DEBUG_printf(("cupsPrintFile: Unable to open connection - %s.\n",
|
||||
strerror(errno)));
|
||||
DEBUG_puts("Unable to connect to server!");
|
||||
last_error = IPP_SERVICE_UNAVAILABLE;
|
||||
return (0);
|
||||
}
|
||||
@@ -1640,6 +1493,8 @@ cupsPrintFiles(const char *name, /* I - Printer or class name */
|
||||
ippDelete(response);
|
||||
}
|
||||
|
||||
cupsLangFree(language);
|
||||
|
||||
return (jobid);
|
||||
}
|
||||
|
||||
@@ -1695,6 +1550,7 @@ cups_connect(const char *name, /* I - Destination (printer[@host]) */
|
||||
if ((cups_server = httpConnectEncrypt(hostname, ippPort(),
|
||||
cupsEncryption())) == NULL)
|
||||
{
|
||||
DEBUG_puts("Unable to connect to server!");
|
||||
last_error = IPP_SERVICE_UNAVAILABLE;
|
||||
return (NULL);
|
||||
}
|
||||
@@ -1703,89 +1559,6 @@ cups_connect(const char *name, /* I - Destination (printer[@host]) */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'cups_local_auth()' - Get the local authorization certificate if
|
||||
* available/applicable...
|
||||
*/
|
||||
|
||||
static int /* O - 1 if available, 0 if not */
|
||||
cups_local_auth(http_t *http) /* I - Connection */
|
||||
{
|
||||
#if defined(WIN32) || defined(__EMX__)
|
||||
/*
|
||||
* Currently WIN32 and OS-2 do not support the CUPS server...
|
||||
*/
|
||||
|
||||
return (0);
|
||||
#else
|
||||
int pid; /* Current process ID */
|
||||
FILE *fp; /* Certificate file */
|
||||
char filename[1024], /* Certificate filename */
|
||||
certificate[33];/* Certificate string */
|
||||
const char *root; /* Server root directory */
|
||||
|
||||
|
||||
DEBUG_printf(("cups_local_auth(http=%p) hostaddr=%08x, hostname=\"%s\"\n",
|
||||
http, ntohl(http->hostaddr.sin_addr.s_addr), http->hostname));
|
||||
|
||||
/*
|
||||
* See if we are accessing localhost...
|
||||
*/
|
||||
|
||||
if (ntohl(http->hostaddr.sin_addr.s_addr) != 0x7f000001 &&
|
||||
strcasecmp(http->hostname, "localhost") != 0)
|
||||
{
|
||||
DEBUG_puts("cups_local_auth: Not a local connection!");
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try opening a certificate file for this PID. If that fails,
|
||||
* try the root certificate...
|
||||
*/
|
||||
|
||||
if ((root = getenv("CUPS_SERVERROOT")) == NULL)
|
||||
root = CUPS_SERVERROOT;
|
||||
|
||||
pid = getpid();
|
||||
snprintf(filename, sizeof(filename), "%s/certs/%d", root, pid);
|
||||
if ((fp = fopen(filename, "r")) == NULL && pid > 0)
|
||||
{
|
||||
DEBUG_printf(("cups_local_auth: Unable to open file %s: %s\n",
|
||||
filename, strerror(errno)));
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/certs/0", root);
|
||||
fp = fopen(filename, "r");
|
||||
}
|
||||
|
||||
if (fp == NULL)
|
||||
{
|
||||
DEBUG_printf(("cups_local_auth: Unable to open file %s: %s\n",
|
||||
filename, strerror(errno)));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the certificate from the file...
|
||||
*/
|
||||
|
||||
fgets(certificate, sizeof(certificate), fp);
|
||||
fclose(fp);
|
||||
|
||||
/*
|
||||
* Set the authorization string and return...
|
||||
*/
|
||||
|
||||
snprintf(authstring, sizeof(authstring), "Local %s", certificate);
|
||||
|
||||
DEBUG_printf(("cups_local_auth: Returning authstring = \"%s\"\n",
|
||||
authstring));
|
||||
|
||||
return (1);
|
||||
#endif /* WIN32 || __EMX__ */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id$".
|
||||
*/
|
||||
|
||||
@@ -35,19 +35,7 @@ BANNERS = classified \
|
||||
topsecret \
|
||||
unclassified
|
||||
|
||||
CHARSETS = windows-874 \
|
||||
windows-1250 \
|
||||
windows-1251 \
|
||||
windows-1252 \
|
||||
windows-1253 \
|
||||
windows-1254 \
|
||||
windows-1255 \
|
||||
windows-1256 \
|
||||
windows-1257 \
|
||||
windows-1258 \
|
||||
koi8-r \
|
||||
koi8-u \
|
||||
iso-8859-1 \
|
||||
CHARSETS = iso-8859-1 \
|
||||
iso-8859-2 \
|
||||
iso-8859-3 \
|
||||
iso-8859-4 \
|
||||
@@ -62,7 +50,18 @@ CHARSETS = windows-874 \
|
||||
iso-8859-15 \
|
||||
koi8-r \
|
||||
koi8-u \
|
||||
utf-8
|
||||
utf-8 \
|
||||
windows-874 \
|
||||
windows-1250 \
|
||||
windows-1251 \
|
||||
windows-1252 \
|
||||
windows-1253 \
|
||||
windows-1254 \
|
||||
windows-1255 \
|
||||
windows-1256 \
|
||||
windows-1257 \
|
||||
windows-1258
|
||||
|
||||
DATAFILES = HPGLprolog psglyphs testprint.ps
|
||||
|
||||
|
||||
|
||||
@@ -53,19 +53,17 @@ DOCUMENTS = cmp.shtml idd.shtml ipp.shtml sam.shtml sdd.shtml \
|
||||
svd.shtml translation.shtml
|
||||
DOCIMAGES = images/cups-block-diagram.gif images/cups-large.gif \
|
||||
images/cups-medium.gif images/cups-small.gif
|
||||
WEBPAGES = cups.css cupsdoc.css index.html documentation.html
|
||||
WEBPAGES = cups.css cupsdoc.css index.html documentation.html \
|
||||
robots.txt
|
||||
WEBIMAGES = images/accept-jobs.gif \
|
||||
images/add-class.gif \
|
||||
images/add-printer.gif \
|
||||
images/cancel-job.gif \
|
||||
images/cancel-jobs.gif \
|
||||
images/cancel.gif \
|
||||
images/classes.gif \
|
||||
images/config-printer.gif \
|
||||
images/continue.gif \
|
||||
images/delete-class.gif \
|
||||
images/delete-printer.gif \
|
||||
images/draft.gif \
|
||||
images/hold-job.gif \
|
||||
images/left.gif \
|
||||
images/logo.gif \
|
||||
@@ -96,6 +94,7 @@ WEBIMAGES = images/accept-jobs.gif \
|
||||
#
|
||||
|
||||
all: $(DOCUMENTS:.shtml=.pdf) $(DOCUMENTS:.shtml=.html) overview.pdf
|
||||
cd de; $(MAKE) $(MFLAGS) all
|
||||
cd fr; $(MAKE) $(MFLAGS) all
|
||||
|
||||
|
||||
@@ -115,6 +114,7 @@ clean:
|
||||
$(RM) $(DOCUMENTS:.shtml=.pdf)
|
||||
$(RM) $(DOCUMENTS:.shtml=.html)
|
||||
$(RM) overview.pdf
|
||||
cd de; $(MAKE) $(MFLAGS) clean
|
||||
cd fr; $(MAKE) $(MFLAGS) clean
|
||||
|
||||
|
||||
@@ -139,6 +139,7 @@ install:
|
||||
for file in $(WEBIMAGES) $(DOCIMAGES); do \
|
||||
$(INSTALL_MAN) $$file $(DOCDIR)/images; \
|
||||
done
|
||||
cd de; $(MAKE) $(MFLAGS) install
|
||||
cd fr; $(MAKE) $(MFLAGS) install
|
||||
|
||||
|
||||
@@ -178,7 +179,7 @@ spm.ps: spm.shtml
|
||||
|
||||
sum.html: sum.shtml
|
||||
echo Formatting $@...
|
||||
$(HTMLDOC) --titleimage images/cups-large.gif -f $@ $<
|
||||
$(HTMLDOC) --verbose --titleimage images/cups-large.gif -f $@ $<
|
||||
sum.pdf: sum.shtml
|
||||
echo Formatting $@...
|
||||
$(HTMLDOC) --titleimage images/cups-large.gif --duplex --compression=9 \
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<HEAD>
|
||||
<TITLE>CUPS Configuration Management Plan</TITLE>
|
||||
<META NAME="author" CONTENT="Easy Software Products">
|
||||
<META NAME="copyright" CONTENT="Copyright 1997-2002, All Rights Reserved">
|
||||
<META NAME="copyright" CONTENT="Copyright 1997-2003, All Rights Reserved">
|
||||
<META NAME="docnumber" CONTENT="CUPS-CMP-1.1">
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso-8859-1">
|
||||
<STYLE TYPE="text/css"><!--
|
||||
@@ -24,7 +24,7 @@ PRE { font-family: monospace }
|
||||
<H1>CUPS Configuration Management Plan</H1></A><BR>
|
||||
CUPS-CMP-1.1<BR>
|
||||
Easy Software Products<BR>
|
||||
Copyright 1997-2002, All Rights Reserved<BR>
|
||||
Copyright 1997-2003, All Rights Reserved<BR>
|
||||
</CENTER>
|
||||
<HR>
|
||||
<H1 ALIGN="CENTER"><A NAME="CONTENTS">Table of Contents</A></H1>
|
||||
@@ -58,7 +58,12 @@ Copyright 1997-2002, All Rights Reserved<BR>
|
||||
<LI><A HREF="#5_1">5.1 Version Numbering</A></LI>
|
||||
<LI><A HREF="#5_2">5.2 Generation</A></LI>
|
||||
<LI><A HREF="#5_3">5.3 Testing</A></LI>
|
||||
<LI><A HREF="#5_4">5.4 Release</A></LI>
|
||||
<LI><A HREF="#5_4">5.4 Releases</A></LI>
|
||||
<UL>
|
||||
<LI><A HREF="#5_4_1">5.4.1 Beta Releases</A></LI>
|
||||
<LI><A HREF="#5_4_2">5.4.2 Release Candidates</A></LI>
|
||||
<LI><A HREF="#5_4_3">5.4.3 Production Releases</A></LI>
|
||||
</UL>
|
||||
</UL>
|
||||
<B><A HREF="#6">A Glossary</A></B>
|
||||
<UL>
|
||||
@@ -116,9 +121,9 @@ Copyright 1997-2002, All Rights Reserved<BR>
|
||||
<B><A HREF="#8">C Software Trouble Report Form</A></B><HR>
|
||||
<H1><A NAME="1">1 Scope</A></H1>
|
||||
<H2><A NAME="1_1">1.1 Identification</A></H2>
|
||||
This configuration management plan document provides the guidelines for
|
||||
development and maintenance of the Common UNIX Printing System ("CUPS")
|
||||
Version 1.1 software.
|
||||
<P>This configuration management plan document provides the guidelines
|
||||
for development and maintenance of the Common UNIX Printing System
|
||||
("CUPS") Version 1.1 software.</P>
|
||||
<H2><A NAME="1_2">1.2 System Overview</A></H2>
|
||||
<P>CUPS provides a portable printing layer for UNIX®-based operating
|
||||
systems. It has been developed by<A HREF="http://www.easysw.com"> Easy
|
||||
@@ -131,13 +136,23 @@ Copyright 1997-2002, All Rights Reserved<BR>
|
||||
also supported with reduced functionality. CUPS adds network printer
|
||||
browsing and PostScript Printer Description ("PPD") based printing
|
||||
options to support real-world printing under UNIX.</P>
|
||||
<P>CUPS also includes a customized version of GNU Ghostscript (currently
|
||||
based off GNU Ghostscript 5.50) and an image file RIP that are used to
|
||||
support non-PostScript printers. Sample drivers for HP and EPSON
|
||||
printers are included that use these filters.</P>
|
||||
<P>CUPS includes an image file RIP that supports printing of image files
|
||||
to non-PostScript printers. A customized version of GNU Ghostscript
|
||||
7.05 for CUPS called ESP Ghostscript is available separately to support
|
||||
printing of PostScript files within the CUPS driver framework. Sample
|
||||
drivers for Dymo, EPSON, HP, and OKIDATA printers are included that use
|
||||
these filters.</P>
|
||||
<P>Drivers for thousands of printers are provided with our ESP Print Pro
|
||||
software, available at:</P>
|
||||
<PRE>
|
||||
<A HREF="http://www.easysw.com/printpro/">http://www.easysw.com/printpro/</A>
|
||||
</PRE>
|
||||
<P>CUPS is licensed under the GNU General Public License and GNU Library
|
||||
General Public License. Please contact Easy Software Products for
|
||||
commercial support and "binary distribution" rights.</P>
|
||||
<H2><A NAME="1_3">1.3 Document Overview</A></H2>
|
||||
This configuration management document is organized into the following
|
||||
sections:
|
||||
<P>This configuration management document is organized into the
|
||||
following sections:</P>
|
||||
<UL>
|
||||
<LI>1 - Scope</LI>
|
||||
<LI>2 - References</LI>
|
||||
@@ -195,122 +210,173 @@ Adobe PostScript Language Reference, Third Edition.</A></LI>
|
||||
</UL>
|
||||
<H1><A NAME="3">3 File Management</A></H1>
|
||||
<H2><A NAME="3_1">3.1 Directory Structure</A></H2>
|
||||
Each source file shall be placed a sub-directory corresponding to the
|
||||
<P>Each source file shall be placed a sub-directory corresponding to the
|
||||
software sub-system it belongs to ("scheduler", "cups", etc.) To remain
|
||||
compatible with older UNIX filesystems, directory names shall not
|
||||
exceed 16 characters in length.
|
||||
exceed 16 characters in length.</P>
|
||||
<H2><A NAME="3_2">3.2 Source Files</A></H2>
|
||||
Source files shall be documented and formatted as described in Appendix
|
||||
B, Coding Requirements.
|
||||
<P>Source files shall be documented and formatted as described in
|
||||
Appendix B, Coding Requirements. To remain compatible with older UNIX
|
||||
filesystems, source file names shall not exceed 16 characters in
|
||||
length.</P>
|
||||
<H2><A NAME="3_3">3.3 Configuration Management</A></H2>
|
||||
Source files shall be placed under the control of the Concurrent
|
||||
<P>Source files shall be placed under the control of the Concurrent
|
||||
Versions System ("CVS") software. Source files shall be "checked in"
|
||||
with each change so that modifications can be tracked.
|
||||
with each change so that modifications can be tracked.</P>
|
||||
<P>Documentation on the CVS software is included with the whitepaper,
|
||||
"CVS II: Parallelizing Software Development".</P>
|
||||
<H1><A NAME="4">4 Trouble Report Processing</A></H1>
|
||||
A Software Trouble Report ("STR") shall be submitted every time a user
|
||||
or vendor experiences a problem with the CUPS software. Trouble reports
|
||||
are maintained in a database with one of the following states:
|
||||
<P>A Software Trouble Report ("STR") shall be submitted every time a
|
||||
user or vendor experiences a problem with the CUPS software. Trouble
|
||||
reports are maintained in a database with one of the following states:</P>
|
||||
<OL>
|
||||
<LI>STR is closed with complete resolution</LI>
|
||||
<LI>STR is closed without resolution</LI>
|
||||
<LI>STR is active</LI>
|
||||
<LI>STR is pending (new STR or additional information available)</LI>
|
||||
</OL>
|
||||
Trouble reports shall be processed using the following steps.
|
||||
<P>Trouble reports shall be processed using the following steps.</P>
|
||||
<H2><A NAME="4_1">4.1 Classification</A></H2>
|
||||
When a trouble report is received it must be classified at one of the
|
||||
following levels:
|
||||
<P>When a trouble report is received it must be classified at one of the
|
||||
following priority levels:</P>
|
||||
<OL>
|
||||
<LI>Request for enhancement</LI>
|
||||
<LI>Documentation error</LI>
|
||||
<LI>Unable to print a file</LI>
|
||||
<LI>Unable to print to a printer</LI>
|
||||
<LI>Unable to print at all</LI>
|
||||
<LI>Request for enhancement, e.g. asking for a feature</LI>
|
||||
<LI>Low, e.g. a documentation error or undocumented side-effect</LI>
|
||||
<LI>Moderate, e.g. unable to print a file or unable to compile the
|
||||
software</LI>
|
||||
<LI>High, e.g. unable to print to a printer or key functionality not
|
||||
working</LI>
|
||||
<LI>Critical, e.g. unable to print at all</LI>
|
||||
</OL>
|
||||
The scope of the problem should also be determined as:
|
||||
<P>Level 4 and 5 trouble reports must be resolved in the next software
|
||||
release. Level 1 to 3 trouble reports are scheduled for resolution in a
|
||||
specific release at the discretion of the release coordinator.</P>
|
||||
<P>The scope of the problem should also be determined as:</P>
|
||||
<OL>
|
||||
<LI>Specific to a machine</LI>
|
||||
<LI>Specific to a machine or printer</LI>
|
||||
<LI>Specific to an operating system</LI>
|
||||
<LI>Applies to all machines and operating systems</LI>
|
||||
<LI>Applies to all machines, printers, and operating systems</LI>
|
||||
</OL>
|
||||
<H2><A NAME="4_2">4.2 Identification</A></H2>
|
||||
Once the level and scope of the trouble report is determined the
|
||||
<P>Once the level and scope of the trouble report is determined the
|
||||
software sub-system(s) involved with the problem are determined. This
|
||||
may involve additional communication with the user or vendor to isolate
|
||||
the problem to a specific cause.
|
||||
the problem to a specific cause.</P>
|
||||
<P>When the sub-system(s) involved have been identified, an engineer
|
||||
will then determine the change(s) needed and estimate the time required
|
||||
for the change(s).</P>
|
||||
<H2><A NAME="4_3">4.3 Correction</A></H2>
|
||||
Corrections are scheduled based upon the severity and complexity of the
|
||||
problem. Once all changes have been made, documented, and tested
|
||||
<P>Corrections are scheduled based upon the severity and complexity of
|
||||
the problem. Once all changes have been made, documented, and tested
|
||||
successfully a new software release snapshot is generated. Additional
|
||||
tests are added as necessary for proper testing of the changes.
|
||||
tests are added as necessary for proper testing of the changes.</P>
|
||||
<H2><A NAME="4_4">4.4 Notification</A></H2>
|
||||
The user or vendor is notified when the fix is available or if the
|
||||
problem was caused by user error.
|
||||
<P>The user or vendor is notified when the fix is available or if the
|
||||
problem was caused by user error.</P>
|
||||
<H1><A NAME="5">5 Software Releases</A></H1>
|
||||
<H2><A NAME="5_1">5.1 Version Numbering</A></H2>
|
||||
CUPS uses a three-part version number separated by periods to represent
|
||||
the major, minor, and patch release numbers:
|
||||
<UL>
|
||||
<P>CUPS uses a three-part version number separated by periods to
|
||||
represent the major, minor, and patch release numbers:</P>
|
||||
<PRE>
|
||||
major.minor.patch
|
||||
1.1.0
|
||||
MAJOR.MINOR.PATCH
|
||||
1.1.0
|
||||
</PRE>
|
||||
</UL>
|
||||
Beta-test releases are indentified by appending the letter B followed
|
||||
by the build number:
|
||||
<UL>
|
||||
<P>Beta-test releases are indentified by appending the letter B followed
|
||||
by the build number:</P>
|
||||
<PRE>
|
||||
major.minor.patchbbuild
|
||||
1.1.0b1
|
||||
MAJOR.MINOR.PATCHbBUILD
|
||||
1.1.0b1
|
||||
</PRE>
|
||||
</UL>
|
||||
A CVS snapshot is generated for every beta and final release and uses
|
||||
<P>Release candidates are indentified by appending the letters RC
|
||||
followed by the build number:</P>
|
||||
<PRE>
|
||||
MAJOR.MINOR.PATCHrcBUILD
|
||||
1.1.0rc1
|
||||
</PRE>
|
||||
<P>A CVS snapshot is generated for every beta and final release and uses
|
||||
the version number preceded by the letter "v" and with the decimal
|
||||
points replaced by underscores:
|
||||
<UL>
|
||||
points replaced by underscores:</P>
|
||||
<PRE>
|
||||
v1_0_0b1
|
||||
v1_0_0
|
||||
v1_1_0b1
|
||||
v1_1_0rc1
|
||||
v1_1_0
|
||||
</PRE>
|
||||
</UL>
|
||||
Each change that corrects a fault in a software sub-system increments
|
||||
the patch release number. If a change affects the software design of
|
||||
CUPS then the minor release number will be incremented and the patch
|
||||
release number reset to 0. If CUPS is completely redesigned the major
|
||||
release number will be incremented and the minor and patch release
|
||||
numbers reset to 0:
|
||||
<UL>
|
||||
<P>Each change that corrects a fault in a software sub-system increments
|
||||
the patch release number. If a change affects the overall software
|
||||
design of CUPS then the minor release number will be incremented and
|
||||
the patch release number reset to 0. If CUPS is completely redesigned
|
||||
the major release number will be incremented and the minor and patch
|
||||
release numbers reset to 0:</P>
|
||||
<PRE>
|
||||
1.1.0b1 First beta release
|
||||
1.1.0b2 Second beta release
|
||||
1.1.0 First production release
|
||||
1.1.1b1 First beta of 1.1.1
|
||||
1.1.1 Production release of 1.1.1
|
||||
1.1.1b1 First beta of 1.1.1
|
||||
1.1.1 Production release of 1.1.1
|
||||
2.0.0b1 First beta of 2.0.0
|
||||
2.0.0 Production release of 2.0.0
|
||||
1.1.0b1 First beta release
|
||||
1.1.0b2 Second beta release
|
||||
1.1.0rc1 First release candidate
|
||||
1.1.0rc2 Second release candidate
|
||||
1.1.0 First production release
|
||||
1.1.1b1 First beta of 1.1.1
|
||||
1.1.1rc1 First release candidate of 1.1.1
|
||||
1.1.1 Production release of 1.1.1
|
||||
1.1.2b1 First beta of 1.1.2
|
||||
1.1.2rc1 First release candidate of 1.1.2
|
||||
1.1.2 Production release of 1.1.2
|
||||
2.0.0b1 First beta of 2.0.0
|
||||
2.0.0rc1 First release candidate of 2.0.0
|
||||
2.0.0 Production release of 2.0.0
|
||||
</PRE>
|
||||
</UL>
|
||||
<H2><A NAME="5_2">5.2 Generation</A></H2>
|
||||
Software releases shall be generated for each successfully completed
|
||||
<P>Software releases shall be generated for each successfully completed
|
||||
software trouble report. All object and executable files shall be
|
||||
deleted prior to performing a full build to ensure that source files
|
||||
are recompiled.
|
||||
are recompiled.</P>
|
||||
<H2><A NAME="5_3">5.3 Testing</A></H2>
|
||||
Software testing shall be conducted according to the CUPS Software Test
|
||||
Plan, CUPS-STP-1.1. Failed tests cause STRs to be generated to correct
|
||||
the problems found.
|
||||
<H2><A NAME="5_4">5.4 Release</A></H2>
|
||||
When testing has been completed successfully a new distribution image
|
||||
is created from the current CVS code "snapshot". No production release
|
||||
shall contain software that has not passed the appropriate software
|
||||
tests.
|
||||
<P>Software testing shall be conducted according to the CUPS Software
|
||||
Test Plan, CUPS-STP-1.1. Failed tests cause STRs to be generated to
|
||||
correct the problems found.</P>
|
||||
<H2><A NAME="5_4">5.4 Releases</A></H2>
|
||||
<P>When testing has been completed successfully a new distribution image
|
||||
is created from the current CVS code "snapshot". No release shall
|
||||
contain software that has not passed the appropriate software tests.
|
||||
Three types of releases are used, beta, release candidate, and
|
||||
production, and are released using the following basic schedule:
|
||||
<CENTER>
|
||||
<TABLE BORDER="1">
|
||||
<TR><TH>Week</TH><TH>Version</TH><TH>Description</TH></TR>
|
||||
<TR><TD>T-6 weeks</TD><TD>1.1.0b1</TD><TD>First beta</TD></TR>
|
||||
<TR><TD>T-5 weeks</TD><TD>1.1.0b2</TD><TD>Second beta</TD></TR>
|
||||
<TR><TD>T-4 weeks</TD><TD>1.1.0b3</TD><TD>Third beta</TD></TR>
|
||||
<TR><TD>T-3 weeks</TD><TD>1.1.0rc1</TD><TD>First release candidate</TD></TR>
|
||||
<TR><TD>T-2 weeks</TD><TD>1.1.0rc2</TD><TD>Second release candidate</TD></TR>
|
||||
<TR><TD>T-0 weeks</TD><TD>1.1.0</TD><TD>Production</TD></TR>
|
||||
</TABLE>
|
||||
</CENTER>
|
||||
</P>
|
||||
<P>Beta releases are typically used prior to new major and minor version
|
||||
releases. At least one release candidate is generated prior to each
|
||||
production release.</P>
|
||||
<H3><A NAME="5_4_1">5.4.1 Beta Releases</A></H3>
|
||||
<P>Beta releases are generated when substantial changes have been made
|
||||
that may affect the reliability of the software. Beta releases may
|
||||
cause loss of data, functionality, or services and are provided for
|
||||
testing by qualified individuals.</P>
|
||||
<P>Beta releases are an OPTIONAL part of the release process and are
|
||||
generated as deemed appropriate by the release coordinator. Functional
|
||||
changes may be included in subsequent beta releases until the first
|
||||
release candidate.</P>
|
||||
<H3><A NAME="5_4_2">5.4.2 Release Candidates</A></H3>
|
||||
<P>Release candidates are generated at least two weeks prior to a
|
||||
production release. Release candidates are targeted for end-users that
|
||||
wish to test new functionality or bug fixes prior to the production
|
||||
release. While release candidates are intended to be substantially
|
||||
bug-free, they may still contain defects and/or not compile on specific
|
||||
platforms.</P>
|
||||
<P>At least one release candidate is REQUIRED prior to any production
|
||||
release. The distribution of a release candidate marks the end of any
|
||||
functional improvements. Release candidates are generated at weekly
|
||||
intervals until all level 4/5 trouble reports are resolved.</P>
|
||||
<H3><A NAME="5_4_3">5.4.3 Production Releases</A></H3>
|
||||
<P>Production releases are generated after a successful release
|
||||
candidate and represent a stable release of the software suitable for
|
||||
all users.</P>
|
||||
<H1 TYPE="A" VALUE="1"><A NAME="6">A Glossary</A></H1>
|
||||
<H2><A NAME="6_1">A.1 Terms</A></H2>
|
||||
<DL>
|
||||
@@ -359,323 +425,320 @@ v1_0_0
|
||||
<DD>Trivial File Transfer Protocol</DD>
|
||||
</DL>
|
||||
<H1><A NAME="7">B Coding Requirements</A></H1>
|
||||
These coding requirements provide detailed information on source file
|
||||
<P>These coding requirements provide detailed information on source file
|
||||
formatting and documentation content. These guidelines shall be applied
|
||||
to all C and C++ source files provided with CUPS.
|
||||
to all C and C++ source files provided with CUPS. Source code for other
|
||||
languages should conform to these requirements as allowed by the
|
||||
language.</P>
|
||||
<H2><A NAME="7_1">B.1 Source Files</A></H2>
|
||||
<H3><A NAME="7_1_1">B.1.1 Naming</A></H3>
|
||||
All source files names shall be 16 characters or less in length to
|
||||
<P>All source files names shall be 16 characters or less in length to
|
||||
ensure compatibility with older UNIX filesystems. Source files
|
||||
containing functions shall have an extension of ".c" for ANSI C and
|
||||
".cxx" for C++ source files. All other "include" files shall have an
|
||||
extension of ".h".
|
||||
extension of ".h".</P>
|
||||
<H3><A NAME="7_1_2">B.1.2 Documentation</A></H3>
|
||||
The top of each source file shall contain a header giving the name of
|
||||
<P>The top of each source file shall contain a header giving the name of
|
||||
the file, the purpose or nature of the source file, the copyright and
|
||||
licensing notice, and the functions contained in the file. The file
|
||||
name and revision information is provided by the CVS "$Id$" tag:
|
||||
<UL>
|
||||
name and revision information is provided by the CVS "$Id$" tag:</P>
|
||||
<PRE>
|
||||
/*
|
||||
* "$Id$"
|
||||
*
|
||||
* Description of file contents.
|
||||
*
|
||||
* Copyright 1997-2003 by Easy Software Products, all rights
|
||||
* reserved.
|
||||
*
|
||||
* These coded instructions, statements, and computer programs are
|
||||
* the property of Easy Software Products and are protected by
|
||||
* Federal copyright law. Distribution and use rights are outlined
|
||||
* in the file "LICENSE.txt" which should have been included with
|
||||
* this file. If this file is missing or damaged please contact
|
||||
* Easy Software Products at:
|
||||
*
|
||||
* Attn: CUPS Licensing Information
|
||||
* Easy Software Products
|
||||
* 44141 Airport View Drive, Suite 204
|
||||
* Hollywood, Maryland 20636-3111 USA
|
||||
*
|
||||
* Voice: (301) 373-9600
|
||||
* EMail: cups-info@cups.org
|
||||
* WWW: http://www.cups.org
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* function1() - Description 1.
|
||||
* function2() - Description 2.
|
||||
* function3() - Description 3.
|
||||
*/
|
||||
/*
|
||||
* "$Id$"
|
||||
*
|
||||
* Description of file contents.
|
||||
*
|
||||
* Copyright 1997-2003 by Easy Software Products, all rights
|
||||
* reserved.
|
||||
*
|
||||
* These coded instructions, statements, and computer programs are
|
||||
* the property of Easy Software Products and are protected by
|
||||
* Federal copyright law. Distribution and use rights are outlined
|
||||
* in the file "LICENSE.txt" which should have been included with
|
||||
* this file. If this file is missing or damaged please contact
|
||||
* Easy Software Products at:
|
||||
*
|
||||
* Attn: CUPS Licensing Information
|
||||
* Easy Software Products
|
||||
* 44141 Airport View Drive, Suite 204
|
||||
* Hollywood, Maryland 20636-3111 USA
|
||||
*
|
||||
* Voice: (301) 373-9600
|
||||
* EMail: cups-info@cups.org
|
||||
* WWW: http://www.cups.org
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* function1() - Description 1.
|
||||
* function2() - Description 2.
|
||||
* function3() - Description 3.
|
||||
*/
|
||||
</PRE>
|
||||
</UL>
|
||||
The bottom of each source file shall contain a trailer giving the name
|
||||
of the file using the CVS "$Id$" tag. The primary purpose of this is to
|
||||
mark the end of a source file; if the trailer is missing it is possible
|
||||
that code has been lost near the end of the file:
|
||||
<UL>
|
||||
|
||||
<!-- NEED 1in -->
|
||||
<P>For source files that are subject to the Apple OS-Developed Software
|
||||
exception, the following additional comment should appear after the
|
||||
contact information:</P>
|
||||
<PRE>
|
||||
/*
|
||||
* End of "$Id$".
|
||||
*/
|
||||
* This file is subject to the Apple OS-Developed Software exception.
|
||||
</PRE>
|
||||
<P>The bottom of each source file shall contain a trailer giving the
|
||||
name of the file using the CVS "$Id$" tag. The primary purpose of this
|
||||
is to mark the end of a source file; if the trailer is missing it is
|
||||
possible that code has been lost near the end of the file:</P>
|
||||
<PRE>
|
||||
/*
|
||||
* End of "$Id$".
|
||||
*/
|
||||
</PRE>
|
||||
</UL>
|
||||
<H2><A NAME="7_2">B.2 Functions</A></H2>
|
||||
<H3><A NAME="7_2_1">B.2.1 Naming</A></H3>
|
||||
Functions with a global scope shall be capitalized ("DoThis", "DoThat",
|
||||
"DoSomethingElse", etc.) The only exception to this rule shall be the
|
||||
CUPS interface library functions which may begin with a prefix word in
|
||||
lowercase ("cupsDoThis", "cupsDoThat", etc.)
|
||||
<P>Functions with a global scope shall be capitalized ("DoThis",
|
||||
"DoThat", "DoSomethingElse", etc.) The only exception to this rule
|
||||
shall be the CUPS interface library functions which may begin with a
|
||||
prefix word in lowercase ("cupsDoThis", "cupsDoThat", etc.)</P>
|
||||
<P>Functions with a local scope shall be declared "static" and be
|
||||
lowercase with underscores between words ("do_this", "do_that",
|
||||
"do_something_else", etc.)</P>
|
||||
<H3><A NAME="7_2_2">B.2.2 Documentation</A></H3>
|
||||
Each function shall begin with a comment header describing what the
|
||||
<P>Each function shall begin with a comment header describing what the
|
||||
function does, the possible input limits (if any), and the possible
|
||||
output values (if any), and any special information needed:
|
||||
<UL>
|
||||
output values (if any), and any special information needed:</P>
|
||||
<PRE>
|
||||
/*
|
||||
* 'do_this()' - Compute y = this(x).
|
||||
*
|
||||
* Notes: none.
|
||||
*/
|
||||
/*
|
||||
* 'do_this()' - Compute y = this(x).
|
||||
*
|
||||
* Notes: none.
|
||||
*/
|
||||
|
||||
static float /* O - Inverse power value, 0.0 <= y <= 1.1 */
|
||||
do_this(float x) /* I - Power value (0.0 <= x <= 1.1) */
|
||||
{
|
||||
...
|
||||
return (y);
|
||||
}
|
||||
static float /* O - Inverse power value, 0.0 <= y <= 1.1 */
|
||||
do_this(float x) /* I - Power value (0.0 <= x <= 1.1) */
|
||||
{
|
||||
...
|
||||
return (y);
|
||||
}
|
||||
</PRE>
|
||||
</UL>
|
||||
<P>Return/output values are indicated using an "O" prefix, input values
|
||||
are indicated using the "I" prefix, and values that are both input and
|
||||
output use the "IO" prefix for the corresponding in-line comment.</P>
|
||||
<H2><A NAME="7_3">B.3 Methods</A></H2>
|
||||
<H3><A NAME="7_3_1">B.3.1 Naming</A></H3>
|
||||
Methods shall be in lowercase with underscores between words
|
||||
("do_this", "do_that", "do_something_else", etc.)
|
||||
<P>Methods shall be in lowercase with underscores between words
|
||||
("do_this", "do_that", "do_something_else", etc.)</P>
|
||||
<H3><A NAME="7_3_2">B.3.2 Documentation</A></H3>
|
||||
Each method shall begin with a comment header describing what the
|
||||
<P>Each method shall begin with a comment header describing what the
|
||||
method does, the possible input limits (if any), and the possible
|
||||
output values (if any), and any special information needed:
|
||||
<UL>
|
||||
output values (if any), and any special information needed:</P>
|
||||
<PRE>
|
||||
/*
|
||||
* 'class::do_this()' - Compute y = this(x).
|
||||
*
|
||||
* Notes: none.
|
||||
*/
|
||||
/*
|
||||
* 'class::do_this()' - Compute y = this(x).
|
||||
*
|
||||
* Notes: none.
|
||||
*/
|
||||
|
||||
float /* O - Inverse power value, 0.0 <= y <= 1.0 */
|
||||
class::do_this(float x) /* I - Power value (0.0 <= x <= 1.0) */
|
||||
{
|
||||
...
|
||||
return (y);
|
||||
}
|
||||
float /* O - Inverse power value, 0.0 <= y <= 1.0 */
|
||||
class::do_this(float x) /* I - Power value (0.0 <= x <= 1.0) */
|
||||
{
|
||||
...
|
||||
return (y);
|
||||
}
|
||||
</PRE>
|
||||
</UL>
|
||||
<P>Return/output values are indicated using an "O" prefix, input values
|
||||
are indicated using the "I" prefix, and values that are both input and
|
||||
output use the "IO" prefix for the corresponding in-line comment.</P>
|
||||
<H2><A NAME="7_4">B.4 Variables</A></H2>
|
||||
<H3><A NAME="7_4_1">B.4.1 Naming</A></H3>
|
||||
Variables with a global scope shall be capitalized ("ThisVariable",
|
||||
<P>Variables with a global scope shall be capitalized ("ThisVariable",
|
||||
"ThatVariable", "ThisStateVariable", etc.) The only exception to this
|
||||
rule shall be the CUPS interface library global variables which must
|
||||
begin with the prefix "cups" ("cupsThisVariable", "cupsThatVariable",
|
||||
etc.) Global variables shall be replaced by function arguments whenever
|
||||
possible.
|
||||
possible.</P>
|
||||
<P>Variables with a local scope shall be lowercase with underscores
|
||||
between words ("this_variable", "that_variable", etc.) Any local
|
||||
variables shared by functions within a source file shall be declared
|
||||
"static".</P>
|
||||
<H3><A NAME="7_4_2">B.4.2 Documentation</A></H3>
|
||||
Each variable shall be declared on a separate line and shall be
|
||||
immediately followed by a comment block describing the variable:
|
||||
<UL>
|
||||
<P>Each variable shall be declared on a separate line and shall be
|
||||
immediately followed by a comment block describing the variable:</P>
|
||||
<PRE>
|
||||
int this_variable; /* The current state of this */
|
||||
int that_variable; /* The current state of that */
|
||||
int this_variable; /* The current state of this */
|
||||
int that_variable; /* The current state of that */
|
||||
</PRE>
|
||||
</UL>
|
||||
<H2><A NAME="7_5">B.5 Types</A></H2>
|
||||
<H3><A NAME="7_5_1">B.5.1 Naming</A></H3>
|
||||
All type names shall be lowercase with underscores between words and
|
||||
<P>All type names shall be lowercase with underscores between words and
|
||||
"_t" appended to the end of the name ("this_type_t", "that_type_t",
|
||||
etc.)
|
||||
etc.)</P>
|
||||
<H3><A NAME="7_5_2">B.5.2 Documentation</A></H3>
|
||||
Each type shall have a comment block immediately before the typedef:
|
||||
<UL>
|
||||
<P>Each type shall have a comment block immediately before the typedef:</P>
|
||||
<PRE>
|
||||
/*
|
||||
* This type is for CUPS foobar options.
|
||||
*/
|
||||
typedef int cups_this_type_t;
|
||||
/*
|
||||
* This type is for CUPS foobar options.
|
||||
*/
|
||||
typedef int cups_this_type_t;
|
||||
</PRE>
|
||||
</UL>
|
||||
<H2><A NAME="7_6">B.6 Structures</A></H2>
|
||||
<H3><A NAME="7_6_1">B.6.1 Naming</A></H3>
|
||||
All structure names shall be lowercase with underscores between words
|
||||
<P>All structure names shall be lowercase with underscores between words
|
||||
and "_str" appended to the end of the name ("this_struct_str",
|
||||
"that_struct_str", etc.)
|
||||
"that_struct_str", etc.)</P>
|
||||
<H3><A NAME="7_6_2">B.6.2 Documentation</A></H3>
|
||||
Each structure shall have a comment block immediately before the struct
|
||||
and each member shall be documented in accordance with the variable
|
||||
naming policy above:
|
||||
<UL>
|
||||
<P>Each structure shall have a comment block immediately before the
|
||||
struct and each member shall be documented in accordance with the
|
||||
variable naming policy above:</P>
|
||||
<PRE>
|
||||
/*
|
||||
* This structure is for CUPS foobar options.
|
||||
*/
|
||||
struct cups_this_struct_str
|
||||
{
|
||||
int this_member; /* Current state for this */
|
||||
int that_member; /* Current state for that */
|
||||
};
|
||||
/*
|
||||
* This structure is for CUPS foobar options.
|
||||
*/
|
||||
struct cups_this_struct_str
|
||||
{
|
||||
int this_member; /* Current state for this */
|
||||
int that_member; /* Current state for that */
|
||||
};
|
||||
</PRE>
|
||||
</UL>
|
||||
<H2><A NAME="7_7">B.7 Classes</A></H2>
|
||||
<H3><A NAME="7_7_1">B.7.1 Naming</A></H3>
|
||||
All class names shall be lowercase with underscores between words
|
||||
("this_class", "that_class", etc.)
|
||||
<P>All class names shall be lowercase with underscores between words
|
||||
("this_class", "that_class", etc.)</P>
|
||||
<H3><A NAME="7_7_2">B.7.2 Documentation</A></H3>
|
||||
Each class shall have a comment block immediately before the class and
|
||||
each member shall be documented in accordance with the variable naming
|
||||
policy above:
|
||||
<UL>
|
||||
<P>Each class shall have a comment block immediately before the class
|
||||
and each member shall be documented in accordance with the variable
|
||||
naming policy above:</P>
|
||||
<PRE>
|
||||
/*
|
||||
* This class is for CUPS foobar options.
|
||||
*/
|
||||
class cups_this_class
|
||||
{
|
||||
int this_member; /* Current state for this */
|
||||
int that_member; /* Current state for that */
|
||||
};
|
||||
/*
|
||||
* This class is for CUPS foobar options.
|
||||
*/
|
||||
class cups_this_class
|
||||
{
|
||||
int this_member; /* Current state for this */
|
||||
int that_member; /* Current state for that */
|
||||
};
|
||||
</PRE>
|
||||
</UL>
|
||||
<H2><A NAME="7_8">B.8 Constants</A></H2>
|
||||
<H3><A NAME="7_8_1">B.8.1 Naming</A></H3>
|
||||
All constant names shall be uppercase with underscored between words
|
||||
<P>All constant names shall be uppercase with underscored between words
|
||||
("THIS_CONSTANT", "THAT_CONSTANT", etc.) Constants defined for the CUPS
|
||||
interface library must begin with an uppercase prefix
|
||||
("CUPS_THIS_CONSTANT", "CUPS_THAT_CONSTANT", etc.)
|
||||
("CUPS_THIS_CONSTANT", "CUPS_THAT_CONSTANT", etc.)</P>
|
||||
<P>Typed enumerations shall be used whenever possible to allow for type
|
||||
checking by the compiler.</P>
|
||||
<H3><A NAME="7_8_2">B.8.2 Documentation</A></H3>
|
||||
Comment blocks shall immediately follow each constant:
|
||||
<UL>
|
||||
<P>Comment blocks shall immediately follow each constant:</P>
|
||||
<PRE>
|
||||
enum
|
||||
{
|
||||
CUPS_THIS_TRAY, /* This tray */
|
||||
CUPS_THAT_TRAY /* That tray */
|
||||
};
|
||||
enum
|
||||
{
|
||||
CUPS_THIS_TRAY, /* This tray */
|
||||
CUPS_THAT_TRAY /* That tray */
|
||||
};
|
||||
</PRE>
|
||||
</UL>
|
||||
<H2><A NAME="7_9">B.9 Code</A></H2>
|
||||
<H3><A NAME="7_9_1">B.9.1 Documentation</A></H3>
|
||||
All source code shall utilize block comments within functions to
|
||||
describe the operations being performed by a group of statements:
|
||||
<UL>
|
||||
<P>All source code shall utilize block comments within functions to
|
||||
describe the operations being performed by a group of statements:</P>
|
||||
<PRE>
|
||||
/*
|
||||
* Clear the state array before we begin...
|
||||
*/
|
||||
/*
|
||||
* Clear the state array before we begin...
|
||||
*/
|
||||
|
||||
for (i = 0; i < (sizeof(array) / sizeof(sizeof(array[0])); i ++)
|
||||
array[i] = STATE_IDLE;
|
||||
for (i = 0; i < (sizeof(array) / sizeof(sizeof(array[0])); i ++)
|
||||
array[i] = STATE_IDLE;
|
||||
|
||||
/*
|
||||
* Wait for state changes...
|
||||
*/
|
||||
/*
|
||||
* Wait for state changes...
|
||||
*/
|
||||
|
||||
do
|
||||
{
|
||||
for (i = 0; i < (sizeof(array) / sizeof(sizeof(array[0])); i ++)
|
||||
if (array[i] != STATE_IDLE)
|
||||
break;
|
||||
do
|
||||
{
|
||||
for (i = 0; i < (sizeof(array) / sizeof(sizeof(array[0])); i ++)
|
||||
if (array[i] != STATE_IDLE)
|
||||
break;
|
||||
|
||||
if (i == (sizeof(array) / sizeof(array[0])))
|
||||
sleep(1);
|
||||
} while (i == (sizeof(array) / sizeof(array[0])));
|
||||
if (i == (sizeof(array) / sizeof(array[0])))
|
||||
sleep(1);
|
||||
} while (i == (sizeof(array) / sizeof(array[0])));
|
||||
</PRE>
|
||||
</UL>
|
||||
<H3><A NAME="7_9_2">B.9.2 Style</A></H3>
|
||||
<H4 TYPE="a">B.9.2.a Indentation</H4>
|
||||
All code blocks enclosed by brackets shall begin with the opening brace
|
||||
on a new line. The code then follows starting on a new line after the
|
||||
brace and is indented 2 spaces. The closing brace is then placed on a
|
||||
new line following the code at the original indentation:
|
||||
<UL>
|
||||
<P>All code blocks enclosed by brackets shall begin with the opening
|
||||
brace on a new line. The code then follows starting on a new line after
|
||||
the brace and is indented 2 spaces. The closing brace is then placed on
|
||||
a new line following the code at the original indentation:</P>
|
||||
<PRE>
|
||||
{
|
||||
int i; /* Looping var */
|
||||
{
|
||||
int i; /* Looping var */
|
||||
|
||||
/*
|
||||
* Process foobar values from 0 to 999...
|
||||
*/
|
||||
/*
|
||||
* Process foobar values from 0 to 999...
|
||||
*/
|
||||
|
||||
for (i = 0; i < 1000; i ++)
|
||||
{
|
||||
do_this(i);
|
||||
do_that(i);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 1000; i ++)
|
||||
{
|
||||
do_this(i);
|
||||
do_that(i);
|
||||
}
|
||||
}
|
||||
</PRE>
|
||||
</UL>
|
||||
Single-line statements following "do", "else", "for", "if", and "while"
|
||||
shall be indented 2 spaces as well. Blocks of code in a "switch" block
|
||||
shall be indented 4 spaces after each "case" and "default" case:
|
||||
<UL>
|
||||
<P>Single-line statements following "do", "else", "for", "if", and
|
||||
"while" shall be indented 2 spaces as well. Blocks of code in a
|
||||
"switch" block shall be indented 4 spaces after each "case" and
|
||||
"default" case:</P>
|
||||
<PRE>
|
||||
switch (array[i])
|
||||
{
|
||||
case STATE_IDLE :
|
||||
do_this(i);
|
||||
do_that(i);
|
||||
break;
|
||||
default :
|
||||
do_nothing(i);
|
||||
break;
|
||||
}
|
||||
switch (array[i])
|
||||
{
|
||||
case STATE_IDLE :
|
||||
do_this(i);
|
||||
do_that(i);
|
||||
break;
|
||||
default :
|
||||
do_nothing(i);
|
||||
break;
|
||||
}
|
||||
</PRE>
|
||||
</UL>
|
||||
<H4>B.9.2.b Spacing</H4>
|
||||
A space shall follow each reserved word ("if", "while", etc.) Spaces
|
||||
<P>A space shall follow each reserved word ("if", "while", etc.) Spaces
|
||||
shall not be inserted between a function name and the arguments in
|
||||
parenthesis.
|
||||
parenthesis.</P>
|
||||
<H4>B.9.2.c Return Values</H4>
|
||||
Parenthesis shall surround values returned from a function using
|
||||
"return":
|
||||
<UL>
|
||||
<P>Parenthesis shall surround values returned from a function using
|
||||
"return":</P>
|
||||
<PRE>
|
||||
return (STATE_IDLE);
|
||||
return (STATE_IDLE);
|
||||
</PRE>
|
||||
</UL>
|
||||
<H4>B.9.2.d Loops</H4>
|
||||
Whenever convenient loops should count downward to zero to improve
|
||||
program performance:
|
||||
<UL>
|
||||
<P>Whenever convenient loops should count downward to zero to improve
|
||||
program performance:</P>
|
||||
<PRE>
|
||||
for (i = sizeof(array) / sizeof(array[0]) - 1; i >= 0; i --)
|
||||
array[i] = STATE_IDLE;
|
||||
for (i = sizeof(array) / sizeof(array[0]) - 1; i >= 0; i --)
|
||||
array[i] = STATE_IDLE;
|
||||
</PRE>
|
||||
</UL>
|
||||
<H1 ALIGN="RIGHT"><A NAME="8">C Software Trouble Report Form</A></H1>
|
||||
<CENTER>
|
||||
<TABLE WIDTH="80%">
|
||||
<TR><TH ALIGN="RIGHT">Summary of Problem:</TH><TD ALIGN="LEFT">
|
||||
________________________________________</TD></TR>
|
||||
<TR><TH ALIGN="RIGHT">Problem Severity:</TH><TD ALIGN="LEFT">__1=RFE
|
||||
<BR> __2=Documentation-Error
|
||||
<BR> __3=Unable-to-Print-a-File
|
||||
<BR> __4=Unable-to-Print-to-a-Printer
|
||||
<BR> __5=Unable-to-Print-at-All</TD></TR>
|
||||
<TR><TH ALIGN="RIGHT">Problem Scope:</TH><TD ALIGN="LEFT">__1=Machine
|
||||
__2=Operating-System __3=All</TD></TR>
|
||||
<TR><TH ALIGN="RIGHT">Summary of Problem:</TH><TD COLSPAN="2">
|
||||
_____________________________________________</TD></TR>
|
||||
<TR><TD COLSPAN="3"> </TD></TR>
|
||||
<TR><TH ALIGN="RIGHT" ROWSPAN="5" VALIGN="TOP">Problem Severity:</TH><TD>
|
||||
__1</TD><TD>Request for enhancement, e.g. asking for a feature</TD></TR>
|
||||
<TR><TD>__2</TD><TD>Low, e.g. a documentation error or undocumented
|
||||
side-effect</TD></TR>
|
||||
<TR><TD>__3</TD><TD>Moderate, e.g. unable to print a file or unable to
|
||||
compile the software</TD></TR>
|
||||
<TR><TD>__4</TD><TD>High, e.g. unable to print to a printer or key
|
||||
functionality not working</TD></TR>
|
||||
<TR><TD>__5</TD><TD>Critical, e.g. unable to print at all</TD></TR>
|
||||
<TR><TD COLSPAN="3"> </TD></TR>
|
||||
<TR><TH ALIGN="RIGHT" ROWSPAN="3" VALIGN="TOP">Problem Scope:</TH><TD>
|
||||
__1</TD><TD>Machine or printer</TD></TR>
|
||||
<TR><TD>__2</TD><TD>Operating System</TD></TR>
|
||||
<TR><TD>__3</TD><TD>All machines, printers, or operating systems</TD></TR>
|
||||
<TR><TD COLSPAN="3"> </TD></TR>
|
||||
<TR><TH ALIGN="RIGHT" VALIGN="TOP">Detailed Description of Problem:</TH><TD
|
||||
ALIGN="LEFT">________________________________________
|
||||
<BR> ________________________________________
|
||||
<BR> ________________________________________
|
||||
<BR> ________________________________________
|
||||
<BR> ________________________________________
|
||||
<BR> ________________________________________</TD></TR>
|
||||
COLSPAN="2">_____________________________________________
|
||||
<BR> _____________________________________________
|
||||
<BR> _____________________________________________
|
||||
<BR> _____________________________________________
|
||||
<BR> _____________________________________________</TD></TR>
|
||||
</TABLE>
|
||||
</CENTER>
|
||||
</BODY>
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
#
|
||||
# "$Id$"
|
||||
#
|
||||
# Documentation makefile for the Common UNIX Printing System (CUPS).
|
||||
#
|
||||
# Copyright 1993-2003 by Easy Software Products.
|
||||
#
|
||||
# These coded instructions, statements, and computer programs are the
|
||||
# property of Easy Software Products and are protected by Federal
|
||||
# copyright law. Distribution and use rights are outlined in the file
|
||||
# "LICENSE.txt" which should have been included with this file. If this
|
||||
# file is missing or damaged please contact Easy Software Products
|
||||
# at:
|
||||
#
|
||||
# Attn: CUPS Licensing Information
|
||||
# Easy Software Products
|
||||
# 44141 Airport View Drive, Suite 204
|
||||
# Hollywood, Maryland 20636-3111 USA
|
||||
#
|
||||
# Voice: (301) 373-9600
|
||||
# EMail: cups-info@cups.org
|
||||
# WWW: http://www.cups.org
|
||||
#
|
||||
|
||||
include ../../Makedefs
|
||||
|
||||
#
|
||||
# Document files...
|
||||
#
|
||||
|
||||
WEBPAGES = index.html documentation.html
|
||||
WEBIMAGES = images/accept-jobs.gif \
|
||||
images/add-class.gif \
|
||||
images/add-printer.gif \
|
||||
images/cancel-job.gif \
|
||||
images/config-printer.gif \
|
||||
images/continue.gif \
|
||||
images/delete-class.gif \
|
||||
images/delete-printer.gif \
|
||||
images/hold-job.gif \
|
||||
images/manage-classes.gif \
|
||||
images/manage-jobs.gif \
|
||||
images/manage-printers.gif \
|
||||
images/modify-class.gif \
|
||||
images/modify-printer.gif \
|
||||
images/navbar.gif \
|
||||
images/print-test-page.gif \
|
||||
images/reject-jobs.gif \
|
||||
images/release-job.gif \
|
||||
images/restart-job.gif \
|
||||
images/show-active.gif \
|
||||
images/show-completed.gif \
|
||||
images/start-class.gif \
|
||||
images/start-printer.gif \
|
||||
images/stop-class.gif \
|
||||
images/stop-printer.gif
|
||||
|
||||
|
||||
#
|
||||
# Make all documents...
|
||||
#
|
||||
|
||||
all:
|
||||
|
||||
|
||||
#
|
||||
# Remove all generated files...
|
||||
#
|
||||
|
||||
clean:
|
||||
|
||||
|
||||
#
|
||||
# Install all documentation files...
|
||||
#
|
||||
|
||||
install:
|
||||
$(INSTALL_DIR) $(DOCDIR)/de
|
||||
for file in $(WEBPAGES); do \
|
||||
$(INSTALL_MAN) $$file $(DOCDIR)/de; \
|
||||
done
|
||||
$(INSTALL_DIR) $(DOCDIR)/de/images
|
||||
for file in $(WEBIMAGES); do \
|
||||
$(INSTALL_MAN) $$file $(DOCDIR)/de/images; \
|
||||
done
|
||||
|
||||
|
||||
#
|
||||
# End of Makefile.
|
||||
#
|
||||
@@ -0,0 +1,81 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Dokumentation - Common UNIX Printing System</TITLE>
|
||||
<LINK REL=STYLESHEET TYPE="text/css" HREF="cups.css">
|
||||
<MAP NAME="navbar">
|
||||
<AREA SHAPE="RECT" COORDS="12,10,50,20" HREF="http://www.easysw.com" ALT="Easy Software Produkt-Homepage">
|
||||
<AREA SHAPE="RECT" COORDS="82,10,226,20" HREF="admin" ALT="Einrichtungsaufgaben">
|
||||
<AREA SHAPE="RECT" COORDS="235,10,403,20" HREF="classes" ALT="Druckerklassen verwalten">
|
||||
<AREA SHAPE="RECT" COORDS="412,10,488,20" HREF="documentation.html" ALT="Online Hilfe">
|
||||
<AREA SHAPE="RECT" COORDS="497,10,590,20" HREF="jobs" ALT="Druckaufträge">
|
||||
<AREA SHAPE="RECT" COORDS="599,10,717,20" HREF="printers" ALT="Drucker verwalten">
|
||||
<AREA SHAPE="RECT" COORDS="726,10,887,20" HREF="http://www.cups.org" ALT="Aktuelle CUPS Software">
|
||||
</MAP>
|
||||
</HEAD>
|
||||
|
||||
<BODY BGCOLOR="#cccc99" TEXT="#000000" LINK="#0000FF" VLINK="#FF00FF">
|
||||
<CENTER>
|
||||
<IMG SRC="/images/navbar.gif" WIDTH="902" HEIGHT="30" USEMAP="#navbar" BORDER="0" ALT="Common UNIX Printing System">
|
||||
</CENTER>
|
||||
|
||||
<H1>Dokumentation</H1>
|
||||
|
||||
Folgende Dokumentation für CUPS ist auf diesem Server verfügbar:
|
||||
|
||||
<UL>
|
||||
|
||||
<LI>Whitepaper - Ein Überblick über das Common UNIX Printing System (
|
||||
<A HREF="overview.html">HTML</A> |
|
||||
<A HREF="overview.pdf">PDF</A> )
|
||||
|
||||
<LI>Software Benutzerhandbuch (
|
||||
<A HREF="sum.html">HTML</A> |
|
||||
<A HREF="sum.pdf">PDF</A> )
|
||||
|
||||
<LI>Software Administratorhandbuch (
|
||||
<A HREF="sam.html">HTML</A> |
|
||||
<A HREF="sam.pdf">PDF</A> )
|
||||
|
||||
<LI>Software Programmiererhandbuch (
|
||||
<A HREF="spm.html">HTML</A> |
|
||||
<A HREF="spm.pdf">PDF</A> )
|
||||
|
||||
<LI>Entwicklungsmanagement (
|
||||
<A HREF="cmp.html">HTML</A> |
|
||||
<A HREF="cmp.pdf">PDF</A> )
|
||||
|
||||
<LI>CUPS Implementation des IPP (
|
||||
<A HREF="ipp.html">HTML</A> |
|
||||
<A HREF="ipp.pdf">PDF</A> )
|
||||
|
||||
<LI>Schnittstellenbeschreibung (
|
||||
<A HREF="idd.html">HTML</A> |
|
||||
<A HREF="idd.pdf">PDF</A> )
|
||||
|
||||
<LI>Software Designbeschreibung (
|
||||
<A HREF="sdd.html">HTML</A> |
|
||||
<A HREF="sdd.pdf">PDF</A> )
|
||||
|
||||
<LI>Software Wirkleistungsanalyse (
|
||||
<A HREF="sps.html">HTML</A> |
|
||||
<A HREF="sps.pdf">PDF</A> )
|
||||
|
||||
<LI>Software Versionsbeschreibung (
|
||||
<A HREF="svd.html">HTML</A> |
|
||||
<A HREF="svd.pdf">PDF</A> )
|
||||
|
||||
<LI>Software Sicherheitsbericht (
|
||||
<A HREF="ssr.html">HTML</A> |
|
||||
<A HREF="ssr.pdf">PDF</A> )
|
||||
|
||||
</UL>
|
||||
|
||||
<HR>
|
||||
|
||||
<P>Das Common UNIX Printing System, CUPS, und das CUPS Logo sind
|
||||
Warenzeichen der <A HREF="http://www.easysw.com">Easy Software
|
||||
Products</A>. CUPS ist urheberrechtlich geschützt 1997-2003 von Easy Software Products,
|
||||
Alle Rechte vorbehalten.
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
Depois Largura: | Altura: | Tamanho: 324 B |
|
Depois Largura: | Altura: | Tamanho: 315 B |
|
Depois Largura: | Altura: | Tamanho: 325 B |
|
Depois Largura: | Altura: | Tamanho: 291 B |
|
Depois Largura: | Altura: | Tamanho: 337 B |
|
Depois Largura: | Altura: | Tamanho: 208 B |
|
Depois Largura: | Altura: | Tamanho: 276 B |
|
Depois Largura: | Altura: | Tamanho: 296 B |
|
Depois Largura: | Altura: | Tamanho: 302 B |