2 * Copyright (c) 2000-2002, 2004, 2005 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.
15 #pragma ident "%Z%%M% %I% %E% SMI"
18 SM_IDSTR(id
, "@(#)$Id: strio.c,v 1.44 2005/06/09 21:40:19 ca Exp $")
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
44 const void *strio_rpool
;
47 typedef struct sm_str_obj SM_STR_OBJ_T
;
50 ** SM_STRGROW -- increase storage space for string
53 ** s -- current cookie
54 ** size -- new storage size request
57 ** true iff successful.
60 static bool sm_strgrow
__P((SM_STR_OBJ_T
*, size_t));
69 if (s
->strio_size
>= size
)
71 p
= sm_realloc(s
->strio_base
, size
);
75 s
->strio_end
= s
->strio_base
+ size
;
81 ** SM_STRREAD -- read a portion of the string
84 ** fp -- the file pointer
85 ** buf -- location to place read data
86 ** n -- number of bytes to read
89 ** Failure: -1 and sets errno
90 ** Success: >=0, number of bytes read
94 sm_strread(fp
, buf
, n
)
99 register SM_STR_OBJ_T
*s
= fp
->f_cookie
;
102 if (!(s
->strio_flags
& SMRD
) && !(s
->strio_flags
& SMRW
))
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
;
114 ** SM_STRWRITE -- write a portion of the string
117 ** fp -- the file pointer
118 ** buf -- location of data for writing
119 ** n -- number of bytes to write
122 ** Failure: -1 and sets errno
123 ** Success: >=0, number of bytes written
127 sm_strwrite(fp
, buf
, n
)
132 register SM_STR_OBJ_T
*s
= fp
->f_cookie
;
134 if (!(s
->strio_flags
& SMWR
) && !(s
->strio_flags
& SMRW
))
139 if (n
+ s
->strio_offset
> s
->strio_size
)
141 if (!sm_strgrow(s
, n
+ s
->strio_offset
))
144 (void) memmove(s
->strio_base
+ s
->strio_offset
, buf
, n
);
145 s
->strio_offset
+= 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.
156 ** fp -- the file pointer
157 ** offset -- number of bytes offset from "base"
158 ** whence -- determines "base" for 'offset'
161 ** Failure: -1 and sets errno
162 ** Success: >=0, number of bytes read
166 sm_strseek(fp
, offset
, whence
)
172 register SM_STR_OBJ_T
*s
= fp
->f_cookie
;
181 ret
= s
->strio_offset
+ offset
;
190 if (ret
< 0 || ret
> (off_t
)(size_t)(-1)) /* XXX ugly */
192 if ((size_t) ret
> s
->strio_size
)
194 if (sm_strgrow(s
, (size_t)ret
))
197 /* errno set by sm_strgrow */
200 s
->strio_offset
= (size_t) ret
;
205 ** SM_STROPEN -- open a string file type
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)
215 ** Failure: -1 and sets errno
219 sm_stropen(fp
, info
, flags
, rpool
)
225 register SM_STR_OBJ_T
*s
;
228 s
= sm_rpool_malloc_x(rpool
, sizeof(SM_STR_OBJ_T
));
230 s
= sm_malloc(sizeof(SM_STR_OBJ_T
));
233 #endif /* SM_RPOOL */
236 s
->strio_rpool
= rpool
;
239 s
->strio_base
= NULL
;
245 s
->strio_flags
= SMRW
;
248 s
->strio_flags
= SMRD
;
251 s
->strio_flags
= SMWR
;
254 if (s
->strio_rpool
== NULL
)
259 if (s
->strio_rpool
== 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
)
277 s
->strio_size
= strlen(info
);
278 s
->strio_end
= s
->strio_base
+ s
->strio_size
;
284 ** SM_STRCLOSE -- close the string file type and free resources
287 ** fp -- file pointer
297 SM_STR_OBJ_T
*s
= fp
->f_cookie
;
300 sm_free(s
->strio_base
);
301 s
->strio_base
= NULL
;
302 #endif /* !SM_RPOOL */
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
313 ** fp -- the file pointer
314 ** mode -- location of new mode to set
318 ** Failure: -1 and sets errno
322 sm_strsetmode(fp
, mode
)
326 register SM_STR_OBJ_T
*s
= fp
->f_cookie
;
347 s
->strio_flags
&= ~SMMODEMASK
;
348 s
->strio_flags
|= flags
;
353 ** SM_STRGETMODE -- get mode info for the file
356 ** fp -- the file pointer
357 ** mode -- location to store current mode
361 ** Failure: -1 and sets errno
365 sm_strgetmode(fp
, mode
)
369 register SM_STR_OBJ_T
*s
= fp
->f_cookie
;
371 switch (s
->strio_flags
& SMMODEMASK
)
377 *mode
= SM_IO_RDONLY
;
380 *mode
= SM_IO_WRONLY
;
390 ** SM_STRSETINFO -- set info for the file
392 ** Currently only SM_IO_WHAT_MODE is supported for 'what'.
395 ** fp -- the file pointer
396 ** what -- type of information to set
397 ** valp -- location to data for doing set
400 ** Failure: -1 and sets errno
401 ** Success: sm_strsetmode() return [0 (zero)]
405 sm_strsetinfo(fp
, what
, valp
)
412 case SM_IO_WHAT_MODE
:
413 return sm_strsetmode(fp
, (int *) valp
);
421 ** SM_STRGETINFO -- get info for the file
423 ** Currently only SM_IO_WHAT_MODE is supported for 'what'.
426 ** fp -- the file pointer
427 ** what -- type of information requested
428 ** valp -- location to return information in
431 ** Failure: -1 and sets errno
432 ** Success: sm_strgetmode() return [0 (zero)]
436 sm_strgetinfo(fp
, what
, valp
)
443 case SM_IO_WHAT_MODE
:
444 return sm_strgetmode(fp
, (int *) valp
);
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.
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.
467 ** fp -- file pointer
468 ** buf -- memory location for stored data
469 ** size -- size of 'buf'
476 sm_strio_init(fp
, buf
, size
)
481 fp
->sm_magic
= SmFileMagic
;
482 fp
->f_flags
= SMWR
| SMSTR
;
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);
490 fp
->f_getinfo
= NULL
;
491 fp
->f_setinfo
= NULL
;