summaryrefslogtreecommitdiff
path: root/src/include/maildirmessage.h
blob: 9e9c717a11c7412ba6e0b7aa4bd884cc47cdc160 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
/**  --------------------------------------------------------------------
 *  @file  maildirmessage.h
 *  @brief  Declaration of the MaildirMessage class.
 *  @author Andreas Aardal Hanssen
 *  @date 2002-2005
 *  -----------------------------------------------------------------  **/
#ifndef maildirmessage_h_included
#define maildirmessage_h_included
#include <string>
#include <map>
#include <vector>
#include <exception>
#include <iostream>
#include <time.h>

#include <stdio.h>
#include <string.h>

#include "message.h"
#include "address.h"
#include "mime.h"

namespace Binc {

  class Maildir;

  /*!
    \class MaildirMessage
    \brief The MaildirMessage class provides an interface for
    IMAP messages.

    Mailbox independent operations and properties are available
    through this interface.

    \sa Message
  */
  class MaildirMessage : public Message {
  public:
    /*!
      Sets the UID of a message.
      \param uid The UID that will be set.
    */
    void setUID(unsigned int uid);

    /*!
      Returns the UID of a message.
    */
    unsigned int getUID(void) const;

    /*!
      Sets the size of the message. This size must be consistent with
      the size reported when fetching the full message.

      \param size The size of the message in characters, after
      any conversion to CRLF.
    */
    void setSize(unsigned int size);

    /*!
      Returns the size of the message, optionally determining the size
      if it is not yet known.

      \param determine If render is true and the size is unknown, the
      size will be calculated and stored implicitly. Otherwise if the
      size is unknown, 0 is returned.
    */
    unsigned int getSize(bool determine = false) const;

    /*!
      Adds one or more flags to a message.

      \param flags This is a bitmask of flags from the Flags enum.
    */
    void setStdFlag(unsigned char flags);

    /*!
      Resets all flags on a message.
    */
    void resetStdFlags(void);

    /*!
      Returns the flags that are set on a message.
    */
    unsigned char getStdFlags(void) const;

    /*
    */
    void setCustomFlag(const std::string &flag);
    void removeCustomFlag(const std::string &flag);
    void resetCustomFlags(void);
    std::vector<std::string> getCustomFlags(void) const;

    /*!
      Sets the internal flags.

      \param flags a bitmask of the Flags enum.
     */
    void setInternalFlag(unsigned char flags);

    /*!
      Removes the internal flags.

      \param flags a bitmask of the Flags enum.
    */
    void clearInternalFlag(unsigned char flags);

    /*!
      Returns the internal flags.
    */
    unsigned char getInternalFlags(void) const;

    /*!
      Sets a state in a message that indicates that no flags have been
      changed. Used together with hasFlagsChanged() to check if the
      flags in this message have been changed.
    */
    void setFlagsUnchanged(void);

    /*!
      Returns true if flags have been added or reset since the last
      call to setFlagsUnchanged(), otherwise returns false.
    */
    bool hasFlagsChanged(void) const;

    /*!
      Sets the internal date of a message. This is usually the date in
      which the message arrived in the mailbox.

      \param internaldate The internal date of the message in seconds
      since the epoch.
    */
    void setInternalDate(time_t internaldate);

    /*!
      Returns the internal date of the message in seconds since the
      epoch.
    */
    time_t getInternalDate(void) const;

    /*!
      Reads a chunk of up to 4096 bytes from a message.  Call close()
      before readChunk() to read the first chunk from a message.

      readChunk() is used for copying or appending a message to a
      mailbox.

      \param chunk The characters are stored in this string.
    */
    int readChunk(std::string &chunk);

    /*!
      Appends a chunk of bytes to a message. appendChunk() is used for
      copying or appending a message to a mailbox.

      \param chunk The content of this string is appended to the
      message.
    */
    bool appendChunk(const std::string &chunk);

