diff options
Diffstat (limited to 'maildrop/message.h')
| -rw-r--r-- | maildrop/message.h | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/maildrop/message.h b/maildrop/message.h new file mode 100644 index 0000000..0f6a5ee --- /dev/null +++ b/maildrop/message.h @@ -0,0 +1,184 @@ +#ifndef message_h +#define message_h + + +////////////////////////////////////////////////////////////////////////////// +// +// A Message object represents the message being filtered. It is expected +// that the message is going to be scanned, repetitively, from start to +// finish, in one direction. Therefore, access to the message contents is +// sequential. +// +// A Message object can be initiated in two ways. It can be initiated from +// a file. The Message object will check if the file is seekable. If so, +// the Message object will simply use the Mio class to access the file. +// If the file is not seekable, the message will be saved in a temporary +// file, and the Mio class will be used to access the temporary file. +// +// However, if the message size turns out to be smaller the SMALLMSG bytes, +// the message is saved in a memory buffer, and accessed from there, for +// speed. We presume that most messages are less than SMALLMSG bytes long. +// +// The second way is for the messages contents to be manually specified. +// For this initialization method, first the message is saved into the +// memory buffer. If it proves to be too small, the message gets written +// out into a temporary file. +// +////////////////////////////////////////////////////////////////////////////// + +#include "config.h" +#include "mio.h" +#include "tempfile.h" +#include <sys/types.h> +#include <errno.h> +#include <string.h> + +#if HAVE_UNISTD_H +#include <unistd.h> +#else + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +#endif + +class Buffer; + +class Message { + Mio mio; + TempFile tempfile; + char *buffer; + char *bufptr; + char *extra_headers; + char *extra_headersptr; + off_t msgsize; + off_t msglines; + + static void readerr(); + static void seekerr(); +public: + Message(); + ~Message(); + void Init(int); // Initialize from file descriptor + + void Init(); // Begin initializing externally + void Init(const void *, unsigned); // From existing contents. + void ExtraHeaders(const Buffer &); + void Rewind(); // Start reading the message + void RewindIgnore(); // Rewind, ignore msginfo + int appendline(Buffer &, int=1); // Read newline-terminated line. + void seek(off_t); + off_t tell(); + int get_c(); + int peek(); + off_t MessageSize(); + off_t MessageLines() { return (msglines); } + void setmsgsize(); + } ; + +#include "funcs.h" +#include "maildrop.h" + +inline int Message::peek() // Current character. +{ + if (extra_headersptr) + return ( (unsigned char) *extra_headersptr ); + + if (mio.fd() >= 0) + { + errno=0; + + int c=mio.peek(); + + if (c < 0 && errno) readerr(); + return (c); + } + + if (bufptr >= buffer + msgsize) return (-1); + return ( (int)(unsigned char)*bufptr ); +} + +inline int Message::get_c() // Get character. +{ +int c; + + if (extra_headersptr) + { + c= (unsigned char) *extra_headersptr++; + if (!*extra_headersptr) extra_headersptr=0; + return (c); + } + + if (mio.fd() >= 0) + { + errno=0; + + c=mio.get(); + if (c < 0 && errno) readerr(); + return (c); + } + + if (bufptr >= buffer + msgsize) return (-1); + return ( (int)(unsigned char)*bufptr++ ); +} + +inline off_t Message::tell() +{ +off_t pos; + + if ( mio.fd() < 0) + pos=bufptr - buffer; + else + { + pos=mio.tell(); + if (pos == -1) seekerr(); + } + pos -= maildrop.msginfo.msgoffset; + if (extra_headersptr) + pos += extra_headersptr-extra_headers; + else + { + if (extra_headers) pos += strlen(extra_headers); + } + return (pos); +} + +inline void Message::seek(off_t n) +{ +int l=0; + + if (extra_headers && n < (l=strlen(extra_headers))) + { + extra_headersptr= extra_headers + n; + n=0; + } + else + { + extra_headersptr=0; + n -= l; + } + n += maildrop.msginfo.msgoffset; + + if (mio.fd() >= 0) + { + if (mio.seek(n, SEEK_SET) < 0) seekerr(); + } + else + { + if (n > msgsize) n=msgsize; + bufptr=buffer+n; + } +} + +inline off_t Message::MessageSize() +{ + off_t s=msgsize; + s -= maildrop.msginfo.msgoffset; + if (extra_headers) + s += strlen(extra_headers); + + return (s); +} + +#endif |
