File indexing completed on 2024-04-28 05:18:35
0001 /* 0002 SPDX-FileCopyrightText: 2009 Bertjan Broeksema <broeksema@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include "kmbox_export.h" 0010 #include "mboxentry.h" 0011 #include <memory> 0012 0013 #include <KMime/KMimeMessage> 0014 0015 namespace KMBox 0016 { 0017 class MBoxPrivate; 0018 0019 /** 0020 * @short A class to access mail storages in MBox format. 0021 * 0022 * @author Bertjan Broeksema <broeksema@kde.org> 0023 * @since 4.6 0024 */ 0025 class KMBOX_EXPORT MBox 0026 { 0027 public: 0028 /** 0029 * Describes the type of locking that will be used. 0030 */ 0031 enum LockType { ProcmailLockfile, MuttDotlock, MuttDotlockPrivileged, None }; 0032 0033 /** 0034 * Creates a new mbox object. 0035 */ 0036 MBox(); 0037 0038 /** 0039 * Destroys the mbox object. 0040 * 0041 * The file will be unlocked if it is still open. 0042 */ 0043 ~MBox(); 0044 0045 /** 0046 * Appends @p message to the MBox and returns the corresponding mbox entry for it. 0047 * You must load a mbox file by making a call to load( const QString& ) before 0048 * appending entries. 0049 * The returned mbox entry is <em>only</em> valid for that particular file. 0050 * 0051 * @param message The message to append to the mbox. 0052 * @return the corresponding mbox entry for the message in the file or an invalid mbox entry 0053 * if the message was not added. 0054 */ 0055 [[nodiscard]] MBoxEntry appendMessage(const KMime::Message::Ptr &message); 0056 0057 /** 0058 * Retrieve the mbox entry objects for all emails from the file except the 0059 * @p deleteEntries. 0060 * The @p deletedEntries should be a list of mbox entries with offsets of deleted messages. 0061 * @param deletedEntries list of mbox entries that have been deleted and need not be retrieved 0062 * Note: One <em>must</em> call load() before calling this method. 0063 */ 0064 [[nodiscard]] MBoxEntry::List entries(const MBoxEntry::List &deletedEntries = MBoxEntry::List()) const; 0065 0066 /** 0067 * Returns the file name that was passed to the last call to load(). 0068 */ 0069 [[nodiscard]] QString fileName() const; 0070 0071 /** 0072 * Loads the raw mbox data from disk into the current MBox object. Messages 0073 * already present are <em>not</em> preserved. This method does not load the 0074 * full messages into memory but only the offsets of the messages and their 0075 * sizes. If the file currently is locked this method will do nothing and 0076 * return false. Appended messages that are not written yet will get lost. 0077 * 0078 * @param fileName the name of the mbox on disk. 0079 * @return true, if successful, false on error. 0080 * 0081 * @see save( const QString & ) 0082 */ 0083 [[nodiscard]] bool load(const QString &fileName); 0084 0085 /** 0086 * Locks the mbox file using the configured lock method. This can be used 0087 * for consecutive calls to readMessage and readMessageHeaders. Calling lock() 0088 * before these calls prevents the mbox file being locked for every call. 0089 * 0090 * NOTE: Even when the lock method is None the mbox is internally marked as 0091 * locked. This means that it must be unlocked before calling load(). 0092 * 0093 * @return true if locked successful, false on error. 0094 * 0095 * @see setLockType( LockType ), unlock() 0096 */ 0097 [[nodiscard]] bool lock(); 0098 0099 /** 0100 * Returns whether or not the mbox currently is locked. 0101 */ 0102 [[nodiscard]] bool locked() const; 0103 0104 /** 0105 * Removes all messages for the given mbox entries from the current reference file 0106 * (the file that is loaded with load( const QString & ). 0107 * This method will first check if all lines at the offsets are actually 0108 * separator lines if this is not then no message will be deleted to prevent 0109 * corruption. 0110 * 0111 * @param deletedEntries The mbox entries of the messages that should be removed from 0112 * the file. 0113 * @param movedEntries Optional list for storing pairs of mbox entries that got moved 0114 * within the file due to the deletions. 0115 * The @c first member of the pair is the entry with the original offsets 0116 * the @c second member is the entry with the new (current) offset 0117 * 0118 * @return true if all offsets refer to a mbox separator line and a file was 0119 * loaded, false otherwise. If the latter, the physical file has 0120 * not changed. 0121 */ 0122 [[nodiscard]] bool purge(const MBoxEntry::List &deletedEntries, QList<MBoxEntry::Pair> *movedEntries = nullptr); 0123 0124 /** 0125 * Reads the entire message from the file for the given mbox @p entry. If the 0126 * mbox file is not locked this method will lock the file before reading and 0127 * unlock it after reading. If the file already is locked, it will not 0128 * unlock the file after reading the entry. 0129 * 0130 * @param entry The entry in the mbox file. 0131 * @return Message for the given entry or 0 if the file could not be locked 0132 * or the entry offset > fileSize. 0133 * 0134 * @see lock(), unlock() 0135 */ 0136 KMime::Message *readMessage(const MBoxEntry &entry); 0137 0138 /** 0139 * Reads the headers of the message for the given mbox @p entry. If the 0140 * mbox file is not locked this method will lock the file before reading and 0141 * unlock it after reading. If the file already is locked, it will not 0142 * unlock the file after reading the entry. 0143 * 0144 * @param entry The entry in the mbox file. 0145 * @return QByteArray containing the raw message header data. 0146 * 0147 * @see lock(), unlock() 0148 */ 0149 [[nodiscard]] QByteArray readMessageHeaders(const MBoxEntry &entry); 0150 0151 /** 0152 * Reads the entire message from the file for the given mbox @p entry. If the 0153 * mbox file is not locked this method will lock the file before reading and 0154 * unlock it after reading. If the file already is locked, it will not 0155 * unlock the file after reading the entry. 0156 * 0157 * @param entry The entry in the mbox file. 0158 * @return QByteArray containing the raw message data. 0159 * 0160 * @see lock(), unlock() 0161 */ 0162 [[nodiscard]] QByteArray readRawMessage(const MBoxEntry &entry); 0163 0164 /** 0165 * Writes the mbox to disk. If the fileName is empty only appended messages 0166 * will be written to the file that was passed to load( const QString & ). 0167 * Otherwise the contents of the file that was loaded with load is copied to 0168 * @p fileName first. 0169 * 0170 * @param fileName the name of the file 0171 * @return true if the save was successful; false otherwise. 0172 * 0173 * @see load( const QString & ) 0174 */ 0175 [[nodiscard]] bool save(const QString &fileName = QString()); 0176 0177 /** 0178 * Sets the locktype that should be used for locking the mbox file. If the 0179 * new LockType cannot be used (e.g. the lockfile executable could not be 0180 * found) the LockType will not be changed. 0181 * @param ltype the locktype to set 0182 * This method will not do anything if the mbox object is currently locked 0183 * to make sure that it doesn't leave a locked file for one of the lockfile 0184 * / mutt_dotlock methods. 0185 */ 0186 [[nodiscard]] bool setLockType(LockType ltype); 0187 0188 /** 0189 * Sets the lockfile that should be used by the procmail or the KDE lock 0190 * file method. If this method is not called and one of the before mentioned 0191 * lock methods is used the name of the lock file will be equal to 0192 * MBOXFILENAME.lock. 0193 * @param lockFile the lockfile to set 0194 */ 0195 void setLockFile(const QString &lockFile); 0196 0197 /** 0198 * By default the unlock method will directly unlock the file. However this 0199 * is expensive in case of many consecutive calls to readEntry. Setting the 0200 * time out to a non zero value will keep the lock open until the timeout has 0201 * passed. On each read the timer will be reset. 0202 * @param msec the time out to set for file lock 0203 */ 0204 void setUnlockTimeout(int msec); 0205 0206 /** 0207 * Unlock the mbox file. 0208 * 0209 * @return true if the unlock was successful, false otherwise. 0210 * 0211 * @see lock() 0212 */ 0213 [[nodiscard]] bool unlock(); 0214 /** 0215 * Set the access mode of the mbox file to read only. 0216 * 0217 * If this is set to true, the mbox file can only be read from disk. 0218 * When the mbox file given in load() can not be opened in readWrite mode, 0219 * but can be opened in readOnly mode, this flag is automatically set to true. 0220 * You can still append messages, which are stored in memory 0221 * until save() is called, but the mbox can not be saved/purged to itself. 0222 * However it is possible to save it to a different file. 0223 * @param ro the readOnly flag to use 0224 * 0225 * @see save( const QString & ) 0226 * 0227 * @since 4.14.5 0228 */ 0229 void setReadOnly(bool ro = true); 0230 0231 /** 0232 * Returns if the current access mode is set to readOnly. 0233 * 0234 * The access mode can either be set explicitly with setReadOnly() or 0235 * implicitly by calling load() on a readOnly file. 0236 * 0237 * @since 4.14.5 0238 */ 0239 [[nodiscard]] bool isReadOnly() const; 0240 0241 private: 0242 //@cond PRIVATE 0243 Q_DISABLE_COPY(MBox) 0244 std::unique_ptr<class MBoxPrivate> const d; 0245 //@endcond 0246 }; 0247 }