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