1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate /*
30*7c478bd9Sstevel@tonic-gate  * General utility routines.
31*7c478bd9Sstevel@tonic-gate  */
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate #include <syslog.h>
34*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
35*7c478bd9Sstevel@tonic-gate #include <stdio.h>
36*7c478bd9Sstevel@tonic-gate #include <stdarg.h>
37*7c478bd9Sstevel@tonic-gate #include <strings.h>
38*7c478bd9Sstevel@tonic-gate #include <time.h>
39*7c478bd9Sstevel@tonic-gate #include <errno.h>
40*7c478bd9Sstevel@tonic-gate #include <libintl.h>
41*7c478bd9Sstevel@tonic-gate #include <unistd.h>
42*7c478bd9Sstevel@tonic-gate #include "inetd_impl.h"
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate 
45*7c478bd9Sstevel@tonic-gate /* location of inetd's debug log file */
46*7c478bd9Sstevel@tonic-gate #define	DEBUG_LOG_FILE		"/var/tmp/inetd.log"
47*7c478bd9Sstevel@tonic-gate 
48*7c478bd9Sstevel@tonic-gate /* size of buffer used in msg() to expand printf() like messages into */
49*7c478bd9Sstevel@tonic-gate #define	MSG_BUF_SIZE		1024
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate /* size of buffer used in msg() to store a date/time string */
52*7c478bd9Sstevel@tonic-gate #define	TIME_BUF_SIZE		50
53*7c478bd9Sstevel@tonic-gate 
54*7c478bd9Sstevel@tonic-gate /* number of pollfd we grow the pollfd array by at a time in set_pollfd() */
55*7c478bd9Sstevel@tonic-gate #define	POLLFDS_GROWTH_SIZE	16
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate /* enumeration of message types supported by msg() */
58*7c478bd9Sstevel@tonic-gate typedef enum {
59*7c478bd9Sstevel@tonic-gate 	MT_ERROR,
60*7c478bd9Sstevel@tonic-gate 	MT_DEBUG,
61*7c478bd9Sstevel@tonic-gate 	MT_WARN
62*7c478bd9Sstevel@tonic-gate } si_msg_type_t;
63*7c478bd9Sstevel@tonic-gate 
64*7c478bd9Sstevel@tonic-gate /*
65*7c478bd9Sstevel@tonic-gate  * Collection of information for each method type.
66*7c478bd9Sstevel@tonic-gate  * NOTE:  This table is indexed into using the instance_method_t
67*7c478bd9Sstevel@tonic-gate  * enumeration, so the ordering needs to be kept in synch.
68*7c478bd9Sstevel@tonic-gate  */
69*7c478bd9Sstevel@tonic-gate method_type_info_t methods[] = {
70*7c478bd9Sstevel@tonic-gate 	{IM_START, START_METHOD_NAME, IIS_NONE},
71*7c478bd9Sstevel@tonic-gate 	{IM_ONLINE, ONLINE_METHOD_NAME, IIS_ONLINE},
72*7c478bd9Sstevel@tonic-gate 	{IM_OFFLINE, OFFLINE_METHOD_NAME, IIS_OFFLINE},
73*7c478bd9Sstevel@tonic-gate 	{IM_DISABLE, DISABLE_METHOD_NAME, IIS_DISABLED},
74*7c478bd9Sstevel@tonic-gate 	{IM_REFRESH, REFRESH_METHOD_NAME, IIS_ONLINE},
75*7c478bd9Sstevel@tonic-gate 	{IM_NONE, "none", IIS_NONE}
76*7c478bd9Sstevel@tonic-gate };
77*7c478bd9Sstevel@tonic-gate 
78*7c478bd9Sstevel@tonic-gate struct pollfd	*poll_fds = NULL;
79*7c478bd9Sstevel@tonic-gate nfds_t		num_pollfds;
80*7c478bd9Sstevel@tonic-gate static FILE	*debug_fp = NULL;
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate boolean_t	logging_enabled;
83*7c478bd9Sstevel@tonic-gate 
84*7c478bd9Sstevel@tonic-gate void
85*7c478bd9Sstevel@tonic-gate msg_init(void)
86*7c478bd9Sstevel@tonic-gate {
87*7c478bd9Sstevel@tonic-gate 	openlog(SYSLOG_IDENT, LOG_PID|LOG_CONS, LOG_DAEMON);
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate 	/* Try once at startup to open the log file. */
90*7c478bd9Sstevel@tonic-gate 	debug_fp = fopen(DEBUG_LOG_FILE, "r+");
91*7c478bd9Sstevel@tonic-gate 	if (debug_fp != NULL)
92*7c478bd9Sstevel@tonic-gate 		(void) fseeko(debug_fp, 0, SEEK_END);
93*7c478bd9Sstevel@tonic-gate 	logging_enabled = B_TRUE;
94*7c478bd9Sstevel@tonic-gate }
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate void
97*7c478bd9Sstevel@tonic-gate msg_fini(void)
98*7c478bd9Sstevel@tonic-gate {
99*7c478bd9Sstevel@tonic-gate 	logging_enabled = B_FALSE;
100*7c478bd9Sstevel@tonic-gate 	if (debug_fp != NULL) {
101*7c478bd9Sstevel@tonic-gate 		(void) fclose(debug_fp);
102*7c478bd9Sstevel@tonic-gate 		debug_fp = NULL;
103*7c478bd9Sstevel@tonic-gate 	}
104*7c478bd9Sstevel@tonic-gate 	closelog();
105*7c478bd9Sstevel@tonic-gate }
106*7c478bd9Sstevel@tonic-gate 
107*7c478bd9Sstevel@tonic-gate /*
108*7c478bd9Sstevel@tonic-gate  * Outputs a msg. If 'type' is set tp MT_ERROR or MT_WARN the message goes
109*7c478bd9Sstevel@tonic-gate  * to syslog with severitys LOG_ERROR and LOG_WARN respectively. For all
110*7c478bd9Sstevel@tonic-gate  * values of 'type' the message is written to the debug log file, if it
111*7c478bd9Sstevel@tonic-gate  * was openable when inetd started.
112*7c478bd9Sstevel@tonic-gate  */
113*7c478bd9Sstevel@tonic-gate static void
114*7c478bd9Sstevel@tonic-gate msg(si_msg_type_t type, const char *format, va_list ap)
115*7c478bd9Sstevel@tonic-gate {
116*7c478bd9Sstevel@tonic-gate 	/*
117*7c478bd9Sstevel@tonic-gate 	 * Use a stack buffer so we stand more chance of reporting a
118*7c478bd9Sstevel@tonic-gate 	 * memory shortage failure.
119*7c478bd9Sstevel@tonic-gate 	 */
120*7c478bd9Sstevel@tonic-gate 	char		buf[MSG_BUF_SIZE];
121*7c478bd9Sstevel@tonic-gate 	char		timebuf[TIME_BUF_SIZE];
122*7c478bd9Sstevel@tonic-gate 
123*7c478bd9Sstevel@tonic-gate 	if (!logging_enabled)
124*7c478bd9Sstevel@tonic-gate 		return;
125*7c478bd9Sstevel@tonic-gate 
126*7c478bd9Sstevel@tonic-gate 	(void) vsnprintf(buf, sizeof (buf), format, ap);
127*7c478bd9Sstevel@tonic-gate 
128*7c478bd9Sstevel@tonic-gate 	/*
129*7c478bd9Sstevel@tonic-gate 	 * Log error and warning messages to syslog with appropriate severity.
130*7c478bd9Sstevel@tonic-gate 	 */
131*7c478bd9Sstevel@tonic-gate 	if (type == MT_ERROR) {
132*7c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, "%s", buf);
133*7c478bd9Sstevel@tonic-gate 	} else if (type == MT_WARN) {
134*7c478bd9Sstevel@tonic-gate 		syslog(LOG_WARNING, "%s", buf);
135*7c478bd9Sstevel@tonic-gate 	}
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate 	if (debug_fp != NULL) {
138*7c478bd9Sstevel@tonic-gate 		struct tm	tms;
139*7c478bd9Sstevel@tonic-gate 		time_t		tm;
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate 		/*
142*7c478bd9Sstevel@tonic-gate 		 * We managed to open the log file at startup. Log all
143*7c478bd9Sstevel@tonic-gate 		 * message types there - in addition to syslog.
144*7c478bd9Sstevel@tonic-gate 		 */
145*7c478bd9Sstevel@tonic-gate 		tm = time(NULL);
146*7c478bd9Sstevel@tonic-gate 		(void) strftime(timebuf, sizeof (timebuf), NULL,
147*7c478bd9Sstevel@tonic-gate 		    localtime_r(&tm, &tms));
148*7c478bd9Sstevel@tonic-gate 		(void) fputs(timebuf, debug_fp);
149*7c478bd9Sstevel@tonic-gate 		(void) fputs(": ", debug_fp);
150*7c478bd9Sstevel@tonic-gate 
151*7c478bd9Sstevel@tonic-gate 		if (type == MT_ERROR) {
152*7c478bd9Sstevel@tonic-gate 			(void) fputs("ERROR: ", debug_fp);
153*7c478bd9Sstevel@tonic-gate 		} else if (type == MT_DEBUG) {
154*7c478bd9Sstevel@tonic-gate 			(void) fputs("DEBUG: ", debug_fp);
155*7c478bd9Sstevel@tonic-gate 		} else if (type == MT_WARN) {
156*7c478bd9Sstevel@tonic-gate 			(void) fputs("WARN: ", debug_fp);
157*7c478bd9Sstevel@tonic-gate 		}
158*7c478bd9Sstevel@tonic-gate 
159*7c478bd9Sstevel@tonic-gate 		(void) fputs(buf, debug_fp);
160*7c478bd9Sstevel@tonic-gate 
161*7c478bd9Sstevel@tonic-gate 		if (buf[strlen(buf) - 1] != '\n')
162*7c478bd9Sstevel@tonic-gate 			(void) fputc('\n', debug_fp);
163*7c478bd9Sstevel@tonic-gate 
164*7c478bd9Sstevel@tonic-gate 		(void) fflush(debug_fp);
165*7c478bd9Sstevel@tonic-gate 	}
166*7c478bd9Sstevel@tonic-gate }
167*7c478bd9Sstevel@tonic-gate 
168*7c478bd9Sstevel@tonic-gate /*
169*7c478bd9Sstevel@tonic-gate  * Output a warning message. Unlike error_msg(), syslog doesn't get told
170*7c478bd9Sstevel@tonic-gate  * to log to the console if syslogd isn't around.
171*7c478bd9Sstevel@tonic-gate  */
172*7c478bd9Sstevel@tonic-gate void
173*7c478bd9Sstevel@tonic-gate warn_msg(const char *format, ...)
174*7c478bd9Sstevel@tonic-gate {
175*7c478bd9Sstevel@tonic-gate 	va_list ap;
176*7c478bd9Sstevel@tonic-gate 
177*7c478bd9Sstevel@tonic-gate 	closelog();
178*7c478bd9Sstevel@tonic-gate 	openlog(SYSLOG_IDENT, LOG_PID, LOG_DAEMON);
179*7c478bd9Sstevel@tonic-gate 
180*7c478bd9Sstevel@tonic-gate 	va_start(ap, format);
181*7c478bd9Sstevel@tonic-gate 	msg(MT_WARN, format, ap);
182*7c478bd9Sstevel@tonic-gate 	va_end(ap);
183*7c478bd9Sstevel@tonic-gate 
184*7c478bd9Sstevel@tonic-gate 	closelog();
185*7c478bd9Sstevel@tonic-gate 	openlog(SYSLOG_IDENT, LOG_PID|LOG_CONS, LOG_DAEMON);
186*7c478bd9Sstevel@tonic-gate }
187*7c478bd9Sstevel@tonic-gate 
188*7c478bd9Sstevel@tonic-gate void
189*7c478bd9Sstevel@tonic-gate debug_msg(const char *format, ...)
190*7c478bd9Sstevel@tonic-gate {
191*7c478bd9Sstevel@tonic-gate 	va_list ap;
192*7c478bd9Sstevel@tonic-gate 
193*7c478bd9Sstevel@tonic-gate 	va_start(ap, format);
194*7c478bd9Sstevel@tonic-gate 	msg(MT_DEBUG, format, ap);
195*7c478bd9Sstevel@tonic-gate 	va_end(ap);
196*7c478bd9Sstevel@tonic-gate }
197*7c478bd9Sstevel@tonic-gate 
198*7c478bd9Sstevel@tonic-gate void
199*7c478bd9Sstevel@tonic-gate error_msg(const char *format, ...)
200*7c478bd9Sstevel@tonic-gate {
201*7c478bd9Sstevel@tonic-gate 	va_list ap;
202*7c478bd9Sstevel@tonic-gate 
203*7c478bd9Sstevel@tonic-gate 	va_start(ap, format);
204*7c478bd9Sstevel@tonic-gate 	msg(MT_ERROR, format, ap);
205*7c478bd9Sstevel@tonic-gate 	va_end(ap);
206*7c478bd9Sstevel@tonic-gate }
207*7c478bd9Sstevel@tonic-gate 
208*7c478bd9Sstevel@tonic-gate void
209*7c478bd9Sstevel@tonic-gate poll_fini(void)
210*7c478bd9Sstevel@tonic-gate {
211*7c478bd9Sstevel@tonic-gate 	if (poll_fds != NULL) {
212*7c478bd9Sstevel@tonic-gate 		free(poll_fds);
213*7c478bd9Sstevel@tonic-gate 		poll_fds = NULL;
214*7c478bd9Sstevel@tonic-gate 	}
215*7c478bd9Sstevel@tonic-gate }
216*7c478bd9Sstevel@tonic-gate 
217*7c478bd9Sstevel@tonic-gate struct pollfd *
218*7c478bd9Sstevel@tonic-gate find_pollfd(int fd)
219*7c478bd9Sstevel@tonic-gate {
220*7c478bd9Sstevel@tonic-gate 	nfds_t n;
221*7c478bd9Sstevel@tonic-gate 
222*7c478bd9Sstevel@tonic-gate 	for (n = 0; n < num_pollfds; n++) {
223*7c478bd9Sstevel@tonic-gate 		if (poll_fds[n].fd == fd)
224*7c478bd9Sstevel@tonic-gate 			return (&(poll_fds[n]));
225*7c478bd9Sstevel@tonic-gate 	}
226*7c478bd9Sstevel@tonic-gate 	return (NULL);
227*7c478bd9Sstevel@tonic-gate }
228*7c478bd9Sstevel@tonic-gate 
229*7c478bd9Sstevel@tonic-gate int
230*7c478bd9Sstevel@tonic-gate set_pollfd(int fd, uint16_t events)
231*7c478bd9Sstevel@tonic-gate {
232*7c478bd9Sstevel@tonic-gate 	struct pollfd	*p;
233*7c478bd9Sstevel@tonic-gate 	int		i;
234*7c478bd9Sstevel@tonic-gate 
235*7c478bd9Sstevel@tonic-gate 	debug_msg("Entering set_pollfd, fd: %d, num_pollfds: %d, fds: %x,"
236*7c478bd9Sstevel@tonic-gate 	    " events: %hu", fd, num_pollfds, poll_fds, events);
237*7c478bd9Sstevel@tonic-gate 
238*7c478bd9Sstevel@tonic-gate 	p = find_pollfd(fd);
239*7c478bd9Sstevel@tonic-gate 	if ((p == NULL) && ((p = find_pollfd(-1)) == NULL)) {
240*7c478bd9Sstevel@tonic-gate 		if ((p = realloc(poll_fds,
241*7c478bd9Sstevel@tonic-gate 		    ((num_pollfds + POLLFDS_GROWTH_SIZE) *
242*7c478bd9Sstevel@tonic-gate 		    sizeof (struct pollfd)))) == NULL) {
243*7c478bd9Sstevel@tonic-gate 			return (-1);
244*7c478bd9Sstevel@tonic-gate 		}
245*7c478bd9Sstevel@tonic-gate 		poll_fds = p;
246*7c478bd9Sstevel@tonic-gate 
247*7c478bd9Sstevel@tonic-gate 		for (i = 1; i < POLLFDS_GROWTH_SIZE; i++)
248*7c478bd9Sstevel@tonic-gate 			poll_fds[num_pollfds + i].fd = -1;
249*7c478bd9Sstevel@tonic-gate 
250*7c478bd9Sstevel@tonic-gate 		p = &poll_fds[num_pollfds];
251*7c478bd9Sstevel@tonic-gate 		num_pollfds += POLLFDS_GROWTH_SIZE;
252*7c478bd9Sstevel@tonic-gate 	}
253*7c478bd9Sstevel@tonic-gate 
254*7c478bd9Sstevel@tonic-gate 	p->fd = fd;
255*7c478bd9Sstevel@tonic-gate 	p->events = events;
256*7c478bd9Sstevel@tonic-gate 	p->revents = 0;
257*7c478bd9Sstevel@tonic-gate 
258*7c478bd9Sstevel@tonic-gate 	return (0);
259*7c478bd9Sstevel@tonic-gate }
260*7c478bd9Sstevel@tonic-gate 
261*7c478bd9Sstevel@tonic-gate void
262*7c478bd9Sstevel@tonic-gate clear_pollfd(int fd)
263*7c478bd9Sstevel@tonic-gate {
264*7c478bd9Sstevel@tonic-gate 	struct pollfd *p;
265*7c478bd9Sstevel@tonic-gate 
266*7c478bd9Sstevel@tonic-gate 	if ((p = find_pollfd(fd)) != NULL) {
267*7c478bd9Sstevel@tonic-gate 		p->fd = -1;
268*7c478bd9Sstevel@tonic-gate 		p->events = 0;
269*7c478bd9Sstevel@tonic-gate 		p->revents = 0;
270*7c478bd9Sstevel@tonic-gate 	}
271*7c478bd9Sstevel@tonic-gate }
272*7c478bd9Sstevel@tonic-gate 
273*7c478bd9Sstevel@tonic-gate boolean_t
274*7c478bd9Sstevel@tonic-gate isset_pollfd(int fd)
275*7c478bd9Sstevel@tonic-gate {
276*7c478bd9Sstevel@tonic-gate 	struct pollfd *p = find_pollfd(fd);
277*7c478bd9Sstevel@tonic-gate 
278*7c478bd9Sstevel@tonic-gate 	return ((p != NULL) && (p->revents & POLLIN));
279*7c478bd9Sstevel@tonic-gate }
280*7c478bd9Sstevel@tonic-gate 
281*7c478bd9Sstevel@tonic-gate /*
282*7c478bd9Sstevel@tonic-gate  * An extension of read() that keeps retrying until either the full request has
283*7c478bd9Sstevel@tonic-gate  * completed, the other end of the connection/pipe is closed, no data is
284*7c478bd9Sstevel@tonic-gate  * readable for a non-blocking socket/pipe, or an unexpected error occurs.
285*7c478bd9Sstevel@tonic-gate  * Returns 0 if the data is successfully read, 1 if the other end of the pipe/
286*7c478bd9Sstevel@tonic-gate  * socket is closed or there's nothing to read from a non-blocking socket/pipe,
287*7c478bd9Sstevel@tonic-gate  * else -1 if an unexpected error occurs.
288*7c478bd9Sstevel@tonic-gate  */
289*7c478bd9Sstevel@tonic-gate int
290*7c478bd9Sstevel@tonic-gate safe_read(int fd, void *buf, size_t sz)
291*7c478bd9Sstevel@tonic-gate {
292*7c478bd9Sstevel@tonic-gate 	int	ret;
293*7c478bd9Sstevel@tonic-gate 	size_t  cnt = 0;
294*7c478bd9Sstevel@tonic-gate 	char    *cp = (char *)buf;
295*7c478bd9Sstevel@tonic-gate 
296*7c478bd9Sstevel@tonic-gate 	if (sz == 0)
297*7c478bd9Sstevel@tonic-gate 		return (0);
298*7c478bd9Sstevel@tonic-gate 
299*7c478bd9Sstevel@tonic-gate 	do {
300*7c478bd9Sstevel@tonic-gate 		switch (ret = read(fd, cp + cnt, sz - cnt)) {
301*7c478bd9Sstevel@tonic-gate 		case 0:			/* other end of pipe/socket closed */
302*7c478bd9Sstevel@tonic-gate 			return (1);
303*7c478bd9Sstevel@tonic-gate 		case -1:
304*7c478bd9Sstevel@tonic-gate 			if (errno == EAGAIN) {		/* nothing to read */
305*7c478bd9Sstevel@tonic-gate 				return (1);
306*7c478bd9Sstevel@tonic-gate 			} else if (errno != EINTR) {
307*7c478bd9Sstevel@tonic-gate 				error_msg(gettext("Unexpected read error: %s"),
308*7c478bd9Sstevel@tonic-gate 				    strerror(errno));
309*7c478bd9Sstevel@tonic-gate 				return (-1);
310*7c478bd9Sstevel@tonic-gate 			}
311*7c478bd9Sstevel@tonic-gate 			break;
312*7c478bd9Sstevel@tonic-gate 
313*7c478bd9Sstevel@tonic-gate 		default:
314*7c478bd9Sstevel@tonic-gate 			cnt += ret;
315*7c478bd9Sstevel@tonic-gate 		}
316*7c478bd9Sstevel@tonic-gate 	} while (cnt != sz);
317*7c478bd9Sstevel@tonic-gate 
318*7c478bd9Sstevel@tonic-gate 	return (0);
319*7c478bd9Sstevel@tonic-gate }
320*7c478bd9Sstevel@tonic-gate 
321*7c478bd9Sstevel@tonic-gate /*
322*7c478bd9Sstevel@tonic-gate  * Return B_TRUE if instance 'inst' has exceeded its configured maximum
323*7c478bd9Sstevel@tonic-gate  * concurrent copies limit, else B_FALSE.
324*7c478bd9Sstevel@tonic-gate  */
325*7c478bd9Sstevel@tonic-gate boolean_t
326*7c478bd9Sstevel@tonic-gate copies_limit_exceeded(instance_t *inst)
327*7c478bd9Sstevel@tonic-gate {
328*7c478bd9Sstevel@tonic-gate 	/* any value <=0 means that copies limits are disabled */
329*7c478bd9Sstevel@tonic-gate 	return ((inst->config->basic->max_copies > 0) &&
330*7c478bd9Sstevel@tonic-gate 	    (inst->copies >= inst->config->basic->max_copies));
331*7c478bd9Sstevel@tonic-gate }
332*7c478bd9Sstevel@tonic-gate 
333*7c478bd9Sstevel@tonic-gate /*
334*7c478bd9Sstevel@tonic-gate  * Cancel the method/con-rate offline timer associated with the instance.
335*7c478bd9Sstevel@tonic-gate  */
336*7c478bd9Sstevel@tonic-gate void
337*7c478bd9Sstevel@tonic-gate cancel_inst_timer(instance_t *inst)
338*7c478bd9Sstevel@tonic-gate {
339*7c478bd9Sstevel@tonic-gate 	(void) iu_cancel_timer(timer_queue, inst->timer_id, NULL);
340*7c478bd9Sstevel@tonic-gate 	inst->timer_id = -1;
341*7c478bd9Sstevel@tonic-gate }
342*7c478bd9Sstevel@tonic-gate 
343*7c478bd9Sstevel@tonic-gate /*
344*7c478bd9Sstevel@tonic-gate  * Cancel the bind retry timer associated with the instance.
345*7c478bd9Sstevel@tonic-gate  */
346*7c478bd9Sstevel@tonic-gate void
347*7c478bd9Sstevel@tonic-gate cancel_bind_timer(instance_t *inst)
348*7c478bd9Sstevel@tonic-gate {
349*7c478bd9Sstevel@tonic-gate 	(void) iu_cancel_timer(timer_queue, inst->bind_timer_id, NULL);
350*7c478bd9Sstevel@tonic-gate 	inst->bind_timer_id = -1;
351*7c478bd9Sstevel@tonic-gate }
352*7c478bd9Sstevel@tonic-gate 
353*7c478bd9Sstevel@tonic-gate void
354*7c478bd9Sstevel@tonic-gate enable_blocking(int fd)
355*7c478bd9Sstevel@tonic-gate {
356*7c478bd9Sstevel@tonic-gate 	int flags = fcntl(fd, F_GETFL, 0);
357*7c478bd9Sstevel@tonic-gate 	(void) fcntl(fd, F_SETFL, (flags & ~O_NONBLOCK));
358*7c478bd9Sstevel@tonic-gate }
359*7c478bd9Sstevel@tonic-gate 
360*7c478bd9Sstevel@tonic-gate void
361*7c478bd9Sstevel@tonic-gate disable_blocking(int fd)
362*7c478bd9Sstevel@tonic-gate {
363*7c478bd9Sstevel@tonic-gate 	int flags = fcntl(fd, F_GETFL, 0);
364*7c478bd9Sstevel@tonic-gate 	(void) fcntl(fd, F_SETFL, (flags | O_NONBLOCK));
365*7c478bd9Sstevel@tonic-gate }
366