xref: /titanic_50/usr/src/cmd/sendmail/libsm/strio.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright (c) 2000-2002, 2004 Sendmail, Inc. and its suppliers.
3*7c478bd9Sstevel@tonic-gate  *      All rights reserved.
4*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1990, 1993
5*7c478bd9Sstevel@tonic-gate  *	The Regents of the University of California.  All rights reserved.
6*7c478bd9Sstevel@tonic-gate  *
7*7c478bd9Sstevel@tonic-gate  * This code is derived from software contributed to Berkeley by
8*7c478bd9Sstevel@tonic-gate  * Chris Torek.
9*7c478bd9Sstevel@tonic-gate  *
10*7c478bd9Sstevel@tonic-gate  * By using this file, you agree to the terms and conditions set
11*7c478bd9Sstevel@tonic-gate  * forth in the LICENSE file which can be found at the top level of
12*7c478bd9Sstevel@tonic-gate  * the sendmail distribution.
13*7c478bd9Sstevel@tonic-gate  */
14*7c478bd9Sstevel@tonic-gate 
15*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
16*7c478bd9Sstevel@tonic-gate 
17*7c478bd9Sstevel@tonic-gate #include <sm/gen.h>
18*7c478bd9Sstevel@tonic-gate SM_IDSTR(id, "@(#)$Id: strio.c,v 1.43 2004/08/03 20:48:30 ca Exp $")
19*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
20*7c478bd9Sstevel@tonic-gate #include <unistd.h>
21*7c478bd9Sstevel@tonic-gate #include <fcntl.h>
22*7c478bd9Sstevel@tonic-gate #include <string.h>
23*7c478bd9Sstevel@tonic-gate #include <errno.h>
24*7c478bd9Sstevel@tonic-gate #include <sm/rpool.h>
25*7c478bd9Sstevel@tonic-gate #include <sm/io.h>
26*7c478bd9Sstevel@tonic-gate #include <sm/heap.h>
27*7c478bd9Sstevel@tonic-gate #include <sm/conf.h>
28*7c478bd9Sstevel@tonic-gate #include "local.h"
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate static int	sm_strsetmode __P((SM_FILE_T*, const int *));
31*7c478bd9Sstevel@tonic-gate static int	sm_strgetmode __P((SM_FILE_T*, int *));
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate /*
34*7c478bd9Sstevel@tonic-gate **  Cookie structure for the "strio" file type
35*7c478bd9Sstevel@tonic-gate */
36*7c478bd9Sstevel@tonic-gate 
37*7c478bd9Sstevel@tonic-gate struct sm_str_obj
38*7c478bd9Sstevel@tonic-gate {
39*7c478bd9Sstevel@tonic-gate 	char		*strio_base;
40*7c478bd9Sstevel@tonic-gate 	char		*strio_end;
41*7c478bd9Sstevel@tonic-gate 	size_t		strio_size;
42*7c478bd9Sstevel@tonic-gate 	size_t		strio_offset;
43*7c478bd9Sstevel@tonic-gate 	int		strio_flags;
44*7c478bd9Sstevel@tonic-gate 	const void	*strio_rpool;
45*7c478bd9Sstevel@tonic-gate };
46*7c478bd9Sstevel@tonic-gate 
47*7c478bd9Sstevel@tonic-gate typedef struct sm_str_obj SM_STR_OBJ_T;
48*7c478bd9Sstevel@tonic-gate 
49*7c478bd9Sstevel@tonic-gate /*
50*7c478bd9Sstevel@tonic-gate **  SM_STRGROW -- increase storage space for string
51*7c478bd9Sstevel@tonic-gate **
52*7c478bd9Sstevel@tonic-gate **	Parameters:
53*7c478bd9Sstevel@tonic-gate **		s -- current cookie
54*7c478bd9Sstevel@tonic-gate **		size -- new storage size request
55*7c478bd9Sstevel@tonic-gate **
56*7c478bd9Sstevel@tonic-gate **	Returns:
57*7c478bd9Sstevel@tonic-gate **		true iff successful.
58*7c478bd9Sstevel@tonic-gate */
59*7c478bd9Sstevel@tonic-gate 
60*7c478bd9Sstevel@tonic-gate static bool sm_strgrow __P((SM_STR_OBJ_T *, size_t));
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate static bool
63*7c478bd9Sstevel@tonic-gate sm_strgrow(s, size)
64*7c478bd9Sstevel@tonic-gate 	SM_STR_OBJ_T *s;
65*7c478bd9Sstevel@tonic-gate 	size_t size;
66*7c478bd9Sstevel@tonic-gate {
67*7c478bd9Sstevel@tonic-gate 	register void *p;
68*7c478bd9Sstevel@tonic-gate 
69*7c478bd9Sstevel@tonic-gate 	if (s->strio_size >= size)
70*7c478bd9Sstevel@tonic-gate 		return true;
71*7c478bd9Sstevel@tonic-gate 	p = sm_realloc(s->strio_base, size);
72*7c478bd9Sstevel@tonic-gate 	if (p == NULL)
73*7c478bd9Sstevel@tonic-gate 		return false;
74*7c478bd9Sstevel@tonic-gate 	s->strio_base = p;
75*7c478bd9Sstevel@tonic-gate 	s->strio_end = s->strio_base + size;
76*7c478bd9Sstevel@tonic-gate 	s->strio_size = size;
77*7c478bd9Sstevel@tonic-gate 	return true;
78*7c478bd9Sstevel@tonic-gate }
79*7c478bd9Sstevel@tonic-gate 
80*7c478bd9Sstevel@tonic-gate /*
81*7c478bd9Sstevel@tonic-gate **  SM_STRREAD -- read a portion of the string
82*7c478bd9Sstevel@tonic-gate **
83*7c478bd9Sstevel@tonic-gate **	Parameters:
84*7c478bd9Sstevel@tonic-gate **		fp -- the file pointer
85*7c478bd9Sstevel@tonic-gate **		buf -- location to place read data
86*7c478bd9Sstevel@tonic-gate **		n -- number of bytes to read
87*7c478bd9Sstevel@tonic-gate **
88*7c478bd9Sstevel@tonic-gate **	Returns:
89*7c478bd9Sstevel@tonic-gate **		Failure: -1 and sets errno
90*7c478bd9Sstevel@tonic-gate **		Success: >=0, number of bytes read
91*7c478bd9Sstevel@tonic-gate */
92*7c478bd9Sstevel@tonic-gate 
93*7c478bd9Sstevel@tonic-gate ssize_t
94*7c478bd9Sstevel@tonic-gate sm_strread(fp, buf, n)
95*7c478bd9Sstevel@tonic-gate 	SM_FILE_T *fp;
96*7c478bd9Sstevel@tonic-gate 	char *buf;
97*7c478bd9Sstevel@tonic-gate 	size_t n;
98*7c478bd9Sstevel@tonic-gate {
99*7c478bd9Sstevel@tonic-gate 	register SM_STR_OBJ_T *s = fp->f_cookie;
100*7c478bd9Sstevel@tonic-gate 	int len;
101*7c478bd9Sstevel@tonic-gate 
102*7c478bd9Sstevel@tonic-gate 	if (!(s->strio_flags & SMRD) && !(s->strio_flags & SMRW))
103*7c478bd9Sstevel@tonic-gate 	{
104*7c478bd9Sstevel@tonic-gate 		errno = EBADF;
105*7c478bd9Sstevel@tonic-gate 		return -1;
106*7c478bd9Sstevel@tonic-gate 	}
107*7c478bd9Sstevel@tonic-gate 	len = SM_MIN(s->strio_size - s->strio_offset, n);
108*7c478bd9Sstevel@tonic-gate 	(void) memmove(buf, s->strio_base + s->strio_offset, len);
109*7c478bd9Sstevel@tonic-gate 	s->strio_offset += len;
110*7c478bd9Sstevel@tonic-gate 	return len;
111*7c478bd9Sstevel@tonic-gate }
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate /*
114*7c478bd9Sstevel@tonic-gate **  SM_STRWRITE -- write a portion of the string
115*7c478bd9Sstevel@tonic-gate **
116*7c478bd9Sstevel@tonic-gate **	Parameters:
117*7c478bd9Sstevel@tonic-gate **		fp -- the file pointer
118*7c478bd9Sstevel@tonic-gate **		buf -- location of data for writing
119*7c478bd9Sstevel@tonic-gate **		n -- number of bytes to write
120*7c478bd9Sstevel@tonic-gate **
121*7c478bd9Sstevel@tonic-gate **	Returns:
122*7c478bd9Sstevel@tonic-gate **		Failure: -1 and sets errno
123*7c478bd9Sstevel@tonic-gate **		Success: >=0, number of bytes written
124*7c478bd9Sstevel@tonic-gate */
125*7c478bd9Sstevel@tonic-gate 
126*7c478bd9Sstevel@tonic-gate ssize_t
127*7c478bd9Sstevel@tonic-gate sm_strwrite(fp, buf, n)
128*7c478bd9Sstevel@tonic-gate 	SM_FILE_T *fp;
129*7c478bd9Sstevel@tonic-gate 	char const *buf;
130*7c478bd9Sstevel@tonic-gate 	size_t n;
131*7c478bd9Sstevel@tonic-gate {
132*7c478bd9Sstevel@tonic-gate 	register SM_STR_OBJ_T *s = fp->f_cookie;
133*7c478bd9Sstevel@tonic-gate 
134*7c478bd9Sstevel@tonic-gate 	if (!(s->strio_flags & SMWR) && !(s->strio_flags & SMRW))
135*7c478bd9Sstevel@tonic-gate 	{
136*7c478bd9Sstevel@tonic-gate 		errno = EBADF;
137*7c478bd9Sstevel@tonic-gate 		return -1;
138*7c478bd9Sstevel@tonic-gate 	}
139*7c478bd9Sstevel@tonic-gate 	if (n + s->strio_offset > s->strio_size)
140*7c478bd9Sstevel@tonic-gate 	{
141*7c478bd9Sstevel@tonic-gate 		if (!sm_strgrow(s, n + s->strio_offset))
142*7c478bd9Sstevel@tonic-gate 			return 0;
143*7c478bd9Sstevel@tonic-gate 	}
144*7c478bd9Sstevel@tonic-gate 	(void) memmove(s->strio_base + s->strio_offset, buf, n);
145*7c478bd9Sstevel@tonic-gate 	s->strio_offset += n;
146*7c478bd9Sstevel@tonic-gate 	return n;
147*7c478bd9Sstevel@tonic-gate }
148*7c478bd9Sstevel@tonic-gate 
149*7c478bd9Sstevel@tonic-gate /*
150*7c478bd9Sstevel@tonic-gate **  SM_STRSEEK -- position the offset pointer for the string
151*7c478bd9Sstevel@tonic-gate **
152*7c478bd9Sstevel@tonic-gate **	Only SM_IO_SEEK_SET, SM_IO_SEEK_CUR and SM_IO_SEEK_END are valid
153*7c478bd9Sstevel@tonic-gate **	values for whence.
154*7c478bd9Sstevel@tonic-gate **
155*7c478bd9Sstevel@tonic-gate **	Parameters:
156*7c478bd9Sstevel@tonic-gate **		fp -- the file pointer
157*7c478bd9Sstevel@tonic-gate **		offset -- number of bytes offset from "base"
158*7c478bd9Sstevel@tonic-gate **		whence -- determines "base" for 'offset'
159*7c478bd9Sstevel@tonic-gate **
160*7c478bd9Sstevel@tonic-gate **	Returns:
161*7c478bd9Sstevel@tonic-gate **		Failure: -1 and sets errno
162*7c478bd9Sstevel@tonic-gate **		Success: >=0, number of bytes read
163*7c478bd9Sstevel@tonic-gate */
164*7c478bd9Sstevel@tonic-gate 
165*7c478bd9Sstevel@tonic-gate off_t
166*7c478bd9Sstevel@tonic-gate sm_strseek(fp, offset, whence)
167*7c478bd9Sstevel@tonic-gate 	SM_FILE_T *fp;
168*7c478bd9Sstevel@tonic-gate 	off_t offset;
169*7c478bd9Sstevel@tonic-gate 	int whence;
170*7c478bd9Sstevel@tonic-gate {
171*7c478bd9Sstevel@tonic-gate 	register off_t ret;
172*7c478bd9Sstevel@tonic-gate 	register SM_STR_OBJ_T *s = fp->f_cookie;
173*7c478bd9Sstevel@tonic-gate 
174*7c478bd9Sstevel@tonic-gate reseek:
175*7c478bd9Sstevel@tonic-gate 	switch (whence)
176*7c478bd9Sstevel@tonic-gate 	{
177*7c478bd9Sstevel@tonic-gate 	  case SM_IO_SEEK_SET:
178*7c478bd9Sstevel@tonic-gate 		ret = offset;
179*7c478bd9Sstevel@tonic-gate 		break;
180*7c478bd9Sstevel@tonic-gate 	  case SM_IO_SEEK_CUR:
181*7c478bd9Sstevel@tonic-gate 		ret = s->strio_offset + offset;
182*7c478bd9Sstevel@tonic-gate 		break;
183*7c478bd9Sstevel@tonic-gate 	  case SM_IO_SEEK_END:
184*7c478bd9Sstevel@tonic-gate 		ret = s->strio_size;
185*7c478bd9Sstevel@tonic-gate 		break;
186*7c478bd9Sstevel@tonic-gate 	  default:
187*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
188*7c478bd9Sstevel@tonic-gate 		return -1;
189*7c478bd9Sstevel@tonic-gate 	}
190*7c478bd9Sstevel@tonic-gate 	if (ret < 0 || ret > (off_t)(size_t)(-1))	/* XXX ugly */
191*7c478bd9Sstevel@tonic-gate 		return -1;
192*7c478bd9Sstevel@tonic-gate 	if ((size_t) ret > s->strio_size)
193*7c478bd9Sstevel@tonic-gate 	{
194*7c478bd9Sstevel@tonic-gate 		if (sm_strgrow(s, (size_t)ret))
195*7c478bd9Sstevel@tonic-gate 			goto reseek;
196*7c478bd9Sstevel@tonic-gate 
197*7c478bd9Sstevel@tonic-gate 		/* errno set by sm_strgrow */
198*7c478bd9Sstevel@tonic-gate 		return -1;
199*7c478bd9Sstevel@tonic-gate 	}
200*7c478bd9Sstevel@tonic-gate 	s->strio_offset = (size_t) ret;
201*7c478bd9Sstevel@tonic-gate 	return ret;
202*7c478bd9Sstevel@tonic-gate }
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate /*
205*7c478bd9Sstevel@tonic-gate **  SM_STROPEN -- open a string file type
206*7c478bd9Sstevel@tonic-gate **
207*7c478bd9Sstevel@tonic-gate **	Parameters:
208*7c478bd9Sstevel@tonic-gate **		fp -- file pointer open to be associated with
209*7c478bd9Sstevel@tonic-gate **		info -- initial contents (NULL for none)
210*7c478bd9Sstevel@tonic-gate **		flags -- flags for methods of access (was mode)
211*7c478bd9Sstevel@tonic-gate **		rpool -- resource pool to use memory from (if applicable)
212*7c478bd9Sstevel@tonic-gate **
213*7c478bd9Sstevel@tonic-gate **	Results:
214*7c478bd9Sstevel@tonic-gate **		Success: 0 (zero)
215*7c478bd9Sstevel@tonic-gate **		Failure: -1 and sets errno
216*7c478bd9Sstevel@tonic-gate */
217*7c478bd9Sstevel@tonic-gate 
218*7c478bd9Sstevel@tonic-gate int
219*7c478bd9Sstevel@tonic-gate sm_stropen(fp, info, flags, rpool)
220*7c478bd9Sstevel@tonic-gate 	SM_FILE_T *fp;
221*7c478bd9Sstevel@tonic-gate 	const void *info;
222*7c478bd9Sstevel@tonic-gate 	int flags;
223*7c478bd9Sstevel@tonic-gate 	const void *rpool;
224*7c478bd9Sstevel@tonic-gate {
225*7c478bd9Sstevel@tonic-gate 	register SM_STR_OBJ_T *s;
226*7c478bd9Sstevel@tonic-gate 
227*7c478bd9Sstevel@tonic-gate #if SM_RPOOL
228*7c478bd9Sstevel@tonic-gate 	s = sm_rpool_malloc_x(rpool, sizeof(SM_STR_OBJ_T));
229*7c478bd9Sstevel@tonic-gate #else /* SM_RPOOL */
230*7c478bd9Sstevel@tonic-gate 	s = sm_malloc(sizeof(SM_STR_OBJ_T));
231*7c478bd9Sstevel@tonic-gate 	if (s == NULL)
232*7c478bd9Sstevel@tonic-gate 		return -1;
233*7c478bd9Sstevel@tonic-gate #endif /* SM_RPOOL */
234*7c478bd9Sstevel@tonic-gate 
235*7c478bd9Sstevel@tonic-gate 	fp->f_cookie = s;
236*7c478bd9Sstevel@tonic-gate 	s->strio_rpool = rpool;
237*7c478bd9Sstevel@tonic-gate 	s->strio_offset = 0;
238*7c478bd9Sstevel@tonic-gate 	s->strio_size = 0;
239*7c478bd9Sstevel@tonic-gate 	s->strio_base = NULL;
240*7c478bd9Sstevel@tonic-gate 	s->strio_end = 0;
241*7c478bd9Sstevel@tonic-gate 
242*7c478bd9Sstevel@tonic-gate 	switch (flags)
243*7c478bd9Sstevel@tonic-gate 	{
244*7c478bd9Sstevel@tonic-gate 	  case SM_IO_RDWR:
245*7c478bd9Sstevel@tonic-gate 		s->strio_flags = SMRW;
246*7c478bd9Sstevel@tonic-gate 		break;
247*7c478bd9Sstevel@tonic-gate 	  case SM_IO_RDONLY:
248*7c478bd9Sstevel@tonic-gate 		s->strio_flags = SMRD;
249*7c478bd9Sstevel@tonic-gate 		break;
250*7c478bd9Sstevel@tonic-gate 	  case SM_IO_WRONLY:
251*7c478bd9Sstevel@tonic-gate 		s->strio_flags = SMWR;
252*7c478bd9Sstevel@tonic-gate 		break;
253*7c478bd9Sstevel@tonic-gate 	  case SM_IO_APPEND:
254*7c478bd9Sstevel@tonic-gate 		if (s->strio_rpool == NULL)
255*7c478bd9Sstevel@tonic-gate 			sm_free(s);
256*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
257*7c478bd9Sstevel@tonic-gate 		return -1;
258*7c478bd9Sstevel@tonic-gate 	  default:
259*7c478bd9Sstevel@tonic-gate 		if (s->strio_rpool == NULL)
260*7c478bd9Sstevel@tonic-gate 			sm_free(s);
261*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
262*7c478bd9Sstevel@tonic-gate 		return -1;
263*7c478bd9Sstevel@tonic-gate 	}
264*7c478bd9Sstevel@tonic-gate 
265*7c478bd9Sstevel@tonic-gate 	if (info != NULL)
266*7c478bd9Sstevel@tonic-gate 	{
267*7c478bd9Sstevel@tonic-gate 		s->strio_base = sm_strdup_x(info);
268*7c478bd9Sstevel@tonic-gate 		if (s->strio_base == NULL)
269*7c478bd9Sstevel@tonic-gate 		{
270*7c478bd9Sstevel@tonic-gate 			int save_errno = errno;
271*7c478bd9Sstevel@tonic-gate 
272*7c478bd9Sstevel@tonic-gate 			if (s->strio_rpool == NULL)
273*7c478bd9Sstevel@tonic-gate 				sm_free(s);
274*7c478bd9Sstevel@tonic-gate 			errno = save_errno;
275*7c478bd9Sstevel@tonic-gate 			return -1;
276*7c478bd9Sstevel@tonic-gate 		}
277*7c478bd9Sstevel@tonic-gate 		s->strio_size = strlen(info);
278*7c478bd9Sstevel@tonic-gate 		s->strio_end = s->strio_base + s->strio_size;
279*7c478bd9Sstevel@tonic-gate 	}
280*7c478bd9Sstevel@tonic-gate 	return 0;
281*7c478bd9Sstevel@tonic-gate }
282*7c478bd9Sstevel@tonic-gate 
283*7c478bd9Sstevel@tonic-gate /*
284*7c478bd9Sstevel@tonic-gate **  SM_STRCLOSE -- close the string file type and free resources
285*7c478bd9Sstevel@tonic-gate **
286*7c478bd9Sstevel@tonic-gate **	Parameters:
287*7c478bd9Sstevel@tonic-gate **		fp -- file pointer
288*7c478bd9Sstevel@tonic-gate **
289*7c478bd9Sstevel@tonic-gate **	Results:
290*7c478bd9Sstevel@tonic-gate **		Success: 0 (zero)
291*7c478bd9Sstevel@tonic-gate */
292*7c478bd9Sstevel@tonic-gate 
293*7c478bd9Sstevel@tonic-gate int
294*7c478bd9Sstevel@tonic-gate sm_strclose(fp)
295*7c478bd9Sstevel@tonic-gate 	SM_FILE_T *fp;
296*7c478bd9Sstevel@tonic-gate {
297*7c478bd9Sstevel@tonic-gate 	SM_STR_OBJ_T *s = fp->f_cookie;
298*7c478bd9Sstevel@tonic-gate 
299*7c478bd9Sstevel@tonic-gate #if !SM_RPOOL
300*7c478bd9Sstevel@tonic-gate 	sm_free(s->strio_base);
301*7c478bd9Sstevel@tonic-gate 	s->strio_base = NULL;
302*7c478bd9Sstevel@tonic-gate #endif /* !SM_RPOOL */
303*7c478bd9Sstevel@tonic-gate 	return 0;
304*7c478bd9Sstevel@tonic-gate }
305*7c478bd9Sstevel@tonic-gate 
306*7c478bd9Sstevel@tonic-gate /*
307*7c478bd9Sstevel@tonic-gate **  SM_STRSETMODE -- set mode info for the file
308*7c478bd9Sstevel@tonic-gate **
309*7c478bd9Sstevel@tonic-gate **	 Note: changing the mode can be a safe way to have the "parent"
310*7c478bd9Sstevel@tonic-gate **	 set up a string that the "child" is not to modify
311*7c478bd9Sstevel@tonic-gate **
312*7c478bd9Sstevel@tonic-gate **	Parameters:
313*7c478bd9Sstevel@tonic-gate **		fp -- the file pointer
314*7c478bd9Sstevel@tonic-gate **		mode -- location of new mode to set
315*7c478bd9Sstevel@tonic-gate **
316*7c478bd9Sstevel@tonic-gate **	Results:
317*7c478bd9Sstevel@tonic-gate **		Success: 0 (zero)
318*7c478bd9Sstevel@tonic-gate **		Failure: -1 and sets errno
319*7c478bd9Sstevel@tonic-gate */
320*7c478bd9Sstevel@tonic-gate 
321*7c478bd9Sstevel@tonic-gate static int
322*7c478bd9Sstevel@tonic-gate sm_strsetmode(fp, mode)
323*7c478bd9Sstevel@tonic-gate 	SM_FILE_T *fp;
324*7c478bd9Sstevel@tonic-gate 	const int *mode;
325*7c478bd9Sstevel@tonic-gate {
326*7c478bd9Sstevel@tonic-gate 	register SM_STR_OBJ_T *s = fp->f_cookie;
327*7c478bd9Sstevel@tonic-gate 	int flags;
328*7c478bd9Sstevel@tonic-gate 
329*7c478bd9Sstevel@tonic-gate 	switch (*mode)
330*7c478bd9Sstevel@tonic-gate 	{
331*7c478bd9Sstevel@tonic-gate 	  case SM_IO_RDWR:
332*7c478bd9Sstevel@tonic-gate 		flags = SMRW;
333*7c478bd9Sstevel@tonic-gate 		break;
334*7c478bd9Sstevel@tonic-gate 	  case SM_IO_RDONLY:
335*7c478bd9Sstevel@tonic-gate 		flags = SMRD;
336*7c478bd9Sstevel@tonic-gate 		break;
337*7c478bd9Sstevel@tonic-gate 	  case SM_IO_WRONLY:
338*7c478bd9Sstevel@tonic-gate 		flags = SMWR;
339*7c478bd9Sstevel@tonic-gate 		break;
340*7c478bd9Sstevel@tonic-gate 	  case SM_IO_APPEND:
341*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
342*7c478bd9Sstevel@tonic-gate 		return -1;
343*7c478bd9Sstevel@tonic-gate 	  default:
344*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
345*7c478bd9Sstevel@tonic-gate 		return -1;
346*7c478bd9Sstevel@tonic-gate 	}
347*7c478bd9Sstevel@tonic-gate 	s->strio_flags &= ~SMMODEMASK;
348*7c478bd9Sstevel@tonic-gate 	s->strio_flags |= flags;
349*7c478bd9Sstevel@tonic-gate 	return 0;
350*7c478bd9Sstevel@tonic-gate }
351*7c478bd9Sstevel@tonic-gate 
352*7c478bd9Sstevel@tonic-gate /*
353*7c478bd9Sstevel@tonic-gate **  SM_STRGETMODE -- get mode info for the file
354*7c478bd9Sstevel@tonic-gate **
355*7c478bd9Sstevel@tonic-gate **	Parameters:
356*7c478bd9Sstevel@tonic-gate **		fp -- the file pointer
357*7c478bd9Sstevel@tonic-gate **		mode -- location to store current mode
358*7c478bd9Sstevel@tonic-gate **
359*7c478bd9Sstevel@tonic-gate **	Results:
360*7c478bd9Sstevel@tonic-gate **		Success: 0 (zero)
361*7c478bd9Sstevel@tonic-gate **		Failure: -1 and sets errno
362*7c478bd9Sstevel@tonic-gate */
363*7c478bd9Sstevel@tonic-gate 
364*7c478bd9Sstevel@tonic-gate int
365*7c478bd9Sstevel@tonic-gate sm_strgetmode(fp, mode)
366*7c478bd9Sstevel@tonic-gate 	SM_FILE_T *fp;
367*7c478bd9Sstevel@tonic-gate 	int *mode;
368*7c478bd9Sstevel@tonic-gate {
369*7c478bd9Sstevel@tonic-gate 	register SM_STR_OBJ_T *s = fp->f_cookie;
370*7c478bd9Sstevel@tonic-gate 
371*7c478bd9Sstevel@tonic-gate 	switch (s->strio_flags & SMMODEMASK)
372*7c478bd9Sstevel@tonic-gate 	{
373*7c478bd9Sstevel@tonic-gate 	  case SMRW:
374*7c478bd9Sstevel@tonic-gate 		*mode = SM_IO_RDWR;
375*7c478bd9Sstevel@tonic-gate 		break;
376*7c478bd9Sstevel@tonic-gate 	  case SMRD:
377*7c478bd9Sstevel@tonic-gate 		*mode = SM_IO_RDONLY;
378*7c478bd9Sstevel@tonic-gate 		break;
379*7c478bd9Sstevel@tonic-gate 	  case SMWR:
380*7c478bd9Sstevel@tonic-gate 		*mode = SM_IO_WRONLY;
381*7c478bd9Sstevel@tonic-gate 		break;
382*7c478bd9Sstevel@tonic-gate 	  default:
383*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
384*7c478bd9Sstevel@tonic-gate 		return -1;
385*7c478bd9Sstevel@tonic-gate 	}
386*7c478bd9Sstevel@tonic-gate 	return 0;
387*7c478bd9Sstevel@tonic-gate }
388*7c478bd9Sstevel@tonic-gate 
389*7c478bd9Sstevel@tonic-gate /*
390*7c478bd9Sstevel@tonic-gate **  SM_STRSETINFO -- set info for the file
391*7c478bd9Sstevel@tonic-gate **
392*7c478bd9Sstevel@tonic-gate **	Currently only SM_IO_WHAT_MODE is supported for 'what'.
393*7c478bd9Sstevel@tonic-gate **
394*7c478bd9Sstevel@tonic-gate **	Parameters:
395*7c478bd9Sstevel@tonic-gate **		fp -- the file pointer
396*7c478bd9Sstevel@tonic-gate **		what -- type of information to set
397*7c478bd9Sstevel@tonic-gate **		valp -- location to data for doing set
398*7c478bd9Sstevel@tonic-gate **
399*7c478bd9Sstevel@tonic-gate **	Results:
400*7c478bd9Sstevel@tonic-gate **		Failure: -1 and sets errno
401*7c478bd9Sstevel@tonic-gate **		Success: sm_strsetmode() return [0 (zero)]
402*7c478bd9Sstevel@tonic-gate */
403*7c478bd9Sstevel@tonic-gate 
404*7c478bd9Sstevel@tonic-gate int
405*7c478bd9Sstevel@tonic-gate sm_strsetinfo(fp, what, valp)
406*7c478bd9Sstevel@tonic-gate 	SM_FILE_T *fp;
407*7c478bd9Sstevel@tonic-gate 	int what;
408*7c478bd9Sstevel@tonic-gate 	void *valp;
409*7c478bd9Sstevel@tonic-gate {
410*7c478bd9Sstevel@tonic-gate 	switch(what)
411*7c478bd9Sstevel@tonic-gate 	{
412*7c478bd9Sstevel@tonic-gate 	  case SM_IO_WHAT_MODE:
413*7c478bd9Sstevel@tonic-gate 		return sm_strsetmode(fp, (int *) valp);
414*7c478bd9Sstevel@tonic-gate 	  default:
415*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
416*7c478bd9Sstevel@tonic-gate 		return -1;
417*7c478bd9Sstevel@tonic-gate 	}
418*7c478bd9Sstevel@tonic-gate }
419*7c478bd9Sstevel@tonic-gate 
420*7c478bd9Sstevel@tonic-gate /*
421*7c478bd9Sstevel@tonic-gate **  SM_STRGETINFO -- get info for the file
422*7c478bd9Sstevel@tonic-gate **
423*7c478bd9Sstevel@tonic-gate **	Currently only SM_IO_WHAT_MODE is supported for 'what'.
424*7c478bd9Sstevel@tonic-gate **
425*7c478bd9Sstevel@tonic-gate **	Parameters:
426*7c478bd9Sstevel@tonic-gate **		fp -- the file pointer
427*7c478bd9Sstevel@tonic-gate **		what -- type of information requested
428*7c478bd9Sstevel@tonic-gate **		valp -- location to return information in
429*7c478bd9Sstevel@tonic-gate **
430*7c478bd9Sstevel@tonic-gate **	Results:
431*7c478bd9Sstevel@tonic-gate **		Failure: -1 and sets errno
432*7c478bd9Sstevel@tonic-gate **		Success: sm_strgetmode() return [0 (zero)]
433*7c478bd9Sstevel@tonic-gate */
434*7c478bd9Sstevel@tonic-gate 
435*7c478bd9Sstevel@tonic-gate int
436*7c478bd9Sstevel@tonic-gate sm_strgetinfo(fp, what, valp)
437*7c478bd9Sstevel@tonic-gate 	SM_FILE_T *fp;
438*7c478bd9Sstevel@tonic-gate 	int what;
439*7c478bd9Sstevel@tonic-gate 	void *valp;
440*7c478bd9Sstevel@tonic-gate {
441*7c478bd9Sstevel@tonic-gate 	switch(what)
442*7c478bd9Sstevel@tonic-gate 	{
443*7c478bd9Sstevel@tonic-gate 	  case SM_IO_WHAT_MODE:
444*7c478bd9Sstevel@tonic-gate 		return sm_strgetmode(fp, (int *) valp);
445*7c478bd9Sstevel@tonic-gate 	  default:
446*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
447*7c478bd9Sstevel@tonic-gate 		return -1;
448*7c478bd9Sstevel@tonic-gate 	}
449*7c478bd9Sstevel@tonic-gate }
450*7c478bd9Sstevel@tonic-gate 
451*7c478bd9Sstevel@tonic-gate /*
452*7c478bd9Sstevel@tonic-gate **  SM_STRIO_INIT -- initializes a write-only string type
453*7c478bd9Sstevel@tonic-gate **
454*7c478bd9Sstevel@tonic-gate **  Original comments below. This function does not appear to be used anywhere.
455*7c478bd9Sstevel@tonic-gate **  The same functionality can be done by changing the mode of the file.
456*7c478bd9Sstevel@tonic-gate **  ------------
457*7c478bd9Sstevel@tonic-gate ** sm_strio_init initializes an SM_FILE_T structure as a write-only file
458*7c478bd9Sstevel@tonic-gate ** that writes into the specified buffer:
459*7c478bd9Sstevel@tonic-gate ** - Use sm_io_putc, sm_io_fprintf, etc, to write into the buffer.
460*7c478bd9Sstevel@tonic-gate **   Attempts to write more than size-1 characters into the buffer will fail
461*7c478bd9Sstevel@tonic-gate **   silently (no error is reported).
462*7c478bd9Sstevel@tonic-gate ** - Use sm_io_fflush to nul terminate the string in the buffer
463*7c478bd9Sstevel@tonic-gate **   (the write pointer is not advanced).
464*7c478bd9Sstevel@tonic-gate ** No memory is allocated either by sm_strio_init or by sm_io_{putc,write} etc.
465*7c478bd9Sstevel@tonic-gate **
466*7c478bd9Sstevel@tonic-gate **	Parameters:
467*7c478bd9Sstevel@tonic-gate **		fp -- file pointer
468*7c478bd9Sstevel@tonic-gate **		buf -- memory location for stored data
469*7c478bd9Sstevel@tonic-gate **		size -- size of 'buf'
470*7c478bd9Sstevel@tonic-gate **
471*7c478bd9Sstevel@tonic-gate **	Results:
472*7c478bd9Sstevel@tonic-gate **		none.
473*7c478bd9Sstevel@tonic-gate */
474*7c478bd9Sstevel@tonic-gate 
475*7c478bd9Sstevel@tonic-gate void
476*7c478bd9Sstevel@tonic-gate sm_strio_init(fp, buf, size)
477*7c478bd9Sstevel@tonic-gate 	SM_FILE_T *fp;
478*7c478bd9Sstevel@tonic-gate 	char *buf;
479*7c478bd9Sstevel@tonic-gate 	size_t size;
480*7c478bd9Sstevel@tonic-gate {
481*7c478bd9Sstevel@tonic-gate 	fp->sm_magic = SmFileMagic;
482*7c478bd9Sstevel@tonic-gate 	fp->f_flags = SMWR | SMSTR;
483*7c478bd9Sstevel@tonic-gate 	fp->f_file = -1;
484*7c478bd9Sstevel@tonic-gate 	fp->f_bf.smb_base = fp->f_p = (unsigned char *) buf;
485*7c478bd9Sstevel@tonic-gate 	fp->f_bf.smb_size = fp->f_w = (size ? size - 1 : 0);
486*7c478bd9Sstevel@tonic-gate 	fp->f_lbfsize = 0;
487*7c478bd9Sstevel@tonic-gate 	fp->f_r = 0;
488*7c478bd9Sstevel@tonic-gate 	fp->f_read = NULL;
489*7c478bd9Sstevel@tonic-gate 	fp->f_seek = NULL;
490*7c478bd9Sstevel@tonic-gate 	fp->f_getinfo = NULL;
491*7c478bd9Sstevel@tonic-gate 	fp->f_setinfo = NULL;
492*7c478bd9Sstevel@tonic-gate }
493