[dovecot-cvs] dovecot/src/lib-mail Makefile.am, 1.8,
	1.9 istream-header-filter.c, NONE, 1.1 istream-header-filter.h,
	NONE, 1.1
    cras at procontrol.fi 
    cras at procontrol.fi
       
    Sun Jun 20 09:20:34 EEST 2004
    
        - Previous message: [dovecot-cvs] dovecot/src/lib strfuncs.c, 1.39, 1.40 strfuncs.h,
	1.19, 1.20
 
        - Next message: [dovecot-cvs] dovecot/src/lib-storage/index/mbox mbox-mail.c, 1.8,
	1.9 mbox-save.c, 1.50, 1.51 mbox-storage.c, 1.80,
	1.81 mbox-storage.h, 1.20, 1.21
 
         -  Messages sorted by: 
              [ date ]
              [ thread ]
              [ subject ]
              [ author ]
         
 
       
    
  
Update of /home/cvs/dovecot/src/lib-mail
In directory talvi:/tmp/cvs-serv4578/lib-mail
Modified Files:
	Makefile.am 
Added Files:
	istream-header-filter.c istream-header-filter.h 
Log Message:
Added istream-header-filter, which allows filtering specified headers from
input stream.
Index: Makefile.am
===================================================================
RCS file: /home/cvs/dovecot/src/lib-mail/Makefile.am,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- Makefile.am	27 Apr 2004 20:25:53 -0000	1.8
+++ Makefile.am	20 Jun 2004 06:20:32 -0000	1.9
@@ -5,6 +5,7 @@
 	-I$(top_srcdir)/src/lib-charset
 
 libmail_a_SOURCES = \
+	istream-header-filter.c \
 	message-address.c \
 	message-body-search.c \
 	message-content-parser.c \
@@ -19,6 +20,7 @@
 	quoted-printable.c
 
 noinst_HEADERS = \
+	istream-header-filter.h \
 	mail-types.h \
 	message-address.h \
 	message-body-search.h \
--- NEW FILE: istream-header-filter.c ---
/* Copyright (C) 2003-2004 Timo Sirainen */
/* FIXME: the header wouldn't necessarily have to be read in memory. we could
   just parse it forward in _read(). */
