]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/api-filter.shtml
Update all references to OS X to macOS.
[thirdparty/cups.git] / cups / api-filter.shtml
index e95c8d08f12bc2f66da5fb30a930c3e8c644f8a2..1b8f6f3cfbfbb909bd086f1af4d6184620eeb0d4 100644 (file)
@@ -1,9 +1,7 @@
 <!--
-  "$Id: api-filter.shtml 7677 2008-06-19 23:22:19Z mike $"
-
   Filter and backend programming introduction for CUPS.
 
-  Copyright 2007-2012 by Apple Inc.
+  Copyright 2007-2016 by Apple Inc.
   Copyright 1997-2006 by Easy Software Products, all rights reserved.
 
   These coded instructions, statements, and computer programs are the
@@ -81,7 +79,7 @@ directory to write to.</p>
 
 <p>In addition, some operating systems provide additional security mechanisms
 that further limit file system access, even for backends running as root. On
-OS X, for example, no backend may write to a user's home directory.</p>
+macOS, for example, no backend may write to a user's home directory. See the <a href="#SANDBOXING">Sandboxing on macOS</a> section for more information.</p>
 </blockquote>
 
 <h3><a name="SIGNALS">Canceled Jobs and Signal Handling</a></h3>
@@ -153,7 +151,7 @@ when running print filters and backends:</p>
 
        <dt>APPLE_LANGUAGE</dt>
        <dd>The Apple language identifier associated with the job
-       (OS X only).</dd>
+       (macOS only).</dd>
 
        <dt>CHARSET</dt>
        <dd>The job character set, typically "utf-8".</dd>
@@ -237,7 +235,7 @@ prefix strings:</p>
        <code>marker-types</code>, <code>printer-alert</code>, and
        <code>printer-alert-description</code> printer attributes. Standard
        <code>marker-types</code> values are listed in <a href='#TABLE1'>Table
-       1</a>.</dd>
+       1</a>. String values need special handling - see <a href="#ATTR_STRINGS">Reporting Attribute String Values</a> below.</dd>
 
        <dt>CRIT: message</dt>
        <dd>Sets the printer-state-message attribute and adds the specified
@@ -287,7 +285,7 @@ prefix strings:</p>
        <dd>Sets or clears printer-state-reason keywords for the current queue.
        Typically this is used to indicate persistent media, ink, toner, and
        configuration conditions or errors on a printer.
-       <a href='#TABLE2'>Table 2</a> lists the standard state keywords -
+       <a href='#TABLE2'>Table 2</a> lists some of the standard "printer-state-reasons" keywords from the <a href="http://www.iana.org/assignments/ipp-registrations/ipp-registrations.xhtml#ipp-registrations-4">IANA IPP Registry</a> -
        use vendor-prefixed ("com.example.foo") keywords for custom states. See
        <a href="#MANAGING_STATE">Managing Printer State in a Filter</a> for more
        information.
@@ -320,11 +318,11 @@ the "DEBUG:" prefix string.</p>
        <td>Fuser unit</td>
 </tr>
 <tr>
-       <td>fuserCleaningPad</td>
+       <td>fuser-cleaning-pad</td>
        <td>Fuser cleaning pad</td>
 </tr>
 <tr>
-       <td>fuserOil</td>
+       <td>fuser-oil</td>
        <td>Fuser oil</td>
 </tr>
 <tr>
@@ -336,7 +334,7 @@ the "DEBUG:" prefix string.</p>
        <td>Photo conductor</td>
 </tr>
 <tr>
-       <td>solidWax</td>
+       <td>solid-wax</td>
        <td>Wax supply</td>
 </tr>
 <tr>
@@ -348,19 +346,19 @@ the "DEBUG:" prefix string.</p>
        <td>Toner supply</td>
 </tr>
 <tr>
-       <td>transferUnit</td>
+       <td>transfer-unit</td>
        <td>Transfer unit</td>
 </tr>
 <tr>
