X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fcups.git;a=blobdiff_plain;f=backend%2Fusb-unix.c;h=104ea7d43cbe3549751891067e399a0d978e0bb9;hp=47b2cf1f08e737ec67577a97f583fb5211f93608;hb=91c84a3551145559de2956179661e111e373db95;hpb=2abf387cae0cce4bf3a0a259ded28ef0269aec47 diff --git a/backend/usb-unix.c b/backend/usb-unix.c index 47b2cf1f0..104ea7d43 100644 --- a/backend/usb-unix.c +++ b/backend/usb-unix.c @@ -1,27 +1,18 @@ /* - * "$Id: usb-unix.c 6032 2006-10-12 19:19:47Z mike $" + * "$Id: usb-unix.c 6910 2007-09-04 20:34:29Z mike $" * * USB port backend for the Common UNIX Printing System (CUPS). * * This file is included from "usb.c" when compiled on UNIX/Linux. * - * Copyright 1997-2006 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. * @@ -30,6 +21,7 @@ * 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... */ /* @@ -44,7 +36,8 @@ * Local functions... */ -int open_device(const char *uri, int *use_bc); +static int open_device(const char *uri, int *use_bc); +static void side_cb(int print_fd, int device_fd, int use_bc); /* @@ -55,7 +48,7 @@ int /* O - Exit status */ print_device(const char *uri, /* I - Device URI */ const char *hostname, /* I - Hostname/manufacturer */ const char *resource, /* I - Resource/modelname */ - const char *options, /* I - Device options/serial number */ + char *options, /* I - Device options/serial number */ 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) */ @@ -78,14 +71,28 @@ print_device(const char *uri, /* I - Device URI */ do { +#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 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... + * 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, "Canon") != 0 || - strstr(hostname, "Minolta") != NULL; + use_bc = strcasecmp(hostname, "Brother") && + strcasecmp(hostname, "Canon") && + strncasecmp(hostname, "Konica", 6) && + strncasecmp(hostname, "Minolta", 7); +#endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__ */ if ((device_fd = open_device(uri, &use_bc)) == -1) { @@ -98,8 +105,9 @@ print_device(const char *uri, /* I - Device URI */ * available printer in the class. */ - fputs("INFO: Unable to open USB device, queuing on next printer in class...\n", - stderr); + _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... @@ -112,19 +120,23 @@ print_device(const char *uri, /* I - Device URI */ 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 || 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)); + _cupsLangPrintf(stderr, + _("ERROR: Unable to open device file \"%s\": %s\n"), + resource, strerror(errno)); return (CUPS_BACKEND_FAILED); } } @@ -161,11 +173,16 @@ print_device(const char *uri, /* I - Device URI */ lseek(print_fd, 0, SEEK_SET); } - tbytes = backendRunLoop(print_fd, device_fd, use_bc); + tbytes = backendRunLoop(print_fd, device_fd, use_bc, side_cb); if (print_fd != 0 && tbytes >= 0) - fprintf(stderr, "INFO: Sent print file, " CUPS_LLFMT " bytes...\n", - CUPS_LLCAST tbytes); + _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); } /* @@ -264,7 +281,7 @@ list_devices(void) } #elif defined(__hpux) #elif defined(__osf) -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) int i; /* Looping var */ char device[255]; /* Device filename */ @@ -287,7 +304,7 @@ list_devices(void) * 'open_device()' - Open a USB device... */ -int /* O - File descriptor or -1 on error */ +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 */ { @@ -328,7 +345,7 @@ open_device(const char *uri, /* I - Device URI */ * Find the correct USB device... */ - do + for (;;) { for (busy = 0, i = 0; i < 16; i ++) { @@ -377,7 +394,8 @@ open_device(const char *uri, /* I - Device URI */ * 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); } @@ -397,20 +415,11 @@ open_device(const char *uri, /* I - Device URI */ 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); } } - while (busy); - - /* - * Couldn't find the printer, return "no such device or address"... - */ - - errno = ENODEV; - - return (-1); } #elif defined(__sun) && defined(ECPPIOC_GETDEVID) { @@ -490,8 +499,8 @@ open_device(const char *uri, /* I - Device URI */ 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); } } @@ -507,7 +516,12 @@ open_device(const char *uri, /* I - Device URI */ } #else { - if ((fd = open(uri + 4, O_RDWR | O_EXCL)) < 0) + 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; @@ -525,5 +539,72 @@ open_device(const char *uri, /* I - Device URI */ /* - * End of "$Id: usb-unix.c 6032 2006-10-12 19:19:47Z mike $". + * '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: usb-unix.c 6910 2007-09-04 20:34:29Z mike $". */