summaryrefslogtreecommitdiff
path: root/cups
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2008-01-31 17:01:57 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2008-01-31 17:01:57 +0000
commit5a738aeaea5c4dd9384a8601cc5c99be683b69ca (patch)
tree519e13a0beb3234458a686c2f7cb25b36fef4f72 /cups
parentd9bca400bee5f6168a7e07f85279251f040d734c (diff)
Merge changes from CUPS 1.4svn-r7282.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@614 a1ca3aef-8c08-0410-bb20-df032aa958be
Diffstat (limited to 'cups')
-rw-r--r--cups/Makefile73
-rw-r--r--cups/adminutil.c12
-rw-r--r--cups/api-array.header34
-rw-r--r--cups/api-array.shtml170
-rw-r--r--cups/api-cups.header40
-rw-r--r--cups/api-cups.shtml428
-rw-r--r--cups/api-filedir.header36
-rw-r--r--cups/api-filedir.shtml36
-rw-r--r--cups/api-filter.header39
-rw-r--r--cups/api-filter.shtml323
-rw-r--r--cups/api-httpipp.header37
-rw-r--r--cups/api-httpipp.shtml322
-rw-r--r--cups/api-overview.header49
-rw-r--r--cups/api-overview.shtml95
-rw-r--r--cups/api-ppd.header36
-rw-r--r--cups/api-ppd.shtml196
-rw-r--r--cups/array.c54
-rw-r--r--cups/array.h2
-rw-r--r--cups/attr.c18
-rw-r--r--cups/auth.c45
-rw-r--r--cups/backend.h8
-rw-r--r--cups/cups.h24
-rw-r--r--cups/dest.c59
-rw-r--r--cups/dir.c38
-rw-r--r--cups/emit.c10
-rw-r--r--cups/encode.c303
-rw-r--r--cups/file.c141
-rw-r--r--cups/getputfile.c30
-rw-r--r--cups/ipp-private.h3
-rw-r--r--cups/ipp.c25
-rw-r--r--cups/ipp.h2
-rw-r--r--cups/language.c2
-rw-r--r--cups/libcups.exp1
-rw-r--r--cups/localize.c62
-rw-r--r--cups/mark.c461
-rw-r--r--cups/notify.c8
-rw-r--r--cups/options.c486
-rw-r--r--cups/ppd.c6
-rw-r--r--cups/ppd.h18
-rw-r--r--cups/sidechannel.h26
-rw-r--r--cups/tempfile.c6
-rw-r--r--cups/test.ppd8
-rw-r--r--cups/testppd.c55
-rw-r--r--cups/usersys.c26
-rw-r--r--cups/util.c181
45 files changed, 2892 insertions, 1142 deletions
diff --git a/cups/Makefile b/cups/Makefile
index e00a368e3..4ea63e200 100644
--- a/cups/Makefile
+++ b/cups/Makefile
@@ -444,29 +444,86 @@ testsnmp: testsnmp.o libcups.a
apihelp:
echo Generating CUPS API help files...
+ mxmldoc --section "Programming" \
+ --title "Introduction to CUPS Programming" \
+ --css ../doc/cups-printable.css \
+ --header api-overview.header --intro api-overview.shtml \
+ >../doc/help/api-overview.html
mxmldoc --section "Programming" --title "Array API" \
- --intro api-array.shtml \
+ --css ../doc/cups-printable.css \
+ --header api-array.header --intro api-array.shtml \
array.h array.c >../doc/help/api-array.html
mxmldoc --section "Programming" --title "CUPS API" \
- --intro api-cups.shtml \
+ --css ../doc/cups-printable.css \
+ --header api-cups.header --intro api-cups.shtml \
cups.h dest.c getputfile.c language.c notify.c \
options.c tempfile.c usersys.c \
util.c >../doc/help/api-cups.html
mxmldoc --section "Programming" --title "File and Directory APIs" \
- --intro api-filedir.shtml \
+ --css ../doc/cups-printable.css \
+ --header api-filedir.header --intro api-filedir.shtml \
file.h file.c dir.h dir.c >../doc/help/api-filedir.html
mxmldoc --section "Programming" --title "PPD API" \
- --intro api-ppd.shtml \
+ --css ../doc/cups-printable.css \
+ --header api-ppd.header --intro api-ppd.shtml \
ppd.h attr.c custom.c emit.c localize.c mark.c page.c \
ppd.c >../doc/help/api-ppd.html
mxmldoc --section "Programming" --title "HTTP and IPP APIs" \
- --intro api-httpipp.shtml \
+ --css ../doc/cups-printable.css \
+ --header api-httpipp.header --intro api-httpipp.shtml \
http.h ipp.h auth.c encode.c http.c http-addr.c \
http-support.c ipp.c ipp-support.c md5passwd.c \
request.c >../doc/help/api-httpipp.html
- mxmldoc --section "Programming" --title "Filter and Backend APIs" \
- --intro api-filter.shtml \
- backchannel.c sidechannel.c sidechannel.h >../doc/help/api-filter.html
+ mxmldoc --section "Programming" \
+ --title "Filter and Backend Programming" \
+ --css ../doc/cups-printable.css \
+ --header api-filter.header --intro api-filter.shtml \
+ backchannel.c backend.h sidechannel.c sidechannel.h \
+ >../doc/help/api-filter.html
+
+framedhelp:
+ echo Generating CUPS API help files...
+ mxmldoc --framed api-overview \
+ --section "Programming" \
+ --title "Introduction to CUPS Programming" \
+ --css ../doc/cups-printable.css \
+ --header api-overview.header --intro api-overview.shtml
+ mxmldoc --framed api-array \
+ --section "Programming" --title "Array API" \
+ --css ../doc/cups-printable.css \
+ --header api-array.header --intro api-array.shtml \
+ array.h array.c
+ mxmldoc --framed api-cups \
+ --section "Programming" --title "CUPS API" \
+ --css ../doc/cups-printable.css \
+ --header api-cups.header --intro api-cups.shtml \
+ cups.h dest.c getputfile.c language.c notify.c \
+ options.c tempfile.c usersys.c \
+ util.c >../doc/help/api-cups.html
+ mxmldoc --framed api-filedir \
+ --section "Programming" --title "File and Directory APIs" \
+ --css ../doc/cups-printable.css \
+ --header api-filedir.header --intro api-filedir.shtml \
+ file.h file.c dir.h dir.c >../doc/help/api-filedir.html
+ mxmldoc --framed api-ppd \
+ --section "Programming" --title "PPD API" \
+ --css ../doc/cups-printable.css \
+ --header api-ppd.header --intro api-ppd.shtml \
+ ppd.h attr.c custom.c emit.c localize.c mark.c page.c \
+ ppd.c >../doc/help/api-ppd.html
+ mxmldoc --framed api-httpipp \
+ --section "Programming" --title "HTTP and IPP APIs" \
+ --css ../doc/cups-printable.css \
+ --header api-httpipp.header --intro api-httpipp.shtml \
+ http.h ipp.h auth.c encode.c http.c http-addr.c \
+ http-support.c ipp.c ipp-support.c md5passwd.c \
+ request.c >../doc/help/api-httpipp.html
+ mxmldoc --framed api-filter \
+ --section "Programming" \
+ --title "Filter and Backend Programming" \
+ --css ../doc/cups-printable.css \
+ --header api-filter.header --intro api-filter.shtml \
+ backchannel.c backend.h sidechannel.c sidechannel.h
#
diff --git a/cups/adminutil.c b/cups/adminutil.c
index 3eda26dba..c75b0d904 100644
--- a/cups/adminutil.c
+++ b/cups/adminutil.c
@@ -1613,8 +1613,6 @@ _cupsAdminSetServerSettings(
if (remote_admin)
cupsFilePrintf(temp, " Allow %s\n",
remote_any > 0 ? "all" : "@LOCAL");
- else
- cupsFilePuts(temp, " Allow localhost\n");
}
else if (in_conf_location && remote_admin >= 0)
{
@@ -1632,8 +1630,6 @@ _cupsAdminSetServerSettings(
if (remote_admin)
cupsFilePrintf(temp, " Allow %s\n",
remote_any > 0 ? "all" : "@LOCAL");
- else
- cupsFilePuts(temp, " Allow localhost\n");
}
else if (in_root_location && (remote_admin >= 0 || share_printers >= 0))
{
@@ -1654,8 +1650,6 @@ _cupsAdminSetServerSettings(
if (remote_admin > 0 || share_printers > 0)
cupsFilePrintf(temp, " Allow %s\n",
remote_any > 0 ? "all" : "@LOCAL");
- else
- cupsFilePuts(temp, " Allow localhost\n");
}
in_admin_location = 0;
@@ -1876,8 +1870,6 @@ _cupsAdminSetServerSettings(
if (remote_admin > 0 || share_printers > 0)
cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL");
- else
- cupsFilePuts(temp, " Allow localhost\n");
cupsFilePuts(temp, "</Location>\n");
}
@@ -1894,8 +1886,6 @@ _cupsAdminSetServerSettings(
if (remote_admin)
cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL");
- else
- cupsFilePuts(temp, " Allow localhost\n");
cupsFilePuts(temp, "</Location>\n");
}
@@ -1915,8 +1905,6 @@ _cupsAdminSetServerSettings(
if (remote_admin)
cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL");
- else
- cupsFilePuts(temp, " Allow localhost\n");
cupsFilePuts(temp, "</Location>\n");
}
diff --git a/cups/api-array.header b/cups/api-array.header
new file mode 100644
index 000000000..34b796f4c
--- /dev/null
+++ b/cups/api-array.header
@@ -0,0 +1,34 @@
+<!--
+ "$Id$"
+
+ Array API header for the Common UNIX Printing System (CUPS).
+
+ Copyright 2008 by Apple Inc.
+
+ These coded instructions, statements, and computer programs are the
+ property of Apple Inc. and are protected by Federal copyright
+ law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ which should have been included with this file. If this file is
+ file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">Array API</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+ <th>Header</th>
+ <th>cups/array.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+ <th>Library</th>
+ <td>-lcups</td>
+</tr>
+<tr>
+ <th>See Also</th>
+ <td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a></td>
+</tr>
+</tbody>
+</table></div>
diff --git a/cups/api-array.shtml b/cups/api-array.shtml
index 355aa4822..92c540b09 100644
--- a/cups/api-array.shtml
+++ b/cups/api-array.shtml
@@ -3,7 +3,7 @@
Array API introduction for the Common UNIX Printing System (CUPS).
- Copyright 2007 by Apple Inc.
+ Copyright 2007-2008 by Apple Inc.
Copyright 1997-2006 by Easy Software Products, all rights reserved.
These coded instructions, statements, and computer programs are the
@@ -13,33 +13,165 @@
file is missing or damaged, see the license at "http://www.cups.org/".
-->
-<h2 class='title'>Introduction</h2>
+<h2 class='title'><a name='OVERVIEW'>Overview</a></h2>
-<p>The CUPS array API provides a high-performance generic array
-container. The contents of the array container can be sorted and
-the container itself is designed for optimal speed and memory
-usage under a wide variety of conditions.</p>
+<p>The CUPS array API provides a high-performance generic array container.
+The contents of the array container can be sorted and the container itself is
+designed for optimal speed and memory usage under a wide variety of conditions.
+Sorted arrays use a binary search algorithm from the last found or inserted
+element to quickly find matching elements in the array. Arrays created with the
+optional hash function can often find elements with a single lookup. The
+<a href='#cups_array_t'><code>cups_array_t</code></a> type is used when
+referring to a CUPS array.</p>
<p>The CUPS scheduler (<tt>cupsd</tt>) and many of the CUPS API
functions use the array API to efficiently manage large lists of
data.</p>
-<h2 class='title'>General Usage</h2>
+<h3><a name='MANAGING_ARRAYS'>Managing Arrays</a></h3>
-<p>The <var>&lt;cups/array.h&gt;</var> header file must be
-included to use the <tt>cupsArray</tt> functions.</p>
+<p>Arrays are created using either the
+<a href='#cupsArrayNew'><code>cupsArrayNew</code></a> or
+<a href='#cupsArrayNew2'><code>cupsArrayNew2</code></a> functions. The
+first function creates a new array with the specified callback function
+and user data pointer:</p>
-<p>Programs using these functions must be linked to the CUPS
-library: <var>libcups.a</var>, <var>libcups.so.2</var>,
-<var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
-<var>libcups2.lib</var> depending on the platform. The following
-command compiles <var>myprogram.c</var> using GCC and the CUPS
-library:</p>
+<pre class='example'>
+#include &lt;cups/array.h&gt;
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcups</kbd>
+static int compare_func(void *first, void *second, void *user_data);
+
+void *user_data;
+<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew'>cupsArrayNew</a>(compare_func, user_data);
+</pre>
+
+<p>The comparison function (type
+<a href="#cups_arrayfunc_t"><code>cups_arrayfunc_t</code></a>) is called
+whenever an element is added to the array and can be <code>NULL</code> to
+create an unsorted array. The function returns -1 if the first element should
+come before the second, 0 if the first and second elements should have the same
+ordering, and 1 if the first element should come after the second.</p>
+
+<p>The "user_data" pointer is passed to your comparison function. Pass
+<code>NULL</code> if you do not need to associate the elements in your array
+with additional information.</p>
+
+<p>The <a href='#cupsArrayNew2'><code>cupsArrayNew2</code></a> function adds
+two more arguments to support hashed lookups, which can potentially provide
+instantaneous ("O(1)") lookups in your array:</p>
+
+<pre class='example'>
+#include &lt;cups/array.h&gt;
+
+#define HASH_SIZE 512 /* Size of hash table */
+
+static int compare_func(void *first, void *second, void *user_data);
+static int hash_func(void *element, void *user_data);
+
+void *user_data;
+<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew2'>cupsArrayNew2</a>(compare_func, user_data, hash_func, HASH_SIZE);
+</pre>
+
+<p>The hash function (type
+<a href="#cups_ahash_func_t"><code>cups_ahash_func_t</code></a>) returns a
+number from 0 to (hash_size-1) that (hopefully) uniquely identifies the
+element and is called whenever you look up an element in the array with
+<a href='#cupsArrayFind'><code>cupsArrayFind</code></a>. The hash size is
+only limited by available memory, but generally should not be larger than
+16384 to realize any performance improvement.</p>
+
+<p>Once you have created the array, you add elements using the
+<a href='#cupsArrayAdd'><code>cupsArrayAdd</code></a>
+<a href='#cupsArrayInsert'><code>cupsArrayInsert</code></a> functions.
+The first function adds an element to the array, adding the new element
+after any elements that have the same order, while the second inserts the
+element before others with the same order. For unsorted arrays,
+<a href='#cupsArrayAdd'><code>cupsArrayAdd</code></a> appends the elemnt to
+the end of the array while
+<a href='#cupsArrayInsert'><code>cupsArrayInsert</code></a> inserts the
+element at the beginning of the array. For example, the following code
+creates a sorted array of character strings:</p>
+
+<pre class='example'>
+#include &lt;cups/array.h&gt;
+
+/* Use strcmp() to compare strings - it will ignore the user_data pointer */
+<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew'>cupsArrayNew</a>((<a href='#cups_array_func_t'>cups_array_func_t</a>)strcmp, NULL);
+
+/* Add four strings to the array */
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "One Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Two Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Red Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Blue Fish");
</pre>
-<h2 class='title'>Compatibility</h2>
+<p>Elements are removed using the
+<a href='#cupsArrayRemove'><code>cupsArrayRemove</code></a> function, for
+example:</p>
-<p>All of these functions require CUPS 1.2 or higher.</p>
+<pre class='example'>
+#include &lt;cups/array.h&gt;
+
+/* Use strcmp() to compare strings - it will ignore the user_data pointer */
+<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew'>cupsArrayNew</a>((<a href='#cups_array_func_t'>cups_array_func_t</a>)strcmp, NULL);
+
+/* Add four strings to the array */
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "One Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Two Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Red Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Blue Fish");
+
+/* Remove "Red Fish" */
+<a href='#cupsArrayRemove'>cupsArrayRemove</a>(array, "Red Fish");
+</pre>
+
+<p>Finally, you free the memory used by the array using the
+<a href='#cupsArrayDelete'><code>cupsArrayDelete</code></a> function. All
+of the memory for the array and hash table (if any) is freed, however <em>CUPS
+does not free the elements</em> - if necessary, you must allocate and free the
+elements yourself.</p>
+
+<h3><a name='FINDING_AND_ENUMERATING'>Finding and Enumerating Elements</a></h3>
+
+<p>CUPS provides several functions to find and enumerate elements in an
+array. Each one sets or updates a "current index" into the array, such that
+future lookups will start where the last one left off:</p>
+
+<dl>
+ <dt><a href='#cupsArrayFind'><code>cupsArrayFind</code></a></dt>
+ <dd>Returns the first matching element .</dd>
+ <dt><a href='#cupsArrayFirst'><code>cupsArrayFirst</code></a></dt>
+ <dd>Returns the first element in the array.</dd>
+ <dt><a href='#cupsArrayIndex'><code>cupsArrayIndex</code></a></dt>
+ <dd>Returns the Nth element in the array.</dd>
+ <dt><a href='#cupsArrayLast'><code>cupsArrayLast</code></a></dt>
+ <dd>Returns the last element in the array.</dd>
+ <dt><a href='#cupsArrayNext'><code>cupsArrayNext</code></a></dt>
+ <dd>Returns the next element in the array.</dd>
+ <dt><a href='#cupsArrayPrev'><code>cupsArrayPrev</code></a></dt>
+ <dd>Returns the previous element in the array.</dd>
+</dl>
+
+<p>Each of these functions returns <code>NULL</code> when there is no
+corresponding element. For example, a simple <code>for</code> loop using the
+<a href='#cupsArrayFirst'><code>cupsArrayFirst</code></a> and
+<a href='#cupsArrayNext'><code>cupsArrayNext</code></a> functions will
+enumerate all of the strings in our previous example:</p>
+
+<pre class='example'>
+#include &lt;cups/array.h&gt;
+
+/* Use strcmp() to compare strings - it will ignore the user_data pointer */
+<a href='#cups_array_t'>cups_array_t</a> *array = <a href='#cupsArrayNew'>cupsArrayNew</a>((<a href='#cups_array_func_t'>cups_array_func_t</a>)strcmp, NULL);
+
+/* Add four strings to the array */
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "One Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Two Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Red Fish");
+<a href='#cupsArrayAdd'>cupsArrayAdd</a>(array, "Blue Fish");
+
+/* Show all of the strings in the array */
+char *s;
+for (s = (char *)<a href='#cupsArrayFirst'>cupsArrayFirst</a>(array); s != NULL; s = (char *)<a href='#cupsArrayNext'>cupsArrayNext</a>(array))
+ puts(s);
+</pre>
diff --git a/cups/api-cups.header b/cups/api-cups.header
new file mode 100644
index 000000000..a706b55af
--- /dev/null
+++ b/cups/api-cups.header
@@ -0,0 +1,40 @@
+<!--
+ "$Id$"
+
+ CUPS API header for the Common UNIX Printing System (CUPS).
+
+ Copyright 2008 by Apple Inc.
+
+ These coded instructions, statements, and computer programs are the
+ property of Apple Inc. and are protected by Federal copyright
+ law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ which should have been included with this file. If this file is
+ file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">CUPS API</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+ <th>Header</th>
+ <th>cups/cups.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+ <th>Library</th>
+ <td>-lcups</td>
+</tr>
+<tr>
+ <th>See Also</th>
+ <td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a><br>
+ Programming: <a href='api-array.html' target='_top'>Array API</a><br>
+ Programming: <a href='api-filedir.html' target='_top'>File and Directory APIs</a><br>
+ Programming: <a href='api-filter.html' target='_top'>Filter and Backend Programming</a><br>
+ Programming: <a href='api-httpipp.html' target='_top'>HTTP and IPP APIs</a><br>
+ Programming: <a href='api-ppd.html' target='_top'>PPD API</a><br>
+ Programming: <a href='api-raster.html' target='_top'>Raster API</a></td>
+</tr>
+</tbody>
+</table></div>
diff --git a/cups/api-cups.shtml b/cups/api-cups.shtml
index 483feb30b..29982e58d 100644
--- a/cups/api-cups.shtml
+++ b/cups/api-cups.shtml
@@ -3,7 +3,7 @@
CUPS API introduction for the Common UNIX Printing System (CUPS).
- Copyright 2007 by Apple Inc.
+ Copyright 2007-2008 by Apple Inc.
Copyright 1997-2006 by Easy Software Products, all rights reserved.
These coded instructions, statements, and computer programs are the
@@ -13,35 +13,415 @@
file is missing or damaged, see the license at "http://www.cups.org/".
-->
-<h2 class='title'>Introduction</h2>
+<h2 class='title'><a name='OVERVIEW'>Overview</a></h2>
-<p>The CUPS library provides a whole collection of interfaces
-needed to support the internal needs of the CUPS software as well
-as the needs of applications, filters, printer drivers, and
-backends.</p>
+<p>The CUPS API provides the convenience functions needed to support
+applications, filters, printer drivers, and backends that need to interface
+with the CUPS scheduler.</p>
-<p>Unlike the rest of CUPS, the CUPS API library is provided
-under the GNU Library General Public License. This means that you
-can use the CUPS API library in both proprietary and open-source
-programs.</p>
+<h3><a name='PRINTERS_AND_CLASSES'>Printers and Classes</a></h3>
-<h2 class='title'>General Usage</h2>
+<p>Printers and classes (collections of printers) are accessed through
+the <a href="#cups_dest_t"><code>cups_dest_t</code></a> structure which
+includes the name (<code>name</code>), instance (<code>instance</code> -
+a way of selected certain saved options), and the options and attributes
+associated with that destination (<code>num_options</code> and
+<code>options</code>). Destinations are created using the
+<a href="#cupsGetDests"><code>cupsGetDests</code></a> function and freed
+using the <a href='#cupsFreeDests'><code>cupsFreeDests</code></a> function.
+The <a href='#cupsGetDest'><code>cupsGetDest</code></a> function finds a
+specific destination for printing:</p>
-<p>The <var>&lt;cups/cups.h&gt;</var> header file must be included to
-use the CUPS functions.</p>
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
-<p>Programs using these functions must be linked to the CUPS
-library: <var>libcups.a</var>, <var>libcups.so.2</var>,
-<var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
-<var>libcups2.lib</var> depending on the platform. The following
-command compiles <var>myprogram.c</var> using GCC and the CUPS
-library:</p>
+<a href='#cups_dest_t'>cups_dest_t</a> *dests;
+int num_dests = <a href='#cupsGetDests'>cupsGetDests</a>(&amp;dests);
+<a href='#cups_dest_t'>cups_dest_t</a> *dest = <a href='#cupsGetDest'>cupsGetDest</a>("name", NULL, num_dests, dests);
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcups</kbd>
+/* do something wiith dest */
+
+<a href='#cupsFreeDests'>cupsFreeDests</a>(num_dests, dests);
</pre>
-<h2 class='title'>Compatibility</h2>
+<p>Passing <code>NULL</code> to
+<a href='#cupsGetDest'><code>cupsGetDest</code></a> for the destination name
+will return the default destination. Similarly, passing a <code>NULL</code>
+instance will return the default instance for that destination.</p>
+
+<div class='table'><table summary='Table 1: Printer Attributes' width='80%'>
+<caption>Table 1: <a name='TABLE1'>Printer Attributes</a></caption>
+<thead>
+<tr>
+ <th>Attribute Name</th>
+ <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+ <td>"auth-info-required"</td>
+ <td>The type of authentication required for printing to this
+ destination: "none", "username,password", "domain,username,password",
+ or "negotiate" (Kerberos)</td>
+</tr>
+<tr>
+ <td>"printer-info"</td>
+ <td>The human-readable description of the destination such as "My
+ Laser Printer".</td>
+</tr>
+<tr>
+ <td>"printer-is-accepting-jobs"</td>
+ <td>"1" if the destination is accepting new jobs, "0" if not.</td>
+</tr>
+<tr>
+ <td>"printer-is-shared"</td>
+ <td>"1" if the destination is being shared with other computers, "0" if
+ not.</td>
+</tr>
+<tr>
+ <td>"printer-location"</td>
+ <td>The human-readable location of the destination such as "Lab 4".</td>
+</tr>
+<tr>
+ <td>"printer-make-and-model"</td>
+ <td>The human-readable make and model of the destination such as "HP
+ LaserJet 4000 Series".</td>
+</tr>
+<tr>
+ <td>"printer-state"</td>
+ <td>"3" if the destination is idle, "4" if the destination is printing
+ a job, and "5" if the destination is stopped.</td>
+</tr>
+<tr>
+ <td>"printer-state-change-time"</td>
+ <td>The UNIX time when the destination entered the current state.</td>
+</tr>
+<tr>
+ <td>"printer-state-reasons"</td>
+ <td>Additional comma-delimited state keywords for the destination
+ such as "media-tray-empty-error" and "toner-low-warning".</td>
+</tr>
+<tr>
+ <td>"printer-type"</td>
+ <td>The <a href='#cups_printer_t'><code>cups_printer_t</code></a>
+ value associated with the destination.</td>
+</tr>
+</tbody>
+</table></div>
+
+<h3><a name='OPTIONS'>Options</a></h3>
+
+<p>Options are stored in arrays of
+<a href='#cups_option_t'><code>cups_option_t</code></a> structures. Each
+option has a name (<code>name</code>) and value (<code>value</code>)
+associated with it. The <a href='#cups_dest_t'><code>cups_dest_t</code></a>
+<code>num_options</code> and <code>options</code> members contain the
+default options for a particular destination, along with several informational
+attributes about the destination as shown in <a href='#TABLE1'>Table 1</a>.
+The <a href='#cupsGetOption'><code>cupsGetOption</code></a> function gets
+the value for the named option. For example, the following code lists the
+available destinations and their human-readable descriptions:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+<a href='#cups_dest_t'>cups_dest_t</a> *dests;
+int num_dests = <a href='#cupsGetDests'>cupsGetDests</a>(&amp;dests);
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+int i;
+const char *value;
+
+for (i = num_dests, dest = dests; i > 0; i --, dest ++)
+ if (dest->instance == NULL)
+ {
+ value = <a href='#cupsGetOption'>cupsGetOption</a>("printer-info", dest->num_options, dest->options);
+ printf("%s (%s)\n", dest->name, value ? value : "no description");
+ }
+
+<a href='#cupsFreeDests'>cupsFreeDests</a>(num_dests, dests);
+</pre>
+
+<p>You can create your own option arrays using the
+<a href='#cupsAddOption'><code>cupsAddOption</code></a> function, which
+adds a single named option to an array:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+int num_options = 0;
+<a href='#cups_option_t'>cups_option_t</a> *options = NULL;
+
+/* The returned num_options value is updated as needed */
+num_options = <a href='#cupsAddOption'>cupsAddOption</a>("first", "value", num_options, &amp;options);
+
+/* This adds a second option value */
+num_options = <a href='#cupsAddOption'>cupsAddOption</a>("second", "value", num_options, &amp;options);
+
+/* This replaces the first option we added */
+num_options = <a href='#cupsAddOption'>cupsAddOption</a>("first", "new value", num_options, &amp;options);
+</pre>
+
+<p>Use a <code>for</code> loop to copy the options from a destination:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+int i;
+int num_options = 0;
+<a href='#cups_option_t'>cups_option_t</a> *options = NULL;
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+
+for (i = 0; i < dest->num_options; i ++)
+ num_options = <a href='#cupsAddOption'>cupsAddOption</a>(dest->options[i].name, dest->options[i].value, num_options, &amp;options);
+</pre>
+
+<p>Use the <a href='#cupsFreeOptions'><code>cupsFreeOptions</code></a>
+function to free the options array when you are done using it:</p>
+
+<pre class='example'>
+<a href='#cupsFreeOptions'>cupsFreeOptions</a>(num_options, options);
+</pre>
+
+<h3><a name='PRINT_JOBS'>Print Jobs</a></h3>
+
+<p>Print jobs are identified by a locally-unique job ID number from 1 to
+2<sup>31</sup>-1 and have options and one or more files for printing to a
+single destination. The <a href='#cupsPrintFile'><code>cupsPrintFile</code></a>
+function creates a new job with one file. The following code prints the CUPS
+test page file:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+int num_options;
+<a href='#cups_option_t'>cups_option_t</a> *options;
+int job_id;
+
+/* Print a single file */
+job_id = <a href='#cupsPrintFile'>cupsPrintFile</a>(dest->name, "/usr/share/cups/data/testprint.ps", "Test Print", num_options, options);
+</pre>
+
+<p>The <a href='#cupsPrintFiles'><code>cupsPrintFiles</code></a> function
+creates a job with multiple files. The files are provided in a
+<code>char *</code> array:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+int num_options;
+<a href='#cups_option_t'>cups_option_t</a> *options;
+int job_id;
+char *files[3] = { "file1.pdf", "file2.pdf", "file3.pdf" };
+
+/* Print three files */
+job_id = <a href='#cupsPrintFiles'>cupsPrintFiles</a>(dest->name, 3, files, "Test Print", num_options, options);
+</pre>
+
+<p>Finally, the <a href='#cupsCreateJob'><code>cupsCreateJob</code></a>
+function creates a new job with no files in it. Files are added using the
+<a href='#cupsStartDocument'><code>cupsStartDocument</code></a>,
+<a href='api-httpipp.html#cupsWriteRequestData'><code>cupsWriteRequestData</code></a>,
+and <a href='#cupsFinishDocument'><code>cupsFinishDocument</code></a> functions.
+The following example creates a job with 10 text files for printing:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+int num_options;
+<a href='#cups_option_t'>cups_option_t</a> *options;
+int job_id;
+int i;
+char buffer[1024];
+
+/* Create the job */
+job_id = <a href='#cupsCreateJob'>cupsCreateJob</a>(CUPS_HTTP_DEFAULT, dest->name, "10 Text Files", num_options, options);
+
+/* If the job is created, add 10 files */
+if (job_id > 0)
+{
+ for (i = 1; i &lt;= 10; i ++)
+ {
+ snprintf(buffer, sizeof(buffer), "file%d.txt", i);
+
+ <a href='#cupsStartDocument'>cupsStartDocument</a>(CUPS_HTTP_DEFAULT, dest->name, job_id, buffer, CUPS_FORMAT_TEXT, i == 10);
+
+ snprintf(buffer, sizeof(buffer),
+ "File %d\n"
+ "\n"
+ "One fish,\n"
+ "Two fish,\n
+ "Red fish,\n
+ "Blue fish\n", i);
+
+ /* cupsWriteRequestData can be called as many times as needed */
+ <a href='#cupsWriteRequestData'>cupsWriteRequestData</a>(CUPS_HTTP_DEFAULT, buffer, strlen(buffer));
+
+ <a href='#cupsFinishDocument'>cupsFinishDocument</a>(CUPS_HTTP_DEFAULT, dest->name);
+ }
+}
+</pre>
+
+<p>Once you have created a job, you can monitor its status using the
+<a href='#cupsGetJobs'><code>cupsGetJobs</code></a> function, which returns
+an array of <a href='#cups_job_t'><code>cups_job_t</code></a> structures.
+Each contains the job ID (<code>id</code>), destination name
+(<code>dest</code>), title (<code>title</code>), and other information
+associated with the job. The job array is freed using the
+<a href='#cupsFreeJobs'><code>cupsFreeJobs</code></a> function. The following
+example monitors a specific job ID, showing the current job state once every
+5 seconds until the job is completed:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+int job_id;
+int num_jobs;
+<a href='#cups_job_t'>cups_job_t</a> *jobs;
+int i;
+ipp_jstate_t job_state = IPP_JOB_PENDING;
+
+while (job_state &lt; IPP_JOB_STOPPED)
+{
+ /* Get my jobs (1) with any state (-1) */
+ num_jobs = <a href='#cupsGetJobs'>cupsGetJobs</a>(&amp;jobs, dest->name, 1, -1);
+
+ /* Loop to find my job */
+ job_state = IPP_JOB_COMPLETED;
+
+ for (i = 0; i &lt; num_jobs; i ++)
+ if (jobs[i].id == job_id)
+ {
+ job_state = jobs[i].state;
+ break;
+ }
+
+ /* Free the job array */
+ <a href='#cupsFreeJobs'>cupsFreeJobs</a>(num_jobs, jobs);
+
+ /* Show the current state */
+ switch (job_state)
+ {
+ case IPP_JOB_PENDING :
+ printf("Job %d is pending.\n", job_id);
+ break;
+ case IPP_JOB_HELD :
+ printf("Job %d is held.\n", job_id);
+ break;
+ case IPP_JOB_PROCESSING :
+ printf("Job %d is processing.\n", job_id);
+ break;
+ case IPP_JOB_STOPPED :
+ printf("Job %d is stopped.\n", job_id);
+ break;
+ case IPP_JOB_CANCELED :
+ printf("Job %d is canceled.\n", job_id);
+ break;
+ case IPP_JOB_ABORTED :
+ printf("Job %d is aborted.\n", job_id);
+ break;
+ case IPP_JOB_COMPLETED :
+ printf("Job %d is completed.\n", job_id);
+ break;
+ }
+
+ /* Sleep if the job is not finished */
+ if (job_state &lt; IPP_JOB_STOPPED)
+ sleep(5);
+}
+</pre>
+
+<p>To cancel a job, use the
+<a href='#cupsCancelJob'><code>cupsCancelJob</code></a> function with the
+job ID:</p>
+
+<pre class='exmaple'>
+#include &lt;cups/cups.h&gt;
+
+<a href='#cups_dest_t'>cups_dest_t</a> *dest;
+int job_id;
+
+<a href='#cupsCancelJob'>cupsCancelJob</a>(dest->name, job_id);
+</pre>
+
+<h3><a name='ERROR_HANDLING'>Error Handling</a></h3>
+
+<p>If any of the CUPS API printing functions returns an error, the reason for
+that error can be found by calling the
+<a href='#cupsLastError'><code>cupsLastError</code></a> and
+<a href='#cupsLastErrorString'><code>cupsLastErrorString</code></a> functions.
+<a href='#cupsLastError'><code>cupsLastError</code></a> returns the last IPP
+error code
+(<a href='api-httpipp.html#ipp_status_t'><code>ipp_status_t</code></a>)
+that was encountered, while
+<a href='#cupsLastErrorString'><code>cupsLastErrorString</code></a> returns
+a (localized) human-readable string that can be shown to the user. For example,
+if any of the job creation functions returns a job ID of 0, you can use
+<a href='#cupsLastErrorString'><code>cupsLastErrorString</code></a> to show
+the reason why the job could not be created:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+int job_id;
+
+if (job_id == 0)
+ puts(cupsLastErrorString());
+</pre>
+
+<h3><a name='PASSWORDS_AND_AUTHENTICATION'>Passwords and Authentication</a></h3>
+
+<p>CUPS supports authentication of any request, including submission of print
+jobs. The default mechanism for getting the username and password is to use the
+login user and a password from the console.</p>
+
+<p>To support other types of applications, in particular Graphical User
+Interfaces ("GUIs"), the CUPS API provides functions to set the default
+username and to register a callback function that returns a password string.</p>
+
+<p>The <a href="#cupsSetPasswordCB"><code>cupsSetPasswordCB</code></a>
+function is used to set a password callback in your program. Only one
+function can be used at any time.</p>
+
+<p>The <a href="#cupsSetUser"><code>cupsSetUser</code></a> function sets the
+current username for authentication. This function can be called by your
+password callback function to change the current username as needed.</p>
+
+<p>The following example shows a simple password callback that gets a
+username and password from the user:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+const char *
+my_password_cb(const char *prompt)
+{
+ char user[65];
+
+
+ puts(prompt);
+
+ /* Get a username from the user */
+ printf("Username: ");
+ if (fgets(user, sizeof(user), stdin) == NULL)
+ return (NULL);
+
+ /* Strip the newline from the string and set the user */
+ user[strlen(user) - 1] = '\0';
+
+ <a href='#cupsSetUser'>cupsSetUser</a>(user);
+
+ /* Use getpass() to ask for the password... */
+ return (getpass("Password: "));
+}
+
+<a href='#cupsSetPasswordCB'>cupsSetPasswordCB</a>(my_password_cb);
+</pre>
-<p>Unless otherwise specified, the CUPS API functions require
-CUPS 1.1 or higher.</p>
+<p>Similarly, a GUI could display the prompt string in a window with input
+fields for the username and password. The username should default to the
+string returned by the <a href="#cupsUser"><code>cupsUser</code></a>
+function.</p>
diff --git a/cups/api-filedir.header b/cups/api-filedir.header
new file mode 100644
index 000000000..755311511
--- /dev/null
+++ b/cups/api-filedir.header
@@ -0,0 +1,36 @@
+<!--
+ "$Id$"
+
+ File and Directory API header for the Common UNIX Printing System (CUPS).
+
+ Copyright 2008 by Apple Inc.
+
+ These coded instructions, statements, and computer programs are the
+ property of Apple Inc. and are protected by Federal copyright
+ law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ which should have been included with this file. If this file is
+ file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">File and Directory APIs</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+ <th>Headers</th>
+ <th>cups/file.h<br>
+ cups/dir.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+ <th>Library</th>
+ <td>-lcups</td>
+</tr>
+<tr>
+ <th>See Also</th>
+ <td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a><br>
+ Programming: <a href='api-cups.html' target='_top'>CUPS API</a></td>
+</tr>
+</tbody>
+</table></div>
diff --git a/cups/api-filedir.shtml b/cups/api-filedir.shtml
index b356e655c..2b19efa8a 100644
--- a/cups/api-filedir.shtml
+++ b/cups/api-filedir.shtml
@@ -3,7 +3,7 @@
File and directory API introduction for the Common UNIX Printing System (CUPS).
- Copyright 2007 by Apple Inc.
+ Copyright 2007-2008 by Apple Inc.
Copyright 1997-2005 by Easy Software Products, all rights reserved.
These coded instructions, statements, and computer programs are the
@@ -13,45 +13,19 @@
file is missing or damaged, see the license at "http://www.cups.org/".
-->
-<h2 class='title'>Introduction</h2>
+<h2 class='title'><a name="OVERVIEW">Overview</a></h2>
<p>The CUPS file and directory APIs provide portable interfaces
for manipulating files and listing files and directories. Unlike
-stdio <tt>FILE</tt> streams, the <tt>cupsFile</tt> functions
+stdio <code>FILE</code> streams, the <code>cupsFile</code> functions
allow you to open more than 256 files at any given time. They
also manage the platform-specific details of locking, large file
support, line endings (CR, LF, or CR LF), and reading and writing
files using Flate ("gzip") compression. Finally, you can also
connect, read from, and write to network connections using the
-<tt>cupsFile</tt> functions.</p>
+<code>cupsFile</code> functions.</p>
-<p>The <tt>cupsDir</tt> functions manage the platform-specific
+<p>The <code>cupsDir</code> functions manage the platform-specific
details of directory access/listing and provide a convenient way
to get both a list of files and the information (permissions,
size, timestamp, etc.) for each of those files.</p>
-
-<p>The CUPS scheduler (<tt>cupsd</tt>), <tt>mailto</tt> notifier,
-and many of the CUPS API functions use these functions for
-everything except console (stdin, stdout, stderr) I/O.</p>
-
-<h2 class='title'>General Usage</h2>
-
-<p>The <var>&lt;cups/dir.h&gt;</var> and
-<var>&lt;cups/file.h&gt;</var> header files must be included to
-use the <tt>cupsDir</tt> and <tt>cupsFile</tt> functions,
-respectively.</p>
-
-<p>Programs using these functions must be linked to the CUPS
-library: <var>libcups.a</var>, <var>libcups.so.2</var>,
-<var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
-<var>libcups2.lib</var> depending on the platform. The following
-command compiles <var>myprogram.c</var> using GCC and the CUPS
-library:</p>
-
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcups</kbd>
-</pre>
-
-<h2 class='title'>Compatibility</h2>
-
-<p>All of these functions require CUPS 1.2 or higher.</p>
diff --git a/cups/api-filter.header b/cups/api-filter.header
new file mode 100644
index 000000000..f7ae6a368
--- /dev/null
+++ b/cups/api-filter.header
@@ -0,0 +1,39 @@
+<!--
+ "$Id$"
+
+ Filter and backend programming header for the Common UNIX Printing System
+ (CUPS).
+
+ Copyright 2008 by Apple Inc.
+
+ These coded instructions, statements, and computer programs are the
+ property of Apple Inc. and are protected by Federal copyright
+ law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ which should have been included with this file. If this file is
+ file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">Filter and Backend Programming</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+ <th>Header</th>
+ <th>cups/backend.h<br>
+ cups/sidechannel.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+ <th>Library</th>
+ <td>-lcups</td>
+</tr>
+<tr>
+ <th>See Also</th>
+ <td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a><br>
+ Programming: <a href='api-cups.html' target='_top'>CUPS API</a><br>
+ Programming: <a href='api-ppd.html' target='_top'>PPD API</a><br>
+ Programming: <a href='api-raster.html' target='_top'>Raster API</a></td>
+</tr>
+</tbody>
+</table></div>
diff --git a/cups/api-filter.shtml b/cups/api-filter.shtml
index 0eda305c7..4f72dfe71 100644
--- a/cups/api-filter.shtml
+++ b/cups/api-filter.shtml
@@ -1,9 +1,10 @@
<!--
"$Id: api-filter.shtml 6649 2007-07-11 21:46:42Z mike $"
- Filter and backend API introduction for the Common UNIX Printing System (CUPS).
+ Filter and backend programming introduction for the Common UNIX Printing
+ System (CUPS).
- Copyright 2007 by Apple Inc.
+ Copyright 2007-2008 by Apple Inc.
Copyright 1997-2006 by Easy Software Products, all rights reserved.
These coded instructions, statements, and computer programs are the
@@ -13,132 +14,220 @@
file is missing or damaged, see the license at "http://www.cups.org/".
-->
-<h2 class='title'>Introduction</h2>
+<h2 class='title'><a name="OVERVIEW">Overview</a></h2>
-<p>The CUPS filter and backend APIs define standard exit codes
-and provide access to the backchannel data stream. They are only
-used when writing backends, filters, and port monitors.</p>
+<p>Filters, printer drivers, port monitors, and backends use a common interface
+for processing print jobs and communicating status information to the scheduler.
+Each filter is run with a standard set of command-line arguments:<p>
-<h2 class='title'>General Usage</h2>
+<dl class="code">
-<p>The <var>&lt;cups/backend.h&gt;</var> and
-<var>&lt;cups/cups.h&gt;</var> header files must be included to
-use the <tt>CUPS_BACKEND_</tt> constants and
-<tt>cupsBackChannel</tt> functions, respectively.</p>
+ <dt>argv[1]</dt>
+ <dd>The job ID</dd>
-<p>The <var>&lt;cups/sidechannel.h&gt;</var> header file must be
-included to use the <tt>CUPS_SC_</tt> constants and <tt>cupsSideChannel</tt> functions.</p>
+ <dt>argv[2]</dt>
+ <dd>The user printing the job</dd>
-<p>Programs using these functions must be linked to the CUPS
-library: <var>libcups.a</var>, <var>libcups.so.2</var>,
-<var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
-<var>libcups2.lib</var> depending on the platform. The following
-command compiles <var>myprogram.c</var> using GCC and the CUPS
-library:</p>
+ <dt>argv[3]</dt>
+ <dd>The job name/title</dd>
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcups</kbd>
-</pre>
+ <dt>argv[4]</dt>
+ <dd>The number of copies to print</dd>
+ <dt>argv[5]</dt>
+ <dd>The options that were provided when the job was submitted</dd>
-<h2 class='title'>Compatibility</h2>
+ <dt>argv[6]</dt>
+ <dd>The file to print (first filter only)</dd>
+</dl>
-<p>The <tt>cupsBackChannel</tt> functions require CUPS 1.2 or higher. The <tt>cupsSideChannel</tt> functions require CUPS 1.3 or higher.</p>
+<p>The scheduler runs one or more of these programs to print any given job. The
+first filter reads from the print file and writes to the standard output, while
+the remaining filters read from the standard input and write to the standard
+output. The backend is the last filter in the chain and writes to the
+device.</p>
+<h3><a name="EXITCODES">Exit Codes</a></h3>
-<h2 class='title'>Using the cupsBackChannel APIs</h2>
+<p>Filters must exit with status 0 when they successfully generate print data
+or 1 when they encounter an error. Backends can return any of the
+<a href="#cups_backend_t"><code>cups_backend_t</code></a> constants.</p>
-<p>The <tt>cupsBackChannel</tt> APIs allow your filters, drivers, and port monitors to read data back from a printer and your backends to send data from a printer to the filters, drivers, and port monitors associated with the current job. Back-channel data is normally sent by the printer in response to a command sent from your program to the printer via <tt>stdout</tt>.</p>
+<h3><a name="ENVIRONMENT">Environment Variables</a></h3>
-<p>The <tt>cupsBackChannelRead()</tt> function reads data from the printer via the backend. You provide a timeout in seconds along with a buffer pointer and the size of that buffer. It returns the number of bytes or -1 if there was an error. The following code example shows how to poll for back-channel data in your program:</p>
+<p>The following environment variables are defined by the printing system:</p>
-<pre class='command'>
-#include &lt;cups/cups.h&gt;
+<dl class="code">
-char buffer[8192];
-ssize_t bytes;
+ <dt>APPLE_LANGUAGES</dt>
+ <dd>The Apple language identifier associated with the job
+ (Mac OS X only).</dd>
-/* Use a timeout of 0.0 seconds to poll for back-channel data */
-bytes = cupsBackChannelRead(buffer, sizeof(buffer), 0.0);
-</pre>
+ <dt>CHARSET</dt>
+ <dd>The job character set, typically "utf-8".</dd>
-<p>If you are writing a backend, the <tt>cupsBackChannelWrite()</tt> function sends any back-channel data you have received from the printer to upstream filters in the print filter chain. We recommend using a timeout of 1.0 seconds:</p>
+ <dt>CLASS</dt>
+ <dd>When a job is submitted to a printer class, contains the name of
+ the destination printer class. Otherwise this environment
+ variable will not be set.</dd>
-<pre class='command'>
-#include &lt;cups/cups.h&gt;
+ <dt>CONTENT_TYPE</dt>
+ <dd>The MIME type associated with the file (e.g.
+ application/postscript).</dd>
-char buffer[8192];
-ssize_t bytes;
-
-/* Use a timeout of 1.0 seconds to give filters a chance to read */
-cupsBackChannelWrite(buffer, bytes, 1.0);
-</pre>
+ <dt>CUPS_CACHEDIR</dt>
+ <dd>The directory where cache files can be stored.</dd>
+ <dt>CUPS_DATADIR</dt>
+ <dd>The directory where data files can be found.</dd>
-<h2 class='title'>Using the cupsSideChannel APIs</h2>
+ <dt>CUPS_SERVERROOT</dt>
+ <dd>The root directory of the server.</dd>
-<p>The <tt>cupsSideChannel</tt> APIs allow your filters, drivers, port monitors, and backend to send and receive the following out-of-band commands:</p>
+ <dt>DEVICE_URI</dt>
+ <dd>The device-uri associated with the printer.</dd>
-<ul>
+ <dt>FINAL_CONTENT_TYPE</dt>
+ <dd>The MIME type associated with the printer (e.g.
+ application/vnd.cups-postscript).</dd>
- <li><tt>CUPS_SC_CMD_SOFT_RESET</tt> - Do a soft reset</li>
- <li><tt>CUPS_SC_CMD_DRAIN_OUTPUT</tt> - Drain all pending output</li>
- <li><tt>CUPS_SC_CMD_GET_BIDI</tt> - Return bidirectional capabilities</li>
- <li><tt>CUPS_SC_CMD_GET_DEVICE_ID</tt> - Return the IEEE-1284 device ID</li>
- <li><tt>CUPS_SC_CMD_GET_STATE</tt> - Return the device state</li>
+ <dt>LANG</dt>
+ <dd>The language locale associated with the job.</dd>
-</ul>
+ <dt>PPD</dt>
+ <dd>The full pathname of the PostScript Printer Description (PPD)
+ file for this printer.</dd>
+ <dt>PRINTER</dt>
+ <dd>The name of the printer.</dd>
-<h3>Sending Commands from a Filter, Driver, or Port Monitor</h3>
+ <dt>RIP_CACHE</dt>
+ <dd>The recommended amount of memory to use for Raster Image
+ Processors (RIPs).</dd>
-<p>The <tt>cupsSideChannelDoRequest()</tt> function is used by filters, drivers, and port monitors to send a command to the backend and read back a response:</p>
-
-<pre class='command'>
-cups_sc_status_t cupsSideChannelDoRequest(cups_sc_command_t command,
- char *data, int *datalen,
- double timeout);
-</pre>
+</dl>
-<p>The <tt>CUPS_SC_CMD_SOFT_RESET</tt> and <tt>CUPS_SC_CMD_DRAIN_OUTPUT</tt> commands do not return any data values, while the others return one or more bytes. The <tt>timeout</tt> parameter allows your program to poll or wait for the command to complete - use a timeout of 30 seconds for <tt>CUPS_SC_CMD_SOFT_RESET</tt> and <tt>CUPS_SC_CMD_DRAIN_OUTPUT</tt> and a timeout of 1 second for all other commands.</p>
+<h3><a name="MESSAGES">Communicating with the Scheduler</a></h3>
-<p><tt>CUPS_SC_CMD_GET_BIDI</tt> returns a single <tt>char</tt> value that tells you whether the backend supports bidirectional communications:</p>
+<p>Filters and backends communicate wih the scheduler by writing messages
+to the standard error file. For example, the following code sets the current
+printer state message to "Printing page 5":</p>
-<pre class='command'>
-#include &lt;cups/sidechannel.h&gt;
+<pre class="example">
+int page = 5;
-char data;
-int datalen;
-cups_sc_bidi_t bidi;
-cups_sc_status_t status;
+fprintf(stderr, "INFO: Printing page %d\n", page);
+</pre>
-/* Tell cupsSideChannelDoRequest() how big our buffer is... */
-datalen = 1;
+<p>Each message is a single line of text starting with one of the following
+prefix strings:</p>
+
+<dl class="code">
+
+ <dt>ALERT: message</dt>
+ <dd>Sets the printer-state-message attribute and adds the specified
+ message to the current error log file using the "alert" log level.</dd>
+
+ <dt>ATTR: attribute=value [attribute=value]</dt>
+ <dd>Sets the named printer or job attribute(s). Typically this is used
+ to set the <code>marker-colors</code>, <code>marker-levels</code>,
+ <code>marker-names</code>, <code>marker-types</code>,
+ <code>printer-alert</code>, and <code>printer-alert-description</code>
+ printer attributes.</dd>
+
+ <dt>CRIT: message</dt>
+ <dd>Sets the printer-state-message attribute and adds the specified
+ message to the current error log file using the "critical" log
+ level.</dd>
+
+ <dt>DEBUG: message</dt>
+ <dd>Sets the printer-state-message attribute and adds the specified
+ message to the current error log file using the "debug" log level.</dd>
+
+ <dt>DEBUG2: message</dt>
+ <dd>Sets the printer-state-message attribute and adds the specified
+ message to the current error log file using the "debug2" log level.</dd>
+
+ <dt>EMERG: message</dt>
+ <dd>Sets the printer-state-message attribute and adds the specified
+ message to the current error log file using the "emergency" log
+ level.</dd>
+
+ <dt>ERROR: message</dt>
+ <dd>Sets the printer-state-message attribute and adds the specified
+ message to the current error log file using the "error" log level.</dd>
+
+ <dt>INFO: message</dt>
+ <dd>Sets the printer-state-message attribute. If the current log level
+ is set to "debug2", also adds the specified message to the current error
+ log file using the "info" log level.</dd>
+
+ <dt>NOTICE: message</dt>
+ <dd>Sets the printer-state-message attribute and adds the specified
+ message to the current error log file using the "notice" log level.</dd>
+
+ <dt>PAGE: page-number #-copies</dt>
+ <dt>PAGE: total #-pages</dt>
+ <dd>Adds an entry to the current page log file. The first form adds
+ #-copies to the job-media-sheets-completed attribute. The second
+ form sets the job-media-sheets-completed attribute to #-pages.</dd>
+
+ <dt>STATE: printer-state-reason [printer-state-reason ...]</dt>
+ <dt>STATE: + printer-state-reason [printer-state-reason ...]</dt>
+ <dt>STATE: - printer-state-reason [printer-state-reason ...]</dt>
+ <dd>Sets, adds, or removes printer-state-reason keywords to the
+ current queue. Typically this is used to indicate media, ink, and
+ toner conditions on a printer.</dd>
+
+ <dt>WARNING: message</dt>
+ <dd>Sets the printer-state-message attribute and adds the specified
+ message to the current error log file using the "warning" log
+ level.</dd>
+
+</dl>
+
+<p>Messages without one of these prefixes are treated as if they began with
+the "DEBUG:" prefix string.</p>
+
+<h3><a name="COMMUNICATING">Communicating with the Backend</a></h3>
+
+<p>Filters can communicate with the backend via the
+<a href="#cupsBackChannelRead"><code>cupsBackChannelRead</code></a> and
+<a href="#cupsSideChannelDoRequest"><code>cupsSideChannelDoRequest</code></a>
+functions. The
+<a href="#cupsBackChannelRead"><code>cupsBackChannelRead</code></a> function
+reads data that has been sent back from the device and is typically used to
+obtain status and configuration information. For example, the following code
+polls the backend for back-channel data:</p>
+
+<pre class="example">
+#include &lt;cups/cups.h&gt;
-/* Get the bidirectional capabilities, waiting for up to 1 second */
-status = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_BIDI, &amp;data, &amp;datalen, 1.0);
+char buffer[8192];
+ssize_t bytes;
-/* Use the returned value if OK was returned and the length is still 1 */
-if (status == CUPS_SC_STATUS_OK && datalen == 1)
- bidi = (cups_sc_bidi_t)data;
-else
- bidi = CUPS_SC_BIDI_NOT_SUPPORTED;
+/* Use a timeout of 0.0 seconds to poll for back-channel data */
+bytes = cupsBackChannelRead(buffer, sizeof(buffer), 0.0);
</pre>
-<p><tt>CUPS_SC_CMD_GET_DEVICE_ID</tt> returns a string of characters containing the IEEE-1284 device ID for the connected printer:</p>
+The
+<a href="#cupsSideChannelDoRequest"><code>cupsSideChannelDoRequest</code></a>
+function allows you to get out-of-band status information and do synchronization
+with the device. For example, the following code gets the current IEEE-1284
+device ID string from the backend:</p>
-<pre class='command'>
+<pre class="example">
#include &lt;cups/sidechannel.h&gt;
char data[2049];
int datalen;
-cups_sc_status_t status;
+<a href="#cups_sc_status_t">cups_sc_status_t</a> status;
/* Tell cupsSideChannelDoRequest() how big our buffer is, less 1 byte for nul-termination... */
datalen = sizeof(data) - 1;
/* Get the IEEE-1284 device ID, waiting for up to 1 second */
-status = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_DEVICE_ID, data, &amp;datalen, 1.0);
+status = <a href="#cupsSideChannelDoRequest">cupsSideChannelDoRequest</a>(CUPS_SC_CMD_GET_DEVICE_ID, data, &amp;datalen, 1.0);
/* Use the returned value if OK was returned and the length is non-zero */
if (status == CUPS_SC_STATUS_OK && datalen > 0)
@@ -147,59 +236,53 @@ else
data[0] = '\0';
</pre>
-<p><tt>CUPS_SC_CMD_GET_STATE</tt> returns a single <tt>char</tt> value that tells you the current device state:</p>
-
-<pre class='command'>
-#include &lt;cups/sidechannel.h&gt;
+<p>Backends communicate with filters using the reciprocal functions
+<a href="#cupsBackChannelWrite"><code>cupsBackChannelWrite</code></a>,
+<a href="#cupsSideChannelRead"><code>cupsSideChannelRead</code></a>, and
+<a href="#cupsSideChannelWrite"><code>cupsSideChannelWrite</code></a>. We
+recommend writing back-channel data using a timeout of 1.0 seconds:</p>
-char data;
-int datalen;
-cups_sc_state_t state;
-cups_sc_status_t status;
-
-/* Tell cupsSideChannelDoRequest() how big our buffer is... */
-datalen = 1;
-
-/* Get the bidirectional capabilities, waiting for up to 1 second */
-status = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_STATE, &amp;data, &amp;datalen, 1.0);
-
-/* Use the returned value if OK was returned and the length is still 1 */
-if (status == CUPS_SC_STATUS_OK && datalen == 1)
- state = (cups_sc_state_t)data;
-else
- state = CUPS_SC_STATE_OFFLINE;
-</pre>
-
-
-<h3>Handling Commands in your Backend</h3>
+<pre class="example">
+#include &lt;cups/cups.h&gt;
-<p>The <tt>cupsSideChannelRead()</tt> function is used by backends to read a command from a filter, driver, or port monitor:</p>
+char buffer[8192];
+ssize_t bytes;
-<pre class='command'>
-int cupsSideChannelRead(cups_sc_command_t &amp;command,
- cups_sc_status_t &amp;status,
- char *data, int *datalen, double timeout);
+/* Use a timeout of 1.0 seconds to give filters a chance to read */
+cupsBackChannelWrite(buffer, bytes, 1.0);
</pre>
-<p>Backends can either poll for commands using a <tt>timeout</tt> of 0.0, wait indefinitely for commands using a <tt>timeout</tt> of -1.0 (probably in a separate thread for that purpose), or use <tt>select()</tt> or <tt>poll()</tt> on the <tt>CUPS_SC_FD</tt> file descriptor (4) to handle input and output on several file descriptors at the same time. Backends can pass <tt>NULL</tt> for the <tt>data</tt> and <tt>datalen</tt> parameters, since none of the commands sent by upstream filters contain any data at this time.</p>
-
-<p>Once a command is processed, the backend uses the <tt>cupsSideChannelWrite()</tt> function to send its response:</p>
-
-<pre class='command'>
+<p>The <a href="#cupsSideChannelRead"><code>cupsSideChannelRead</code></a>
+function reads a side-channel command from a filter, driver, or port monitor.
+Backends can either poll for commands using a <code>timeout</code> of 0.0, wait
+indefinitely for commands using a <code>timeout</code> of -1.0 (probably in a
+separate thread for that purpose), or use <code>select</code> or
+<code>poll</code> on the <code>CUPS_SC_FD</code> file descriptor (4) to handle
+input and output on several file descriptors at the same time. Backends can pass
+<code>NULL</code> for the <code>data</code> and <code>datalen</code> parameters
+since none of the commands sent by upstream filters contain any data at this
+time.</p>
+
+<p>Once a command is processed, the backend uses the
+<a href="#cupsSideChannelWrite"><code>cupsSideChannelWrite</code></a> function
+to send its response. For example, the following code shows how to poll for a
+side-channel command and respond to it:</p>
+
+<pre class="example">
#include &lt;cups/sidechannel.h&gt;
-cups_sc_command_t command;
-cups_sc_status_t status;
+<a href="#cups_sc_command_t">cups_sc_command_t</a> command;
+<a href="#cups_sc_status_t">cups_sc_status_t</a> status;
/* Poll for a command... */
-if (!cupsSideChannelRead(&amp;command, &amp;status, NULL, NULL, 0.0))
+if (!<a href="#cupsSideChannelRead">cupsSideChannelRead</a>(&amp;command, &amp;status, NULL, NULL, 0.0))
{
char data[2048];
int datalen;
switch (command)
{
- ... handle supported commands, file data/datalen/status with values as needed ...
+ /* handle supported commands, file data/datalen/status with values as needed */
default :
status = CUPS_SC_STATUS_NOT_IMPLEMENTED;
@@ -208,6 +291,6 @@ if (!cupsSideChannelRead(&amp;command, &amp;status, NULL, NULL, 0.0))
}
/* Send a response... */
- cupsSideChannelWrite(command, status, data, datalen, 1.0);
+ <a href="#cupsSideChannelWrite">cupsSideChannelWrite</a>(command, status, data, datalen, 1.0);
}
</pre>
diff --git a/cups/api-httpipp.header b/cups/api-httpipp.header
new file mode 100644
index 000000000..03d5a8def
--- /dev/null
+++ b/cups/api-httpipp.header
@@ -0,0 +1,37 @@
+<!--
+ "$Id$"
+
+ HTTP and IPP API header for the Common UNIX Printing System (CUPS).
+
+ Copyright 2007-2008 by Apple Inc.
+ Copyright 1997-2006 by Easy Software Products, all rights reserved.
+
+ These coded instructions, statements, and computer programs are the
+ property of Apple Inc. and are protected by Federal copyright
+ law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ which should have been included with this file. If this file is
+ file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">HTTP and IPP APIs</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+ <th>Header</th>
+ <th>cups/cups.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+ <th>Library</th>
+ <td>-lcups</td>
+</tr>
+<tr>
+ <th>See Also</th>
+ <td>Programming: <a href='api-overview.html'>Introduction to CUPS Programming</a><br>
+ Programming: <a href='api-cups.html'>CUPS API</a><br>
+ References: <a href='spec-ipp.html'>CUPS Implementation of IPP</a></td>
+</tr>
+</tbody>
+</table></div>
diff --git a/cups/api-httpipp.shtml b/cups/api-httpipp.shtml
index 93e34f934..b755b7ded 100644
--- a/cups/api-httpipp.shtml
+++ b/cups/api-httpipp.shtml
@@ -3,7 +3,7 @@
HTTP and IPP API introduction for the Common UNIX Printing System (CUPS).
- Copyright 2007 by Apple Inc.
+ Copyright 2007-2008 by Apple Inc.
Copyright 1997-2006 by Easy Software Products, all rights reserved.
These coded instructions, statements, and computer programs are the
@@ -13,31 +13,311 @@
file is missing or damaged, see the license at "http://www.cups.org/".
-->
-<h2 class='title'>Introduction</h2>
+<h2 class='title'><a name='OVERVIEW'>Overview</a></h2>
-<p>The CUPS HTTP and IPP APIs provide low-level access to the
-HTTP and IPP protocols and CUPS scheduler. They are typically
-used by monitoring and administration programs to perform
-specific functions not supported by the high-level CUPS API
-functions.</p>
+<p>The CUPS HTTP and IPP APIs provide low-level access to the HTTP and IPP
+protocols and CUPS scheduler. They are typically used by monitoring and
+administration programs to perform specific functions not supported by the
+high-level CUPS API functions.</p>
-<h2 class='title'>General Usage</h2>
+<p>The HTTP APIs use an opaque structure called
+<a href='#http_t'><code>http_t</code></a> to manage connections to
+a particular HTTP or IPP server. The
+<a href='#httpConnectEncrypt'><code>httpConnectEncrypt</code></a> function is
+used to create an instance of this structure for a particular server.
+The constant <code>CUPS_HTTP_DEFAULT</code> can be used with all of the
+<code>cups</code> functions to refer to the default CUPS server - the functions
+create a per-thread <a href='#http_t'><code>http_t</code></a> as needed.</p>
-<p>The <var>&lt;cups/cups.h&gt;</var> header file must be included to
-use the HTTP and IPP functions.</p>
+<p>The IPP APIs use two structures for requests (messages sent to the CUPS
+scheduler) and responses (messages sent back to your application from the
+scheduler). The <a href='#ipp_t'><code>ipp_t</code></a> structure holds a
+complete request or response and is allocated using the
+<a href='#ippNew'><code>ippNew</code></a> or
+<a href='#ippNewRequest'><code>ippNewRequest</code></a> functions and
+freed using the <a href='#ippDelete'><code>ippDelete</code></a> function.</p>
-<p>Programs using these functions must be linked to the CUPS
-library: <var>libcups.a</var>, <var>libcups.so.2</var>,
-<var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
-<var>libcups2.lib</var> depending on the platform. The following
-command compiles <var>myprogram.c</var> using GCC and the CUPS
-library:</p>
+<p>The second structure is called
+<a href='#ipp_attribute_t'><code>ipp_attribute_t</code></a> and holds a
+single IPP attribute which consists of a group tag (<code>group_tag</code>), a
+value type tag (<code>value_tag</code>), the attribute name (<code>name</code>),
+and 1 or more values (<code>values[]</code>). Attributes are added to an
+<a href='#ipp_t'><code>ipp_t</code></a> structure using one of the
+<code>ippAdd</code> functions. For example, use
+<a href='#ippAddString'><code>ippAddString</code></a> to add a
+"requesting-user-name" string attribute to a request:</p>
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcups</kbd>
+<pre class='example'>
+<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(IPP_GET_JOBS);
+
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, cupsUser());
+</pre>
+
+<p>Once you have created an IPP request, use the <code>cups</code>
+functions to send the request to and read the response from the server.
+For example, the <a href='#cupsDoRequest'><code>cupsDoRequest</code></a>
+function can be used for simple query operations that do not involve files:</p>
+
+<pre class='example'>
+#include &lt;cups/cups.h&gt;
+
+
+<a href='#ipp_t'>ipp_t</a> *<a name='get_jobs'>get_jobs</a>(void)
+{
+ <a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(IPP_GET_JOBS);
+
+ <a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, cupsUser());
+
+ return (<a href='#cupsDoRequest'>cupsDoRequest</a>(CUPS_HTTP_DEFAULT, request, "/"));
+}
+</pre>
+
+<p>The <a href='#cupsDoRequest'><code>cupsDoRequest</code></a> function frees
+the request structure and returns an IPP response structure or NULL pointer if
+the request could not be sent to the server. Once you have a response from
+the server, you can either use the
+<a href='#ippFindAttribute'><code>ippFindAttribute</code></a> and
+<a href='#ippFindNextAttribute'><code>ippFindNextAttribute</code></a> functions
+to find specific attributes, for example:</p>
+
+<pre class='example'>
+<a href='#ipp_t'>ipp_t</a> *response;
+<a href='#ipp_attribute_t'>ipp_attribute_t</a> *attr;
+
+attr = <a href='#ippFindAttribute'>ippFindAttribute</a>(response, "printer-state", IPP_TAG_ENUM);
+</pre>
+
+<p>You can also walk the list of attributes with a simple <code>for</code> loop
+like this:</p>
+
+<pre class='example'>
+<a href='#ipp_t'>ipp_t</a> *response;
+<a href='#ipp_attribute_t'>ipp_attribute_t</a> *attr;
+
+for (attr = response->attrs; attr != NULL; attr = attr->next)
+ if (attr->name == NULL)
+ puts("--SEPARATOR--");
+ else
+ puts(attr->name);
</pre>
-<h2 class='title'>Compatibility</h2>
+<p>The <code>for</code> loop approach is normally used when collecting
+attributes for multiple objects (jobs, printers, etc.) in a response. Attributes
+with <code>NULL</code> names indicate a separator between the attributes of
+each object. For example, the following code will list the jobs returned from
+our previous <a href='#get_jobs'><code>get_jobs</code></a> example code:</p>
+
+<pre class='example'>
+<a href='#ipp_t'>ipp_t</a> *response = <a href='#get_jobs'>get_jobs</a>();
+
+if (response != NULL)
+{
+ <a href='#ipp_attribute_t'>ipp_attribute_t</a> *attr;
+ int job_id = 0;
+ char *job_name = NULL;
+ char *job_originating_user_name = NULL;
+
+ puts("Job ID Owner Title");
+ puts("------ ---------------- ---------------------------------");
+
+ for (attr = response->attrs; attr != NULL; attr = attr->next)
+ {
+ /* Attributes without names are separators between jobs */
+ if (attr->name == NULL)
+ {
+ if (job_id > 0 &amp;&amp; job_name != NULL &amp;&amp; job_originating_user_name != NULL)
+ printf("%5d %-16s %s\n", job_id, job_originating_user_name, job_name);
+
+ job_id = 0;
+ job_name = NULL;
+ job_originating_user_name = NULL;
+ continue;
+ }
+ else if (!strcmp(attr->name, "job-id") &amp;&amp; attr->value_tag == IPP_TAG_INTEGER)
+ job_id = attr->values[0].integer;
+ else if (!strcmp(attr->name, "job-name") &amp;&amp; attr->value_tag == IPP_TAG_NAME)
+ job_name = attr->values[0].string.text;
+ else if (!strcmp(attr->name, "job-originating-user-name") &amp;&amp;
+ attr->value_tag == IPP_TAG_NAME)
+ job_originating_user_name = attr->values[0].string.text;
+ }
+
+ if (job_id > 0 &amp;&amp; job_name != NULL &amp;&amp; job_originating_user_name != NULL)
+ printf("%5d %-16s %s\n", job_id, job_originating_user_name, job_name);
+}
+</pre>
+
+<h3><a name='CREATING_URI_STRINGS'>Creating URI Strings</a></h3>
+
+<p>To ensure proper encoding, the
+<a href='#httpAssembleURIf'><code>httpAssembleURIf</code></a> function must be
+used to format a "printer-uri" string for all printer-based requests:</p>
+
+<pre class='example'>
+const char *name = "Foo";
+char uri[1024];
+<a href='#ipp_t'>ipp_t</a> *request;
+
+<a href='#httpAssembleURIf'>httpAssembleURIf</a>(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, cupsServer(),
+ ippPort(), "/printers/%s", name);
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
+</pre>
+
+<h3><a name='SENDING_REQUESTS_WITH_FILES'>Sending Requests with Files</a></h3>
+
+<p>The <a href='#cupsDoFileRequest'><code>cupsDoFileRequest</code></a> and
+<a href='#cupsDoIORequest'><code>cupsDoIORequest</code></a> functions are
+used for requests involving files. The
+<a href='#cupsDoFileRequest'><code>cupsDoFileRequest</code></a> function
+attaches the named file to a request and is typically used when sending a print
+file or changing a printer's PPD file:</p>
+
+<pre class='example'>
+const char *filename = "/usr/share/cups/data/testprint.ps";
+const char *name = "Foo";
+char uri[1024];
+char resource[1024];
+<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(IPP_PRINT_JOB);
+<a href='#ipp_t'>ipp_t</a> *response;
+
+/* Use httpAssembleURIf for the printer-uri string */
+<a href='#httpAssembleURIf'>httpAssembleURIf</a>(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, cupsServer(),
+ ippPort(), "/printers/%s", name);
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, cupsUser());
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
+ NULL, "testprint.ps");
-<p>Unless otherwise specified, the HTTP and IPP API functions
-require CUPS 1.1 or higher.</p>
+/* Use snprintf for the resource path */
+snprintf(resource, sizeof(resource), "/printers/%s", name);
+
+response = <a href='#cupsDoFileRequest'>cupsDoFileRequest</a>(CUPS_HTTP_DEFAULT, request, resource, filename);
+</pre>
+
+<p>The <a href='#cupsDoIORequest'><code>cupsDoIORequest</code></a> function
+optionally attaches a file to the request and optionally saves a file in the
+response from the server. It is used when using a pipe for the request
+attachment or when using a request that returns a file, currently only
+<code>CUPS_GET_DOCUMENT</code> and <code>CUPS_GET_PPD</code>. For example,
+the following code will download the PPD file for the sample HP LaserJet
+printer driver:</p>
+
+<pre class='example'>
+char tempfile[1024];
+int tempfd;
+<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(CUPS_GET_PPD);
+<a href='#ipp_t'>ipp_t</a> *response;
+
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
+ NULL, "laserjet.ppd");
+
+tempfd = cupsTempFd(tempfile, sizeof(tempfile));
+
+response = <a href='#cupsDoIORequest'>cupsDoIORequest</a>(CUPS_HTTP_DEFAULT, request, "/", -1, tempfd);
+</pre>
+
+<p>The example passes <code>-1</code> for the input file descriptor to specify
+that no file is to be attached to the request. The PPD file attached to the
+response is written to the temporary file descriptor we created using the
+<code>cupsTempFd</code> function.</p>
+
+<h3><a name='ASYNCHRONOUS_REQUEST_PROCESSING'>Asynchronous Request Processing</a></h3>
+
+<p>The <a href='#cupsSendRequest'><code>cupsSendRequest</code></a> and
+<a href='#cupsGetResponse'><code>cupsGetResponse</code></a> support
+asynchronous communications with the server. Unlike the other request
+functions, the IPP request is not automatically freed, so remember to
+free your request with the <a href='#ippDelete'><code>ippDelete</code></a>
+function.</p>
+
+<p>File data is attached to the request using the
+<a href='#cupsWriteRequestData'><code>cupsWriteRequestData</code></a>
+function, while file data returned from the server is read using the
+<a href='#cupsReadResponseData'><code>cupsReadResponseData</code></a>
+function. We can rewrite the previous <code>CUPS_GET_PPD</code> example
+to use the asynchronous functions quite easily:</p>
+
+<pre class='example'>
+char tempfile[1024];
+int tempfd;
+<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(CUPS_GET_PPD);
+<a href='#ipp_t'>ipp_t</a> *response;
+
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
+ NULL, "laserjet.ppd");
+
+tempfd = cupsTempFd(tempfile, sizeof(tempfile));
+
+if (<a href='#cupsSendRequest'>cupsSendRequest</a>(CUPS_HTTP_DEFAULT, request, "/") == HTTP_CONTINUE)
+{
+ response = <a href='#cupsGetResponse'>cupsGetResponse</a>(CUPS_HTTP_DEFAULT, "/");
+
+ if (response != NULL)
+ {
+ ssize_t bytes;
+ char buffer[8192];
+
+ while ((bytes = <a href='#cupsReadResponseData'>cupsReadResponseData</a>(CUPS_HTTP_DEFAULT, buffer, sizeof(buffer))) > 0)
+ write(tempfd, buffer, bytes);
+ }
+}
+
+/* Free the request! */
+<a href='#ippDelete'>ippDelete</a>(request);
+</pre>
+
+<p>The <a href='#cupsSendRequest'><code>cupsSendRequest</code></a> function
+returns the initial HTTP request status, typically either
+<code>HTTP_CONTINUE</code> or <code>HTTP_UNAUTHORIZED</code>. The latter status
+is returned when the request requires authentication of some sort. The
+<a href='#cupsDoAuthentication'><code>cupsDoAuthentication</code></a> function
+must be called when your see <code>HTTP_UNAUTHORIZED</code> and the request
+re-sent. We can add authentication support to our example code by using a
+<code>do ... while</code> loop:</p>
+
+<pre class='example'>
+char tempfile[1024];
+int tempfd;
+<a href='#ipp_t'>ipp_t</a> *request = <a href='#ippNewRequest'>ippNewRequest</a>(CUPS_GET_PPD);
+<a href='#ipp_t'>ipp_t</a> *response;
+http_status_t status;
+
+<a href='#ippAddString'>ippAddString</a>(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
+ NULL, "laserjet.ppd");
+
+tempfd = cupsTempFd(tempfile, sizeof(tempfile));
+
+/* Loop for authentication */
+do
+{
+ status = a href='#cupsSendRequest'>cupsSendRequest</a>(CUPS_HTTP_DEFAULT, request, "/");
+
+ if (status == HTTP_UNAUTHORIZED)
+ {
+ /* Try to authenticate, break out of the loop if that fails */
+ if (<a href='#cupsDoAuthentication'>cupsDoAuthentication</a>(CUPS_HTTP_DEFAULT, "POST", "/"))
+ break;
+ }
+}
+while (status != HTTP_CONTINUE &amp;&amp; status != HTTP_UNAUTHORIZED);
+
+if (status == HTTP_CONTINUE)
+{
+ response = <a href='#cupsGetResponse'>cupsGetResponse</a>(CUPS_HTTP_DEFAULT, "/");
+
+ if (response != NULL)
+ {
+ ssize_t bytes;
+ char buffer[8192];
+
+ while ((bytes = <a href='#cupsReadResponseData'>cupsReadResponseData</a>(CUPS_HTTP_DEFAULT, buffer, sizeof(buffer))) > 0)
+ write(tempfd, buffer, bytes);
+ }
+}
+
+/* Free the request! */
+<a href='#ippDelete'>ippDelete</a>(request);
+</pre>
diff --git a/cups/api-overview.header b/cups/api-overview.header
new file mode 100644
index 000000000..51dbb2776
--- /dev/null
+++ b/cups/api-overview.header
@@ -0,0 +1,49 @@
+<!--
+ "$Id: api-cups.header 7279 2008-01-31 01:50:44Z mike $"
+
+ Introduction to CUPS programming header for the Common UNIX Printing System
+ (CUPS).
+
+ Copyright 2008 by Apple Inc.
+
+ These coded instructions, statements, and computer programs are the
+ property of Apple Inc. and are protected by Federal copyright
+ law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ which should have been included with this file. If this file is
+ file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">Introduction to CUPS Programming</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+ <th>Headers</th>
+ <th>cups/cups.h<br>
+ cups/array.h<br>
+ cups/backend.h<br>
+ cups/dir.h<br>
+ cups/file.h<br>
+ cups/ppd.h<br>
+ cups/raster.h<br>
+ cups/sidechannel.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+ <th>Libraries</th>
+ <td>-lcups<br>
+ -lcupsimage</td>
+</tr>
+<tr>
+ <th>See Also</th>
+ <td>Programming: <a href='api-cups.html' target='_top'>CUPS API</a><br>
+ Programming: <a href='api-array.html' target='_top'>Array API</a><br>
+ Programming: <a href='api-filedir.html' target='_top'>File and Directory APIs</a><br>
+ Programming: <a href='api-filter.html' target='_top'>Filter and Backend Programming</a><br>
+ Programming: <a href='api-httpipp.html' target='_top'>HTTP and IPP APIs</a><br>
+ Programming: <a href='api-ppd.html' target='_top'>PPD API</a><br>
+ Programming: <a href='api-raster.html' target='_top'>Raster API</a></td>
+</tr>
+</tbody>
+</table></div>
diff --git a/cups/api-overview.shtml b/cups/api-overview.shtml
new file mode 100644
index 000000000..dd1d6061d
--- /dev/null
+++ b/cups/api-overview.shtml
@@ -0,0 +1,95 @@
+<!--
+ "$Id: api-cups.header 7279 2008-01-31 01:50:44Z mike $"
+
+ Introduction to CUPS programming content for the Common UNIX Printing System
+ (CUPS).
+
+ Copyright 2008 by Apple Inc.
+
+ These coded instructions, statements, and computer programs are the
+ property of Apple Inc. and are protected by Federal copyright
+ law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ which should have been included with this file. If this file is
+ file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h2 class="title"><a name="OVERVIEW">Overview</a></h2>
+
+<p>CUPS provides two libraries that interface with the different parts of the
+printing system. The "cups" library provides all of the common application and
+filter functions while the "cupsimage" library provides all of the imaging
+functions used in raster printer drivers. The "cups" library functions are
+accessed by including the <var>&lt;cups/cups.h&gt;</var> header, while
+"cupsimage" functions are found in the <var>&lt;cups/raster.h&gt;</var>
+header.</p>
+
+<h2 class="title"><a name="COMPILING">Compiling Programs</a></h2>
+
+<p>The CUPS libraries can be used from any C, C++, or Objective C program.
+The method of compiling against the libraries varies depending on the
+operating system and installation of CUPS. The following sections show how
+to compile a simple program (shown below) in two common environments.</p>
+
+<p>The following simple program lists the available printers on the system:</p>
+
+<pre class="example">
+#include &lt;stdio.h&gt;
+#include &lt;cups/cups.h&gt;
+
+int main(void)
+{
+ int i;
+ cups_dest_t *dests, *dest;
+ int num_dests = cupsGetDests(&amp;dests);
+
+ for (i = num_dests, dest = dests; i &gt; 0; i --, dest ++)
+ {
+ if (dest->instance)
+ printf("%s/%s\n", dest->name, dest->instance);
+ else
+ puts(dest->name);
+ }
+
+ return (0);
+}
+</pre>
+
+<h3><a name="XCODE">Compiling with Xcode</a></h3>
+
+<p>In Xcode, choose <var>New Project...</var> from the <var>File</var> menu,
+then select the <var>Standard Tool</var> project type under <var>Command Line
+Utility</var>. Click <var>Next</var> and choose a project directory. Click
+<var>Next</var> to create the project.</p>
+
+<p>In the project window, double-click on the <var>Targets</var> group and
+control-click on the simple target to show the context menu. Choose
+<var>Existing Framework...</var> from the <var>Add</var> submenu. When the file
+chooser sheet appears, press the <kbd>/</kbd> key and enter "/usr/lib". Scroll
+down the file list and select the <var>libcups.dylib</var> file. Click the
+<var>Add</var> button in the file chooser and attributes sheets.</p>
+
+<p>In the project window, double-click on the <var>main.c</var> source file.
+Replace the template source code with the listing above and save it. Click the
+<var>Build and Go</var> button to build the sample program and run it.</p>
+
+<h3><a name="COMMANDLINE">Compiling with GCC</a></h3>
+
+<p>From the command-line, create a file called <var>sample.c</var> using your
+favorite editor and then run the following command to compile it with GCC and
+run it:</p>
+
+<pre class="command">
+gcc -o simple `cups-config --cflags` simple.c `cups-config --libs`
+./simple
+</pre>
+
+<p>The <code>cups-config</code> command provides the compiler flags
+("cups-config --cflags") and libraries ("cups-config --libs") needed for the
+local system.</p>
+
+<h2 class="title"><a name="WHERETOGO">Where to Go Next</a></h2>
+
+<p>If you are developing a print filter, driver, or backend, see the
+<a href="api-filter.html" target="_top">Filter and Backend Programming</a>
+guide. Raster printer driver developers should also read the
+<a href="api-raster.html" target="_top">Raster API</a> reference.</p>
diff --git a/cups/api-ppd.header b/cups/api-ppd.header
new file mode 100644
index 000000000..dfcb26a4c
--- /dev/null
+++ b/cups/api-ppd.header
@@ -0,0 +1,36 @@
+<!--
+ "$Id$"
+
+ PPD API header for the Common UNIX Printing System (CUPS).
+
+ Copyright 2008 by Apple Inc.
+
+ These coded instructions, statements, and computer programs are the
+ property of Apple Inc. and are protected by Federal copyright
+ law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ which should have been included with this file. If this file is
+ file is missing or damaged, see the license at "http://www.cups.org/".
+-->
+
+<h1 class="title">PPD API</h1>
+
+<div class='summary'><table summary='General Information'>
+<thead>
+<tr>
+ <th>Header</th>
+ <th>cups/ppd.h</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+ <th>Library</th>
+ <td>-lcups</td>
+</tr>
+<tr>
+ <th>See Also</th>
+ <td>Programming: <a href='api-overview.html' target='_top'>Introduction to CUPS Programming</a><br>
+ Programming: <a href='api-cups.html' target='_top'>CUPS API</a><br>
+ Reference: <a href='spec-ppd.html' target='_top'>CUPS PPD Specification</a></td>
+</tr>
+</tbody>
+</table></div>
diff --git a/cups/api-ppd.shtml b/cups/api-ppd.shtml
index 497e7ae6b..c1c2402d3 100644
--- a/cups/api-ppd.shtml
+++ b/cups/api-ppd.shtml
@@ -13,31 +13,187 @@
file is missing or damaged, see the license at "http://www.cups.org/".
-->
-<h2 class='title'>Introduction</h2>
+<h2 class='title'><a name='OVERVIEW'>Overview</a></h2>
-<p>The CUPS PPD API provides read-only access the data in
-PostScript Printer Description ("PPD") files. With it you can
-display printer options to users, mark option choices and check
-for conflicting choices, and output marked choices in PostScript
-output.</p>
+<p>The CUPS PPD API provides read-only access the data in PostScript Printer
+Description ("PPD") files which are used for all printers with a driver. With
+it you can display printer options to users, mark option choices and check for
+conflicting choices, and output marked choices in PostScript output. The
+<a href="#ppd_file_t"><code>ppd_file_t</code></a> structure contains all of
+the information in a PPD file.</p>
-<h2 class='title'>General Usage</h2>
+<h3><a name="LOADING">Loading a PPD File</a></h3>
-<p>The <var>&lt;cups/ppd.h&gt;</var> header file must be included
-to use the <tt>ppd</tt> functions.</p>
+<p>The <a href="#ppdOpenFile"><code>ppdOpenFile</code></a> function "opens" a
+PPD file and loads it into memory. For example, the following code opens the
+current printer's PPD file in a CUPS filter:</p>
-<p>Programs using these functions must be linked to the CUPS
-library: <var>libcups.a</var>, <var>libcups.so.2</var>,
-<var>libcups.2.dylib</var>, <var>libcups_s.a</var>, or
-<var>libcups2.lib</var> depending on the platform. The following
-command compiles <var>myprogram.c</var> using GCC and the CUPS
-library:</p>
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
-<pre class='command'>
-<kbd>gcc -o myprogram myprogram.c -lcups</kbd>
+<a href="#ppd_file_t">ppd_file_t</a> *ppd = <a href="#ppdOpenFile">ppdOpenFile</a>(getenv("PPD"));
</pre>
-<h2 class='title'>Compatibility</h2>
+<p>The return value is a pointer to a new
+<a href="#ppd_file_t"><code>ppd_file_t</code></a> structure or <code>NULL</code>
+if the PPD file does not exist or cannot be loaded. The
+<a href="#ppdClose"><code>ppdClose</code></a> function frees the memory used
+by the structure:</p>
-<p>Unless otherwise specified, the PPD API functions require CUPS
-1.1 or higher.</p>
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd;
+
+<a href="#ppdClose">ppdClose</a>(ppd);
+</pre>
+
+<h3><a name="OPTIONS_AND_GROUPS">Options and Groups</a></h3>
+
+<p>PPD files support multiple options, which are stored in arrays of
+<a href="#ppd_option_t"><code>ppd_option_t</code></a> and
+<a href="#ppd_choice_t"><code>ppd_choice_t</code></a> structures.</p>
+
+<p>Each option in turn is associated with a group stored in a
+<a href="#ppd_group_t"><code>ppd_group_t</code></a> structure. Groups can be
+specified in the PPD file; if an option is not associated with a group
+then it is put in an automatically-generated "General" group. Groups can also
+have sub-groups, however CUPS currently ignores sub-groups because of past
+abuses of this functionality.</p>
+
+<p>Options are selected by marking them using one of three functions. The
+first is <a href="#ppdMarkDefaults"><code>ppdMarkDefaults</code></a> which
+selects all of the default options in the PPD file:</p>
+
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd;
+
+<a href="#ppdMarkDefaults">ppdMarkDefaults</a>(ppd);
+</pre>
+
+<p>The second is <a href="#ppdMarkOption"><code>ppdMarkOption</code></a>
+which selects a single option choice in the PPD file. For example, the following
+code selects the manual feed media source:</p>
+
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd;
+
+<a href="#ppdMarkOption">ppdMarkOption</a>(ppd, "InputSlot", "ManualFeed");
+</pre>
+
+<p>The last function is
+<a href="#cupsMarkOptions"><code>cupsMarkOptions</code></a> which selects
+multiple option choices in the PPD file from an array of CUPS options, mapping
+IPP attributes like "media" and "sides" to their corresponding PPD options. You
+typically use this function in a print filter with
+<code>cupsParseOptions</code> and
+<a href="#ppdMarkDefaults"><code>ppdMarkDefaults</code></a> to select all of
+the option choices needed for the job, for example:</p>
+
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd = <a href="#ppdOpenFile">ppdOpenFile</a>(getenv("PPD"));
+cups_option_t *options = NULL;
+int num_options = cupsParseOptions(argv[5], 0, &amp;options);
+
+<a href="#ppdMarkDefaults">ppdMarkDefaults</a>(ppd);
+<a href="#cupsMarkOptions">cupsMarkOptions</a>(ppd, num_options, options);
+</pre>
+
+<h3><a name="CONSTRAINTS">Constraints</a></h3>
+
+<p>PPD files support specification of conflict conditions, called
+constraints, between different options. Constraints are stored in an array of
+<a href="#ppd_const_t"><code>ppd_const_t</code></a> structures which specify
+the options and choices that conflict with each other. The
+<a href="#ppdConflicts"><code>ppdConflicts</code></a> function tells you
+how many of the selected options are incompatible.</p>
+
+<h3><a name="PAGE_SIZES">Page Sizes</a></h3>
+
+<p>Page sizes are special options which have physical dimensions and margins
+associated with them. The size information is stored in
+<a href="#ppd_size_t"><code>ppd_size_t</code></a> structures and is available
+by looking up the named size with the
+<a href="#ppdPageSize"><code>ppdPageSize</code></a> function. The page size and
+margins are returned in units called points; there are 72 points per inch. If
+you pass <code>NULL</code> for the size, the currently selected size is
+returned:</p>
+
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd;
+<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, NULL);
+</pre>
+
+<p>Besides the standard page sizes listed in a PPD file, some printers
+support variable or custom page sizes. Custom page sizes are supported if the
+<code>variables_sizes</code> member of the
+<a href="#ppd_file_t"><code>ppd_file_t</code></a> structure is non-zero.
+The <code>custom_min</code>, <code>custom_max</code>, and
+<code>custom_margins</code> members of the
+<a href="#ppd_file_t"><code>ppd_file_t</code></a> structure define the limits
+of the printable area. To get the resulting media size, use a page size string
+of the form "Custom.<I>width</I>x<I>length</I>", where "width" and "length" are
+in points. Custom page size names can also be specified in inches
+("Custom.<i>width</i>x<i>height</i>in"), centimeters
+("Custom.<i>width</i>x<i>height</i>cm"), or millimeters
+("Custom.<i>width</i>x<i>height</i>mm"):</p>
+
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd;
+
+/* Get an 576x720 point custom page size */
+<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.576x720");
+
+/* Get an 8x10 inch custom page size */
+<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.8x10in");
+
+/* Get a 100x200 millimeter custom page size */
+<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.100x200mm");
+
+/* Get a 12.7x34.5 centimeter custom page size */
+<a href="#ppd_size_t">ppd_size_t</a> *size = <a href="#ppdPageSize">ppdPageSize</a>(ppd, "Custom.12.7x34.5cm");
+</pre>
+
+<h3><a name="ATTRIBUTES">Attributes</a></h3>
+
+<p>Every PPD file is composed of one or more attributes. Most of these
+attributes are used to define groups, options, choices, and page sizes,
+however several informations attributes are available which you may need
+to access in your program or filter. Attributes normally look like one of
+the following examples in a PPD file:</p>
+
+<pre class="example">
+*name: "value"
+*name spec: "value"
+*name spec/text: "value"
+</pre>
+
+<p>The <a href="#ppdFindAttr"><code>ppdFindAttr</code></a> and
+<a href="#ppdFindNextAttr"><code>ppdFindNextAttr</code></a> functions find the
+first and next instances, respectively, of the named attribute with the given
+"spec" string and return a <a href="#ppd_attr_t"><code>ppd_attr_t</code></a>
+structure. If you provide a NULL specifier string, all attributes with the
+given name will be returned. For example, the following code lists all of the
+<code>Product</code> attributes in a PPD file:</p>
+
+<pre class="example">
+#include &lt;cups/ppd.h&gt;
+
+<a href="#ppd_file_t">ppd_file_t</a> *ppd;
+<a href="#ppd_attr_t">ppd_attr_t</a> *attr;
+
+for (attr = <a href="#ppdFindAttr">ppdFindAttr</a>(ppd, "Product", NULL);
+ attr != NULL;
+ attr = <a href="#ppdFindNextAttr">ppdFindNextAttr</a>(ppd, "Product", NULL))
+ puts(attr->value);
+</pre>
diff --git a/cups/array.c b/cups/array.c
index 5728d51e4..df1ae2e54 100644
--- a/cups/array.c
+++ b/cups/array.c
@@ -3,7 +3,7 @@
*
* Sorted array routines for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -101,6 +101,8 @@ static int cups_array_find(cups_array_t *a, void *e, int prev, int *rdiff);
* When adding an element to a sorted array, non-unique elements are
* appended at the end of the run. For unsorted arrays, the element
* is inserted at the end of the array.
+ *
+ * @since CUPS 1.2@
*/
int /* O - 1 on success, 0 on failure */
@@ -129,6 +131,8 @@ cupsArrayAdd(cups_array_t *a, /* I - Array */
/*
* 'cupsArrayClear()' - Clear the array.
+ *
+ * @since CUPS 1.2@
*/
void
@@ -156,6 +160,8 @@ cupsArrayClear(cups_array_t *a) /* I - Array */
/*
* 'cupsArrayCount()' - Get the number of elements in the array.
+ *
+ * @since CUPS 1.2@
*/
int /* O - Number of elements */
@@ -178,6 +184,8 @@ cupsArrayCount(cups_array_t *a) /* I - Array */
/*
* 'cupsArrayCurrent()' - Return the current element in the array.
+ *
+ * @since CUPS 1.2@
*/
void * /* O - Element */
@@ -203,6 +211,8 @@ cupsArrayCurrent(cups_array_t *a) /* I - Array */
/*
* 'cupsArrayDelete()' - Free all memory used by the array.
+ *
+ * @since CUPS 1.2@
*/
void
@@ -232,6 +242,8 @@ cupsArrayDelete(cups_array_t *a) /* I - Array */
/*
* 'cupsArrayDup()' - Duplicate the array.
+ *
+ * @since CUPS 1.2@
*/
cups_array_t * /* O - Duplicate array */
@@ -296,9 +308,11 @@ cupsArrayDup(cups_array_t *a) /* I - Array */
/*
* 'cupsArrayFind()' - Find an element in the array.
+ *
+ * @since CUPS 1.2@
*/
-void * /* O - Element found or NULL */
+void * /* O - Element found or @code NULL@ */
cupsArrayFind(cups_array_t *a, /* I - Array */
void *e) /* I - Element */
{
@@ -389,9 +403,11 @@ cupsArrayFind(cups_array_t *a, /* I - Array */
/*
* 'cupsArrayFirst()' - Get the first element in the array.
+ *
+ * @since CUPS 1.2@
*/
-void * /* O - First element or NULL */
+void * /* O - First element or @code NULL@ */
cupsArrayFirst(cups_array_t *a) /* I - Array */
{
/*
@@ -445,9 +461,11 @@ cupsArrayGetInsert(cups_array_t *a) /* I - Array */
/*
* 'cupsArrayIndex()' - Get the N-th element in the array.
+ *
+ * @since CUPS 1.2@
*/
-void * /* O - N-th element or NULL */
+void * /* O - N-th element or @code NULL@ */
cupsArrayIndex(cups_array_t *a, /* I - Array */
int n) /* I - Index into array, starting at 0 */
{
@@ -466,6 +484,8 @@ cupsArrayIndex(cups_array_t *a, /* I - Array */
* When inserting an element in a sorted array, non-unique elements are
* inserted at the beginning of the run. For unsorted arrays, the element
* is inserted at the beginning of the array.
+ *
+ * @since CUPS 1.2@
*/
int /* O - 0 on failure, 1 on success */
@@ -494,9 +514,11 @@ cupsArrayInsert(cups_array_t *a, /* I - Array */
/*
* 'cupsArrayLast()' - Get the last element in the array.
+ *
+ * @since CUPS 1.2@
*/
-void * /* O - Last element or NULL */
+void * /* O - Last element or @code NULL@ */
cupsArrayLast(cups_array_t *a) /* I - Array */
{
/*
@@ -518,6 +540,8 @@ cupsArrayLast(cups_array_t *a) /* I - Array */
/*
* 'cupsArrayNew()' - Create a new array.
+ *
+ * @since CUPS 1.2@
*/
cups_array_t * /* O - Array */
@@ -579,9 +603,11 @@ cupsArrayNew2(cups_array_func_t f, /* I - Comparison function */
/*
* 'cupsArrayNext()' - Get the next element in the array.
+ *
+ * @since CUPS 1.2@
*/
-void * /* O - Next element or NULL */
+void * /* O - Next element or @code NULL@ */
cupsArrayNext(cups_array_t *a) /* I - Array */
{
/*
@@ -604,9 +630,11 @@ cupsArrayNext(cups_array_t *a) /* I - Array */
/*
* 'cupsArrayPrev()' - Get the previous element in the array.
+ *
+ * @since CUPS 1.2@
*/
-void * /* O - Previous element or NULL */
+void * /* O - Previous element or @code NULL@ */
cupsArrayPrev(cups_array_t *a) /* I - Array */
{
/*
@@ -629,6 +657,8 @@ cupsArrayPrev(cups_array_t *a) /* I - Array */
/*
* 'cupsArrayRemove()' - Remove an element from the array.
+ *
+ * @since CUPS 1.2@
*/
int /* O - 1 on success, 0 on failure */
@@ -689,6 +719,8 @@ cupsArrayRemove(cups_array_t *a, /* I - Array */
/*
* 'cupsArrayRestore()' - Reset the current element to the last cupsArraySave.
+ *
+ * @since CUPS 1.2@
*/
void * /* O - New current element */
@@ -714,6 +746,8 @@ cupsArrayRestore(cups_array_t *a) /* I - Array */
* 'cupsArraySave()' - Mark the current element for a later cupsArrayRestore.
*
* The save/restore stack is guaranteed to be at least 32 elements deep.
+ *
+ * @since CUPS 1.2@
*/
int /* O - 1 on success, 0 on failure */
@@ -734,6 +768,8 @@ cupsArraySave(cups_array_t *a) /* I - Array */
/*
* 'cupsArrayUserData()' - Return the user data for an array.
+ *
+ * @since CUPS 1.2@
*/
void * /* O - User data */
@@ -748,6 +784,8 @@ cupsArrayUserData(cups_array_t *a) /* I - Array */
/*
* 'cups_array_add()' - Insert or append an element to the array...
+ *
+ * @since CUPS 1.2@
*/
static int /* O - 1 on success, 0 on failure */
@@ -916,6 +954,8 @@ cups_array_add(cups_array_t *a, /* I - Array */
/*
* 'cups_array_find()' - Find an element in the array...
+ *
+ * @since CUPS 1.2@
*/
static int /* O - Index of match */
diff --git a/cups/array.h b/cups/array.h
index 74785a4c6..ae5752195 100644
--- a/cups/array.h
+++ b/cups/array.h
@@ -3,7 +3,7 @@
*
* Sorted array definitions for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
diff --git a/cups/attr.c b/cups/attr.c
index d65b3ef45..83e6ba887 100644
--- a/cups/attr.c
+++ b/cups/attr.c
@@ -4,7 +4,7 @@
* PPD model-specific attribute routines for the Common UNIX Printing System
* (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -15,8 +15,8 @@
*
* Contents:
*
- * ppdFindAttr() - Find the first matching attribute...
- * ppdFindNextAttr() - Find the next matching attribute...
+ * ppdFindAttr() - Find the first matching attribute.
+ * ppdFindNextAttr() - Find the next matching attribute.
*/
/*
@@ -30,15 +30,15 @@
/*
- * 'ppdFindAttr()' - Find the first matching attribute...
+ * 'ppdFindAttr()' - Find the first matching attribute.
*
* @since CUPS 1.1.19@
*/
-ppd_attr_t * /* O - Attribute or NULL if not found */
+ppd_attr_t * /* O - Attribute or @code NULL@ if not found */
ppdFindAttr(ppd_file_t *ppd, /* I - PPD file data */
const char *name, /* I - Attribute name */
- const char *spec) /* I - Specifier string or NULL */
+ const char *spec) /* I - Specifier string or @code NULL@ */
{
ppd_attr_t key, /* Search key */
*attr; /* Current attribute */
@@ -102,15 +102,15 @@ ppdFindAttr(ppd_file_t *ppd, /* I - PPD file data */
/*
- * 'ppdFindNextAttr()' - Find the next matching attribute...
+ * 'ppdFindNextAttr()' - Find the next matching attribute.
*
* @since CUPS 1.1.19@
*/
-ppd_attr_t * /* O - Attribute or NULL if not found */
+ppd_attr_t * /* O - Attribute or @code NULL@ if not found */
ppdFindNextAttr(ppd_file_t *ppd, /* I - PPD file data */
const char *name, /* I - Attribute name */
- const char *spec) /* I - Specifier string or NULL */
+ const char *spec) /* I - Specifier string or @code NULL@ */
{
ppd_attr_t *attr; /* Current attribute */
diff --git a/cups/auth.c b/cups/auth.c
index dd2d22c51..adc2436c9 100644
--- a/cups/auth.c
+++ b/cups/auth.c
@@ -76,7 +76,7 @@ static int cups_local_auth(http_t *http);
/*
* 'cupsDoAuthentication()' - Authenticate a request.
*
- * This function should be called in response to a HTTP_UNAUTHORIZED
+ * This function should be called in response to a @code HTTP_UNAUTHORIZED@
* status, prior to resubmitting your request.
*
* @since CUPS 1.1.20@
@@ -84,15 +84,14 @@ static int cups_local_auth(http_t *http);
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 *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[4096]; /* Encoded username:password */
+ nonce[HTTP_MAX_VALUE]; /* nonce="xyz" string */
int localauth; /* Local authentication result */
_cups_globals_t *cg; /* Global data */
@@ -301,14 +300,40 @@ cupsDoAuthentication(http_t *http, /* I - HTTP connection to server */
if (major_status == GSS_S_CONTINUE_NEEDED)
DEBUG_gss_printf(major_status, minor_status, "Continuation needed!");
- if (output_token.length)
+ if (output_token.length > 0 && output_token.length <= 65536)
{
- httpEncode64_2(encode, sizeof(encode), output_token.value,
+ /*
+ * Allocate the authorization string since Windows KDCs can have
+ * arbitrarily large credentials...
+ */
+
+ int authsize = 10 + /* "Negotiate " */
+ output_token.length * 4 / 3 + 1 + /* Base64 */
+ 1; /* nul */
+
+ httpSetAuthString(http, NULL, NULL);
+
+ if ((http->authstring = malloc(authsize)) == NULL)
+ {
+ http->authstring = http->_authstring;
+ authsize = sizeof(http->_authstring);
+ }
+
+ strcpy(http->authstring, "Negotiate ");
+ httpEncode64_2(http->authstring + 10, authsize - 10, output_token.value,
output_token.length);
- httpSetAuthString(http, "Negotiate", encode);
major_status = gss_release_buffer(&minor_status, &output_token);
}
+ else
+ {
+ DEBUG_printf(("cupsDoAuthentication: Kerberos credentials too large - "
+ "%d bytes!\n", output_token.length));
+
+ major_status = gss_release_buffer(&minor_status, &output_token);
+
+ return (-1);
+ }
#endif /* HAVE_GSSAPI */
}
else if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Digest", 6))
@@ -317,6 +342,9 @@ cupsDoAuthentication(http_t *http, /* I - HTTP connection to server */
* Basic authentication...
*/
+ char encode[256]; /* Base64 buffer */
+
+
httpEncode64_2(encode, sizeof(encode), http->userpass,
(int)strlen(http->userpass));
httpSetAuthString(http, "Basic", encode);
@@ -327,7 +355,8 @@ cupsDoAuthentication(http_t *http, /* I - HTTP connection to server */
* Digest authentication...
*/
- char digest[1024]; /* Digest auth data */
+ char encode[33], /* MD5 buffer */
+ digest[1024]; /* Digest auth data */
httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "realm", realm);
diff --git a/cups/backend.h b/cups/backend.h
index 5057f086f..67d5e8115 100644
--- a/cups/backend.h
+++ b/cups/backend.h
@@ -3,7 +3,7 @@
*
* Backend definitions for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2005 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -30,7 +30,7 @@
* Constants...
*/
-typedef enum cups_backend_e /**** Backend exit codes ****/
+enum cups_backend_e /**** Backend exit codes ****/
{
CUPS_BACKEND_OK = 0, /* Job completed successfully */
CUPS_BACKEND_FAILED = 1, /* Job failed, use error-policy */
@@ -38,7 +38,9 @@ typedef enum cups_backend_e /**** Backend exit codes ****/
CUPS_BACKEND_HOLD = 3, /* Job failed, hold job */
CUPS_BACKEND_STOP = 4, /* Job failed, stop queue */
CUPS_BACKEND_CANCEL = 5 /* Job failed, cancel job */
-} cups_backend_t;
+};
+typedef enum cups_backend_e cups_backend_t;
+ /**** Backend exit codes ****/
/*
diff --git a/cups/cups.h b/cups/cups.h
index 187071682..fd8cc3aa3 100644
--- a/cups/cups.h
+++ b/cups/cups.h
@@ -3,7 +3,7 @@
*
* API definitions for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -71,16 +71,21 @@ extern "C" {
# define CUPS_FORMAT_RAW "application/vnd.cups-raw"
# define CUPS_FORMAT_TEXT "text/plain"
# define CUPS_HTTP_DEFAULT (http_t *)0
+# define CUPS_JOBID_ALL -1
+# define CUPS_JOBID_CURRENT 0
# define CUPS_LENGTH_VARIABLE (ssize_t)0
+# define CUPS_WHICHJOBS_ALL -1
+# define CUPS_WHICHJOBS_ACTIVE 0
+# define CUPS_WHICHJOBS_COMPLETED 1
/*
* Types and structures...
*/
-typedef unsigned cups_ptype_t; /**** Printer Type/Capability Bits ****/
-enum cups_ptype_e /* Not a typedef'd enum so we can OR */
-{
+typedef unsigned cups_ptype_t; /**** Printer type/capability bits ****/
+enum cups_ptype_e /**** Printer type/capability bit constants ****/
+{ /* Not a typedef'd enum so we can OR */
CUPS_PRINTER_LOCAL = 0x0000, /* Local printer or class */
CUPS_PRINTER_CLASS = 0x0001, /* Printer class */
CUPS_PRINTER_REMOTE = 0x0002, /* Remote printer or class */
@@ -107,7 +112,7 @@ enum cups_ptype_e /* Not a typedef'd enum so we can OR */
CUPS_PRINTER_AUTHENTICATED = 0x400000,/* Printer requires authentication @since CUPS 1.2@ */
CUPS_PRINTER_COMMANDS = 0x800000, /* Printer supports maintenance commands @since CUPS 1.2@ */
CUPS_PRINTER_DISCOVERED = 0x1000000, /* Printer was automatically discovered and added @since CUPS 1.3@ */
- CUPS_PRINTER_OPTIONS = 0x6fffc /* ~(CLASS | REMOTE | IMPLICIT | DEFAULT | FAX | REJECTING | DELETE | NOT_SHARED | AUTHENTICATED | COMMANDS | DISCOVERED) */
+ CUPS_PRINTER_OPTIONS = 0x6fffc /* ~(CLASS | REMOTE | IMPLICIT | DEFAULT | FAX | REJECTING | DELETE | NOT_SHARED | AUTHENTICATED | COMMANDS | DISCOVERED) @private@ */
};
typedef const char *(*cups_password_cb_t)(const char *);
@@ -158,8 +163,8 @@ extern http_encryption_t cupsEncryption(void);
extern void cupsFreeJobs(int num_jobs, cups_job_t *jobs);
extern int cupsGetClasses(char ***classes) _CUPS_DEPRECATED;
extern const char *cupsGetDefault(void);
-extern int cupsGetJobs(cups_job_t **jobs, const char *dest,
- int myjobs, int completed);
+extern int cupsGetJobs(cups_job_t **jobs, const char *name,
+ int myjobs, int whichjobs);
extern const char *cupsGetPPD(const char *name);
extern int cupsGetPrinters(char ***printers) _CUPS_DEPRECATED;
extern ipp_status_t cupsLastError(void);
@@ -215,7 +220,7 @@ extern const char *cupsGetDefault2(http_t *http) _CUPS_API_1_1_21;
extern int cupsGetDests2(http_t *http, cups_dest_t **dests) _CUPS_API_1_1_21;
extern int cupsGetJobs2(http_t *http, cups_job_t **jobs,
const char *name, int myjobs,
- int completed) _CUPS_API_1_1_21;
+ int whichjobs) _CUPS_API_1_1_21;
extern const char *cupsGetPPD2(http_t *http, const char *name) _CUPS_API_1_1_21;
extern int cupsPrintFile2(http_t *http, const char *name,
const char *filename,
@@ -257,7 +262,8 @@ extern void cupsSetDefaultDest(const char *name,
cups_dest_t *dests) _CUPS_API_1_3;
/**** New in CUPS 1.4 ****/
-extern ipp_status_t cupsCancelJob2(http_t *http, int job_id, int purge);
+extern ipp_status_t cupsCancelJob2(http_t *http, const char *name,
+ int job_id, int purge) _CUPS_API_1_4;
extern int cupsCreateJob(http_t *http, const char *name,
const char *title, int num_options,
cups_option_t *options) _CUPS_API_1_4;
diff --git a/cups/dest.c b/cups/dest.c
index 64b2ca431..6f61181d6 100644
--- a/cups/dest.c
+++ b/cups/dest.c
@@ -101,13 +101,13 @@ static int cups_get_sdests(http_t *http, ipp_op_t op, const char *name,
* returned unchanged. Adding a new instance of a destination creates
* a copy of that destination's options.
*
- * Use the cupsSaveDests() function to save the updated list of
+ * Use the @link cupsSaveDests@ function to save the updated list of
* destinations to the user's lpoptions file.
*/
int /* O - New number of destinations */
cupsAddDest(const char *name, /* I - Destination name */
- const char *instance, /* I - Instance name or NULL for none/primary */
+ const char *instance, /* I - Instance name or @code NULL@ for none/primary */
int num_dests, /* I - Number of destinations */
cups_dest_t **dests) /* IO - Destinations */
{
@@ -218,13 +218,13 @@ cupsFreeDests(int num_dests, /* I - Number of destinations */
/*
* 'cupsGetDest()' - Get the named destination from the list.
*
- * Use the cupsGetDests() or cupsGetDests2() functions to get a
+ * Use the @link cupsGetDests@ or @link cupsGetDests2@ functions to get a
* list of supported destinations for the current user.
*/
-cups_dest_t * /* O - Destination pointer or NULL */
-cupsGetDest(const char *name, /* I - Destination name or NULL for the default destination */
- const char *instance, /* I - Instance name or NULL */
+cups_dest_t * /* O - Destination pointer or @code NULL@ */
+cupsGetDest(const char *name, /* I - Destination name or @code NULL@ for the default destination */
+ const char *instance, /* I - Instance name or @code NULL@ */
int num_dests, /* I - Number of destinations */
cups_dest_t *dests) /* I - Destinations */
{
@@ -284,8 +284,8 @@ cupsGetDest(const char *name, /* I - Destination name or NULL for the default
* printer-make-and-model, printer-state, printer-state-change-time,
* printer-state-reasons, and printer-type attributes as options.
*
- * Use the cupsFreeDests() function to free the destination list and
- * the cupsGetDest() function to find a particular destination.
+ * Use the @link cupsFreeDests@ function to free the destination list and
+ * the @link cupsGetDest@ function to find a particular destination.
*/
int /* O - Number of destinations */
@@ -303,14 +303,14 @@ cupsGetDests(cups_dest_t **dests) /* O - Destinations */
* printer-make-and-model, printer-state, printer-state-change-time,
* printer-state-reasons, and printer-type attributes as options.
*
- * Use the cupsFreeDests() function to free the destination list and
- * the cupsGetDest() function to find a particular destination.
+ * Use the @link cupsFreeDests@ function to free the destination list and
+ * the @link cupsGetDest@ function to find a particular destination.
*
* @since CUPS 1.1.21@
*/
int /* O - Number of destinations */
-cupsGetDests2(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+cupsGetDests2(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
cups_dest_t **dests) /* O - Destinations */
{
int i; /* Looping var */
@@ -477,26 +477,27 @@ cupsGetDests2(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
* 'cupsGetNamedDest()' - Get options for the named destination.
*
* This function is optimized for retrieving a single destination and should
- * be used instead of cupsGetDests() and cupsGetDest() when you either know
- * the name of the destination or want to print to the default destination.
- * If NULL is returned, the destination does not exist or there is no default
- * destination.
+ * be used instead of @link cupsGetDests@ and @link cupsGetDest@ when you either
+ * know the name of the destination or want to print to the default destination.
+ * If @code NULL@ is returned, the destination does not exist or there is no
+ * default destination.
*
- * If "http" is CUPS_HTTP_DEFAULT, the connection to the default print server
- * will be used.
+ * If "http" is @code CUPS_HTTP_DEFAULT@, the connection to the default print
+ * server will be used.
*
- * If "name" is NULL, the default printer for the current user will be returned.
+ * If "name" is @code NULL@, the default printer for the current user will be
+ * returned.
*
- * The returned destination must be freed using cupsFreeDests() with a
- * "num_dests" of 1.
+ * The returned destination must be freed using @link cupsFreeDests@ with a
+ * "num_dests" value of 1.
*
* @since CUPS 1.4@
*/
-cups_dest_t * /* O - Destination or NULL */
-cupsGetNamedDest(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
- const char *name, /* I - Destination name or NULL */
- const char *instance) /* I - Instance name or NULL */
+cups_dest_t * /* O - Destination or @code NULL@ */
+cupsGetNamedDest(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
+ const char *name, /* I - Destination name or @code NULL@ */
+ const char *instance) /* I - Instance name or @code NULL@ */
{
cups_dest_t *dest; /* Destination */
char filename[1024], /* Path to lpoptions */
@@ -595,15 +596,15 @@ cupsGetNamedDest(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT *
*
* Removing a destination/instance does not delete the class or printer
* queue, merely the lpoptions for that destination/instance. Use the
- * cupsSetDests() or cupsSetDests2() functions to save the new options
- * for the user.
+ * @link cupsSetDests@ or @link cupsSetDests2@ functions to save the new
+ * options for the user.
*
* @since CUPS 1.3@
*/
int /* O - New number of destinations */
cupsRemoveDest(const char *name, /* I - Destination name */
- const char *instance, /* I - Instance name or NULL */
+ const char *instance, /* I - Instance name or @code NULL@ */
int num_dests, /* I - Number of destinations */
cups_dest_t **dests) /* IO - Destinations */
{
@@ -650,7 +651,7 @@ cupsRemoveDest(const char *name, /* I - Destination name */
void
cupsSetDefaultDest(
const char *name, /* I - Destination name */
- const char *instance, /* I - Instance name or NULL */
+ const char *instance, /* I - Instance name or @code NULL@ */
int num_dests, /* I - Number of destinations */
cups_dest_t *dests) /* I - Destinations */
{
@@ -703,7 +704,7 @@ cupsSetDests(int num_dests, /* I - Number of destinations */
*/
int /* O - 0 on success, -1 on error */
-cupsSetDests2(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+cupsSetDests2(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
int num_dests, /* I - Number of destinations */
cups_dest_t *dests) /* I - Destinations */
{
diff --git a/cups/dir.c b/cups/dir.c
index b3a689b70..1ef2046b7 100644
--- a/cups/dir.c
+++ b/cups/dir.c
@@ -5,7 +5,7 @@
*
* This set of APIs abstracts enumeration of directory entries.
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2005 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -80,10 +80,12 @@ _cups_dir_time(FILETIME ft) /* I - File time */
/*
* 'cupsDirClose()' - Close a directory.
+ *
+ * @since CUPS 1.2@
*/
void
-cupsDirClose(cups_dir_t *dp) /* I - Directory */
+cupsDirClose(cups_dir_t *dp) /* I - Directory pointer */
{
/*
* Range check input...
@@ -109,9 +111,11 @@ cupsDirClose(cups_dir_t *dp) /* I - Directory */
/*
* 'cupsDirOpen()' - Open a directory.
+ *
+ * @since CUPS 1.2@
*/
-cups_dir_t * /* O - Directory */
+cups_dir_t * /* O - Directory pointer or @code NULL@ if the directory could not be opened. */
cupsDirOpen(const char *directory) /* I - Directory name */
{
cups_dir_t *dp; /* Directory */
@@ -150,10 +154,12 @@ cupsDirOpen(const char *directory) /* I - Directory name */
/*
* 'cupsDirRead()' - Read the next directory entry.
+ *
+ * @since CUPS 1.2@
*/
-cups_dentry_t * /* O - Directory entry */
-cupsDirRead(cups_dir_t *dp) /* I - Directory */
+cups_dentry_t * /* O - Directory entry or @code NULL@ if there are no more */
+cupsDirRead(cups_dir_t *dp) /* I - Directory pointer */
{
WIN32_FIND_DATA entry; /* Directory entry data */
@@ -208,10 +214,12 @@ cupsDirRead(cups_dir_t *dp) /* I - Directory */
/*
* 'cupsDirRewind()' - Rewind to the start of the directory.
+ *
+ * @since CUPS 1.2@
*/
void
-cupsDirRewind(cups_dir_t *dp) /* I - Directory */
+cupsDirRewind(cups_dir_t *dp) /* I - Directory pointer */
{
/*
* Range check input...
@@ -256,10 +264,12 @@ struct _cups_dir_s /**** Directory data structure ****/
/*
* 'cupsDirClose()' - Close a directory.
+ *
+ * @since CUPS 1.2@
*/
void
-cupsDirClose(cups_dir_t *dp) /* I - Directory */
+cupsDirClose(cups_dir_t *dp) /* I - Directory pointer */
{
DEBUG_printf(("cupsDirClose(dp=%p)\n", dp));
@@ -281,9 +291,11 @@ cupsDirClose(cups_dir_t *dp) /* I - Directory */
/*
* 'cupsDirOpen()' - Open a directory.
+ *
+ * @since CUPS 1.2@
*/
-cups_dir_t * /* O - Directory */
+cups_dir_t * /* O - Directory pointer or @code NULL@ if the directory could not be opened. */
cupsDirOpen(const char *directory) /* I - Directory name */
{
cups_dir_t *dp; /* Directory */
@@ -333,10 +345,12 @@ cupsDirOpen(const char *directory) /* I - Directory name */
/*
* 'cupsDirRead()' - Read the next directory entry.
+ *
+ * @since CUPS 1.2@
*/
-cups_dentry_t * /* O - Directory entry */
-cupsDirRead(cups_dir_t *dp) /* I - Directory */
+cups_dentry_t * /* O - Directory entry or @code NULL@ when there are no more */
+cupsDirRead(cups_dir_t *dp) /* I - Directory pointer */
{
struct dirent *entry; /* Pointer to entry */
char filename[1024]; /* Full filename */
@@ -428,10 +442,12 @@ cupsDirRead(cups_dir_t *dp) /* I - Directory */
/*
* 'cupsDirRewind()' - Rewind to the start of the directory.
+ *
+ * @since CUPS 1.2@
*/
void
-cupsDirRewind(cups_dir_t *dp) /* I - Directory */
+cupsDirRewind(cups_dir_t *dp) /* I - Directory pointer */
{
DEBUG_printf(("cupsDirRewind(dp=%p)\n", dp));
diff --git a/cups/emit.c b/cups/emit.c
index 5ac480f35..494b1d45e 100644
--- a/cups/emit.c
+++ b/cups/emit.c
@@ -68,6 +68,9 @@ static const char ppd_custom_code[] =
/*
* 'ppdCollect()' - Collect all marked options that reside in the specified
* section.
+ *
+ * The choices array should be freed using @code free@ when you are
+ * finished with it.
*/
int /* O - Number of options marked */
@@ -83,6 +86,9 @@ ppdCollect(ppd_file_t *ppd, /* I - PPD file data */
* 'ppdCollect2()' - Collect all marked options that reside in the
* specified section and minimum order.
*
+ * The choices array should be freed using @code free@ when you are
+ * finished with it.
+ *
* @since CUPS 1.2@
*/
@@ -545,12 +551,12 @@ ppdEmitJCLEnd(ppd_file_t *ppd, /* I - PPD file record */
* returned string.
*
* The return string is allocated on the heap and should be freed using
- * free() when you are done with it.
+ * @code free@ when you are done with it.
*
* @since CUPS 1.2@
*/
-char * /* O - String containing option code */
+char * /* O - String containing option code or @code NULL@ if there is no option code */
ppdEmitString(ppd_file_t *ppd, /* I - PPD file record */
ppd_section_t section, /* I - Section to write */
float min_order) /* I - Lowest OrderDependency */
diff --git a/cups/encode.c b/cups/encode.c
index 9ac62b870..506b87f0f 100644
--- a/cups/encode.c
+++ b/cups/encode.c
@@ -43,98 +43,98 @@
static const _ipp_option_t ipp_options[] =
{
- { "auth-info", IPP_TAG_TEXT, IPP_TAG_JOB },
- { "auth-info-required", IPP_TAG_KEYWORD, IPP_TAG_PRINTER },
- { "blackplot", IPP_TAG_BOOLEAN, IPP_TAG_JOB },
- { "blackplot-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER },
- { "brightness", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { "brightness-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
- { "columns", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { "columns-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
- { "copies", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { "copies-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
- { "document-format", IPP_TAG_MIMETYPE, IPP_TAG_OPERATION },
- { "document-format-default", IPP_TAG_MIMETYPE, IPP_TAG_PRINTER },
- { "finishings", IPP_TAG_ENUM, IPP_TAG_JOB },
- { "finishings-default", IPP_TAG_ENUM, IPP_TAG_PRINTER },
- { "fitplot", IPP_TAG_BOOLEAN, IPP_TAG_JOB },
- { "fitplot-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER },
- { "gamma", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { "gamma-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
- { "hue", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { "hue-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
- { "job-k-limit", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { "job-page-limit", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { "job-priority", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { "job-quota-period", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { "job-uuid", IPP_TAG_URI, IPP_TAG_JOB },
- { "landscape", IPP_TAG_BOOLEAN, IPP_TAG_JOB },
- { "media", IPP_TAG_KEYWORD, IPP_TAG_JOB },
- { "mirror", IPP_TAG_BOOLEAN, IPP_TAG_JOB },
- { "mirror-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER },
- { "natural-scaling", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { "natural-scaling-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
- { "notify-charset", IPP_TAG_CHARSET, IPP_TAG_SUBSCRIPTION },
- { "notify-events", IPP_TAG_KEYWORD, IPP_TAG_SUBSCRIPTION },
- { "notify-events-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER },
- { "notify-lease-duration", IPP_TAG_INTEGER, IPP_TAG_SUBSCRIPTION },
- { "notify-lease-duration-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
- { "notify-natural-language", IPP_TAG_LANGUAGE, IPP_TAG_SUBSCRIPTION },
- { "notify-pull-method", IPP_TAG_KEYWORD, IPP_TAG_SUBSCRIPTION },
- { "notify-recipient-uri", IPP_TAG_URI, IPP_TAG_SUBSCRIPTION },
- { "notify-time-interval", IPP_TAG_INTEGER, IPP_TAG_SUBSCRIPTION },
- { "notify-user-data", IPP_TAG_STRING, IPP_TAG_SUBSCRIPTION },
- { "number-up", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { "number-up-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
- { "orientation-requested", IPP_TAG_ENUM, IPP_TAG_JOB },
- { "orientation-requested-default", IPP_TAG_ENUM, IPP_TAG_PRINTER },
- { "page-bottom", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { "page-bottom-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
- { "page-left", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { "page-left-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
- { "page-ranges", IPP_TAG_RANGE, IPP_TAG_JOB },
- { "page-ranges-default", IPP_TAG_RANGE, IPP_TAG_PRINTER },
- { "page-right", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { "page-right-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
- { "page-top", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { "page-top-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
- { "penwidth", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { "penwidth-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
- { "port-monitor", IPP_TAG_NAME, IPP_TAG_PRINTER },
- { "ppi", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { "ppi-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
- { "prettyprint", IPP_TAG_BOOLEAN, IPP_TAG_JOB },
- { "prettyprint-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER },
- { "print-quality", IPP_TAG_ENUM, IPP_TAG_JOB },
- { "print-quality-default", IPP_TAG_ENUM, IPP_TAG_PRINTER },
- { "printer-error-policy", IPP_TAG_NAME, IPP_TAG_PRINTER },
- { "printer-info", IPP_TAG_TEXT, IPP_TAG_PRINTER },
- { "printer-is-accepting-jobs",IPP_TAG_BOOLEAN, IPP_TAG_PRINTER },
- { "printer-is-shared", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER },
- { "printer-location", IPP_TAG_TEXT, IPP_TAG_PRINTER },
- { "printer-make-and-model", IPP_TAG_TEXT, IPP_TAG_PRINTER },
- { "printer-more-info", IPP_TAG_URI, IPP_TAG_PRINTER },
- { "printer-op-policy", IPP_TAG_NAME, IPP_TAG_PRINTER },
- { "printer-resolution", IPP_TAG_RESOLUTION, IPP_TAG_JOB },
- { "printer-state", IPP_TAG_ENUM, IPP_TAG_PRINTER },
- { "printer-state-change-time",IPP_TAG_INTEGER, IPP_TAG_PRINTER },
- { "printer-state-reasons", IPP_TAG_KEYWORD, IPP_TAG_PRINTER },
- { "printer-type", IPP_TAG_ENUM, IPP_TAG_PRINTER },
- { "printer-uri", IPP_TAG_URI, IPP_TAG_OPERATION },
- { "queued-job-count", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
- { "raw", IPP_TAG_MIMETYPE, IPP_TAG_OPERATION },
- { "requesting-user-name-allowed", IPP_TAG_NAME, IPP_TAG_PRINTER },
- { "requesting-user-name-denied", IPP_TAG_NAME, IPP_TAG_PRINTER },
- { "resolution", IPP_TAG_RESOLUTION, IPP_TAG_JOB },
- { "resolution-default", IPP_TAG_RESOLUTION, IPP_TAG_PRINTER },
- { "saturation", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { "saturation-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
- { "scaling", IPP_TAG_INTEGER, IPP_TAG_JOB },
- { "scaling-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
- { "sides", IPP_TAG_KEYWORD, IPP_TAG_JOB },
- { "sides-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER },
- { "wrap", IPP_TAG_BOOLEAN, IPP_TAG_JOB },
- { "wrap-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }
+ { 1, "auth-info", IPP_TAG_TEXT, IPP_TAG_JOB },
+ { 1, "auth-info-required", IPP_TAG_KEYWORD, IPP_TAG_PRINTER },
+ { 0, "blackplot", IPP_TAG_BOOLEAN, IPP_TAG_JOB },
+ { 0, "blackplot-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER },
+ { 0, "brightness", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "brightness-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+ { 0, "columns", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "columns-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+ { 0, "copies", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "copies-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+ { 0, "document-format", IPP_TAG_MIMETYPE, IPP_TAG_OPERATION },
+ { 0, "document-format-default", IPP_TAG_MIMETYPE, IPP_TAG_PRINTER },
+ { 1, "finishings", IPP_TAG_ENUM, IPP_TAG_JOB },
+ { 1, "finishings-default", IPP_TAG_ENUM, IPP_TAG_PRINTER },
+ { 0, "fitplot", IPP_TAG_BOOLEAN, IPP_TAG_JOB },
+ { 0, "fitplot-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER },
+ { 0, "gamma", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "gamma-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+ { 0, "hue", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "hue-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+ { 0, "job-k-limit", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "job-page-limit", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "job-priority", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "job-quota-period", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "job-uuid", IPP_TAG_URI, IPP_TAG_JOB },
+ { 0, "landscape", IPP_TAG_BOOLEAN, IPP_TAG_JOB },
+ { 1, "media", IPP_TAG_KEYWORD, IPP_TAG_JOB },
+ { 0, "mirror", IPP_TAG_BOOLEAN, IPP_TAG_JOB },
+ { 0, "mirror-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER },
+ { 0, "natural-scaling", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "natural-scaling-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+ { 0, "notify-charset", IPP_TAG_CHARSET, IPP_TAG_SUBSCRIPTION },
+ { 1, "notify-events", IPP_TAG_KEYWORD, IPP_TAG_SUBSCRIPTION },
+ { 1, "notify-events-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER },
+ { 0, "notify-lease-duration", IPP_TAG_INTEGER, IPP_TAG_SUBSCRIPTION },
+ { 0, "notify-lease-duration-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+ { 0, "notify-natural-language", IPP_TAG_LANGUAGE, IPP_TAG_SUBSCRIPTION },
+ { 0, "notify-pull-method", IPP_TAG_KEYWORD, IPP_TAG_SUBSCRIPTION },
+ { 0, "notify-recipient-uri", IPP_TAG_URI, IPP_TAG_SUBSCRIPTION },
+ { 0, "notify-time-interval", IPP_TAG_INTEGER, IPP_TAG_SUBSCRIPTION },
+ { 0, "notify-user-data", IPP_TAG_STRING, IPP_TAG_SUBSCRIPTION },
+ { 0, "number-up", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "number-up-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+ { 0, "orientation-requested", IPP_TAG_ENUM, IPP_TAG_JOB },
+ { 0, "orientation-requested-default", IPP_TAG_ENUM, IPP_TAG_PRINTER },
+ { 0, "page-bottom", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "page-bottom-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+ { 0, "page-left", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "page-left-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+ { 1, "page-ranges", IPP_TAG_RANGE, IPP_TAG_JOB },
+ { 1, "page-ranges-default", IPP_TAG_RANGE, IPP_TAG_PRINTER },
+ { 0, "page-right", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "page-right-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+ { 0, "page-top", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "page-top-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+ { 0, "penwidth", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "penwidth-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+ { 0, "port-monitor", IPP_TAG_NAME, IPP_TAG_PRINTER },
+ { 0, "ppi", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "ppi-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+ { 0, "prettyprint", IPP_TAG_BOOLEAN, IPP_TAG_JOB },
+ { 0, "prettyprint-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER },
+ { 0, "print-quality", IPP_TAG_ENUM, IPP_TAG_JOB },
+ { 0, "print-quality-default", IPP_TAG_ENUM, IPP_TAG_PRINTER },
+ { 0, "printer-error-policy", IPP_TAG_NAME, IPP_TAG_PRINTER },
+ { 0, "printer-info", IPP_TAG_TEXT, IPP_TAG_PRINTER },
+ { 0, "printer-is-accepting-jobs", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER },
+ { 0, "printer-is-shared", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER },
+ { 0, "printer-location", IPP_TAG_TEXT, IPP_TAG_PRINTER },
+ { 0, "printer-make-and-model", IPP_TAG_TEXT, IPP_TAG_PRINTER },
+ { 0, "printer-more-info", IPP_TAG_URI, IPP_TAG_PRINTER },
+ { 0, "printer-op-policy", IPP_TAG_NAME, IPP_TAG_PRINTER },
+ { 0, "printer-resolution", IPP_TAG_RESOLUTION, IPP_TAG_JOB },
+ { 0, "printer-state", IPP_TAG_ENUM, IPP_TAG_PRINTER },
+ { 0, "printer-state-change-time", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+ { 1, "printer-state-reasons", IPP_TAG_KEYWORD, IPP_TAG_PRINTER },
+ { 0, "printer-type", IPP_TAG_ENUM, IPP_TAG_PRINTER },
+ { 0, "printer-uri", IPP_TAG_URI, IPP_TAG_OPERATION },
+ { 0, "queued-job-count", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+ { 0, "raw", IPP_TAG_MIMETYPE, IPP_TAG_OPERATION },
+ { 1, "requesting-user-name-allowed", IPP_TAG_NAME, IPP_TAG_PRINTER },
+ { 1, "requesting-user-name-denied", IPP_TAG_NAME, IPP_TAG_PRINTER },
+ { 0, "resolution", IPP_TAG_RESOLUTION, IPP_TAG_JOB },
+ { 0, "resolution-default", IPP_TAG_RESOLUTION, IPP_TAG_PRINTER },
+ { 0, "saturation", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "saturation-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+ { 0, "scaling", IPP_TAG_INTEGER, IPP_TAG_JOB },
+ { 0, "scaling-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER },
+ { 0, "sides", IPP_TAG_KEYWORD, IPP_TAG_JOB },
+ { 0, "sides-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER },
+ { 0, "wrap", IPP_TAG_BOOLEAN, IPP_TAG_JOB },
+ { 0, "wrap-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }
};
@@ -192,7 +192,8 @@ cupsEncodeOptions2(
char *s, /* Pointer into option value */
*val, /* Pointer to option value */
*copy, /* Copy of option value */
- *sep; /* Option separator */
+ *sep, /* Option separator */
+ quote; /* Quote character */
ipp_attribute_t *attr; /* IPP attribute */
ipp_tag_t value_tag; /* IPP value tag */
cups_option_t *option; /* Current option */
@@ -284,41 +285,28 @@ cupsEncodeOptions2(
* Count the number of values...
*/
- for (count = 1, sep = option->value; *sep; sep ++)
+ if (match && match->multivalue)
{
- if (*sep == '\'')
+ for (count = 1, sep = option->value, quote = 0; *sep; sep ++)
{
- /*
- * Skip quoted option value...
- */
-
- sep ++;
-
- while (*sep && *sep != '\'')
- sep ++;
-
- if (!*sep)
- sep --;
- }
- else if (*sep == '\"')
- {
- /*
- * Skip quoted option value...
- */
-
- sep ++;
+ if (*sep == quote)
+ quote = 0;
+ else if (!quote && (*sep == '\'' || *sep == '\"'))
+ {
+ /*
+ * Skip quoted option value...
+ */
- while (*sep && *sep != '\"')
+ quote = *sep++;
+ }
+ else if (*sep == ',' && !quote)
+ count ++;
+ else if (*sep == '\\' && sep[1])
sep ++;
-
- if (!*sep)
- sep --;
}
- else if (*sep == ',')
- count ++;
- else if (*sep == '\\' && sep[1])
- sep ++;
}
+ else
+ count = 1;
DEBUG_printf(("cupsEncodeOptions2: option = \'%s\', count = %d\n",
option->name, count));
@@ -390,50 +378,47 @@ cupsEncodeOptions2(
* Scan the value string for values...
*/
- for (j = 0; j < count; val = sep, j ++)
+ for (j = 0, sep = val; j < count; val = sep, j ++)
{
/*
* Find the end of this value and mark it if needed...
*/
- for (sep = val; *sep; sep ++)
+ if (count > 1)
{
- if (*sep == '\'')
+ for (quote = 0; *sep; sep ++)
{
- /*
- * Skip quoted option value...
- */
-
- sep ++;
-
- while (*sep && *sep != '\'')
- sep ++;
+ if (*sep == quote)
+ {
+ /*
+ * Finish quoted value...
+ */
- if (!*sep)
- sep --;
- }
- else if (*sep == '\"')
- {
- /*
- * Skip quoted option value...
- */
+ quote = 0;
+ }
+ else if (!quote && (*sep == '\'' || *sep == '\"'))
+ {
+ /*
+ * Handle quoted option value...
+ */
- sep ++;
+ quote = *sep;
+ }
+ else if (*sep == ',' && count > 1)
+ break;
+ else if (*sep == '\\' && sep[1])
+ {
+ /*
+ * Skip quoted character...
+ */
- while (*sep && *sep != '\"')
sep ++;
-
- if (!*sep)
- sep --;
+ }
}
- else if (*sep == ',')
- break;
- else if (*sep == '\\' && sep[1])
- sep ++;
- }
- if (*sep == ',')
- *sep++ = '\0';
+ if (*sep == ',')
+ *sep++ = '\0';
+ }
/*
* Copy the option value(s) over as needed by the type...
@@ -447,7 +432,7 @@ cupsEncodeOptions2(
* Integer/enumeration value...
*/
- attr->values[j].integer = strtol(val, &s, 0);
+ attr->values[j].integer = strtol(val, &s, 10);
DEBUG_printf(("cupsEncodeOptions2: Added integer option value %d...\n",
attr->values[j].integer));
@@ -489,12 +474,12 @@ cupsEncodeOptions2(
s = val;
}
else
- attr->values[j].range.lower = strtol(val, &s, 0);
+ attr->values[j].range.lower = strtol(val, &s, 10);
if (*s == '-')
{
if (s[1])
- attr->values[j].range.upper = strtol(s + 1, NULL, 0);
+ attr->values[j].range.upper = strtol(s + 1, NULL, 10);
else
attr->values[j].range.upper = 2147483647;
}
@@ -511,10 +496,10 @@ cupsEncodeOptions2(
* Resolution...
*/
- attr->values[j].resolution.xres = strtol(val, &s, 0);
+ attr->values[j].resolution.xres = strtol(val, &s, 10);
if (*s == 'x')
- attr->values[j].resolution.yres = strtol(s + 1, &s, 0);
+ attr->values[j].resolution.yres = strtol(s + 1, &s, 10);
else
attr->values[j].resolution.yres = attr->values[j].resolution.xres;
@@ -533,7 +518,7 @@ cupsEncodeOptions2(
*/
attr->values[j].unknown.length = (int)strlen(val);
- attr->values[j].unknown.data = _cupsStrAlloc(val);
+ attr->values[j].unknown.data = strdup(val);
DEBUG_printf(("cupsEncodeOptions2: Added octet-string value \"%s\"...\n",
attr->values[j].unknown.data));
diff --git a/cups/file.c b/cups/file.c
index e7c7b0b15..9f92727a2 100644
--- a/cups/file.c
+++ b/cups/file.c
@@ -8,7 +8,7 @@
* our own file functions allows us to provide transparent support of
* gzip'd print files, PPD files, etc.
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -26,8 +26,8 @@
* cupsFileFlush() - Flush pending output.
* cupsFileGetChar() - Get a single character from a file.
* cupsFileGetConf() - Get a line from a configuration file...
- * cupsFileGetLine() - Get a CR and/or LF-terminated line that may
- * contain binary data.
+ * cupsFileGetLine() - Get a CR and/or LF-terminated line that may contain
+ * binary data.
* cupsFileGets() - Get a CR and/or LF-terminated line.
* cupsFileLock() - Temporarily lock access to a file.
* cupsFileNumber() - Return the file descriptor associated with a CUPS
@@ -39,7 +39,8 @@
* cupsFilePutChar() - Write a character.
* cupsFilePuts() - Write a string.
* cupsFileRead() - Read from a file.
- * cupsFileRewind() - Rewind a file.
+ * cupsFileRewind() - Set the current file position to the beginning of
+ * the file.
* cupsFileSeek() - Seek in a file.
* cupsFileStderr() - Return a CUPS file associated with stderr.
* cupsFileStdin() - Return a CUPS file associated with stdin.
@@ -134,6 +135,8 @@ static ssize_t cups_write(cups_file_t *fp, const char *buf, size_t bytes);
/*
* 'cupsFileClose()' - Close a CUPS file.
+ *
+ * @since CUPS 1.2@
*/
int /* O - 0 on success, -1 on error */
@@ -261,9 +264,11 @@ cupsFileClose(cups_file_t *fp) /* I - CUPS file */
/*
* 'cupsFileCompression()' - Return whether a file is compressed.
+ *
+ * @since CUPS 1.2@
*/
-int /* O - CUPS_FILE_NONE or CUPS_FILE_GZIP */
+int /* O - @code CUPS_FILE_NONE@ or @code CUPS_FILE_GZIP@ */
cupsFileCompression(cups_file_t *fp) /* I - CUPS file */
{
return (fp ? fp->compressed : CUPS_FILE_NONE);
@@ -272,9 +277,11 @@ cupsFileCompression(cups_file_t *fp) /* I - CUPS file */
/*
* 'cupsFileEOF()' - Return the end-of-file status.
+ *
+ * @since CUPS 1.2@
*/
-int /* O - 1 on EOF, 0 otherwise */
+int /* O - 1 on end of file, 0 otherwise */
cupsFileEOF(cups_file_t *fp) /* I - CUPS file */
{
return (fp ? fp->eof : 1);
@@ -287,11 +294,13 @@ cupsFileEOF(cups_file_t *fp) /* I - CUPS file */
* This function allows the paths in the path string to be separated by
* colons (UNIX standard) or semicolons (Windows standard) and stores the
* result in the buffer supplied. If the file cannot be found in any of
- * the supplied paths, NULL is returned. A NULL path only matches the
- * current directory.
+ * the supplied paths, @code NULL@ is returned. A @code NULL@ path only
+ * matches the current directory.
+ *
+ * @since CUPS 1.2@
*/
-const char * /* O - Full path to file or NULL */
+const char * /* O - Full path to file or @code NULL@ if not found */
cupsFileFind(const char *filename, /* I - File to find */
const char *path, /* I - Colon/semicolon-separated path */
int executable, /* I - 1 = executable files, 0 = any file/dir */
@@ -386,6 +395,8 @@ cupsFileFind(const char *filename, /* I - File to find */
/*
* 'cupsFileFlush()' - Flush pending output.
+ *
+ * @since CUPS 1.2@
*/
int /* O - 0 on success, -1 on error */
@@ -431,9 +442,11 @@ cupsFileFlush(cups_file_t *fp) /* I - CUPS file */
/*
* 'cupsFileGetChar()' - Get a single character from a file.
+ *
+ * @since CUPS 1.2@
*/
-int /* O - Character or -1 on EOF */
+int /* O - Character or -1 on end of file */
cupsFileGetChar(cups_file_t *fp) /* I - CUPS file */
{
/*
@@ -469,9 +482,11 @@ cupsFileGetChar(cups_file_t *fp) /* I - CUPS file */
/*
* 'cupsFileGetConf()' - Get a line from a configuration file...
+ *
+ * @since CUPS 1.2@
*/
-char * /* O - Line read or NULL on eof/error */
+char * /* O - Line read or @code NULL@ on end of file or error */
cupsFileGetConf(cups_file_t *fp, /* I - CUPS file */
char *buf, /* O - String buffer */
size_t buflen, /* I - Size of string buffer */
@@ -603,13 +618,15 @@ cupsFileGetConf(cups_file_t *fp, /* I - CUPS file */
* 'cupsFileGetLine()' - Get a CR and/or LF-terminated line that may
* contain binary data.
*
- * This function differs from cupsFileGets() in that the trailing CR and LF
- * are preserved, as is any binary data on the line. The buffer is nul-
- * terminated, however you should use the returned length to determine
+ * This function differs from @link cupsFileGets@ in that the trailing CR
+ * and LF are preserved, as is any binary data on the line. The buffer is
+ * nul-terminated, however you should use the returned length to determine
* the number of bytes on the line.
+ *
+ * @since CUPS 1.2@
*/
-size_t /* O - Number of bytes on line or 0 on EOF */
+size_t /* O - Number of bytes on line or 0 on end of file */
cupsFileGetLine(cups_file_t *fp, /* I - File to read from */
char *buf, /* I - Buffer */
size_t buflen) /* I - Size of buffer */
@@ -671,9 +688,11 @@ cupsFileGetLine(cups_file_t *fp, /* I - File to read from */
/*
* 'cupsFileGets()' - Get a CR and/or LF-terminated line.
+ *
+ * @since CUPS 1.2@
*/
-char * /* O - Line read or NULL on eof/error */
+char * /* O - Line read or @code NULL@ on end of file or error */
cupsFileGets(cups_file_t *fp, /* I - CUPS file */
char *buf, /* O - String buffer */
size_t buflen) /* I - Size of string buffer */
@@ -742,10 +761,12 @@ cupsFileGets(cups_file_t *fp, /* I - CUPS file */
/*
* 'cupsFileLock()' - Temporarily lock access to a file.
+ *
+ * @since CUPS 1.2@
*/
int /* O - 0 on success, -1 on error */
-cupsFileLock(cups_file_t *fp, /* I - File to lock */
+cupsFileLock(cups_file_t *fp, /* I - CUPS file */
int block) /* I - 1 to wait for the lock, 0 to fail right away */
{
/*
@@ -769,20 +790,39 @@ cupsFileLock(cups_file_t *fp, /* I - File to lock */
/*
* 'cupsFileNumber()' - Return the file descriptor associated with a CUPS file.
+ *
+ * @since CUPS 1.2@
*/
int /* O - File descriptor */
cupsFileNumber(cups_file_t *fp) /* I - CUPS file */
{
- return (fp->fd);
+ if (fp)
+ return (fp->fd);
+ else
+ return (-1);
}
/*
* 'cupsFileOpen()' - Open a CUPS file.
+ *
+ * The "mode" parameter can be "r" to read, "w" to write, overwriting any
+ * existing file, "a" to append to an existing file or create a new file,
+ * or "s" to open a socket connection.
+ *
+ * When opening for writing ("w") or appending ("a"), an optional number from
+ * 1 to 9 can be supplied which enables Flate compression of the file.
+ *
+ * When opening a socket connection, the filename is a string of the form
+ * "address:port" or "hostname:port". The socket will make an IPv4 or IPv6
+ * connection as needed, generally preferring IPv6 connections when there is
+ * a choice.
+ *
+ * @since CUPS 1.2@
*/
-cups_file_t * /* O - CUPS file or NULL */
+cups_file_t * /* O - CUPS file or @code NULL@ if the file or socket cannot be opened */
cupsFileOpen(const char *filename, /* I - Name of file */
const char *mode) /* I - Open mode */
{
@@ -877,9 +917,17 @@ cupsFileOpen(const char *filename, /* I - Name of file */
/*
* 'cupsFileOpenFd()' - Open a CUPS file using a file descriptor.
+ *
+ * The "mode" parameter can be "r" to read, "a" or "w" to write, or "s"
+ * to treat the file descriptor as a bidirectional socket connection.
+ *
+ * When opening for writing ("w") or appending ("a"), an optional number from
+ * 1 to 9 can be supplied which enables Flate compression of the file.
+ *
+ * @since CUPS 1.2@
*/
-cups_file_t * /* O - CUPS file or NULL */
+cups_file_t * /* O - CUPS file or @code NULL@ if the file could not be opened */
cupsFileOpenFd(int fd, /* I - File descriptor */
const char *mode) /* I - Open mode */
{
@@ -984,9 +1032,11 @@ cupsFileOpenFd(int fd, /* I - File descriptor */
/*
* 'cupsFilePeekChar()' - Peek at the next character from a file.
+ *
+ * @since CUPS 1.2@
*/
-int /* O - Character or -1 on EOF */
+int /* O - Character or -1 on end of file */
cupsFilePeekChar(cups_file_t *fp) /* I - CUPS file */
{
/*
@@ -1014,9 +1064,11 @@ cupsFilePeekChar(cups_file_t *fp) /* I - CUPS file */
/*
* 'cupsFilePrintf()' - Write a formatted string.
+ *
+ * @since CUPS 1.2@
*/
-int /* O - Number of bytes written or -1 */
+int /* O - Number of bytes written or -1 on error */
cupsFilePrintf(cups_file_t *fp, /* I - CUPS file */
const char *format, /* I - Printf-style format string */
...) /* I - Additional args as necessary */
@@ -1067,6 +1119,8 @@ cupsFilePrintf(cups_file_t *fp, /* I - CUPS file */
/*
* 'cupsFilePutChar()' - Write a character.
+ *
+ * @since CUPS 1.2@
*/
int /* O - 0 on success, -1 on error */
@@ -1115,9 +1169,13 @@ cupsFilePutChar(cups_file_t *fp, /* I - CUPS file */
/*
* 'cupsFilePuts()' - Write a string.
+ *
+ * Like the @code fputs@ function, no newline is appended to the string.
+ *
+ * @since CUPS 1.2@
*/
-int /* O - Number of bytes written or -1 */
+int /* O - Number of bytes written or -1 on error */
cupsFilePuts(cups_file_t *fp, /* I - CUPS file */
const char *s) /* I - String to write */
{
@@ -1173,9 +1231,11 @@ cupsFilePuts(cups_file_t *fp, /* I - CUPS file */
/*
* 'cupsFileRead()' - Read from a file.
+ *
+ * @since CUPS 1.2@
*/
-ssize_t /* O - Number of bytes read or -1 */
+ssize_t /* O - Number of bytes read or -1 on error */
cupsFileRead(cups_file_t *fp, /* I - CUPS file */
char *buf, /* O - Buffer */
size_t bytes) /* I - Number of bytes to read */
@@ -1242,10 +1302,13 @@ cupsFileRead(cups_file_t *fp, /* I - CUPS file */
/*
- * 'cupsFileRewind()' - Rewind a file.
+ * 'cupsFileRewind()' - Set the current file position to the beginning of the
+ * file.
+ *
+ * @since CUPS 1.2@
*/
-off_t /* O - New file position or -1 */
+off_t /* O - New file position or -1 on error */
cupsFileRewind(cups_file_t *fp) /* I - CUPS file */
{
/*
@@ -1299,9 +1362,11 @@ cupsFileRewind(cups_file_t *fp) /* I - CUPS file */
/*
* 'cupsFileSeek()' - Seek in a file.
+ *
+ * @since CUPS 1.2@
*/
-off_t /* O - New file position or -1 */
+off_t /* O - New file position or -1 on error */
cupsFileSeek(cups_file_t *fp, /* I - CUPS file */
off_t pos) /* I - Position in file */
{
@@ -1454,9 +1519,11 @@ cupsFileSeek(cups_file_t *fp, /* I - CUPS file */
/*
* 'cupsFileStderr()' - Return a CUPS file associated with stderr.
+ *
+ * @since CUPS 1.2@
*/
-cups_file_t *
+cups_file_t * /* O - CUPS file */
cupsFileStderr(void)
{
_cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals... */
@@ -1488,9 +1555,11 @@ cupsFileStderr(void)
/*
* 'cupsFileStdin()' - Return a CUPS file associated with stdin.
+ *
+ * @since CUPS 1.2@
*/
-cups_file_t *
+cups_file_t * /* O - CUPS file */
cupsFileStdin(void)
{
_cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals... */
@@ -1516,9 +1585,11 @@ cupsFileStdin(void)
/*
* 'cupsFileStdout()' - Return a CUPS file associated with stdout.
+ *
+ * @since CUPS 1.2@
*/
-cups_file_t *
+cups_file_t * /* O - CUPS file */
cupsFileStdout(void)
{
_cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals... */
@@ -1550,6 +1621,8 @@ cupsFileStdout(void)
/*
* 'cupsFileTell()' - Return the current file position.
+ *
+ * @since CUPS 1.2@
*/
off_t /* O - File position */
@@ -1561,10 +1634,12 @@ cupsFileTell(cups_file_t *fp) /* I - CUPS file */
/*
* 'cupsFileUnlock()' - Unlock access to a file.
+ *
+ * @since CUPS 1.2@
*/
int /* O - 0 on success, -1 on error */
-cupsFileUnlock(cups_file_t *fp) /* I - File to lock */
+cupsFileUnlock(cups_file_t *fp) /* I - CUPS file */
{
/*
* Range check...
@@ -1587,9 +1662,11 @@ cupsFileUnlock(cups_file_t *fp) /* I - File to lock */
/*
* 'cupsFileWrite()' - Write to a file.
+ *
+ * @since CUPS 1.2@
*/
-ssize_t /* O - Number of bytes written */
+ssize_t /* O - Number of bytes written or -1 on error */
cupsFileWrite(cups_file_t *fp, /* I - CUPS file */
const char *buf, /* I - Buffer */
size_t bytes) /* I - Number of bytes to write */
diff --git a/cups/getputfile.c b/cups/getputfile.c
index b39a8339b..e144bd8e6 100644
--- a/cups/getputfile.c
+++ b/cups/getputfile.c
@@ -3,7 +3,7 @@
*
* Get/put file functions for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -45,13 +45,13 @@
/*
* 'cupsGetFd()' - Get a file from the server.
*
- * This function returns HTTP_OK when the file is successfully retrieved.
+ * This function returns @code HTTP_OK@ when the file is successfully retrieved.
*
* @since CUPS 1.1.20@
*/
http_status_t /* O - HTTP status */
-cupsGetFd(http_t *http, /* I - HTTP connection to server */
+cupsGetFd(http_t *http, /* I - HTTP connection to server or @code CUPS_HTTP_DEFAULT@ */
const char *resource, /* I - Resource name */
int fd) /* I - File descriptor */
{
@@ -69,7 +69,7 @@ cupsGetFd(http_t *http, /* I - HTTP connection to server */
DEBUG_printf(("cupsGetFd(http=%p, resource=\"%s\", fd=%d)\n", http,
resource, fd));
- if (!http || !resource || fd < 0)
+ if (!resource || fd < 0)
{
if (http)
http->error = EINVAL;
@@ -77,6 +77,9 @@ cupsGetFd(http_t *http, /* I - HTTP connection to server */
return (HTTP_ERROR);
}
+ if (!http)
+ http = _cupsConnect();
+
/*
* Then send GET requests to the HTTP server...
*/
@@ -182,13 +185,13 @@ cupsGetFd(http_t *http, /* I - HTTP connection to server */
/*
* 'cupsGetFile()' - Get a file from the server.
*
- * This function returns HTTP_OK when the file is successfully retrieved.
+ * This function returns @code HTTP_OK@ when the file is successfully retrieved.
*
* @since CUPS 1.1.20@
*/
http_status_t /* O - HTTP status */
-cupsGetFile(http_t *http, /* I - HTTP connection to server */
+cupsGetFile(http_t *http, /* I - HTTP connection to server or @code CUPS_HTTP_DEFAULT@ */
const char *resource, /* I - Resource name */
const char *filename) /* I - Filename */
{
@@ -249,13 +252,14 @@ cupsGetFile(http_t *http, /* I - HTTP connection to server */
/*
* 'cupsPutFd()' - Put a file on the server.
*
- * This function returns HTTP_CREATED when the file is stored successfully.
+ * This function returns @code HTTP_CREATED@ when the file is stored
+ * successfully.
*
* @since CUPS 1.1.20@
*/
http_status_t /* O - HTTP status */
-cupsPutFd(http_t *http, /* I - HTTP connection to server */
+cupsPutFd(http_t *http, /* I - HTTP connection to server or @code CUPS_HTTP_DEFAULT@ */
const char *resource, /* I - Resource name */
int fd) /* I - File descriptor */
{
@@ -272,7 +276,7 @@ cupsPutFd(http_t *http, /* I - HTTP connection to server */
DEBUG_printf(("cupsPutFd(http=%p, resource=\"%s\", fd=%d)\n", http,
resource, fd));
- if (!http || !resource || fd < 0)
+ if (!resource || fd < 0)
{
if (http)
http->error = EINVAL;
@@ -280,6 +284,9 @@ cupsPutFd(http_t *http, /* I - HTTP connection to server */
return (HTTP_ERROR);
}
+ if (!http)
+ http = _cupsConnect();
+
/*
* Then send PUT requests to the HTTP server...
*/
@@ -430,13 +437,14 @@ cupsPutFd(http_t *http, /* I - HTTP connection to server */
/*
* 'cupsPutFile()' - Put a file on the server.
*
- * This function returns HTTP_CREATED when the file is stored successfully.
+ * This function returns @code HTTP_CREATED@ when the file is stored
+ * successfully.
*
* @since CUPS 1.1.20@
*/
http_status_t /* O - HTTP status */
-cupsPutFile(http_t *http, /* I - HTTP connection to server */
+cupsPutFile(http_t *http, /* I - HTTP connection to server or @code CUPS_HTTP_DEFAULT@ */
const char *resource, /* I - Resource name */
const char *filename) /* I - Filename */
{
diff --git a/cups/ipp-private.h b/cups/ipp-private.h
index e38ca26e1..0083d2a38 100644
--- a/cups/ipp-private.h
+++ b/cups/ipp-private.h
@@ -3,7 +3,7 @@
*
* Private IPP definitions for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -40,6 +40,7 @@ extern "C" {
typedef struct /**** Attribute mapping data ****/
{
+ int multivalue; /* Option has multiple values? */
const char *name; /* Option/attribute name */
ipp_tag_t value_tag; /* Value tag for this attribute */
ipp_tag_t group_tag; /* Group tag for this attribute */
diff --git a/cups/ipp.c b/cups/ipp.c
index f212fd117..41f65c1d6 100644
--- a/cups/ipp.c
+++ b/cups/ipp.c
@@ -1187,17 +1187,15 @@ ippReadIO(void *src, /* I - Data source */
attr->value_tag = tag;
}
- else if (value_tag == IPP_TAG_STRING ||
- (value_tag >= IPP_TAG_TEXTLANG &&
- value_tag <= IPP_TAG_MIMETYPE))
+ else if (value_tag >= IPP_TAG_TEXTLANG &&
+ value_tag <= IPP_TAG_MIMETYPE)
{
/*
* String values can sometimes come across in different
* forms; accept sets of differing values...
*/
- if (tag != IPP_TAG_STRING &&
- (tag < IPP_TAG_TEXTLANG || tag > IPP_TAG_MIMETYPE))
+ if (tag < IPP_TAG_TEXTLANG || tag > IPP_TAG_MIMETYPE)
return (IPP_ERROR);
}
else if (value_tag != tag)
@@ -1334,6 +1332,7 @@ ippReadIO(void *src, /* I - Data source */
value->integer = n;
break;
+
case IPP_TAG_BOOLEAN :
if (n != 1)
{
@@ -1349,10 +1348,10 @@ ippReadIO(void *src, /* I - Data source */
value->boolean = buffer[0];
break;
+
case IPP_TAG_TEXT :
case IPP_TAG_NAME :
case IPP_TAG_KEYWORD :
- case IPP_TAG_STRING :
case IPP_TAG_URI :
case IPP_TAG_URISCHEME :
case IPP_TAG_CHARSET :
@@ -1375,6 +1374,7 @@ ippReadIO(void *src, /* I - Data source */
DEBUG_printf(("ippReadIO: value = \'%s\'\n",
value->string.text));
break;
+
case IPP_TAG_DATE :
if (n != 11)
{
@@ -1388,6 +1388,7 @@ ippReadIO(void *src, /* I - Data source */
return (IPP_ERROR);
}
break;
+
case IPP_TAG_RESOLUTION :
if (n != 9)
{
@@ -1410,6 +1411,7 @@ ippReadIO(void *src, /* I - Data source */
value->resolution.units =
(ipp_res_t)buffer[8];
break;
+
case IPP_TAG_RANGE :
if (n != 8)
{
@@ -1430,6 +1432,7 @@ ippReadIO(void *src, /* I - Data source */
(((((buffer[4] << 8) | buffer[5]) << 8) | buffer[6]) << 8) |
buffer[7];
break;
+
case IPP_TAG_TEXTLANG :
case IPP_TAG_NAMELANG :
if (n >= sizeof(buffer) || n < 4)
@@ -1955,7 +1958,6 @@ ippWriteIO(void *dst, /* I - Destination */
case IPP_TAG_TEXT :
case IPP_TAG_NAME :
case IPP_TAG_KEYWORD :
- case IPP_TAG_STRING :
case IPP_TAG_URI :
case IPP_TAG_URISCHEME :
case IPP_TAG_CHARSET :
@@ -2521,7 +2523,6 @@ _ippFreeAttr(ipp_attribute_t *attr) /* I - Attribute to free */
case IPP_TAG_TEXT :
case IPP_TAG_NAME :
case IPP_TAG_KEYWORD :
- case IPP_TAG_STRING :
case IPP_TAG_URI :
case IPP_TAG_URISCHEME :
case IPP_TAG_CHARSET :
@@ -2560,6 +2561,13 @@ _ippFreeAttr(ipp_attribute_t *attr) /* I - Attribute to free */
ippDelete(value->collection);
break;
+ case IPP_TAG_STRING :
+ for (i = 0, value = attr->values;
+ i < attr->num_values;
+ i ++, value ++)
+ free(value->unknown.data);
+ break;
+
default :
if (!((int)attr->value_tag & IPP_TAG_COPY))
{
@@ -2648,7 +2656,6 @@ ipp_length(ipp_t *ipp, /* I - IPP message or collection */
case IPP_TAG_TEXT :
case IPP_TAG_NAME :
case IPP_TAG_KEYWORD :
- case IPP_TAG_STRING :
case IPP_TAG_URI :
case IPP_TAG_URISCHEME :
case IPP_TAG_CHARSET :
diff --git a/cups/ipp.h b/cups/ipp.h
index 29ef86afd..2a36fe35b 100644
--- a/cups/ipp.h
+++ b/cups/ipp.h
@@ -265,7 +265,7 @@ typedef enum ipp_status_e /**** IPP status codes... ****/
IPP_OK_TOO_MANY_EVENTS, /* successful-ok-too-many-events */
IPP_OK_BUT_CANCEL_SUBSCRIPTION, /* successful-ok-but-cancel-subscription */
IPP_OK_EVENTS_COMPLETE, /* successful-ok-events-complete */
- IPP_REDIRECTION_OTHER_SITE = 0x200, /* */
+ IPP_REDIRECTION_OTHER_SITE = 0x200, /* redirection-other-site @private@ */
CUPS_SEE_OTHER = 0x280, /* cups-see-other */
IPP_BAD_REQUEST = 0x0400, /* client-error-bad-request */
IPP_FORBIDDEN, /* client-error-forbidden */
diff --git a/cups/language.c b/cups/language.c
index ea629c903..e08bde626 100644
--- a/cups/language.c
+++ b/cups/language.c
@@ -344,7 +344,7 @@ cupsLangFlush(void)
/*
* 'cupsLangFree()' - Free language data.
*
- * This does not actually free anything; use cupsLangFlush() for that.
+ * This does not actually free anything; use @link cupsLangFlush@ for that.
*/
void
diff --git a/cups/libcups.exp b/cups/libcups.exp
index a757eedcd..930c0d5d2 100644
--- a/cups/libcups.exp
+++ b/cups/libcups.exp
@@ -305,6 +305,7 @@ _ppdIsMarked
_ppdLastError
_ppdLocalize
_ppdLocalizeIPPReason
+_ppdLocalizeMarkerName
_ppdMarkDefaults
_ppdMarkOption
_ppdNextCustomParam
diff --git a/cups/localize.c b/cups/localize.c
index c03786ff3..9c91f6260 100644
--- a/cups/localize.c
+++ b/cups/localize.c
@@ -1,9 +1,9 @@
/*
* "$Id: localize.c 6882 2007-08-29 21:05:10Z mike $"
*
- * PPD custom option routines for the Common UNIX Printing System (CUPS).
+ * PPD localization routines for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -25,11 +25,13 @@
*
* Contents:
*
- * ppdLocalize() - Localize the PPD file to the current locale.
- * ppdLocalizeIPPReason() - Get the localized version of a cupsIPPReason
- * attribute.
- * ppd_ll_CC() - Get the current locale names.
- * ppd_localized_attr() - Find a localized attribute.
+ * ppdLocalize() - Localize the PPD file to the current locale.
+ * ppdLocalizeIPPReason() - Get the localized version of a cupsIPPReason
+ * attribute.
+ * ppdLocalizeMarkerName() - Get the localized version of a marker-names
+ * attribute value.
+ * ppd_ll_CC() - Get the current locale names.
+ * ppd_localized_attr() - Find a localized attribute.
*/
/*
@@ -387,6 +389,52 @@ ppdLocalizeIPPReason(
/*
+ * 'ppdLocalizeMarkerName()' - Get the localized version of a marker-names
+ * attribute value.
+ *
+ * This function uses the current locale to find the corresponding name
+ * text from the attribute value. If no localized text for the requested
+ * name can be found, @code NULL@ is returned.
+ *
+ * @since CUPS 1.4@
+ */
+
+const char * /* O - Value or @code NULL@ if not found */
+ppdLocalizeMarkerName(
+ ppd_file_t *ppd, /* I - PPD file */
+ const char *name) /* I - Marker name to look up */
+{
+ ppd_attr_t *locattr; /* Localized attribute */
+ char ll_CC[6], /* Language + country locale */
+ ll[3]; /* Language locale */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (!ppd || !name)
+ return (NULL);
+
+ /*
+ * Get the default language...
+ */
+
+ ppd_ll_CC(ll_CC, sizeof(ll_CC), ll, sizeof(ll));
+
+ /*
+ * Find the localized attribute...
+ */
+
+ if ((locattr = ppd_localized_attr(ppd, "cupsMarkerName", name,
+ ll_CC, ll)) == NULL)
+ locattr = ppdFindAttr(ppd, "cupsMarkerName", name);
+
+ return (locattr ? locattr->text : NULL);
+}
+
+
+/*
* 'ppd_ll_CC()' - Get the current locale names.
*/
diff --git a/cups/mark.c b/cups/mark.c
index 689aefb0f..0dbb0b8d1 100644
--- a/cups/mark.c
+++ b/cups/mark.c
@@ -1,9 +1,9 @@
/*
- * "$Id: mark.c 6939 2007-09-10 21:18:02Z mike $"
+ * "$Id: mark.c 7278 2008-01-31 01:23:09Z mike $"
*
* Option marking routines for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -18,16 +18,20 @@
*
* Contents:
*
- * ppdConflicts() - Check to see if there are any conflicts.
+ * cupsMarkOptions() - Mark command-line options in a PPD file.
+ * ppdConflicts() - Check to see if there are any conflicts among the
+ * marked option choices.
* ppdFindChoice() - Return a pointer to an option choice.
* ppdFindMarkedChoice() - Return the marked choice for the specified option.
* ppdFindOption() - Return a pointer to the specified option.
- * ppdFirstOption() - Return the first option in the PPD file.
- * ppdNextOption() - Return the next option in the PPD file.
- * ppdIsMarked() - Check to see if an option is marked...
+ * ppdIsMarked() - Check to see if an option is marked.
* ppdMarkDefaults() - Mark all default options in the PPD file.
* ppdMarkOption() - Mark an option in a PPD file.
+ * ppdFirstOption() - Return the first option in the PPD file.
+ * ppdNextOption() - Return the next option in the PPD file.
+ * debug_marked() - Output the marked array to stdout...
* ppd_defaults() - Set the defaults for this group and all sub-groups.
+ * ppd_mark_choices() - Mark one or more option choices from a string.
*/
/*
@@ -43,11 +47,317 @@
* Local functions...
*/
+#ifdef DEBUG
+static void debug_marked(ppd_file_t *ppd, const char *title);
+#else
+# define debug_marked(ppd,title)
+#endif /* DEBUG */
static void ppd_defaults(ppd_file_t *ppd, ppd_group_t *g);
+static int ppd_mark_choices(ppd_file_t *ppd, const char *options);
/*
- * 'ppdConflicts()' - Check to see if there are any conflicts.
+ * 'cupsMarkOptions()' - Mark command-line options in a PPD file.
+ *
+ * This function maps the IPP "finishings", "media", "mirror",
+ * "multiple-document-handling", "output-bin", "printer-resolution", and
+ * "sides" attributes to their corresponding PPD options and choices.
+ */
+
+int /* O - 1 if conflicting */
+cupsMarkOptions(
+ ppd_file_t *ppd, /* I - PPD file */
+ int num_options, /* I - Number of options */
+ cups_option_t *options) /* I - Options */
+{
+ int i, j, k; /* Looping vars */
+ int conflict; /* Option conflicts */
+ char *val, /* Pointer into value */
+ *ptr, /* Pointer into string */
+ s[255]; /* Temporary string */
+ const char *page_size; /* PageSize option */
+ cups_option_t *optptr; /* Current option */
+ ppd_option_t *option; /* PPD option */
+ ppd_attr_t *attr; /* PPD attribute */
+ static const char * const duplex_options[] =
+ { /* Duplex option names */
+ "Duplex", /* Adobe */
+ "EFDuplex", /* EFI */
+ "EFDuplexing", /* EFI */
+ "KD03Duplex", /* Kodak */
+ "JCLDuplex" /* Samsung */
+ };
+ static const char * const duplex_one[] =
+ { /* one-sided names */
+ "None",
+ "False"
+ };
+ static const char * const duplex_two_long[] =
+ { /* two-sided-long-edge names */
+ "DuplexNoTumble", /* Adobe */
+ "LongEdge", /* EFI */
+ "Top" /* EFI */
+ };
+ static const char * const duplex_two_short[] =
+ { /* two-sided-long-edge names */
+ "DuplexTumble", /* Adobe */
+ "ShortEdge", /* EFI */
+ "Bottom" /* EFI */
+ };
+
+
+ /*
+ * Check arguments...
+ */
+
+ if (!ppd || num_options <= 0 || !options)
+ return (0);
+
+ debug_marked(ppd, "Before...");
+
+ /*
+ * Mark options...
+ */
+
+ conflict = 0;
+
+ for (i = num_options, optptr = options; i > 0; i --, optptr ++)
+ if (!strcasecmp(optptr->name, "media"))
+ {
+ /*
+ * Loop through the option string, separating it at commas and
+ * marking each individual option as long as the corresponding
+ * PPD option (PageSize, InputSlot, etc.) is not also set.
+ *
+ * For PageSize, we also check for an empty option value since
+ * some versions of MacOS X use it to specify auto-selection
+ * of the media based solely on the size.
+ */
+
+ page_size = cupsGetOption("PageSize", num_options, options);
+
+ for (val = optptr->value; *val;)
+ {
+ /*
+ * Extract the sub-option from the string...
+ */
+
+ for (ptr = s; *val && *val != ',' && (ptr - s) < (sizeof(s) - 1);)
+ *ptr++ = *val++;
+ *ptr++ = '\0';
+
+ if (*val == ',')
+ val ++;
+
+ /*
+ * Mark it...
+ */
+
+ if (!page_size || !page_size[0])
+ if (ppdMarkOption(ppd, "PageSize", s))
+ conflict = 1;
+
+ if (cupsGetOption("InputSlot", num_options, options) == NULL)
+ if (ppdMarkOption(ppd, "InputSlot", s))
+ conflict = 1;
+
+ if (cupsGetOption("MediaType", num_options, options) == NULL)
+ if (ppdMarkOption(ppd, "MediaType", s))
+ conflict = 1;
+
+ if (cupsGetOption("EFMediaType", num_options, options) == NULL)
+ if (ppdMarkOption(ppd, "EFMediaType", s)) /* EFI */
+ conflict = 1;
+
+ if (cupsGetOption("EFMediaQualityMode", num_options, options) == NULL)
+ if (ppdMarkOption(ppd, "EFMediaQualityMode", s)) /* EFI */
+ conflict = 1;
+
+ if (strcasecmp(s, "manual") == 0 &&
+ cupsGetOption("ManualFeed", num_options, options) == NULL)
+ if (ppdMarkOption(ppd, "ManualFeed", "True"))
+ conflict = 1;
+ }
+ }
+ else if (!strcasecmp(optptr->name, "sides"))
+ {
+ for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
+ if (cupsGetOption(duplex_options[j], num_options, options) != NULL)
+ break;
+
+ if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
+ {
+ /*
+ * Don't override the PPD option with the IPP attribute...
+ */
+
+ continue;
+ }
+
+ if (!strcasecmp(optptr->value, "one-sided"))
+ {
+ /*
+ * Mark the appropriate duplex option for one-sided output...
+ */
+
+ for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
+ if ((option = ppdFindOption(ppd, duplex_options[j])) != NULL)
+ break;
+
+ if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
+ {
+ for (k = 0; k < (int)(sizeof(duplex_one) / sizeof(duplex_one[0])); k ++)
+ if (ppdFindChoice(option, duplex_one[k]))
+ {
+ if (ppdMarkOption(ppd, duplex_options[j], duplex_one[k]))
+ conflict = 1;
+
+ break;
+ }
+ }
+ }
+ else if (!strcasecmp(optptr->value, "two-sided-long-edge"))
+ {
+ /*
+ * Mark the appropriate duplex option for two-sided-long-edge output...
+ */
+
+ for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
+ if ((option = ppdFindOption(ppd, duplex_options[j])) != NULL)
+ break;
+
+ if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
+ {
+ for (k = 0; k < (int)(sizeof(duplex_two_long) / sizeof(duplex_two_long[0])); k ++)
+ if (ppdFindChoice(option, duplex_two_long[k]))
+ {
+ if (ppdMarkOption(ppd, duplex_options[j], duplex_two_long[k]))
+ conflict = 1;
+
+ break;
+ }
+ }
+ }
+ else if (!strcasecmp(optptr->value, "two-sided-short-edge"))
+ {
+ /*
+ * Mark the appropriate duplex option for two-sided-short-edge output...
+ */
+
+ for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
+ if ((option = ppdFindOption(ppd, duplex_options[j])) != NULL)
+ break;
+
+ if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
+ {
+ for (k = 0; k < (int)(sizeof(duplex_two_short) / sizeof(duplex_two_short[0])); k ++)
+ if (ppdFindChoice(option, duplex_two_short[k]))
+ {
+ if (ppdMarkOption(ppd, duplex_options[j], duplex_two_short[k]))
+ conflict = 1;
+
+ break;
+ }
+ }
+ }
+ }
+ else if (!strcasecmp(optptr->name, "resolution") ||
+ !strcasecmp(optptr->name, "printer-resolution"))
+ {
+ if (ppdMarkOption(ppd, "Resolution", optptr->value))
+ conflict = 1;
+ if (ppdMarkOption(ppd, "SetResolution", optptr->value))
+ /* Calcomp, Linotype, QMS, Summagraphics, Tektronix, Varityper */
+ conflict = 1;
+ if (ppdMarkOption(ppd, "JCLResolution", optptr->value)) /* HP */
+ conflict = 1;
+ if (ppdMarkOption(ppd, "CNRes_PGP", optptr->value)) /* Canon */
+ conflict = 1;
+ }
+ else if (!strcasecmp(optptr->name, "output-bin"))
+ {
+ if (!cupsGetOption("OutputBin", num_options, options))
+ if (ppdMarkOption(ppd, "OutputBin", optptr->value))
+ conflict = 1;
+ }
+ else if (!strcasecmp(optptr->name, "multiple-document-handling"))
+ {
+ if (!cupsGetOption("Collate", num_options, options) &&
+ ppdFindOption(ppd, "Collate"))
+ {
+ if (strcasecmp(optptr->value, "separate-documents-uncollated-copies"))
+ {
+ if (ppdMarkOption(ppd, "Collate", "True"))
+ conflict = 1;
+ }
+ else
+ {
+ if (ppdMarkOption(ppd, "Collate", "False"))
+ conflict = 1;
+ }
+ }
+ }
+ else if (!strcasecmp(optptr->name, "finishings"))
+ {
+ /*
+ * Lookup cupsIPPFinishings attributes for each value...
+ */
+
+ for (ptr = optptr->value; *ptr;)
+ {
+ /*
+ * Get the next finishings number...
+ */
+
+ if (!isdigit(*ptr & 255))
+ break;
+
+ if ((j = strtol(ptr, &ptr, 10)) < 3)
+ break;
+
+ /*
+ * Skip separator as needed...
+ */
+
+ if (*ptr == ',')
+ ptr ++;
+
+ /*
+ * Look it up in the PPD file...
+ */
+
+ sprintf(s, "%d", j);
+
+ if ((attr = ppdFindAttr(ppd, "cupsIPPFinishings", s)) == NULL)
+ continue;
+
+ /*
+ * Apply "*Option Choice" settings from the attribute value...
+ */
+
+ if (ppd_mark_choices(ppd, attr->value))
+ conflict = 1;
+ }
+ }
+ else if (!strcasecmp(optptr->name, "mirror"))
+ {
+ if (ppdMarkOption(ppd, "MirrorPrint", optptr->value))
+ conflict = 1;
+ }
+ else if (ppdMarkOption(ppd, optptr->name, optptr->value))
+ conflict = 1;
+
+ debug_marked(ppd, "After...");
+
+ return (conflict);
+}
+
+
+/*
+ * 'ppdConflicts()' - Check to see if there are any conflicts among the
+ * marked option choices.
+ *
+ * The returned value is the same as returned by @link ppdMarkOption@.
*/
int /* O - Number of conflicts found */
@@ -189,7 +499,7 @@ ppdConflicts(ppd_file_t *ppd) /* I - PPD to check */
* 'ppdFindChoice()' - Return a pointer to an option choice.
*/
-ppd_choice_t * /* O - Choice pointer or NULL */
+ppd_choice_t * /* O - Choice pointer or @code NULL@ */
ppdFindChoice(ppd_option_t *o, /* I - Pointer to option */
const char *choice) /* I - Name of choice */
{
@@ -212,7 +522,7 @@ ppdFindChoice(ppd_option_t *o, /* I - Pointer to option */
* 'ppdFindMarkedChoice()' - Return the marked choice for the specified option.
*/
-ppd_choice_t * /* O - Pointer to choice or NULL */
+ppd_choice_t * /* O - Pointer to choice or @code NULL@ */
ppdFindMarkedChoice(ppd_file_t *ppd, /* I - PPD file */
const char *option) /* I - Keyword/option name */
{
@@ -230,7 +540,7 @@ ppdFindMarkedChoice(ppd_file_t *ppd, /* I - PPD file */
* 'ppdFindOption()' - Return a pointer to the specified option.
*/
-ppd_option_t * /* O - Pointer to option or NULL */
+ppd_option_t * /* O - Pointer to option or @code NULL@ */
ppdFindOption(ppd_file_t *ppd, /* I - PPD file data */
const char *option) /* I - Option/Keyword name */
{
@@ -278,7 +588,7 @@ ppdFindOption(ppd_file_t *ppd, /* I - PPD file data */
/*
- * 'ppdIsMarked()' - Check to see if an option is marked...
+ * 'ppdIsMarked()' - Check to see if an option is marked.
*/
int /* O - Non-zero if option is marked */
@@ -338,11 +648,6 @@ ppdMarkDefaults(ppd_file_t *ppd) /* I - PPD file record */
/*
* 'ppdMarkOption()' - Mark an option in a PPD file.
- *
- * Notes:
- *
- * -1 is returned if the given option would conflict with any currently
- * selected option.
*/
int /* O - Number of conflicts */
@@ -668,12 +973,12 @@ ppdMarkOption(ppd_file_t *ppd, /* I - PPD file record */
/*
* 'ppdFirstOption()' - Return the first option in the PPD file.
*
- * Options are returned from all groups in sorted order.
+ * Options are returned from all groups in ascending alphanumeric order.
*
* @since CUPS 1.2@
*/
-ppd_option_t * /* O - First option or NULL */
+ppd_option_t * /* O - First option or @code NULL@ */
ppdFirstOption(ppd_file_t *ppd) /* I - PPD file */
{
if (!ppd)
@@ -686,12 +991,12 @@ ppdFirstOption(ppd_file_t *ppd) /* I - PPD file */
/*
* 'ppdNextOption()' - Return the next option in the PPD file.
*
- * Options are returned from all groups in sorted order.
+ * Options are returned from all groups in ascending alphanumeric order.
*
* @since CUPS 1.2@
*/
-ppd_option_t * /* O - Next option or NULL */
+ppd_option_t * /* O - Next option or @code NULL@ */
ppdNextOption(ppd_file_t *ppd) /* I - PPD file */
{
if (!ppd)
@@ -701,17 +1006,39 @@ ppdNextOption(ppd_file_t *ppd) /* I - PPD file */
}
+#ifdef DEBUG
+/*
+ * 'debug_marked()' - Output the marked array to stdout...
+ */
+
+static void
+debug_marked(ppd_file_t *ppd, /* I - PPD file data */
+ const char *title) /* I - Title for list */
+{
+ ppd_choice_t *c; /* Current choice */
+
+
+ printf("cupsMarkOptions: %s\n", title);
+
+ for (c = (ppd_choice_t *)cupsArrayFirst(ppd->marked);
+ c;
+ c = (ppd_choice_t *)cupsArrayNext(ppd->marked))
+ printf("cupsMarkOptions: %s=%s\n", c->option->keyword, c->choice);
+}
+#endif /* DEBUG */
+
+
/*
* 'ppd_defaults()' - Set the defaults for this group and all sub-groups.
*/
static void
-ppd_defaults(ppd_file_t *ppd, /* I - PPD file */
- ppd_group_t *g) /* I - Group to default */
+ppd_defaults(ppd_file_t *ppd, /* I - PPD file */
+ ppd_group_t *g) /* I - Group to default */
{
- int i; /* Looping var */
- ppd_option_t *o; /* Current option */
- ppd_group_t *sg; /* Current sub-group */
+ int i; /* Looping var */
+ ppd_option_t *o; /* Current option */
+ ppd_group_t *sg; /* Current sub-group */
for (i = g->num_options, o = g->options; i > 0; i --, o ++)
@@ -724,5 +1051,87 @@ ppd_defaults(ppd_file_t *ppd, /* I - PPD file */
/*
- * End of "$Id: mark.c 6939 2007-09-10 21:18:02Z mike $".
+ * 'ppd_mark_choices()' - Mark one or more option choices from a string.
+ */
+
+static int /* O - 1 if there are conflicts, 0 otherwise */
+ppd_mark_choices(ppd_file_t *ppd, /* I - PPD file */
+ const char *options) /* I - "*Option Choice ..." string */
+{
+ char option[PPD_MAX_NAME], /* Current option */
+ choice[PPD_MAX_NAME], /* Current choice */
+ *ptr; /* Pointer into option or choice */
+ int conflict = 0; /* Do we have a conflict? */
+
+
+ if (!options)
+ return (0);
+
+ /*
+ * Read all of the "*Option Choice" pairs from the string, marking PPD
+ * options as we go...
+ */
+
+ while (*options)
+ {
+ /*
+ * Skip leading whitespace...
+ */
+
+ while (isspace(*options & 255))
+ options ++;
+
+ if (*options != '*')
+ break;
+
+ /*
+ * Get the option name...
+ */
+
+ options ++;
+ ptr = option;
+ while (*options && !isspace(*options & 255) &&
+ ptr < (option + sizeof(option) - 1))
+ *ptr++ = *options++;
+
+ if (ptr == option)
+ break;
+
+ *ptr = '\0';
+
+ /*
+ * Get the choice...
+ */
+
+ while (isspace(*options & 255))
+ options ++;
+
+ if (!*options)
+ break;
+
+ ptr = choice;
+ while (*options && !isspace(*options & 255) &&
+ ptr < (choice + sizeof(choice) - 1))
+ *ptr++ = *options++;
+
+ *ptr = '\0';
+
+ /*
+ * Mark the option...
+ */
+
+ if (ppdMarkOption(ppd, option, choice))
+ conflict = 1;
+ }
+
+ /*
+ * Return whether we had any conflicts...
+ */
+
+ return (conflict);
+}
+
+
+/*
+ * End of "$Id: mark.c 7278 2008-01-31 01:23:09Z mike $".
*/
diff --git a/cups/notify.c b/cups/notify.c
index 02bb74560..32ff2c805 100644
--- a/cups/notify.c
+++ b/cups/notify.c
@@ -3,7 +3,7 @@
*
* Notification routines for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 2005-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -36,7 +36,7 @@
* @since CUPS 1.2@
*/
-char * /* O - Subject string or NULL */
+char * /* O - Subject string or @code NULL@ */
cupsNotifySubject(cups_lang_t *lang, /* I - Language data */
ipp_t *event) /* I - Event data */
{
@@ -162,12 +162,12 @@ cupsNotifySubject(cups_lang_t *lang, /* I - Language data */
/*
* 'cupsNotifyText()' - Return the text for the given notification message.
*
- * The returned string must be freed by the caller using free().
+ * The returned string must be freed by the caller using @code free@.
*
* @since CUPS 1.2@
*/
-char * /* O - Message text or NULL */
+char * /* O - Message text or @code NULL@ */
cupsNotifyText(cups_lang_t *lang, /* I - Language data */
ipp_t *event) /* I - Event data */
{
diff --git a/cups/options.c b/cups/options.c
index f04138497..4ffb39f82 100644
--- a/cups/options.c
+++ b/cups/options.c
@@ -1,5 +1,5 @@
/*
- * "$Id: options.c 6943 2007-09-10 23:00:33Z mike $"
+ * "$Id: options.c 7278 2008-01-31 01:23:09Z mike $"
*
* Option routines for the Common UNIX Printing System (CUPS).
*
@@ -16,14 +16,11 @@
*
* Contents:
*
- * cupsAddOption() - Add an option to an option array.
- * cupsFreeOptions() - Free all memory used by options.
- * cupsGetOption() - Get an option value.
- * cupsMarkOptions() - Mark command-line options in a PPD file.
- * cupsParseOptions() - Parse options from a command-line argument.
- * cupsRemoveOptions() - Remove an option from an option array.
- * debug_marked() - Output the marked array to stdout...
- * ppd_mark_choices() - Mark one or more option choices from a string.
+ * cupsAddOption() - Add an option to an option array.
+ * cupsFreeOptions() - Free all memory used by options.
+ * cupsGetOption() - Get an option value.
+ * cupsParseOptions() - Parse options from a command-line argument.
+ * cupsRemoveOption() - Remove an option from an option array.
*/
/*
@@ -38,25 +35,16 @@
/*
- * Local functions...
- */
-
-#ifdef DEBUG
-static void debug_marked(ppd_file_t *ppd, const char *title);
-#else
-# define debug_marked(ppd,title)
-#endif /* DEBUG */
-static int ppd_mark_choices(ppd_file_t *ppd, const char *options);
-
-
-/*
* 'cupsAddOption()' - Add an option to an option array.
+ *
+ * New option arrays can be initialized simply by passing 0 for the
+ * "num_options" parameter.
*/
-int /* O - Number of options */
-cupsAddOption(const char *name, /* I - Name of option */
- const char *value, /* I - Value of option */
- int num_options,/* I - Number of options */
+int /* O - Number of options */
+cupsAddOption(const char *name, /* I - Name of option */
+ const char *value, /* I - Value of option */
+ int num_options,/* I - Number of options */
cups_option_t **options) /* IO - Pointer to options */
{
int i; /* Looping var */
@@ -139,7 +127,7 @@ cupsFreeOptions(
* 'cupsGetOption()' - Get an option value.
*/
-const char * /* O - Option value or NULL */
+const char * /* O - Option value or @code NULL@ */
cupsGetOption(const char *name, /* I - Name of option */
int num_options,/* I - Number of options */
cups_option_t *options) /* I - Options */
@@ -159,306 +147,13 @@ cupsGetOption(const char *name, /* I - Name of option */
/*
- * 'cupsMarkOptions()' - Mark command-line options in a PPD file.
- */
-
-int /* O - 1 if conflicting */
-cupsMarkOptions(
- ppd_file_t *ppd, /* I - PPD file */
- int num_options, /* I - Number of options */
- cups_option_t *options) /* I - Options */
-{
- int i, j, k; /* Looping vars */
- int conflict; /* Option conflicts */
- char *val, /* Pointer into value */
- *ptr, /* Pointer into string */
- s[255]; /* Temporary string */
- const char *page_size; /* PageSize option */
- cups_option_t *optptr; /* Current option */
- ppd_option_t *option; /* PPD option */
- ppd_attr_t *attr; /* PPD attribute */
- static const char * const duplex_options[] =
- { /* Duplex option names */
- "Duplex", /* Adobe */
- "EFDuplex", /* EFI */
- "EFDuplexing", /* EFI */
- "KD03Duplex", /* Kodak */
- "JCLDuplex" /* Samsung */
- };
- static const char * const duplex_one[] =
- { /* one-sided names */
- "None",
- "False"
- };
- static const char * const duplex_two_long[] =
- { /* two-sided-long-edge names */
- "DuplexNoTumble", /* Adobe */
- "LongEdge", /* EFI */
- "Top" /* EFI */
- };
- static const char * const duplex_two_short[] =
- { /* two-sided-long-edge names */
- "DuplexTumble", /* Adobe */
- "ShortEdge", /* EFI */
- "Bottom" /* EFI */
- };
-
-
- /*
- * Check arguments...
- */
-
- if (ppd == NULL || num_options <= 0 || options == NULL)
- return (0);
-
- debug_marked(ppd, "Before...");
-
- /*
- * Mark options...
- */
-
- conflict = 0;
-
- for (i = num_options, optptr = options; i > 0; i --, optptr ++)
- if (!strcasecmp(optptr->name, "media"))
- {
- /*
- * Loop through the option string, separating it at commas and
- * marking each individual option as long as the corresponding
- * PPD option (PageSize, InputSlot, etc.) is not also set.
- *
- * For PageSize, we also check for an empty option value since
- * some versions of MacOS X use it to specify auto-selection
- * of the media based solely on the size.
- */
-
- page_size = cupsGetOption("PageSize", num_options, options);
-
- for (val = optptr->value; *val;)
- {
- /*
- * Extract the sub-option from the string...
- */
-
- for (ptr = s; *val && *val != ',' && (ptr - s) < (sizeof(s) - 1);)
- *ptr++ = *val++;
- *ptr++ = '\0';
-
- if (*val == ',')
- val ++;
-
- /*
- * Mark it...
- */
-
- if (!page_size || !page_size[0])
- if (ppdMarkOption(ppd, "PageSize", s))
- conflict = 1;
-
- if (cupsGetOption("InputSlot", num_options, options) == NULL)
- if (ppdMarkOption(ppd, "InputSlot", s))
- conflict = 1;
-
- if (cupsGetOption("MediaType", num_options, options) == NULL)
- if (ppdMarkOption(ppd, "MediaType", s))
- conflict = 1;
-
- if (cupsGetOption("EFMediaType", num_options, options) == NULL)
- if (ppdMarkOption(ppd, "EFMediaType", s)) /* EFI */
- conflict = 1;
-
- if (cupsGetOption("EFMediaQualityMode", num_options, options) == NULL)
- if (ppdMarkOption(ppd, "EFMediaQualityMode", s)) /* EFI */
- conflict = 1;
-
- if (strcasecmp(s, "manual") == 0 &&
- cupsGetOption("ManualFeed", num_options, options) == NULL)
- if (ppdMarkOption(ppd, "ManualFeed", "True"))
- conflict = 1;
- }
- }
- else if (!strcasecmp(optptr->name, "sides"))
- {
- for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
- if (cupsGetOption(duplex_options[j], num_options, options) != NULL)
- break;
-
- if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
- {
- /*
- * Don't override the PPD option with the IPP attribute...
- */
-
- continue;
- }
-
- if (!strcasecmp(optptr->value, "one-sided"))
- {
- /*
- * Mark the appropriate duplex option for one-sided output...
- */
-
- for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
- if ((option = ppdFindOption(ppd, duplex_options[j])) != NULL)
- break;
-
- if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
- {
- for (k = 0; k < (int)(sizeof(duplex_one) / sizeof(duplex_one[0])); k ++)
- if (ppdFindChoice(option, duplex_one[k]))
- {
- if (ppdMarkOption(ppd, duplex_options[j], duplex_one[k]))
- conflict = 1;
-
- break;
- }
- }
- }
- else if (!strcasecmp(optptr->value, "two-sided-long-edge"))
- {
- /*
- * Mark the appropriate duplex option for two-sided-long-edge output...
- */
-
- for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
- if ((option = ppdFindOption(ppd, duplex_options[j])) != NULL)
- break;
-
- if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
- {
- for (k = 0; k < (int)(sizeof(duplex_two_long) / sizeof(duplex_two_long[0])); k ++)
- if (ppdFindChoice(option, duplex_two_long[k]))
- {
- if (ppdMarkOption(ppd, duplex_options[j], duplex_two_long[k]))
- conflict = 1;
-
- break;
- }
- }
- }
- else if (!strcasecmp(optptr->value, "two-sided-short-edge"))
- {
- /*
- * Mark the appropriate duplex option for two-sided-short-edge output...
- */
-
- for (j = 0; j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])); j ++)
- if ((option = ppdFindOption(ppd, duplex_options[j])) != NULL)
- break;
-
- if (j < (int)(sizeof(duplex_options) / sizeof(duplex_options[0])))
- {
- for (k = 0; k < (int)(sizeof(duplex_two_short) / sizeof(duplex_two_short[0])); k ++)
- if (ppdFindChoice(option, duplex_two_short[k]))
- {
- if (ppdMarkOption(ppd, duplex_options[j], duplex_two_short[k]))
- conflict = 1;
-
- break;
- }
- }
- }
- }
- else if (!strcasecmp(optptr->name, "resolution") ||
- !strcasecmp(optptr->name, "printer-resolution"))
- {
- if (ppdMarkOption(ppd, "Resolution", optptr->value))
- conflict = 1;
- if (ppdMarkOption(ppd, "SetResolution", optptr->value))
- /* Calcomp, Linotype, QMS, Summagraphics, Tektronix, Varityper */
- conflict = 1;
- if (ppdMarkOption(ppd, "JCLResolution", optptr->value)) /* HP */
- conflict = 1;
- if (ppdMarkOption(ppd, "CNRes_PGP", optptr->value)) /* Canon */
- conflict = 1;
- }
- else if (!strcasecmp(optptr->name, "output-bin"))
- {
- if (!cupsGetOption("OutputBin", num_options, options))
- if (ppdMarkOption(ppd, "OutputBin", optptr->value))
- conflict = 1;
- }
- else if (!strcasecmp(optptr->name, "multiple-document-handling"))
- {
- if (!cupsGetOption("Collate", num_options, options) &&
- ppdFindOption(ppd, "Collate"))
- {
- if (strcasecmp(optptr->value, "separate-documents-uncollated-copies"))
- {
- if (ppdMarkOption(ppd, "Collate", "True"))
- conflict = 1;
- }
- else
- {
- if (ppdMarkOption(ppd, "Collate", "False"))
- conflict = 1;
- }
- }
- }
- else if (!strcasecmp(optptr->name, "finishings"))
- {
- /*
- * Lookup cupsIPPFinishings attributes for each value...
- */
-
- for (ptr = optptr->value; *ptr;)
- {
- /*
- * Get the next finishings number...
- */
-
- if (!isdigit(*ptr & 255))
- break;
-
- if ((j = strtol(ptr, &ptr, 10)) < 3)
- break;
-
- /*
- * Skip separator as needed...
- */
-
- if (*ptr == ',')
- ptr ++;
-
- /*
- * Look it up in the PPD file...
- */
-
- sprintf(s, "%d", j);
-
- if ((attr = ppdFindAttr(ppd, "cupsIPPFinishings", s)) == NULL)
- continue;
-
- /*
- * Apply "*Option Choice" settings from the attribute value...
- */
-
- if (ppd_mark_choices(ppd, attr->value))
- conflict = 1;
- }
- }
- else if (!strcasecmp(optptr->name, "mirror"))
- {
- if (ppdMarkOption(ppd, "MirrorPrint", optptr->value))
- conflict = 1;
- }
- else if (ppdMarkOption(ppd, optptr->name, optptr->value))
- conflict = 1;
-
- debug_marked(ppd, "After...");
-
- return (conflict);
-}
-
-
-/*
* 'cupsParseOptions()' - Parse options from a command-line argument.
*
* This function converts space-delimited name/value pairs according
* to the PAPI text option ABNF specification. Collection values
* ("name={a=... b=... c=...}") are stored with the curley brackets
- * intact - use cupsParseOptions() on the value to extract the collection
- * attributes.
+ * intact - use @code cupsParseOptions@ on the value to extract the
+ * collection attributes.
*/
int /* O - Number of options found */
@@ -470,7 +165,8 @@ cupsParseOptions(
char *copyarg, /* Copy of input string */
*ptr, /* Pointer into string */
*name, /* Pointer to name */
- *value; /* Pointer to value */
+ *value, /* Pointer to value */
+ quote; /* Quote character */
/*
@@ -510,7 +206,7 @@ cupsParseOptions(
*/
name = ptr;
- while (!isspace(*ptr & 255) && *ptr != '=' && *ptr != '\0')
+ while (!isspace(*ptr & 255) && *ptr != '=' && *ptr)
ptr ++;
/*
@@ -530,10 +226,10 @@ cupsParseOptions(
if (*ptr != '=')
{
/*
- * Start of another option...
+ * Boolean option...
*/
- if (strncasecmp(name, "no", 2) == 0)
+ if (!strncasecmp(name, "no", 2))
num_options = cupsAddOption(name + 2, "false", num_options,
options);
else
@@ -548,38 +244,18 @@ cupsParseOptions(
*ptr++ = '\0';
- if (*ptr == '\'')
+ if (*ptr == '\'' || *ptr == '\"')
{
/*
* Quoted string constant...
*/
- ptr ++;
- value = ptr;
-
- while (*ptr != '\'' && *ptr != '\0')
- {
- if (*ptr == '\\')
- _cups_strcpy(ptr, ptr + 1);
-
- ptr ++;
- }
-
- if (*ptr != '\0')
- *ptr++ = '\0';
- }
- else if (*ptr == '\"')
- {
- /*
- * Double-quoted string constant...
- */
-
- ptr ++;
+ quote = *ptr++;
value = ptr;
- while (*ptr != '\"' && *ptr != '\0')
+ while (*ptr != quote && *ptr)
{
- if (*ptr == '\\')
+ if (*ptr == '\\' && ptr[1])
_cups_strcpy(ptr, ptr + 1);
ptr ++;
@@ -612,7 +288,7 @@ cupsParseOptions(
break;
}
}
- else if (*ptr == '\\')
+ else if (*ptr == '\\' && ptr[1])
_cups_strcpy(ptr, ptr + 1);
if (*ptr != '\0')
@@ -626,9 +302,9 @@ cupsParseOptions(
value = ptr;
- while (!isspace(*ptr & 255) && *ptr != '\0')
+ while (!isspace(*ptr & 255) && *ptr)
{
- if (*ptr == '\\')
+ if (*ptr == '\\' && ptr[1])
_cups_strcpy(ptr, ptr + 1);
ptr ++;
@@ -715,110 +391,6 @@ cupsRemoveOption(
}
-#ifdef DEBUG
-/*
- * 'debug_marked()' - Output the marked array to stdout...
- */
-
-static void
-debug_marked(ppd_file_t *ppd, /* I - PPD file data */
- const char *title) /* I - Title for list */
-{
- ppd_choice_t *c; /* Current choice */
-
-
- printf("cupsMarkOptions: %s\n", title);
-
- for (c = (ppd_choice_t *)cupsArrayFirst(ppd->marked);
- c;
- c = (ppd_choice_t *)cupsArrayNext(ppd->marked))
- printf("cupsMarkOptions: %s=%s\n", c->option->keyword, c->choice);
-}
-#endif /* DEBUG */
-
-
-/*
- * 'ppd_mark_choices()' - Mark one or more option choices from a string.
- */
-
-static int /* O - 1 if there are conflicts, 0 otherwise */
-ppd_mark_choices(ppd_file_t *ppd, /* I - PPD file */
- const char *options) /* I - "*Option Choice ..." string */
-{
- char option[PPD_MAX_NAME], /* Current option */
- choice[PPD_MAX_NAME], /* Current choice */
- *ptr; /* Pointer into option or choice */
- int conflict = 0; /* Do we have a conflict? */
-
-
- if (!options)
- return (0);
-
- /*
- * Read all of the "*Option Choice" pairs from the string, marking PPD
- * options as we go...
- */
-
- while (*options)
- {
- /*
- * Skip leading whitespace...
- */
-
- while (isspace(*options & 255))
- options ++;
-
- if (*options != '*')
- break;
-
- /*
- * Get the option name...
- */
-
- options ++;
- ptr = option;
- while (*options && !isspace(*options & 255) &&
- ptr < (option + sizeof(option) - 1))
- *ptr++ = *options++;
-
- if (ptr == option)
- break;
-
- *ptr = '\0';
-
- /*
- * Get the choice...
- */
-
- while (isspace(*options & 255))
- options ++;
-
- if (!*options)
- break;
-
- ptr = choice;
- while (*options && !isspace(*options & 255) &&
- ptr < (choice + sizeof(choice) - 1))
- *ptr++ = *options++;
-
- *ptr = '\0';
-
- /*
- * Mark the option...
- */
-
- if (ppdMarkOption(ppd, option, choice))
- conflict = 1;
- }
-
- /*
- * Return whether we had any conflicts...
- */
-
- return (conflict);
-}
-
-
/*
- * End of "$Id: options.c 6943 2007-09-10 23:00:33Z mike $".
+ * End of "$Id: options.c 7278 2008-01-31 01:23:09Z mike $".
*/
diff --git a/cups/ppd.c b/cups/ppd.c
index ea9eb86b7..a70a0cfeb 100644
--- a/cups/ppd.c
+++ b/cups/ppd.c
@@ -428,7 +428,7 @@ ppdOpen(FILE *fp) /* I - File to read from */
* @since CUPS 1.2@
*/
-ppd_file_t * /* O - PPD file record */
+ppd_file_t * /* O - PPD file record or @code NULL@ if the PPD file could not be opened. */
ppdOpen2(cups_file_t *fp) /* I - File to read from */
{
int i, j, k; /* Looping vars */
@@ -2020,7 +2020,7 @@ ppdOpen2(cups_file_t *fp) /* I - File to read from */
* 'ppdOpenFd()' - Read a PPD file into memory.
*/
-ppd_file_t * /* O - PPD file record */
+ppd_file_t * /* O - PPD file record or @code NULL@ if the PPD file could not be opened. */
ppdOpenFd(int fd) /* I - File to read from */
{
cups_file_t *fp; /* CUPS file pointer */
@@ -2070,7 +2070,7 @@ ppdOpenFd(int fd) /* I - File to read from */
* 'ppdOpenFile()' - Read a PPD file into memory.
*/
-ppd_file_t * /* O - PPD file record */
+ppd_file_t * /* O - PPD file record or @code NULL@ if the PPD file could not be opened. */
ppdOpenFile(const char *filename) /* I - File to read from */
{
cups_file_t *fp; /* File pointer */
diff --git a/cups/ppd.h b/cups/ppd.h
index f154c6ba3..c99981793 100644
--- a/cups/ppd.h
+++ b/cups/ppd.h
@@ -4,7 +4,7 @@
* PostScript Printer Description definitions for the Common UNIX Printing
* System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -118,11 +118,14 @@ typedef enum ppd_status_e /**** Status Codes @since CUPS 1.1.19@ ****/
PPD_BAD_CUSTOM_PARAM /* Bad custom parameter */
} ppd_status_t;
-typedef enum ppd_conform_e /**** Conformance Levels @since CUPS 1.1.19@ ****/
+enum ppd_conform_e /**** Conformance Levels @since CUPS 1.1.19@ ****/
{
PPD_CONFORM_RELAXED, /* Relax whitespace and control char */
PPD_CONFORM_STRICT /* Require strict conformance */
-} ppd_conform_t;
+};
+
+typedef enum ppd_conform_e ppd_conform_t;
+ /**** Conformance Levels @since CUPS 1.1.19@ ****/
typedef struct ppd_attr_s /**** PPD Attribute Structure @since CUPS 1.1.19@ ****/
{
@@ -172,7 +175,7 @@ typedef struct ppd_group_s /**** Groups ****/
struct ppd_group_s *subgroups; /* Sub-groups (max depth = 1) */
} ppd_group_t;
-typedef struct /**** Constraints ****/
+typedef struct ppd_const_s /**** Constraints ****/
{
char option1[PPD_MAX_NAME]; /* First keyword */
char choice1[PPD_MAX_NAME]; /* First option/choice (blank for all) */
@@ -392,7 +395,12 @@ extern ppd_file_t *ppdOpen2(cups_file_t *fp) _CUPS_API_1_2;
extern const char *ppdLocalizeIPPReason(ppd_file_t *ppd,
const char *reason,
const char *scheme,
- char *buffer, size_t bufsize) _CUPS_API_1_3;
+ char *buffer,
+ size_t bufsize) _CUPS_API_1_3;
+
+/**** New in CUPS 1.4 ****/
+extern const char *ppdLocalizeMarkerName(ppd_file_t *ppd,
+ const char *name) _CUPS_API_1_4;
/*
diff --git a/cups/sidechannel.h b/cups/sidechannel.h
index bfe3cc0d6..e2eae6eb7 100644
--- a/cups/sidechannel.h
+++ b/cups/sidechannel.h
@@ -3,7 +3,7 @@
*
* Side-channel API definitions for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -45,22 +45,26 @@ extern "C" {
* Enumerations...
*/
-typedef enum /**** Bidirectional capabilities ****/
+enum cups_sc_bidi_e /**** Bidirectional capabilities ****/
{
CUPS_SC_BIDI_NOT_SUPPORTED = 0, /* Bidirectional I/O is not supported */
CUPS_SC_BIDI_SUPPORTED = 1 /* Bidirectional I/O is supported */
-} cups_sc_bidi_t;
+};
+typedef enum cups_sc_bidi_e cups_sc_bidi_t;
+ /**** Bidirectional capabilities ****/
-typedef enum /**** Request command codes ****/
+enum cups_sc_command_e /**** Request command codes ****/
{
CUPS_SC_CMD_SOFT_RESET = 1, /* Do a soft reset */
CUPS_SC_CMD_DRAIN_OUTPUT = 2, /* Drain all pending output */
CUPS_SC_CMD_GET_BIDI = 3, /* Return bidirectional capabilities */
CUPS_SC_CMD_GET_DEVICE_ID = 4, /* Return the IEEE-1284 device ID */
CUPS_SC_CMD_GET_STATE = 5 /* Return the device state */
-} cups_sc_command_t;
+};
+typedef enum cups_sc_command_e cups_sc_command_t;
+ /**** Request command codes ****/
-typedef enum /**** Printer state bits ****/
+enum cups_sc_state_e /**** Printer state bits ****/
{
CUPS_SC_STATE_OFFLINE = 0, /* Device is off-line */
CUPS_SC_STATE_ONLINE = 1, /* Device is on-line */
@@ -70,9 +74,11 @@ typedef enum /**** Printer state bits ****/
CUPS_SC_STATE_MEDIA_EMPTY = 32, /* Paper out condition */
CUPS_SC_STATE_MARKER_LOW = 64, /* Toner/ink low condition */
CUPS_SC_STATE_MARKER_EMPTY = 128 /* Toner/ink out condition */
-} cups_sc_state_t;
+};
+typedef enum cups_sc_state_e cups_sc_state_t;
+ /**** Printer state bits ****/
-typedef enum /**** Response status codes ****/
+enum cups_sc_status_e /**** Response status codes ****/
{
CUPS_SC_STATUS_NONE, /* No status */
CUPS_SC_STATUS_OK, /* Operation succeeded */
@@ -82,7 +88,9 @@ typedef enum /**** Response status codes ****/
CUPS_SC_STATUS_BAD_MESSAGE, /* The command/response message was invalid */
CUPS_SC_STATUS_TOO_BIG, /* Response too big */
CUPS_SC_STATUS_NOT_IMPLEMENTED /* Command not implemented */
-} cups_sc_status_t;
+};
+typedef enum cups_sc_status_e cups_sc_status_t;
+ /**** Response status codes ****/
/*
diff --git a/cups/tempfile.c b/cups/tempfile.c
index 5d5bd5206..30cbc0cae 100644
--- a/cups/tempfile.c
+++ b/cups/tempfile.c
@@ -3,7 +3,7 @@
*
* Temp file utilities for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -155,8 +155,8 @@ cupsTempFd(char *filename, /* I - Pointer to buffer */
* 'cupsTempFile()' - Generates a temporary filename.
*
* The temporary filename is returned in the filename buffer.
- * This function is deprecated - use cupsTempFd() or cupsTempFile2()
- * instead.
+ * This function is deprecated - use @link cupsTempFd@ or
+ * @link cupsTempFile2@ instead.
*
* @deprecated@
*/
diff --git a/cups/test.ppd b/cups/test.ppd
index 05d36c010..35682234a 100644
--- a/cups/test.ppd
+++ b/cups/test.ppd
@@ -139,7 +139,7 @@
*CloseGroup: Extended
-*% IPP reasons (for ppdLocalizeIPPReason tests)
+*% IPP reasons for ppdLocalizeIPPReason tests
*cupsIPPReason foo/Foo Reason: "http://foo/bar.html
help:anchor='foo'%20bookID=Vendor%20Help
/help/foo/bar.html"
@@ -163,6 +163,12 @@ help:anchor='foo'%20bookID=Vendor%20Help
/help/zh/foo/bar.html"
*End
+*% Marker names for ppdLocalizeMarkerName tests
+*cupsMarkerName cyan/Cyan Toner: ""
+*fr.cupsMarkerName cyan/La Toner Cyan: ""
+*zh_TW.cupsMarkerName cyan/Number 1 Cyan Toner: ""
+*zh.cupsMarkerName cyan/Number 2 Cyan Toner: ""
+
*DefaultFont: Courier
*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
diff --git a/cups/testppd.c b/cups/testppd.c
index e88a12568..9efa851f5 100644
--- a/cups/testppd.c
+++ b/cups/testppd.c
@@ -99,6 +99,7 @@ main(int argc, /* I - Number of command-line arguments */
int conflicts; /* Number of conflicts */
char *s; /* String */
char buffer[8192]; /* String buffer */
+ const char *text; /* Localized text */
status = 0;
@@ -235,6 +236,60 @@ main(int argc, /* I - Number of command-line arguments */
status ++;
printf("FAIL (\"%s\" instead of \"Number 1 Foo Reason\")\n", buffer);
}
+
+ /*
+ * cupsMarkerName localization...
+ */
+
+ putenv("LANG=en");
+
+ fputs("ppdLocalizeMarkerName(bogus): ", stdout);
+
+ if ((text = ppdLocalizeMarkerName(ppd, "bogus")) != NULL)
+ {
+ status ++;
+ printf("FAIL (\"%s\" instead of NULL)\n", text);
+ }
+ else
+ puts("PASS");
+
+ fputs("ppdLocalizeMarkerName(cyan): ", stdout);
+
+ if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
+ !strcmp(text, "Cyan Toner"))
+ puts("PASS");
+ else
+ {
+ status ++;
+ printf("FAIL (\"%s\" instead of \"Cyan Toner\")\n",
+ text ? text : "(null)");
+ }
+
+ putenv("LANG=fr");
+
+ fputs("ppdLocalizeMarkerName(fr cyan): ", stdout);
+ if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
+ !strcmp(text, "La Toner Cyan"))
+ puts("PASS");
+ else
+ {
+ status ++;
+ printf("FAIL (\"%s\" instead of \"La Toner Cyan\")\n",
+ text ? text : "(null)");
+ }
+
+ putenv("LANG=zh_TW");
+
+ fputs("ppdLocalizeMarkerName(zh_TW cyan): ", stdout);
+ if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
+ !strcmp(text, "Number 1 Cyan Toner"))
+ puts("PASS");
+ else
+ {
+ status ++;
+ printf("FAIL (\"%s\" instead of \"Number 1 Cyan Toner\")\n",
+ text ? text : "(null)");
+ }
}
else
{
diff --git a/cups/usersys.c b/cups/usersys.c
index 64d71d22a..c8d2b2864 100644
--- a/cups/usersys.c
+++ b/cups/usersys.c
@@ -4,7 +4,7 @@
* User, system, and password routines for the Common UNIX Printing
* System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -56,7 +56,7 @@ static cups_file_t *cups_open_client_conf(void);
* The default encryption setting comes from the CUPS_ENCRYPTION
* environment variable, then the ~/.cupsrc file, and finally the
* /etc/cups/client.conf file. If not set, the default is
- * HTTP_ENCRYPT_IF_REQUESTED.
+ * @code HTTP_ENCRYPT_IF_REQUESTED@.
*/
http_encryption_t /* O - Encryption settings */
@@ -133,7 +133,7 @@ cupsEncryption(void)
/*
* 'cupsGetPassword()' - Get a password from the user.
*
- * Uses the current password callback function. Returns NULL if the
+ * Uses the current password callback function. Returns @code NULL@ if the
* user does not provide a password.
*/
@@ -151,7 +151,13 @@ cupsGetPassword(const char *prompt) /* I - Prompt string */
void
cupsSetEncryption(http_encryption_t e) /* I - New encryption preference */
{
- _cupsGlobals()->encryption = e;
+ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
+
+
+ cg->encryption = e;
+
+ if (cg->http)
+ httpEncryption(cg->http, e);
}
@@ -266,7 +272,7 @@ cupsServer(void)
/*
* 'cupsSetPasswordCB()' - Set the password callback for CUPS.
*
- * Pass NULL to restore the default (console) password callback.
+ * Pass @code NULL@ to restore the default (console) password callback.
*/
void
@@ -286,7 +292,7 @@ cupsSetPasswordCB(cups_password_cb_t cb)/* I - Callback function */
* 'cupsSetServer()' - Set the default server name.
*
* The "server" string can be a fully-qualified hostname, a numeric
- * IPv4 or IPv6 address, or a domain socket pathname. Pass NULL to
+ * IPv4 or IPv6 address, or a domain socket pathname. Pass @code NULL@ to
* restore the default server name.
*/
@@ -319,13 +325,19 @@ cupsSetServer(const char *server) /* I - Server name */
cg->server[0] = '\0';
cg->servername[0] = '\0';
}
+
+ if (cg->http)
+ {
+ httpClose(cg->http);
+ cg->http = NULL;
+ }
}
/*
* 'cupsSetUser()' - Set the default user name.
*
- * Pass NULL to restore the default user name.
+ * Pass @code NULL@ to restore the default user name.
*/
void
diff --git a/cups/util.c b/cups/util.c
index 6dea98085..eade62f08 100644
--- a/cups/util.c
+++ b/cups/util.c
@@ -84,7 +84,10 @@ static int cups_get_printer_uri(http_t *http, const char *name,
/*
* 'cupsCancelJob()' - Cancel a print job on the default server.
*
- * Use the cupsLastError() and cupsLastErrorString() functions to get
+ * Pass @code CUPS_JOBID_ALL@ to cancel all jobs or @code CUPS_JOBID_CURRENT@
+ * to cancel the current job on the named destination.
+ *
+ * Use the @link cupsLastError@ and @link cupsLastErrorString@ functions to get
* the cause of any failure.
*/
@@ -92,7 +95,7 @@ int /* O - 1 on success, 0 on failure */
cupsCancelJob(const char *name, /* I - Name of printer or class */
int job_id) /* I - Job ID */
{
- return (cupsCancelJob2(CUPS_HTTP_DEFAULT, job_id, 0)
+ return (cupsCancelJob2(CUPS_HTTP_DEFAULT, name, job_id, 0)
< IPP_REDIRECTION_OTHER_SITE);
}
@@ -103,18 +106,22 @@ cupsCancelJob(const char *name, /* I - Name of printer or class */
* Canceled jobs remain in the job history while purged jobs are removed
* from the job history.
*
- * Use the cupsLastError() and cupsLastErrorString() functions to get
+ * Pass @code CUPS_JOBID_ALL@ to cancel all jobs or @code CUPS_JOBID_CURRENT@
+ * to cancel the current job on the named destination.
+ *
+ * Use the @link cupsLastError@ and @link cupsLastErrorString@ functions to get
* the cause of any failure.
*
* @since CUPS 1.4@
*/
ipp_status_t /* O - IPP status */
-cupsCancelJob2(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
- int job_id, /* I - Job ID */
- int purge) /* I - 1 to purge, 0 to cancel */
+cupsCancelJob2(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
+ const char *name, /* I - Name of printer or class */
+ int job_id, /* I - Job ID or 0 for the current job, -1 for all jobs */
+ int purge) /* I - 1 to purge, 0 to cancel */
{
- char uri[HTTP_MAX_URI]; /* Job URI */
+ char uri[HTTP_MAX_URI]; /* Job/printer URI */
ipp_t *request; /* IPP request */
@@ -122,7 +129,7 @@ cupsCancelJob2(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
* Range check input...
*/
- if (job_id <= 0)
+ if (job_id < -1 || (!name && job_id == 0))
{
_cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL));
return (0);
@@ -137,25 +144,42 @@ cupsCancelJob2(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
return (IPP_SERVICE_UNAVAILABLE);
/*
- * Build an IPP_CANCEL_JOB request, which requires the following
+ * Build an IPP_CANCEL_JOB or IPP_PURGE_JOBS request, which requires the following
* attributes:
*
* attributes-charset
* attributes-natural-language
- * job-uri
+ * job-uri or printer-uri + job-id
* requesting-user-name
- * [purge-job]
+ * [purge-job] or [purge-jobs]
*/
- request = ippNewRequest(IPP_CANCEL_JOB);
+ request = ippNewRequest(job_id < 0 ? IPP_PURGE_JOBS : IPP_CANCEL_JOB);
- snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id);
+ if (name)
+ {
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", ippPort(), "/printers/%s", name);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
+ uri);
+ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id",
+ job_id);
+ }
+ else if (job_id > 0)
+ {
+ snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
+ }
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
NULL, cupsUser());
- if (purge)
+
+ if (purge && job_id >= 0)
ippAddBoolean(request, IPP_TAG_OPERATION, "purge-job", 1);
+ else if (!purge && job_id < 0)
+ ippAddBoolean(request, IPP_TAG_OPERATION, "purge-jobs", 0);
/*
* Do the request...
@@ -170,15 +194,15 @@ cupsCancelJob2(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
/*
* 'cupsCreateJob()' - Create an empty job.
*
- * Submit files for printing to the job using the cupsStartDocument(),
- * cupsWriteRequestData(), and cupsFinishDocument() functions.
+ * Submit files for printing to the job using the @link cupsStartDocument@,
+ * @link cupsWriteRequestData@, and @link cupsFinishDocument@ functions.
*
* @since CUPS 1.4@
*/
int /* O - Job ID or 0 on error */
cupsCreateJob(
- http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+ http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
const char *name, /* I - Printer or class name */
const char *title, /* I - Title of job */
int num_options, /* I - Number of options */
@@ -251,11 +275,13 @@ cupsCreateJob(
/*
* 'cupsFinishDocument()' - Finish sending a document.
*
+ * The document must have been started using @link cupsStartDocument@.
+ *
* @since CUPS 1.4@
*/
ipp_status_t /* O - Status of document submission */
-cupsFinishDocument(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+cupsFinishDocument(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
const char *name) /* I - Printer or class name */
{
char resource[1024]; /* Printer resource */
@@ -299,7 +325,7 @@ cupsFreeJobs(int num_jobs, /* I - Number of jobs */
/*
* 'cupsGetClasses()' - Get a list of printer classes from the default server.
*
- * This function is deprecated - use cupsGetDests() instead.
+ * This function is deprecated - use @link cupsGetDests@ instead.
*
* @deprecated@
*/
@@ -394,12 +420,12 @@ cupsGetClasses(char ***classes) /* O - Classes */
* This function returns the default printer or class as defined by
* the LPDEST or PRINTER environment variables. If these environment
* variables are not set, the server default destination is returned.
- * Applications should use the cupsGetDests() and cupsGetDest() functions
- * to get the user-defined default printer, as this function does not
- * support the lpoptions-defined default printer.
+ * Applications should use the @link cupsGetDests@ and @link cupsGetDest@
+ * functions to get the user-defined default printer, as this function does
+ * not support the lpoptions-defined default printer.
*/
-const char * /* O - Default printer or NULL */
+const char * /* O - Default printer or @code NULL@ */
cupsGetDefault(void)
{
/*
@@ -416,15 +442,15 @@ cupsGetDefault(void)
* This function returns the default printer or class as defined by
* the LPDEST or PRINTER environment variables. If these environment
* variables are not set, the server default destination is returned.
- * Applications should use the cupsGetDests() and cupsGetDest() functions
- * to get the user-defined default printer, as this function does not
- * support the lpoptions-defined default printer.
+ * Applications should use the @link cupsGetDests@ and @link cupsGetDest@
+ * functions to get the user-defined default printer, as this function does
+ * not support the lpoptions-defined default printer.
*
* @since CUPS 1.1.21@
*/
-const char * /* O - Default printer or NULL */
-cupsGetDefault2(http_t *http) /* I - HTTP connection */
+const char * /* O - Default printer or @code NULL@ */
+cupsGetDefault2(http_t *http) /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
{
ipp_t *request, /* IPP Request */
*response; /* IPP Response */
@@ -487,21 +513,24 @@ cupsGetDefault2(http_t *http) /* I - HTTP connection */
/*
* 'cupsGetJobs()' - Get the jobs from the default server.
+ *
+ * A "whichjobs" value of @code CUPS_WHICHJOBS_ALL@ returns all jobs regardless
+ * of state, while @code CUPS_WHICHJOBS_ACTIVE@ returns jobs that are
+ * pending, processing, or held and @code CUPS_WHICHJOBS_COMPLETED@ returns
+ * jobs that are stopped, canceled, aborted, or completed.
*/
int /* O - Number of jobs */
cupsGetJobs(cups_job_t **jobs, /* O - Job data */
- const char *mydest, /* I - NULL = all destinations, *
- * otherwise show jobs for mydest */
+ const char *name, /* I - @code NULL@ = all destinations, otherwise show jobs for mydest */
int myjobs, /* I - 0 = all users, 1 = mine */
- int completed) /* I - -1 = show all, 0 = active, *
- * 1 = completed jobs */
+ int whichjobs) /* I - @code CUPS_WHICHJOBS_ALL@, @code CUPS_WHICHJOBS_ACTIVE@, or @code CUPS_WHICHJOBS_COMPLETED@ */
{
/*
* Return the jobs...
*/
- return (cupsGetJobs2(CUPS_HTTP_DEFAULT, jobs, mydest, myjobs, completed));
+ return (cupsGetJobs2(CUPS_HTTP_DEFAULT, jobs, name, myjobs, whichjobs));
}
@@ -509,17 +538,20 @@ cupsGetJobs(cups_job_t **jobs, /* O - Job data */
/*
* 'cupsGetJobs2()' - Get the jobs from the specified server.
*
+ * A "whichjobs" value of @code CUPS_WHICHJOBS_ALL@ returns all jobs regardless
+ * of state, while @code CUPS_WHICHJOBS_ACTIVE@ returns jobs that are
+ * pending, processing, or held and @code CUPS_WHICHJOBS_COMPLETED@ returns
+ * jobs that are stopped, canceled, aborted, or completed.
+ *
* @since CUPS 1.1.21@
*/
int /* O - Number of jobs */
-cupsGetJobs2(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+cupsGetJobs2(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
cups_job_t **jobs, /* O - Job data */
- const char *mydest, /* I - NULL = all destinations, *
- * otherwise show jobs for mydest */
+ const char *name, /* I - @code NULL@ = all destinations, otherwise show jobs for mydest */
int myjobs, /* I - 0 = all users, 1 = mine */
- int completed) /* I - -1 = show all, 0 = active, *
- * 1 = completed jobs */
+ int whichjobs) /* I - @code CUPS_WHICHJOBS_ALL@, @code CUPS_WHICHJOBS_ACTIVE@, or @code CUPS_WHICHJOBS_COMPLETED@ */
{
int n; /* Number of jobs */
ipp_t *request, /* IPP Request */
@@ -570,10 +602,10 @@ cupsGetJobs2(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
* Get the right URI...
*/
- if (mydest)
+ if (name)
{
if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
- "localhost", 0, "/printers/%s", mydest) != HTTP_URI_OK)
+ "localhost", 0, "/printers/%s", name) != HTTP_URI_OK)
{
_cupsSetError(IPP_INTERNAL_ERROR, NULL);
@@ -611,10 +643,10 @@ cupsGetJobs2(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
if (myjobs)
ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1);
- if (completed > 0)
+ if (whichjobs == CUPS_WHICHJOBS_COMPLETED)
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
"which-jobs", NULL, "completed");
- else if (completed < 0)
+ else if (whichjobs == CUPS_WHICHJOBS_ALL)
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
"which-jobs", NULL, "all");
@@ -776,7 +808,7 @@ cupsGetJobs2(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
/*
* 'cupsGetPPD()' - Get the PPD file for a printer on the default server.
*
- * For classes, cupsGetPPD() returns the PPD file for the first printer
+ * For classes, @code cupsGetPPD@ returns the PPD file for the first printer
* in the class.
*/
@@ -804,14 +836,14 @@ cupsGetPPD(const char *name) /* I - Printer name */
/*
* 'cupsGetPPD2()' - Get the PPD file for a printer from the specified server.
*
- * For classes, cupsGetPPD2() returns the PPD file for the first printer
+ * For classes, @code cupsGetPPD2@ returns the PPD file for the first printer
* in the class.
*
* @since CUPS 1.1.21@
*/
const char * /* O - Filename for PPD file */
-cupsGetPPD2(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+cupsGetPPD2(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
const char *name) /* I - Printer name */
{
_cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
@@ -840,12 +872,16 @@ cupsGetPPD2(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
* the empty string, a new temporary file is created, otherwise the existing
* file will be overwritten as needed.
*
- * On success, HTTP_OK is returned for a new PPD file and HTTP_NOT_MODIFIED
- * if the existing PPD file is up-to-date. Any other status is an error.
+ * On success, @code HTTP_OK@ is returned for a new PPD file and
+ * @code HTTP_NOT_MODIFIED@ if the existing PPD file is up-to-date. Any other
+ * status is an error.
+ *
+ * For classes, @code cupsGetPPD3@ returns the PPD file for the first printer
+ * in the class.
*/
http_status_t /* O - HTTP status */
-cupsGetPPD3(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+cupsGetPPD3(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
const char *name, /* I - Printer name */
time_t *modtime, /* IO - Modification time */
char *buffer, /* I - Filename buffer */
@@ -1026,7 +1062,7 @@ cupsGetPPD3(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
/*
* 'cupsGetPrinters()' - Get a list of printers from the default server.
*
- * This function is deprecated - use cupsGetDests() instead.
+ * This function is deprecated - use @link cupsGetDests@ instead.
*
* @deprecated@
*/
@@ -1133,19 +1169,19 @@ cupsGetPrinters(char ***printers) /* O - Printers */
* 'cupsGetServerPPD()' - Get an available PPD file from the server.
*
* This function returns the named PPD file from the server. The
- * list of available PPDs is provided by the IPP CUPS_GET_PPDS
+ * list of available PPDs is provided by the IPP @code CUPS_GET_PPDS@
* operation.
*
* You must remove (unlink) the PPD file when you are finished with
* it. The PPD filename is stored in a static location that will be
- * overwritten on the next call to cupsGetPPD(), cupsGetPPD2(), or
- * cupsGetServerPPD().
+ * overwritten on the next call to @link cupsGetPPD@, @link cupsGetPPD2@,
+ * or @link cupsGetServerPPD@.
*
* @since CUPS 1.3@
*/
-char * /* O - Name of PPD file or NULL on error */
-cupsGetServerPPD(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+char * /* O - Name of PPD file or @code NULL@ on error */
+cupsGetServerPPD(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
const char *name) /* I - Name of PPD file ("ppd-name") */
{
int fd; /* PPD file descriptor */
@@ -1234,7 +1270,7 @@ cupsLastErrorString(void)
* 'cupsPrintFile()' - Print a file to a printer or class on the default server.
*/
-int /* O - Job ID */
+int /* O - Job ID or 0 on error */
cupsPrintFile(const char *name, /* I - Printer or class name */
const char *filename, /* I - File to print */
const char *title, /* I - Title of job */
@@ -1251,12 +1287,13 @@ cupsPrintFile(const char *name, /* I - Printer or class name */
/*
- * 'cupsPrintFile2()' - Print a file to a printer or class on the specified server.
+ * 'cupsPrintFile2()' - Print a file to a printer or class on the specified
+ * server.
*
* @since CUPS 1.1.21@
*/
-int /* O - Job ID */
+int /* O - Job ID or 0 on error */
cupsPrintFile2(
http_t *http, /* I - HTTP connection */
const char *name, /* I - Printer or class name */
@@ -1279,7 +1316,7 @@ cupsPrintFile2(
* default server.
*/
-int /* O - Job ID */
+int /* O - Job ID or 0 on error */
cupsPrintFiles(
const char *name, /* I - Printer or class name */
int num_files, /* I - Number of files */
@@ -1309,9 +1346,9 @@ cupsPrintFiles(
* @since CUPS 1.1.21@
*/
-int /* O - Job ID */
+int /* O - Job ID or 0 on error */
cupsPrintFiles2(
- http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+ http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
const char *name, /* I - Printer or class name */
int num_files, /* I - Number of files */
const char **files, /* I - File(s) to print */
@@ -1378,7 +1415,7 @@ cupsPrintFiles2(
* Unable to open print file, cancel the job and return...
*/
- cupsCancelJob2(http, job_id, 0);
+ cupsCancelJob2(http, name, job_id, 0);
return (0);
}
@@ -1397,7 +1434,7 @@ cupsPrintFiles2(
* Unable to queue, cancel the job and return...
*/
- cupsCancelJob2(http, job_id, 0);
+ cupsCancelJob2(http, name, job_id, 0);
return (0);
}
}
@@ -1409,24 +1446,24 @@ cupsPrintFiles2(
/*
* 'cupsStartDocument()' - Add a document to a job created with cupsCreateJob().
*
- * Use cupsWriteRequestData() to write data for the document and
- * cupsFinishDocument() to finish the document and get the submission status.
+ * Use @link cupsWriteRequestData@ to write data for the document and
+ * @link cupsFinishDocument@ to finish the document and get the submission status.
*
- * The MIME type constants CUPS_FORMAT_AUTO, CUPS_FORMAT_PDF,
- * CUPS_FORMAT_POSTSCRIPT, CUPS_FORMAT_RAW, and CUPS_FORMAT_TEXT are provided
- * for the "format" argument, although any supported MIME type string can be
- * supplied.
+ * The MIME type constants @code CUPS_FORMAT_AUTO@, @code CUPS_FORMAT_PDF@,
+ * @code CUPS_FORMAT_POSTSCRIPT@, @code CUPS_FORMAT_RAW@, and
+ * @code CUPS_FORMAT_TEXT@ are provided for the "format" argument, although
+ * any supported MIME type string can be supplied.
*
* @since CUPS 1.4@
*/
http_status_t /* O - HTTP status of request */
cupsStartDocument(
- http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+ http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */
const char *name, /* I - Printer or class name */
- int job_id, /* I - Job ID from cupsCreateJob() */
+ int job_id, /* I - Job ID from @link cupsCreateJob@ */
const char *docname, /* I - Name of document */
- const char *format, /* I - MIME type or CUPS_FORMAT_foo */
+ const char *format, /* I - MIME type or @code CUPS_FORMAT_foo@ */
int last_document) /* I - 1 for last document in job, 0 otherwise */
{
char resource[1024], /* Resource for destinatio */