-CHANGES.txt - 2008-05-14
+CHANGES.txt - 2008-05-15
------------------------
CHANGES IN CUPS V1.4b1
+ - Added a PageLogFormat directive to the cupsd.conf file to
+ control the format of lines in the page_log file.
- Filters can now send PPD: messages to stderr to set PPD
keywords like DefaultPageSize while a job is printing.
- Added a mdns backend for discovery and printing to printers
Browsing On
BrowseOrder allow,deny
BrowseAllow all
+BrowseLocalProtocols
# Default authentication type, when authentication is required...
DefaultAuthType Basic
dnl Check for Authorization Services support
AC_CHECK_HEADER(Security/Authorization.h, [
AC_DEFINE(HAVE_AUTHORIZATION_H)
- CUPS_DEFAULT_PRINTADMIN_AUTH="@AUTHKEY(system.print.admin) @admin @lpadmin"
- CUPS_SYSTEM_AUTHKEY="SystemGroupAuthKey system.preferences"])
+ if grep -q system.print.operator /etc/authorization; then
+ CUPS_DEFAULT_PRINTADMIN_AUTH="@AUTHKEY(system.print.admin) @admin @lpadmin"
+ CUPS_SYSTEM_AUTHKEY="SystemGroupAuthKey system.preferences"
+ else
+ CUPS_DEFAULT_PRINTADMIN_AUTH="@AUTHKEY(system.print.operator) @admin @lpadmin"
+ CUPS_SYSTEM_AUTHKEY="SystemGroupAuthKey system.print.admin"
+ fi])
AC_CHECK_HEADER(Security/SecBasePriv.h,AC_DEFINE(HAVE_SECBASEPRIV_H))
dnl Check for sandbox/Seatbelt support
char * /* O - PPD file or NULL */
cupsAdminCreateWindowsPPD(
- http_t *http, /* I - Connection to server */
+ http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
const char *dest, /* I - Printer or class */
char *buffer, /* I - Filename buffer */
int bufsize) /* I - Size of filename buffer */
if (buffer)
*buffer = '\0';
+ if (!http)
+ http = _cupsConnect();
+
if (!http || !dest || !buffer || bufsize < 2)
return (NULL);
int /* O - 1 on success, 0 on failure */
cupsAdminGetServerSettings(
- http_t *http, /* I - Connection to server */
+ http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
int *num_settings, /* O - Number of settings */
cups_option_t **settings) /* O - Settings */
{
int /* O - 1 on success, 0 on failure */
_cupsAdminGetServerSettings(
- http_t *http, /* I - Connection to server */
+ http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
int *num_settings, /* O - Number of settings */
cups_option_t **settings) /* O - Settings */
{
* Range check input...
*/
+ if (!http)
+ http = _cupsConnect();
+
if (!http || !num_settings || !settings)
{
_cupsSetError(IPP_INTERNAL_ERROR, NULL);
int /* O - 1 on success, 0 on failure */
cupsAdminSetServerSettings(
- http_t *http, /* I - Connection to server */
+ http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
int num_settings, /* I - Number of settings */
cups_option_t *settings) /* I - Settings */
{
int /* O - 1 on success, 0 on failure */
_cupsAdminSetServerSettings(
- http_t *http, /* I - Connection to server */
+ http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
int num_settings, /* I - Number of settings */
cups_option_t *settings) /* I - Settings */
{
* Range check input...
*/
+ if (!http)
+ http = _cupsConnect();
+
if (!http || !num_settings || !settings)
{
_cupsSetError(IPP_INTERNAL_ERROR, NULL);
* Decode text: URI and add to the buffer...
*/
- if (bufptr > buffer)
- *bufptr++ = ' '; /* Add leading whitespace */
-
valptr += 5;
while (*valptr && !isspace(*valptr & 255) && bufptr < bufend)
help:anchor='foo'%20bookID=Vendor%20Help
/help/foo/bar.html"
*End
-*fr.cupsIPPReason foo/La Foo Reason: "text:La%20Long
+*fr.cupsIPPReason foo/La Foo Reason: "text:La%20Long%20
text:Foo%20Reason
http://foo/fr/bar.html
help:anchor='foo'%20bookID=Vendor%20Help
/help/fr/foo/bar.html"
*End
-*zh_TW.cupsIPPReason foo/Number 1 Foo Reason: "text:Number%201
+*zh_TW.cupsIPPReason foo/Number 1 Foo Reason: "text:Number%201%20
text:Foo%20Reason
http://foo/zh_TW/bar.html
help:anchor='foo'%20bookID=Vendor%20Help
/help/zh_TW/foo/bar.html"
*End
-*zh.cupsIPPReason foo/Number 2 Foo Reason: "text:Number%202
+*zh.cupsIPPReason foo/Number 2 Foo Reason: "text:Number%202%20
text:Foo%20Reason
http://foo/zh/bar.html
help:anchor='foo'%20bookID=Vendor%20Help
information to the system log instead of a plain file.</P>
+<H2 CLASS="title"><A NAME="PageLogFormat">PageLogFormat</A></H2>
+
+<H3>Examples</H3>
+
+<PRE CLASS="command">
+PageLogFormat %p %j %u %T %P %C %{job-billing} %{job-originating-host-name} %{job-name} %{media} %{sides}
+PageLogFormat PAGE %p %j %u %P %C %{job-billing} %{job-originating-host-name}
+</PRE>
+
+<H3>Description</H3>
+
+<P>The <CODE>PageLogFormat</CODE> directive sets the format of lines
+that are logged to the page log file. Sequences beginning with percent (%)
+characters are replaced with the corresponding information, while all other
+characters are copied literally. The following percent sequences are
+recognized:</P>
+
+<UL>
+
+ <LI><CODE>%%</CODE>: Inserts a single percent character.</LI>
+
+ <LI><CODE>%{name}</CODE>: Inserts the value of the specified IPP
+ attribute.</LI>
+
+ <LI><CODE>%C</CODE>: Inserts the number of copies for the current page.</LI>
+
+ <LI><CODE>%P</CODE>: Inserts the current page number.</LI>
+
+ <LI><CODE>%T</CODE>: Inserts the current date and time in common log
+ format.</LI>
+
+ <LI><CODE>%j</CODE>: Inserts the job ID.</LI>
+
+ <LI><CODE>%p</CODE>: Inserts the printer name.</LI>
+
+ <LI><CODE>%u</CODE>: Inserts the username.</LI>
+
+</UL>
+
+<P>The default is "%p %j %u %T %P %C %{job-billing} %{job-originating-host-name} %{job-name} %{media} %{sides}".</P>
+
+
<H2 CLASS="title"><SPAN CLASS="info">CUPS 1.2</SPAN><A NAME="PassEnv">PassEnv</A></H2>
<H3>Examples</H3>
<BODY>
<P>The <VAR>page_log</VAR> file lists each page that is sent to a
-printer. Each line contains the following information:</P>
+printer. By default, each line contains the following information:</P>
<P CLASS="command">
-printer user job-id date-time page-number num-copies job-billing<BR>
+printer user job-id date-time page-number num-copies job-billing job-originating-host-name job-name media sides<BR>
<BR>
-DeskJet root 2 [20/May/1999:19:21:05 +0000] 1 1 acme-123<BR>
+DeskJet root 2 [20/May/1999:19:21:05 +0000] 1 1 acme-123 localhost myjob letter one-sided<BR>
-DeskJet root 2 [20/May/1999:19:21:05 +0000] 2 1 acme-123<BR>
+DeskJet root 2 [20/May/1999:19:21:05 +0000] 2 1 acme-123 localhost myjob letter one-sided<BR>
</P>
+<p>The <a href="ref-cupsd_conf.html#PageLogFormat"><code>PageLogFormat</code></a>
+directive can be used to change this information.</p>
+
<P>The <I>printer</I> field contains the name of the printer that
printed the page. If you send a job to a printer class, this
field will contain the name of the printer that was assigned the
<CODE>Create-Job</CODE> or <CODE>Print-Job</CODE> requests or "-"
if none was provided.
+<P>The <I>job-originating-host-name</I> field contains the hostname or IP
+address of the client that printed the job.</P>
+
+<P>The <I>job-name</I> field contains a copy of the
+<CODE>job-name</CODE> attribute provided with the IPP
+<CODE>Create-Job</CODE> or <CODE>Print-Job</CODE> requests or "-"
+if none was provided.
+
+<P>The <I>media</I> field contains a copy of the
+<CODE>media</CODE> attribute provided with the IPP
+<CODE>Create-Job</CODE> or <CODE>Print-Job</CODE> requests or "-"
+if none was provided.
+
+<P>The <I>sides</I> field contains a copy of the
+<CODE>sides</CODE> attribute provided with the IPP
+<CODE>Create-Job</CODE> or <CODE>Print-Job</CODE> requests or "-"
+if none was provided.
+
</BODY>
</HTML>
CUPS command file format specification for the Common UNIX Printing
System (CUPS).
+ Copyright 2007-2008 by Apple Inc.
Copyright 1997-2006 by Easy Software Products.
These coded instructions, statements, and computer programs are the
files by checking the <code>printer-type</code> attribute for the
<code>CUPS_PRINTER_COMMANDS</code> capability bit.</p>
+<p>In addition, the PPD file for a printer can contain a
+<code>cupsCommands</code> keyword that provides a list of supported
+commands separated by spaces, for example:</p>
+
+<pre class='command'>
+*cupsCommand: "AutoConfigure Clean PrintSelfTestPage ReportLevels"
+</pre>
+
+<p>If no <code>cupsCommands</code> keyword is provided, the command filter
+must support <a href='#AutoConfigure'><code>AutoConfigure</code></a>,
+<a href='#Clean'><code>Clean</code></a>,
+<a href='#PrintSelfTestPage'><code>PrintSelfTestPage</code></a>,
+and <a href='#ReportLevels'><code>ReportLevels</code></a>. The scheduler also
+provides the <code>printer-commands</code> attribute containing the list of
+supported commands.</p>
+
+
<h2 class='title'><a name='SYNTAX'>File Syntax</a></h2>
<p>CUPS command files are ASCII text files. The first line of a
# This is a comment
</pre>
-<p>The printer commands are described below. Printer commands are
-case-insensitive, so "PRINTSELFTESTPAGE", "printselftestpage",
-and "PrintSelfTestPage" are equivalent. Commands that accept
-arguments have their arguments on the same line separated by
-whitespace.</p>
+<p>Commands are any sequence of letters, numbers, and punctuation characters
+optionally followed by parameters separated by whitespace, e.g.:</p>
+
+<pre class='command'>
+Clean all
+PrintSelfTestPage
+</pre>
+
+<p>Command names are case-insensitive, so "PRINTSELFTESTPAGE",
+"printselftestpage", and "PrintSelfTestPage" are equivalent. Vendor-specific
+commands should use a domain name prefix, e.g.:</p>
+
+<pre class='command'>
+com.vendor.foo
+com.vendor.bar param param2 ... paramN
+</pre>
+
+
+<h2 class='title'><a name='COMMANDS'>Standard Commands</a></h2>
-<h2 class='title'><a name='COMMANDS'>Commands</a></h2>
+<p>The following are the standard commands supported by the format. The only
+required command is
+<a href='#PrintSelfTestPage'><code>PrintSelfTestPage</code></a>.</p>
-<h3>Clean</h3>
-<p class='summary'>Clean colorname</p>
+<h3><a name='AutoConfigure'>AutoConfigure</a></h3>
-<p>Does a standard print head cleaning. If a printer does not
-support cleaning of individual colors or cartridges, then all
-print heads are cleaned. Command filters MUST support the "all"
-colorname. Other standard color names include "black", "color",
-"photo", "cyan", "magenta", "yellow", "light-cyan",
-"light-magenta", "light-black", "light-gray", and
-"dark-gray".</p>
+<p class='summary'>AutoConfigure</p>
+
+<p>The <code>AutoConfigure</code> command updates the printer's PPD file
+and driver state information to reflect the current configuration of the
+printer. There are no arguments for this command.</p>
+
+<p>Example:</p>
+
+<pre class='command'>
+#CUPS-COMMAND
+AutoConfigure
+</pre>
+
+
+<h3><a name='Clean'>Clean</a></h3>
+
+<p class='summary'>Clean <i>colorname</i></p>
+
+<p>The <code>Clean</code> command performs a standard print head cleaning. The
+"colorname" parameter specifies which color or head to clean. If a printer does
+not support cleaning of individual colors or cartridges, then all colors are
+cleaned. Command filters MUST support the "all" colorname. Other standard color
+names include "black", "color", "photo", "cyan", "magenta", "yellow",
+"light-cyan", "light-magenta", "light-black", "light-gray", and "dark-gray".</p>
<p>Example:</p>
Clean all
</pre>
-<h3>PrintSelfTestPage</h3>
+
+<h3><a name='PrintAlignmentPage'>PrintAlignmentPage</a></h3>
+
+<p class='summary'>PrintAlignmentPage pass</p>
+
+<p>The <code>PrintAlignmentPage</code> command prints a head alignment page on
+the printer. The "pass" parameter provides a pass number from 1 to N. The number
+of passes is device-dependent.</p>
+
+<p>Example:</p>
+
+<pre class='command'>
+#CUPS-COMMAND
+PrintAlignmentPage 1
+</pre>
+
+
+<h3><a name='PrintSelfTestPage'>PrintSelfTestPage</a></h3>
<p class='summary'>PrintSelfTestPage</p>
-<p>Print a self-test page on the printer. Typically this page
-shows if all jets on a print head are functioning properly.</p>
+<p>The <code>PrintSelfTestPage</code> command prints a self-test page on the
+printer. Typically this page shows whether all jets on a print head are
+functioning and that the print feed mechanisms are working properly.</p>
<p>Example:</p>
PrintSelfTestPage
</pre>
+
+<h3><a name='ReportLevels'>ReportLevels</a></h3>
+
+<p class='summary'>ReportLevels</p>
+
+<p>The <code>ReportLevels</code> command queries the supply levels on a printer
+and reports "marker-colors", "marker-levels", "marker-names", and
+"marker-types" attributes using "ATTR:" messages sent to the scheduler.</p>
+
+<p>Example:</p>
+
+<pre class='command'>
+#CUPS-COMMAND
+ReportLevels
+</pre>
+
+
+<h3><a name='SetAlignment'>SetAlignment</a></h3>
+
+<p class='summary'>SetAlignment pass value ... valueN</p>
+
+<p>The <code>SetAlignment</code> command sets print head alignment values. The
+"pass" parameter is a number from 1 to N. All parameters are
+device-dependent.</p>
+
+<p>Example:</p>
+
+<pre class='command'>
+#CUPS-COMMAND
+SetAlignment 1 14
+</pre>
+
+
</body>
</html>
<p>The port-monitor-supported attribute specifies the available port monitors.
+<h4><a name="printer-commands">printer-commands (1setOf Type3 keyword)</a><span class='info'>CUPS 1.4</span></h4>
+
+<p>The printer-commands attribute specifies the commands that are supported
+by the CUPS command file filter. The keyword "none" indicates that no commands
+are supported.</p>
+
<h4><a name="printer-dns-sd-name">printer-dns-sd-name (name(MAX) | noValue)</a><span class='info'>CUPS 1.4</span></h4>
<p>The printer-dns-sd-name attribute specifies the registered DNS-SD service
</blockquote>
-<h3><a name='cupsColorProfile'>cupsColorProfile</a></h3>
+<h3><span class='info'>Deprecated</span><a name='cupsColorProfile'>cupsColorProfile</a></h3>
<p class='summary'>*cupsColorProfile Resolution/MediaType: "density
gamma m00 m01 m02 m10 m11 m12 m20 m21 m22"</p>
*cupsColorProfile -/-: "0.9 2.0 1.0 0.0 -0.2 -0.4 1.0 0.0 -0.2 0.0 1.0"
</pre>
+
<h3><span class='info'>Mac OS X 10.3/CUPS 1.2</span><a name='cupsICCProfile'>cupsICCProfile</a></h3>
<p class='summary'>*cupsICCProfile
<p>Also see the related <a href='#APDuplexRequiresFlippedMargin'><tt>APDuplexRequiresFlippedMargin</tt></a>
attribute.</p>
+<h3><span class='info'>CUPS 1.4</span><a name='cupsCommands'>cupsCommands</a></h3>
+
+<p class='summary'>*cupsCommands: "name name2 ... nameN"</p>
+
+<p>This string attribute specifies the commands that are supported by the
+CUPS command file filter for this device. The command names are separated
+by whitespace.</p>
+
+<p>Example:</p>
+
+<pre class='command'>
+<em>*% Specify the list of commands we support</em>
+*cupsCommands: "AutoConfigure Clean PrintSelfTestPage ReportLevels com.vendor.foo"
+</pre>
+
+
<h3><span class='info'>CUPS 1.3</span><a name='cupsEvenDuplex'>cupsEvenDuplex</a></h3>
<p class='summary'>*cupsEvenDuplex: boolean</p>
<li>Added <tt>cupsMarkerName</tt> attribute.</li>
+ <li>Added <tt>cupsCommands</tt> attribute.</li>
+
</ul>
<HTML>
<!-- SECTION: Getting Started -->
<HEAD>
- <TITLE>What's New in CUPS 1.3</TITLE>
+ <TITLE>What's New in CUPS 1.4</TITLE>
</HEAD>
<BODY>
-<P>CUPS 1.3 adds over 30 changes and new features to CUPS 1.2.x.
-This page provides a high-level outline of these changes. If you
-have never used CUPS before, read the <A
-HREF="overview.html">"Overview of CUPS"</A> document instead.</P>
+<P>CUPS 1.4 adds over ?? changes and new features to CUPS 1.3.x. This page provides a high-level outline of these changes. If you have never used CUPS before, read the <A HREF="overview.html">"Overview of CUPS"</A> document instead.</P>
-<H2 CLASS="title"><A NAME="CHANGES">Changes in CUPS 1.3</A></H2>
+<H2 CLASS="title"><A NAME="COMMANDS">Commands</A></H2>
-<DL CLASS="category">
+<OL START="1">
- <DT>Networking</DT>
- <DD><OL START="1">
+ <LI><EM>lppasswd;</EM> the lppasswd program is no longer installed setuid by default.</LI>
- <LI><EM>Kerberos;</EM> CUPS now supports Kerberos authentication</LI>
+ <LI><EM>cupsfilter;</EM> the cupsfilter program now supports filtering of already-queued print job files.</LI>
- <LI><EM>Mac OS X Authorization Services;</EM> CUPS now supports the Authorization Services framework, providing role-based access control in addition to the tradition UNIX model</LI>
+ <LI><EM>;</EM> </LI>
- <LI><EM>Peer Credentials;</EM> CUPS now supports authentication using peer credentials provided over UNiX domain sockets</LI>
+ <LI><EM>;</EM> </LI>
- <LI><EM>SNMP Support;</EM> SNMP lookups are no longer performed by default, and IPP is no longer used for discovered printers</LI>
+ <LI><EM>;</EM> </LI>
- <LI><EM>LPD Support;</EM> The LPD backend now supports a faster streaming mode that does not require a temporary file</LI>
+</OL>
- </OL></DD>
+<H2 CLASS="title"><A NAME="WEBIF">Web Interface</A></H2>
- <DT>Browsing</DT>
- <DD><OL START="6">
+<OL START="1">
- <LI><EM>CUPS Browsing;</EM> The default configuration now shows shared printers from any address (not just <tt>@LOCAL</tt>)</LI>
+ <LI><EM>Look-n-feel;</EM> the web interface has been given a new look with a new CUPS logo.</LI>
- <LI><EM>DNS-SD (Bonjour/Zeroconf) Support;</EM> CUPS
- now supports printer sharing via DNS service discovery</LI>
+ <LI><EM>Security;</EM> the web interface has been updated to require authentication for printing of test pages and RSS subscription operations.</LI>
- <LI><EM>LDAP w/SSL;</EM> CUPS now supports encrypted LDAP sessions</LI>
+ <LI><EM>Printer sharing;</EM> the "share printer" and "unshare printer" buttons are now only shown when printer sharing is enabled in the scheduler.</LI>
- </OL></DD>
+ <LI><EM>Printer configuration;</EM> improvements have been made to the add and modify printer pages.</LI>
+ <LI><EM>;</EM> </LI>
- <DT>Web Interface</DT>
- <DD><OL START="9">
+ <LI><EM>;</EM> </LI>
- <LI><EM>Internet Printer Sharing;</EM> You can now share printers over the Internet via the basic server settings</LI>
+ <LI><EM>;</EM> </LI>
- <LI><EM>Improved On-Line Help;</EM> Searching the on-line help now shows results for all text, not just headings and links</LI>
+ <LI><EM>;</EM> </LI>
- <LI><EM>Printer Setup;</EM> The available printer list is now only show when requested and the <VAR>Add This Printer</VAR> button now allows you to change the default name, location, and description</LI>
+</OL>
- <LI><EM>Printer Configuration;</EM> Raw printers and classes can now be configured using the <var>Set Printer Options</var> button</LI>
- </OL></DD>
+<H2 CLASS="title"><A NAME="NETWORKING">Networking</A></H2>
+<OL START="1">
- <DT>IPP Support</DT>
- <DD><OL START="13"></EM></LI>
+ <LI><EM>Bonjour (DNS-SD) printing support;</EM> a new mdns backend provides Bonjour-based printer discovery and the ipp, lpd, and socket backends now support Bonjour address resolution.</LI>
- <LI><EM>Job Printer Attributes;</EM> CUPS now provides <tt>job-printer-state-message</tt> and <tt>job-printer-state-reasons</tt> attributes containing copies of the corresponding printer attributes to provide important history information with each job</LI>
+ <LI><EM>Bonjour (DNS-SD) perforance tuning;</EM> the scheduler now only uses a single file descriptor for printer sharing. It previously used one per printer.</LI>
- <LI><EM>PPD Operations and Attributes;</EM> The new CUPS_GET_PPD operation allows you to retrieve PPD files from the scheduler; also, CUPS_GET_PPDS now reports more information and supports more value filters</LI>
+ <LI><EM>Bonjour (DNS-SD) web interface registry;</EM> when remote access is enabled, the scheduler registers the web interface for easier access</LI>
- <LI><EM>Printer Defaults;</EM> The <tt>document-forma-default</tt>, <tt>notify-events-default</tt>, and <tt>notify-lease-duration-default</tt> attributes can be set for each printer and class</LI>
+ <LI><EM>SNMP-based monitoring;</EM> the ipp, lpd, and socket backends now report supply levels and printer status using SNMP queries.</LI>
- <LI><EM>PWG Printer Alert Support;</EM> CUPS now supports the <tt>printer-alert</tt> and <tt>printer-alert-description</tt> attributes</LI>
+ <LI><EM>SNMP port monitor MIB;</EM> the ipp, lpd, snmp, and socket now support the PWG port monitor MIB</LI>
- <LI><EM>Server-Side Options;</EM> Server-side default options can now be retrieved using the "printer-defaults" group keyword</LI>
+ <LI><EM>;</EM> </LI>
- </OL></DD>
+ <LI><EM>;</EM> </LI>
+</OL>
- <DT>Scheduler</DT>
- <DD><OL START="18">
- <LI><EM>Client Support;</EM> The scheduler now uses <tt>poll()</tt>, <tt>epoll()</tt>, or <var>/dev/kqueue</var> on platforms that provide them to support large numbers of clients</LI>
+<H2 CLASS="title"><A NAME="IPP">IPP Support</A></H2>
- <LI><EM>"Default" Authentication;</EM> You can now specify an <tt>AuthType</tt> of <tt>Default</tt> in locations and policies, which maps to the <tt>DefaultAuthType</tt> value</LI>
+<OL START="1"></EM></LI>
- <LI><EM>Larger Numbers of Clients;</EM> The scheduler now uses poll(), epoll(), or /dev/kqueue instead of select() when possible</LI>
+ <LI><EM>CUPS-Get-Document operation;</EM> the scheduler now supports a "get document" operation to download files from a print job.</LI>
- <LI><EM>New cupsctl Command;</EM> The new cupsctl command allows you to perform basic server configuration from the command-line</LI>
+ <LI><EM>;</EM> </LI>
- </OL></DD>
+ <LI><EM>;</EM> </LI>
+ <LI><EM>;</EM> </LI>
- <DT>Printer Drivers</DT>
- <DD><OL START="22">
+ <LI><EM>;</EM> </LI>
- <LI><EM>cupstestppd Improvements;</EM> The test utility now provides more extensive tests and options</LI>
+ <LI><EM>;</EM> </LI>
- <LI><EM>Label Printer Driver;</EM> Added support for the Intellibar label printers</LI>
+</OL>
- <LI><EM>Localized Printer Drivers;</EM> The CUPS sample drivers are now localized in several languages</LI>
- <LI><EM>PJL Support;</EM> New <tt>cupsPJLCharset</tt> attribute controls character set for PJL strings</LI>
+<H2 CLASS="title"><A NAME="SCHEDULER">Scheduler</A></H2>
- <LI><EM>Pre-Filter Support;</EM> Drivers can now register format-specific filters to pre-screen print jobs</LI>
+<OL START="1">
- <LI><EM>Side-Channel API;</EM> This new API provides out-of-band control of devices</LI>
+ <LI><EM>Performance tuning;</EM> the scheduler now coalesces configuration and state file changes to reduce the amount of disk activity.</LI>
- </OL></DD>
+ <LI><EM>Configuration files;</EM> the default cupsd.conf file now provides an "authenticated" policy for easy authenticated sharing of printers.</LI>
+ <LI><EM>Seatbelt support;</EM> the scheduler now runs child processes using restrictive policies on Mac OS X for improved security and job isolation.</LI>
- <DT>CUPS API</DT>
- <DD><OL START="28">
+ <LI><EM>PAM support;</EM> the scheduler now sets more PAM attributes to better support third-party authentication schemes.</LI>
- <LI><EM>Administration API;</EM> New <tt>cupsAdminGetServerSettings()</tt> and <tt>cupsAdminSetServerSettings()</tt> functions</LI>
+ <LI><EM>Test option;</EM> the scheduler now supports a test mode via the "-t" option.</LI>
- <LI><EM>Array API;</EM> New <tt>cupsArrayGetIndex()</tt>, <tt>cupsArrayGetInsert()</tt>, and <tt>cupsArrayNew2()</tt> functions</LI>
+ <LI><EM>Page logging;</EM> the scheduler now supports a <code>PageLogFormat</code> directive to control the format of the page_log file.</LI>
- <LI><EM>Destination API;</EM> New <tt>cupsRemoveDest()</tt> and <tt>cupsSetDefaultDest()</tt> functions</LI>
+ <LI><EM>;</EM> </LI>
- <LI><EM>HTTP API;</EM> The <tt>http_t</tt> structure is now completely private</LI>
+ <LI><EM>;</EM> </LI>
- <LI><EM>PPD API;</EM> New <tt>ppdLocalizeIPPReason()</tt>function and greatly improved <tt>ppdConflicts()</tt> performance</LI>
+ <LI><EM>;</EM> </LI>
- </OL></DD>
+ <LI><EM>;</EM> </LI>
+ <LI><EM>;</EM> </LI>
+
+</OL>
+
+
+<H2 CLASS="title"><A NAME="DRIVERS">Printer Drivers</A></H2>
+
+<OL START="1">
+
+ <LI><EM>Dynamic PPD support;</EM> drivers can now set PPD keywords
+ dynamically using <code>PPD:</code> messages.</LI>
+
+ <LI><EM>Generic PostScript command filter;</EM> a new CUPS command file filter for PostScript printers provides auto-configuration, self-test page, and status and supply level reporting functions.</LI>
+
+ <LI><EM>PJL support;</EM> the cupsPJLDisplay PPD attribute controls the PJL commands used to display the current user and job on the printer.</LI>
+
+ <LI><EM>Driver development kit;</EM> the CUPS DDK is now a standard part of CUPS</LI>
+
+ <LI><EM>PPD compiler improvements;</EM> the PPD compiler now supports Mac OS X .strings files for localization and ... </LI>
+
+ <LI><EM>Generic PostScript and PCL drivers;</EM> new generic PostScript and PCL drivers provide improved support for laser printers.</LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+</OL>
+
+
+<H2 CLASS="title"><A NAME="FILTERS">Print Filters</A></H2>
+
+<OL START="1">
+
+ <LI><EM>Image filters;</EM> the standard image filters now support image files larger than 2GB.</LI>
+
+ <LI><EM>Device discovery;</EM> the cups-deviced helper now runs backends in parallel for faster discovery and streams the results of discovery as the backends provide them.</LI>
+
+ <LI><EM>PDF filter;</EM> the pdftops filter has been replaced with a wrapper program that runs the Xpdf, poppler, or Ghostscript PDF to PostScript utilities.</LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+</OL>
+
+
+<H2 CLASS="title"><A NAME="CUPSAPI">CUPS API</A></H2>
+
+<OL START="1">
+
+ <LI><EM>Streaming API;</EM> a new streaming request API provides asynchronous job creation and request submission.</LI>
+
+ <LI><EM>Device discovery;</EM> the new <code>cupsGetDevices</code> function streams discovered devices to an application-provided callback function.</LI>
+
+ <LI><EM>PPD support;</EM> two new functions are provided, cupsGetPPD3 and ppdLocalizeMarkerName, to update the local copy of a printers's PPD file and get a localized marker (supply) name, respectively.</LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+ <LI><EM>;</EM> </LI>
+
+</OL>
-</DL>
</BODY>
</HTML>
done
mantohtml: mantohtml.o
- $(CC) $(LDFLAGS) -o $@ mantohtml.o
+ $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ mantohtml.o
#
.\" which should have been included with this file. If this file is
.\" file is missing or damaged, see the license at "http://www.cups.org/".
.\"
-.TH cupsd.conf 5 "Common UNIX Printing System" "2 January 2008" "Apple Inc."
+.TH cupsd.conf 5 "Common UNIX Printing System" "15 May 2008" "Apple Inc."
.SH NAME
cupsd.conf \- server configuration file for cups
.SH DESCRIPTION
.br
Specifies the page log filename.
.TP 5
+PageLogFormat format string
+.br
+Specifies the format of page log lines.
+.TP 5
PassEnv variable [... variable]
.br
Passes the specified environment variable(s) to child processes.
return;
}
- httpFlushWrite(HTTP(con));
+ if (con->http.data_encoding == HTTP_ENCODE_CHUNKED)
+ httpFlushWrite(HTTP(con));
con->bytes += bytes;
{ "MaxSubscriptionsPerPrinter",&MaxSubscriptionsPerPrinter, CUPSD_VARTYPE_INTEGER },
{ "MaxSubscriptionsPerUser", &MaxSubscriptionsPerUser, CUPSD_VARTYPE_INTEGER },
{ "PageLog", &PageLog, CUPSD_VARTYPE_STRING },
+ { "PageLogFormat", &PageLogFormat, CUPSD_VARTYPE_STRING },
{ "PreserveJobFiles", &JobFiles, CUPSD_VARTYPE_BOOLEAN },
{ "PreserveJobHistory", &JobHistory, CUPSD_VARTYPE_BOOLEAN },
{ "Printcap", &Printcap, CUPSD_VARTYPE_STRING },
cupsdSetString(&AccessLog, CUPS_LOGDIR "/access_log");
cupsdSetString(&ErrorLog, CUPS_LOGDIR "/error_log");
cupsdSetString(&PageLog, CUPS_LOGDIR "/page_log");
+ cupsdSetString(&PageLogFormat,
+ "%p %j %u %T %P %C %{job-billing} "
+ "%{job-originating-host-name} %{job-name} %{media} %{sides}");
cupsdSetString(&Printcap, CUPS_DEFAULT_PRINTCAP);
cupsdSetString(&PrintcapGUI, "/usr/bin/glpoptions");
cupsdSetString(&FontPath, CUPS_FONTPATH);
/* Error log file */
*PageFile VALUE(NULL);
/* Page log file */
+VAR char *PageLogFormat VALUE(NULL);
+ /* Page log format */
VAR mime_t *MimeDatabase VALUE(NULL);
/* MIME type database */
VAR int NumMimeTypes VALUE(0);
selector[PPD_MAX_NAME];
/* Profile selection string */
ppd_file_t *ppd; /* PPD file */
- ppd_attr_t *attr, /* cupsICCProfile attributes */
- *profileid_attr;/* cupsProfileID attribute */
+ ppd_attr_t *attr, /* Profile attributes */
+ *profileid_attr,/* cupsProfileID attribute */
+ *q1_attr, /* ColorModel (or other) qualifier */
+ *q2_attr, /* MediaType (or other) qualifier */
+ *q3_attr; /* Resolution (or other) qualifier */
+ char q_keyword[PPD_MAX_NAME];
+ /* Qualifier keyword */
+ const char *q1_choice, /* ColorModel (or other) choice */
+ *q2_choice, /* MediaType (or other) choice */
+ *q3_choice; /* Resolution (or other) choice */
const char *profile_key; /* Profile keyword */
ppd_option_t *cm_option; /* Color model option */
- ppd_choice_t *cm_choice, /* Color model choice */
- *q1_choice, /* ColorModel (or other) qualifier */
- *q2_choice, /* MediaType (or other) qualifier */
- *q3_choice; /* Resolution (or other) qualifier */
+ ppd_choice_t *cm_choice; /* Color model choice */
int num_profiles; /* Number of profiles */
CMError error; /* Last error */
unsigned device_id, /* Printer device ID */
if ((ppd = ppdOpenFile(ppdfile)) == NULL)
return;
- ppdMarkDefaults(ppd);
-
/*
* See if we have any profiles...
*/
if (num_profiles > 0)
{
- /*
- * Figure out the default profile selectors...
- */
+ if (profile_key[0] == 'A')
+ {
+ /*
+ * For Tioga PPDs, get the default profile using the DefaultAPTiogaProfile
+ * attribute...
+ */
- if ((attr = ppdFindAttr(ppd, "cupsICCQualifier1", NULL)) != NULL &&
- attr->value && attr->value[0])
- q1_choice = ppdFindMarkedChoice(ppd, attr->value);
- else
- q1_choice = ppdFindMarkedChoice(ppd, "ColorModel");
+ if ((attr = ppdFindAttr(ppd, "DefaultAPTiogaProfile", NULL)) != NULL &&
+ attr->value)
+ default_profile_id = atoi(attr->value);
- if ((attr = ppdFindAttr(ppd, "cupsICCQualifier2", NULL)) != NULL &&
- attr->value && attr->value[0])
- q2_choice = ppdFindMarkedChoice(ppd, attr->value);
+ q1_choice = q2_choice = q3_choice = NULL;
+ }
else
- q2_choice = ppdFindMarkedChoice(ppd, "MediaType");
+ {
+ /*
+ * For CUPS PPDs, figure out the default profile selector values...
+ */
- if ((attr = ppdFindAttr(ppd, "cupsICCQualifier3", NULL)) != NULL &&
- attr->value && attr->value[0])
- q3_choice = ppdFindMarkedChoice(ppd, attr->value);
- else
- q3_choice = ppdFindMarkedChoice(ppd, "Resolution");
+ if ((attr = ppdFindAttr(ppd, "cupsICCQualifier1", NULL)) != NULL &&
+ attr->value && attr->value[0])
+ {
+ snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value);
+ q1_attr = ppdFindAttr(ppd, q_keyword, NULL);
+ }
+ else if ((q1_attr = ppdFindAttr(ppd, "DefaultColorModel", NULL)) == NULL)
+ q1_attr = ppdFindAttr(ppd, "DefaultColorSpace", NULL);
+
+ if (q1_attr && q1_attr->value && q1_attr->value[0])
+ q1_choice = q1_attr->value;
+ else
+ q1_choice = "";
+
+ if ((attr = ppdFindAttr(ppd, "cupsICCQualifier2", NULL)) != NULL &&
+ attr->value && attr->value[0])
+ {
+ snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value);
+ q2_attr = ppdFindAttr(ppd, q_keyword, NULL);
+ }
+ else
+ q2_attr = ppdFindAttr(ppd, "DefaultMediaType", NULL);
+
+ if (q2_attr && q2_attr->value && q2_attr->value[0])
+ q2_choice = q2_attr->value;
+ else
+ q2_choice = NULL;
+
+ if ((attr = ppdFindAttr(ppd, "cupsICCQualifier3", NULL)) != NULL &&
+ attr->value && attr->value[0])
+ {
+ snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value);
+ q3_attr = ppdFindAttr(ppd, q_keyword, NULL);
+ }
+ else
+ q3_attr = ppdFindAttr(ppd, "DefaultResolution", NULL);
+
+ if (q3_attr && q3_attr->value && q3_attr->value[0])
+ q3_choice = q3_attr->value;
+ else
+ q3_choice = NULL;
+ }
/*
* Build the array of profiles...
* See if this is the default profile...
*/
- if (!default_profile_id && q1_choice)
+ if (!default_profile_id)
{
if (q2_choice)
{
if (q3_choice)
{
snprintf(selector, sizeof(selector), "%s.%s.%s",
- q1_choice->choice, q2_choice->choice, q3_choice->choice);
+ q1_choice, q2_choice, q3_choice);
if (!strcmp(selector, attr->spec))
default_profile_id = profile_id;
}
if (!default_profile_id)
{
- snprintf(selector, sizeof(selector), "%s.%s.", q1_choice->choice,
- q2_choice->choice);
+ snprintf(selector, sizeof(selector), "%s.%s.", q1_choice,
+ q2_choice);
if (!strcmp(selector, attr->spec))
default_profile_id = profile_id;
}
if (!default_profile_id && q3_choice)
{
- snprintf(selector, sizeof(selector), "%s..%s", q1_choice->choice,
- q3_choice->choice);
+ snprintf(selector, sizeof(selector), "%s..%s", q1_choice,
+ q3_choice);
if (!strcmp(selector, attr->spec))
default_profile_id = profile_id;
}
if (!default_profile_id)
{
- snprintf(selector, sizeof(selector), "%s..", q1_choice->choice);
+ snprintf(selector, sizeof(selector), "%s..", q1_choice);
if (!strcmp(selector, attr->spec))
default_profile_id = profile_id;
}
cupsArrayAdd(ra, "pdl-override-supported");
cupsArrayAdd(ra, "printer-alert");
cupsArrayAdd(ra, "printer-alert-description");
+ cupsArrayAdd(ra, "printer-commands");
cupsArrayAdd(ra, "printer-current-time");
cupsArrayAdd(ra, "printer-driver-installer");
+ cupsArrayAdd(ra, "printer-dns-sd-name");
cupsArrayAdd(ra, "printer-info");
cupsArrayAdd(ra, "printer-is-accepting-jobs");
cupsArrayAdd(ra, "printer-location");
cupsArrayAdd(ra, "printer-state");
cupsArrayAdd(ra, "printer-state-message");
cupsArrayAdd(ra, "printer-state-reasons");
+ cupsArrayAdd(ra, "printer-type");
cupsArrayAdd(ra, "printer-up-time");
cupsArrayAdd(ra, "printer-uri-supported");
cupsArrayAdd(ra, "queued-job-count");
cupsdHoldJob(job);
- cupsdAddEvent(CUPSD_EVENT_JOB_STATE, job->printer, job,
+ cupsdAddEvent(CUPSD_EVENT_JOB_STATE, cupsdFindDest(job->dest), job,
"Job held by user.");
if ((newattr = ippFindAttribute(con->request, "job-hold-until",
cupsdSetJobHoldUntil(job, attr->values[0].string.text);
- cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, job->printer, job,
+ cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, cupsdFindDest(job->dest), job,
"Job job-hold-until value changed by user.");
}
attr->value_tag = IPP_TAG_KEYWORD;
attr->values[0].string.text = _cupsStrAlloc("no-hold");
- cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, job->printer, job,
+ cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, cupsdFindDest(job->dest), job,
"Job job-hold-until value changed by user.");
}
cupsdReleaseJob(job);
- cupsdAddEvent(CUPSD_EVENT_JOB_STATE, job->printer, job,
+ cupsdAddEvent(CUPSD_EVENT_JOB_STATE, cupsdFindDest(job->dest), job,
"Job released by user.");
cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Released by \"%s\".", jobid,
*/
if (event & CUPSD_EVENT_PRINTER_QUEUE_ORDER_CHANGED)
- cupsdAddEvent(CUPSD_EVENT_PRINTER_QUEUE_ORDER_CHANGED, job->printer, job,
+ cupsdAddEvent(CUPSD_EVENT_PRINTER_QUEUE_ORDER_CHANGED,
+ cupsdFindDest(job->dest), job,
"Job priority changed by user.");
if (event & CUPSD_EVENT_JOB_STATE)
- cupsdAddEvent(CUPSD_EVENT_JOB_STATE, job->printer, job,
+ cupsdAddEvent(CUPSD_EVENT_JOB_STATE, cupsdFindDest(job->dest), job,
job->state_value == IPP_JOB_HELD ?
"Job held by user." : "Job restarted by user.");
if (event & CUPSD_EVENT_JOB_CONFIG_CHANGED)
- cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, job->printer, job,
+ cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, cupsdFindDest(job->dest), job,
"Job options changed by user.");
/*
strlcpy(job->printer->state_message, message,
sizeof(job->printer->state_message));
cupsdAddPrinterHistory(job->printer);
- event |= CUPSD_EVENT_PRINTER_STATE;
+
+ if (loglevel < CUPSD_LOG_INFO)
+ event |= CUPSD_EVENT_PRINTER_STATE;
update_job_attrs(job);
}
cupsdLogPage(cupsd_job_t *job, /* I - Job being printed */
const char *page) /* I - Page being printed */
{
- ipp_attribute_t *billing, /* job-billing attribute */
- *hostname; /* job-originating-host-name attribute */
+ int i; /* Looping var */
+ char buffer[2048], /* Buffer for page log */
+ *bufptr, /* Pointer into buffer */
+ name[256]; /* Attribute name */
+ const char *format, /* Pointer into PageLogFormat */
+ *nameend; /* End of attribute name */
+ ipp_attribute_t *attr; /* Current attribute */
+ int number; /* Page number */
+ char copies[256]; /* Number of copies */
- billing = ippFindAttribute(job->attrs, "job-billing", IPP_TAG_ZERO);
- hostname = ippFindAttribute(job->attrs, "job-originating-host-name",
- IPP_TAG_ZERO);
+ /*
+ * Format the line going into the page log...
+ */
+
+ if (!PageLogFormat)
+ return (1);
+
+ number = 1;
+ strcpy(copies, "1");
+ sscanf(page, "%d%255s", &number, copies);
+
+ for (format = PageLogFormat, bufptr = buffer; *format; format ++)
+ {
+ if (*format == '%')
+ {
+ format ++;
+
+ switch (*format)
+ {
+ case '%' : /* Literal % */
+ if (bufptr < (buffer + sizeof(buffer) - 1))
+ *bufptr++ = '%';
+ break;
+
+ case 'p' : /* Printer name */
+ strlcpy(bufptr, job->printer->name,
+ sizeof(buffer) - (bufptr - buffer));
+ bufptr += strlen(bufptr);
+ break;
+
+ case 'j' : /* Job ID */
+ snprintf(bufptr, sizeof(buffer) - (bufptr - buffer), "%d", job->id);
+ bufptr += strlen(bufptr);
+ break;
+
+ case 'u' : /* Username */
+ strlcpy(bufptr, job->username ? job->username : "-",
+ sizeof(buffer) - (bufptr - buffer));
+ bufptr += strlen(bufptr);
+ break;
+
+ case 'T' : /* Date and time */
+ strlcpy(bufptr, cupsdGetDateTime(time(NULL)),
+ sizeof(buffer) - (bufptr - buffer));
+ bufptr += strlen(bufptr);
+ break;
+
+ case 'P' : /* Page number */
+ snprintf(bufptr, sizeof(buffer) - (bufptr - buffer), "%d", number);
+ bufptr += strlen(bufptr);
+ break;
+
+ case 'C' : /* Number of copies */
+ strlcpy(bufptr, copies, sizeof(buffer) - (bufptr - buffer));
+ bufptr += strlen(bufptr);
+ break;
+
+ case '{' : /* {attribute} */
+ if ((nameend = strchr(format, '}')) != NULL &&
+ (nameend - format - 2) < (sizeof(name) - 1))
+ {
+ /*
+ * Pull the name from inside the brackets...
+ */
+
+ memcpy(name, format + 1, nameend - format - 2);
+ name[nameend - format - 2] = '\0';
+
+ if ((attr = ippFindAttribute(job->attrs, name,
+ IPP_TAG_ZERO)) != NULL)
+ {
+ /*
+ * Add the attribute value...
+ */
+
+ format = nameend;
+
+ for (i = 0;
+ i < attr->num_values &&
+ bufptr < (buffer + sizeof(buffer) - 1);
+ i ++)
+ {
+ if (i)
+ *bufptr++ = ',';
+
+ switch (attr->value_tag)
+ {
+ case IPP_TAG_INTEGER :
+ case IPP_TAG_ENUM :
+ snprintf(bufptr, sizeof(buffer) - (bufptr - buffer),
+ "%d", attr->values[i].integer);
+ bufptr += strlen(bufptr);
+ break;
+
+ case IPP_TAG_BOOLEAN :
+ snprintf(bufptr, sizeof(buffer) - (bufptr - buffer),
+ "%d", attr->values[i].boolean);
+ bufptr += strlen(bufptr);
+ break;
+
+ case IPP_TAG_TEXTLANG :
+ case IPP_TAG_NAMELANG :
+ case IPP_TAG_TEXT :
+ case IPP_TAG_NAME :
+ case IPP_TAG_KEYWORD :
+ case IPP_TAG_URI :
+ case IPP_TAG_URISCHEME :
+ case IPP_TAG_CHARSET :
+ case IPP_TAG_LANGUAGE :
+ case IPP_TAG_MIMETYPE :
+ strlcpy(bufptr, attr->values[i].string.text,
+ sizeof(buffer) - (bufptr - buffer));
+ bufptr += strlen(bufptr);
+ break;
+
+ default :
+ strlcpy(bufptr, "???",
+ sizeof(buffer) - (bufptr - buffer));
+ bufptr += strlen(bufptr);
+ break;
+ }
+ }
+ }
+ else if (bufptr < (buffer + sizeof(buffer) - 1))
+ *bufptr++ = '-';
+ break;
+ }
+
+ default :
+ if (bufptr < (buffer + sizeof(buffer) - 2))
+ {
+ *bufptr++ = '%';
+ *bufptr++ = *format;
+ }
+ break;
+ }
+ }
+ else if (bufptr < (buffer + sizeof(buffer) - 1))
+ *bufptr++ = *format;
+ }
+ *bufptr = '\0';
+
#ifdef HAVE_VSYSLOG
/*
* See if we are logging pages via syslog...
if (!strcmp(PageLog, "syslog"))
{
- syslog(LOG_INFO, "PAGE %s %s %d %s %s %s", job->printer->name,
- job->username ? job->username : "-",
- job->id, page, billing ? billing->values[0].string.text : "-",
- hostname->values[0].string.text);
+ syslog(LOG_INFO, "%s", buffer);
return (1);
}
* billing hostname
*/
- cupsFilePrintf(PageFile, "%s %s %d %s %s %s %s\n", job->printer->name,
- job->username ? job->username : "-",
- job->id, cupsdGetDateTime(time(NULL)), page,
- billing ? billing->values[0].string.text : "-",
- hostname->values[0].string.text);
+ cupsFilePrintf(PageFile, "%s\n", buffer);
cupsFileFlush(PageFile);
return (1);
{ /* No authentication */
"none"
};
+ static const char * const standard_commands[] =
+ { /* Standard CUPS commands */
+ "AutoConfigure",
+ "Clean",
+ "PrintSelfTestPage",
+ "ReportLevels"
+ };
DEBUG_printf(("cupsdSetPrinterAttrs: entering name = %s, type = %x\n", p->name,
p->type |= CUPS_PRINTER_COMMANDS;
}
+ if (p->type & CUPS_PRINTER_COMMANDS)
+ {
+ char *commands, /* Copy of commands */
+ *start, /* Start of name */
+ *end; /* End of name */
+ int count; /* Number of commands */
+
+
+ if ((ppdattr = ppdFindAttr(ppd, "cupsCommands", NULL)) != NULL &&
+ ppdattr->value && ppdattr->value[0])
+ {
+ for (count = 0, start = ppdattr->value; *start; count ++)
+ {
+ while (isspace(*start & 255))
+ start ++;
+
+ if (!*start)
+ break;
+
+ while (*start && !isspace(*start & 255))
+ start ++;
+ }
+ }
+ else
+ count = 0;
+
+ if (count > 0)
+ {
+ /*
+ * Make a copy of the commands string and count how many ...
+ */
+
+ attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "printer-commands", count, NULL, NULL);
+
+ commands = strdup(ppdattr->value);
+
+ for (count = 0, start = commands; *start; count ++)
+ {
+ while (isspace(*start & 255))
+ start ++;
+
+ if (!*start)
+ break;
+
+ end = start;
+ while (*end && !isspace(*end & 255))
+ end ++;
+
+ if (*end)
+ *end++ = '\0';
+
+ attr->values[count].string.text = _cupsStrAlloc(start);
+
+ start = end;
+ }
+
+ free(commands);
+ }
+ else
+ {
+ /*
+ * Add the standard list of commands...
+ */
+
+ ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "printer-commands",
+ (int)(sizeof(standard_commands) /
+ sizeof(standard_commands[0])), NULL,
+ standard_commands);
+ }
+ }
+ else
+ {
+ /*
+ * No commands supported...
+ */
+
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "printer-commands", NULL, "none");
+ }
+
/*
* Show current and available port monitors for this printer...
*/
on-line help information.</P>
<P>If you are new to CUPS, read the "<a
-href="overview.html">Overview of CUPS</a>" page. Veteran users
-should read the "<a href="whatsnew.html">What's New in CUPS
-1.3</a>" page.</P>
+href="/help/overview.html">Overview of CUPS</a>" page. Veteran users
+should read the "<a href="/help/whatsnew.html">What's New in CUPS
+1.4</a>" page.</P>
-<P>The <A HREF="http://www.cups.org/">CUPS Home Page</A> also
+<P>The <A HREF="http://www.cups.org/">CUPS home page</A> also
provides many resources including user discussion forums, answers
to frequently-asked questions, and a form for submitting bug
reports and feature requests.</P>}