]>
git.ipfire.org Git - thirdparty/cups.git/blob - backend/scsi-linux.c
2 * "$Id: scsi-linux.c 6422 2007-03-30 20:49:37Z mike $"
4 * Linux SCSI printer support for the Common UNIX Printing System (CUPS).
6 * Copyright 2003-2005 by Easy Software Products, all rights reserved.
8 * Redistribution and use in source and binary forms, with or
9 * without modification, are permitted provided that the
10 * following conditions are met:
12 * 1. Redistributions of source code must retain the above
13 * copyright notice, this list of conditions and the
14 * following disclaimer.
16 * 2. Redistributions in binary form must reproduce the
17 * above copyright notice, this list of conditions and
18 * the following disclaimer in the documentation and/or
19 * other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use
22 * of this software must display the following
25 * This product includes software developed by Easy
28 * 4. The name of Easy Software Products may not be used to
29 * endorse or promote products derived from this software
30 * without specific prior written permission.
32 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS
33 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
34 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
35 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
37 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
38 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
39 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
40 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
42 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
43 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
49 * list_devices() - List the available SCSI printer devices.
50 * print_device() - Print a file to a SCSI device.
54 * Include necessary headers.
58 #include <cups/i18n.h>
62 * We currently only support the Linux 2.4 generic SCSI interface.
65 #ifndef SG_DXFER_TO_DEV
67 * Dummy functions that do nothing on unsupported platforms...
69 void list_devices(void) {}
70 int print_device(const char *resource
, int fd
, int copies
) { return (1); }
75 * 'list_devices()' - List the available SCSI printer devices.
81 puts("direct scsi \"Unknown\" \"SCSI Printer\"");
86 * 'print_device()' - Print a file to a SCSI device.
89 int /* O - Print status */
90 print_device(const char *resource
, /* I - SCSI device */
91 int fd
, /* I - File to print */
92 int copies
) /* I - Number of copies to print */
94 int scsi_fd
; /* SCSI file descriptor */
95 char buffer
[8192]; /* Data buffer */
96 int bytes
; /* Number of bytes */
97 int try; /* Current try */
98 sg_io_hdr_t scsi_req
; /* SCSI request */
99 unsigned char scsi_cmd
[6], /* SCSI command data */
100 scsi_sense
[32]; /* SCSI sense data */
101 # if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
102 struct sigaction action
; /* Actions for POSIX signals */
103 # endif /* HAVE_SIGACTION && !HAVE_SIGSET */
107 * Make sure we have a valid resource name...
110 if (strncmp(resource
, "/dev/sg", 7) != 0)
112 fprintf(stderr
, _("ERROR: Bad SCSI device file \"%s\"!\n"), resource
);
113 return (CUPS_BACKEND_STOP
);
117 * Open the SCSI device file...
120 fputs("STATE: +connecting-to-device\n", stderr
);
124 if ((scsi_fd
= open(resource
, O_RDWR
| O_EXCL
)) == -1)
126 if (getenv("CLASS") != NULL
)
129 * If the CLASS environment variable is set, the job was submitted
130 * to a class and not to a specific queue. In this case, we want
131 * to abort immediately so that the job can be requeued on the next
132 * available printer in the class.
135 _cupsLangPuts(stderr
,
136 _("INFO: Unable to contact printer, queuing on next "
137 "printer in class...\n"));
140 * Sleep 5 seconds to keep the job from requeuing too rapidly...
145 return (CUPS_BACKEND_FAILED
);
148 if (errno
!= EAGAIN
&& errno
!= EBUSY
)
150 fprintf(stderr
, _("ERROR: Unable to open device file \"%s\": %s\n"),
151 resource
, strerror(errno
));
152 return (CUPS_BACKEND_FAILED
);
156 fputs(_("INFO: Printer busy; will retry in 30 seconds...\n"), stderr
);
161 while (scsi_fd
== -1);
163 fputs("STATE: -connecting-to-device\n", stderr
);
166 * Now that we are "connected" to the port, ignore SIGTERM so that we
167 * can finish out any page data the driver sends (e.g. to eject the
168 * current page... Only ignore SIGTERM if we are printing data from
169 * stdin (otherwise you can't cancel raw jobs...)
174 # ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
175 sigset(SIGTERM
, SIG_IGN
);
176 # elif defined(HAVE_SIGACTION)
177 memset(&action
, 0, sizeof(action
));
179 sigemptyset(&action
.sa_mask
);
180 action
.sa_handler
= SIG_IGN
;
181 sigaction(SIGTERM
, &action
, NULL
);
183 signal(SIGTERM
, SIG_IGN
);
184 # endif /* HAVE_SIGSET */
188 * Copy the print file to the device...
194 lseek(fd
, 0, SEEK_SET
);
196 while ((bytes
= read(fd
, buffer
, sizeof(buffer
))) > 0)
198 memset(&scsi_req
, 0, sizeof(scsi_req
));
200 scsi_req
.interface_id
= 'S';
201 scsi_req
.dxfer_direction
= SG_DXFER_TO_DEV
;
202 scsi_req
.cmd_len
= 6;
203 scsi_req
.mx_sb_len
= sizeof(scsi_sense
);
204 scsi_req
.iovec_count
= 0;
205 scsi_req
.dxfer_len
= bytes
;
206 scsi_req
.dxferp
= buffer
;
207 scsi_req
.cmdp
= scsi_cmd
;
208 scsi_req
.sbp
= scsi_sense
;
209 scsi_req
.timeout
= 60 * 1000;
211 scsi_cmd
[0] = 0x0a; /* Group 0 print command */
213 scsi_cmd
[2] = bytes
/ 65536;
214 scsi_cmd
[3] = bytes
/ 256;
218 for (try = 0; try < 10; try ++)
219 if (ioctl(scsi_fd
, SG_IO
, &scsi_req
) < 0 ||
220 scsi_req
.status
!= 0)
223 _("WARNING: SCSI command timed out (%d); retrying...\n"),
232 fprintf(stderr
, _("ERROR: Unable to send print data (%d)\n"),
235 return (CUPS_BACKEND_FAILED
);
243 * Close the device and return...
248 return (CUPS_BACKEND_OK
);
250 #endif /* !SG_DXFER_TO_DEV */
254 * End of "$Id: scsi-linux.c 6422 2007-03-30 20:49:37Z mike $".