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