-       <td>wasteInk</td>
+       <td>waste-ink</td>
        <td>Waste ink tank</td>
 </tr>
 <tr>
-       <td>wasteToner</td>
+       <td>waste-toner</td>
        <td>Waste toner tank</td>
 </tr>
 <tr>
-       <td>wasteWax</td>
+       <td>waste-wax</td>
        <td>Waste wax tank</td>
 </tr>
 </tbody>
@@ -440,6 +438,95 @@ the "DEBUG:" prefix string.</p>
 </tbody>
 </table></div>
 
+
+<h4><a name="ATTR_STRINGS">Reporting Attribute String Values</a></h4>
+
+<p>When reporting string values using "ATTR:" messages, a filter or backend must take special care to appropriately quote those values. The scheduler uses the CUPS option parsing code for attributes, so the general syntax is:</p>
+
+<pre class="example">
+name=simple
+name=simple,simple,...
+name='complex value'
+name="complex value"
+name='"complex value"','"complex value"',...
+</pre>
+
+<p>Simple values are strings that do not contain spaces, quotes, backslashes, or the comma and can be placed verbatim in the "ATTR:" message, for example:</p>
+
+<pre class="example">
+int levels[4] = { 40, 50, 60, 70 }; /* CMYK */
+
+fputs("ATTR: marker-colors=#00FFFF,#FF00FF,#FFFF00,#000000\n", stderr);
+fputs("ATTR: marker-high-levels=100,100,100,100\n", stderr);
+fprintf(stderr, "ATTR: marker-levels=%d,%d,%d,%d\n", levels[0], levels[1],
+        levels[2], levels[3], levels[4]);
+fputs("ATTR: marker-low-levels=5,5,5,5\n", stderr);
+fputs("ATTR: marker-types=toner,toner,toner,toner\n", stderr);
+</pre>
+
+<p>Complex values that contains spaces, quotes, backslashes, or the comma must be quoted. For a single value a single set of quotes is sufficient:</p>
+
+<pre class="example">
+fputs("ATTR: marker-message='Levels shown are approximate.'\n", stderr);
+</pre>
+
+<p>When multiple values are reported, each value must be enclosed by a set of single and double quotes:</p>
+
+<pre class="example">
+fputs("ATTR: marker-names='\"Cyan Toner\"','\"Magenta Toner\"',"
+      "'\"Yellow Toner\"','\"Black Toner\"'\n", stderr);
+</pre>
+
+<p>The IPP backend includes a <var>quote_string</var> function that may be used to properly quote a complex value in an "ATTR:" message:</p>
+
+<pre class="example">
+static const char *                     /* O - Quoted string */
+quote_string(const char *s,             /* I - String */
+             char       *q,             /* I - Quoted string buffer */
+             size_t     qsize)          /* I - Size of quoted string buffer */
+{
+  char  *qptr,                          /* Pointer into string buffer */
+        *qend;                          /* End of string buffer */
+
+
+  qptr = q;
+  qend = q + qsize - 5;
+
+  if (qend &lt; q)
+  {
+    *q = '\0';
+    return (q);
+  }
+
+  *qptr++ = '\'';
+  *qptr++ = '\"';
+
+  while (*s && qptr &lt; qend)
+  {
+    if (*s == '\\' || *s == '\"' || *s == '\'')
+    {
+      if (qptr &lt; (qend - 4))
+      {
+        *qptr++ = '\\';
+        *qptr++ = '\\';
+        *qptr++ = '\\';
+      }
+      else
+        break;
+    }
+
+    *qptr++ = *s++;
+  }
+
+  *qptr++ = '\"';
+  *qptr++ = '\'';
+  *qptr   = '\0';
+
+  return (q);
+}
+</pre>
+
+
 <h4><a name="MANAGING_STATE">Managing Printer State in a Filter</a></h4>
 
 <p>Filters are responsible for managing the state keywords they set using
