Update zoneinfo database.
[dragonfly.git] / contrib / sendmail / include / sm / io.h
1 /*
2  * Copyright (c) 2000-2003 Sendmail, Inc. and its suppliers.
3  *      All rights reserved.
4  * Copyright (c) 1990
5  *       The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Chris Torek.
9  *
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.
13  *
14  *      $Id: io.h,v 1.23.2.2 2003/09/05 20:35:28 ca Exp $
15  */
16
17 /*-
18  *      @(#)stdio.h     5.17 (Berkeley) 6/3/91
19  */
20
21 #ifndef SM_IO_H
22 #define SM_IO_H
23
24 #include <stdio.h>
25 #include <sm/gen.h>
26 #include <sm/varargs.h>
27
28 /* mode for sm io (exposed) */
29 #define SM_IO_RDWR      1       /* read-write */
30 #define SM_IO_RDONLY    2       /* read-only */
31 #define SM_IO_WRONLY    3       /* write-only */
32 #define SM_IO_APPEND    4       /* write-only from eof */
33 #define SM_IO_APPENDRW  5       /* read-write from eof */
34 #define SM_IO_RDWRTR    6       /* read-write with truncation indicated */
35
36 # define SM_IO_BINARY   0x0     /* binary mode: not used in Unix */
37 #define SM_IS_BINARY(mode)      ((mode) & SM_IO_BINARY != 0)
38 #define SM_IO_MODE(mode)        ((mode) & 0x0f)
39
40 #define SM_IO_RDWR_B            (SM_IO_RDWR|SM_IO_BINARY)
41 #define SM_IO_RDONLY_B          (SM_IO_RDONLY|SM_IO_BINARY)
42 #define SM_IO_WRONLY_B          (SM_IO_WRONLY|SM_IO_BINARY)
43 #define SM_IO_APPEND_B          (SM_IO_APPEND|SM_IO_BINARY)
44 #define SM_IO_APPENDRW_B        (SM_IO_APPENDRW|SM_IO_BINARY)
45 #define SM_IO_RDWRTR_B          (SM_IO_RDWRTR|SM_IO_BINARY)
46
47 /* for sm_io_fseek, et al api's (exposed) */
48 #define SM_IO_SEEK_SET  0
49 #define SM_IO_SEEK_CUR  1
50 #define SM_IO_SEEK_END  2
51
52 /* flags for info what's with different types (exposed) */
53 #define SM_IO_WHAT_MODE         1
54 #define SM_IO_WHAT_VECTORS      2
55 #define SM_IO_WHAT_FD           3
56 #define SM_IO_WHAT_TYPE         4
57 #define SM_IO_WHAT_ISTYPE       5
58 #define SM_IO_IS_READABLE       6
59 #define SM_IO_WHAT_TIMEOUT      7
60 #define SM_IO_WHAT_SIZE         8
61
62 /* info flags (exposed) */
63 #define SM_IO_FTYPE_CREATE      1
64 #define SM_IO_FTYPE_MODIFY      2
65 #define SM_IO_FTYPE_DELETE      3
66
67 #define SM_IO_SL_PRIO           1
68
69 #define SM_IO_OPEN_MAX          20
70
71 /* for internal buffers */
72 struct smbuf
73 {
74         unsigned char   *smb_base;
75         int             smb_size;
76 };
77
78 /*
79 **  sm I/O state variables (internal only).
80 **
81 **      The following always hold:
82 **
83 **              if (flags&(SMLBF|SMWR)) == (SMLBF|SMWR),
84 **                      lbfsize is -bf.size, else lbfsize is 0
85 **              if flags&SMRD, w is 0
86 **              if flags&SMWR, r is 0
87 **
88 **      This ensures that the getc and putc macros (or inline functions) never
89 **      try to write or read from a file that is in `read' or `write' mode.
90 **      (Moreover, they can, and do, automatically switch from read mode to
91 **      write mode, and back, on "r+" and "w+" files.)
92 **
93 **      lbfsize is used only to make the inline line-buffered output stream
94 **      code as compact as possible.
95 **
96 **      ub, up, and ur are used when ungetc() pushes back more characters
97 **      than fit in the current bf, or when ungetc() pushes back a character
98 **      that does not match the previous one in bf.  When this happens,
99 **      ub.base becomes non-nil (i.e., a stream has ungetc() data iff
100 **      ub.base!=NULL) and up and ur save the current values of p and r.
101 */
102
103 typedef struct sm_file SM_FILE_T;
104
105 struct sm_file
106 {
107         const char      *sm_magic;      /* This SM_FILE_T is free when NULL */
108         unsigned char   *f_p;           /* current position in (some) buffer */
109         int             f_r;            /* read space left for getc() */
110         int             f_w;            /* write space left for putc() */
111         long            f_flags;        /* flags, below */
112         short           f_file;         /* fileno, if Unix fd, else -1 */
113         struct smbuf    f_bf;           /* the buffer (>= 1 byte, if !NULL) */
114         int             f_lbfsize;      /* 0 or -bf.size, for inline putc */
115
116         /* These can be used for any purpose by a file type implementation: */
117         void            *f_cookie;
118         int             f_ival;
119
120         /* operations */
121         int             (*f_close) __P((SM_FILE_T *));
122         ssize_t         (*f_read)  __P((SM_FILE_T *, char *, size_t));
123         off_t           (*f_seek)  __P((SM_FILE_T *, off_t, int));
124         ssize_t         (*f_write) __P((SM_FILE_T *, const char *, size_t));
125         int             (*f_open) __P((SM_FILE_T *, const void *, int,
126                                         const void *));
127         int             (*f_setinfo) __P((SM_FILE_T *, int , void *));
128         int             (*f_getinfo) __P((SM_FILE_T *, int , void *));
129         int             f_timeout;
130         int             f_timeoutstate;   /* either blocking or non-blocking */
131         char            *f_type;        /* for by-type lookups */
132         struct sm_file  *f_flushfp;     /* flush this before reading parent */
133         struct sm_file  *f_modefp;      /* sync mode with this fp */
134
135         /* separate buffer for long sequences of ungetc() */
136         struct smbuf    f_ub;   /* ungetc buffer */
137         unsigned char   *f_up;  /* saved f_p when f_p is doing ungetc */
138         int             f_ur;   /* saved f_r when f_r is counting ungetc */
139
140         /* tricks to meet minimum requirements even when malloc() fails */
141         unsigned char   f_ubuf[3];      /* guarantee an ungetc() buffer */
142         unsigned char   f_nbuf[1];      /* guarantee a getc() buffer */
143
144         /* Unix stdio files get aligned to block boundaries on fseek() */
145         int             f_blksize;      /* stat.st_blksize (may be != bf.size) */
146         off_t           f_lseekoff;     /* current lseek offset */
147         int             f_dup_cnt;      /* count file dup'd */
148 };
149
150 __BEGIN_DECLS
151 extern SM_FILE_T        SmIoF[];
152 extern const char       SmFileMagic[];
153 extern SM_FILE_T        SmFtStdio_def;
154 extern SM_FILE_T        SmFtStdiofd_def;
155 extern SM_FILE_T        SmFtString_def;
156 extern SM_FILE_T        SmFtSyslog_def;
157 extern SM_FILE_T        SmFtRealStdio_def;
158
159 #define SMIOIN_FILENO           0
160 #define SMIOOUT_FILENO          1
161 #define SMIOERR_FILENO          2
162 #define SMIOSTDIN_FILENO        3
163 #define SMIOSTDOUT_FILENO       4
164 #define SMIOSTDERR_FILENO       5
165
166 /* Common predefined and already (usually) open files (exposed) */
167 #define smioin          (&SmIoF[SMIOIN_FILENO])
168 #define smioout         (&SmIoF[SMIOOUT_FILENO])
169 #define smioerr         (&SmIoF[SMIOERR_FILENO])
170 #define smiostdin       (&SmIoF[SMIOSTDIN_FILENO])
171 #define smiostdout      (&SmIoF[SMIOSTDOUT_FILENO])
172 #define smiostderr      (&SmIoF[SMIOSTDERR_FILENO])
173
174 #define SmFtStdio       (&SmFtStdio_def)
175 #define SmFtStdiofd     (&SmFtStdiofd_def)
176 #define SmFtString      (&SmFtString_def)
177 #define SmFtSyslog      (&SmFtSyslog_def)
178 #define SmFtRealStdio   (&SmFtRealStdio_def)
179
180 #ifdef __STDC__
181 # define SM_IO_SET_TYPE(f, name, open, close, read, write, seek, get, set, timeout) \
182     (f) = {SmFileMagic, (unsigned char *) 0, 0, 0, 0L, -1, {0}, 0, (void *) 0,\
183         0, (close), (read), (seek), (write), (open), (set), (get), (timeout),\
184         0, (name)}
185 # define SM_IO_INIT_TYPE(f, name, open, close, read, write, seek, get, set, timeout)
186
187 #else /* __STDC__ */
188 # define SM_IO_SET_TYPE(f, name, open, close, read, write, seek, get, set, timeout) (f)
189 # define SM_IO_INIT_TYPE(f, name, open, close, read, write, seek, get, set, timeout) \
190         (f).sm_magic = SmFileMagic;     \
191         (f).f_p = (unsigned char *) 0;  \
192         (f).f_r = 0;    \
193         (f).f_w = 0;    \
194         (f).f_flags = 0L;       \
195         (f).f_file = 0; \
196         (f).f_bf.smb_base = (unsigned char *) 0;        \
197         (f).f_bf.smb_size = 0;  \
198         (f).f_lbfsize = 0;      \
199         (f).f_cookie = (void *) 0;      \
200         (f).f_ival = 0; \
201         (f).f_close = (close);  \
202         (f).f_read = (read);    \
203         (f).f_seek = (seek);    \
204         (f).f_write = (write);  \
205         (f).f_open = (open);    \
206         (f).f_setinfo = (set);  \
207         (f).f_getinfo = (get);  \
208         (f).f_timeout = (timeout);      \
209         (f).f_timeoutstate = 0; \
210         (f).f_type = (name);
211
212 #endif /* __STDC__ */
213
214 __END_DECLS
215
216 /* Internal flags */
217 #define SMFBF           0x000001        /* XXXX fully buffered */
218 #define SMLBF           0x000002        /* line buffered */
219 #define SMNBF           0x000004        /* unbuffered */
220 #define SMNOW           0x000008        /* Flush each write; take read now */
221 #define SMRD            0x000010        /* OK to read */
222 #define SMWR            0x000020        /* OK to write */
223         /* RD and WR are never simultaneously asserted */
224 #define SMRW            0x000040        /* open for reading & writing */
225 #define SMFEOF          0x000080        /* found EOF */
226 #define SMERR           0x000100        /* found error */
227 #define SMMBF           0x000200        /* buf is from malloc */
228 #define SMAPP           0x000400        /* fdopen()ed in append mode */
229 #define SMSTR           0x000800        /* this is an snprintf string */
230 #define SMOPT           0x001000        /* do fseek() optimisation */
231 #define SMNPT           0x002000        /* do not do fseek() optimisation */
232 #define SMOFF           0x004000        /* set iff offset is in fact correct */
233 #define SMALC           0x010000        /* allocate string space dynamically */
234
235 #define SMMODEMASK      0x0070  /* read/write mode */
236
237 /* defines for timeout constants */
238 #define SM_TIME_IMMEDIATE       (0)
239 #define SM_TIME_FOREVER         (-1)
240 #define SM_TIME_DEFAULT         (-2)
241
242 /* timeout state for blocking */
243 #define SM_TIME_BLOCK           (0)     /* XXX just bool? */
244 #define SM_TIME_NONBLOCK        (1)
245
246 /* Exposed buffering type flags */
247 #define SM_IO_FBF       0       /* setvbuf should set fully buffered */
248 #define SM_IO_LBF       1       /* setvbuf should set line buffered */
249 #define SM_IO_NBF       2       /* setvbuf should set unbuffered */
250
251 /* setvbuf buffered, but through at lower file type layers */
252 #define SM_IO_NOW       3
253
254 /*
255 **  size of buffer used by setbuf.
256 **  If underlying filesystem blocksize is discoverable that is used instead
257 */
258
259 #define SM_IO_BUFSIZ    4096
260
261 #define SM_IO_EOF       (-1)
262
263 /* Functions defined in ANSI C standard.  */
264 __BEGIN_DECLS
265 SM_FILE_T *sm_io_autoflush __P((SM_FILE_T *, SM_FILE_T *));
266 void     sm_io_automode __P((SM_FILE_T *, SM_FILE_T *));
267 void     sm_io_clearerr __P((SM_FILE_T *));
268 int      sm_io_close __P((SM_FILE_T *, int SM_NONVOLATILE));
269 SM_FILE_T *sm_io_dup __P((SM_FILE_T *));
270 int      sm_io_eof __P((SM_FILE_T *));
271 int      sm_io_error __P((SM_FILE_T *));
272 char    *sm_io_fgets __P((SM_FILE_T *, int, char *, int));
273 int      sm_io_flush __P((SM_FILE_T *, int SM_NONVOLATILE));
274
275 int PRINTFLIKE(3, 4)
276 sm_io_fprintf __P((SM_FILE_T *, int, const char *, ...));
277
278 int      sm_io_fputs __P((SM_FILE_T *, int, const char *));
279
280 int SCANFLIKE(3, 4)
281 sm_io_fscanf __P((SM_FILE_T *, int, const char *, ...));
282
283 int      sm_io_getc __P((SM_FILE_T *, int));
284 int      sm_io_getinfo __P((SM_FILE_T *, int, void *));
285 SM_FILE_T *sm_io_open __P((const SM_FILE_T *, int SM_NONVOLATILE, const void *,
286                            int, const void *));
287 int      sm_io_purge __P((SM_FILE_T *));
288 int      sm_io_putc __P((SM_FILE_T *, int, int));
289 size_t   sm_io_read __P((SM_FILE_T *, int, void *, size_t));
290 SM_FILE_T *sm_io_reopen __P((const SM_FILE_T *, int SM_NONVOLATILE,
291                              const void *, int, const void *, SM_FILE_T *));
292 void     sm_io_rewind __P((SM_FILE_T *, int));
293 int      sm_io_seek __P((SM_FILE_T *, int SM_NONVOLATILE, long SM_NONVOLATILE,
294                          int SM_NONVOLATILE));
295 int      sm_io_setinfo __P((SM_FILE_T *, int, void *));
296 int      sm_io_setvbuf __P((SM_FILE_T *, int, char *, int, size_t));
297
298 int SCANFLIKE(2, 3)
299 sm_io_sscanf __P((const char *, char const *, ...));
300
301 long     sm_io_tell __P((SM_FILE_T *, int SM_NONVOLATILE));
302 int      sm_io_ungetc __P((SM_FILE_T *, int, int));
303 int      sm_io_vfprintf __P((SM_FILE_T *, int, const char *, va_list));
304 size_t   sm_io_write __P((SM_FILE_T *, int, const void *, size_t));
305
306 void     sm_strio_init __P((SM_FILE_T *, char *, size_t));
307
308 extern SM_FILE_T *
309 sm_io_fopen __P((
310         char *_pathname,
311         int _flags,
312         ...));
313
314 extern SM_FILE_T *
315 sm_io_stdioopen __P((
316         FILE *_stream,
317         char *_mode));
318
319 extern int
320 sm_vasprintf __P((
321         char **_str,
322         const char *_fmt,
323         va_list _ap));
324
325 extern int
326 sm_vsnprintf __P((
327         char *,
328         size_t,
329         const char *,
330         va_list));
331
332 extern void
333 sm_perror __P((
334         const char *));
335
336 __END_DECLS
337
338 /*
339 ** Functions internal to the implementation.
340 */
341
342 __BEGIN_DECLS
343 int     sm_rget __P((SM_FILE_T *, int));
344 int     sm_vfscanf __P((SM_FILE_T *, int SM_NONVOLATILE, const char *,
345                         va_list SM_NONVOLATILE));
346 int     sm_wbuf __P((SM_FILE_T *, int, int));
347 __END_DECLS
348
349 /*
350 **  The macros are here so that we can
351 **  define function versions in the library.
352 */
353
354 #define sm_getc(f, t) \
355         (--(f)->f_r < 0 ? \
356                 sm_rget(f, t) : \
357                 (int)(*(f)->f_p++))
358
359 /*
360 **  This has been tuned to generate reasonable code on the vax using pcc.
361 **  (It also generates reasonable x86 code using gcc.)
362 */
363
364 #define sm_putc(f, t, c) \
365         (--(f)->f_w < 0 ? \
366                 (f)->f_w >= (f)->f_lbfsize ? \
367                         (*(f)->f_p = (c)), *(f)->f_p != '\n' ? \
368                                 (int)*(f)->f_p++ : \
369                                 sm_wbuf(f, t, '\n') : \
370                         sm_wbuf(f, t, (int)(c)) : \
371                 (*(f)->f_p = (c), (int)*(f)->f_p++))
372
373 #define sm_eof(p)       (((p)->f_flags & SMFEOF) != 0)
374 #define sm_error(p)     (((p)->f_flags & SMERR) != 0)
375 #define sm_clearerr(p)  ((void)((p)->f_flags &= ~(SMERR|SMFEOF)))
376
377 #define sm_io_eof(p)    sm_eof(p)
378 #define sm_io_error(p)  sm_error(p)
379
380 #define sm_io_clearerr(p)       sm_clearerr(p)
381
382 #ifndef lint
383 # ifndef _POSIX_SOURCE
384 #  define sm_io_getc(fp, t)     sm_getc(fp, t)
385 #  define sm_io_putc(fp, t, x)  sm_putc(fp, t, x)
386 # endif /* _POSIX_SOURCE */
387 #endif /* lint */
388
389 #endif /* SM_IO_H */