1#ifndef _VSTREAM_H_INCLUDED_
2#define _VSTREAM_H_INCLUDED_
3
4/*++
5/* NAME
6/*	vstream 3h
7/* SUMMARY
8/*	simple buffered I/O package
9/* SYNOPSIS
10/*	#include <vstream.h>
11/* DESCRIPTION
12/* .nf
13
14 /*
15  * System library.
16  */
17#include <sys/time.h>
18#include <time.h>
19#include <fcntl.h>
20#include <stdarg.h>
21#include <setjmp.h>
22#include <unistd.h>
23
24 /*
25  * Utility library.
26  */
27#include <vbuf.h>
28
29 /*
30  * Simple buffered stream. The members of this structure are not part of the
31  * official interface and can change without prior notice.
32  */
33typedef ssize_t (*VSTREAM_FN) (int, void *, size_t, int, void *);
34typedef int (*VSTREAM_WAITPID_FN) (pid_t, WAIT_STATUS_T *, int);
35
36#ifdef NO_SIGSETJMP
37#define VSTREAM_JMP_BUF	jmp_buf
38#else
39#define VSTREAM_JMP_BUF	sigjmp_buf
40#endif
41
42typedef struct VSTREAM {
43    VBUF    buf;			/* generic intelligent buffer */
44    int     fd;				/* file handle, no 256 limit */
45    VSTREAM_FN read_fn;			/* buffer fill action */
46    VSTREAM_FN write_fn;		/* buffer fill action */
47    ssize_t req_bufsize;		/* requested read/write buffer size */
48    void   *context;			/* application context */
49    off_t   offset;			/* cached seek info */
50    char   *path;			/* give it at least try */
51    int     read_fd;			/* read channel (double-buffered) */
52    int     write_fd;			/* write channel (double-buffered) */
53    VBUF    read_buf;			/* read buffer (double-buffered) */
54    VBUF    write_buf;			/* write buffer (double-buffered) */
55    pid_t   pid;			/* vstream_popen/close() */
56    VSTREAM_WAITPID_FN waitpid_fn;	/* vstream_popen/close() */
57    int     timeout;			/* read/write timout */
58    VSTREAM_JMP_BUF *jbuf;		/* exception handling */
59    struct timeval iotime;		/* time of last fill/flush */
60    struct timeval time_limit;		/* read/write time limit */
61} VSTREAM;
62
63extern VSTREAM vstream_fstd[];		/* pre-defined streams */
64
65#define VSTREAM_IN		(&vstream_fstd[0])
66#define VSTREAM_OUT		(&vstream_fstd[1])
67#define VSTREAM_ERR		(&vstream_fstd[2])
68
69#define VSTREAM_FLAG_RD_ERR	VBUF_FLAG_RD_ERR	/* read error */
70#define VSTREAM_FLAG_WR_ERR	VBUF_FLAG_WR_ERR	/* write error */
71#define VSTREAM_FLAG_RD_TIMEOUT	VBUF_FLAG_RD_TIMEOUT	/* read timeout */
72#define VSTREAM_FLAG_WR_TIMEOUT	VBUF_FLAG_WR_TIMEOUT	/* write timeout */
73
74#define	VSTREAM_FLAG_ERR	VBUF_FLAG_ERR	/* some I/O error */
75#define VSTREAM_FLAG_EOF	VBUF_FLAG_EOF	/* end of file */
76#define VSTREAM_FLAG_TIMEOUT	VBUF_FLAG_TIMEOUT	/* timeout error */
77#define VSTREAM_FLAG_FIXED	VBUF_FLAG_FIXED	/* fixed-size buffer */
78#define VSTREAM_FLAG_BAD	VBUF_FLAG_BAD
79
80#define VSTREAM_FLAG_READ	(1<<8)	/* read buffer */
81#define VSTREAM_FLAG_WRITE	(1<<9)	/* write buffer */
82#define VSTREAM_FLAG_SEEK	(1<<10)	/* seek info valid */
83#define VSTREAM_FLAG_NSEEK	(1<<11)	/* can't seek this file */
84#define VSTREAM_FLAG_DOUBLE	(1<<12)	/* double buffer */
85#define VSTREAM_FLAG_DEADLINE	(1<<13)	/* deadline active */
86
87#define VSTREAM_PURGE_READ	(1<<0)	/* flush unread data */
88#define VSTREAM_PURGE_WRITE	(1<<1)	/* flush unwritten data */
89#define VSTREAM_PURGE_BOTH	(VSTREAM_PURGE_READ|VSTREAM_PURGE_WRITE)
90
91#define VSTREAM_BUFSIZE		4096
92
93extern VSTREAM *vstream_fopen(const char *, int, mode_t);
94extern int vstream_fclose(VSTREAM *);
95extern off_t vstream_fseek(VSTREAM *, off_t, int);
96extern off_t vstream_ftell(VSTREAM *);
97extern int vstream_fpurge(VSTREAM *, int);
98extern int vstream_fflush(VSTREAM *);
99extern int vstream_fputs(const char *, VSTREAM *);
100extern VSTREAM *vstream_fdopen(int, int);
101extern int vstream_fdclose(VSTREAM *);
102
103#define vstream_fread(v, b, n)	vbuf_read(&(v)->buf, (b), (n))
104#define vstream_fwrite(v, b, n)	vbuf_write(&(v)->buf, (b), (n))
105
106#define VSTREAM_PUTC(ch, vp)	VBUF_PUT(&(vp)->buf, (ch))
107#define VSTREAM_GETC(vp)	VBUF_GET(&(vp)->buf)
108#define vstream_ungetc(vp, ch)	vbuf_unget(&(vp)->buf, (ch))
109#define VSTREAM_EOF		VBUF_EOF
110
111#define VSTREAM_PUTCHAR(ch)	VSTREAM_PUTC((ch), VSTREAM_OUT)
112#define VSTREAM_GETCHAR()	VSTREAM_GETC(VSTREAM_IN)
113
114#define vstream_fileno(vp)	((vp)->fd)
115#define vstream_req_bufsize(vp)	((const ssize_t) ((vp)->req_bufsize))
116#define vstream_context(vp)	((vp)->context)
117#define vstream_rd_error(vp)	vbuf_rd_error(&(vp)->buf)
118#define vstream_wr_error(vp)	vbuf_wr_error(&(vp)->buf)
119#define vstream_ferror(vp)	vbuf_error(&(vp)->buf)
120#define vstream_feof(vp)	vbuf_eof(&(vp)->buf)
121#define vstream_rd_timeout(vp)	vbuf_rd_timeout(&(vp)->buf)
122#define vstream_wr_timeout(vp)	vbuf_wr_timeout(&(vp)->buf)
123#define vstream_ftimeout(vp)	vbuf_timeout(&(vp)->buf)
124#define vstream_clearerr(vp)	vbuf_clearerr(&(vp)->buf)
125#define VSTREAM_PATH(vp)	((vp)->path ? (const char *) (vp)->path : "unknown_stream")
126#define vstream_ftime(vp)	((time_t) ((vp)->iotime.tv_sec))
127#define vstream_ftimeval(vp)	((vp)->iotime)
128
129#define vstream_fstat(vp, fl)	((vp)->buf.flags & (fl))
130
131extern void vstream_control(VSTREAM *, int,...);
132
133#define VSTREAM_CTL_END		0
134#define VSTREAM_CTL_READ_FN	1
135#define VSTREAM_CTL_WRITE_FN	2
136#define VSTREAM_CTL_PATH	3
137#define VSTREAM_CTL_DOUBLE	4
138#define VSTREAM_CTL_READ_FD	5
139#define VSTREAM_CTL_WRITE_FD	6
140#define VSTREAM_CTL_WAITPID_FN	7
141#define VSTREAM_CTL_TIMEOUT	8
142#define VSTREAM_CTL_EXCEPT	9
143#define VSTREAM_CTL_CONTEXT	10
144#ifdef F_DUPFD
145#define VSTREAM_CTL_DUPFD	11
146#endif
147#define VSTREAM_CTL_BUFSIZE	12
148#define VSTREAM_CTL_SWAP_FD	13
149#define VSTREAM_CTL_START_DEADLINE	14
150#define VSTREAM_CTL_STOP_DEADLINE	15
151
152extern VSTREAM *PRINTFLIKE(1, 2) vstream_printf(const char *,...);
153extern VSTREAM *PRINTFLIKE(2, 3) vstream_fprintf(VSTREAM *, const char *,...);
154
155extern VSTREAM *vstream_popen(int,...);
156extern int vstream_pclose(VSTREAM *);
157
158#define vstream_ispipe(vp)	((vp)->pid != 0)
159
160#define VSTREAM_POPEN_END	0	/* terminator */
161#define VSTREAM_POPEN_COMMAND	1	/* command is string */
162#define VSTREAM_POPEN_ARGV	2	/* command is array */
163#define VSTREAM_POPEN_UID	3	/* privileges */
164#define VSTREAM_POPEN_GID	4	/* privileges */
165#define VSTREAM_POPEN_ENV	5	/* extra environment */
166#define VSTREAM_POPEN_SHELL	6	/* alternative shell */
167#define VSTREAM_POPEN_WAITPID_FN 7	/* child catcher, waitpid() compat. */
168#define VSTREAM_POPEN_EXPORT	8	/* exportable environment */
169
170extern VSTREAM *vstream_vprintf(const char *, va_list);
171extern VSTREAM *vstream_vfprintf(VSTREAM *, const char *, va_list);
172
173extern ssize_t vstream_peek(VSTREAM *);
174extern ssize_t vstream_bufstat(VSTREAM *, int);
175
176#define VSTREAM_BST_FLAG_IN		(1<<0)
177#define VSTREAM_BST_FLAG_OUT		(1<<1)
178#define VSTREAM_BST_FLAG_PEND		(1<<2)
179
180#define VSTREAM_BST_MASK_DIR	(VSTREAM_BST_FLAG_IN | VSTREAM_BST_FLAG_OUT)
181#define VSTREAM_BST_IN_PEND	(VSTREAM_BST_FLAG_IN | VSTREAM_BST_FLAG_PEND)
182#define VSTREAM_BST_OUT_PEND	(VSTREAM_BST_FLAG_OUT | VSTREAM_BST_FLAG_PEND)
183
184#define vstream_peek(vp) vstream_bufstat((vp), VSTREAM_BST_IN_PEND)
185
186extern const char *vstream_peek_data(VSTREAM *);
187
188 /*
189  * Exception handling. We use pointer to jmp_buf to avoid a lot of unused
190  * baggage for streams that don't need this functionality.
191  *
192  * XXX sigsetjmp()/siglongjmp() save and restore the signal mask which can
193  * avoid surprises in code that manipulates signals, but unfortunately some
194  * systems have bugs in their implementation.
195  */
196#ifdef NO_SIGSETJMP
197#define vstream_setjmp(stream)		setjmp((stream)->jbuf[0])
198#define vstream_longjmp(stream, val)	longjmp((stream)->jbuf[0], (val))
199#else
200#define vstream_setjmp(stream)		sigsetjmp((stream)->jbuf[0], 1)
201#define vstream_longjmp(stream, val)	siglongjmp((stream)->jbuf[0], (val))
202#endif
203
204 /*
205  * Tweaks and workarounds.
206  */
207extern int vstream_tweak_sock(VSTREAM *);
208extern int vstream_tweak_tcp(VSTREAM *);
209
210#define vstream_flags(stream) ((const int) (stream)->buf.flags)
211
212/* LICENSE
213/* .ad
214/* .fi
215/*	The Secure Mailer license must be distributed with this software.
216/* AUTHOR(S)
217/*	Wietse Venema
218/*	IBM T.J. Watson Research
219/*	P.O. Box 704
220/*	Yorktown Heights, NY 10598, USA
221/*--*/
222
223#endif
224