~ubuntu-branches/ubuntu/oneiric/cups/oneiric-proposed

« back to all changes in this revision

Viewing changes to .pc/usb-backend-no-segfault-on-bad-device-id.patch/backend/ieee1284.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt, Till Kamppeter, Martin Pitt
  • Date: 2011-08-07 12:53:12 UTC
  • mfrom: (1.2.13 upstream)
  • Revision ID: james.westby@ubuntu.com-20110807125312-s323cyb3oqaxaemo
Tags: 1.5.0-1
[ Till Kamppeter ]
* New upstream release
* debian/patches/usb-backend-no-segfault-on-bad-device-id.patch,
  debian/patches/usb-backend-accept-old-usblp-uris.patch,
  debian/patches/use-ps2write-ghostscript-device-for-pdftops-filter.patch:
  Removed, included upstream.
* debian/patches/poppler-based-pdftops-fixes.patch,
  debian/patches/do-not-emit-ps-level-3-with-poppler.patch: Replaced patch
  by a new one only containing the parts which remain after removing the
  parts included upstream.
* debian/patches/pidfile.patch,
  debian/patches/ppd-poll-with-client-conf.patch,
  debian/patches/cups-avahi.patch,
  debian/patches/drop_unnecessary_dependencies.patch,
  debian/patches/do-not-broadcast-with-hostnames.patch,
  debian/patches/ppdc-dynamic-linking.patch,
  debian/patches/pstops-based-workflow-only-for-printing-ps-on-a-ps-printer.patch:
  Manually regenerated to adapt to upstream changes.
* debian/patches/manpage-translations.patch,
  debian/patches/rootbackends-worldreadable.patch,
  debian/patches/no-conffile-timestamp.patch,
  debian/patches/read-embedded-options-from-incoming-postscript-and-add-to-ipp-attrs.patch,
  debian/patches/cups-snmp-oids-device-id-hp-ricoh.patch,
  debian/patches/configure-default-browse-protocols.patch,
  debian/patches/logfiles_adm_readable.patch,
  debian/patches/confdirperms.patch,
  debian/patches/printer-filtering.patch,
  debian/patches/show-compile-command-lines.patch,
  debian/patches/log-debug-history-nearly-unlimited.patch:
  Refreshed using quilt.
