]>
git.ipfire.org Git - thirdparty/cups.git/blob - backend/usb.c
2 * "$Id: usb.c,v 1.31 2002/08/09 00:08:29 mike Exp $"
4 * USB port backend for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2002 by Easy Software Products, all rights reserved.
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636-3111 USA
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
24 * This file is subject to the Apple OS-Developed Software exception.
28 * main() - Send a file to the specified USB port.
29 * list_devices() - List all USB devices.
33 * Include necessary headers.
36 #include <cups/cups.h>
40 #include <cups/string.h>
56 void list_devices(void);
60 * 'main()' - Send a file to the specified USB port.
64 * printer-uri job-id user title copies options [file]
67 int /* O - Exit status */
68 main(int argc
, /* I - Number of command-line arguments (6 or 7) */
69 char *argv
[]) /* I - Command-line arguments */
71 char method
[255], /* Method in URI */
72 hostname
[1024], /* Hostname */
73 username
[255], /* Username info (not used) */
74 resource
[1024], /* Resource info (device and options) */
75 *options
; /* Pointer to options */
76 int port
; /* Port number (not used) */
77 int fp
; /* Print file */
78 int copies
; /* Number of copies to print */
79 int fd
; /* Parallel device */
80 int wbytes
; /* Number of bytes written */
81 size_t nbytes
, /* Number of bytes read */
82 tbytes
; /* Total number of bytes written */
83 char buffer
[8192], /* Output buffer */
84 *bufptr
; /* Pointer into buffer */
85 struct termios opts
; /* Parallel port options */
86 #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
87 struct sigaction action
; /* Actions for POSIX signals */
88 #endif /* HAVE_SIGACTION && !HAVE_SIGSET */
92 * Make sure status messages are not buffered...
98 * Check command-line...
106 else if (argc
< 6 || argc
> 7)
108 fputs("Usage: USB job-id user title copies options [file]\n", stderr
);
113 * If we have 7 arguments, print the file named on the command-line.
114 * Otherwise, send stdin instead...
125 * Try to open the print file...
128 if ((fp
= open(argv
[6], O_RDONLY
)) < 0)
130 perror("ERROR: unable to open print file");
134 copies
= atoi(argv
[4]);
138 * Extract the device name and options from the URI...
141 httpSeparate(argv
[0], method
, username
, hostname
, &port
, resource
);
144 * See if there are any options...
147 if ((options
= strchr(resource
, '?')) != NULL
)
150 * Yup, terminate the device name string and move to the first
151 * character of the options...
158 * Open the USB port device...
163 if ((fd
= open(resource
, O_WRONLY
| O_EXCL
)) == -1)
167 fputs("INFO: USB port busy; will retry in 30 seconds...\n", stderr
);
170 else if (errno
== ENXIO
|| errno
== EIO
|| errno
== ENOENT
)
172 fputs("INFO: Printer not connected; will retry in 30 seconds...\n", stderr
);
177 fprintf(stderr
, "ERROR: Unable to open USB port device file \"%s\": %s\n",
178 resource
, strerror(errno
));
186 * Set any options provided...
189 tcgetattr(fd
, &opts
);
191 opts
.c_lflag
&= ~(ICANON
| ECHO
| ISIG
); /* Raw mode */
193 /**** No options supported yet ****/
195 tcsetattr(fd
, TCSANOW
, &opts
);
198 * Now that we are "connected" to the port, ignore SIGTERM so that we
199 * can finish out any page data the driver sends (e.g. to eject the
200 * current page... Only ignore SIGTERM if we are printing data from
201 * stdin (otherwise you can't cancel raw jobs...)
206 #ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
207 sigset(SIGTERM
, SIG_IGN
);
208 #elif defined(HAVE_SIGACTION)
209 memset(&action
, 0, sizeof(action
));
211 sigemptyset(&action
.sa_mask
);
212 action
.sa_handler
= SIG_IGN
;
213 sigaction(SIGTERM
, &action
, NULL
);
215 signal(SIGTERM
, SIG_IGN
);
216 #endif /* HAVE_SIGSET */
220 * Finally, send the print file...
229 fputs("PAGE: 1 1\n", stderr
);
230 lseek(fp
, 0, SEEK_SET
);
234 while ((nbytes
= read(fp
, buffer
, sizeof(buffer
))) > 0)
237 * Write the print data to the printer...
245 if ((wbytes
= write(fd
, bufptr
, nbytes
)) < 0)
247 wbytes
= write(fd
, bufptr
, nbytes
);
251 perror("ERROR: Unable to send print file to printer");
260 fprintf(stderr
, "INFO: Sending print file, %lu bytes...\n",
261 (unsigned long)tbytes
);
266 * Close the socket connection and input file and return...
273 fputs("INFO: Ready to print.\n", stderr
);
280 * 'list_devices()' - List all USB devices.
287 int i
; /* Looping var */
288 int fd
; /* File descriptor */
289 char device
[255]; /* Device filename */
290 FILE *probe
; /* /proc/bus/usb/devices file */
291 char line
[1024], /* Line from file */
292 *delim
, /* Delimiter in file */
293 make
[IPP_MAX_NAME
], /* Make from file */
294 model
[IPP_MAX_NAME
]; /* Model from file */
298 * First try opening one of the USB devices to load the driver
299 * module as needed...
302 if ((fd
= open("/dev/usb/lp0", O_WRONLY
)) >= 0)
303 close(fd
); /* 2.3.x and 2.4.x */
304 else if ((fd
= open("/dev/usb/usblp0", O_WRONLY
)) >= 0)
305 close(fd
); /* Mandrake 7.x */
306 else if ((fd
= open("/dev/usblp0", O_WRONLY
)) >= 0)
307 close(fd
); /* 2.2.x */
310 * Then look at the device list for the USB bus...
313 if ((probe
= fopen("/proc/bus/usb/devices", "r")) != NULL
)
316 * Scan the device list...
321 memset(make
, 0, sizeof(make
));
322 memset(model
, 0, sizeof(model
));
324 while (fgets(line
, sizeof(line
), probe
) != NULL
)
327 * Strip trailing newline.
330 if ((delim
= strrchr(line
, '\n')) != NULL
)
334 * See if it is a printer device ("P: ...")
337 if (strncmp(line
, "S:", 2) == 0)
340 * String attribute...
343 if (strncmp(line
, "S: Manufacturer=", 17) == 0)
345 strlcpy(make
, line
+ 17, sizeof(make
));
346 if (strcmp(make
, "Hewlett-Packard") == 0)
349 else if (strncmp(line
, "S: Product=", 12) == 0)
350 strlcpy(model
, line
+ 12, sizeof(model
));
352 else if (strncmp(line
, "I:", 2) == 0 &&
353 (strstr(line
, "Driver=printer") != NULL
||
354 strstr(line
, "Driver=usblp") != NULL
) &&
358 * We were processing a printer device; send the info out...
361 sprintf(device
, "/dev/usb/lp%d", i
);
362 if (access(device
, 0))
364 sprintf(device
, "/dev/usb/usblp%d", i
);
366 if (access(device
, 0))
367 sprintf(device
, "/dev/usblp%d", i
);
370 printf("direct usb:%s \"%s %s\" \"USB Printer #%d\"\n",
371 device
, make
, model
, i
+ 1);
375 memset(make
, 0, sizeof(make
));
376 memset(model
, 0, sizeof(model
));
383 * Write empty device listings for unused USB devices...
388 sprintf(device
, "/dev/usb/lp%d", i
);
390 if (access(device
, 0))
392 sprintf(device
, "/dev/usb/usblp%d", i
);
394 if (access(device
, 0))
396 sprintf(device
, "/dev/usblp%d", i
);
398 if (access(device
, 0))
403 printf("direct usb:%s \"Unknown\" \"USB Printer #%d\"\n", device
, i
+ 1);
409 * Just check manually for USB devices...
412 for (i
= 0; i
< 16; i
++)
414 sprintf(device
, "/dev/usb/lp%d", i
);
416 if (access(device
, 0))
418 sprintf(device
, "/dev/usb/usblp%d", i
);
420 if (access(device
, 0))
422 sprintf(device
, "/dev/usblp%d", i
);
424 if (access(device
, 0))
429 printf("direct usb:%s \"Unknown\" \"USB Printer #%d\"\n", device
, i
+ 1);
434 #elif defined(__hpux)
436 #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
437 int i
; /* Looping var */
438 char device
[255]; /* Device filename */
441 for (i
= 0; i
< 8; i
++)
443 sprintf(device
, "/dev/ulpt%d", i
);
444 if (!access(device
, 0))
445 printf("direct usb:%s \"Unknown\" \"USB Printer #%d (ulpt)\"\n", device
, i
+ 1);
447 sprintf(device
, "/dev/unlpt%d", i
);
448 if (!access(device
, 0))
449 printf("direct usb:%s \"Unknown\" \"USB Printer #%d\" (unlpt)\n", device
, i
+ 1);
456 * End of "$Id: usb.c,v 1.31 2002/08/09 00:08:29 mike Exp $".