1 /* GNU Mailutils -- a suite of utilities for electronic mail
2    Copyright (C) 2009-2021 Free Software Foundation, Inc.
3 
4    GNU Mailutils is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3, or (at your option)
7    any later version.
8 
9    GNU Mailutils is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>. */
16 
17 #ifndef _MAILUTILS_STREAM_H
18 #define _MAILUTILS_STREAM_H
19 
20 #include <mailutils/types.h>
21 #include <stdarg.h>
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 enum mu_buffer_type
28   {
29     mu_buffer_none,
30     mu_buffer_line,
31     mu_buffer_full
32   };
33 
34 #define MU_SEEK_SET      0
35 #define MU_SEEK_CUR      1
36 #define MU_SEEK_END      2
37 
38 #define MU_STREAM_READ	      0x00000001
39 #define MU_STREAM_WRITE	      0x00000002
40 #define MU_STREAM_RDWR        (MU_STREAM_READ|MU_STREAM_WRITE)
41 #define MU_STREAM_SEEK        0x00000004
42 #define MU_STREAM_APPEND      0x00000008
43 #define MU_STREAM_CREAT	      0x00000010
44 /* So far used only by TCP streams. */
45 #define MU_STREAM_NONBLOCK    0x00000020
46 /* Not used                   0x00000040 */
47 /* Not used. Intended for mailboxes only. */
48 #define MU_STREAM_NONLOCK     0x00000080
49 /* Not used as well           0x00000100  */
50 /* FIXME: This one affects only mailboxes */
51 #define MU_STREAM_QACCESS     0x00000200
52 
53 #define MU_STREAM_RDTHRU      0x00000400
54 #define MU_STREAM_WRTHRU      0x00000800
55 
56 #define MU_STREAM_IRGRP       0x00001000
57 #define MU_STREAM_IWGRP       0x00002000
58 #define MU_STREAM_IROTH       0x00004000
59 #define MU_STREAM_IWOTH       0x00008000
60 #define MU_STREAM_IMASK       0x0000F000
61 
62   /* Ioctl families */
63 #define MU_IOCTL_TRANSPORT        0
64 #define MU_IOCTL_PROGSTREAM       1 /* Program stream */
65 #define MU_IOCTL_SEEK_LIMITS      2 /* Seek limits (get/set),
66 				       Arg: mu_off_t[2] */
67 #define MU_IOCTL_SUBSTREAM        3 /* Substream (get/set) */
68 #define MU_IOCTL_TRANSPORT_BUFFER 4 /* get/set */
69 #define MU_IOCTL_ECHO             5 /* get/set */
70 #define MU_IOCTL_NULLSTREAM       6 /* Null stream (see below) */
71 #define MU_IOCTL_LOGSTREAM        7 /* Log stream (see below) */
72 #define MU_IOCTL_XSCRIPTSTREAM    8 /* Transcript stream (see below) */
73 #define MU_IOCTL_FD               9 /* File descriptor manipulation */
74 #define MU_IOCTL_SYSLOGSTREAM    10 /* Syslog stream (see below) */
75 #define MU_IOCTL_FILTER          11 /* Filter streams (see below) */
76 #define MU_IOCTL_TOPSTREAM       12 /* Same as MU_IOCTL_SUBSTREAM, but
77 				       always returns the topmost substream.
78 				    */
79 #define MU_IOCTL_TLSSTREAM       13 /* TLS stream */
80 #define MU_IOCTL_WORDWRAPSTREAM  14 /* Word-wrapper stream */
81 #define MU_IOCTL_TCPSTREAM       15 /* TCP stream */
82 
83   /* Opcodes common for various families */
84 #define MU_IOCTL_OP_GET 0
85 #define MU_IOCTL_OP_SET 1
86 
87   /* Opcodes for MU_IOCTL_PROGSTREAM */
88 #define MU_IOCTL_PROG_STATUS 0
89 #define MU_IOCTL_PROG_PID    1
90 
91   /* Opcodes for MU_IOCTL_NULLSTREAM */
92   /* Set read pattern.
93      Argument: struct mu_nullstream_pattern *pat.
94      If pat==NULL, any reads from that stream will return EOF. */
95 #define MU_IOCTL_NULLSTREAM_SET_PATTERN 0
96   /* Set pattern class for reads:  Argument int *pclass (a class mask
97      from mailutils/cctype.h) */
98 #define MU_IOCTL_NULLSTREAM_SET_PATCLASS 1
99   /* Limit stream size.  Argument: mu_off_t *psize; */
100 #define MU_IOCTL_NULLSTREAM_SETSIZE 2
101   /* Lift the size limit.  Argument: NULL */
102 #define MU_IOCTL_NULLSTREAM_CLRSIZE 3
103 
104     /* Get or set logging severity.
105        Arg: unsigned *
106     */
107 #define MU_IOCTL_LOGSTREAM_GET_SEVERITY 0
108 #define MU_IOCTL_LOGSTREAM_SET_SEVERITY 1
109 
110   /* Codes 2 and 3 are unused now.
111      For their prior use, see
112       http://mailutils.org/wiki/Source_location_API#Deprecated_interface
113   */
114 
115   /* Get or set log mode.
116      Arg: int *
117   */
118 #define MU_IOCTL_LOGSTREAM_GET_MODE     4
119 #define MU_IOCTL_LOGSTREAM_SET_MODE     5
120 
121   /* Set locus line.
122      Arg: unsigned *
123   */
124 #define MU_IOCTL_LOGSTREAM_SET_LOCUS_LINE  6
125   /* Set locus column.
126      Arg: unsigned *
127   */
128 #define MU_IOCTL_LOGSTREAM_SET_LOCUS_COL   7
129 
130   /* Advance locus line.
131      Arg: NULL (increment by 1)
132           int *
133   */
134 #define MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_LINE 8
135   /* Advance locus column.
136      Arg: NULL (increment by 1)
137           int *
138   */
139 
140 #define MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_COL  9
141 
142   /* Suppress output of messages having severity lower than the
143      given threshold.
144      Arg: int *
145   */
146 #define MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY  10
147   /* Same as above, but:
148      Arg: const char *
149   */
150 #define MU_IOCTL_LOGSTREAM_SUPPRESS_SEVERITY_NAME 11
151 
152   /* Get or set severity output mask.
153      Arg: int *
154   */
155 #define MU_IOCTL_LOGSTREAM_GET_SEVERITY_MASK 12
156 #define MU_IOCTL_LOGSTREAM_SET_SEVERITY_MASK 13
157 
158   /* Clone the stream.
159      Arg: mu_stream_t*
160   */
161 #define MU_IOCTL_LOGSTREAM_CLONE 14
162 
163   /* Get locus range.
164      Arg: struct mu_locus_range *
165   */
166 #define MU_IOCTL_LOGSTREAM_GET_LOCUS_RANGE   15
167 
168   /* Set locus range.
169      Arg: struct mu_locus_range *
170   */
171 #define MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE   16
172 
173   /* Get prefix.
174      Arg: char **
175   */
176 #define MU_IOCTL_LOGSTREAM_GET_PREFIX        17
177 
178   /* Set prefix.
179      Arg: char *
180   */
181 #define MU_IOCTL_LOGSTREAM_SET_PREFIX        18
182 
183   /* Opcodes for MU_IOCTL_XSCRIPTSTREAM */
184   /* Swap transcript levels.
185      Arg: int *X
186 
187      New transcript level is set to *X.
188      If setting separate levels for each channel, use MU_XSCRIPT_LEVEL_PACK
189      macro to pack them into one integer value. Use
190      MU_IOCTL_XSCRIPTSTREAM_CHANNEL to confugure single channel.
191 
192      Upon successful return, previous levels are stored in X. Use the
193      MU_XSCRIPT_LEVEL_UNPACK macro to retrieve level for a particular
194      channel.
195   */
196 #define MU_IOCTL_XSCRIPTSTREAM_LEVEL 0
197 
198   /* Reconfigure a stream channel
199      Arg: struct mu_xscript_channel *
200    */
201 #define MU_IOCTL_XSCRIPTSTREAM_CHANNEL 1
202 
203   /* Opcodes for MU_IOCTL_FD */
204   /* Get "borrow state".  Borrowed descriptors remain in open state
205      after the stream is closed.
206      Arg: int *
207   */
208 #define MU_IOCTL_FD_GET_BORROW 0
209   /* Set borrow state.
210      Arg: int *
211   */
212 #define MU_IOCTL_FD_SET_BORROW 1
213 
214   /* Opcodes for MU_IOCTL_SYSLOGSTREAM */
215   /* Set logger function.
216      Arg: void (*) (int, const char *, ...)
217   */
218 #define MU_IOCTL_SYSLOGSTREAM_SET_LOGGER 0
219 
220   /* Get logger function.
221      Arg: void (**) (int, const char *, ...)
222   */
223 #define MU_IOCTL_SYSLOGSTREAM_GET_LOGGER 1
224 
225   /* Filter streams */
226   /* Get or set disabled state:
227      Arg: int*
228   */
229 #define MU_IOCTL_FILTER_GET_DISABLED 0
230 #define MU_IOCTL_FILTER_SET_DISABLED 1
231 
232   /* Set transcoder output buffer size.
233      Arg: size_t*
234      Has effect only if the stream is unbuffered
235    */
236 #define MU_IOCTL_FILTER_SET_OUTBUF_SIZE  2
237 
238   /* TLS transport streams */
239   /* Get cipher info.
240      Arg: mu_property_t *
241      On success, the following keys are defined: "protocol", "cipher", "mac"
242   */
243 #define MU_IOCTL_TLS_GET_CIPHER_INFO 0
244 
245 #define MU_TRANSPORT_INPUT  0
246 #define MU_TRANSPORT_OUTPUT 1
247 #define MU_TRANSPORT_VALID_TYPE(n) \
248   ((n) == MU_TRANSPORT_INPUT || (n) == MU_TRANSPORT_OUTPUT)
249 
250 /* Word wrapper streams */
251 /* Get left margin. */
252 #define MU_IOCTL_WORDWRAP_GET_MARGIN      0
253 /* Set left margin */
254 #define MU_IOCTL_WORDWRAP_SET_MARGIN      1
255 /* Shift left margin relative to current position */
256 #define MU_IOCTL_WORDWRAP_MOVE_MARGIN     2
257 /* Set left margin for the next line */
258 #define MU_IOCTL_WORDWRAP_SET_NEXT_MARGIN 3
259 /* Get current column */
260 #define MU_IOCTL_WORDWRAP_GET_COLUMN      4
261 
262   /* TCP streams */
263 
264   /* Get socket name.
265      Arg: struct mu_sockaddr **
266   */
267 #define MU_IOCTL_TCP_GETSOCKNAME          0
268 
269 
270 struct mu_nullstream_pattern
271 {
272   char *pattern;
273   size_t size;
274 };
275 
276 struct mu_buffer_query
277 {
278   int type;                     /* One of MU_TRANSPORT_ defines */
279   enum mu_buffer_type buftype;  /* Buffer type */
280   size_t bufsize;               /* Buffer size */
281 };
282 
283 /* Statistics */
284 enum
285   {
286     MU_STREAM_STAT_IN,          /* Bytes read */
287     MU_STREAM_STAT_OUT,         /* Bytes written */
288     MU_STREAM_STAT_READS,       /* Number of reads */
289     MU_STREAM_STAT_WRITES,      /* Number of writes */
290     MU_STREAM_STAT_SEEKS,       /* Number of seeks */
291     MU_STREAM_STAT_INLN,        /* Lines read */
292     MU_STREAM_STAT_OUTLN,       /* Lines written */
293     MU_STREAM_STAT_IN8BIT,      /* 8-bit octets read */
294     MU_STREAM_STAT_OUT8BIT,     /* 8-bit octets written */
295     _MU_STREAM_STAT_MAX
296   };
297 
298 #define MU_STREAM_STAT_MASK(n)  (1U<<(n+1))
299 
300 #define MU_STREAM_STAT_MASK_ALL  \
301   (MU_STREAM_STAT_MASK (MU_STREAM_STAT_IN) | \
302    MU_STREAM_STAT_MASK (MU_STREAM_STAT_OUT) |   \
303    MU_STREAM_STAT_MASK (MU_STREAM_STAT_READS) | \
304    MU_STREAM_STAT_MASK (MU_STREAM_STAT_WRITES) | \
305    MU_STREAM_STAT_MASK (MU_STREAM_STAT_SEEKS) | \
306    MU_STREAM_STAT_MASK (MU_STREAM_STAT_INLN) | \
307    MU_STREAM_STAT_MASK (MU_STREAM_STAT_OUTLN))
308 
309 typedef mu_off_t mu_stream_stat_buffer[_MU_STREAM_STAT_MAX];
310 int mu_stream_set_stat (mu_stream_t stream, int statmask,
311 			mu_stream_stat_buffer statbuf);
312 int mu_stream_get_stat (mu_stream_t stream, int *pstatmask,
313 			mu_off_t **pstatbuf);
314 
315 #define MU_STREAM_DEFBUFSIZ 8192
316 extern size_t mu_stream_default_buffer_size;
317 
318 void mu_stream_ref (mu_stream_t stream);
319 void mu_stream_unref (mu_stream_t stream);
320 void mu_stream_destroy (mu_stream_t *pstream);
321 int mu_stream_open (mu_stream_t stream);
322 const char *mu_stream_strerror (mu_stream_t stream, int rc);
323 int mu_stream_err (mu_stream_t stream);
324 int mu_stream_last_error (mu_stream_t stream);
325 void mu_stream_clearerr (mu_stream_t stream);
326 int mu_stream_seterr (struct _mu_stream *stream, int code, int perm);
327 
328 int mu_stream_is_open (mu_stream_t stream);
329 int mu_stream_eof (mu_stream_t stream);
330 int mu_stream_seek (mu_stream_t stream, mu_off_t offset, int whence,
331 		    mu_off_t *pres);
332 int mu_stream_skip_input_bytes (mu_stream_t stream, mu_off_t count,
333 				mu_off_t *pres);
334 
335 int mu_stream_set_buffer (mu_stream_t stream, enum mu_buffer_type type,
336 			  size_t size);
337 int mu_stream_get_buffer (mu_stream_t stream,
338 			  struct mu_buffer_query *qry);
339 int mu_stream_read (mu_stream_t stream, void *buf, size_t size, size_t *pread);
340 int mu_stream_readdelim (mu_stream_t stream, char *buf, size_t size,
341 			 int delim, size_t *pread);
342 int mu_stream_readline (mu_stream_t stream, char *buf, size_t size, size_t *pread);
343 int mu_stream_getdelim (mu_stream_t stream, char **pbuf, size_t *psize,
344 			int delim, size_t *pread);
345 int mu_stream_getline (mu_stream_t stream, char **pbuf, size_t *psize,
346 		       size_t *pread);
347 int mu_stream_write (mu_stream_t stream, const void *buf, size_t size,
348 		     size_t *pwrite);
349 int mu_stream_writeline (mu_stream_t stream, const char *buf, size_t size);
350 int mu_stream_flush (mu_stream_t stream);
351 int mu_stream_close (mu_stream_t stream);
352 int mu_stream_size (mu_stream_t stream, mu_off_t *psize);
353 int mu_stream_ioctl (mu_stream_t stream, int family, int opcode, void *ptr);
354 int mu_stream_truncate (mu_stream_t stream, mu_off_t);
355 int mu_stream_shutdown (mu_stream_t stream, int how);
356 
357 #define MU_STREAM_READY_RD 0x1
358 #define MU_STREAM_READY_WR 0x2
359 #define MU_STREAM_READY_EX 0x4
360 struct timeval;  /* Needed for the following declaration */
361 
362 int mu_stream_wait   (mu_stream_t stream, int *pflags, struct timeval *);
363 
364 void mu_stream_get_flags (mu_stream_t stream, int *pflags);
365 int mu_stream_set_flags (mu_stream_t stream, int fl);
366 int mu_stream_clr_flags (mu_stream_t stream, int fl);
367 
368 int mu_stream_vprintf (mu_stream_t str, const char *fmt, va_list ap);
369 int mu_stream_printf (mu_stream_t stream, const char *fmt, ...)
370                       MU_PRINTFLIKE(2,3);
371 
372 int mu_stream_copy (mu_stream_t dst, mu_stream_t src, mu_off_t size,
373 		    mu_off_t *pcsz);
374 int mu_stream_copy_wcb (mu_stream_t dst, mu_stream_t src, mu_off_t size,
375 			void (*cbf) (char *, size_t, void *), void *cbd,
376 			mu_off_t *pcsz);
377 int mu_stream_copy_nl (mu_stream_t dst, mu_stream_t src, mu_off_t size,
378 		       mu_off_t *pcsz);
379 
380 int mu_stream_header_copy (mu_stream_t dst, mu_stream_t src, char **exclude_names);
381 
382 int mu_stream_shift (mu_stream_t str, mu_off_t off_a, mu_off_t off_b,
383 		     size_t bufsize);
384 
385 int mu_file_stream_create (mu_stream_t *pstream, const char *filename, int flags);
386 struct mu_tempfile_hints;
387 int mu_temp_file_stream_create (mu_stream_t *pstream,
388 				struct mu_tempfile_hints *hints, int flags);
389 int mu_fd_stream_create (mu_stream_t *pstream, char *filename, int fd,
390 			 int flags);
391 
392 #define MU_STDIN_FD  0
393 #define MU_STDOUT_FD 1
394 #define MU_STDERR_FD 2
395 int mu_stdio_stream_create (mu_stream_t *pstream, int fd, int flags);
396 
397 int mu_memory_stream_create (mu_stream_t *pstream, int flags);
398 int mu_static_memory_stream_create (mu_stream_t *pstream, const void *mem,
399 				    size_t size);
400 int mu_fixed_memory_stream_create (mu_stream_t *pstream, void *mem,
401 				   size_t size, int flags);
402 
403 int mu_mapfile_stream_create (mu_stream_t *pstream, const char *filename,
404 			      int flags);
405 int mu_socket_stream_create (mu_stream_t *pstream, const char *filename,
406 			     int flags);
407 
408 int mu_streamref_create_abridged (mu_stream_t *pref, mu_stream_t str,
409 				  mu_off_t start, mu_off_t end);
410 int mu_streamref_create (mu_stream_t *pref, mu_stream_t str);
411 
412 int mu_tcp_stream_create_from_sa (mu_stream_t *pstream,
413 				  struct mu_sockaddr *remote_addr,
414 				  struct mu_sockaddr *source_addr, int flags);
415 
416 int mu_tcp_stream_create_with_source_ip (mu_stream_t *stream,
417 					 const char *host, unsigned port,
418 					 unsigned long source_ip,
419 					 int flags);
420 int mu_tcp_stream_create_with_source_host (mu_stream_t *stream,
421 					   const char *host, unsigned port,
422 					   const char *source_host,
423 					   int flags);
424 int mu_tcp_stream_create (mu_stream_t *stream, const char *host, unsigned port,
425 			  int flags);
426 
427 /* Transcript log levels */
428 #define MU_XSCRIPT_NORMAL  0  /* Normal transcript */
429 #define MU_XSCRIPT_SECURE  1  /* Security-related data filtered out */
430 #define MU_XSCRIPT_PAYLOAD 2  /* Actual payload (may be copious) */
431 
432 #define MU_XSCRIPT_LEVEL_PACK_BIT 0x100
433 #define MU_XSCRIPT_LEVEL_IS_PACKED(m) ((m) & MU_XSCRIPT_LEVEL_PACK_BIT)
434 
435 /* Packing/unpacking of channel modes for the
436    MU_IOCTL_XSCRIPTSTREAM.MU_IOCTL_XSCRIPTSTREAM_LEVEL ioctl.
437 */
438 #define MU_XSCRIPT_LEVEL_MASK(chan, mode)	\
439   (((mode) & 0x3) << ((chan)<<2))
440 #define MU_XSCRIPT_LEVEL_UNMASK(chan, mode)	\
441   ((((mode) & 0xff) >> ((chan)<<2)) & 0x3)
442 
443 /* Combine input and output channel modes into one integer, unless they
444    are the same, in which case return input mode unchanged.
445  */
446 #define MU_XSCRIPT_LEVEL_PACK(imode, omode)	\
447   ((imode) == (omode)				\
448    ? (imode)					\
449    : (MU_XSCRIPT_LEVEL_PACK_BIT			\
450       | MU_XSCRIPT_LEVEL_MASK(0,imode)		\
451       | MU_XSCRIPT_LEVEL_MASK(1,omode)))
452 #define MU_XSCRIPT_LEVEL_UNPACK(chan, pack)	\
453   (MU_XSCRIPT_LEVEL_IS_PACKED(pack)		\
454    ? MU_XSCRIPT_LEVEL_UNMASK(chan, pack) : (pack))
455 
456 struct mu_xscript_channel
457 {
458   int cd;                   /* Channel descriptor */
459   int level;                /* Channel transcript level */
460   size_t length;            /* Length of data, for MU_XSCRIPT_PAYLOAD */
461 };
462 
463 int mu_xscript_stream_create(mu_stream_t *pref, mu_stream_t transport,
464 			     mu_stream_t logstr,
465 			     const char *prefix[]);
466 
467 int mu_iostream_create (mu_stream_t *pref, mu_stream_t in, mu_stream_t out);
468 int mu_dbgstream_create(mu_stream_t *pref, int severity);
469 
470 int mu_rdcache_stream_create (mu_stream_t *pstream, mu_stream_t transport,
471 			      int flags);
472 
473 int mu_nullstream_create (mu_stream_t *pref, int flags);
474 
475 int mu_wordwrap_stream_create (mu_stream_t *pstream, mu_stream_t transport,
476 			       size_t left_margin, size_t right_margin);
477 
478 extern size_t mu_temp_file_threshold_size;
479 int mu_temp_stream_create (mu_stream_t *pstream, size_t threshold);
480 
481 #ifdef __cplusplus
482 }
483 #endif
484 
485 #endif
486