#include "lib.h"
#include "buffer.h"
#include "message-parser.h"
#include "istream-internal.h"
#include "istream-header-filter.h"
#include <stdlib.h>
struct header_filter_istream {
	struct _istream istream;
	struct istream *input;
	buffer_t *headers;
	struct message_size header_size;
};
static void _close(struct _iostream *stream __attr_unused__)
{
}
static void _destroy(struct _iostream *stream)
{
	struct header_filter_istream *mstream =
		(struct header_filter_istream *)stream;
	i_stream_unref(mstream->input);
	buffer_free(mstream->headers);
}
static void _set_max_buffer_size(struct _iostream *stream, size_t max_size)
{
	struct header_filter_istream *mstream =
		(struct header_filter_istream *)stream;
	i_stream_set_max_buffer_size(mstream->input, max_size);
}
static void _set_blocking(struct _iostream *stream, int timeout_msecs,
			  void (*timeout_cb)(void *), void *context)
{
	struct header_filter_istream *mstream =
		(struct header_filter_istream *)stream;
	i_stream_set_blocking(mstream->input, timeout_msecs,
			      timeout_cb, context);
}
static ssize_t _read(struct _istream *stream)
{
	struct header_filter_istream *mstream =
		(struct header_filter_istream *)stream;
	ssize_t ret;
	size_t pos;
	if (stream->istream.v_offset < mstream->header_size.virtual_size) {
		/* we don't support mixing headers and body.
		   it shouldn't be needed. */
		return -2;
	}
	if (mstream->input->v_offset - mstream->header_size.physical_size !=
	    stream->istream.v_offset - mstream->header_size.virtual_size) {
		i_stream_seek(mstream->input, stream->istream.v_offset -
			      mstream->header_size.virtual_size +
			      mstream->header_size.physical_size);
	}
	ret = i_stream_read(mstream->input);
	mstream->istream.pos -= mstream->istream.skip;
	mstream->istream.skip = 0;
	mstream->istream.buffer = i_stream_get_data(mstream->input, &pos);
	if (pos <= mstream->istream.pos) {
		i_assert(ret <= 0);
	} else {
		ret = pos - mstream->istream.pos;
                mstream->istream.pos = pos;
	}
	return ret;
}
static void _seek(struct _istream *stream, uoff_t v_offset)
{
	struct header_filter_istream *mstream =
		(struct header_filter_istream *)stream;
	stream->istream.v_offset = v_offset;
	if (v_offset < mstream->header_size.virtual_size) {
		/* still in headers */
		stream->skip = v_offset;
		stream->pos = mstream->header_size.virtual_size;
		stream->buffer = buffer_get_data(mstream->headers, NULL);
	} else {
		/* body - use our real input stream */
		stream->skip = stream->pos = 0;
		stream->buffer = NULL;
		v_offset += mstream->header_size.physical_size -
			mstream->header_size.virtual_size;
		i_stream_seek(mstream->input, v_offset);
	}
}
static void read_and_hide_headers(struct istream *input,
				  const char *const *headers,
				  size_t headers_count, buffer_t *dest,
				  struct message_size *hdr_size)
{
	struct message_header_parser_ctx *hdr_ctx;
	struct message_header_line *hdr;
	uoff_t virtual_size = 0;
	hdr_ctx = message_parse_header_init(input, hdr_size, FALSE);
	while ((hdr = message_parse_header_next(hdr_ctx)) != NULL) {
		if (hdr->eoh) {
			if (dest != NULL)
				buffer_append(dest, "\r\n", 2);
			else
				virtual_size += 2;
			break;
		}
		if (bsearch(hdr->name, headers, headers_count,
			    sizeof(*headers), bsearch_strcasecmp) != NULL) {
			/* ignore */
		} else if (dest != NULL) {
			if (!hdr->continued) {
				buffer_append(dest, hdr->name, hdr->name_len);
				buffer_append(dest, ": ", 2);
			}
			buffer_append(dest, hdr->value, hdr->value_len);
			buffer_append(dest, "\r\n", 2);
		} else {
			if (!hdr->continued)
				virtual_size += hdr->name_len + 2;
			virtual_size += hdr->value_len + 2;
		}
	}
	message_parse_header_deinit(hdr_ctx);
	if (dest != NULL)
		virtual_size = buffer_get_used_size(dest);
	hdr_size->virtual_size = virtual_size;
	hdr_size->lines = 0;
}
struct istream *
i_stream_create_header_filter(pool_t pool, struct istream *input,
			      const char *const *headers, size_t headers_count)
{
	struct header_filter_istream *mstream;
	mstream = p_new(pool, struct header_filter_istream, 1);
	mstream->input = input;
	i_stream_ref(mstream->input);
	mstream->headers = buffer_create_dynamic(default_pool,
						 8192, (size_t)-1);
	read_and_hide_headers(input, headers, headers_count, mstream->headers,
			      &mstream->header_size);
	mstream->istream.buffer = buffer_get_data(mstream->headers, NULL);
	mstream->istream.pos = mstream->header_size.virtual_size;
	mstream->istream.iostream.close = _close;
	mstream->istream.iostream.destroy = _destroy;
	mstream->istream.iostream.set_max_buffer_size = _set_max_buffer_size;
	mstream->istream.iostream.set_blocking = _set_blocking;
	mstream->istream.read = _read;
	mstream->istream.seek = _seek;
	return _i_stream_create(&mstream->istream, pool, -1, 0);
}
--- NEW FILE: istream-header-filter.h ---
#ifndef __ISTREAM_HEADER_FILTER_H
#define __ISTREAM_HEADER_FILTER_H
/* NOTE: NULL-terminated headers list must be sorted. */
struct istream *
i_stream_create_header_filter(pool_t pool, struct istream *input,
			      const char *const *headers, size_t headers_count);
#endif
    
    
        
	- Previous message: [dovecot-cvs] dovecot/src/lib strfuncs.c, 1.39, 1.40 strfuncs.h,
	1.19, 1.20
 
	- Next message: [dovecot-cvs] dovecot/src/lib-storage/index/mbox mbox-mail.c, 1.8,
	1.9 mbox-save.c, 1.50, 1.51 mbox-storage.c, 1.80,
	1.81 mbox-storage.h, 1.20, 1.21
 
         -  Messages sorted by: 
              [ date ]
              [ thread ]
              [ subject ]
              [ author ]
         
 
       
More information about the dovecot-cvs
mailing list