1/*-
2 * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD$
27 */
28
29#include <sys/types.h>
30#include <sys/stat.h>
31
32#include <assert.h>
33#include <zlib.h>
34#include <err.h>
35#include <errno.h>
36#include <fcntl.h>
37#include <stdarg.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <unistd.h>
42
43#include "misc.h"
44#include "stream.h"
45
46/*
47 * Simple stream API to make my life easier.  If the fgetln() and
48 * funopen() functions were standard and if funopen() wasn't using
49 * wrong types for the function pointers, I could have just used
50 * stdio, but life sucks.
51 *
52 * For now, streams are always block-buffered.
53 */
54
55/*
56 * Try to quiet warnings as much as possible with GCC while staying
57 * compatible with other compilers.
58 */
59#ifndef __unused
60#if defined(__GNUC__) && (__GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 7)
61#define	__unused	__attribute__((__unused__))
62#else
63#define	__unused
64#endif
65#endif
66
67/*
68 * Flags passed to the flush methods.
69 *
70 * STREAM_FLUSH_CLOSING is passed during the last flush call before
71 * closing a stream.  This allows the zlib filter to emit the EOF
72 * marker as appropriate.  In all other cases, STREAM_FLUSH_NORMAL
73 * should be passed.
74 *
75 * These flags are completely unused in the default flush method,
76 * but they are very important for the flush method of the zlib
77 * filter.
78 */
79typedef enum {
80	STREAM_FLUSH_NORMAL,
81	STREAM_FLUSH_CLOSING
82} stream_flush_t;
83
84/*
85 * This is because buf_new() will always allocate size + 1 bytes,
86 * so our buffer sizes will still be power of 2 values.
87 */
88#define	STREAM_BUFSIZ	1023
89
90struct buf {
91	char *buf;
92	size_t size;
93	size_t in;
94	size_t off;
95};
96
97struct stream {
98	void *cookie;
99	int fd;
100	int buf;
101	struct buf *rdbuf;
102	struct buf *wrbuf;
103	stream_readfn_t *readfn;
104	stream_writefn_t *writefn;
105	stream_closefn_t *closefn;
106	int eof;
107	struct stream_filter *filter;
108	void *fdata;
109};
110
111typedef int	stream_filter_initfn_t(struct stream *, void *);
112typedef void	stream_filter_finifn_t(struct stream *);
113typedef int	stream_filter_flushfn_t(struct stream *, struct buf *,
114		    stream_flush_t);
115typedef ssize_t	stream_filter_fillfn_t(struct stream *, struct buf *);
116
117struct stream_filter {
118	stream_filter_t id;
119	stream_filter_initfn_t *initfn;
120	stream_filter_finifn_t *finifn;
121	stream_filter_fillfn_t *fillfn;
122	stream_filter_flushfn_t *flushfn;
123};
124
125/* Low-level buffer API. */
126#define	buf_avail(buf)		((buf)->size - (buf)->off - (buf)->in)
127#define	buf_count(buf)		((buf)->in)
128#define	buf_size(buf)		((buf)->size)
129
130static void		 buf_more(struct buf *, size_t);
131static void		 buf_less(struct buf *, size_t);
132static void		 buf_grow(struct buf *, size_t);
133
134/* Internal stream functions. */
135static ssize_t		 stream_fill(struct stream *);
136static ssize_t		 stream_fill_default(struct stream *, struct buf *);
137static int		 stream_flush_int(struct stream *, stream_flush_t);
138static int		 stream_flush_default(struct stream *, struct buf *,
139			     stream_flush_t);
140
141/* Filters specific functions. */
142static struct stream_filter *stream_filter_lookup(stream_filter_t);
143static int		 stream_filter_init(struct stream *, void *);
144static void		 stream_filter_fini(struct stream *);
145
146/* The zlib stream filter declarations. */
147#define	ZFILTER_EOF	1				/* Got Z_STREAM_END. */
148
149struct zfilter {
150	int flags;
151	struct buf *rdbuf;
152	struct buf *wrbuf;
153	z_stream *rdstate;
154	z_stream *wrstate;
155};
156
157static int		 zfilter_init(struct stream *, void *);
158static void		 zfilter_fini(struct stream *);
159static ssize_t		 zfilter_fill(struct stream *, struct buf *);
160static int		 zfilter_flush(struct stream *, struct buf *,
161			     stream_flush_t);
162
163/* The MD5 stream filter. */
164struct md5filter {
165	MD5_CTX ctx;
166	char *md5;
167	char lastc;
168#define PRINT	1
169#define WS	2
170#define STRING	3
171#define SEEN	4
172	int state;
173};
174
175static int		 md5filter_init(struct stream *, void *);
176static void		 md5filter_fini(struct stream *);
177static ssize_t		 md5filter_fill(struct stream *, struct buf *);
178static int		 md5filter_flush(struct stream *, struct buf *,
179			     stream_flush_t);
180static int		 md5rcsfilter_flush(struct stream *, struct buf *,
181			     stream_flush_t);
182
183/* The available stream filters. */
184struct stream_filter stream_filters[] = {
185	{
186		STREAM_FILTER_NULL,
187		NULL,
188		NULL,
189		stream_fill_default,
190		stream_flush_default
191	},
192	{
193	       	STREAM_FILTER_ZLIB,
194		zfilter_init,
195		zfilter_fini,
196		zfilter_fill,
197		zfilter_flush
198	},
199	{
200		STREAM_FILTER_MD5,
201		md5filter_init,
202		md5filter_fini,
203		md5filter_fill,
204		md5filter_flush
205	},
206	{
207		STREAM_FILTER_MD5RCS,
208		md5filter_init,
209		md5filter_fini,
210		md5filter_fill,
211		md5rcsfilter_flush
212	}
213
214};
215
216
217/* Create a new buffer. */
218struct buf *
219buf_new(size_t size)
220{
221	struct buf *buf;
222
223	buf = xmalloc(sizeof(struct buf));
224	/*
225	 * We keep one spare byte so that stream_getln() can put a '\0'
226	 * there in case the stream doesn't have an ending newline.
227	 */
228	buf->buf = xmalloc(size + 1);
229	memset(buf->buf, 0, size + 1);
230	buf->size = size;
231	buf->in = 0;
232	buf->off = 0;
233	return (buf);
234}
235
236/*
237 * Grow the size of the buffer.  If "need" is 0, bump its size to the
238 * next power of 2 value.  Otherwise, bump it to the next power of 2
239 * value bigger than "need".
240 */
241static void
242buf_grow(struct buf *buf, size_t need)
243{
244
245	if (need == 0)
246		buf->size = buf->size * 2 + 1; /* Account for the spare byte. */
247	else {
248		assert(need > buf->size);
249		while (buf->size < need)
250			buf->size = buf->size * 2 + 1;
251	}
252	buf->buf = xrealloc(buf->buf, buf->size + 1);
253}
254
255/* Make more room in the buffer if needed. */
256static void
257buf_prewrite(struct buf *buf)
258{
259
260	if (buf_count(buf) == buf_size(buf))
261		buf_grow(buf, 0);
262	if (buf_count(buf) > 0 && buf_avail(buf) == 0) {
263		memmove(buf->buf, buf->buf + buf->off, buf_count(buf));
264		buf->off = 0;
265	}
266}
267
268/* Account for "n" bytes being added in the buffer. */
269static void
270buf_more(struct buf *buf, size_t n)
271{
272
273	assert(n <= buf_avail(buf));
274	buf->in += n;
275}
276
277/* Account for "n" bytes having been read in the buffer. */
278static void
279buf_less(struct buf *buf, size_t n)
280{
281
282	assert(n <= buf_count(buf));
283	buf->in -= n;
284	if (buf->in == 0)
285		buf->off = 0;
286	else
287		buf->off += n;
288}
289
290/* Free a buffer. */
291void
292buf_free(struct buf *buf)
293{
294
295	free(buf->buf);
296	free(buf);
297}
298
299static struct stream *
300stream_new(stream_readfn_t *readfn, stream_writefn_t *writefn,
301    stream_closefn_t *closefn)
302{
303	struct stream *stream;
304
305	stream = xmalloc(sizeof(struct stream));
306	if (readfn == NULL && writefn == NULL) {
307		errno = EINVAL;
308		return (NULL);
309	}
310	if (readfn != NULL)
311		stream->rdbuf = buf_new(STREAM_BUFSIZ);
312	else
313		stream->rdbuf = NULL;
314	if (writefn != NULL)
315		stream->wrbuf = buf_new(STREAM_BUFSIZ);
316	else
317		stream->wrbuf = NULL;
318	stream->cookie = NULL;
319	stream->fd = -1;
320	stream->buf = 0;
321	stream->readfn = readfn;
322	stream->writefn = writefn;
323	stream->closefn = closefn;
324	stream->filter = stream_filter_lookup(STREAM_FILTER_NULL);
325	stream->fdata = NULL;
326	stream->eof = 0;
327	return (stream);
328}
329
330/* Create a new stream associated with a void *. */
331struct stream *
332stream_open(void *cookie, stream_readfn_t *readfn, stream_writefn_t *writefn,
333    stream_closefn_t *closefn)
334{
335	struct stream *stream;
336
337	stream = stream_new(readfn, writefn, closefn);
338	stream->cookie = cookie;
339	return (stream);
340}
341
342/* Associate a file descriptor with a stream. */
343struct stream *
344stream_open_fd(int fd, stream_readfn_t *readfn, stream_writefn_t *writefn,
345    stream_closefn_t *closefn)
346{
347	struct stream *stream;
348
349	stream = stream_new(readfn, writefn, closefn);
350	stream->cookie = &stream->fd;
351	stream->fd = fd;
352	return (stream);
353}
354
355/* Associate a buf with a stream. */
356struct stream *
357stream_open_buf(struct buf *b)
358{
359	struct stream *stream;
360
361	stream = stream_new(stream_read_buf, stream_append_buf, stream_close_buf);
362	stream->cookie = b;
363	stream->buf = 1;
364	b->in = 0;
365	return (stream);
366}
367
368/*
369 * Truncate a buffer, just decrease offset pointer.
370 * XXX: this can be dangerous if not used correctly.
371 */
372void
373stream_truncate_buf(struct buf *b, off_t off)
374{
375	b->off += off;
376}
377
378/* Like open() but returns a stream. */
379struct stream *
380stream_open_file(const char *path, int flags, ...)
381{
382	struct stream *stream;
383	stream_readfn_t *readfn;
384	stream_writefn_t *writefn;
385	va_list ap;
386	mode_t mode;
387	int fd;
388
389	va_start(ap, flags);
390	if (flags & O_CREAT) {
391		/*
392		 * GCC says I should not be using mode_t here since it's
393		 * promoted to an int when passed through `...'.
394		 */
395		mode = va_arg(ap, int);
396		fd = open(path, flags, mode);
397	} else
398		fd = open(path, flags);
399	va_end(ap);
400	if (fd == -1)
401		return (NULL);
402
403	flags &= O_ACCMODE;
404	if (flags == O_RDONLY) {
405		readfn = stream_read_fd;
406		writefn = NULL;
407	} else if (flags == O_WRONLY) {
408		readfn = NULL;
409		writefn = stream_write_fd;
410	} else if (flags == O_RDWR) {
411		assert(flags == O_RDWR);
412		readfn = stream_read_fd;
413		writefn = stream_write_fd;
414	} else {
415		errno = EINVAL;
416		close(fd);
417		return (NULL);
418	}
419
420	stream = stream_open_fd(fd, readfn, writefn, stream_close_fd);
421	if (stream == NULL)
422		close(fd);
423	return (stream);
424}
425
426/* Return the file descriptor associated with this stream, or -1. */
427int
428stream_fileno(struct stream *stream)
429{
430
431	return (stream->fd);
432}
433
434/* Convenience read function for character buffers. */
435ssize_t
436stream_read_buf(void *cookie, void *buf, size_t size)
437{
438	struct buf *b;
439	size_t avail;
440
441	/* Use in to be read offset. */
442	b = (struct buf *)cookie;
443	/* Just return what we have if the request is to large. */
444	avail = b->off - b->in;
445	if (avail < size) {
446		memcpy(buf, (b->buf + b->in), avail);
447		b->in += avail;
448		return (avail);
449	}
450	memcpy(buf, (b->buf + b->in), size);
451	b->in += size;
452	return (size);
453}
454
455/* Convenience write function for appending character buffers. */
456ssize_t
457stream_append_buf(void *cookie, const void *buf, size_t size)
458{
459	struct buf *b;
460	size_t avail;
461
462	/* Use off to be write offset. */
463	b = (struct buf *)cookie;
464
465	avail = b->size - b->off;
466	if (size > avail)
467		buf_grow(b, b->size + size);
468	memcpy((b->buf + b->off), buf, size);
469	b->off += size;
470	b->buf[b->off] = '\0';
471	return (size);
472}
473
474/* Convenience close function for freeing character buffers. */
475int
476stream_close_buf(void *cookie)
477{
478	void *data;
479
480	data = cookie;
481	/* Basically a NOP. */
482	return (0);
483}
484
485/* Convenience read function for file descriptors. */
486ssize_t
487stream_read_fd(void *cookie, void *buf, size_t size)
488{
489	ssize_t nbytes;
490	int fd;
491
492	fd = *(int *)cookie;
493	nbytes = read(fd, buf, size);
494	return (nbytes);
495}
496
497/* Convenience write function for file descriptors. */
498ssize_t
499stream_write_fd(void *cookie, const void *buf, size_t size)
500{
501	ssize_t nbytes;
502	int fd;
503
504	fd = *(int *)cookie;
505	nbytes = write(fd, buf, size);
506	return (nbytes);
507}
508
509/* Convenience close function for file descriptors. */
510int
511stream_close_fd(void *cookie)
512{
513	int fd, ret;
514
515	fd = *(int *)cookie;
516	ret = close(fd);
517	return (ret);
518}
519
520/* Read some bytes from the stream. */
521ssize_t
522stream_read(struct stream *stream, void *buf, size_t size)
523{
524	struct buf *rdbuf;
525	ssize_t ret;
526	size_t n;
527
528	rdbuf = stream->rdbuf;
529	if (buf_count(rdbuf) == 0) {
530		ret = stream_fill(stream);
531		if (ret <= 0)
532			return (-1);
533	}
534	n = min(size, buf_count(rdbuf));
535	memcpy(buf, rdbuf->buf + rdbuf->off, n);
536	buf_less(rdbuf, n);
537	return (n);
538}
539
540/* A blocking stream_read call. */
541ssize_t
542stream_read_blocking(struct stream *stream, void *buf, size_t size)
543{
544	struct buf *rdbuf;
545	ssize_t ret;
546	size_t n;
547
548	rdbuf = stream->rdbuf;
549	while (buf_count(rdbuf) <= size) {
550		ret = stream_fill(stream);
551		if (ret <= 0)
552			return (-1);
553	}
554	/* XXX: Should be at least size bytes in the buffer, right? */
555	/* Just do this to make sure. */
556	n = min(size, buf_count(rdbuf));
557	memcpy(buf, rdbuf->buf + rdbuf->off, n);
558	buf_less(rdbuf, n);
559	return (n);
560}
561
562/*
563 * Read a line from the stream and return a pointer to it.
564 *
565 * If "len" is non-NULL, the length of the string will be put into it.
566 * The pointer is only valid until the next stream API call.  The line
567 * can be modified by the caller, provided he doesn't write before or
568 * after it.
569 *
570 * This is somewhat similar to the BSD fgetln() function, except that
571 * "len" can be NULL here.  In that case the string is terminated by
572 * overwriting the '\n' character with a NUL character.  If it's the
573 * last line in the stream and it has no ending newline, we can still
574 * add '\0' after it, because we keep one spare byte in the buffers.
575 *
576 * However, be warned that one can't handle binary lines properly
577 * without knowing the size of the string since those can contain
578 * NUL characters.
579 */
580char *
581stream_getln(struct stream *stream, size_t *len)
582{
583	struct buf *buf;
584	char *cp, *line;
585	ssize_t n;
586	size_t done, size;
587
588	buf = stream->rdbuf;
589	if (buf_count(buf) == 0) {
590		n = stream_fill(stream);
591		if (n <= 0)
592			return (NULL);
593	}
594	cp = memchr(buf->buf + buf->off, '\n', buf_count(buf));
595	for (done = buf_count(buf); cp == NULL; done += n) {
596		n = stream_fill(stream);
597		if (n < 0)
598			return (NULL);
599		if (n == 0)
600			/* Last line of the stream. */
601			cp = buf->buf + buf->off + buf->in - 1;
602		else
603			cp = memchr(buf->buf + buf->off + done, '\n',
604			    buf_count(buf) - done);
605	}
606	line = buf->buf + buf->off;
607	assert(cp >= line);
608	size = cp - line + 1;
609	buf_less(buf, size);
610	if (len != NULL) {
611		*len = size;
612	} else {
613		/* Terminate the string when len == NULL. */
614		if (line[size - 1] == '\n')
615			line[size - 1] = '\0';
616		else
617			line[size] = '\0';
618	}
619	return (line);
620}
621
622/* Write some bytes to a stream. */
623ssize_t
624stream_write(struct stream *stream, const void *src, size_t nbytes)
625{
626	struct buf *buf;
627	int error;
628
629	buf = stream->wrbuf;
630	if (nbytes > buf_size(buf))
631		buf_grow(buf, nbytes);
632	if (nbytes > buf_avail(buf)) {
633		error = stream_flush_int(stream, STREAM_FLUSH_NORMAL);
634		if (error)
635			return (-1);
636	}
637	memcpy(buf->buf + buf->off + buf->in, src, nbytes);
638	buf_more(buf, nbytes);
639	return (nbytes);
640}
641
642/* Formatted output to a stream. */
643int
644stream_printf(struct stream *stream, const char *fmt, ...)
645{
646	struct buf *buf;
647	va_list ap;
648	int error, ret;
649
650	buf = stream->wrbuf;
651again:
652	va_start(ap, fmt);
653	ret = vsnprintf(buf->buf + buf->off + buf->in, buf_avail(buf), fmt, ap);
654	va_end(ap);
655	if (ret < 0)
656		return (ret);
657	if ((unsigned)ret >= buf_avail(buf)) {
658		if ((unsigned)ret >= buf_size(buf))
659			buf_grow(buf, ret + 1);
660		if ((unsigned)ret >= buf_avail(buf)) {
661			error = stream_flush_int(stream, STREAM_FLUSH_NORMAL);
662			if (error)
663				return (-1);
664		}
665		goto again;
666	}
667	buf_more(buf, ret);
668	return (ret);
669}
670
671/* Flush the entire write buffer of the stream. */
672int
673stream_flush(struct stream *stream)
674{
675	int error;
676
677	error = stream_flush_int(stream, STREAM_FLUSH_NORMAL);
678	return (error);
679}
680
681/* Internal flush API. */
682static int
683stream_flush_int(struct stream *stream, stream_flush_t how)
684{
685	struct buf *buf;
686	int error;
687
688	buf = stream->wrbuf;
689	error = (*stream->filter->flushfn)(stream, buf, how);
690	assert(buf_count(buf) == 0);
691	return (error);
692}
693
694/* The default flush method. */
695static int
696stream_flush_default(struct stream *stream, struct buf *buf,
697    stream_flush_t __unused how)
698{
699	ssize_t n;
700
701	while (buf_count(buf) > 0) {
702		do {
703			n = (*stream->writefn)(stream->cookie,
704			    buf->buf + buf->off, buf_count(buf));
705		} while (n == -1 && errno == EINTR);
706		if (n <= 0)
707			return (-1);
708		buf_less(buf, n);
709	}
710	return (0);
711}
712
713/* Flush the write buffer and call fsync() on the file descriptor. */
714int
715stream_sync(struct stream *stream)
716{
717	int error;
718
719	if (stream->fd == -1) {
720		errno = EINVAL;
721		return (-1);
722	}
723	error = stream_flush_int(stream, STREAM_FLUSH_NORMAL);
724	if (error)
725		return (-1);
726	error = fsync(stream->fd);
727	return (error);
728}
729
730/* Like truncate() but on a stream. */
731int
732stream_truncate(struct stream *stream, off_t size)
733{
734	int error;
735
736	if (stream->fd == -1) {
737		errno = EINVAL;
738		return (-1);
739	}
740	error = stream_flush_int(stream, STREAM_FLUSH_NORMAL);
741	if (error)
742		return (-1);
743	error = ftruncate(stream->fd, size);
744	return (error);
745}
746
747/* Like stream_truncate() except the off_t parameter is an offset. */
748int
749stream_truncate_rel(struct stream *stream, off_t off)
750{
751	struct stat sb;
752	int error;
753
754	if (stream->buf) {
755		stream_truncate_buf(stream->cookie, off);
756		return (0);
757	}
758	if (stream->fd == -1) {
759		errno = EINVAL;
760		return (-1);
761	}
762	error = stream_flush_int(stream, STREAM_FLUSH_NORMAL);
763	if (error)
764		return (-1);
765	error = fstat(stream->fd, &sb);
766	if (error)
767		return (-1);
768	error = stream_truncate(stream, sb.st_size + off);
769	return (error);
770}
771
772/* Rewind the stream. */
773int
774stream_rewind(struct stream *stream)
775{
776	int error;
777
778	if (stream->fd == -1) {
779		errno = EINVAL;
780		return (-1);
781	}
782	if (stream->rdbuf != NULL)
783		buf_less(stream->rdbuf, buf_count(stream->rdbuf));
784	if (stream->wrbuf != NULL) {
785		error = stream_flush_int(stream, STREAM_FLUSH_NORMAL);
786		if (error)
787			return (error);
788	}
789	error = lseek(stream->fd, 0, SEEK_SET);
790	return (error);
791}
792
793/* Return EOF status. */
794int
795stream_eof(struct stream *stream)
796{
797
798	return (stream->eof);
799}
800
801/* Close a stream and free any resources held by it. */
802int
803stream_close(struct stream *stream)
804{
805	int error;
806
807	if (stream == NULL)
808		return (0);
809
810	error = 0;
811	if (stream->wrbuf != NULL)
812		error = stream_flush_int(stream, STREAM_FLUSH_CLOSING);
813	stream_filter_fini(stream);
814	if (stream->closefn != NULL)
815		/*
816		 * We might overwrite a previous error from stream_flush(),
817		 * but we have no choice, because wether it had worked or
818		 * not, we need to close the file descriptor.
819		 */
820		error = (*stream->closefn)(stream->cookie);
821	if (stream->rdbuf != NULL)
822		buf_free(stream->rdbuf);
823	if (stream->wrbuf != NULL)
824		buf_free(stream->wrbuf);
825	free(stream);
826	return (error);
827}
828
829/* The default fill method. */
830static ssize_t
831stream_fill_default(struct stream *stream, struct buf *buf)
832{
833	ssize_t n;
834
835	if (stream->eof)
836		return (0);
837	assert(buf_avail(buf) > 0);
838	n = (*stream->readfn)(stream->cookie, buf->buf + buf->off + buf->in,
839	    buf_avail(buf));
840	if (n < 0)
841		return (-1);
842	if (n == 0) {
843		stream->eof = 1;
844		return (0);
845	}
846	buf_more(buf, n);
847	return (n);
848}
849
850/*
851 * Refill the read buffer.  This function is not permitted to return
852 * without having made more bytes available, unless there was an error.
853 * Moreover, stream_fill() returns the number of bytes added.
854 */
855static ssize_t
856stream_fill(struct stream *stream)
857{
858	struct stream_filter *filter;
859	struct buf *buf;
860#ifndef NDEBUG
861	size_t oldcount;
862#endif
863	ssize_t n;
864
865	filter = stream->filter;
866	buf = stream->rdbuf;
867	buf_prewrite(buf);
868#ifndef NDEBUG
869	oldcount = buf_count(buf);
870#endif
871	n = (*filter->fillfn)(stream, buf);
872	assert((n > 0 && n == (signed)(buf_count(buf) - oldcount)) ||
873	    (n <= 0 && buf_count(buf) == oldcount));
874	return (n);
875}
876
877/*
878 * Lookup a stream filter.
879 *
880 * We are not supposed to get passed an invalid filter id, since
881 * filter ids are an enum type and we don't have invalid filter
882 * ids in the enum :-).  Thus, we are not checking for out of
883 * bounds access here.  If it happens, it's the caller's fault
884 * anyway.
885 */
886static struct stream_filter *
887stream_filter_lookup(stream_filter_t id)
888{
889	struct stream_filter *filter;
890
891	filter = stream_filters;
892	while (filter->id != id)
893		filter++;
894	return (filter);
895}
896
897static int
898stream_filter_init(struct stream *stream, void *data)
899{
900	struct stream_filter *filter;
901	int error;
902
903	filter = stream->filter;
904	if (filter->initfn == NULL)
905		return (0);
906	error = (*filter->initfn)(stream, data);
907	return (error);
908}
909
910static void
911stream_filter_fini(struct stream *stream)
912{
913	struct stream_filter *filter;
914
915	filter = stream->filter;
916	if (filter->finifn != NULL)
917		(*filter->finifn)(stream);
918}
919
920/*
921 * Start a filter on a stream.
922 */
923int
924stream_filter_start(struct stream *stream, stream_filter_t id, void *data)
925{
926	struct stream_filter *filter;
927	int error;
928
929	filter = stream->filter;
930	if (id == filter->id)
931		return (0);
932	stream_filter_fini(stream);
933	stream->filter = stream_filter_lookup(id);
934	stream->fdata = NULL;
935	error = stream_filter_init(stream, data);
936	return (error);
937}
938
939
940/* Stop a filter, this is equivalent to setting the null filter. */
941void
942stream_filter_stop(struct stream *stream)
943{
944
945	stream_filter_start(stream, STREAM_FILTER_NULL, NULL);
946}
947
948/* The zlib stream filter implementation. */
949
950/* Take no chances with zlib... */
951static void *
952zfilter_alloc(void __unused *opaque, unsigned int items, unsigned int size)
953{
954
955	return (xmalloc(items * size));
956}
957
958static void
959zfilter_free(void __unused *opaque, void *ptr)
960{
961
962	free(ptr);
963}
964
965static int
966zfilter_init(struct stream *stream, void __unused *data)
967{
968	struct zfilter *zf;
969	struct buf *buf;
970	z_stream *state;
971	int rv;
972
973	zf = xmalloc(sizeof(struct zfilter));
974	memset(zf, 0, sizeof(struct zfilter));
975	if (stream->rdbuf != NULL) {
976		state = xmalloc(sizeof(z_stream));
977		state->zalloc = zfilter_alloc;
978		state->zfree = zfilter_free;
979		state->opaque = Z_NULL;
980		rv = inflateInit(state);
981		if (rv != Z_OK)
982			errx(1, "inflateInit: %s", state->msg);
983		buf = buf_new(buf_size(stream->rdbuf));
984		zf->rdbuf = stream->rdbuf;
985		stream->rdbuf = buf;
986		zf->rdstate = state;
987	}
988	if (stream->wrbuf != NULL) {
989		state = xmalloc(sizeof(z_stream));
990		state->zalloc = zfilter_alloc;
991		state->zfree = zfilter_free;
992		state->opaque = Z_NULL;
993		rv = deflateInit(state, Z_DEFAULT_COMPRESSION);
994		if (rv != Z_OK)
995			errx(1, "deflateInit: %s", state->msg);
996		buf = buf_new(buf_size(stream->wrbuf));
997		zf->wrbuf = stream->wrbuf;
998		stream->wrbuf = buf;
999		zf->wrstate = state;
1000	}
1001	stream->fdata = zf;
1002	return (0);
1003}
1004
1005static void
1006zfilter_fini(struct stream *stream)
1007{
1008	struct zfilter *zf;
1009	struct buf *zbuf;
1010	z_stream *state;
1011	ssize_t n;
1012
1013	zf = stream->fdata;
1014	if (zf->rdbuf != NULL) {
1015		state = zf->rdstate;
1016		zbuf = zf->rdbuf;
1017		/*
1018		 * Even if it has produced all the bytes, zlib sometimes
1019		 * hasn't seen the EOF marker, so we need to call inflate()
1020		 * again to make sure we have eaten all the zlib'ed bytes.
1021		 */
1022		if ((zf->flags & ZFILTER_EOF) == 0) {
1023			n = zfilter_fill(stream, stream->rdbuf);
1024			assert(n == 0 && zf->flags & ZFILTER_EOF);
1025		}
1026		inflateEnd(state);
1027		free(state);
1028		buf_free(stream->rdbuf);
1029		stream->rdbuf = zbuf;
1030	}
1031	if (zf->wrbuf != NULL) {
1032		state = zf->wrstate;
1033		zbuf = zf->wrbuf;
1034		/*
1035		 * Compress the remaining bytes in the buffer, if any,
1036		 * and emit an EOF marker as appropriate.  We ignore
1037		 * the error because we can't do anything about it at
1038		 * this point, and it can happen if we're getting
1039		 * disconnected.
1040		 */
1041		(void)zfilter_flush(stream, stream->wrbuf,
1042		    STREAM_FLUSH_CLOSING);
1043		deflateEnd(state);
1044		free(state);
1045		buf_free(stream->wrbuf);
1046		stream->wrbuf = zbuf;
1047	}
1048	free(zf);
1049}
1050
1051static int
1052zfilter_flush(struct stream *stream, struct buf *buf, stream_flush_t how)
1053{
1054	struct zfilter *zf;
1055	struct buf *zbuf;
1056	z_stream *state;
1057	size_t lastin, lastout, ate, prod;
1058	int done, error, flags, rv;
1059
1060	zf = stream->fdata;
1061	state = zf->wrstate;
1062	zbuf = zf->wrbuf;
1063
1064	if (how == STREAM_FLUSH_NORMAL)
1065		flags = Z_SYNC_FLUSH;
1066	else
1067		flags = Z_FINISH;
1068
1069	done = 0;
1070	rv = Z_OK;
1071
1072again:
1073	/*
1074	 * According to zlib.h, we should have at least 6 bytes
1075	 * available when using deflate() with Z_SYNC_FLUSH.
1076	 */
1077	if ((buf_avail(zbuf) < 6 && flags == Z_SYNC_FLUSH) ||
1078	    rv == Z_BUF_ERROR || buf_avail(buf) == 0) {
1079		error = stream_flush_default(stream, zbuf, how);
1080		if (error)
1081			return (error);
1082	}
1083
1084	state->next_in = (Bytef *)(buf->buf + buf->off);
1085	state->avail_in = buf_count(buf);
1086	state->next_out = (Bytef *)(zbuf->buf + zbuf->off + zbuf->in);
1087	state->avail_out = buf_avail(zbuf);
1088	lastin = state->avail_in;
1089	lastout = state->avail_out;
1090	rv = deflate(state, flags);
1091	if (rv != Z_BUF_ERROR && rv != Z_OK && rv != Z_STREAM_END)
1092		errx(1, "deflate: %s", state->msg);
1093	ate = lastin - state->avail_in;
1094	prod = lastout - state->avail_out;
1095	buf_less(buf, ate);
1096	buf_more(zbuf, prod);
1097	if ((flags == Z_SYNC_FLUSH && buf_count(buf) > 0) ||
1098	    (flags == Z_FINISH && rv != Z_STREAM_END) ||
1099	    (rv == Z_BUF_ERROR))
1100		goto again;
1101
1102	assert(rv == Z_OK || (rv == Z_STREAM_END && flags == Z_FINISH));
1103	error = stream_flush_default(stream, zbuf, how);
1104	return (error);
1105}
1106
1107static ssize_t
1108zfilter_fill(struct stream *stream, struct buf *buf)
1109{
1110	struct zfilter *zf;
1111	struct buf *zbuf;
1112	z_stream *state;
1113	size_t lastin, lastout, new;
1114	ssize_t n;
1115	int rv;
1116
1117	zf = stream->fdata;
1118	state = zf->rdstate;
1119	zbuf = zf->rdbuf;
1120
1121	assert(buf_avail(buf) > 0);
1122	if (buf_count(zbuf) == 0) {
1123		n = stream_fill_default(stream, zbuf);
1124		if (n <= 0)
1125			return (n);
1126	}
1127again:
1128	assert(buf_count(zbuf) > 0);
1129	state->next_in = (Bytef *)(zbuf->buf + zbuf->off);
1130	state->avail_in = buf_count(zbuf);
1131	state->next_out = (Bytef *)(buf->buf + buf->off + buf->in);
1132	state->avail_out = buf_avail(buf);
1133	lastin = state->avail_in;
1134	lastout = state->avail_out;
1135	rv = inflate(state, Z_SYNC_FLUSH);
1136	buf_less(zbuf, lastin - state->avail_in);
1137	new = lastout - state->avail_out;
1138	if (new == 0 && rv != Z_STREAM_END) {
1139		n = stream_fill_default(stream, zbuf);
1140		if (n == -1)
1141			return (-1);
1142		if (n == 0)
1143			return (0);
1144		goto again;
1145	}
1146	if (rv != Z_STREAM_END && rv != Z_OK)
1147		errx(1, "inflate: %s", state->msg);
1148	if (rv == Z_STREAM_END)
1149		zf->flags |= ZFILTER_EOF;
1150	buf_more(buf, new);
1151	return (new);
1152}
1153
1154/* The MD5 stream filter implementation. */
1155static int
1156md5filter_init(struct stream *stream, void *data)
1157{
1158	struct md5filter *mf;
1159
1160	mf = xmalloc(sizeof(struct md5filter));
1161	MD5_Init(&mf->ctx);
1162	mf->md5 = data;
1163	mf->lastc = ';';
1164	mf->state = PRINT;
1165	stream->fdata = mf;
1166	return (0);
1167}
1168
1169static void
1170md5filter_fini(struct stream *stream)
1171{
1172	struct md5filter *mf;
1173
1174	mf = stream->fdata;
1175	MD5_End(mf->md5, &mf->ctx);
1176	free(stream->fdata);
1177}
1178
1179static ssize_t
1180md5filter_fill(struct stream *stream, struct buf *buf)
1181{
1182	ssize_t n;
1183
1184	assert(buf_avail(buf) > 0);
1185	n = stream_fill_default(stream, buf);
1186	return (n);
1187}
1188
1189static int
1190md5filter_flush(struct stream *stream, struct buf *buf, stream_flush_t how)
1191{
1192	struct md5filter *mf;
1193	int error;
1194
1195	mf = stream->fdata;
1196	MD5_Update(&mf->ctx, buf->buf + buf->off, buf->in);
1197	error = stream_flush_default(stream, buf, how);
1198	return (error);
1199}
1200
1201/* MD5 flush for RCS, where whitespaces are omitted. */
1202static int
1203md5rcsfilter_flush(struct stream *stream, struct buf *buf, stream_flush_t how)
1204{
1205	struct md5filter *mf;
1206	char *ptr, *end;
1207	char *start;
1208	char space[2];
1209	int error;
1210
1211	mf = stream->fdata;
1212	space[0] = ' ';
1213	space[1] = '\0';
1214	ptr = buf->buf + buf->off;
1215	end = buf->buf + buf->off + buf->in;
1216
1217#define IS_WS(var) ((var) == ' ' || (var) == '\n' || (var) == '\t' || \
1218                    (var) == '\010' || (var) == '\013' || (var) == '\f' || \
1219                    (var) == '\r')
1220
1221#define IS_SPECIAL(var) ((var) == '$' || (var) == ',' || (var) == ':' || \
1222			 (var) == ';' || (var) == '@')
1223
1224#define IS_PRINT(var) (!IS_WS(var) && (var) != '@')
1225
1226	/* XXX: We can do better than this state machine. */
1227	while (ptr < end) {
1228		switch (mf->state) {
1229			/* Outside RCS statements. */
1230			case PRINT:
1231				start = ptr;
1232				while (ptr < end && IS_PRINT(*ptr)) {
1233					mf->lastc = *ptr;
1234					ptr++;
1235				}
1236				MD5_Update(&mf->ctx, start, (ptr - start));
1237				if (ptr < end) {
1238					if (*ptr == '@') {
1239						MD5_Update(&mf->ctx, ptr, 1);
1240						ptr++;
1241						mf->state = STRING;
1242					} else {
1243						mf->state = WS;
1244					}
1245				}
1246				break;
1247			case WS:
1248				while (ptr < end && IS_WS(*ptr)) {
1249					ptr++;
1250				}
1251				if (ptr < end) {
1252					if (*ptr == '@') {
1253						if (mf->lastc == '@') {
1254							MD5_Update(&mf->ctx,
1255							    space, 1);
1256						}
1257						MD5_Update(&mf->ctx, ptr, 1);
1258						ptr++;
1259						mf->state = STRING;
1260					} else {
1261						if (!IS_SPECIAL(*ptr) &&
1262						    !IS_SPECIAL(mf->lastc)) {
1263							MD5_Update(&mf->ctx,
1264							    space, 1);
1265						}
1266						mf->state = PRINT;
1267					}
1268				}
1269				break;
1270			case STRING:
1271				start = ptr;
1272				while (ptr < end && *ptr != '@') {
1273					ptr++;
1274				}
1275				MD5_Update(&mf->ctx, start, (ptr - start));
1276				if (ptr < end) {
1277					MD5_Update(&mf->ctx, ptr, 1);
1278					ptr++;
1279					mf->state = SEEN;
1280				}
1281				break;
1282			case SEEN:
1283				if (*ptr == '@') {
1284					MD5_Update(&mf->ctx, ptr, 1);
1285					ptr++;
1286					mf->state = STRING;
1287				} else if(IS_WS(*ptr)) {
1288					mf->lastc = '@';
1289					mf->state = WS;
1290				} else {
1291					mf->state = PRINT;
1292				}
1293				break;
1294			default:
1295				err(1, "Invalid state");
1296				break;
1297		}
1298	}
1299
1300	error = stream_flush_default(stream, buf, how);
1301	return (error);
1302}
1303
1304