4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
40 #include <sys/types.h>
41 #include <sys/socket.h>
43 #include <netinet/in.h>
48 static int netpr_send_message(int, char *, ...);
49 static int xfer_cfAfile(int, char *, char *, uint
);
52 bsd_print(int sockfd
, caddr_t pa
, np_bsdjob_t
* bsdjob
)
58 syslog(LOG_DEBUG
, "bsd_print");
60 filesize
= bsdjob
->np_data
->np_data_size
;
61 syslog(LOG_DEBUG
, "filesize is %d", filesize
);
64 if (netpr_send_message(sockfd
, "%c%s\n", XFER_REQUEST
,
65 bsdjob
->np_printer
) != 0) {
66 return (NETWORK_ERROR_SEND_RESPONSE
);
73 if (bsdjob
->np_print_order
== CONTROL_FIRST
) {
74 if ((xfer_cfAfile(sockfd
, bsdjob
->np_cfAfile
,
75 bsdjob
->np_cfAfilename
,
76 bsdjob
->np_cfAfilesize
)) != 0) {
77 (void) fprintf(stderr
,
78 gettext("Netpr: Error sending control file\n"));
79 syslog(LOG_DEBUG
, "Error sending control file");
80 return (NETWORK_ERROR_UNKNOWN
);
85 /* send msg - get ready for transfer */
87 if ((netpr_send_message(sockfd
, "%c%d %s\n", XFER_DATA
, filesize
,
88 bsdjob
->np_data
->np_dfAfilename
)) != 0) {
89 return (NETWORK_ERROR_SEND_RESPONSE
);
96 if ((xfer
= xfer_file(sockfd
, pa
, filesize
, bsdjob
->np_timeout
)) != 0) {
100 /* send msg - done */
101 if ((net
= netpr_send_message(sockfd
, "", NULL
)) != 0) {
102 (void) fprintf(stderr
,
103 gettext("Netpr: network error transfering %s returns: %d\n"),
104 bsdjob
->np_filename
, net
);
106 "network error transfering %s returns: %d",
107 bsdjob
->np_filename
, net
);
108 return (NETWORK_ERROR_WRITE_FAILED
);
115 if (bsdjob
->np_print_order
== DATA_FIRST
) {
116 if ((xfer_cfAfile(sockfd
, bsdjob
->np_cfAfile
,
117 bsdjob
->np_cfAfilename
,
118 bsdjob
->np_cfAfilesize
)) != 0) {
120 (void) fprintf(stderr
,
121 gettext("Netpr: Error sending control file\n"));
122 syslog(LOG_DEBUG
, "Error sending control file");
123 return (NETWORK_ERROR_UNKNOWN
);
131 xfer_file(int sockfd
, caddr_t pa
, int filesize
, int seed
)
139 syslog(LOG_DEBUG
, "xfer_file");
143 timeout
= seed
= seed
? seed
: 10;
147 syslog(LOG_DEBUG
, "xfer_file: write while loop => ctr = %d", ctr
);
148 syslog(LOG_DEBUG
, "xfer_file: timeout = %d", timeout
);
150 (void) signal(SIGALRM
, null_sighandler
);
152 nw
= write(sockfd
, pa
, ctr
);
153 syslog(LOG_DEBUG
, "xfer_file: write while loop => nw = %d", nw
);
155 if ((nw
== 0) || (nw
< 0)) {
156 if (timeout
< (seed
* 4)) {
157 (void) sleep(timeout
);
159 } else if (timeout
== (seed
* 4)) {
160 (void) sleep(timeout
);
164 * Send message to user once
166 if (error_msg
== 0) {
168 tell_lptell(ERRORMSG
,
169 gettext("Printer not accepting input;"
170 "possibly offline or out of paper."));
173 } else if (timeout
> (seed
* 4)) {
174 (void) sleep(timeout
);
176 timeout
= (seed
* 10);
183 tell_lptell(OKMSG
, "Current");
195 xfer_cfAfile(int sockfd
, char * cfAfile
, char * cfAname
, uint size
)
203 syslog(LOG_DEBUG
, "xfer_cfAfile");
205 if ((netpr_send_message(sockfd
, "%c%d %s\n", XFER_CONTROL
,
206 size
, cfAname
)) != 0) {
207 return (NETWORK_ERROR_MSG_FAILED
);
210 /* send the control file */
213 syslog(LOG_DEBUG
, "xfer_cfAfile : cfAfile %s", pa
);
214 syslog(LOG_DEBUG
, "xfer_cfAfile : size %d", size
);
216 /* send control file */
220 (void) signal(SIGALRM
, null_sighandler
);
222 nw
= write(sockfd
, pa
, size
);
226 (void) sleep(timeout
);
228 } else if (timeout
== 16) {
229 /* talk with the printer and see what's happening */
230 /* send message back to caller */
231 (void) sleep(timeout
);
235 tell_lptell(ERRORMSG
,
236 gettext("Printer not accepting input;"
237 "possibly offline or out of paper."));
239 } else if (timeout
> 16) {
240 (void) sleep(timeout
);
247 if (printererr
== 1) {
248 (void) fprintf(stderr
, gettext("Printer status ok\n"));
249 tell_lptell(OKMSG
, "Current");
253 /* send msg - done */
254 if (netpr_send_message(sockfd
, "", NULL
) != 0) {
255 return (NETWORK_ERROR_MSG_FAILED
);
262 * netpr_response() reads in a byte from the network printer
265 netpr_response(int nd
)
271 syslog(LOG_DEBUG
, "netpr_response");
273 (void) signal(SIGALRM
, null_sighandler
);
277 if ((read(nd
, &c
, 1) != 1)) {
279 if (firstloop
== 0) {
284 if (errno
== EINTR
) {
285 if (msg_given
== 0) {
286 tell_lptell(ERRORMSG
,
287 gettext("Printer not responding;"
288 "Either warming up or needs attention"));
291 "read hanging in netpr_response: %m");
296 "read in netpr_response failed: %m");
297 return (NETWORK_READ_RESPONSE_FAILED
);
303 "Printer returned error: %m");
304 return (NETWORK_PRINTER_REFUSED_CONN
);
307 tell_lptell(OKMSG
, "Current");
316 netpr_send_message(int nd
, char *fmt
, ...)
326 syslog(LOG_DEBUG
, "netpr_send_message");
328 (void) vsnprintf(buf
, sizeof (buf
), fmt
, ap
);
332 ctr
= (strlen(buf
) != 0) ? strlen(buf
) : 1;
334 syslog(LOG_DEBUG
, "netpr_send_message : ctr = %d", ctr
);
336 (void) signal(SIGALRM
, null_sighandler
);
338 nw
= write(nd
, pa
, ctr
);
339 syslog(LOG_DEBUG
, "netpr_send_message : nw = %d", nw
);
344 (void) sleep(timeout
);
346 } else if (timeout
== 16) {
347 (void) sleep(timeout
);
351 tell_lptell(ERRORMSG
,
352 gettext("Printer not accepting input;"
353 "possibly offline or out of paper."));
356 (void) sleep(timeout
);
361 tell_lptell(OKMSG
, "Current");
365 return (netpr_response(nd
));
369 * null() is to be used as a signal handler that does nothing. It is used in
370 * place of SIG_IGN, because we want the signal to be delivered and
371 * interupt the current system call.
375 null_sighandler(int i
)