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