*
* This file is included from "usb.c" when compiled on UNIX/Linux.
*
- * Copyright 1997-2005 by Easy Software Products, all rights reserved.
+ * Copyright 2007 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
- * property of Easy Software Products and are protected by Federal
- * copyright law. Distribution and use rights are outlined in the file
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
* "LICENSE" which should have been included with this file. If this
- * file is missing or damaged please contact Easy Software Products
- * at:
- *
- * Attn: CUPS Licensing Information
- * Easy Software Products
- * 44141 Airport View Drive, Suite 204
- * Hollywood, Maryland 20636 USA
- *
- * Voice: (301) 373-9600
- * EMail: cups-info@cups.org
- * WWW: http://www.cups.org
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*
* Contents:
*
- * main() - Send a file to the specified USB port.
+ * print_device() - Print a file to a USB device.
* list_devices() - List all USB devices.
+ * open_device() - Open a USB device...
+ * side_cb() - Handle side-channel requests...
*/
/*
* Include necessary headers.
*/
-#ifdef __linux
-# include <sys/ioctl.h>
-# include <linux/lp.h>
-# define IOCNR_GET_DEVICE_ID 1
-
-/*
- * Get device_id string
- */
-# define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len)
-#endif /* __linux */
-
-#ifdef __sun
-# ifdef __sparc
-# include <sys/ecppio.h>
-# else
-# include <sys/ioccom.h>
-# include <sys/ecppsys.h>
-# endif /* __sparc */
-#endif /* __sun */
+#include "ieee1284.c"
+#include <sys/select.h>
/*
* Local functions...
*/
-void decode_device_id(int port, const char *device_id,
- char *make_model, int mmsize,
- char *uri, int urisize);
-int open_device(const char *uri);
+static int open_device(const char *uri, int *use_bc);
+static void side_cb(int print_fd, int device_fd, int use_bc);
/*
const char *hostname, /* I - Hostname/manufacturer */
const char *resource, /* I - Resource/modelname */
const char *options, /* I - Device options/serial number */
- int fp, /* I - File descriptor to print */
- int copies) /* I - Copies to print */
+ int print_fd, /* I - File descriptor to print */
+ int copies, /* I - Copies to print */
+ int argc, /* I - Number of command-line arguments (6 or 7) */
+ char *argv[]) /* I - Command-line arguments */
{
- int fd; /* USB device */
- int wbytes; /* Number of bytes written */
- size_t nbytes, /* Number of bytes read */
- tbytes; /* Total number of bytes written */
- char buffer[8192], /* Output buffer */
- *bufptr; /* Pointer into buffer */
+ int use_bc; /* Use backchannel path? */
+ int device_fd; /* USB device */
+ size_t tbytes; /* Total number of bytes written */
struct termios opts; /* Parallel port options */
-#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
- struct sigaction action; /* Actions for POSIX signals */
-#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
-#ifdef __linux
- unsigned int status; /* Port status (off-line, out-of-paper, etc.) */
-#endif /* __linux */
+ (void)argc;
+ (void)argv;
+
/*
* Open the USB port device...
*/
+ fputs("STATE: +connecting-to-device\n", stderr);
+
do
{
- if ((fd = open_device(uri)) == -1)
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
+ /*
+ * *BSD's ulpt driver currently does not support the
+ * back-channel, incorrectly returns data ready on a select(),
+ * and locks up on read()...
+ */
+
+ use_bc = 0;
+
+#else
+ /*
+ * Disable backchannel data when printing to Brother, Canon, or
+ * Minolta USB printers - apparently these printers will return
+ * the IEEE-1284 device ID over and over and over when they get
+ * a read request...
+ */
+
+ use_bc = strcasecmp(hostname, "Brother") &&
+ strcasecmp(hostname, "Canon") &&
+ strcasecmp(hostname, "Konica Minolta") &&
+ strcasecmp(hostname, "Minolta");
+#endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__ */
+
+ if ((device_fd = open_device(uri, &use_bc)) == -1)
{
+ if (getenv("CLASS") != NULL)
+ {
+ /*
+ * If the CLASS environment variable is set, the job was submitted
+ * to a class and not to a specific queue. In this case, we want
+ * to abort immediately so that the job can be requeued on the next
+ * available printer in the class.
+ */
+
+ _cupsLangPuts(stderr,
+ _("INFO: Unable to contact printer, queuing on next "
+ "printer in class...\n"));
+
+ /*
+ * Sleep 5 seconds to keep the job from requeuing too rapidly...
+ */
+
+ sleep(5);
+
+ return (CUPS_BACKEND_FAILED);
+ }
+
if (errno == EBUSY)
{
- fputs("INFO: USB port busy; will retry in 30 seconds...\n", stderr);
- sleep(30);
+ _cupsLangPuts(stderr,
+ _("INFO: Printer busy; will retry in 10 seconds...\n"));
+ sleep(10);
}
- else if (errno == ENXIO || errno == EIO || errno == ENOENT)
+ else if (errno == ENXIO || errno == EIO || errno == ENOENT ||
+ errno == ENODEV)
{
- fputs("INFO: Printer not connected; will retry in 30 seconds...\n", stderr);
+ _cupsLangPuts(stderr,
+ _("INFO: Printer not connected; will retry in 30 "
+ "seconds...\n"));
sleep(30);
}
else
{
- fprintf(stderr, "ERROR: Unable to open USB device \"%s\": %s\n",
- uri, strerror(errno));
- return (1);
+ _cupsLangPrintf(stderr,
+ _("ERROR: Unable to open device file \"%s\": %s\n"),
+ resource, strerror(errno));
+ return (CUPS_BACKEND_FAILED);
}
}
}
- while (fd < 0);
+ while (device_fd < 0);
+
+ fputs("STATE: -connecting-to-device\n", stderr);
/*
* Set any options provided...
*/
- tcgetattr(fd, &opts);
+ tcgetattr(device_fd, &opts);
opts.c_lflag &= ~(ICANON | ECHO | ISIG); /* Raw mode */
/**** No options supported yet ****/
- tcsetattr(fd, TCSANOW, &opts);
-
- /*
- * Now that we are "connected" to the port, ignore SIGTERM so that we
- * can finish out any page data the driver sends (e.g. to eject the
- * current page... Only ignore SIGTERM if we are printing data from
- * stdin (otherwise you can't cancel raw jobs...)
- */
-
- if (!fp)
- {
-#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
- sigset(SIGTERM, SIG_IGN);
-#elif defined(HAVE_SIGACTION)
- memset(&action, 0, sizeof(action));
-
- sigemptyset(&action.sa_mask);
- action.sa_handler = SIG_IGN;
- sigaction(SIGTERM, &action, NULL);
-#else
- signal(SIGTERM, SIG_IGN);
-#endif /* HAVE_SIGSET */
- }
-
-#if defined(__linux) && defined(LP_POUTPA)
- /*
- * Show the printer status before we send the file; normally, we'd
- * do this while we write data to the printer, however at least some
- * Linux kernels have buggy USB drivers which don't like to be
- * queried while sending data to the printer...
- *
- * Also, we're using the 8255 constants instead of the ones that are
- * supposed to be used, as it appears that the USB driver also doesn't
- * follow standards...
- */
-
- if (ioctl(fd, LPGETSTATUS, &status) == 0)
- {
- fprintf(stderr, "DEBUG: LPGETSTATUS returned a port status of %02X...\n", status);
-
- if (status & LP_POUTPA)
- fputs("WARNING: Media tray empty!\n", stderr);
- else if (!(status & LP_PERRORP))
- fputs("WARNING: Printer fault!\n", stderr);
- else if (!(status & LP_PSELECD))
- fputs("WARNING: Printer off-line.\n", stderr);
- }
-#endif /* __linux && LP_POUTPA */
+ tcsetattr(device_fd, TCSANOW, &opts);
/*
* Finally, send the print file...
*/
- wbytes = 0;
+ tbytes = 0;
- while (copies > 0)
+ while (copies > 0 && tbytes >= 0)
{
copies --;
- if (fp != 0)
+ if (print_fd != 0)
{
fputs("PAGE: 1 1\n", stderr);
- lseek(fp, 0, SEEK_SET);
+ lseek(print_fd, 0, SEEK_SET);
}
- tbytes = 0;
- while ((nbytes = read(fp, buffer, sizeof(buffer))) > 0)
- {
- /*
- * Write the print data to the printer...
- */
-
- tbytes += nbytes;
- bufptr = buffer;
-
- while (nbytes > 0)
- {
-
- if ((wbytes = write(fd, bufptr, nbytes)) < 0)
- if (errno == ENOTTY)
- wbytes = write(fd, bufptr, nbytes);
-
- if (wbytes < 0)
- {
- perror("ERROR: Unable to send print file to printer");
- break;
- }
-
- nbytes -= wbytes;
- bufptr += wbytes;
- }
-
- if (wbytes < 0)
- break;
+ tbytes = backendRunLoop(print_fd, device_fd, use_bc, side_cb);
- if (fp)
- fprintf(stderr, "INFO: Sending print file, %lu bytes...\n",
- (unsigned long)tbytes);
- }
+ if (print_fd != 0 && tbytes >= 0)
+ _cupsLangPrintf(stderr,
+#ifdef HAVE_LONG_LONG
+ _("INFO: Sent print file, %lld bytes...\n"),
+#else
+ _("INFO: Sent print file, %ld bytes...\n"),
+#endif /* HAVE_LONG_LONG */
+ CUPS_LLCAST tbytes);
}
/*
* Close the USB port and return...
*/
- close(fd);
-
- return (wbytes < 0);
-}
-
-
-/*
- * 'decode_device_id()' - Decode the IEEE-1284 device ID string.
- */
-
-void
-decode_device_id(int port, /* I - Port number */
- const char *device_id, /* I - 1284 device ID string */
- char *make_model, /* O - Make/model */
- int mmsize, /* I - Size of buffer */
- char *uri, /* O - Device URI */
- int urisize) /* I - Size of buffer */
-{
- char *attr, /* 1284 attribute */
- *delim, /* 1284 delimiter */
- *uriptr, /* Pointer into URI */
- *mfg, /* Manufacturer string */
- *mdl, /* Model string */
- serial_number[1024]; /* Serial number string */
-
-
- /*
- * Look for the description field...
- */
-
- if ((attr = strstr(device_id, "DES:")) != NULL)
- attr += 4;
- else if ((attr = strstr(device_id, "DESCRIPTION:")) != NULL)
- attr += 12;
-
- if ((mfg = strstr(device_id, "MANUFACTURER:")) != NULL)
- mfg += 13;
- else if ((mfg = strstr(device_id, "MFG:")) != NULL)
- mfg += 4;
-
- if ((mdl = strstr(device_id, "MODEL:")) != NULL)
- mdl += 6;
- else if ((mdl = strstr(device_id, "MDL:")) != NULL)
- mdl += 4;
-
- if (attr)
- {
- if (strncasecmp(attr, "Hewlett-Packard ", 16) == 0)
- {
- strlcpy(make_model, "HP ", mmsize);
- strlcpy(make_model + 3, attr + 16, mmsize - 3);
- }
- else
- {
- strlcpy(make_model, attr, mmsize);
- }
-
- if ((delim = strchr(make_model, ';')) != NULL)
- *delim = '\0';
- }
- else if (mfg && mdl)
- {
- /*
- * Build a make-model string from the manufacturer and model attributes...
- */
-
- strlcpy(make_model, mfg, mmsize);
-
- if ((delim = strchr(make_model, ';')) != NULL)
- *delim = '\0';
-
- strlcat(make_model, " ", mmsize);
- strlcat(make_model, mdl, mmsize);
-
- if ((delim = strchr(make_model, ';')) != NULL)
- *delim = '\0';
- }
- else
- {
- /*
- * Use "Unknown" as the printer make and model...
- */
-
- strlcpy(make_model, "Unknown", mmsize);
- }
-
- /*
- * Look for the serial number field...
- */
-
- if ((attr = strstr(device_id, "SERN:")) != NULL)
- attr += 5;
- else if ((attr = strstr(device_id, "SERIALNUMBER:")) != NULL)
- attr += 13;
- else if ((attr = strstr(device_id, ";SN:")) != NULL)
- attr += 4;
-
- if (mfg)
- {
- /*
- * Make sure manufacturer is truncated at delimiter...
- */
-
- if ((delim = strchr(mfg, ';')) != NULL)
- *delim = '\0';
- }
-
- if (mdl)
- {
- /*
- * Make sure model is truncated at delimiter...
- */
-
- if ((delim = strchr(mdl, ';')) != NULL)
- *delim = '\0';
- }
-
- if (attr)
- {
- strlcpy(serial_number, attr, sizeof(serial_number));
-
- if ((delim = strchr(serial_number, ';')) != NULL)
- *delim = '\0';
- }
- else
- serial_number[0] = '\0';
-
- /*
- * Generate the device URI from the make_model and serial number strings.
- */
-
- strlcpy(uri, "usb://", urisize);
- for (uriptr = uri + 6, delim = make_model;
- *delim && uriptr < (uri + urisize - 1);
- delim ++)
- if (*delim == ' ')
- {
- delim ++;
- *uriptr++ = '/';
- break;
- }
- else
- *uriptr++ = *delim;
-
- for (; *delim && uriptr < (uri + urisize - 3); delim ++)
- if (*delim == ' ')
- {
- *uriptr++ = '%';
- *uriptr++ = '2';
- *uriptr++ = '0';
- }
- else
- *uriptr++ = *delim;
-
- *uriptr = '\0';
+ close(device_fd);
- if (serial_number[0])
- {
- /*
- * Add the serial number to the URI...
- */
-
- strlcat(uri, "?serial=", urisize);
- strlcat(uri, serial_number, urisize);
- }
+ return (tbytes < 0 ? CUPS_BACKEND_FAILED : CUPS_BACKEND_OK);
}
list_devices(void)
{
#ifdef __linux
- int i; /* Looping var */
- int length; /* Length of device ID info */
- int fd; /* File descriptor */
- char format[255], /* Format for device filename */
- device[255], /* Device filename */
- device_id[1024], /* Device ID string */
- device_uri[1024], /* Device URI string */
- make_model[1024]; /* Make and model */
-
-
- /*
- * First figure out which USB printer filename to use...
- */
-
- if (access("/dev/usblp0", 0) == 0)
- strcpy(format, "/dev/usblp%d");
- else if (access("/dev/usb/usblp0", 0) == 0)
- strcpy(format, "/dev/usb/usblp%d");
- else
- strcpy(format, "/dev/usb/lp%d");
+ int i; /* Looping var */
+ int fd; /* File descriptor */
+ char device[255], /* Device filename */
+ device_id[1024], /* Device ID string */
+ device_uri[1024], /* Device URI string */
+ make_model[1024]; /* Make and model */
/*
- * Then open each USB device...
+ * Try to open each USB device...
*/
for (i = 0; i < 16; i ++)
{
- sprintf(device, format, i);
+ /*
+ * Linux has a long history of changing the standard filenames used
+ * for USB printer devices. We get the honor of trying them all...
+ */
- if ((fd = open(device, O_RDWR | O_EXCL)) >= 0)
+ sprintf(device, "/dev/usblp%d", i);
+
+ if ((fd = open(device, O_RDWR | O_EXCL)) < 0)
{
- if (ioctl(fd, LPIOC_GET_DEVICE_ID(sizeof(device_id)), device_id) == 0)
- {
- length = (((unsigned)device_id[0] & 255) << 8) +
- ((unsigned)device_id[1] & 255);
+ if (errno != ENOENT)
+ continue;
- /*
- * Check to see if the length is larger than our buffer; first
- * assume that the vendor incorrectly implemented the 1284 spec,
- * and then limit the length to the size of our buffer...
- */
+ sprintf(device, "/dev/usb/lp%d", i);
- if (length > (sizeof(device_id) - 2))
- length = (((unsigned)device_id[1] & 255) << 8) +
- ((unsigned)device_id[0] & 255);
+ if ((fd = open(device, O_RDWR | O_EXCL)) < 0)
+ {
+ if (errno != ENOENT)
+ continue;
- if (length > (sizeof(device_id) - 2))
- length = sizeof(device_id) - 2;
+ sprintf(device, "/dev/usb/usblp%d", i);
- memmove(device_id, device_id + 2, length);
- device_id[length] = '\0';
+ if ((fd = open(device, O_RDWR | O_EXCL)) < 0)
+ continue;
}
- else
- device_id[0] = '\0';
-
- close(fd);
}
- else
- device_id[0] = '\0';
- if (device_id[0])
- {
- decode_device_id(i, device_id, make_model, sizeof(make_model),
- device_uri, sizeof(device_uri));
+ if (!backendGetDeviceID(fd, device_id, sizeof(device_id),
+ make_model, sizeof(make_model),
+ "usb", device_uri, sizeof(device_uri)))
+ printf("direct %s \"%s\" \"%s USB #%d\" \"%s\"\n", device_uri,
+ make_model, make_model, i + 1, device_id);
- printf("direct %s \"%s\" \"USB Printer #%d\"\n", device_uri,
- make_model, i + 1);
- }
- else
- printf("direct usb:%s \"Unknown\" \"USB Printer #%d\"\n", device, i + 1);
+ close(fd);
}
#elif defined(__sgi)
-#elif defined(__sun)
+#elif defined(__sun) && defined(ECPPIOC_GETDEVID)
int i; /* Looping var */
int fd; /* File descriptor */
char device[255], /* Device filename */
device_id[1024], /* Device ID string */
device_uri[1024], /* Device URI string */
make_model[1024]; /* Make and model */
-# ifdef ECPPIOC_GETDEVID
- struct ecpp_device_id did; /* Device ID buffer */
-# endif /* ECPPIOC_GETDEVID */
/*
{
sprintf(device, "/dev/usb/printer%d", i);
-# ifndef ECPPIOC_GETDEVID
- if (!access(device, 0))
- printf("direct usb:%s \"Unknown\" \"USB Printer #%d\"\n", device, i + 1);
-# else
- if ((fd = open(device, O_RDWR | O_EXCL)) >= 0)
+ if ((fd = open(device, O_WRONLY | O_EXCL)) >= 0)
{
- did.mode = ECPP_CENTRONICS;
- did.len = sizeof(device_id);
- did.rlen = 0;
- did.addr = device_id;
-
- if (ioctl(fd, ECPPIOC_GETDEVID, &did) == 0)
- {
- if (did.rlen < (sizeof(device_id) - 1))
- device_id[did.rlen] = '\0';
- else
- device_id[sizeof(device_id) - 1] = '\0';
- }
- else
- device_id[0] = '\0';
+ if (!backendGetDeviceID(fd, device_id, sizeof(device_id),
+ make_model, sizeof(make_model),
+ "usb", device_uri, sizeof(device_uri)))
+ printf("direct %s \"%s\" \"%s USB #%d\" \"%s\"\n", device_uri,
+ make_model, make_model, i + 1, device_id);
close(fd);
}
- else
- device_id[0] = '\0';
-
- if (device_id[0])
- {
- decode_device_id(i, device_id, make_model, sizeof(make_model),
- device_uri, sizeof(device_uri));
-
- printf("direct %s \"%s\" \"USB Printer #%d\"\n", device_uri,
- make_model, i + 1);
- }
- else
- printf("direct usb:%s \"Unknown\" \"USB Printer #%d\"\n", device, i + 1);
-# endif /* !ECPPIOC_GETDEVID */
}
#elif defined(__hpux)
#elif defined(__osf)
-#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
int i; /* Looping var */
char device[255]; /* Device filename */
* 'open_device()' - Open a USB device...
*/
-int /* O - File descriptor or -1 on error */
-open_device(const char *uri) /* I - Device URI */
+static int /* O - File descriptor or -1 on error */
+open_device(const char *uri, /* I - Device URI */
+ int *use_bc) /* O - Set to 0 for unidirectional */
{
+ int fd; /* File descriptor */
+
+
/*
* The generic implementation just treats the URI as a device filename...
* Specific operating systems may also support using the device serial
* number and/or make/model.
*/
- if (strncmp(uri, "usb:/dev/", 9) == 0)
- return (open(uri + 4, O_RDWR | O_EXCL));
+ if (!strncmp(uri, "usb:/dev/", 9))
#ifdef __linux
- else if (strncmp(uri, "usb://", 6) == 0)
+ {
+ /*
+ * Do not allow direct devices anymore...
+ */
+
+ errno = ENODEV;
+ return (-1);
+ }
+ else if (!strncmp(uri, "usb://", 6))
{
/*
* For Linux, try looking up the device serial number or model...
int i; /* Looping var */
int busy; /* Are any ports busy? */
- int length; /* Length of device ID info */
- int fd; /* File descriptor */
- char format[255], /* Format for device filename */
- device[255], /* Device filename */
+ char device[255], /* Device filename */
device_id[1024], /* Device ID string */
make_model[1024], /* Make and model */
device_uri[1024]; /* Device URI string */
/*
- * First figure out which USB printer filename to use...
- */
-
- if (access("/dev/usblp0", 0) == 0)
- strcpy(format, "/dev/usblp%d");
- else if (access("/dev/usb/usblp0", 0) == 0)
- strcpy(format, "/dev/usb/usblp%d");
- else
- strcpy(format, "/dev/usb/lp%d");
-
- /*
- * Then find the correct USB device...
+ * Find the correct USB device...
*/
do
{
for (busy = 0, i = 0; i < 16; i ++)
{
- sprintf(device, format, i);
+ /*
+ * Linux has a long history of changing the standard filenames used
+ * for USB printer devices. We get the honor of trying them all...
+ */
+
+ sprintf(device, "/dev/usblp%d", i);
- if ((fd = open(device, O_RDWR | O_EXCL)) >= 0)
+ if ((fd = open(device, O_RDWR | O_EXCL)) < 0 && errno == ENOENT)
{
- if (ioctl(fd, LPIOC_GET_DEVICE_ID(sizeof(device_id)), device_id) == 0)
+ sprintf(device, "/dev/usb/lp%d", i);
+
+ if ((fd = open(device, O_RDWR | O_EXCL)) < 0 && errno == ENOENT)
{
- length = (((unsigned)device_id[0] & 255) << 8) +
- ((unsigned)device_id[1] & 255);
- memmove(device_id, device_id + 2, length);
- device_id[length] = '\0';
+ sprintf(device, "/dev/usb/usblp%d", i);
+
+ if ((fd = open(device, O_RDWR | O_EXCL)) < 0 && errno == ENOENT)
+ continue;
}
- else
- device_id[0] = '\0';
+ }
+
+ if (fd >= 0)
+ {
+ backendGetDeviceID(fd, device_id, sizeof(device_id),
+ make_model, sizeof(make_model),
+ "usb", device_uri, sizeof(device_uri));
}
else
{
if (errno == EBUSY)
busy = 1;
- device_id[0] = '\0';
+ device_uri[0] = '\0';
}
- if (device_id[0])
+ if (!strcmp(uri, device_uri))
{
/*
- * Got the device ID - is this the one?
+ * Yes, return this file descriptor...
*/
- decode_device_id(i, device_id, make_model, sizeof(make_model),
- device_uri, sizeof(device_uri));
-
- if (strcmp(uri, device_uri) == 0)
- {
- /*
- * Yes, return this file descriptor...
- */
-
- fprintf(stderr, "DEBUG: Printer using device file \"%s\"...\n", device);
+ fprintf(stderr, "DEBUG: Printer using device file \"%s\"...\n",
+ device);
- return (fd);
- }
+ return (fd);
}
/*
if (busy)
{
- fputs("INFO: USB printer is busy; will retry in 5 seconds...\n",
- stderr);
+ _cupsLangPuts(stderr,
+ _("INFO: Printer busy; will retry in 5 seconds...\n"));
sleep(5);
}
}
return (-1);
}
#elif defined(__sun) && defined(ECPPIOC_GETDEVID)
- else if (strncmp(uri, "usb://", 6) == 0)
+ {
+ /*
+ * Do not allow direct devices anymore...
+ */
+
+ errno = ENODEV;
+ return (-1);
+ }
+ else if (!strncmp(uri, "usb://", 6))
{
/*
* For Solaris, try looking up the device serial number or model...
int i; /* Looping var */
int busy; /* Are any ports busy? */
- int fd; /* File descriptor */
char device[255], /* Device filename */
device_id[1024], /* Device ID string */
make_model[1024], /* Make and model */
device_uri[1024]; /* Device URI string */
- struct ecpp_device_id did; /* Device ID buffer */
/*
{
sprintf(device, "/dev/usb/printer%d", i);
- if ((fd = open(device, O_RDWR | O_EXCL)) >= 0)
- {
- did.mode = ECPP_CENTRONICS;
- did.len = sizeof(device_id);
- did.rlen = 0;
- did.addr = device_id;
-
- if (ioctl(fd, ECPPIOC_GETDEVID, &did) == 0)
- {
- if (did.rlen < (sizeof(device_id) - 1))
- device_id[did.rlen] = '\0';
- else
- device_id[sizeof(device_id) - 1] = '\0';
- }
- else
- device_id[0] = '\0';
- }
+ if ((fd = open(device, O_WRONLY | O_EXCL)) >= 0)
+ backendGetDeviceID(fd, device_id, sizeof(device_id),
+ make_model, sizeof(make_model),
+ "usb", device_uri, sizeof(device_uri));
else
{
/*
if (errno == EBUSY)
busy = 1;
- device_id[0] = '\0';
+ device_uri[0] = '\0';
}
- if (device_id[0])
+ if (!strcmp(uri, device_uri))
{
/*
- * Got the device ID - is this the one?
+ * Yes, return this file descriptor...
*/
- decode_device_id(i, device_id, make_model, sizeof(make_model),
- device_uri, sizeof(device_uri));
+ fputs("DEBUG: Setting use_bc to 0!\n", stderr);
+
+ *use_bc = 0;
- if (strcmp(uri, device_uri) == 0)
- return (fd); /* Yes, return this file descriptor... */
+ return (fd);
}
/*
if (busy)
{
- fputs("INFO: USB printer is busy; will retry in 5 seconds...\n",
- stderr);
+ _cupsLangPuts(stderr,
+ _("INFO: Printer is busy; will retry in 5 seconds...\n"));
sleep(5);
}
}
return (-1);
}
+#else
+ {
+ if (use_bc)
+ fd = open(uri + 4, O_RDWR | O_EXCL);
+ else
+ fd = -1;
+
+ if (fd < 0)
+ {
+ fd = open(uri + 4, O_WRONLY | O_EXCL);
+ *use_bc = 0;
+ }
+
+ return (fd);
+ }
#endif /* __linux */
else
{
}
+/*
+ * 'side_cb()' - Handle side-channel requests...
+ */
+
+static void
+side_cb(int print_fd, /* I - Print file */
+ int device_fd, /* I - Device file */
+ int use_bc) /* I - Using back-channel? */
+{
+ cups_sc_command_t command; /* Request command */
+ cups_sc_status_t status; /* Request/response status */
+ char data[2048]; /* Request/response data */
+ int datalen; /* Request/response data size */
+
+
+ datalen = sizeof(data);
+
+ if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0))
+ {
+ _cupsLangPuts(stderr, _("WARNING: Failed to read side-channel request!\n"));
+ return;
+ }
+
+ switch (command)
+ {
+ case CUPS_SC_CMD_DRAIN_OUTPUT :
+ if (backendDrainOutput(print_fd, device_fd))
+ status = CUPS_SC_STATUS_IO_ERROR;
+ else if (tcdrain(device_fd))
+ status = CUPS_SC_STATUS_IO_ERROR;
+ else
+ status = CUPS_SC_STATUS_OK;
+
+ datalen = 0;
+ break;
+
+ case CUPS_SC_CMD_GET_BIDI :
+ data[0] = use_bc;
+ datalen = 1;
+ break;
+
+ case CUPS_SC_CMD_GET_DEVICE_ID :
+ memset(data, 0, sizeof(data));
+
+ if (backendGetDeviceID(device_fd, data, sizeof(data) - 1,
+ NULL, 0, NULL, NULL, 0))
+ {
+ status = CUPS_SC_STATUS_NOT_IMPLEMENTED;
+ datalen = 0;
+ }
+ else
+ {
+ status = CUPS_SC_STATUS_OK;
+ datalen = strlen(data);
+ }
+ break;
+
+ default :
+ status = CUPS_SC_STATUS_NOT_IMPLEMENTED;
+ datalen = 0;
+ break;
+ }
+
+ cupsSideChannelWrite(command, status, data, datalen, 1.0);
+}
+
+
/*
* End of "$Id$".
*/