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 * 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 * 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 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 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 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 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