~ubuntu-branches/ubuntu/wily/cups/wily

« back to all changes in this revision

Viewing changes to debian/patches/cups-1.6.4-changes.patch

  • Committer: Package Import Robot
  • Author(s): Till Kamppeter
  • Date: 2013-09-24 22:15:01 UTC
  • mfrom: (99.1.28 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130924221501-115ywce51xe7hhok
* debian/patches/cups-1.6.4-changes.patch: Merged latest fixes from upstream,
  taken from CUPS 1.6.4, as there is no public repository of CUPS any more
  and due to Apple policies the next 1.7.x release, 1.7.0 final, happens
  only with the next release of Mac OS X. Fixes:
   - Removed some duplicate page size definitions for some ISO sizes that were
     causing problems
   - The IPP backend did not add the "last-document" attribute
   - Added a SyncOnClose directive to cups-files.conf to force cupsd to
     call fsync before closing any configuration/state files it writes
     (LP: #1157972, Red Hat bug #984883).
   - Added USB quirk rule for Lexmark E238
   - Closed server connections were still not always detected
   - The libusb-based USB backend now loads its list of quirks from files
     in /usr/share/cups/usb instead of using a hardcoded table, this
     makes spotting and fixing USB problems much easier.
   - The scheduler did not properly register ICC color profiles with
     colord
* debian/patches/usb-backend-more-quirk-rules.patch,
  debian/patches/handle-server-terminating-connection.patch,
  debian/patches/colord-add-profile-fix.patch: Removed, included upstream.
* debian/patches/pidfile.patch,
  debian/patches/rootbackends-worldreadable.patch,
  debian/patches/airprint-support.patch,
  debian/patches/do-not-broadcast-with-hostnames.patch,
  debian/patches/mention-rfc2911-in-ipptoolfile-for-clarity.patch,
  debian/patches/add-ipp-backend-of-cups-1.4.patch,
  debian/patches/confdirperms.patch,
  debian/patches/show-compile-command-lines.patch,
  debian/patches/log-debug-history-nearly-unlimited.patch: Refreshed with
  quilt.
* debian/local/apparmor-profile: Silenced AppArmor noise in syslog
  (LP: #1229766).
* debian/local/cupsd-sync-files-on-close.patch: Activate CUPS daemon
  syncing files when closing, so that config files (like printers.conf)
  do not mysteriously disappear (LP: #1157972, Red Hat bug #984883).
* debian/cups-server-common.install: Install /usr/share/cups/usb/ with the
  USB backend quirk rules file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
--- a/Makedefs.in
 
2
+++ b/Makedefs.in
 
3
@@ -218,6 +218,7 @@
 
4
 SERVERROOT     =       $(BUILDROOT)@CUPS_SERVERROOT@
 
5
 SMFMANIFESTDIR =       @SMFMANIFESTDIR@
 
6
 STATEDIR       =       $(BUILDROOT)@CUPS_STATEDIR@
 
7
+USBQUIRKS      =       @USBQUIRKS@
 
8
 XINETD         =       @XINETD@
 
9
 
 
10
 MAN1EXT                =       @MAN1EXT@
 
11
--- a/backend/Makefile
 
12
+++ b/backend/Makefile
 
13
@@ -109,6 +109,11 @@
 
14
 #
 
15
 
 
16
 install-data:
 
17
+       if test "x$(USBQUIRKS)" != x; then \
 
18
+               echo Installing USB quirks in $(USBQUIRKS); \
 
19
+               $(INSTALL_DIR) -m 755 $(USBQUIRKS); \
 
20
+               $(INSTALL_DATA) org.cups.usb-quirks $(USBQUIRKS); \
 
21
+       fi
 
22
 
 
23
 
 
24
 #
 
25
--- a/backend/ipp.c
 
26
+++ b/backend/ipp.c
 
27
@@ -1699,8 +1699,8 @@
 
28
          ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
 
29
                        "requesting-user-name", NULL, argv[2]);
 
30
 
 
31
-        if ((i + 1) >= num_files)
 
32
-         ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1);
 
33
+       ippAddBoolean(request, IPP_TAG_OPERATION, "last-document",
 
34
+                     (i + 1) >= num_files);
 
35
 
 
36
        if (document_format)
 
37
          ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
 
38
--- /dev/null
 
39
+++ b/backend/org.cups.usb-quirks
 
40
@@ -0,0 +1,214 @@
 
41
+# USB backend 'quirks' file.
 
42
+#
 
43
+# This file lists known issues with various vendors or printers.  Each
 
44
+# line contains either a comment (starting with #) or the USB vendor ID,
 
45
+# product ID (omit for all vendor products), and a list of known issues:
 
46
+#
 
47
+#   blacklist     The printer is not functional with the USB backend.
 
48
+#   no-reattach   Do no re-attach usblp kernel module after printing.
 
49
+#   soft-reset    Do a soft reset after printing for cleanup.
 
50
+#   unidir        Only supported unidirectional I/O
 
51
+#   usb-init      Needs vendor USB initialization string.
 
52
+#   vendor-class  Uses vendor-specific class or subclass.
 
53
+#   whitelist     The printer is functional with the USB backend.
 
54
+
 
55
+# HP DeskJet 895C
 
56
+0x03f0 0x0004 unidir
 
57
+
 
58
+# HP DeskJet 880C
 
59
+0x03f0 0x0104 unidir
 
60
+
 
61
+# HP DeskJet 815C
 
62
+0x03f0 0x0204 unidir
 
63
+
 
64
+# HP DeskJet 810C/812C
 
65
+0x03f0 0x0304 unidir
 
66
+
 
67
+# HP DeskJet 830C
 
68
+0x03f0 0x0404 unidir
 
69
+
 
70
+# HP DeskJet 885C
 
71
+0x03f0 0x0504 unidir
 
72
+
 
73
+# HP DeskJet 840C
 
74
+0x03f0 0x0604 unidir
 
75
+
 
76
+# HP DeskJet 816C
 
77
+0x03f0 0x0804 unidir
 
78
+
 
79
+# HP Deskjet 959C
 
80
+0x03f0 0x1104 unidir
 
81
+
 
82
+# NEC Picty900 (HP OEM)
 
83
+0x0409 0xefbe unidir
 
84
+
 
85
+# NEC Picty760 (HP OEM)
 
86
+0x0409 0xbef4 unidir
 
87
+
 
88
+# NEC Picty920 (HP OEM)
 
89
+0x0409 0xf0be unidir
 
90
+
 
91
+# NEC Picty800 (HP OEM)
 
92
+0x0409 0xf1be unidir
 
93
+
 
94
+# Lexmark International, Inc. (e250d), https://bugs.launchpad.net/bugs/1084164
 
95
+0x043d 0x00f3 no-reattach
 
96
+
 
97
+# Kyocera Mita FS 820, by zut <kernel@zut.de>
 
98
+0x0482 0x0010 unidir
 
99
+
 
100
+# Canon, Inc. PIXMA iP6000D Printer, https://bugs.launchpad.net/bugs/1160638
 
101
+0x04a9 0x1095 unidir
 
102
+
 
103
+# Canon, Inc. PIXMA iP4200 Printer, http://www.cups.org/str.php?L4155
 
104
+0x04a9 0x10a2 unidir
 
105
+
 
106
+# Canon, Inc. PIXMA iP4300 Printer, https://bugs.launchpad.net/bugs/1032385
 
107
+0x04a9 0x10b6 unidir
 
108
+
 
109
+# Canon, Inc. MP210 https://bugzilla.redhat.com/show_bug.cgi?id=847923#c53
 
110
+0x04a9 0x1721 unidir
 
111
+
 
112
+# Canon, Inc. MP500 Printer, https://bugs.launchpad.net/bugs/1032456
 
113
+0x04a9 0x170c unidir
 
114
+
 
115
+# Canon, Inc. MP510 Printer, https://bugs.launchpad.net/bugs/1050009
 
116
+0x04a9 0x1717 unidir
 
117
+
 
118
+# Canon, Inc. MP550 Printer, http://www.cups.org/str.php?L4155
 
119
+0x04a9 0x173d unidir
 
120
+
 
121
+# Canon, Inc. MP560 Printer, http://www.cups.org/str.php?L4155
 
122
+0x04a9 0x173e unidir
 
123
+
 
124
+# Canon, Inc. MF4150 Printer, https://bugs.launchpad.net/bugs/1160638
 
125
+0x04a9 0x26a3 no-reattach
 
126
+
 
127
+# Brother Industries, Ltd HL-1430 Laser Printer, https://bugs.launchpad.net/bugs/1038695
 
128
+0x04f9 0x001a no-reattach
 
129
+
 
130
+# Brother Industries, Ltd HL-1440 Laser Printer, https://bugs.launchpad.net/bugs/1000253
 
131
+0x04f9 0x000d no-reattach unidir
 
132
+
 
133
+# Brother Industries, Ltd HL-1450 Laser Printer, https://bugs.launchpad.net/bugs/1000253
 
134
+0x04f9 0x000e no-reattach unidir
 
135
+
 
136
+# Oki Data Corp. Okipage 14ex Printer, https://bugs.launchpad.net/bugs/872483
 
137
+0x06bc 0x000b no-reattach
 
138
+
 
139
+# Oki Data Corp. B410d, https://bugs.launchpad.net/bugs/872483
 
140
+0x06bc 0x01c7 no-reattach
 
141
+
 
142
+# Seiko Epson Corp. Stylus Color 740 / Photo 750, http://bugs.debian.org/697970
 
143
+0x04b8 0x0001 no-reattach unidir
 
144
+
 
145
+# Seiko Epson Corp. Stylus Color 670, https://bugs.launchpad.net/bugs/872483
 
146
+0x04b8 0x0005 no-reattach
 
147
+
 
148
+# Seiko Epson Receipt Printer M129C
 
149
+0x04b8 0x0202 vendor-class
 
150
+
 
151
+# Prolific Technology, Inc. PL2305 Parallel Port (USB -> Parallel adapter), https://bugs.launchpad.net/bugs/987485
 
152
+0x067b 0x2305 no-reattach soft-reset unidir
 
153
+
 
154
+# Xerox Phaser 3124 https://bugzilla.redhat.com/show_bug.cgi?id=867392
 
155
+0x0924 0x3ce9 no-reattach
 
156
+
 
157
+# Xerox WorkCentre 3210 https://bugs.launchpad.net/bugs/1102470
 
158
+0x0924 0x4293 no-reattach
 
159
+
 
160
+# QinHeng Electronics CH340S (USB -> Parallel adapter), https://bugs.launchpad.net/bugs/1000253
 
161
+0x1a86 0x7584 no-reattach
 
162
+
 
163
+# All Samsung devices, https://bugs.launchpad.net/bugs/1032456
 
164
+0x04e8 soft-reset
 
165
+
 
166
+# All Zebra devices, https://bugs.launchpad.net/bugs/1001028
 
167
+0x0a5f unidir
 
168
+
 
169
+# Canon CP-10
 
170
+0x04a9 0x304a blacklist
 
171
+
 
172
+# Canon CP-100
 
173
+0x04a9 0x3063 blacklist
 
174
+
 
175
+# Canon CP-200
 
176
+0x04a9 0x307c blacklist
 
177
+
 
178
+# Canon CP-300
 
179
+0x04a9 0x307d blacklist
 
180
+
 
181
+# Canon CP-220
 
182
+0x04a9 0x30bd blacklist
 
183
+
 
184
+# Canon CP-330
 
185
+0x04a9 0x30be blacklist
 
186
+
 
187
+# Canon SELPHY CP400
 
188
+0x04a9 0x30f6 blacklist
 
189
+
 
190
+# Canon SELPHY CP600
 
191
+0x04a9 0x310b blacklist
 
192
+
 
193
+# Canon SELPHY CP710
 
194
+0x04a9 0x3127 blacklist
 
195
+
 
196
+# Canon SELPHY CP510
 
197
+0x04a9 0x3128 blacklist
 
198
+
 
199
+# Canon SELPHY ES1
 
200
+0x04a9 0x3141 blacklist
 
201
+
 
202
+# Canon SELPHY CP730
 
203
+0x04a9 0x3142 blacklist
 
204
+
 
205
+# Canon SELPHY CP720
 
206
+0x04a9 0x3143 blacklist
 
207
+
 
208
+# Canon SELPHY CP750
 
209
+0x04a9 0x3170 blacklist
 
210
+
 
211
+# Canon SELPHY CP740
 
212
+0x04a9 0x3171 blacklist
 
213
+
 
214
+# Canon SELPHY ES2
 
215
+0x04a9 0x3185 blacklist
 
216
+
 
217
+# Canon SELPHY ES20
 
218
+0x04a9 0x3186 blacklist
 
219
+
 
220
+# Canon SELPHY CP770
 
221
+0x04a9 0x31aa blacklist
 
222
+
 
223
+# Canon SELPHY CP760
 
224
+0x04a9 0x31ab blacklist
 
225
+
 
226
+# Canon SELPHY ES30
 
227
+0x04a9 0x31b0 blacklist
 
228
+
 
229
+# Canon SELPHY CP780
 
230
+0x04a9 0x31dd blacklist
 
231
+
 
232
+# Canon SELPHY ES40
 
233
+0x04a9 0x31ee blacklist
 
234
+
 
235
+# Canon SELPHY CP800
 
236
+0x04a9 0x3214 blacklist
 
237
+
 
238
+# Canon SELPHY CP900
 
239
+0x04a9 0x3255 blacklist
 
240
+
 
241
+# Canon SELPHY CP810
 
242
+0x04a9 0x3256 blacklist
 
243
+
 
244
+# Canon SELPHY CP500
 
245
+0x04a9 0x30f5 blacklist
 
246
+
 
247
+# Canon SELPHY ES3
 
248
+0x04a9 0x31af blacklist
 
249
+
 
250
+# Canon SELPHY CP780
 
251
+0x04a9 0x31dd blacklist
 
252
+
 
253
+# Lexmark E238 (<rdar://problem/14493054>)
 
254
+0x043d 0x00d7 no-reattach
 
255
--- a/backend/usb-libusb.c
 
256
+++ b/backend/usb-libusb.c
 
257
@@ -16,18 +16,20 @@
 
258
  *   list_devices()      - List the available printers.
 
259
  *   print_device()      - Print a file to a USB device.
 
260
  *   close_device()      - Close the connection to the USB printer.
 
261
+ *   compare_quirks()    - Compare two quirks entries.
 
262
  *   find_device()       - Find or enumerate USB printers.
 
263
+ *   find_quirks()       - Find the quirks for the given printer, if any.
 
264
  *   get_device_id()     - Get the IEEE-1284 device ID for the printer.
 
265
  *   list_cb()           - List USB printers for discovery.
 
266
+ *   load_quirks()       - Load all quirks files in the /usr/share/cups/usb
 
267
+ *                         directory.
 
268
  *   make_device_uri()   - Create a device URI for a USB printer.
 
269
  *   open_device()       - Open a connection to the USB printer.
 
270
  *   print_cb()          - Find a USB printer for printing.
 
271
- *   printer_class_soft_reset()' - Do the soft reset request specific to
 
272
- *                          printers
 
273
- *   quirks()            - Get the known quirks of a given printer model
 
274
  *   read_thread()       - Thread to read the backchannel data on.
 
275
  *   sidechannel_thread() - Handle side-channel requests.
 
276
  *   soft_reset()        - Send a soft reset to the device.
 
277
+ *   soft_reset_printer() - Do the soft reset request specific to printers
 
278
  */
 
279
 
 
280
 /*
 
281
@@ -36,6 +38,7 @@
 
282
 
 
283
 #include <libusb.h>
 
284
 #include <cups/cups-private.h>
 
285
+#include <cups/dir.h>
 
286
 #include <pthread.h>
 
287
 #include <sys/select.h>
 
288
 #include <sys/types.h>
 
289
@@ -70,15 +73,15 @@
 
290
                        read_endp,      /* Read endpoint */
 
291
                        protocol,       /* Protocol: 1 = Uni-di, 2 = Bi-di. */
 
292
                        usblp_attached, /* "usblp" kernel module attached? */
 
293
-                       reset_after_job; /* Set to 1 by print_device() */
 
294
-  unsigned int         quirks;         /* Quirks flags */
 
295
+                       reset_after_job;/* Set to 1 by print_device() */
 
296
+  unsigned             quirks;         /* Quirks flags */
 
297
   struct libusb_device_handle *handle; /* Open handle to device */
 
298
 } usb_printer_t;
 
299
 
 
300
 typedef int (*usb_cb_t)(usb_printer_t *, const char *, const char *,
 
301
                         const void *);
 
302
 
 
303
-typedef struct usb_globals_s
 
304
+typedef struct usb_globals_s           /* Global USB printer information */
 
305
 {
 
306
   usb_printer_t                *printer;       /* Printer */
 
307
 
 
308
@@ -105,143 +108,41 @@
 
309
 } usb_globals_t;
 
310
 
 
311
 /*
 
312
- * Quirks: various printer quirks are handled by this table & its flags.
 
313
+ * Quirks: various printer quirks are handled by this structure and its flags.
 
314
  *
 
315
- * This is copied from the usblp kernel module. So we can easily copy and paste
 
316
- * new quirks from the module.
 
317
+ * The quirks table used to be compiled into the backend but is now loaded from
 
318
+ * one or more files in the /usr/share/cups/usb directory.
 
319
  */
 
320
 
 
321
-struct quirk_printer_struct {
 
322
-       int vendorId;
 
323
-       int productId;
 
324
-       unsigned int quirks;
 
325
-};
 
326
-
 
327
-#define USBLP_QUIRK_BIDIR      0x1     /* reports bidir but requires
 
328
-                                          unidirectional mode (no INs/reads) */
 
329
-#define USBLP_QUIRK_USB_INIT   0x2     /* needs vendor USB init string */
 
330
-#define USBLP_QUIRK_BAD_CLASS  0x4     /* descriptor uses vendor-specific
 
331
-                                          Class or SubClass */
 
332
-#define USBLP_QUIRK_BLACKLIST  0x8     /* these printers do not conform to the USB print spec */
 
333
-#define USBLP_QUIRK_RESET      0x4000  /* After printing do a reset
 
334
-                                          for clean-up */
 
335
-#define USBLP_QUIRK_NO_REATTACH        0x8000  /* After printing we cannot re-attach
 
336
+#define USB_QUIRK_BLACKLIST    0x0001  /* Does not conform to the spec */
 
337
+#define USB_QUIRK_NO_REATTACH  0x0002  /* After printing we cannot re-attach
 
338
                                           the usblp kernel module */
 
339
+#define USB_QUIRK_SOFT_RESET   0x0004  /* After printing do a soft reset
 
340
+                                          for clean-up */
 
341
+#define USB_QUIRK_UNIDIR       0x0008  /* Requires unidirectional mode */
 
342
+#define USB_QUIRK_USB_INIT     0x0010  /* Needs vendor USB init string */
 
343
+#define USB_QUIRK_VENDOR_CLASS 0x0020  /* Descriptor uses vendor-specific
 
344
+                                          Class or SubClass */
 
345
+#define USB_QUIRK_WHITELIST    0x0000  /* no quirks */
 
346
+
 
347
+
 
348
+typedef struct usb_quirk_s             /* USB "quirk" information */
 
349
+{
 
350
+  int          vendor_id,              /* Affected vendor ID */
 
351
+               product_id;             /* Affected product ID or 0 for all */
 
352
+  unsigned     quirks;                 /* Quirks bitfield */
 
353
+} usb_quirk_t;
 
354
+
 
355
 
 
356
-static const struct quirk_printer_struct quirk_printers[] = {
 
357
-       { 0x03f0, 0x0004, USBLP_QUIRK_BIDIR }, /* HP DeskJet 895C */
 
358
-       { 0x03f0, 0x0104, USBLP_QUIRK_BIDIR }, /* HP DeskJet 880C */
 
359
-       { 0x03f0, 0x0204, USBLP_QUIRK_BIDIR }, /* HP DeskJet 815C */
 
360
-       { 0x03f0, 0x0304, USBLP_QUIRK_BIDIR }, /* HP DeskJet 810C/812C */
 
361
-       { 0x03f0, 0x0404, USBLP_QUIRK_BIDIR }, /* HP DeskJet 830C */
 
362
-       { 0x03f0, 0x0504, USBLP_QUIRK_BIDIR }, /* HP DeskJet 885C */
 
363
-       { 0x03f0, 0x0604, USBLP_QUIRK_BIDIR }, /* HP DeskJet 840C */
 
364
-       { 0x03f0, 0x0804, USBLP_QUIRK_BIDIR }, /* HP DeskJet 816C */
 
365
-       { 0x03f0, 0x1104, USBLP_QUIRK_BIDIR }, /* HP Deskjet 959C */
 
366
-       { 0x0409, 0xefbe, USBLP_QUIRK_BIDIR }, /* NEC Picty900 (HP OEM) */
 
367
-       { 0x0409, 0xbef4, USBLP_QUIRK_BIDIR }, /* NEC Picty760 (HP OEM) */
 
368
-       { 0x0409, 0xf0be, USBLP_QUIRK_BIDIR }, /* NEC Picty920 (HP OEM) */
 
369
-       { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
 
370
-       { 0x043d, 0x00f3, USBLP_QUIRK_NO_REATTACH }, /* Lexmark International,
 
371
-                      Inc. (e250d), https://bugs.launchpad.net/bugs/1084164 */
 
372
-       { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820,
 
373
-                                                 by zut <kernel@zut.de> */
 
374
-       { 0x04a9, 0x1095, USBLP_QUIRK_BIDIR }, /* Canon, Inc. PIXMA iP6000D
 
375
-                           Printer, https://bugs.launchpad.net/bugs/1160638 */
 
376
-       { 0x04a9, 0x10a2, USBLP_QUIRK_BIDIR }, /* Canon, Inc. PIXMA iP4200
 
377
-                           Printer, http://www.cups.org/str.php?L4155 */
 
378
-       { 0x04a9, 0x10b6, USBLP_QUIRK_BIDIR }, /* Canon, Inc. PIXMA iP4300
 
379
-                           Printer, https://bugs.launchpad.net/bugs/1032385 */
 
380
-       { 0x04a9, 0x1721, USBLP_QUIRK_BIDIR }, /* Canon, Inc. MP210
 
381
-                     https://bugzilla.redhat.com/show_bug.cgi?id=847923#c53 */
 
382
-       { 0x04a9, 0x170c, USBLP_QUIRK_BIDIR }, /* Canon, Inc. MP500
 
383
-                           Printer, https://bugs.launchpad.net/bugs/1032456 */
 
384
-       { 0x04a9, 0x1717, USBLP_QUIRK_BIDIR }, /* Canon, Inc. MP510
 
385
-                           Printer, https://bugs.launchpad.net/bugs/1050009 */
 
386
-       { 0x04a9, 0x173d, USBLP_QUIRK_BIDIR }, /* Canon, Inc. MP550
 
387
-                           Printer, http://www.cups.org/str.php?L4155 */
 
388
-       { 0x04a9, 0x173e, USBLP_QUIRK_BIDIR }, /* Canon, Inc. MP560
 
389
-                           Printer, http://www.cups.org/str.php?L4155 */
 
390
-       { 0x04a9, 0x26a3, USBLP_QUIRK_NO_REATTACH }, /* Canon, Inc. MF4150
 
391
-                           Printer, https://bugs.launchpad.net/bugs/1160638 */
 
392
-       { 0x04f9, 0x001a, USBLP_QUIRK_NO_REATTACH }, /* Brother Industries, Ltd
 
393
-                                                 HL-1430 Laser Printer,
 
394
-                                    https://bugs.launchpad.net/bugs/1038695 */
 
395
-       { 0x04f9, 0x000d, USBLP_QUIRK_BIDIR |
 
396
-                         USBLP_QUIRK_NO_REATTACH }, /* Brother Industries, Ltd
 
397
-                                                 HL-1440 Laser Printer,
 
398
-                                    https://bugs.launchpad.net/bugs/1000253 */
 
399
-       { 0x04f9, 0x000e, USBLP_QUIRK_BIDIR |
 
400
-                         USBLP_QUIRK_NO_REATTACH }, /* Brother Industries, Ltd
 
401
-                                                 HL-1450 Laser Printer,
 
402
-                                    https://bugs.launchpad.net/bugs/1000253 */
 
403
-       { 0x06bc, 0x000b, USBLP_QUIRK_NO_REATTACH }, /* Oki Data Corp.
 
404
-                                                 Okipage 14ex Printer,
 
405
-                                    https://bugs.launchpad.net/bugs/872483 */
 
406
-       { 0x06bc, 0x01c7, USBLP_QUIRK_NO_REATTACH }, /* Oki Data Corp. B410d,
 
407
-                                    https://bugs.launchpad.net/bugs/872483 */
 
408
-       { 0x04b8, 0x0001, USBLP_QUIRK_BIDIR |
 
409
-                         USBLP_QUIRK_NO_REATTACH }, /* Seiko Epson Corp. Stylus Color 740 / Photo 750,
 
410
-                                    http://bugs.debian.org/697970 */
 
411
-       { 0x04b8, 0x0005, USBLP_QUIRK_NO_REATTACH }, /* Seiko Epson Corp. Stylus Color 670,
 
412
-                                    https://bugs.launchpad.net/bugs/872483 */
 
413
-       { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt
 
414
-                                                     Printer M129C */
 
415
-       { 0x067b, 0x2305, USBLP_QUIRK_BIDIR |
 
416
-                         USBLP_QUIRK_NO_REATTACH |
 
417
-                         USBLP_QUIRK_RESET },
 
418
-       /* Prolific Technology, Inc. PL2305 Parallel Port
 
419
-          (USB -> Parallel adapter), https://bugs.launchpad.net/bugs/987485 */
 
420
-       { 0x0924, 0x3ce9, USBLP_QUIRK_NO_REATTACH }, /* Xerox Phaser 3124
 
421
-                         https://bugzilla.redhat.com/show_bug.cgi?id=867392 */
 
422
-       { 0x0924, 0x4293, USBLP_QUIRK_NO_REATTACH }, /* Xerox WorkCentre 3210
 
423
-                                    https://bugs.launchpad.net/bugs/1102470 */
 
424
-       { 0x1a86, 0x7584, USBLP_QUIRK_NO_REATTACH }, /* QinHeng Electronics
 
425
-   CH340S (USB -> Parallel adapter), https://bugs.launchpad.net/bugs/1000253 */
 
426
-       { 0x04e8, 0x0000, USBLP_QUIRK_RESET }, /* All Samsung devices,
 
427
-                                    https://bugs.launchpad.net/bugs/1032456 */
 
428
-       { 0x0a5f, 0x0000, USBLP_QUIRK_BIDIR }, /* All Zebra devices,
 
429
-                                    https://bugs.launchpad.net/bugs/1001028 */
 
430
-       /* Canon */
 
431
-       { 0x04a9, 0x304a, USBLP_QUIRK_BLACKLIST }, /* Canon CP-10 */
 
432
-       { 0x04a9, 0x3063, USBLP_QUIRK_BLACKLIST }, /* Canon CP-100 */
 
433
-       { 0x04a9, 0x307c, USBLP_QUIRK_BLACKLIST }, /* Canon CP-200 */
 
434
-       { 0x04a9, 0x307d, USBLP_QUIRK_BLACKLIST }, /* Canon CP-300 */
 
435
-       { 0x04a9, 0x30bd, USBLP_QUIRK_BLACKLIST }, /* Canon CP-220 */
 
436
-       { 0x04a9, 0x30be, USBLP_QUIRK_BLACKLIST }, /* Canon CP-330 */
 
437
-       { 0x04a9, 0x30f6, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP400 */
 
438
-       { 0x04a9, 0x310b, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP600 */
 
439
-       { 0x04a9, 0x3127, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP710 */
 
440
-       { 0x04a9, 0x3128, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP510 */
 
441
-       { 0x04a9, 0x3141, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY ES1 */
 
442
-       { 0x04a9, 0x3142, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP730 */
 
443
-       { 0x04a9, 0x3143, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP720 */
 
444
-       { 0x04a9, 0x3170, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP750 */
 
445
-       { 0x04a9, 0x3171, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP740 */
 
446
-       { 0x04a9, 0x3185, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY ES2 */
 
447
-       { 0x04a9, 0x3186, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY ES20 */
 
448
-       { 0x04a9, 0x31aa, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP770 */
 
449
-       { 0x04a9, 0x31ab, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP760 */
 
450
-       { 0x04a9, 0x31b0, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY ES30 */
 
451
-       { 0x04a9, 0x31dd, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP780 */
 
452
-       { 0x04a9, 0x31ee, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY ES40 */
 
453
-       { 0x04a9, 0x3214, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP800 */
 
454
-       { 0x04a9, 0x3255, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP900 */
 
455
-       { 0x04a9, 0x3256, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP810 */
 
456
-       { 0x04a9, 0x30F5, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP500 */
 
457
-       { 0x04a9, 0x31AF, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY ES3 */
 
458
-       { 0x04a9, 0x31DD, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP780 */
 
459
-        /* MISSING PIDs: CP520, CP530, CP790 */
 
460
-       { 0, 0 }
 
461
-};
 
462
 
 
463
 
 
464
 /*
 
465
  * Globals...
 
466
  */
 
467
 
 
468
+cups_array_t           *all_quirks;    /* Array of printer quirks */
 
469
 usb_globals_t          g = { 0 };      /* Globals */
 
470
-libusb_device           **list;         /* List of connected USB devices */
 
471
+libusb_device          **all_list;     /* List of connected USB devices */
 
472
 
 
473
 
 
474
 /*
 
475
@@ -249,22 +150,24 @@
 
476
  */
 
477
 
 
478
 static int             close_device(usb_printer_t *printer);
 
479
+static int             compare_quirks(usb_quirk_t *a, usb_quirk_t *b);
 
480
 static usb_printer_t   *find_device(usb_cb_t cb, const void *data);
 
481
+static unsigned                find_quirks(int vendor_id, int product_id);
 
482
 static int             get_device_id(usb_printer_t *printer, char *buffer,
 
483
                                      size_t bufsize);
 
484
 static int             list_cb(usb_printer_t *printer, const char *device_uri,
 
485
                                const char *device_id, const void *data);
 
486
+static void            load_quirks(void);
 
487
 static char            *make_device_uri(usb_printer_t *printer,
 
488
                                         const char *device_id,
 
489
                                         char *uri, size_t uri_size);
 
490
 static int             open_device(usb_printer_t *printer, int verbose);
 
491
 static int             print_cb(usb_printer_t *printer, const char *device_uri,
 
492
                                 const char *device_id, const void *data);
 
493
-static int             printer_class_soft_reset(usb_printer_t *printer);
 
494
-static unsigned int    quirks(int vendor, int product);
 
495
 static void            *read_thread(void *reference);
 
496
 static void            *sidechannel_thread(void *reference);
 
497
 static void            soft_reset(void);
 
498
+static int             soft_reset_printer(usb_printer_t *printer);
 
499
 
 
500
 
 
501
 /*
 
502
@@ -274,6 +177,8 @@
 
503
 void
 
504
 list_devices(void)
 
505
 {
 
506
+  load_quirks();
 
507
+
 
508
   fputs("DEBUG: list_devices\n", stderr);
 
509
   find_device(list_cb, NULL);
 
510
 }
 
511
@@ -316,6 +221,8 @@
 
512
   const char   *val;                   /* Option value */
 
513
 
 
514
 
 
515
+  load_quirks();
 
516
+
 
517
  /*
 
518
   * See if the side-channel descriptor is valid...
 
519
   */
 
520
@@ -341,9 +248,9 @@
 
521
 
 
522
  /*
 
523
   * Some devices need a reset after finishing a job, these devices are
 
524
-  * marked with the USBLP_QUIRK_RESET quirk.
 
525
+  * marked with the USB_QUIRK_SOFT_RESET quirk.
 
526
   */
 
527
-  g.printer->reset_after_job = (g.printer->quirks & USBLP_QUIRK_RESET ? 1 : 0);
 
528
+  g.printer->reset_after_job = (g.printer->quirks & USB_QUIRK_SOFT_RESET ? 1 : 0);
 
529
 
 
530
  /*
 
531
   * If we are printing data from a print driver on stdin, ignore SIGTERM
 
532
@@ -760,7 +667,7 @@
 
533
   * Clean up ....
 
534
   */
 
535
 
 
536
-  libusb_free_device_list(list, 1);
 
537
+  libusb_free_device_list(all_list, 1);
 
538
   libusb_exit(NULL);
 
539
 
 
540
   return (status);
 
541
@@ -880,6 +787,23 @@
 
542
 
 
543
 
 
544
 /*
 
545
+ * 'compare_quirks()' - Compare two quirks entries.
 
546
+ */
 
547
+
 
548
+static int                             /* O - Result of comparison */
 
549
+compare_quirks(usb_quirk_t *a,         /* I - First quirk entry */
 
550
+               usb_quirk_t *b)         /* I - Second quirk entry */
 
551
+{
 
552
+  int result;                          /* Result of comparison */
 
553
+
 
554
+  if ((result = b->vendor_id - a->vendor_id) == 0)
 
555
+    result = b->product_id - a->product_id;
 
556
+
 
557
+  return (result);
 
558
+}
 
559
+
 
560
+
 
561
+/*
 
562
  * 'find_device()' - Find or enumerate USB printers.
 
563
  */
 
564
 
 
565
@@ -923,7 +847,7 @@
 
566
   if (err)
 
567
   {
 
568
     fprintf(stderr, "DEBUG: Unable to initialize USB access via libusb, "
 
569
-                    "libusb error %i\n", err);
 
570
+                    "libusb error %i\n", (int)err);
 
571
     return (NULL);
 
572
   }
 
573
 
 
574
@@ -951,13 +875,13 @@
 
575
           !devdesc.idProduct)
 
576
        continue;
 
577
 
 
578
-      printer.quirks = quirks(devdesc.idVendor, devdesc.idProduct);
 
579
+      printer.quirks = find_quirks(devdesc.idVendor, devdesc.idProduct);
 
580
 
 
581
      /*
 
582
       * Ignore blacklisted printers...
 
583
       */
 
584
 
 
585
-      if (printer.quirks & USBLP_QUIRK_BLACKLIST)
 
586
+      if (printer.quirks & USB_QUIRK_BLACKLIST)
 
587
         continue;
 
588
 
 
589
       for (conf = 0; conf < devdesc.bNumConfigurations; conf ++)
 
590
@@ -986,13 +910,13 @@
 
591
 
 
592
            if (((altptr->bInterfaceClass != LIBUSB_CLASS_PRINTER ||
 
593
                  altptr->bInterfaceSubClass != 1) &&
 
594
-                ((printer.quirks & USBLP_QUIRK_BAD_CLASS) == 0)) ||
 
595
+                ((printer.quirks & USB_QUIRK_VENDOR_CLASS) == 0)) ||
 
596
                (altptr->bInterfaceProtocol != 1 &&     /* Unidirectional */
 
597
                 altptr->bInterfaceProtocol != 2) ||    /* Bidirectional */
 
598
                altptr->bInterfaceProtocol < protocol)
 
599
              continue;
 
600
 
 
601
-           if (printer.quirks & USBLP_QUIRK_BAD_CLASS)
 
602
+           if (printer.quirks & USB_QUIRK_VENDOR_CLASS)
 
603
              fprintf(stderr, "DEBUG: Printer does not report class 7 and/or "
 
604
                      "subclass 1 but works as a printer anyway\n");
 
605
 
 
606
@@ -1049,7 +973,7 @@
 
607
              {
 
608
                fprintf(stderr, "DEBUG: Device protocol: %d\n",
 
609
                        printer.protocol);
 
610
-               if (printer.quirks & USBLP_QUIRK_BIDIR)
 
611
+               if (printer.quirks & USB_QUIRK_UNIDIR)
 
612
                {
 
613
                  printer.read_endp = -1;
 
614
                  fprintf(stderr, "DEBUG: Printer reports bi-di support "
 
615
@@ -1069,7 +993,7 @@
 
616
                                           altsetting[printer.altset].
 
617
                                           endpoint[printer.write_endp].
 
618
                                           bEndpointAddress;
 
619
-               if (printer.quirks & USBLP_QUIRK_NO_REATTACH)
 
620
+               if (printer.quirks & USB_QUIRK_NO_REATTACH)
 
621
                {
 
622
                  printer.usblp_attached = 0;
 
623
                  fprintf(stderr, "DEBUG: Printer does not like usblp "
 
624
@@ -1105,6 +1029,35 @@
 
625
 
 
626
 
 
627
 /*
 
628
+ * 'find_quirks()' - Find the quirks for the given printer, if any.
 
629
+ *
 
630
+ * First looks for an exact match, then looks for the vendor ID wildcard match.
 
631
+ */
 
632
+
 
633
+static unsigned                                /* O - Quirks flags */
 
634
+find_quirks(int vendor_id,             /* I - Vendor ID */
 
635
+            int product_id)            /* I - Product ID */
 
636
+{
 
637
+  usb_quirk_t  key,                    /* Search key */
 
638
+               *match;                 /* Matching quirk entry */
 
639
+
 
640
+
 
641
+  key.vendor_id  = vendor_id;
 
642
+  key.product_id = product_id;
 
643
+
 
644
+  if ((match = cupsArrayFind(all_quirks, &key)) != NULL)
 
645
+    return (match->quirks);
 
646
+
 
647
+  key.product_id = 0;
 
648
+
 
649
+  if ((match = cupsArrayFind(all_quirks, &key)) != NULL)
 
650
+    return (match->quirks);
 
651
+
 
652
+  return (USB_QUIRK_WHITELIST);
 
653
+}
 
654
+
 
655
+
 
656
+/*
 
657
  * 'get_device_id()' - Get the IEEE-1284 device ID for the printer.
 
658
  */
 
659
 
 
660
@@ -1210,6 +1163,104 @@
 
661
 
 
662
 
 
663
 /*
 
664
+ * 'load_quirks()' - Load all quirks files in the /usr/share/cups/usb directory.
 
665
+ */
 
666
+
 
667
+static void
 
668
+load_quirks(void)
 
669
+{
 
670
+  const char   *datadir;               /* CUPS_DATADIR environment variable */
 
671
+  char         filename[1024],         /* Filename */
 
672
+               line[1024];             /* Line from file */
 
673
+  cups_dir_t   *dir;                   /* Directory */
 
674
+  cups_dentry_t        *dent;                  /* Directory entry */
 
675
+  cups_file_t  *fp;                    /* Quirks file */
 
676
+  usb_quirk_t  *quirk;                 /* New quirk */
 
677
+
 
678
+
 
679
+  all_quirks = cupsArrayNew((cups_array_func_t)compare_quirks, NULL);
 
680
+
 
681
+  if ((datadir = getenv("CUPS_DATADIR")) == NULL)
 
682
+    datadir = CUPS_DATADIR;
 
683
+
 
684
+  snprintf(filename, sizeof(filename), "%s/usb", datadir);
 
685
+  if ((dir = cupsDirOpen(filename)) == NULL)
 
686
+  {
 
687
+    perror(filename);
 
688
+    return;
 
689
+  }
 
690
+
 
691
+  fprintf(stderr, "DEBUG: Loading USB quirks from \"%s\".\n", filename);
 
692
+
 
693
+  while ((dent = cupsDirRead(dir)) != NULL)
 
694
+  {
 
695
+    if (!S_ISREG(dent->fileinfo.st_mode))
 
696
+      continue;
 
697
+
 
698
+    snprintf(filename, sizeof(filename), "%s/usb/%s", datadir, dent->filename);
 
699
+    if ((fp = cupsFileOpen(filename, "r")) == NULL)
 
700
+    {
 
701
+      perror(filename);
 
702
+      continue;
 
703
+    }
 
704
+
 
705
+    while (cupsFileGets(fp, line, sizeof(line)))
 
706
+    {
 
707
+     /*
 
708
+      * Skip blank and comment lines...
 
709
+      */
 
710
+
 
711
+      if (line[0] == '#' || !line[0])
 
712
+        continue;
 
713
+
 
714
+     /*
 
715
+      * Add a quirk...
 
716
+      */
 
717
+
 
718
+      if ((quirk = calloc(1, sizeof(usb_quirk_t))) == NULL)
 
719
+      {
 
720
+        perror("DEBUG: Unable to allocate memory for quirk");
 
721
+        break;
 
722
+      }
 
723
+
 
724
+      if (sscanf(line, "%x%x", &quirk->vendor_id, &quirk->product_id) < 1)
 
725
+      {
 
726
+        fprintf(stderr, "DEBUG: Bad line: %s\n", line);
 
727
+        free(quirk);
 
728
+        continue;
 
729
+      }
 
730
+
 
731
+      if (strstr(line, " blacklist"))
 
732
+        quirk->quirks |= USB_QUIRK_BLACKLIST;
 
733
+
 
734
+      if (strstr(line, " no-reattach"))
 
735
+        quirk->quirks |= USB_QUIRK_NO_REATTACH;
 
736
+
 
737
+      if (strstr(line, " soft-reset"))
 
738
+        quirk->quirks |= USB_QUIRK_SOFT_RESET;
 
739
+
 
740
+      if (strstr(line, " unidir"))
 
741
+        quirk->quirks |= USB_QUIRK_UNIDIR;
 
742
+
 
743
+      if (strstr(line, " usb-init"))
 
744
+        quirk->quirks |= USB_QUIRK_USB_INIT;
 
745
+
 
746
+      if (strstr(line, " vendor-class"))
 
747
+        quirk->quirks |= USB_QUIRK_VENDOR_CLASS;
 
748
+
 
749
+      cupsArrayAdd(all_quirks, quirk);
 
750
+    }
 
751
+
 
752
+    cupsFileClose(fp);
 
753
+  }
 
754
+
 
755
+  fprintf(stderr, "DEBUG: Loaded %d quirks.\n", cupsArrayCount(all_quirks));
 
756
+
 
757
+  cupsDirClose(dir);
 
758
+}
 
759
+
 
760
+
 
761
+/*
 
762
  * 'make_device_uri()' - Create a device URI for a USB printer.
 
763
  */
 
764
 
 
765
@@ -1636,65 +1687,6 @@
 
766
 
 
767
 
 
768
 /*
 
769
- * 'printer_class_soft_reset()' - Do the soft reset request specific to printers
 
770
- *
 
771
- * This soft reset is specific to the printer device class and is much less
 
772
- * invasive than the general USB reset libusb_reset_device(). Especially it
 
773
- * does never happen that the USB addressing and configuration changes. What
 
774
- * is actually done is that all buffers get flushed and the bulk IN and OUT
 
775
- * pipes get reset to their default states. This clears all stall conditions.
 
776
- * See http://cholla.mmto.org/computers/linux/usb/usbprint11.pdf
 
777
- */
 
778
-
 
779
-static int                             /* O - 0 on success, < 0 on error */
 
780
-printer_class_soft_reset(usb_printer_t *printer) /* I - Printer */
 
781
-{
 
782
-  struct libusb_config_descriptor *confptr = NULL;
 
783
-                                        /* Pointer to current configuration */
 
784
-  int interface,
 
785
-      errcode;
 
786
-
 
787
-  if (libusb_get_config_descriptor(printer->device, printer->conf, &confptr)
 
788
-      < 0)
 
789
-    interface = printer->iface;
 
790
-  else
 
791
-    interface = confptr->interface[printer->iface].
 
792
-      altsetting[printer->altset].bInterfaceNumber;
 
793
-  libusb_free_config_descriptor(confptr);
 
794
-  if ((errcode = libusb_control_transfer(printer->handle,
 
795
-                                        LIBUSB_REQUEST_TYPE_CLASS |
 
796
-                                        LIBUSB_ENDPOINT_OUT |
 
797
-                                        LIBUSB_RECIPIENT_OTHER,
 
798
-                                        2, 0, interface, NULL, 0, 5000)) < 0)
 
799
-    errcode = libusb_control_transfer(printer->handle,
 
800
-                                     LIBUSB_REQUEST_TYPE_CLASS |
 
801
-                                     LIBUSB_ENDPOINT_OUT |
 
802
-                                     LIBUSB_RECIPIENT_INTERFACE,
 
803
-                                     2, 0, interface, NULL, 0, 5000);
 
804
-  return errcode;
 
805
-}
 
806
-
 
807
-
 
808
-/*
 
809
- * 'quirks()' - Get the known quirks of a given printer model
 
810
- */
 
811
-
 
812
-static unsigned int quirks(int vendor, int product)
 
813
-{
 
814
-  int i;
 
815
-
 
816
-  for (i = 0; quirk_printers[i].vendorId; i++)
 
817
-  {
 
818
-    if (vendor == quirk_printers[i].vendorId &&
 
819
-       (quirk_printers[i].productId == 0x0000 ||
 
820
-        product == quirk_printers[i].productId))
 
821
-      return quirk_printers[i].quirks;
 
822
-  }
 
823
-  return 0;
 
824
-}
 
825
-
 
826
-
 
827
-/*
 
828
  * 'read_thread()' - Thread to read the backchannel data on.
 
829
  */
 
830
 
 
831
@@ -1917,13 +1909,15 @@
 
832
  * 'soft_reset()' - Send a soft reset to the device.
 
833
  */
 
834
 
 
835
-static void soft_reset(void)
 
836
+static void
 
837
+soft_reset(void)
 
838
 {
 
839
   fd_set         input_set;            /* Input set for select() */
 
840
   struct timeval  tv;                  /* Time value */
 
841
   char           buffer[2048];         /* Buffer */
 
842
   struct timespec cond_timeout;                /* pthread condition timeout */
 
843
 
 
844
+
 
845
  /*
 
846
   * Send an abort once a second until the I/O lock is released by the main
 
847
   * thread...
 
848
@@ -1968,7 +1962,7 @@
 
849
   * Send the reset...
 
850
   */
 
851
 
 
852
-  printer_class_soft_reset(g.printer);
 
853
+  soft_reset_printer(g.printer);
 
854
 
 
855
  /*
 
856
   * Release the I/O lock...
 
857
@@ -1981,6 +1975,51 @@
 
858
 }
 
859
 
 
860
 
 
861
+/*
 
862
+ * 'soft_reset_printer()' - Do the soft reset request specific to printers
 
863
+ *
 
864
+ * This soft reset is specific to the printer device class and is much less
 
865
+ * invasive than the general USB reset libusb_reset_device(). Especially it
 
866
+ * does never happen that the USB addressing and configuration changes. What
 
867
+ * is actually done is that all buffers get flushed and the bulk IN and OUT
 
868
+ * pipes get reset to their default states. This clears all stall conditions.
 
869
+ * See http://cholla.mmto.org/computers/linux/usb/usbprint11.pdf
 
870
+ */
 
871
+
 
872
+static int                             /* O - 0 on success, < 0 on error */
 
873
+soft_reset_printer(
 
874
+    usb_printer_t *printer)            /* I - Printer */
 
875
+{
 
876
+  struct libusb_config_descriptor *confptr = NULL;
 
877
+                                        /* Pointer to current configuration */
 
878
+  int interface,                       /* Interface to reset */
 
879
+      errcode;                         /* Error code */
 
880
+
 
881
+
 
882
+  if (libusb_get_config_descriptor(printer->device, printer->conf,
 
883
+                                   &confptr) < 0)
 
884
+    interface = printer->iface;
 
885
+  else
 
886
+    interface = confptr->interface[printer->iface].
 
887
+                         altsetting[printer->altset].bInterfaceNumber;
 
888
+
 
889
+  libusb_free_config_descriptor(confptr);
 
890
+
 
891
+  if ((errcode = libusb_control_transfer(printer->handle,
 
892
+                                        LIBUSB_REQUEST_TYPE_CLASS |
 
893
+                                        LIBUSB_ENDPOINT_OUT |
 
894
+                                        LIBUSB_RECIPIENT_OTHER,
 
895
+                                        2, 0, interface, NULL, 0, 5000)) < 0)
 
896
+    errcode = libusb_control_transfer(printer->handle,
 
897
+                                     LIBUSB_REQUEST_TYPE_CLASS |
 
898
+                                     LIBUSB_ENDPOINT_OUT |
 
899
+                                     LIBUSB_RECIPIENT_INTERFACE,
 
900
+                                     2, 0, interface, NULL, 0, 5000);
 
901
+
 
902
+  return (errcode);
 
903
+}
 
904
+
 
905
+
 
906
 /*
 
907
  * End of "$Id: usb-libusb.c 10977 2013-05-13 16:46:08Z msweet $".
 
908
  */
 
909
--- a/conf/cups-files.conf.in
 
910
+++ b/conf/cups-files.conf.in
 
911
@@ -8,6 +8,9 @@
 
912
 # List of events that are considered fatal errors for the scheduler...
 
913
 #FatalErrors @CUPS_FATAL_ERRORS@
 
914
 
 
915
+# Do we call fsync() after writing configuration or status files?
 
916
+#SyncOnClose No
 
917
+
 
918
 # Default user and group for filters/backends/helper programs; this cannot be
 
919
 # any user or group that resolves to ID 0 for security reasons...
 
920
 #User @CUPS_USER@
 
921
--- a/config-scripts/cups-common.m4
 
922
+++ b/config-scripts/cups-common.m4
 
923
@@ -225,7 +225,9 @@
 
924
 AC_ARG_ENABLE(libusb, [  --enable-libusb         use libusb for USB printing])
 
925
 
 
926
 LIBUSB=""
 
927
+USBQUIRKS=""
 
928
 AC_SUBST(LIBUSB)
 
929
+AC_SUBST(USBQUIRKS)
 
930
 
 
931
 if test "x$PKGCONFIG" != x; then
 
932
        if test x$enable_libusb = xyes -o $uname != Darwin; then
 
933
@@ -235,6 +237,7 @@
 
934
                        AC_DEFINE(HAVE_LIBUSB)
 
935
                        CFLAGS="$CFLAGS `$PKGCONFIG --cflags libusb-1.0`"
 
936
                        LIBUSB="`$PKGCONFIG --libs libusb-1.0`"
 
937
+                       USBQUIRKS="\$(DATADIR)/usb"
 
938
                else
 
939
                        AC_MSG_RESULT(no)
 
940
                fi
 
941
--- a/configure
 
942
+++ b/configure
 
943
@@ -727,6 +727,7 @@
 
944
 LIBZ
 
945
 INSTALL_GZIP
 
946
 LIBWRAP
 
947
+USBQUIRKS
 
948
 LIBUSB
 
949
 LIBMXML
 
950
 EGREP
 
951
@@ -5232,6 +5233,8 @@
 
952
 
 
953
 
 
954
 LIBUSB=""
 
955
+USBQUIRKS=""
 
956
+
 
957
 
 
958
 
 
959
 if test "x$PKGCONFIG" != x; then
 
960
@@ -5245,6 +5248,7 @@
 
961
 
 
962
                        CFLAGS="$CFLAGS `$PKGCONFIG --cflags libusb-1.0`"
 
963
                        LIBUSB="`$PKGCONFIG --libs libusb-1.0`"
 
964
+                       USBQUIRKS="\$(DATADIR)/usb"
 
965
                else
 
966
                        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 
967
 $as_echo "no" >&6; }
 
968
--- a/cups/pwg-media.c
 
969
+++ b/cups/pwg-media.c
 
970
@@ -233,13 +233,11 @@
 
971
   _PWG_MEDIA_MM("prc_4_110x208mm", NULL, "EnvPRC4", 110, 208),
 
972
   _PWG_MEDIA_MM("prc_8_120x309mm", NULL, "EnvPRC8", 120, 309),
 
973
   _PWG_MEDIA_MM("prc_6_120x320mm", NULL, NULL, 120, 320),
 
974
-  _PWG_MEDIA_MM("prc_3_125x176mm", NULL, "EnvPRC3", 125, 176),
 
975
   _PWG_MEDIA_MM("prc_16k_146x215mm", NULL, "PRC16K", 146, 215),
 
976
   _PWG_MEDIA_MM("prc_7_160x230mm", NULL, "EnvPRC7", 160, 230),
 
977
   _PWG_MEDIA_MM("om_juuro-ku-kai_198x275mm", NULL, NULL, 198, 275),
 
978
   _PWG_MEDIA_MM("om_pa-kai_267x389mm", NULL, NULL, 267, 389),
 
979
   _PWG_MEDIA_MM("om_dai-pa-kai_275x395mm", NULL, NULL, 275, 395),
 
980
-  _PWG_MEDIA_MM("prc_10_324x458mm", NULL, "EnvPRC10", 324, 458),
 
981
 
 
982
   /* Chinese Standard Sheet Media Inch Sizes */
 
983
   _PWG_MEDIA_IN("roc_16k_7.75x10.75in", NULL, "roc16k", 7.75, 10.75),
 
984
@@ -251,7 +249,6 @@
 
985
   /* Other Metric Standard Sheet Media Sizes */
 
986
   _PWG_MEDIA_MM("om_small-photo_100x150mm", NULL, "om_small-photo", 100, 150),
 
987
   _PWG_MEDIA_MM("om_italian_110x230mm", NULL, "EnvItalian", 110, 230),
 
988
-  _PWG_MEDIA_MM("om_postfix_114x229mm", NULL, NULL, 114, 229),
 
989
   _PWG_MEDIA_MM("om_large-photo_200x300", NULL, "om_large-photo", 200, 300),
 
990
   _PWG_MEDIA_MM("om_folio_210x330mm", "folio", "Folio", 210, 330),
 
991
   _PWG_MEDIA_MM("om_folio-sp_215x315mm", NULL, "FolioSP", 215, 315),
 
992
--- a/cups/request.c
 
993
+++ b/cups/request.c
 
994
@@ -1018,13 +1018,14 @@
 
995
       */
 
996
 
 
997
       char ch;                         /* Connection check byte */
 
998
+      ssize_t  n;                      /* Number of bytes */
 
999
 
 
1000
 #ifdef WIN32
 
1001
-      if (recv(cg->http->fd, &ch, 1, MSG_PEEK) < 0 &&
 
1002
-          WSAGetLastError() != WSAEWOULDBLOCK)
 
1003
+      if ((n = recv(cg->http->fd, &ch, 1, MSG_PEEK)) == 0 ||
 
1004
+          (n < 0 && WSAGetLastError() != WSAEWOULDBLOCK))
 
1005
 #else
 
1006
-      if (recv(cg->http->fd, &ch, 1, MSG_PEEK | MSG_DONTWAIT) < 0 &&
 
1007
-          errno != EWOULDBLOCK)
 
1008
+      if ((n = recv(cg->http->fd, &ch, 1, MSG_PEEK | MSG_DONTWAIT)) == 0 ||
 
1009
+          (n < 0 && errno != EWOULDBLOCK))
 
1010
 #endif /* WIN32 */
 
1011
       {
 
1012
        /*
 
1013
--- a/doc/help/ref-cups-files-conf.html.in
 
1014
+++ b/doc/help/ref-cups-files-conf.html.in
 
1015
@@ -429,6 +429,31 @@
 
1016
 default server directory is <VAR>/etc/cups</VAR>.</P>
 
1017
 
 
1018
 
 
1019
+<H2 CLASS="title"><SPAN CLASS="info">CUPS 1.6.4</SPAN><A NAME="SyncOnClose">SyncOnClose</A></H2>
 
1020
+
 
1021
+<H3>Examples</H3>
 
1022
+
 
1023
+<PRE CLASS="command">
 
1024
+SyncOnClose No
 
1025
+SyncOnClose Yes
 
1026
+</PRE>
 
1027
+
 
1028
+<H3>Description</H3>
 
1029
+
 
1030
+<P>The <CODE>SyncOnClose</CODE> directive determines whether the scheduler
 
1031
+flushes changes to configuration and state files to disk. The default is
 
1032
+<CODE>No</CODE> which relies on the operating system to schedule a suitable
 
1033
+time to write changes to disk.</P>
 
1034
+
 
1035
+<BLOCKQUOTE><B>Note:</B>
 
1036
+
 
1037
+<P>Setting <CODE>SyncOnClose</CODE> to <CODE>Yes</CODE> makes the scheduler use the <CODE>fsync(2)</CODE> system call to write all changes to disk, however the drive or network file system server may still delay writing data to disk. Do not depend on this functionality to prevent data loss in the event of unexpected hardware failure.</P>
 
1038
+
 
1039
+<P>Enabling <CODE>SyncOnClose</CODE> may also cause the scheduler to periodically become unresponsive while it waits for changes to be written.</P>
 
1040
+
 
1041
+</BLOCKQUOTE>
 
1042
+
 
1043
+
 
1044
 <H2 CLASS="title"><A NAME="SystemGroup">SystemGroup</A></H2>
 
1045
 
 
1046
 <H3>Examples</H3>
 
1047
--- a/man/cups-files.conf.man.in
 
1048
+++ b/man/cups-files.conf.man.in
 
1049
@@ -12,7 +12,7 @@
 
1050
 .\"   which should have been included with this file.  If this file is
 
1051
 .\"   file is missing or damaged, see the license at "http://www.cups.org/".
 
1052
 .\"
 
1053
-.TH cups-files.conf 5 "CUPS" "8 July 2013" "Apple Inc."
 
1054
+.TH cups-files.conf 5 "CUPS" "26 July 2013" "Apple Inc."
 
1055
 .SH NAME
 
1056
 cups-files.conf \- file and directory configuration file for cups
 
1057
 .SH DESCRIPTION
 
1058
@@ -122,6 +122,12 @@
 
1059
 .br
 
1060
 Specifies the directory where the server configuration files can be found.
 
1061
 .TP 5
 
1062
+SyncOnClose Yes
 
1063
+.TP 5
 
1064
+SyncOnClose No
 
1065
+Specifies whether the scheduler calls \fIfsync(2)\fR after writing configuration
 
1066
+or state files. The default is No.
 
1067
+.TP 5
 
1068
 SystemGroup group-name [group-name ...]
 
1069
 .br
 
1070
 Specifies the group(s) to use for System class authentication.
 
1071
--- a/packaging/cups.spec
 
1072
+++ b/packaging/cups.spec
 
1073
@@ -222,6 +222,9 @@
 
1074
 /usr/share/cups/ppdc/*
 
1075
 %dir /usr/share/cups/templates
 
1076
 /usr/share/cups/templates/*
 
1077
+%dir /usr/share/cups/usb
 
1078
+/usr/share/cups/usb/*
 
1079
+
 
1080
 %dir /usr/share/doc/cups
 
1081
 /usr/share/doc/cups/*.*
 
1082
 %dir /usr/share/doc/cups/help
 
1083
--- a/packaging/cups.spec.in
 
1084
+++ b/packaging/cups.spec.in
 
1085
@@ -222,6 +222,9 @@
 
1086
 /usr/share/cups/ppdc/*
 
1087
 %dir /usr/share/cups/templates
 
1088
 /usr/share/cups/templates/*
 
1089
+%dir /usr/share/cups/usb
 
1090
+/usr/share/cups/usb/*
 
1091
+
 
1092
 %dir /usr/share/doc/cups
 
1093
 /usr/share/doc/cups/*.*
 
1094
 %dir /usr/share/doc/cups/help
 
1095
--- a/scheduler/colorman.c
 
1096
+++ b/scheduler/colorman.c
 
1097
@@ -103,11 +103,10 @@
 
1098
 #  define COLORD_KIND_PRINTER  "printer"
 
1099
                                        /* printing output device */
 
1100
 
 
1101
-#  define COLORD_DBUS_MSG(p,m) dbus_message_new_method_call(\
 
1102
-                                       "org.freedesktop.ColorManager", (p),\
 
1103
-                                        "org.freedesktop.ColorManager", (m))
 
1104
-                                        /* Macro to make new colord messages */
 
1105
-#  define COLORD_DBUS_PATH     "/org/freedesktop/ColorManager"
 
1106
+#  define COLORD_DBUS_SERVICE          "org.freedesktop.ColorManager"
 
1107
+#  define COLORD_DBUS_INTERFACE        "org.freedesktop.ColorManager"
 
1108
+#  define COLORD_DBUS_INTERFACE_DEVICE "org.freedesktop.ColorManager.Device"
 
1109
+#  define COLORD_DBUS_PATH             "/org/freedesktop/ColorManager"
 
1110
                                        /* Path for color management system */
 
1111
 #  define COLORD_DBUS_TIMEOUT  5000    /* Timeout for connecting to colord in ms */
 
1112
 #endif /* __APPLE__ */
 
1113
@@ -939,7 +938,10 @@
 
1114
   snprintf(device_id, sizeof(device_id), "cups-%s", p->name);
 
1115
   device_path = device_id;
 
1116
 
 
1117
-  message = COLORD_DBUS_MSG(COLORD_DBUS_PATH, "CreateDevice");
 
1118
+  message = dbus_message_new_method_call(COLORD_DBUS_SERVICE,
 
1119
+                                         COLORD_DBUS_PATH,
 
1120
+                                         COLORD_DBUS_INTERFACE,
 
1121
+                                         "CreateDevice");
 
1122
 
 
1123
   dbus_message_iter_init_append(message, &args);
 
1124
   dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &device_path);
 
1125
@@ -1048,7 +1050,10 @@
 
1126
   * Create the profile...
 
1127
   */
 
1128
 
 
1129
-  message = COLORD_DBUS_MSG(COLORD_DBUS_PATH, "CreateProfile");
 
1130
+  message = dbus_message_new_method_call(COLORD_DBUS_SERVICE,
 
1131
+                                         COLORD_DBUS_PATH,
 
1132
+                                         COLORD_DBUS_INTERFACE,
 
1133
+                                         "CreateProfile");
 
1134
 
 
1135
   idstrlen = strlen(printer_name) + 1 + strlen(qualifier) + 1;
 
1136
   if ((idstr = malloc(idstrlen)) == NULL)
 
1137
@@ -1144,7 +1149,10 @@
 
1138
   * Delete the device...
 
1139
   */
 
1140
 
 
1141
-  message = COLORD_DBUS_MSG(COLORD_DBUS_PATH, "DeleteDevice");
 
1142
+  message = dbus_message_new_method_call(COLORD_DBUS_SERVICE,
 
1143
+                                         COLORD_DBUS_PATH,
 
1144
+                                         COLORD_DBUS_INTERFACE,
 
1145
+                                         "DeleteDevice");
 
1146
 
 
1147
   dbus_message_iter_init_append(message, &args);
 
1148
   dbus_message_iter_append_basic(&args, DBUS_TYPE_OBJECT_PATH, &device_path);
 
1149
@@ -1196,7 +1204,10 @@
 
1150
   DBusError    error;                  /* D-Bus error */
 
1151
 
 
1152
 
 
1153
-  message = COLORD_DBUS_MSG(device_path, "AddProfile");
 
1154
+  message = dbus_message_new_method_call(COLORD_DBUS_SERVICE,
 
1155
+                                         device_path,
 
1156
+                                         COLORD_DBUS_INTERFACE_DEVICE,
 
1157
+                                         "AddProfile");
 
1158
 
 
1159
   dbus_message_iter_init_append(message, &args);
 
1160
   dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &relation);
 
1161
@@ -1266,7 +1277,10 @@
 
1162
   char         *device_path = NULL;    /* Device object path */
 
1163
 
 
1164
 
 
1165
-  message = COLORD_DBUS_MSG(COLORD_DBUS_PATH, "FindDeviceById");
 
1166
+  message = dbus_message_new_method_call(COLORD_DBUS_SERVICE,
 
1167
+                                         COLORD_DBUS_PATH,
 
1168
+                                         COLORD_DBUS_INTERFACE,
 
1169
+                                         "FindDeviceById");
 
1170
 
 
1171
   dbus_message_iter_init_append(message, &args);
 
1172
   dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &device_id);
 
1173
--- a/scheduler/conf.c
 
1174
+++ b/scheduler/conf.c
 
1175
@@ -174,6 +174,7 @@
 
1176
   { "ServerRoot",              &ServerRoot,            CUPSD_VARTYPE_PATHNAME },
 
1177
   { "SMBConfigFile",           &SMBConfigFile,         CUPSD_VARTYPE_STRING },
 
1178
   { "StateDir",                        &StateDir,              CUPSD_VARTYPE_STRING },
 
1179
+  { "SyncOnClose",             &SyncOnClose,           CUPSD_VARTYPE_BOOLEAN },
 
1180
 #ifdef HAVE_AUTHORIZATION_H
 
1181
   { "SystemGroupAuthKey",      &SystemGroupAuthKey,    CUPSD_VARTYPE_STRING },
 
1182
 #endif /* HAVE_AUTHORIZATION_H */
 
1183
@@ -734,6 +735,7 @@
 
1184
   ReloadTimeout                   = DEFAULT_KEEPALIVE;
 
1185
   RootCertDuration         = 300;
 
1186
   StrictConformance        = FALSE;
 
1187
+  SyncOnClose              = FALSE;
 
1188
   Timeout                  = DEFAULT_TIMEOUT;
 
1189
   WebInterface             = CUPS_DEFAULT_WEBIF;
 
1190
 
 
1191
--- a/scheduler/conf.h
 
1192
+++ b/scheduler/conf.h
 
1193
@@ -172,6 +172,8 @@
 
1194
                                        /* Which errors are fatal? */
 
1195
                        StrictConformance       VALUE(FALSE),
 
1196
                                        /* Require strict IPP conformance? */
 
1197
+                       SyncOnClose             VALUE(FALSE),
 
1198
+                                       /* Call fsync() when closing files? */
 
1199
                        LogFilePerm             VALUE(0644);
 
1200
                                        /* Permissions for log files */
 
1201
 VAR cupsd_loglevel_t   LogLevel                VALUE(CUPSD_LOG_WARN);
 
1202
--- a/scheduler/file.c
 
1203
+++ b/scheduler/file.c
 
1204
@@ -109,6 +109,29 @@
 
1205
 
 
1206
 
 
1207
  /*
 
1208
+  * Synchronize changes to disk if SyncOnClose is enabled.
 
1209
+  */
 
1210
+
 
1211
+  if (SyncOnClose)
 
1212
+  {
 
1213
+    if (cupsFileFlush(fp))
 
1214
+    {
 
1215
+      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to write changes to \"%s\": %s",
 
1216
+                     filename, strerror(errno));
 
1217
+      cupsFileClose(fp);
 
1218
+      return (-1);
 
1219
+    }
 
1220
+
 
1221
+    if (fsync(cupsFileNumber(fp)))
 
1222
+    {
 
1223
+      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to sync changes to \"%s\": %s",
 
1224
+                     filename, strerror(errno));
 
1225
+      cupsFileClose(fp);
 
1226
+      return (-1);
 
1227
+    }
 
1228
+  }
 
1229
+
 
1230
+ /*
 
1231
   * First close the file...
 
1232
   */
 
1233