xref: /onnv-gate/usr/src/cmd/lp/model/netpr/net.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate 
23*0Sstevel@tonic-gate /*
24*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
25*0Sstevel@tonic-gate  * Use is subject to license terms.
26*0Sstevel@tonic-gate  */
27*0Sstevel@tonic-gate 
28*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate #include <stdio.h>
31*0Sstevel@tonic-gate #include <stdlib.h>
32*0Sstevel@tonic-gate #include <stdarg.h>
33*0Sstevel@tonic-gate #include <libintl.h>
34*0Sstevel@tonic-gate #include <signal.h>
35*0Sstevel@tonic-gate #include <errno.h>
36*0Sstevel@tonic-gate #include <fcntl.h>
37*0Sstevel@tonic-gate #include <unistd.h>
38*0Sstevel@tonic-gate #include <string.h>
39*0Sstevel@tonic-gate #include <strings.h>
40*0Sstevel@tonic-gate #include <syslog.h>
41*0Sstevel@tonic-gate #include <sys/types.h>
42*0Sstevel@tonic-gate #include <sys/socket.h>
43*0Sstevel@tonic-gate #include <sys/file.h>
44*0Sstevel@tonic-gate #include <netinet/in.h>
45*0Sstevel@tonic-gate #include "netpr.h"
46*0Sstevel@tonic-gate 
47*0Sstevel@tonic-gate #define	TIMEOUT		1
48*0Sstevel@tonic-gate 
49*0Sstevel@tonic-gate static int netpr_send_message(int, char *, ...);
50*0Sstevel@tonic-gate static int xfer_cfAfile(int, char *, char *, uint);
51*0Sstevel@tonic-gate 
52*0Sstevel@tonic-gate int
53*0Sstevel@tonic-gate bsd_print(int sockfd, caddr_t pa, np_bsdjob_t * bsdjob)
54*0Sstevel@tonic-gate {
55*0Sstevel@tonic-gate 	int filesize;
56*0Sstevel@tonic-gate 	int xfer;
57*0Sstevel@tonic-gate 	int net;
58*0Sstevel@tonic-gate 
59*0Sstevel@tonic-gate 	syslog(LOG_DEBUG, "bsd_print");
60*0Sstevel@tonic-gate 
61*0Sstevel@tonic-gate 	filesize = bsdjob->np_data->np_data_size;
62*0Sstevel@tonic-gate 	syslog(LOG_DEBUG, "filesize is %d", filesize);
63*0Sstevel@tonic-gate 
64*0Sstevel@tonic-gate 
65*0Sstevel@tonic-gate 	if (netpr_send_message(sockfd, "%c%s\n", XFER_REQUEST,
66*0Sstevel@tonic-gate 		bsdjob->np_printer) != 0) {
67*0Sstevel@tonic-gate 		return (NETWORK_ERROR_SEND_RESPONSE);
68*0Sstevel@tonic-gate 	}
69*0Sstevel@tonic-gate 
70*0Sstevel@tonic-gate 	/*
71*0Sstevel@tonic-gate 	 * control file
72*0Sstevel@tonic-gate 	 */
73*0Sstevel@tonic-gate 
74*0Sstevel@tonic-gate 	if (bsdjob->np_print_order == CONTROL_FIRST) {
75*0Sstevel@tonic-gate 		if ((xfer_cfAfile(sockfd, bsdjob->np_cfAfile,
76*0Sstevel@tonic-gate 		    bsdjob->np_cfAfilename,
77*0Sstevel@tonic-gate 		    bsdjob->np_cfAfilesize)) != 0) {
78*0Sstevel@tonic-gate 			(void) fprintf(stderr,
79*0Sstevel@tonic-gate 			    gettext("Netpr: Error sending control file\n"));
80*0Sstevel@tonic-gate 			syslog(LOG_DEBUG, "Error sending control file");
81*0Sstevel@tonic-gate 			    return (NETWORK_ERROR_UNKNOWN);
82*0Sstevel@tonic-gate 
83*0Sstevel@tonic-gate 		}
84*0Sstevel@tonic-gate 	}
85*0Sstevel@tonic-gate 
86*0Sstevel@tonic-gate 	/* send msg - get ready for transfer */
87*0Sstevel@tonic-gate 
88*0Sstevel@tonic-gate 	if ((netpr_send_message(sockfd, "%c%d %s\n", XFER_DATA, filesize,
89*0Sstevel@tonic-gate 	    bsdjob->np_data->np_dfAfilename)) != 0) {
90*0Sstevel@tonic-gate 		return (NETWORK_ERROR_SEND_RESPONSE);
91*0Sstevel@tonic-gate 	}
92*0Sstevel@tonic-gate 
93*0Sstevel@tonic-gate 	/*
94*0Sstevel@tonic-gate 	 * send the file
95*0Sstevel@tonic-gate 	 */
96*0Sstevel@tonic-gate 
97*0Sstevel@tonic-gate 	if ((xfer = xfer_file(sockfd, pa, filesize, bsdjob->np_timeout)) != 0) {
98*0Sstevel@tonic-gate 		return (xfer);
99*0Sstevel@tonic-gate 	}
100*0Sstevel@tonic-gate 
101*0Sstevel@tonic-gate 	/* send msg - done */
102*0Sstevel@tonic-gate 	if ((net = netpr_send_message(sockfd, "", NULL)) != 0) {
103*0Sstevel@tonic-gate 		(void) fprintf(stderr,
104*0Sstevel@tonic-gate 		gettext("Netpr: network error transfering %s returns: %d\n"),
105*0Sstevel@tonic-gate 			bsdjob->np_filename, net);
106*0Sstevel@tonic-gate 		syslog(LOG_DEBUG,
107*0Sstevel@tonic-gate 			"network error transfering %s returns: %d",
108*0Sstevel@tonic-gate 			bsdjob->np_filename, net);
109*0Sstevel@tonic-gate 		return (NETWORK_ERROR_WRITE_FAILED);
110*0Sstevel@tonic-gate 	}
111*0Sstevel@tonic-gate 
112*0Sstevel@tonic-gate 	/*
113*0Sstevel@tonic-gate 	 * control file
114*0Sstevel@tonic-gate 	 */
115*0Sstevel@tonic-gate 
116*0Sstevel@tonic-gate 	if (bsdjob->np_print_order == DATA_FIRST) {
117*0Sstevel@tonic-gate 		if ((xfer_cfAfile(sockfd, bsdjob->np_cfAfile,
118*0Sstevel@tonic-gate 		    bsdjob->np_cfAfilename,
119*0Sstevel@tonic-gate 		    bsdjob->np_cfAfilesize)) != 0) {
120*0Sstevel@tonic-gate 
121*0Sstevel@tonic-gate 			(void) fprintf(stderr,
122*0Sstevel@tonic-gate 			    gettext("Netpr: Error sending control file\n"));
123*0Sstevel@tonic-gate 			    syslog(LOG_DEBUG, "Error sending control file");
124*0Sstevel@tonic-gate 			    return (NETWORK_ERROR_UNKNOWN);
125*0Sstevel@tonic-gate 		}
126*0Sstevel@tonic-gate 	}
127*0Sstevel@tonic-gate 
128*0Sstevel@tonic-gate 	return (0);
129*0Sstevel@tonic-gate }
130*0Sstevel@tonic-gate 
131*0Sstevel@tonic-gate int
132*0Sstevel@tonic-gate xfer_file(int sockfd, caddr_t pa, int filesize, int seed)
133*0Sstevel@tonic-gate {
134*0Sstevel@tonic-gate 	int ctr;
135*0Sstevel@tonic-gate 	int timeout;
136*0Sstevel@tonic-gate 	int nw;
137*0Sstevel@tonic-gate 	int error_msg = 0;
138*0Sstevel@tonic-gate 	int pause = 0;
139*0Sstevel@tonic-gate 
140*0Sstevel@tonic-gate 	syslog(LOG_DEBUG, "xfer_file");
141*0Sstevel@tonic-gate 
142*0Sstevel@tonic-gate 	/* send file */
143*0Sstevel@tonic-gate 	ctr = filesize;
144*0Sstevel@tonic-gate 	timeout = seed = seed ? seed : 10;
145*0Sstevel@tonic-gate 
146*0Sstevel@tonic-gate 	while (ctr > 0) {
147*0Sstevel@tonic-gate 
148*0Sstevel@tonic-gate 	syslog(LOG_DEBUG, "xfer_file: write while loop => ctr = %d", ctr);
149*0Sstevel@tonic-gate 	syslog(LOG_DEBUG, "xfer_file: timeout = %d", timeout);
150*0Sstevel@tonic-gate 
151*0Sstevel@tonic-gate 		(void) signal(SIGALRM, null_sighandler);
152*0Sstevel@tonic-gate 		(void) alarm(2);
153*0Sstevel@tonic-gate 		nw = write(sockfd, pa, ctr);
154*0Sstevel@tonic-gate 	syslog(LOG_DEBUG, "xfer_file: write while loop => nw = %d", nw);
155*0Sstevel@tonic-gate 		(void) alarm(0);
156*0Sstevel@tonic-gate 		if ((nw == 0) || (nw < 0)) {
157*0Sstevel@tonic-gate 			if (timeout < (seed * 4)) {
158*0Sstevel@tonic-gate 				(void) sleep(timeout);
159*0Sstevel@tonic-gate 				timeout *= 2;
160*0Sstevel@tonic-gate 			} else if (timeout == (seed * 4)) {
161*0Sstevel@tonic-gate 				(void) sleep(timeout);
162*0Sstevel@tonic-gate 				timeout *= 2;
163*0Sstevel@tonic-gate 
164*0Sstevel@tonic-gate 				/*
165*0Sstevel@tonic-gate 				 * Send message to user once
166*0Sstevel@tonic-gate 				 */
167*0Sstevel@tonic-gate 				if (error_msg == 0) {
168*0Sstevel@tonic-gate 					error_msg++;
169*0Sstevel@tonic-gate 					tell_lptell(ERRORMSG,
170*0Sstevel@tonic-gate 					gettext("Printer not accepting input;"
171*0Sstevel@tonic-gate 					"possibly offline or out of paper."));
172*0Sstevel@tonic-gate 				}
173*0Sstevel@tonic-gate 
174*0Sstevel@tonic-gate 			} else if (timeout > (seed * 4)) {
175*0Sstevel@tonic-gate 				(void) sleep(timeout);
176*0Sstevel@tonic-gate 				if (pause++ > 3)
177*0Sstevel@tonic-gate 					timeout = (seed * 10);
178*0Sstevel@tonic-gate 			}
179*0Sstevel@tonic-gate 
180*0Sstevel@tonic-gate 		} else {
181*0Sstevel@tonic-gate 			ctr -= nw;
182*0Sstevel@tonic-gate 			pa += nw;
183*0Sstevel@tonic-gate 			if (error_msg) {
184*0Sstevel@tonic-gate 				tell_lptell(OKMSG, "Current");
185*0Sstevel@tonic-gate 				error_msg = 0;
186*0Sstevel@tonic-gate 				pause = 0;
187*0Sstevel@tonic-gate 			}
188*0Sstevel@tonic-gate 			timeout = seed;
189*0Sstevel@tonic-gate 		}
190*0Sstevel@tonic-gate 	}
191*0Sstevel@tonic-gate 
192*0Sstevel@tonic-gate 	return (E_SUCCESS);
193*0Sstevel@tonic-gate }
194*0Sstevel@tonic-gate 
195*0Sstevel@tonic-gate static int
196*0Sstevel@tonic-gate xfer_cfAfile(int sockfd, char * cfAfile, char * cfAname, uint size)
197*0Sstevel@tonic-gate {
198*0Sstevel@tonic-gate 	int ctr;
199*0Sstevel@tonic-gate 	caddr_t pa;
200*0Sstevel@tonic-gate 	int nw = 0;
201*0Sstevel@tonic-gate 	int timeout;
202*0Sstevel@tonic-gate 	int printererr;
203*0Sstevel@tonic-gate 
204*0Sstevel@tonic-gate 	syslog(LOG_DEBUG, "xfer_cfAfile");
205*0Sstevel@tonic-gate 
206*0Sstevel@tonic-gate 	if ((netpr_send_message(sockfd, "%c%d %s\n", XFER_CONTROL,
207*0Sstevel@tonic-gate 		size, cfAname)) != 0) {
208*0Sstevel@tonic-gate 		return (NETWORK_ERROR_MSG_FAILED);
209*0Sstevel@tonic-gate 	}
210*0Sstevel@tonic-gate 
211*0Sstevel@tonic-gate 	/* send the control file */
212*0Sstevel@tonic-gate 	pa = cfAfile;
213*0Sstevel@tonic-gate 	ctr = size;
214*0Sstevel@tonic-gate 	syslog(LOG_DEBUG, "xfer_cfAfile : cfAfile %s", pa);
215*0Sstevel@tonic-gate 	syslog(LOG_DEBUG, "xfer_cfAfile : size %d", size);
216*0Sstevel@tonic-gate 
217*0Sstevel@tonic-gate 	/* send control file */
218*0Sstevel@tonic-gate 	timeout = TIMEOUT;
219*0Sstevel@tonic-gate 	printererr = 0;
220*0Sstevel@tonic-gate 	while (ctr > 0) {
221*0Sstevel@tonic-gate 		(void) signal(SIGALRM, null_sighandler);
222*0Sstevel@tonic-gate 		(void) alarm(2);
223*0Sstevel@tonic-gate 		nw = write(sockfd, pa, size);
224*0Sstevel@tonic-gate 		(void) alarm(0);
225*0Sstevel@tonic-gate 		if (nw <= 0) {
226*0Sstevel@tonic-gate 			if (timeout < 16) {
227*0Sstevel@tonic-gate 				(void) sleep(timeout);
228*0Sstevel@tonic-gate 				timeout *= 2;
229*0Sstevel@tonic-gate 			} else if (timeout == 16) {
230*0Sstevel@tonic-gate 			/* talk with the printer and see what's happening */
231*0Sstevel@tonic-gate 				/* send message back to caller */
232*0Sstevel@tonic-gate 				(void) sleep(timeout);
233*0Sstevel@tonic-gate 				timeout *= 2;
234*0Sstevel@tonic-gate 				printererr = 1;
235*0Sstevel@tonic-gate 
236*0Sstevel@tonic-gate 				tell_lptell(ERRORMSG,
237*0Sstevel@tonic-gate 				gettext("Printer not accepting input;"
238*0Sstevel@tonic-gate 				"possibly offline or out of paper."));
239*0Sstevel@tonic-gate 
240*0Sstevel@tonic-gate 			} else if (timeout > 16) {
241*0Sstevel@tonic-gate 				(void) sleep(timeout);
242*0Sstevel@tonic-gate 			}
243*0Sstevel@tonic-gate 		}
244*0Sstevel@tonic-gate 		ctr -= nw;
245*0Sstevel@tonic-gate 		pa += nw;
246*0Sstevel@tonic-gate 	}
247*0Sstevel@tonic-gate 
248*0Sstevel@tonic-gate 	if (printererr == 1) {
249*0Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("Printer status ok\n"));
250*0Sstevel@tonic-gate 		tell_lptell(OKMSG, "Current");
251*0Sstevel@tonic-gate 	}
252*0Sstevel@tonic-gate 
253*0Sstevel@tonic-gate 
254*0Sstevel@tonic-gate 	/* send msg - done */
255*0Sstevel@tonic-gate 	if (netpr_send_message(sockfd, "", NULL) != 0) {
256*0Sstevel@tonic-gate 		return (NETWORK_ERROR_MSG_FAILED);
257*0Sstevel@tonic-gate 	}
258*0Sstevel@tonic-gate 
259*0Sstevel@tonic-gate 	return (0);
260*0Sstevel@tonic-gate }
261*0Sstevel@tonic-gate 
262*0Sstevel@tonic-gate /*
263*0Sstevel@tonic-gate  *  netpr_response() reads in a byte from the network printer
264*0Sstevel@tonic-gate  */
265*0Sstevel@tonic-gate static int
266*0Sstevel@tonic-gate netpr_response(int nd)
267*0Sstevel@tonic-gate {
268*0Sstevel@tonic-gate 	char    c;
269*0Sstevel@tonic-gate 	int msg_given = 0;
270*0Sstevel@tonic-gate 	int firstloop = 0;
271*0Sstevel@tonic-gate 
272*0Sstevel@tonic-gate 	syslog(LOG_DEBUG, "netpr_response");
273*0Sstevel@tonic-gate 
274*0Sstevel@tonic-gate 	(void) signal(SIGALRM, null_sighandler);
275*0Sstevel@tonic-gate 	(void) alarm(2);
276*0Sstevel@tonic-gate 	while (1) {
277*0Sstevel@tonic-gate 		errno = 0;
278*0Sstevel@tonic-gate 		if ((read(nd, &c, 1) != 1)) {
279*0Sstevel@tonic-gate 
280*0Sstevel@tonic-gate 			if (firstloop == 0) {
281*0Sstevel@tonic-gate 				(void) alarm(0);
282*0Sstevel@tonic-gate 				firstloop++;
283*0Sstevel@tonic-gate 			}
284*0Sstevel@tonic-gate 
285*0Sstevel@tonic-gate 			if (errno == EINTR) {
286*0Sstevel@tonic-gate 				if (msg_given == 0) {
287*0Sstevel@tonic-gate 				    tell_lptell(ERRORMSG,
288*0Sstevel@tonic-gate 				    gettext("Printer not responding;"
289*0Sstevel@tonic-gate 				    "Either warming up or needs attention"));
290*0Sstevel@tonic-gate 				    msg_given++;
291*0Sstevel@tonic-gate 				    syslog(LOG_DEBUG,
292*0Sstevel@tonic-gate 					"read hanging in netpr_response: %m");
293*0Sstevel@tonic-gate 				}
294*0Sstevel@tonic-gate 
295*0Sstevel@tonic-gate 			} else {
296*0Sstevel@tonic-gate 				syslog(LOG_DEBUG,
297*0Sstevel@tonic-gate 					"read in netpr_response failed: %m");
298*0Sstevel@tonic-gate 				return (NETWORK_READ_RESPONSE_FAILED);
299*0Sstevel@tonic-gate 			}
300*0Sstevel@tonic-gate 
301*0Sstevel@tonic-gate 		} else {
302*0Sstevel@tonic-gate 			if (c) {
303*0Sstevel@tonic-gate 				syslog(LOG_DEBUG,
304*0Sstevel@tonic-gate 					"Printer returned error: %m");
305*0Sstevel@tonic-gate 				return (NETWORK_PRINTER_REFUSED_CONN);
306*0Sstevel@tonic-gate 			} else {
307*0Sstevel@tonic-gate 				if (msg_given)
308*0Sstevel@tonic-gate 					tell_lptell(OKMSG, "Current");
309*0Sstevel@tonic-gate 				return (0);
310*0Sstevel@tonic-gate 			}
311*0Sstevel@tonic-gate 		}
312*0Sstevel@tonic-gate 	}
313*0Sstevel@tonic-gate 
314*0Sstevel@tonic-gate }
315*0Sstevel@tonic-gate 
316*0Sstevel@tonic-gate static int
317*0Sstevel@tonic-gate netpr_send_message(int nd, char *fmt, ...)
318*0Sstevel@tonic-gate {
319*0Sstevel@tonic-gate 	char    buf[BUFSIZ];
320*0Sstevel@tonic-gate 	int ctr;
321*0Sstevel@tonic-gate 	char * pa;
322*0Sstevel@tonic-gate 	va_list ap;
323*0Sstevel@tonic-gate 	int timeout = 1;
324*0Sstevel@tonic-gate 	int nw;
325*0Sstevel@tonic-gate 	int err_msg = 0;
326*0Sstevel@tonic-gate 
327*0Sstevel@tonic-gate 	syslog(LOG_DEBUG, "netpr_send_message");
328*0Sstevel@tonic-gate 	va_start(ap, fmt);
329*0Sstevel@tonic-gate 	(void) vsnprintf(buf, sizeof (buf), fmt, ap);
330*0Sstevel@tonic-gate 	va_end(ap);
331*0Sstevel@tonic-gate 
332*0Sstevel@tonic-gate 	pa = buf;
333*0Sstevel@tonic-gate 	ctr = (strlen(buf) != 0) ? strlen(buf) : 1;
334*0Sstevel@tonic-gate 
335*0Sstevel@tonic-gate 	syslog(LOG_DEBUG, "netpr_send_message : ctr = %d", ctr);
336*0Sstevel@tonic-gate 	while (ctr > 0) {
337*0Sstevel@tonic-gate 		(void) signal(SIGALRM, null_sighandler);
338*0Sstevel@tonic-gate 		(void) alarm(2);
339*0Sstevel@tonic-gate 		nw = write(nd, pa, ctr);
340*0Sstevel@tonic-gate 	syslog(LOG_DEBUG, "netpr_send_message : nw = %d", nw);
341*0Sstevel@tonic-gate 		(void) alarm(0);
342*0Sstevel@tonic-gate 
343*0Sstevel@tonic-gate 		if (nw <= 0) {
344*0Sstevel@tonic-gate 			if (timeout < 16) {
345*0Sstevel@tonic-gate 				(void) sleep(timeout);
346*0Sstevel@tonic-gate 				timeout *= 2;
347*0Sstevel@tonic-gate 			} else if (timeout == 16) {
348*0Sstevel@tonic-gate 				(void) sleep(timeout);
349*0Sstevel@tonic-gate 				timeout *= 2;
350*0Sstevel@tonic-gate 				if (err_msg == 0) {
351*0Sstevel@tonic-gate 					err_msg++;
352*0Sstevel@tonic-gate 					tell_lptell(ERRORMSG,
353*0Sstevel@tonic-gate 					gettext("Printer not accepting input;"
354*0Sstevel@tonic-gate 					"possibly offline or out of paper."));
355*0Sstevel@tonic-gate 				}
356*0Sstevel@tonic-gate 			} else
357*0Sstevel@tonic-gate 				(void) sleep(timeout);
358*0Sstevel@tonic-gate 		} else {
359*0Sstevel@tonic-gate 			ctr -= nw;
360*0Sstevel@tonic-gate 			pa += nw;
361*0Sstevel@tonic-gate 			if (err_msg)
362*0Sstevel@tonic-gate 				tell_lptell(OKMSG, "Current");
363*0Sstevel@tonic-gate 		}
364*0Sstevel@tonic-gate 	}
365*0Sstevel@tonic-gate 
366*0Sstevel@tonic-gate 	return (netpr_response(nd));
367*0Sstevel@tonic-gate }
368*0Sstevel@tonic-gate 
369*0Sstevel@tonic-gate /*
370*0Sstevel@tonic-gate  *  null() is to be used as a signal handler that does nothing.  It is used in
371*0Sstevel@tonic-gate  *      place of SIG_IGN, because we want the signal to be delivered and
372*0Sstevel@tonic-gate  *      interupt the current system call.
373*0Sstevel@tonic-gate  */
374*0Sstevel@tonic-gate /*ARGSUSED*/
375*0Sstevel@tonic-gate void
376*0Sstevel@tonic-gate null_sighandler(int i)
377*0Sstevel@tonic-gate {
378*0Sstevel@tonic-gate }
379