]> git.ipfire.org Git - thirdparty/cups.git/blame - backend/scsi-irix.c
Merge changes from CUPS 1.5svn-r8849.
[thirdparty/cups.git] / backend / scsi-irix.c
CommitLineData
ef416fc2 1/*
2e4ff8af 2 * "$Id: scsi-irix.c 6834 2007-08-22 18:29:25Z mike $"
ef416fc2 3 *
4 * IRIX SCSI printer support for the Common UNIX Printing System (CUPS).
5 *
4d301e69 6 * Copyright 2007-2009 by Apple Inc.
ef416fc2 7 * Copyright 2003-2005 by Easy Software Products, all rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or
10 * without modification, are permitted provided that the
11 * following conditions are met:
12 *
13 * 1. Redistributions of source code must retain the above
14 * copyright notice, this list of conditions and the
15 * following disclaimer.
16 *
17 * 2. Redistributions in binary form must reproduce the
18 * above copyright notice, this list of conditions and
19 * the following disclaimer in the documentation and/or
20 * other materials provided with the distribution.
21 *
22 * 3. All advertising materials mentioning features or use
23 * of this software must display the following
24 * acknowledgement:
25 *
26 * This product includes software developed by Easy
27 * Software Products.
28 *
29 * 4. The name of Easy Software Products may not be used to
30 * endorse or promote products derived from this software
31 * without specific prior written permission.
32 *
33 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS
34 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
35 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
36 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
38 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
39 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
40 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
41 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
43 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
44 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
46 * DAMAGE.
47 *
48 * Contents:
49 *
50 * list_devices() - List the available SCSI printer devices.
51 * print_device() - Print a file to a SCSI device.
52 */
53
54/*
55 * Include necessary headers.
56 */
57
58#include <bstring.h> /* memcpy() and friends */
59#include <sys/dsreq.h> /* SCSI interface stuff */
60
61
62/*
63 * 'list_devices()' - List the available SCSI printer devices.
64 */
65
66void
67list_devices(void)
68{
8b450588
MS
69 printf("direct scsi \"Unknown\" \"%s\"\n",
70 _cupsLangString(cupsLangDefault(), _("SCSI Printer")));
ef416fc2 71}
72
73
74/*
75 * 'print_device()' - Print a file to a SCSI device.
76 */
77
78int /* O - Print status */
79print_device(const char *resource, /* I - SCSI device */
80 int fd, /* I - File to print */
81 int copies) /* I - Number of copies to print */
82{
83 int scsi_fd; /* SCSI file descriptor */
84 char buffer[8192]; /* Data buffer */
85 int bytes; /* Number of bytes */
86 int try; /* Current try */
87 dsreq_t scsi_req; /* SCSI request */
88 char scsi_cmd[6]; /* SCSI command data */
89#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
90 struct sigaction action; /* Actions for POSIX signals */
91#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
92
93
94 /*
95 * Make sure we have a valid resource name...
96 */
97
98 if (strncmp(resource, "/dev/scsi/", 10) != 0)
99 {
4d301e69 100 _cupsLangPrintf(stderr, _("ERROR: Bad SCSI device file \"%s\"\n"),
db1f069b 101 resource);
ef416fc2 102 return (CUPS_BACKEND_STOP);
103 }
104
105 /*
106 * Open the SCSI device file...
107 */
108
757d2cad 109 fputs("STATE: +connecting-to-device\n", stderr);
110
ef416fc2 111 do
112 {
113 if ((scsi_fd = open(resource, O_RDWR | O_EXCL)) == -1)
114 {
115 if (getenv("CLASS") != NULL)
116 {
117 /*
118 * If the CLASS environment variable is set, the job was submitted
119 * to a class and not to a specific queue. In this case, we want
120 * to abort immediately so that the job can be requeued on the next
121 * available printer in the class.
122 */
123
db1f069b
MS
124 _cupsLangPuts(stderr,
125 _("INFO: Unable to contact printer, queuing on next "
126 "printer in class...\n"));
ef416fc2 127
128 /*
129 * Sleep 5 seconds to keep the job from requeuing too rapidly...
130 */
131
132 sleep(5);
133
134 return (1);
135 }
136
137 if (errno != EAGAIN && errno != EBUSY)
138 {
db1f069b
MS
139 _cupsLangPrintf(stderr,
140 _("ERROR: Unable to open device file \"%s\": %s\n"),
141 resource, strerror(errno));
ef416fc2 142 return (CUPS_BACKEND_FAILED);
143 }
144 else
145 {
db1f069b
MS
146 _cupsLangPuts(stderr,
147 _("INFO: Printer busy; will retry in 30 seconds...\n"));
ef416fc2 148 sleep(30);
149 }
150 }
151 }
152 while (scsi_fd == -1);
153
757d2cad 154 fputs("STATE: -connecting-to-device\n", stderr);
155
ef416fc2 156 /*
157 * Now that we are "connected" to the port, ignore SIGTERM so that we
158 * can finish out any page data the driver sends (e.g. to eject the
159 * current page... Only ignore SIGTERM if we are printing data from
160 * stdin (otherwise you can't cancel raw jobs...)
161 */
162
163 if (fd != 0)
164 {
165#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
166 sigset(SIGTERM, SIG_IGN);
167#elif defined(HAVE_SIGACTION)
168 memset(&action, 0, sizeof(action));
169
170 sigemptyset(&action.sa_mask);
171 action.sa_handler = SIG_IGN;
172 sigaction(SIGTERM, &action, NULL);
173#else
174 signal(SIGTERM, SIG_IGN);
175#endif /* HAVE_SIGSET */
176 }
177
178 /*
179 * Copy the print file to the device...
180 */
181
182 while (copies > 0)
183 {
184 if (fd != 0)
185 lseek(fd, 0, SEEK_SET);
186
187 while ((bytes = read(fd, buffer, sizeof(buffer))) > 0)
188 {
189 memset(&scsi_req, 0, sizeof(scsi_req));
190
191 scsi_req.ds_flags = DSRQ_WRITE;
192 scsi_req.ds_time = 60 * 1000;
193 scsi_req.ds_cmdbuf = scsi_cmd;
194 scsi_req.ds_cmdlen = 6;
195 scsi_req.ds_databuf = buffer;
196 scsi_req.ds_datalen = bytes;
197
198 scsi_cmd[0] = 0x0a; /* Group 0 print command */
199 scsi_cmd[1] = 0x00;
200 scsi_cmd[2] = bytes / 65536;
201 scsi_cmd[3] = bytes / 256;
202 scsi_cmd[4] = bytes;
203 scsi_cmd[5] = 0x00;
204
205 for (try = 0; try < 10; try ++)
206 if (ioctl(scsi_fd, DS_ENTER, &scsi_req) < 0 ||
207 scsi_req.ds_status != 0)
208 {
db1f069b
MS
209 _cupsLangPrintf(stderr,
210 _("WARNING: SCSI command timed out (%d); "
211 "retrying...\n"), scsi_req.ds_status);
ef416fc2 212 sleep(try + 1);
213 }
214 else
215 break;
216
217 if (try >= 10)
218 {
db1f069b
MS
219 _cupsLangPrintf(stderr, _("ERROR: Unable to send print data (%d)\n"),
220 scsi_req.ds_status);
ef416fc2 221 close(scsi_fd);
222 return (CUPS_BACKEND_FAILED);
223 }
224 }
225
226 copies --;
227 }
228
229 /*
230 * Close the device and return...
231 */
232
233 close(fd);
234
235 return (CUPS_BACKEND_OK);
236}
237
238
239/*
2e4ff8af 240 * End of "$Id: scsi-irix.c 6834 2007-08-22 18:29:25Z mike $".
ef416fc2 241 */