    /*!
      Resets a message and frees all allocated resources.
    */
    void close(void);

    /*!
      Marks the message as expunged. Equivalent to calling
      setStdFlag() with F_EXPUNGED.
    */
    void setExpunged(void);

    /*!
      Removes the F_EXPUNGED flag from the message.
    */
    void setUnExpunged(void);

    /*!
      Returns true if the message is marked as expunged, otherwise
      returns false.
    */
    bool isExpunged(void) const;

    /*!
      Returns the first occurrance of a MIME header in a message,
      counting from the top of the message and downwards, or "" if no
      such header is found.
      \param header The name of the header to be fetched.
    */
    const std::string &getHeader(const std::string &header);

    bool headerContains(const std::string &header,
                        const std::string &text);

    bool bodyContains(const std::string &text);
    bool textContains(const std::string &text);

    bool printBodyStructure(bool extended = true) const;

    bool printEnvelope(void) const;

    bool printHeader(const std::string &section,
                     std::vector<std::string> headers,
                     bool includeHeaders = false,
                     unsigned int startOffset = 0,
                     unsigned int length = UINTMAX,
                      bool mime = false) const;

    unsigned int getHeaderSize(const std::string &section,
                               std::vector<std::string> headers,
                               bool includeHeaders = false,
                               unsigned int startOffset = 0,
                               unsigned int length = UINTMAX,
                               bool mime = false) const;

    bool printBody(const std::string &section = "",
                   unsigned int startOffset = 0,
                   unsigned int length = UINTMAX) const;
                   unsigned int getBodySize(const std::string &section,
                   unsigned int startOffset = 0,
                   unsigned int length = UINTMAX) const;

    bool printDoc(unsigned int startOffset = 0,
                  unsigned int length = UINTMAX,
                  bool onlyText = false) const;

    unsigned int getDocSize(unsigned int startOffset = 0,
                            unsigned int length = UINTMAX,
                            bool onlyText = false) const;

    void setUnique(const std::string &s_in);
    const std::string &getUnique(void) const;

    //--
    MaildirMessage(Maildir &home);
    ~MaildirMessage(void);

    friend class Maildir;

    bool operator < (const MaildirMessage &a) const;

    MaildirMessage(const MaildirMessage &copy);
    MaildirMessage &operator = (const MaildirMessage &copy);

    enum Flags {
      None = 0x00,
      Expunged = 0x01,
      FlagsChanged = 0x02,
      JustArrived = 0x04,
      WasWrittenTo = 0x08,
      Committed = 0x10,
      CustomFlagsChanged = 0x20
    };

  protected:
    bool parseFull(void) const;
    bool parseHeaders(void) const;

    std::string getFixedFilename(void) const;
    std::string getFileName(void) const;

    void setFile(int fd);
    int getFile(void) const;

    void setSafeName(const std::string &name);
    const std::string &getSafeName(void) const;

  private:
    mutable int fd;
    mutable MimeDocument *doc;
    mutable unsigned char internalFlags;
    mutable unsigned char stdflags;
    mutable unsigned int uid;
    mutable unsigned int size;
    mutable std::string unique;
    mutable std::string safeName;
    time_t internaldate;

    Maildir &home;
    static std::string storage;
    std::vector<std::string> *customFlags;
  };

  //------------------------------------------------------------------------
  class MaildirMessageCache
  {
  public:
    ~MaildirMessageCache();

    enum ParseStatus {
      NotParsed,
      HeaderParsed,
      AllParsed
    };

    static MaildirMessageCache &getInstance(void);

    void removeStatus(const MaildirMessage *);
    void addStatus(const MaildirMessage *, ParseStatus pstat);
    ParseStatus getStatus(const MaildirMessage *) const;
    void clear(void);

  private:
    MaildirMessageCache();

    mutable std::map<const MaildirMessage *, ParseStatus> statuses;
    mutable std::deque<const MaildirMessage *> parsed;
  };
}

#endif