@@ -474,7 +561,7 @@ sub-state and not an issue that applies when a job is not printing.</p>
 <blockquote><b>Note:</b>
 
 <p>"STATE:" messages often provide visible alerts to the user. For example,
-on OS X setting a printer-state-reason value with an "-error" or
+on macOS setting a printer-state-reason value with an "-error" or
 "-warning" suffix will cause the printer's dock item to bounce if the
 corresponding reason is localized with a cupsIPPReason keyword in the
 printer's PPD file.</p>
@@ -488,7 +575,7 @@ from localizing the vendor-prefixed keyword in the PPD file - otherwise both
 the generic and vendor-specific keyword will be shown in the user
 interface.</p>
 
-</blockquote></dd>
+</blockquote>
 
 <h4><a name="REPORTING_SUPPLIES">Reporting Supply Levels</a></h4>
 
@@ -613,7 +700,7 @@ datalen = sizeof(data) - 1;
 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)
+if (status == CUPS_SC_STATUS_OK &amp;&amp; datalen > 0)
   data[datalen] = '\0';
 else
   data[0] = '\0';
@@ -763,3 +850,25 @@ void *my_data;
 
 <a href="#cupsSideChannelSNMPWalk">cupsSNMPSideChannelWalk</a>(".1.3.6.1.2.1.43", 5.0, my_callback, my_data);
 </pre>
+
+<h2><a name="SANDBOXING">Sandboxing on macOS</a></h2>
+
+<p>Starting with macOS 10.6, filters and backends are run inside a security "sandbox" which further limits (beyond the normal UNIX user/group permissions) what a filter or backend can do. This helps to both secure the printing system from malicious software and enforce the functional separation of components in the CUPS filter chain. What follows is a list of actions that are explicitly allowed for all filters and backends:</p>
+
+<ol>
+
+       <li>Reading of files: pursuant to normal UNIX file permissions, filters and backends can read files for the current job from the <var>/private/var/spool/cups</var> directory and other files on mounted filesystems <em>except</em> for user home directories under <var>/Users</var>.</li>
+
+       <li>Writing of files: pursuant to normal UNIX file permissions, filters and backends can read/write files to the cache directory specified by the <code>CUPS_CACHEDIR</code> environment variable, to the state directory specified by the <code>CUPS_STATEDIR</code> environment variable, to the temporary directory specified by the <code>TMPDIR</code> environment variable, and under the <var>/private/var/db</var>, <var>/private/var/folders</var>, <var>/private/var/lib</var>, <var>/private/var/mysql</var>, <var>/private/var/run</var>, <var>/private/var/spool</var> (except <var>/private/var/spool/cups</var>), <var>/Library/Application&nbsp;Support</var>, <var>/Library/Caches</var>, <var>/Library/Logs</var>, <var>/Library/Preferences</var>, <var>/Library/WebServer</var>, and <var>/Users/Shared</var> directories.</li>
+
+       <li>Execution of programs: pursuant to normal UNIX file permissions, filters and backends can execute any program not located under the <var>/Users</var> directory. Child processes inherit the sandbox and are subject to the same restrictions as the parent.</li>
+
+       <li>Bluetooth and USB: backends can access Bluetooth and USB printers through IOKit. <em>Filters cannot access Bluetooth and USB printers directly.</em></li>
+
+       <li>Network: filters and backends can access UNIX domain sockets under the <var>/private/tmp</var>, <var>/private/var/run</var>, and <var>/private/var/tmp</var> directories. Backends can also create IPv4 and IPv6 TCP (outgoing) and UDP (incoming and outgoing) socket, and bind to local source ports. <em>Filters cannot directly create IPv4 and IPv6 TCP or UDP sockets.</em></li>
+
+       <li>Notifications: filters and backends can send notifications via the Darwin <code>notify_post()</code> API.</li>
+
+</ol>
+
+<blockquote><b>Note:</b> The sandbox profile used in CUPS 2.0 still allows some actions that are not listed above - these privileges will be removed over time until the profile matches the list above.</blockquote>