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