2 * Copyright (c) 2000-2002 Sendmail, Inc. and its suppliers.
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
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.
16 SM_IDSTR(id, "@(#)$Id: strio.c,v 1.42 2002/02/11 23:05:50 gshapiro Exp $")
29 ** Cookie structure for the "strio" file type
39 const void *strio_rpool;
42 typedef struct sm_str_obj SM_STR_OBJ_T;
45 ** SM_STRGROW -- increase storage space for string
48 ** s -- current cookie
49 ** size -- new storage size request
52 ** true iff successful.
55 static bool sm_strgrow __P((SM_STR_OBJ_T *, size_t));
64 if (s->strio_size >= size)
66 p = sm_realloc(s->strio_base, size);
70 s->strio_end = s->strio_base + size;
76 ** SM_STRREAD -- read a portion of the string
79 ** fp -- the file pointer
80 ** buf -- location to place read data
81 ** n -- number of bytes to read
84 ** Failure: -1 and sets errno
85 ** Success: >=0, number of bytes read
89 sm_strread(fp, buf, n)
94 register SM_STR_OBJ_T *s = fp->f_cookie;
97 if (!(s->strio_flags & SMRD) && !(s->strio_flags & SMRW))
102 len = SM_MIN(s->strio_size - s->strio_offset, n);
103 (void) memmove(buf, s->strio_base + s->strio_offset, len);
104 s->strio_offset += len;
109 ** SM_STRWRITE -- write a portion of the string
112 ** fp -- the file pointer
113 ** buf -- location of data for writing
114 ** n -- number of bytes to write
117 ** Failure: -1 and sets errno
118 ** Success: >=0, number of bytes written
122 sm_strwrite(fp, buf, n)
127 register SM_STR_OBJ_T *s = fp->f_cookie;
129 if (!(s->strio_flags & SMWR) && !(s->strio_flags & SMRW))
134 if (n + s->strio_offset > s->strio_size)
136 if (!sm_strgrow(s, n + s->strio_offset))
139 (void) memmove(s->strio_base + s->strio_offset, buf, n);
140 s->strio_offset += n;
145 ** SM_STRSEEK -- position the offset pointer for the string
147 ** Only SM_IO_SEEK_SET, SM_IO_SEEK_CUR and SM_IO_SEEK_END are valid
148 ** values for whence.
151 ** fp -- the file pointer
152 ** offset -- number of bytes offset from "base"
153 ** whence -- determines "base" for 'offset'
156 ** Failure: -1 and sets errno
157 ** Success: >=0, number of bytes read
161 sm_strseek(fp, offset, whence)
167 register SM_STR_OBJ_T *s = fp->f_cookie;
176 ret = s->strio_offset + offset;
185 if (ret < 0 || ret > (off_t)(size_t)(-1)) /* XXX ugly */
187 if ((size_t) ret > s->strio_size)
189 if (sm_strgrow(s, (size_t)ret))
192 /* errno set by sm_strgrow */
195 s->strio_offset = (size_t) ret;
200 ** SM_STROPEN -- open a string file type
203 ** fp -- file pointer open to be associated with
204 ** info -- initial contents (NULL for none)
205 ** flags -- flags for methods of access (was mode)
206 ** rpool -- resource pool to use memory from (if applicable)
210 ** Failure: -1 and sets errno
214 sm_stropen(fp, info, flags, rpool)
220 register SM_STR_OBJ_T *s;
223 s = sm_rpool_malloc_x(rpool, sizeof(SM_STR_OBJ_T));
225 s = sm_malloc(sizeof(SM_STR_OBJ_T));
228 #endif /* SM_RPOOL */
231 s->strio_rpool = rpool;
234 s->strio_base = NULL;
240 s->strio_flags = SMRW;
243 s->strio_flags = SMRD;
246 s->strio_flags = SMWR;
249 if (s->strio_rpool == NULL)
254 if (s->strio_rpool == NULL)
262 s->strio_base = sm_strdup_x(info);
263 if (s->strio_base == NULL)
265 int save_errno = errno;
267 if (s->strio_rpool == NULL)
272 s->strio_size = strlen(info);
273 s->strio_end = s->strio_base + s->strio_size;
279 ** SM_STRCLOSE -- close the string file type and free resources
282 ** fp -- file pointer
292 SM_STR_OBJ_T *s = fp->f_cookie;
295 sm_free(s->strio_base);
296 s->strio_base = NULL;
297 #endif /* !SM_RPOOL */
302 ** SM_STRSETMODE -- set mode info for the file
304 ** Note: changing the mode can be a safe way to have the "parent"
305 ** set up a string that the "child" is not to modify
308 ** fp -- the file pointer
309 ** mode -- location of new mode to set
313 ** Failure: -1 and sets errno
317 sm_strsetmode(fp, mode)
321 register SM_STR_OBJ_T *s = fp->f_cookie;
342 s->strio_flags &= ~SMMODEMASK;
343 s->strio_flags |= flags;
348 ** SM_STRGETMODE -- get mode info for the file
351 ** fp -- the file pointer
352 ** mode -- location to store current mode
356 ** Failure: -1 and sets errno
360 sm_strgetmode(fp, mode)
364 register SM_STR_OBJ_T *s = fp->f_cookie;
366 switch (s->strio_flags & SMMODEMASK)
372 *mode = SM_IO_RDONLY;
375 *mode = SM_IO_WRONLY;
385 ** SM_STRSETINFO -- set info for the file
387 ** Currently only SM_IO_WHAT_MODE is supported for 'what'.
390 ** fp -- the file pointer
391 ** what -- type of information to set
392 ** valp -- location to data for doing set
395 ** Failure: -1 and sets errno
396 ** Success: sm_strsetmode() return [0 (zero)]
400 sm_strsetinfo(fp, what, valp)
407 case SM_IO_WHAT_MODE:
408 return sm_strsetmode(fp, (int *) valp);
416 ** SM_STRGETINFO -- get info for the file
418 ** Currently only SM_IO_WHAT_MODE is supported for 'what'.
421 ** fp -- the file pointer
422 ** what -- type of information requested
423 ** valp -- location to return information in
426 ** Failure: -1 and sets errno
427 ** Success: sm_strgetmode() return [0 (zero)]
431 sm_strgetinfo(fp, what, valp)
438 case SM_IO_WHAT_MODE:
439 return sm_strgetmode(fp, (int *) valp);
447 ** SM_STRIO_INIT -- initializes a write-only string type
449 ** Original comments below. This function does not appear to be used anywhere.
450 ** The same functionality can be done by changing the mode of the file.
452 ** sm_strio_init initializes an SM_FILE_T structure as a write-only file
453 ** that writes into the specified buffer:
454 ** - Use sm_io_putc, sm_io_fprintf, etc, to write into the buffer.
455 ** Attempts to write more than size-1 characters into the buffer will fail
456 ** silently (no error is reported).
457 ** - Use sm_io_fflush to nul terminate the string in the buffer
458 ** (the write pointer is not advanced).
459 ** No memory is allocated either by sm_strio_init or by sm_io_{putc,write} etc.
462 ** fp -- file pointer
463 ** buf -- memory location for stored data
464 ** size -- size of 'buf'
471 sm_strio_init(fp, buf, size)
476 fp->sm_magic = SmFileMagic;
477 fp->f_flags = SMWR | SMSTR;
479 fp->f_bf.smb_base = fp->f_p = (unsigned char *) buf;
480 fp->f_bf.smb_size = fp->f_w = (size ? size - 1 : 0);
485 fp->f_getinfo = NULL;
486 fp->f_setinfo = NULL;