xref: /titanic_41/usr/src/cmd/sendmail/libsm/findfp.c (revision 058561cbaa119a6f2659bc27ef343e1b47266bb2)
17c478bd9Sstevel@tonic-gate /*
2*058561cbSjbeck  * Copyright (c) 2000-2002, 2006 Sendmail, Inc. and its suppliers.
37c478bd9Sstevel@tonic-gate  *      All rights reserved.
47c478bd9Sstevel@tonic-gate  * Copyright (c) 1990, 1993
57c478bd9Sstevel@tonic-gate  *	The Regents of the University of California.  All rights reserved.
67c478bd9Sstevel@tonic-gate  *
77c478bd9Sstevel@tonic-gate  * This code is derived from software contributed to Berkeley by
87c478bd9Sstevel@tonic-gate  * Chris Torek.
97c478bd9Sstevel@tonic-gate  *
107c478bd9Sstevel@tonic-gate  * By using this file, you agree to the terms and conditions set
117c478bd9Sstevel@tonic-gate  * forth in the LICENSE file which can be found at the top level of
127c478bd9Sstevel@tonic-gate  * the sendmail distribution.
137c478bd9Sstevel@tonic-gate  */
147c478bd9Sstevel@tonic-gate 
157c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
167c478bd9Sstevel@tonic-gate 
177c478bd9Sstevel@tonic-gate #include <sm/gen.h>
18*058561cbSjbeck SM_RCSID("@(#)$Id: findfp.c,v 1.67 2006/08/28 21:24:46 ca Exp $")
197c478bd9Sstevel@tonic-gate #include <stdlib.h>
207c478bd9Sstevel@tonic-gate #include <unistd.h>
217c478bd9Sstevel@tonic-gate #include <sys/param.h>
227c478bd9Sstevel@tonic-gate #include <errno.h>
237c478bd9Sstevel@tonic-gate #include <string.h>
247c478bd9Sstevel@tonic-gate #include <syslog.h>
257c478bd9Sstevel@tonic-gate #include <sm/io.h>
267c478bd9Sstevel@tonic-gate #include <sm/assert.h>
277c478bd9Sstevel@tonic-gate #include <sm/heap.h>
287c478bd9Sstevel@tonic-gate #include <sm/string.h>
297c478bd9Sstevel@tonic-gate #include <sm/conf.h>
307c478bd9Sstevel@tonic-gate #include "local.h"
317c478bd9Sstevel@tonic-gate #include "glue.h"
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate bool	Sm_IO_DidInit;	/* IO system has been initialized? */
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate const char SmFileMagic[] = "sm_file";
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate /* An open type to map to fopen()-like behavior */
387c478bd9Sstevel@tonic-gate SM_FILE_T SmFtStdio_def =
397c478bd9Sstevel@tonic-gate     {SmFileMagic, 0, 0, 0, (SMRW|SMFBF), -1, {0, 0}, 0, 0, 0,
407c478bd9Sstevel@tonic-gate 	sm_stdclose, sm_stdread, sm_stdseek, sm_stdwrite,
417c478bd9Sstevel@tonic-gate 	sm_stdopen, sm_stdsetinfo, sm_stdgetinfo, SM_TIME_FOREVER,
427c478bd9Sstevel@tonic-gate 	SM_TIME_BLOCK, "stdio" };
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate /* An open type to map to fdopen()-like behavior */
457c478bd9Sstevel@tonic-gate SM_FILE_T SmFtStdiofd_def =
467c478bd9Sstevel@tonic-gate     {SmFileMagic, 0, 0, 0, (SMRW|SMFBF), -1, {0, 0}, 0, 0, 0,
477c478bd9Sstevel@tonic-gate 	sm_stdclose, sm_stdread, sm_stdseek, sm_stdwrite,
487c478bd9Sstevel@tonic-gate 	sm_stdfdopen, sm_stdsetinfo, sm_stdgetinfo, SM_TIME_FOREVER,
497c478bd9Sstevel@tonic-gate 	SM_TIME_BLOCK, "stdiofd" };
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate /* A string file type */
527c478bd9Sstevel@tonic-gate SM_FILE_T SmFtString_def =
537c478bd9Sstevel@tonic-gate     {SmFileMagic, 0, 0, 0, (SMRW|SMNBF), -1, {0, 0}, 0, 0, 0,
547c478bd9Sstevel@tonic-gate 	sm_strclose, sm_strread, sm_strseek, sm_strwrite,
557c478bd9Sstevel@tonic-gate 	sm_stropen, sm_strsetinfo, sm_strgetinfo, SM_TIME_FOREVER,
567c478bd9Sstevel@tonic-gate 	SM_TIME_BLOCK, "string" };
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate #if 0
597c478bd9Sstevel@tonic-gate /* A file type for syslog communications */
607c478bd9Sstevel@tonic-gate SM_FILE_T SmFtSyslog_def =
617c478bd9Sstevel@tonic-gate     {SmFileMagic, 0, 0, 0, (SMRW|SMNBF), -1, {0, 0}, 0, 0, 0,
627c478bd9Sstevel@tonic-gate 	sm_syslogclose, sm_syslogread, sm_syslogseek, sm_syslogwrite,
637c478bd9Sstevel@tonic-gate 	sm_syslogopen, sm_syslogsetinfo, sm_sysloggetinfo, SM_TIME_FOREVER,
647c478bd9Sstevel@tonic-gate 	SM_TIME_BLOCK, "syslog" };
657c478bd9Sstevel@tonic-gate #endif /* 0 */
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate #define NDYNAMIC 10		/* add ten more whenever necessary */
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate #define smio(flags, file, name)						\
707c478bd9Sstevel@tonic-gate     {SmFileMagic, 0, 0, 0, flags, file, {0}, 0, SmIoF+file, 0,		\
717c478bd9Sstevel@tonic-gate 	sm_stdclose, sm_stdread, sm_stdseek, sm_stdwrite,		\
727c478bd9Sstevel@tonic-gate 	sm_stdopen, sm_stdsetinfo, sm_stdgetinfo, SM_TIME_FOREVER,	\
737c478bd9Sstevel@tonic-gate 	SM_TIME_BLOCK, name}
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate /* sm_magic p r w flags file bf lbfsize cookie ival */
767c478bd9Sstevel@tonic-gate #define smstd(flags, file, name)					\
777c478bd9Sstevel@tonic-gate     {SmFileMagic, 0, 0, 0, flags, -1, {0}, 0, 0, file,			\
787c478bd9Sstevel@tonic-gate 	sm_stdioclose, sm_stdioread, sm_stdioseek, sm_stdiowrite,	\
797c478bd9Sstevel@tonic-gate 	sm_stdioopen, sm_stdiosetinfo, sm_stdiogetinfo, SM_TIME_FOREVER,\
807c478bd9Sstevel@tonic-gate 	SM_TIME_BLOCK, name}
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate /* A file type for interfacing to stdio FILE* streams. */
837c478bd9Sstevel@tonic-gate SM_FILE_T SmFtRealStdio_def = smstd(SMRW|SMNBF, -1, "realstdio");
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate 				/* the usual - (stdin + stdout + stderr) */
867c478bd9Sstevel@tonic-gate static SM_FILE_T usual[SM_IO_OPEN_MAX - 3];
877c478bd9Sstevel@tonic-gate static struct sm_glue smuglue = { 0, SM_IO_OPEN_MAX - 3, usual };
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate /* List of builtin automagically already open file pointers */
907c478bd9Sstevel@tonic-gate SM_FILE_T SmIoF[6] =
917c478bd9Sstevel@tonic-gate {
927c478bd9Sstevel@tonic-gate 	smio(SMRD|SMLBF, SMIOIN_FILENO, "smioin"),	/* smioin */
937c478bd9Sstevel@tonic-gate 	smio(SMWR|SMLBF, SMIOOUT_FILENO, "smioout"),	/* smioout */
947c478bd9Sstevel@tonic-gate 	smio(SMWR|SMNBF, SMIOERR_FILENO, "smioerr"),	/* smioerr */
957c478bd9Sstevel@tonic-gate 	smstd(SMRD|SMNBF, SMIOIN_FILENO, "smiostdin"),	/* smiostdin */
967c478bd9Sstevel@tonic-gate 	smstd(SMWR|SMNBF, SMIOOUT_FILENO, "smiostdout"),/* smiostdout */
977c478bd9Sstevel@tonic-gate 	smstd(SMWR|SMNBF, SMIOERR_FILENO, "smiostderr") /* smiostderr */
987c478bd9Sstevel@tonic-gate };
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate /* Structure containing list of currently open file pointers */
1017c478bd9Sstevel@tonic-gate struct sm_glue smglue = { &smuglue, 3, SmIoF };
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate /*
1047c478bd9Sstevel@tonic-gate **  SM_MOREGLUE -- adds more space for open file pointers
1057c478bd9Sstevel@tonic-gate **
1067c478bd9Sstevel@tonic-gate **	Parameters:
1077c478bd9Sstevel@tonic-gate **		n -- number of new spaces for file pointers
1087c478bd9Sstevel@tonic-gate **
1097c478bd9Sstevel@tonic-gate **	Returns:
1107c478bd9Sstevel@tonic-gate **		Raises an exception if no more memory.
1117c478bd9Sstevel@tonic-gate **		Otherwise, returns a pointer to new spaces.
1127c478bd9Sstevel@tonic-gate */
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate static struct sm_glue *sm_moreglue_x __P((int));
1157c478bd9Sstevel@tonic-gate static SM_FILE_T empty;
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate static struct sm_glue *
sm_moreglue_x(n)1187c478bd9Sstevel@tonic-gate sm_moreglue_x(n)
1197c478bd9Sstevel@tonic-gate 	register int n;
1207c478bd9Sstevel@tonic-gate {
1217c478bd9Sstevel@tonic-gate 	register struct sm_glue *g;
1227c478bd9Sstevel@tonic-gate 	register SM_FILE_T *p;
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate 	g = (struct sm_glue *) sm_pmalloc_x(sizeof(*g) + SM_ALIGN_BITS +
1257c478bd9Sstevel@tonic-gate 					    n * sizeof(SM_FILE_T));
1267c478bd9Sstevel@tonic-gate 	p = (SM_FILE_T *) SM_ALIGN(g + 1);
1277c478bd9Sstevel@tonic-gate 	g->gl_next = NULL;
1287c478bd9Sstevel@tonic-gate 	g->gl_niobs = n;
1297c478bd9Sstevel@tonic-gate 	g->gl_iobs = p;
1307c478bd9Sstevel@tonic-gate 	while (--n >= 0)
1317c478bd9Sstevel@tonic-gate 		*p++ = empty;
1327c478bd9Sstevel@tonic-gate 	return g;
1337c478bd9Sstevel@tonic-gate }
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate /*
1367c478bd9Sstevel@tonic-gate **  SM_FP -- allocate and initialize an SM_FILE structure
1377c478bd9Sstevel@tonic-gate **
1387c478bd9Sstevel@tonic-gate **	Parameters:
1397c478bd9Sstevel@tonic-gate **		t -- file type requested to be opened.
1407c478bd9Sstevel@tonic-gate **		flags -- control flags for file type behavior
1417c478bd9Sstevel@tonic-gate **		oldfp -- file pointer to reuse if available (optional)
1427c478bd9Sstevel@tonic-gate **
1437c478bd9Sstevel@tonic-gate **	Returns:
1447c478bd9Sstevel@tonic-gate **		Raises exception on memory exhaustion.
1457c478bd9Sstevel@tonic-gate **		Aborts if type is invalid.
1467c478bd9Sstevel@tonic-gate **		Otherwise, returns file pointer for requested file type.
1477c478bd9Sstevel@tonic-gate */
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate SM_FILE_T *
sm_fp(t,flags,oldfp)1507c478bd9Sstevel@tonic-gate sm_fp(t, flags, oldfp)
1517c478bd9Sstevel@tonic-gate 	const SM_FILE_T *t;
1527c478bd9Sstevel@tonic-gate 	const int flags;
1537c478bd9Sstevel@tonic-gate 	SM_FILE_T *oldfp;
1547c478bd9Sstevel@tonic-gate {
1557c478bd9Sstevel@tonic-gate 	register SM_FILE_T *fp;
1567c478bd9Sstevel@tonic-gate 	register int n;
1577c478bd9Sstevel@tonic-gate 	register struct sm_glue *g;
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate 	SM_REQUIRE(t->f_open && t->f_close && (t->f_read || t->f_write));
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate 	if (!Sm_IO_DidInit)
1627c478bd9Sstevel@tonic-gate 		sm_init();
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate 	if (oldfp != NULL)
1657c478bd9Sstevel@tonic-gate 	{
1667c478bd9Sstevel@tonic-gate 		fp = oldfp;
1677c478bd9Sstevel@tonic-gate 		goto found; /* for opening reusing an 'fp' */
1687c478bd9Sstevel@tonic-gate 	}
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate 	for (g = &smglue;; g = g->gl_next)
1717c478bd9Sstevel@tonic-gate 	{
1727c478bd9Sstevel@tonic-gate 		for (fp = g->gl_iobs, n = g->gl_niobs; --n >= 0; fp++)
1737c478bd9Sstevel@tonic-gate 			if (fp->sm_magic == NULL)
1747c478bd9Sstevel@tonic-gate 				goto found;
1757c478bd9Sstevel@tonic-gate 		if (g->gl_next == NULL)
1767c478bd9Sstevel@tonic-gate 			g->gl_next = sm_moreglue_x(NDYNAMIC);
1777c478bd9Sstevel@tonic-gate 	}
1787c478bd9Sstevel@tonic-gate found:
1797c478bd9Sstevel@tonic-gate 	fp->sm_magic = SmFileMagic; /* 'fp' now valid and in-use */
1807c478bd9Sstevel@tonic-gate 	fp->f_p = NULL;		/* no current pointer */
1817c478bd9Sstevel@tonic-gate 	fp->f_w = 0;		/* nothing to write */
1827c478bd9Sstevel@tonic-gate 	fp->f_r = 0;		/* nothing to read */
1837c478bd9Sstevel@tonic-gate 	fp->f_flags = flags;
1847c478bd9Sstevel@tonic-gate 	fp->f_file = -1;		/* no file */
1857c478bd9Sstevel@tonic-gate 	fp->f_bf.smb_base = NULL;	/* no buffer */
1867c478bd9Sstevel@tonic-gate 	fp->f_bf.smb_size = 0;	/* no buffer size with no buffer */
1877c478bd9Sstevel@tonic-gate 	fp->f_lbfsize = 0;	/* not line buffered */
1887c478bd9Sstevel@tonic-gate 	fp->f_flushfp = NULL;	/* no associated flush file */
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate 	fp->f_cookie = fp;	/* default: *open* overrides cookie setting */
1917c478bd9Sstevel@tonic-gate 	fp->f_close = t->f_close;	/* assign close function */
1927c478bd9Sstevel@tonic-gate 	fp->f_read = t->f_read;		/* assign read function */
1937c478bd9Sstevel@tonic-gate 	fp->f_seek = t->f_seek;		/* assign seek function */
1947c478bd9Sstevel@tonic-gate 	fp->f_write = t->f_write;	/* assign write function */
1957c478bd9Sstevel@tonic-gate 	fp->f_open = t->f_open;		/* assign open function */
1967c478bd9Sstevel@tonic-gate 	fp->f_setinfo = t->f_setinfo;	/* assign setinfo function */
1977c478bd9Sstevel@tonic-gate 	fp->f_getinfo = t->f_getinfo;	/* assign getinfo function */
1987c478bd9Sstevel@tonic-gate 	fp->f_type = t->f_type;		/* file type */
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate 	fp->f_ub.smb_base = NULL;	/* no ungetc buffer */
2017c478bd9Sstevel@tonic-gate 	fp->f_ub.smb_size = 0;		/* no size for no ungetc buffer */
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	if (fp->f_timeout == SM_TIME_DEFAULT)
2047c478bd9Sstevel@tonic-gate 		fp->f_timeout = SM_TIME_FOREVER;
2057c478bd9Sstevel@tonic-gate 	else
2067c478bd9Sstevel@tonic-gate 		fp->f_timeout = t->f_timeout; /* traditional behavior */
2077c478bd9Sstevel@tonic-gate 	fp->f_timeoutstate = SM_TIME_BLOCK; /* by default */
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate 	return fp;
2107c478bd9Sstevel@tonic-gate }
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate /*
2137c478bd9Sstevel@tonic-gate **  SM_CLEANUP -- cleanup function when exit called.
2147c478bd9Sstevel@tonic-gate **
2157c478bd9Sstevel@tonic-gate **	This function is registered via atexit().
2167c478bd9Sstevel@tonic-gate **
2177c478bd9Sstevel@tonic-gate **	Parameters:
2187c478bd9Sstevel@tonic-gate **		none
2197c478bd9Sstevel@tonic-gate **
2207c478bd9Sstevel@tonic-gate **	Returns:
2217c478bd9Sstevel@tonic-gate **		nothing.
2227c478bd9Sstevel@tonic-gate **
2237c478bd9Sstevel@tonic-gate **	Side Effects:
2247c478bd9Sstevel@tonic-gate **		flushes open files before they are forced closed
2257c478bd9Sstevel@tonic-gate */
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate void
sm_cleanup()2287c478bd9Sstevel@tonic-gate sm_cleanup()
2297c478bd9Sstevel@tonic-gate {
2307c478bd9Sstevel@tonic-gate 	int timeout = SM_TIME_DEFAULT;
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate 	(void) sm_fwalk(sm_flush, &timeout); /* `cheating' */
2337c478bd9Sstevel@tonic-gate }
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate /*
2367c478bd9Sstevel@tonic-gate **  SM_INIT -- called whenever sm_io's internal variables must be set up.
2377c478bd9Sstevel@tonic-gate **
2387c478bd9Sstevel@tonic-gate **	Parameters:
2397c478bd9Sstevel@tonic-gate **		none
2407c478bd9Sstevel@tonic-gate **
2417c478bd9Sstevel@tonic-gate **	Returns:
2427c478bd9Sstevel@tonic-gate **		none
2437c478bd9Sstevel@tonic-gate **
2447c478bd9Sstevel@tonic-gate **	Side Effects:
2457c478bd9Sstevel@tonic-gate **		Registers sm_cleanup() using atexit().
2467c478bd9Sstevel@tonic-gate */
2477c478bd9Sstevel@tonic-gate 
2487c478bd9Sstevel@tonic-gate void
sm_init()2497c478bd9Sstevel@tonic-gate sm_init()
2507c478bd9Sstevel@tonic-gate {
2517c478bd9Sstevel@tonic-gate 	if (Sm_IO_DidInit)	/* paranoia */
2527c478bd9Sstevel@tonic-gate 		return;
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate 	/* more paranoia: initialize pointers in a static variable */
2557c478bd9Sstevel@tonic-gate 	empty.f_type = NULL;
2567c478bd9Sstevel@tonic-gate 	empty.sm_magic = NULL;
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate 	/* make sure we clean up on exit */
2597c478bd9Sstevel@tonic-gate 	atexit(sm_cleanup);		/* conservative */
2607c478bd9Sstevel@tonic-gate 	Sm_IO_DidInit = true;
2617c478bd9Sstevel@tonic-gate }
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate /*
2647c478bd9Sstevel@tonic-gate **  SM_IO_SETINFO -- change info for an open file type (fp)
2657c478bd9Sstevel@tonic-gate **
2667c478bd9Sstevel@tonic-gate **	The generic SM_IO_WHAT_VECTORS is auto supplied for all file types.
2677c478bd9Sstevel@tonic-gate **	If the request is to set info other than SM_IO_WHAT_VECTORS then
2687c478bd9Sstevel@tonic-gate **	the request is passed on to the file type's specific setinfo vector.
2697c478bd9Sstevel@tonic-gate **	WARNING: this is working on an active/open file type.
2707c478bd9Sstevel@tonic-gate **
2717c478bd9Sstevel@tonic-gate **	Parameters:
2727c478bd9Sstevel@tonic-gate **		fp -- file to make the setting on
2737c478bd9Sstevel@tonic-gate **		what -- type of information to set
2747c478bd9Sstevel@tonic-gate **		valp -- structure to obtain info from
2757c478bd9Sstevel@tonic-gate **
2767c478bd9Sstevel@tonic-gate **	Returns:
2777c478bd9Sstevel@tonic-gate **		0 on success
2787c478bd9Sstevel@tonic-gate **		-1 on error and sets errno:
2797c478bd9Sstevel@tonic-gate **			- when what != SM_IO_WHAT_VECTORS and setinfo vector
2807c478bd9Sstevel@tonic-gate **				not set
2817c478bd9Sstevel@tonic-gate **			- when vectored setinfo returns -1
2827c478bd9Sstevel@tonic-gate */
2837c478bd9Sstevel@tonic-gate 
2847c478bd9Sstevel@tonic-gate int
sm_io_setinfo(fp,what,valp)2857c478bd9Sstevel@tonic-gate sm_io_setinfo(fp, what, valp)
2867c478bd9Sstevel@tonic-gate 	SM_FILE_T *fp;
2877c478bd9Sstevel@tonic-gate 	int what;
2887c478bd9Sstevel@tonic-gate 	void *valp;
2897c478bd9Sstevel@tonic-gate {
2907c478bd9Sstevel@tonic-gate 	SM_FILE_T *v = (SM_FILE_T *) valp;
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate 	SM_REQUIRE_ISA(fp, SmFileMagic);
2937c478bd9Sstevel@tonic-gate 	switch (what)
2947c478bd9Sstevel@tonic-gate 	{
2957c478bd9Sstevel@tonic-gate 	  case SM_IO_WHAT_VECTORS:
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate 		/*
2987c478bd9Sstevel@tonic-gate 		**  This is the "generic" available for all.
2997c478bd9Sstevel@tonic-gate 		**  This allows the function vectors to be replaced
3007c478bd9Sstevel@tonic-gate 		**  while the file type is active.
3017c478bd9Sstevel@tonic-gate 		*/
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate 		fp->f_close = v->f_close;
3047c478bd9Sstevel@tonic-gate 		fp->f_read = v->f_read;
3057c478bd9Sstevel@tonic-gate 		fp->f_seek = v->f_seek;
3067c478bd9Sstevel@tonic-gate 		fp->f_write = v->f_write;
3077c478bd9Sstevel@tonic-gate 		fp->f_open = v->f_open;
3087c478bd9Sstevel@tonic-gate 		fp->f_setinfo = v->f_setinfo;
3097c478bd9Sstevel@tonic-gate 		fp->f_getinfo = v->f_getinfo;
3107c478bd9Sstevel@tonic-gate 		sm_free(fp->f_type);
3117c478bd9Sstevel@tonic-gate 		fp->f_type = sm_strdup_x(v->f_type);
3127c478bd9Sstevel@tonic-gate 		return 0;
3137c478bd9Sstevel@tonic-gate 	  case SM_IO_WHAT_TIMEOUT:
3147c478bd9Sstevel@tonic-gate 		fp->f_timeout = *((int *)valp);
3157c478bd9Sstevel@tonic-gate 		return 0;
3167c478bd9Sstevel@tonic-gate 	}
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate 	/* Otherwise the vector will check it out */
3197c478bd9Sstevel@tonic-gate 	if (fp->f_setinfo == NULL)
3207c478bd9Sstevel@tonic-gate 	{
3217c478bd9Sstevel@tonic-gate 		errno = EINVAL;
3227c478bd9Sstevel@tonic-gate 		return -1;
3237c478bd9Sstevel@tonic-gate 	}
3247c478bd9Sstevel@tonic-gate 	else
3257c478bd9Sstevel@tonic-gate 		return (*fp->f_setinfo)(fp, what, valp);
3267c478bd9Sstevel@tonic-gate }
3277c478bd9Sstevel@tonic-gate 
3287c478bd9Sstevel@tonic-gate /*
3297c478bd9Sstevel@tonic-gate **  SM_IO_GETINFO -- get information for an active file type (fp)
3307c478bd9Sstevel@tonic-gate **
3317c478bd9Sstevel@tonic-gate **  This function supplies for all file types the answers for the
3327c478bd9Sstevel@tonic-gate **		three requests SM_IO_WHAT_VECTORS, SM_IO_WHAT_TYPE and
3337c478bd9Sstevel@tonic-gate **		SM_IO_WHAT_ISTYPE. Other requests are handled by the getinfo
3347c478bd9Sstevel@tonic-gate **		vector if available for the open file type.
3357c478bd9Sstevel@tonic-gate **	SM_IO_WHAT_VECTORS returns information for the file pointer vectors.
3367c478bd9Sstevel@tonic-gate **	SM_IO_WHAT_TYPE returns the type identifier for the file pointer
3377c478bd9Sstevel@tonic-gate **	SM_IO_WHAT_ISTYPE returns >0 if the passed in type matches the
3387c478bd9Sstevel@tonic-gate **		file pointer's type.
3397c478bd9Sstevel@tonic-gate **	SM_IO_IS_READABLE returns 1 if there is data available for reading,
3407c478bd9Sstevel@tonic-gate **		0 otherwise.
3417c478bd9Sstevel@tonic-gate **
3427c478bd9Sstevel@tonic-gate **	Parameters:
3437c478bd9Sstevel@tonic-gate **		fp -- file pointer for active file type
3447c478bd9Sstevel@tonic-gate **		what -- type of information request
3457c478bd9Sstevel@tonic-gate **		valp -- structure to place obtained info into
3467c478bd9Sstevel@tonic-gate **
3477c478bd9Sstevel@tonic-gate **	Returns:
3487c478bd9Sstevel@tonic-gate **		-1 on error and sets errno:
3497c478bd9Sstevel@tonic-gate **			- when valp==NULL and request expects otherwise
3507c478bd9Sstevel@tonic-gate **			- when request is not SM_IO_WHAT_VECTORS and not
3517c478bd9Sstevel@tonic-gate **				SM_IO_WHAT_TYPE and not SM_IO_WHAT_ISTYPE
3527c478bd9Sstevel@tonic-gate **				and getinfo vector is NULL
3537c478bd9Sstevel@tonic-gate **			- when getinfo type vector returns -1
3547c478bd9Sstevel@tonic-gate **		>=0 on success
3557c478bd9Sstevel@tonic-gate */
3567c478bd9Sstevel@tonic-gate 
3577c478bd9Sstevel@tonic-gate int
sm_io_getinfo(fp,what,valp)3587c478bd9Sstevel@tonic-gate sm_io_getinfo(fp, what, valp)
3597c478bd9Sstevel@tonic-gate 	SM_FILE_T *fp;
3607c478bd9Sstevel@tonic-gate 	int what;
3617c478bd9Sstevel@tonic-gate 	void *valp;
3627c478bd9Sstevel@tonic-gate {
3637c478bd9Sstevel@tonic-gate 	SM_FILE_T *v = (SM_FILE_T *) valp;
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate 	SM_REQUIRE_ISA(fp, SmFileMagic);
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate 	switch (what)
3687c478bd9Sstevel@tonic-gate 	{
3697c478bd9Sstevel@tonic-gate 	  case SM_IO_WHAT_VECTORS:
370*058561cbSjbeck 		if (valp == NULL)
371*058561cbSjbeck 		{
372*058561cbSjbeck 			errno = EINVAL;
373*058561cbSjbeck 			return -1;
374*058561cbSjbeck 		}
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate 		/* This is the "generic" available for all */
3777c478bd9Sstevel@tonic-gate 		v->f_close = fp->f_close;
3787c478bd9Sstevel@tonic-gate 		v->f_read = fp->f_read;
3797c478bd9Sstevel@tonic-gate 		v->f_seek = fp->f_seek;
3807c478bd9Sstevel@tonic-gate 		v->f_write = fp->f_write;
3817c478bd9Sstevel@tonic-gate 		v->f_open = fp->f_open;
3827c478bd9Sstevel@tonic-gate 		v->f_setinfo = fp->f_setinfo;
3837c478bd9Sstevel@tonic-gate 		v->f_getinfo = fp->f_getinfo;
3847c478bd9Sstevel@tonic-gate 		v->f_type = fp->f_type;
3857c478bd9Sstevel@tonic-gate 		return 0;
3867c478bd9Sstevel@tonic-gate 
3877c478bd9Sstevel@tonic-gate 	  case SM_IO_WHAT_TYPE:
3887c478bd9Sstevel@tonic-gate 		if (valp == NULL)
3897c478bd9Sstevel@tonic-gate 		{
3907c478bd9Sstevel@tonic-gate 			errno = EINVAL;
3917c478bd9Sstevel@tonic-gate 			return -1;
3927c478bd9Sstevel@tonic-gate 		}
3937c478bd9Sstevel@tonic-gate 		valp = sm_strdup_x(fp->f_type);
3947c478bd9Sstevel@tonic-gate 		return 0;
3957c478bd9Sstevel@tonic-gate 
3967c478bd9Sstevel@tonic-gate 	  case SM_IO_WHAT_ISTYPE:
3977c478bd9Sstevel@tonic-gate 		if (valp == NULL)
3987c478bd9Sstevel@tonic-gate 		{
3997c478bd9Sstevel@tonic-gate 			errno = EINVAL;
4007c478bd9Sstevel@tonic-gate 			return -1;
4017c478bd9Sstevel@tonic-gate 		}
4027c478bd9Sstevel@tonic-gate 		return strcmp(fp->f_type, valp) == 0;
4037c478bd9Sstevel@tonic-gate 
4047c478bd9Sstevel@tonic-gate 	  case SM_IO_IS_READABLE:
4057c478bd9Sstevel@tonic-gate 
4067c478bd9Sstevel@tonic-gate 		/* if there is data in the buffer, it must be readable */
4077c478bd9Sstevel@tonic-gate 		if (fp->f_r > 0)
4087c478bd9Sstevel@tonic-gate 			return 1;
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate 		/* otherwise query the underlying file */
4117c478bd9Sstevel@tonic-gate 		break;
4127c478bd9Sstevel@tonic-gate 
4137c478bd9Sstevel@tonic-gate 	   case SM_IO_WHAT_TIMEOUT:
4147c478bd9Sstevel@tonic-gate 		*((int *) valp) = fp->f_timeout;
4157c478bd9Sstevel@tonic-gate 		return 0;
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate 	  case SM_IO_WHAT_FD:
4187c478bd9Sstevel@tonic-gate 		if (fp->f_file > -1)
4197c478bd9Sstevel@tonic-gate 			return fp->f_file;
4207c478bd9Sstevel@tonic-gate 
4217c478bd9Sstevel@tonic-gate 		/* try the file type specific getinfo to see if it knows */
4227c478bd9Sstevel@tonic-gate 		break;
4237c478bd9Sstevel@tonic-gate 	}
4247c478bd9Sstevel@tonic-gate 
4257c478bd9Sstevel@tonic-gate 	/* Otherwise the vector will check it out */
4267c478bd9Sstevel@tonic-gate 	if (fp->f_getinfo == NULL)
4277c478bd9Sstevel@tonic-gate 	{
4287c478bd9Sstevel@tonic-gate 		errno = EINVAL;
4297c478bd9Sstevel@tonic-gate 		return -1;
4307c478bd9Sstevel@tonic-gate 	}
4317c478bd9Sstevel@tonic-gate 	return (*fp->f_getinfo)(fp, what, valp);
4327c478bd9Sstevel@tonic-gate }
433