Back to index

courier  0.68.2
message.h
Go to the documentation of this file.
00001 #ifndef       message_h
00002 #define       message_h
00003 
00004 
00006 //
00007 // A Message object represents the message being filtered.  It is expected
00008 // that the message is going to be scanned, repetitively, from start to
00009 // finish, in one direction.  Therefore, access to the message contents is
00010 // sequential.
00011 //
00012 // A Message object can be initiated in two ways.  It can be initiated from
00013 // a file.  The Message object will check if the file is seekable.  If so,
00014 // the Message object will simply use the Mio class to access the file.
00015 // If the file is not seekable, the message will be saved in a temporary
00016 // file, and the Mio class will be used to access the temporary file.
00017 //
00018 // However, if the message size turns out to be smaller the SMALLMSG bytes,
00019 // the message is saved in a memory buffer, and accessed from there, for
00020 // speed.  We presume that most messages are less than SMALLMSG bytes long.
00021 //
00022 // The second way is for the messages contents to be manually specified.
00023 // For this initialization method, first the message is saved into the
00024 // memory buffer.  If it proves to be too small, the message gets written
00025 // out into a temporary file.
00026 //
00028 
00029 #include      "config.h"
00030 #include      "mio.h"
00031 #include      "tempfile.h"
00032 #include      <sys/types.h>
00033 #include      <errno.h>
00034 #include      <string.h>
00035 
00036 #if HAVE_UNISTD_H
00037 #include      <unistd.h>
00038 #else
00039 
00040 #ifndef       SEEK_SET
00041 #define       SEEK_SET      0
00042 #endif
00043 
00044 #endif
00045 
00046 class Buffer;
00047 
00048 class Message {
00049        Mio mio;
00050        TempFile tempfile;
00051        char   *buffer;
00052        char   *bufptr;
00053        char   *extra_headers;
00054        char   *extra_headersptr;
00055        off_t  msgsize;
00056        off_t  msglines;
00057 
00058        static void readerr();
00059        static void seekerr();
00060 public:
00061        Message();
00062        ~Message();
00063        void Init(int);             // Initialize from file descriptor
00064 
00065        void Init();         // Begin initializing externally
00066        void Init(const void *, unsigned); // From existing contents.
00067        void ExtraHeaders(const Buffer &);
00068        void Rewind();              // Start reading the message
00069        void RewindIgnore(); // Rewind, ignore msginfo
00070        int appendline(Buffer &, int=1);   // Read newline-terminated line.
00071        void seek(off_t);
00072        off_t tell();
00073        int get_c();
00074        int peek();
00075        off_t MessageSize();
00076        off_t MessageLines() { return (msglines); }
00077        void setmsgsize();
00078        } ;
00079 
00080 #include      "funcs.h"
00081 #include      "maildrop.h"
00082 
00083 inline int Message::peek()         // Current character.
00084 {
00085        if (extra_headersptr)
00086               return ( (unsigned char) *extra_headersptr );
00087 
00088        if (mio.fd() >= 0)
00089        {
00090               errno=0;
00091 
00092        int    c=mio.peek();
00093 
00094               if (c < 0 && errno)  readerr();
00095               return (c);
00096        }
00097 
00098        if (bufptr >= buffer + msgsize)    return (-1);
00099        return ( (int)(unsigned char)*bufptr );
00100 }
00101 
00102 inline int Message::get_c()        // Get character.
00103 {
00104 int    c;
00105 
00106        if (extra_headersptr)
00107        {
00108               c= (unsigned char) *extra_headersptr++;
00109               if (!*extra_headersptr)     extra_headersptr=0;
00110               return (c);
00111        }
00112 
00113        if (mio.fd() >= 0)
00114        {
00115               errno=0;
00116 
00117               c=mio.get();
00118               if (c < 0 && errno)  readerr();
00119               return (c);
00120        }
00121 
00122        if (bufptr >= buffer + msgsize)    return (-1);
00123        return ( (int)(unsigned char)*bufptr++ );
00124 }
00125 
00126 inline off_t Message::tell()
00127 {
00128 off_t  pos;
00129 
00130        if ( mio.fd() < 0)
00131               pos=bufptr - buffer;
00132        else
00133        {
00134               pos=mio.tell();
00135               if (pos == -1)       seekerr();
00136        }
00137        pos -= maildrop.msginfo.msgoffset;
00138        if (extra_headersptr)
00139               pos += extra_headersptr-extra_headers;
00140        else
00141        {
00142               if (extra_headers)   pos += strlen(extra_headers);
00143        }
00144        return (pos);
00145 }
00146 
00147 inline void Message::seek(off_t n)
00148 {
00149 int    l=0;
00150 
00151        if (extra_headers && n < (l=strlen(extra_headers)))
00152        {
00153               extra_headersptr= extra_headers + n;
00154               n=0;
00155        }
00156        else
00157        {
00158               extra_headersptr=0;
00159               n -= l;
00160        }
00161        n += maildrop.msginfo.msgoffset;
00162 
00163        if (mio.fd() >= 0)
00164        {
00165               if (mio.seek(n, SEEK_SET) < 0)     seekerr();
00166        }
00167        else
00168        {
00169               if (n > msgsize)     n=msgsize;
00170               bufptr=buffer+n;
00171        }
00172 }
00173 
00174 inline off_t Message::MessageSize()
00175 {
00176        off_t s=msgsize;
00177        s -= maildrop.msginfo.msgoffset;
00178        if (extra_headers)
00179               s += strlen(extra_headers);
00180 
00181        return (s);
00182 }
00183 
00184 #endif