1/* 2 * "$Id: usb.c 11093 2013-07-03 20:48:42Z msweet $" 3 * 4 * USB port backend for CUPS. 5 * 6 * Copyright 2007-2012 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 * list_devices() - List all available USB devices to stdout. 20 * print_device() - Print a file to a USB device. 21 * main() - Send a file to the specified USB port. 22 */ 23 24/* 25 * Include necessary headers. 26 */ 27 28#ifdef __APPLE__ 29 /* A header order dependency requires this be first */ 30# include <ApplicationServices/ApplicationServices.h> 31#endif /* __APPLE__ */ 32 33#include "backend-private.h" 34 35#ifdef WIN32 36# include <io.h> 37#else 38# include <unistd.h> 39# include <fcntl.h> 40# include <termios.h> 41#endif /* WIN32 */ 42 43 44/* 45 * Local functions... 46 */ 47 48void list_devices(void); 49int print_device(const char *uri, const char *hostname, 50 const char *resource, char *options, 51 int print_fd, int copies, int argc, char *argv[]); 52 53 54/* 55 * Include the vendor-specific USB implementation... 56 */ 57 58#ifdef HAVE_LIBUSB 59# include "usb-libusb.c" 60#elif defined(__APPLE__) 61# include "usb-darwin.c" 62#elif defined(__linux) || defined(__sun) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) 63# include "usb-unix.c" 64#else 65/* 66 * Use dummy functions that do nothing on unsupported platforms... 67 * These can be used as templates for implementing USB printing on new 68 * platforms... 69 */ 70 71/* 72 * 'list_devices()' - List all available USB devices to stdout. 73 */ 74 75void 76list_devices(void) 77{ 78 /* 79 * Don't have any devices to list... Use output of the form: 80 * 81 * direct usb:/make/model?serial=foo "Make Model" "USB Printer" 82 * 83 * Note that "Hewlett Packard" or any other variation MUST be mapped to 84 * "HP" for compatibility with the PPD and ICC specs. 85 */ 86} 87 88 89/* 90 * 'print_device()' - Print a file to a USB device. 91 */ 92 93int /* O - Exit status */ 94print_device(const char *uri, /* I - Device URI */ 95 const char *hostname, /* I - Hostname/manufacturer */ 96 const char *resource, /* I - Resource/modelname */ 97 char *options, /* I - Device options/serial number */ 98 int print_fd, /* I - File descriptor to print */ 99 int copies, /* I - Copies to print */ 100 int argc, /* I - Number of command-line arguments (6 or 7) */ 101 char *argv[]) /* I - Command-line arguments */ 102{ 103 /* 104 * Can't print, so just reference the arguments to eliminate compiler 105 * warnings and return and exit status of 1. Normally you would use the 106 * arguments to send a file to the printer and return 0 if everything 107 * worked OK and non-zero if there was an error. 108 */ 109 110 (void)uri; 111 (void)hostname; 112 (void)resource; 113 (void)options; 114 (void)print_fd; 115 (void)copies; 116 (void)argc; 117 (void)argv; 118 119 return (CUPS_BACKEND_FAILED); 120} 121#endif /* HAVE_LIBUSB */ 122 123 124/* 125 * 'main()' - Send a file to the specified USB port. 126 * 127 * Usage: 128 * 129 * printer-uri job-id user title copies options [file] 130 */ 131 132int /* O - Exit status */ 133main(int argc, /* I - Number of command-line arguments (6 or 7) */ 134 char *argv[]) /* I - Command-line arguments */ 135{ 136 int print_fd; /* Print file */ 137 int copies; /* Number of copies to print */ 138 int status; /* Exit status */ 139 int port; /* Port number (not used) */ 140 const char *uri; /* Device URI */ 141 char method[255], /* Method in URI */ 142 hostname[1024], /* Hostname */ 143 username[255], /* Username info (not used) */ 144 resource[1024], /* Resource info (device and options) */ 145 *options; /* Pointer to options */ 146#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) 147 struct sigaction action; /* Actions for POSIX signals */ 148#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ 149 150 151 /* 152 * Make sure status messages are not buffered... 153 */ 154 155 setbuf(stderr, NULL); 156 157 /* 158 * Ignore SIGPIPE signals... 159 */ 160 161#ifdef HAVE_SIGSET 162 sigset(SIGPIPE, SIG_IGN); 163#elif defined(HAVE_SIGACTION) 164 memset(&action, 0, sizeof(action)); 165 action.sa_handler = SIG_IGN; 166 sigaction(SIGPIPE, &action, NULL); 167#else 168 signal(SIGPIPE, SIG_IGN); 169#endif /* HAVE_SIGSET */ 170 171 /* 172 * Check command-line... 173 */ 174 175 if (argc == 1) 176 { 177 list_devices(); 178 return (CUPS_BACKEND_OK); 179 } 180 else if (argc < 6 || argc > 7) 181 { 182 _cupsLangPrintf(stderr, 183 _("Usage: %s job-id user title copies options [file]"), 184 argv[0]); 185 return (CUPS_BACKEND_FAILED); 186 } 187 188 /* 189 * Extract the device name and options from the URI... 190 */ 191 192 uri = cupsBackendDeviceURI(argv); 193 194 if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, 195 method, sizeof(method), username, sizeof(username), 196 hostname, sizeof(hostname), &port, 197 resource, sizeof(resource)) < HTTP_URI_OK) 198 { 199 _cupsLangPrintFilter(stderr, "ERROR", 200 _("No device URI found in argv[0] or in DEVICE_URI " 201 "environment variable.")); 202 return (1); 203 } 204 205 /* 206 * See if there are any options... 207 */ 208 209 if ((options = strchr(resource, '?')) != NULL) 210 { 211 /* 212 * Yup, terminate the device name string and move to the first 213 * character of the options... 214 */ 215 216 *options++ = '\0'; 217 } 218 219 /* 220 * If we have 7 arguments, print the file named on the command-line. 221 * Otherwise, send stdin instead... 222 */ 223 224 if (argc == 6) 225 { 226 print_fd = 0; 227 copies = 1; 228 } 229 else 230 { 231 /* 232 * Try to open the print file... 233 */ 234 235 if ((print_fd = open(argv[6], O_RDONLY)) < 0) 236 { 237 _cupsLangPrintError("ERROR", _("Unable to open print file")); 238 return (CUPS_BACKEND_FAILED); 239 } 240 241 copies = atoi(argv[4]); 242 } 243 244 /* 245 * Finally, send the print file... 246 */ 247 248 status = print_device(uri, hostname, resource, options, print_fd, copies, 249 argc, argv); 250 251 /* 252 * Close the input file and return... 253 */ 254 255 if (print_fd != 0) 256 close(print_fd); 257 258 return (status); 259} 260 261 262/* 263 * End of "$Id: usb.c 11093 2013-07-03 20:48:42Z msweet $". 264 */ 265