* debian/patches/default-ripcache-size-auto.patch: Dropped, as once,
  Ghostscript 9.04 is ignoring the cache size value as it crashes easily
  otherwise (Ghostscript upstream bug #691586) and second, CUPS defaults to
  more reasonable 128 MB (now only used for imagetops).
* debian/patches/support-gzipped-charmaps.patch: Dropped, as the SBCS and
  VBCS character maps are not used any more by CUPS.
* debian/rules: Enable threads in the ./configure command line, as otherwise
  CUPS 1.5.0 does not build at all.
* debian/local/filters/pdf-filters/filter/pdftoijs.cxx,
  debian/local/filters/pdf-filters/filter/pdftoraster.cxx,
  debian/local/filters/pdf-filters/pdftoopvp/pdftoopvp.cxx,
  debian/local/filters/pdf-filters/pdftopdf/pdftopdf.cxx: Under CUPS 1.5.x.
  all programs using the PPD API of CUPS need to explicitly include
  "<cups/ppd.h>". Updated the PDF filter add-on package.
* debian/local/filters/pdf-filters/addtocups: Make the addition of the
  pdftopdf and pdftoopvp directories also work with CUPS 1.5.x.
* debian/local/filters/pdf-filters/addtocups,
  debian/local/filters/pdf-filters/removefromcups: Added a symbolic link
  cups/i18n.h, so that texttopdf builds.
* debian/cups-client.install: Install the new ipptool and its sample
  files and manpages.
* debian/cups-client.install: Commented out lines for dropped man page
  translations: ipptool, lppasswd, client.conf, ipptoolfile, cupsenable,
  lpadmin, lpinfo, cupsreject, cupsdisable, cupsaccept
* debian/cups-common.install, debian/rules: The /usr/share/cups/charmaps
  directory got removed from CUPS.
* debian/libcups2-dev.install: cups/i18n.h got renamed to
  cups/language-private.h. Install this as /usr/include/cups/i18n.h.
* debian/libcups2.symbols, debian/libcupsmime1.symbols: Updated.
* debian/cups.lintian-overrides, debian/cups.postinst, debian/cups.prerm,
  debian/cups.templates, debian/local/apparmor-profile: The "scsi"
  CUPS backend got dropped upstream, removed its treatment from these files.

[ Martin Pitt ]
* Add Serbian (Cyrillic) debconf translations, thanks Zlatan Todoric.
  (Closes: #635105)
* Add Serbian (Latin) debconf translations, thanks Zlatan Todoric.
  (Closes: #635108)
* debian/local/apparmor-profile: Allow access to serial printers on USB
  adapters. (LP: #677432)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * "$Id: ieee1284.c 9098 2010-04-09 22:42:09Z mike $"
3
 
 *
4
 
 *   IEEE-1284 support functions for the Common UNIX Printing System (CUPS).
5
 
 *
6
 
 *   Copyright 2007-2009 by Apple Inc.
7
 
 *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
8
 
 *
9
 
 *   These coded instructions, statements, and computer programs are the
10
 
 *   property of Apple Inc. and are protected by Federal copyright
11
 
 *   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
12
 
 *   "LICENSE" which should have been included with this file.  If this
13
 
 *   file is missing or damaged, see the license at "http://www.cups.org/".
14
 
 *
15
 
 *   This file is subject to the Apple OS-Developed Software exception.
16
 
 *
17
 
 * Contents:
18
 
 *
19
 
 *   backendGetDeviceID()  - Get the IEEE-1284 device ID string and
20
 
 *                           corresponding URI.
21
 
 *   backendGetMakeModel() - Get the make and model string from the device ID.
22
 
 */
23
 
 
24
 
/*
25
 
 * Include necessary headers.
26
 
 */
27
 
 
28
 
#include "backend-private.h"
29
 
 
30
 
 
31
 
/*
32
 
 * 'backendGetDeviceID()' - Get the IEEE-1284 device ID string and
33
 
 *                          corresponding URI.
34
 
 */
35
 
 
36
 
int                                     /* O - 0 on success, -1 on failure */
37
 
backendGetDeviceID(
38
 
    int        fd,                      /* I - File descriptor */
39
 
    char       *device_id,              /* O - 1284 device ID */
40
 
    int        device_id_size,          /* I - Size of buffer */
41
 
    char       *make_model,             /* O - Make/model */
42
 
    int        make_model_size,         /* I - Size of buffer */
43
 
    const char *scheme,                 /* I - URI scheme */
44
 
    char       *uri,                    /* O - Device URI */
45
 
    int        uri_size)                /* I - Size of buffer */
46
 
{
47
 
#ifdef __APPLE__ /* This function is a no-op */
48
 
  return (-1);
49
 
 
50
 
#else /* Get the device ID from the specified file descriptor... */
51
 
#  ifdef __linux
52
 
  int   length;                         /* Length of device ID info */
53
 
  int   got_id = 0;
54
 
#  endif /* __linux */
55
 
#  if defined(__sun) && defined(ECPPIOC_GETDEVID)
56
 
  struct ecpp_device_id did;            /* Device ID buffer */
57
 
#  endif /* __sun && ECPPIOC_GETDEVID */
58
 
 
59
 
 
60
 
  DEBUG_printf(("backendGetDeviceID(fd=%d, device_id=%p, device_id_size=%d, "
61
 
                "make_model=%p, make_model_size=%d, scheme=\"%s\", "
62
 
                "uri=%p, uri_size=%d)\n", fd, device_id, device_id_size,
63
 
                make_model, make_model_size, scheme ? scheme : "(null)",
64
 
                uri, uri_size));
65
 
 
66
 
 /*
67
 
  * Range check input...
68
 
  */
69
 
 
70
 
  if (!device_id || device_id_size < 32)
71
 
  {
72
 
    DEBUG_puts("backendGetDeviceID: Bad args!");
73
 
    return (-1);
74
 
  }
75
 
 
76
 
  if (make_model)
77
 
    *make_model = '\0';
78
 
 
79
 
  if (fd >= 0)
80
 
  {
81
 
   /*
82
 
    * Get the device ID string...
83
 
    */
84
 
 
85
 
    *device_id = '\0';
86
 
 
87
 
#  ifdef __linux
88
 
    if (ioctl(fd, LPIOC_GET_DEVICE_ID(device_id_size), device_id))
89
 
    {
90
 
     /*
91
 
      * Linux has to implement things differently for every device it seems.
92
 
      * Since the standard parallel port driver does not provide a simple
93
 
      * ioctl() to get the 1284 device ID, we have to open the "raw" parallel
94
 
      * device corresponding to this port and do some negotiation trickery
95
 
      * to get the current device ID.
96
 
      */
97
 
 
98
 
      if (uri && !strncmp(uri, "parallel:/dev/", 14))
99
 
      {
100
 
        char    devparport[16];         /* /dev/parportN */
101
 
        int     devparportfd,           /* File descriptor for raw device */
102
 
                  mode;                 /* Port mode */
103
 
 
104
 
 
105
 
       /*
106
 
        * Since the Linux parallel backend only supports 4 parallel port
107
 
        * devices, just grab the trailing digit and use it to construct a
108
 
        * /dev/parportN filename...
109
 
        */
110
 
 
111
 
        snprintf(devparport, sizeof(devparport), "/dev/parport%s",
112
 
                 uri + strlen(uri) - 1);
113
 
 
114
 
        if ((devparportfd = open(devparport, O_RDWR | O_NOCTTY)) != -1)
115
 
        {
116
 
         /*
117
 
          * Claim the device...
118
 
          */
119
 
 
120
 
          if (!ioctl(devparportfd, PPCLAIM))
121
 
          {
122
 
            fcntl(devparportfd, F_SETFL, fcntl(devparportfd, F_GETFL) | O_NONBLOCK);
123
 
 
124
 
            mode = IEEE1284_MODE_COMPAT;
125
 
 
126
 
            if (!ioctl(devparportfd, PPNEGOT, &mode))
127
 
            {
128
 
             /*
129
 
              * Put the device into Device ID mode...
130
 
              */
131
 
 
132
 
              mode = IEEE1284_MODE_NIBBLE | IEEE1284_DEVICEID;
133
 
 
134
 
              if (!ioctl(devparportfd, PPNEGOT, &mode))
135
 
              {
136
 
               /*
137
 
                * Read the 1284 device ID...
138
 
                */
139
 
 
140
 
                if ((length = read(devparportfd, device_id,
141
 
                                   device_id_size - 1)) >= 2)
142
 
                {
143
 
                  device_id[length] = '\0';
144
 
                  got_id = 1;
145
 
                }
146
 
              }
147
 
            }
148
 
 
149
 
           /*
150
 
            * Release the device...
151
 
            */
152
 
 
153
 
            ioctl(devparportfd, PPRELEASE);
154
 
          }
155
 
 
156
 
          close(devparportfd);
157
 
        }
158
 
      }
159
 
    }
160
 
    else
161
 
      got_id = 1;
162
 
 
163
 
    if (got_id)
164
 
    {
165
 
     /*
166
 
      * Extract the length of the device ID string from the first two
167
 
      * bytes.  The 1284 spec says the length is stored MSB first...
168
 
      */
169
 
 
170
 
      length = (((unsigned)device_id[0] & 255) << 8) +
171
 
               ((unsigned)device_id[1] & 255);
172
 
 
173
 
     /*
174
 
      * Check to see if the length is larger than our buffer; first
175
 
      * assume that the vendor incorrectly implemented the 1284 spec,
176
 
      * and then limit the length to the size of our buffer...
177
 
      */
178
 
 
179
 
      if (length > device_id_size)
180
 
        length = (((unsigned)device_id[1] & 255) << 8) +
181
 
                 ((unsigned)device_id[0] & 255);
182
 
 
183
 
      if (length > device_id_size)
184
 
        length = device_id_size;
185
 
 
186
 
     /*
187
 
      * The length field counts the number of bytes in the string
188
 
      * including the length field itself (2 bytes).  The minimum
189
 
      * length for a valid/usable device ID is 14 bytes:
190
 
      *
191
 
      *     <LENGTH> MFG: <MFG> ;MDL: <MDL> ;
192
 
      *        2  +   4  +  1  +  5 +  1 +  1
193
 
      */
194
 
 
195
 
      if (length < 14)
196
 
      {
197
 
       /*
198
 
        * Can't use this device ID, so don't try to copy it...
199
 
        */
200
 
 
201
 
        device_id[0] = '\0';
202
 
        got_id       = 0;
203
 
      }
204
 
      else
205
 
      {
206
 
       /*
207
 
        * Copy the device ID text to the beginning of the buffer and
208
 
        * nul-terminate.
209
 
        */
210
 
 
211
 
        length -= 2;
212
 
 
213
 
        memmove(device_id, device_id + 2, length);
214
 
        device_id[length] = '\0';
215
 
      }
216
 
    }
217
 
#    ifdef DEBUG
218
 
    else
219
 
      DEBUG_printf(("backendGetDeviceID: ioctl failed - %s\n",
220
 
                    strerror(errno)));
221
 
#    endif /* DEBUG */
222
 
#  endif /* __linux */
223
 
 
224
 
#   if defined(__sun) && defined(ECPPIOC_GETDEVID)
225
 
    did.mode = ECPP_CENTRONICS;
226
 
    did.len  = device_id_size - 1;
227
 
    did.rlen = 0;
228
 
    did.addr = device_id;
229
 
 
230
 
    if (!ioctl(fd, ECPPIOC_GETDEVID, &did))
231
 
    {
232
 
     /*
233
 
      * Nul-terminate the device ID text.
234
 
      */
235
 
 
236
 
      if (did.rlen < (device_id_size - 1))
237
 
        device_id[did.rlen] = '\0';
238
 
      else
239
 
        device_id[device_id_size - 1] = '\0';
240
 
    }
241
 
#    ifdef DEBUG
242
 
    else
243
 
      DEBUG_printf(("backendGetDeviceID: ioctl failed - %s\n",
244
 
                    strerror(errno)));
245
 
#    endif /* DEBUG */
246
 
#  endif /* __sun && ECPPIOC_GETDEVID */
247
 
  }
248
 
 
249
 
  DEBUG_printf(("backendGetDeviceID: device_id=\"%s\"\n", device_id));
250
 
 
251
 
  if (scheme && uri)
252
 
    *uri = '\0';
253
 
 
254
 
  if (!*device_id)
255
 
    return (-1);
256
 
 
257
 
 /*
258
 
  * Get the make and model...
259
 
  */
260
 
 
261
 
  if (make_model)
262
 
    backendGetMakeModel(device_id, make_model, make_model_size);
263
 
 
264
 
 /*
265
 
  * Then generate a device URI...
266
 
  */
267
 
 
268
 
  if (scheme && uri && uri_size > 32)
269
 
  {
270
 
    int                 num_values;     /* Number of keys and values */
271
 
    cups_option_t       *values;        /* Keys and values in device ID */
272
 
    const char          *mfg,           /* Manufacturer */
273
 
                        *mdl,           /* Model */
274
 
                        *sern;          /* Serial number */
275
 
    char                temp[256],      /* Temporary manufacturer string */
276
 
                        *tempptr;       /* Pointer into temp string */
277
 
 
278
 
 
279
 
   /*
280
 
    * Get the make, model, and serial numbers...
281
 
    */
282
 
 
283
 
    num_values = _ppdGet1284Values(device_id, &values);
284
 
 
285
 
    if ((sern = cupsGetOption("SERIALNUMBER", num_values, values)) == NULL)
286
 
      if ((sern = cupsGetOption("SERN", num_values, values)) == NULL)
287
 
        sern = cupsGetOption("SN", num_values, values);
288
 
 
289
 
    if ((mfg = cupsGetOption("MANUFACTURER", num_values, values)) == NULL)
290
 
      mfg = cupsGetOption("MFG", num_values, values);
291
 
 
292
 
    if ((mdl = cupsGetOption("MODEL", num_values, values)) == NULL)
293
 
      mdl = cupsGetOption("MDL", num_values, values);
294
 
 
295
 
    if (mfg)
296
 
    {
297
 
      if (!strcasecmp(mfg, "Hewlett-Packard"))
298
 
        mfg = "HP";
299
 
      else if (!strcasecmp(mfg, "Lexmark International"))
300
 
        mfg = "Lexmark";
301
 
    }
302
 
    else
303
 
    {
304
 
      strlcpy(temp, make_model, sizeof(temp));
305
 
 
306
 
      if ((tempptr = strchr(temp, ' ')) != NULL)
307
 
        *tempptr = '\0';
308
 
 
309
 
      mfg = temp;
310
 
    }
311
 
 
312
 
    if (!mdl)
313
 
      mdl = "";
314
 
 
315
 
    if (!strncasecmp(mdl, mfg, strlen(mfg)))
316
 
    {
317
 
      mdl += strlen(mfg);
318
 
 
319
 
      while (isspace(*mdl & 255))
320
 
        mdl ++;
321
 
    }
322
 
 
323
 
   /*
324
 
    * Generate the device URI from the manufacturer, make_model, and
325
 
    * serial number strings.
326
 
    */
327
 
 
328
 
    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, uri_size, scheme, NULL, mfg, 0,
329
 
                     "/%s%s%s", mdl, sern ? "?serial=" : "", sern ? sern : "");
330
 
 
331
 
    cupsFreeOptions(num_values, values);
332
 
  }
333
 
 
334
 
  return (0);
335
 
#endif /* __APPLE__ */
336
 
}
337
 
 
338
 
 
339
 
/*
340
 
 * 'backendGetMakeModel()' - Get the make and model string from the device ID.
341
 
 */
342
 
 
343
 
int                                     /* O - 0 on success, -1 on failure */
344
 
backendGetMakeModel(
345
 
    const char *device_id,              /* O - 1284 device ID */
346
 
    char       *make_model,             /* O - Make/model */
347
 
    int        make_model_size)         /* I - Size of buffer */
348
 
{
349
 
  int           num_values;             /* Number of keys and values */
350
 
  cups_option_t *values;                /* Keys and values */
351
 
  const char    *mfg,                   /* Manufacturer string */
352
 
                *mdl,                   /* Model string */
353
 
                *des;                   /* Description string */
354
 
 
355
 
 
356
 
  DEBUG_printf(("backendGetMakeModel(device_id=\"%s\", "
357
 
                "make_model=%p, make_model_size=%d)\n", device_id,
358
 
                make_model, make_model_size));
359
 
 
360
 
 /*
361
 
  * Range check input...
362
 
  */
363
 
 
364
 
  if (!device_id || !*device_id || !make_model || make_model_size < 32)
365
 
  {
366
 
    DEBUG_puts("backendGetMakeModel: Bad args!");
367
 
    return (-1);
368
 
  }
369
 
 
370
 
  *make_model = '\0';
371
 
 
372
 
 /*
373
 
  * Look for the description field...
374
 
  */
375
 
 
376
 
  num_values = _ppdGet1284Values(device_id, &values);
377
 
 
378
 
  if ((mdl = cupsGetOption("MODEL", num_values, values)) == NULL)
379
 
    mdl = cupsGetOption("MDL", num_values, values);
380
 
 
381
 
  if (mdl)
382
 
  {
383
 
   /*
384
 
    * Build a make-model string from the manufacturer and model attributes...
385
 
    */
386
 
 
387
 
    if ((mfg = cupsGetOption("MANUFACTURER", num_values, values)) == NULL)
388
 
      mfg = cupsGetOption("MFG", num_values, values);
389
 
 
390
 
    if (!mfg || !strncasecmp(mdl, mfg, strlen(mfg)))
391
 
    {
392
 
     /*
393
 
      * Just copy the model string, since it has the manufacturer...
394
 
      */
395
 
 
396
 
      _ppdNormalizeMakeAndModel(mdl, make_model, make_model_size);
397
 
    }
398
 
    else
399
 
    {
400
 
     /*
401
 
      * Concatenate the make and model...
402
 
      */
403
 
 
404
 
      char      temp[1024];             /* Temporary make and model */
405
 
 
406
 
      if (mfg)
407
 
        snprintf(temp, sizeof(temp), "%s %s", mfg, mdl);
408
 
      else
409
 
        snprintf(temp, sizeof(temp), "%s", mdl);
410
 
 
411
 
      _ppdNormalizeMakeAndModel(temp, make_model, make_model_size);
412
 
    }
413
 
  }
414
 
  else if ((des = cupsGetOption("DESCRIPTION", num_values, values)) != NULL ||
415
 
           (des = cupsGetOption("DES", num_values, values)) != NULL)
416
 
  {
417
 
   /*
418
 
    * Make sure the description contains something useful, since some
419
 
    * printer manufacturers (HP) apparently don't follow the standards
420
 
    * they helped to define...
421
 
    *
422
 
    * Here we require the description to be 8 or more characters in length,
423
 
    * containing at least one space and one letter.
424
 
    */
425
 
 
426
 
    if (strlen(des) >= 8)
427
 
    {
428
 
      const char        *ptr;           /* Pointer into description */
429
 
      int               letters,        /* Number of letters seen */
430
 
                        spaces;         /* Number of spaces seen */
431
 
 
432
 
 
433
 
      for (ptr = des, letters = 0, spaces = 0; *ptr; ptr ++)
434
 
      {
435
 
        if (isspace(*ptr & 255))
436
 
          spaces ++;
437
 
        else if (isalpha(*ptr & 255))
438
 
          letters ++;
439
 
 
440
 
        if (spaces && letters)
441
 
          break;
442
 
      }
443
 
 
444
 
      if (spaces && letters)
445
 
        _ppdNormalizeMakeAndModel(des, make_model, make_model_size);
446
 
    }
447
 
  }
448
 
 
449
 
  if (!make_model[0])
450
 
  {
451
 
   /*
452
 
    * Use "Unknown" as the printer make and model...
453
 
    */
454
 
 
455
 
    strlcpy(make_model, "Unknown", make_model_size);
456
 
  }
457
 
 
458
 
  cupsFreeOptions(num_values, values);
459
 
 
460
 
  return (0);
461
 
}
462
 
 
463
 
 
464
 
/*
465
 
 * End of "$Id: ieee1284.c 9098 2010-04-09 22:42:09Z mike $".
466
 
 */