1 /* 2 * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client 3 * Copyright (C) 1999-2018 Hiroyuki Yamamoto and the Claws Mail team 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #ifndef __PROCMSG_H__ 20 #define __PROCMSG_H__ 21 22 #ifdef HAVE_CONFIG_H 23 #include "claws-features.h" 24 #endif 25 26 #include <glib.h> 27 #include <stdio.h> 28 #include <time.h> 29 #include <sys/types.h> 30 #include <string.h> 31 #include "common/utils.h" 32 #include "proctypes.h" 33 34 #define MSG_NEW (1U << 0) 35 #define MSG_UNREAD (1U << 1) 36 #define MSG_MARKED (1U << 2) 37 #define MSG_DELETED (1U << 3) 38 #define MSG_REPLIED (1U << 4) 39 #define MSG_FORWARDED (1U << 5) 40 41 #define MSG_CLABEL_SBIT (6) /* start bit of color label */ 42 /* color labels use 4 bits: 6, 7, 8, 9; bit weight is 7<8<9<6, 43 IOW the color label value itself must be computed from MsgPermFlags 44 bits like this: 45 value = bit-7-value*2^0 46 + bit-8-value*2^1 47 + bit-9-value*2^2 48 + bit-6-value*2^3 */ 49 50 /* color label permflags masks */ 51 #define MAKE_MSG_CLABEL(x, h, m, l) (\ 52 ((x) << (MSG_CLABEL_SBIT + 0)) | \ 53 ((h) << (MSG_CLABEL_SBIT + 3)) | \ 54 ((m) << (MSG_CLABEL_SBIT + 2)) | \ 55 ((l) << (MSG_CLABEL_SBIT + 1))) 56 #define MSG_CLABEL_NONE MAKE_MSG_CLABEL(0U, 0U, 0U, 0U) 57 #define MSG_CLABEL_1 MAKE_MSG_CLABEL(0U, 0U, 0U, 1U) 58 #define MSG_CLABEL_2 MAKE_MSG_CLABEL(0U, 0U, 1U, 0U) 59 #define MSG_CLABEL_3 MAKE_MSG_CLABEL(0U, 0U, 1U, 1U) 60 #define MSG_CLABEL_4 MAKE_MSG_CLABEL(0U, 1U, 0U, 0U) 61 #define MSG_CLABEL_5 MAKE_MSG_CLABEL(0U, 1U, 0U, 1U) 62 #define MSG_CLABEL_6 MAKE_MSG_CLABEL(0U, 1U, 1U, 0U) 63 #define MSG_CLABEL_7 MAKE_MSG_CLABEL(0U, 1U, 1U, 1U) 64 #define MSG_CLABEL_8 MAKE_MSG_CLABEL(1U, 0U, 0U, 0U) 65 #define MSG_CLABEL_9 MAKE_MSG_CLABEL(1U, 0U, 0U, 1U) 66 #define MSG_CLABEL_10 MAKE_MSG_CLABEL(1U, 0U, 1U, 0U) 67 #define MSG_CLABEL_11 MAKE_MSG_CLABEL(1U, 0U, 1U, 1U) 68 #define MSG_CLABEL_12 MAKE_MSG_CLABEL(1U, 1U, 0U, 0U) 69 #define MSG_CLABEL_13 MAKE_MSG_CLABEL(1U, 1U, 0U, 1U) 70 #define MSG_CLABEL_14 MAKE_MSG_CLABEL(1U, 1U, 1U, 0U) 71 #define MSG_CLABEL_15 MAKE_MSG_CLABEL(1U, 1U, 1U, 1U) 72 #define MSG_CLABEL_FLAG_MASK (MSG_CLABEL_15) 73 74 #define MSG_IGNORE_THREAD (1U << 10) /* ignore threads */ 75 #define MSG_LOCKED (1U << 11) /* msg is locked */ 76 #define MSG_RETRCPT_SENT (1U << 12) /* new one */ 77 #define MSG_SPAM (1U << 13) /* new one */ 78 #define MSG_POSTFILTERED (1U << 14) 79 #define MSG_WATCH_THREAD (1U << 15) /* watch threads */ 80 #define MSG_FULLY_CACHED (1U << 16) /* IMAP: fully cached */ 81 #define MSG_RETRCPT_GOT (1U << 17) /* got return receipt */ 82 83 /* RESERVED */ 84 #define MSG_RESERVED_CLAWS (1U << 30) /* for Claws Mail */ 85 #define MSG_RESERVED (1U << 31) 86 87 #define MSG_MOVE (1U << 0) 88 #define MSG_COPY (1U << 1) 89 #define MSG_MOVE_DONE (1U << 15) 90 #define MSG_QUEUED (1U << 16) 91 #define MSG_DRAFT (1U << 17) 92 #define MSG_ENCRYPTED (1U << 18) 93 #define MSG_IMAP (1U << 19) 94 #define MSG_NEWS (1U << 20) 95 #define MSG_SIGNED (1U << 21) 96 #define MSG_MULTIPART (1U << 29) 97 #define MSG_HAS_ATTACHMENT (1U << 30) 98 #define MSG_SCANNED (1U << 31) 99 100 #define MSG_CACHED_FLAG_MASK (MSG_MULTIPART | MSG_ENCRYPTED | MSG_SIGNED | MSG_HAS_ATTACHMENT | MSG_SCANNED) 101 102 #define MSG_SET_FLAGS(msg, flags) { (msg) |= (flags); } 103 #define MSG_UNSET_FLAGS(msg, flags) { (msg) &= ~(flags); } 104 #define MSG_SET_PERM_FLAGS(msg, flags) \ 105 MSG_SET_FLAGS((msg).perm_flags, flags) 106 #define MSG_SET_TMP_FLAGS(msg, flags) \ 107 MSG_SET_FLAGS((msg).tmp_flags, flags) 108 #define MSG_UNSET_PERM_FLAGS(msg, flags) \ 109 MSG_UNSET_FLAGS((msg).perm_flags, flags) 110 #define MSG_UNSET_TMP_FLAGS(msg, flags) \ 111 MSG_UNSET_FLAGS((msg).tmp_flags, flags) 112 113 #define MSG_IS_NEW(msg) (((msg).perm_flags & MSG_NEW) != 0) 114 #define MSG_IS_UNREAD(msg) (((msg).perm_flags & MSG_UNREAD) != 0) 115 #define MSG_IS_MARKED(msg) (((msg).perm_flags & MSG_MARKED) != 0) 116 #define MSG_IS_DELETED(msg) (((msg).perm_flags & MSG_DELETED) != 0) 117 #define MSG_IS_REPLIED(msg) (((msg).perm_flags & MSG_REPLIED) != 0) 118 #define MSG_IS_LOCKED(msg) (((msg).perm_flags & MSG_LOCKED) != 0) 119 #define MSG_IS_FORWARDED(msg) (((msg).perm_flags & MSG_FORWARDED) != 0) 120 #define MSG_IS_POSTFILTERED(msg) (((msg).perm_flags & MSG_POSTFILTERED) != 0) 121 122 /* color label decoding/encoding (permflag storage bits <-> color list index value)*/ 123 #define MSG_COLORLABEL_TO_FLAGS(val) (((((guint)(val)) & 7) << (MSG_CLABEL_SBIT+1)) \ 124 | (((guint)(val) & 8) << (MSG_CLABEL_SBIT-3))) 125 #define MSG_COLORLABEL_FROM_FLAGS(val) ((((guint)(val) >> (MSG_CLABEL_SBIT+1)) & 7 ) \ 126 | (((guint)(val) >> (MSG_CLABEL_SBIT-3)) & 8)) 127 #define MSG_GET_COLORLABEL(msg) (((msg).perm_flags & MSG_CLABEL_FLAG_MASK)) 128 #define MSG_GET_COLORLABEL_VALUE(msg) (MSG_COLORLABEL_FROM_FLAGS(MSG_GET_COLORLABEL(msg))) 129 #define MSG_SET_COLORLABEL_VALUE(msg, val) MSG_SET_PERM_FLAGS(msg, MSG_COLORLABEL_TO_FLAGS(val)) 130 131 #define MSG_IS_MOVE(msg) (((msg).tmp_flags & MSG_MOVE) != 0) 132 #define MSG_IS_COPY(msg) (((msg).tmp_flags & MSG_COPY) != 0) 133 #define MSG_IS_MOVE_DONE(msg) (((msg).tmp_flags & MSG_MOVE_DONE) != 0) 134 135 #define MSG_IS_QUEUED(msg) (((msg).tmp_flags & MSG_QUEUED) != 0) 136 #define MSG_IS_DRAFT(msg) (((msg).tmp_flags & MSG_DRAFT) != 0) 137 #define MSG_IS_ENCRYPTED(msg) (((msg).tmp_flags & MSG_ENCRYPTED) != 0) 138 #define MSG_IS_SIGNED(msg) (((msg).tmp_flags & MSG_SIGNED) != 0) 139 #define MSG_IS_IMAP(msg) (((msg).tmp_flags & MSG_IMAP) != 0) 140 #define MSG_IS_NEWS(msg) (((msg).tmp_flags & MSG_NEWS) != 0) 141 #define MSG_IS_MULTIPART(msg) (((msg).tmp_flags & MSG_MULTIPART) != 0) 142 #define MSG_IS_WITH_ATTACHMENT(msg) (((msg).tmp_flags & MSG_HAS_ATTACHMENT) != 0) 143 #define MSG_IS_SCANNED(msg) (((msg).tmp_flags & MSG_SCANNED) != 0) 144 145 /* Claws related flags */ 146 #define MSG_IS_IGNORE_THREAD(msg) (((msg).perm_flags & MSG_IGNORE_THREAD) != 0) 147 #define MSG_IS_RETRCPT_SENT(msg) (((msg).perm_flags & MSG_RETRCPT_SENT) != 0) 148 #define MSG_IS_RETRCPT_GOT(msg) (((msg).perm_flags & MSG_RETRCPT_GOT) != 0) 149 #define MSG_IS_SPAM(msg) (((msg).perm_flags & MSG_SPAM) != 0) 150 #define MSG_IS_WATCH_THREAD(msg) (((msg).perm_flags & MSG_WATCH_THREAD) != 0) 151 #define MSG_IS_FULLY_CACHED(msg) (((msg).perm_flags & MSG_FULLY_CACHED) != 0) 152 153 #define MSGINFO_UPDATE_HOOKLIST "msginfo_update" 154 #define MAIL_FILTERING_HOOKLIST "mail_filtering_hooklist" 155 #define MAIL_LISTFILTERING_HOOKLIST "mail_listfiltering_hooklist" 156 #define MAIL_POSTFILTERING_HOOKLIST "mail_postfiltering_hooklist" 157 158 typedef enum { 159 MSGINFO_UPDATE_FLAGS = 1 << 0, 160 MSGINFO_UPDATE_DELETED = 1 << 1 161 } MsgInfoUpdateFlags; 162 163 #include "prefs_account.h" 164 #include "prefs_filtering.h" 165 #include "folder.h" 166 167 struct _MsgFlags 168 { 169 MsgPermFlags perm_flags; 170 MsgTmpFlags tmp_flags; 171 }; 172 173 typedef enum { 174 IS_NOTHING = 0, 175 IS_MOVE, 176 IS_COPY, 177 IS_DELE 178 } FiltOp; 179 180 /* *********************************************************** * 181 * WARNING: When adding or removing members to this structure, * 182 * be sure to update procmsg.c::procmsg_msginfo_memusage() to * 183 * avoid underestimating cache memory usage - especially since * 184 * this would cause an overflow and metadata loss when writing * 185 * the cache to disk. * 186 * *********************************************************** */ 187 struct _MsgInfo 188 { 189 guint refcnt; 190 191 guint msgnum; 192 goffset size; 193 time_t mtime; 194 time_t date_t; 195 time_t thread_date; 196 197 MsgFlags flags; 198 199 gchar *fromname; 200 201 gchar *date; 202 gchar *from; 203 gchar *to; 204 gchar *cc; 205 gchar *newsgroups; 206 gchar *subject; 207 gchar *msgid; 208 gchar *inreplyto; 209 gchar *xref; 210 211 FolderItem *folder; 212 FolderItem *to_folder; 213 214 FolderItem *to_filter_folder; 215 FiltOp filter_op; 216 217 GSList *references; 218 gchar *fromspace; 219 220 gint score; 221 222 /* used only for encrypted messages */ 223 gchar *plaintext_file; 224 225 gint hidden; 226 227 /* used only for partially received messages */ 228 gint total_size; 229 gint planned_download; 230 231 /* list of tags ids */ 232 GSList *tags; 233 234 MsgInfoExtraData *extradata; 235 }; 236 237 struct _MsgInfoExtraData 238 { 239 GSList *avatars; 240 241 gchar *dispositionnotificationto; 242 gchar *returnreceiptto; 243 244 gchar *resent_from; 245 246 /* used only for partially received messages */ 247 gchar *partial_recv; 248 gchar *account_server; 249 gchar *account_login; 250 251 /* Mailing list support */ 252 gchar *list_post; 253 gchar *list_subscribe; 254 gchar *list_unsubscribe; 255 gchar *list_help; 256 gchar *list_archive; 257 gchar *list_owner; 258 }; 259 260 struct _MsgInfoAvatar 261 { 262 gint avatar_id; 263 gchar *avatar_src; 264 }; 265 266 struct _MsgFileInfo 267 { 268 MsgInfo *msginfo; 269 gchar *file; 270 MsgFlags *flags; 271 }; 272 273 struct _MsgInfoUpdate { 274 MsgInfo *msginfo; 275 MsgInfoUpdateFlags flags; 276 }; 277 278 struct _MailFilteringData 279 { 280 MsgInfo *msginfo; 281 GSList *msglist; 282 GSList *filtered; 283 GSList *unfiltered; 284 PrefsAccount *account; 285 }; 286 287 struct _AvatarCaptureData 288 { 289 MsgInfo *msginfo; 290 const gchar *header; 291 const gchar *content; 292 }; 293 294 GSList *procmsg_read_cache (FolderItem *item, 295 gboolean scan_file); 296 void procmsg_msg_list_free (MsgInfoList *mlist); 297 MsgNumberList *procmsg_get_number_list_for_msgs(MsgInfoList *msglist); 298 void procmsg_get_mark_sum (const gchar *folder, 299 gint *new_msgs, 300 gint *unread_msgs, 301 gint *total_msgs, 302 gint *min, 303 gint *max, 304 gint first); 305 306 GNode *procmsg_get_thread_tree (GSList *mlist); 307 308 gint procmsg_move_messages (GSList *mlist); 309 void procmsg_copy_messages (GSList *mlist); 310 311 /* return path is locale charset */ 312 gchar *procmsg_get_message_file_path (MsgInfo *msginfo); 313 gchar *procmsg_get_message_file (MsgInfo *msginfo); 314 gchar *procmsg_get_message_file_full (MsgInfo *msginfo, 315 gboolean get_headers, 316 gboolean get_body); 317 GSList *procmsg_get_message_file_list (MsgInfoList *mlist); 318 void procmsg_message_file_list_free (MsgInfoList *file_list); 319 FILE *procmsg_open_message (MsgInfo *msginfo, 320 gboolean skip_special_headers); 321 gboolean procmsg_msg_exist (MsgInfo *msginfo); 322 323 void procmsg_get_filter_keyword (MsgInfo *msginfo, 324 gchar **header, 325 gchar **key, 326 PrefsFilterType type); 327 328 void procmsg_empty_all_trash (void); 329 330 gint procmsg_send_queue (FolderItem *queue, 331 gboolean save_msgs, 332 gchar **errstr); 333 gboolean procmsg_queue_lock (gchar **errstr); 334 void procmsg_queue_unlock (void); 335 gboolean procmsg_queue_is_empty (FolderItem *queue); 336 337 MsgInfo *procmsg_msginfo_new (); 338 MsgInfo *procmsg_msginfo_new_ref (MsgInfo *msginfo); 339 MsgInfo *procmsg_msginfo_copy (MsgInfo *msginfo); 340 MsgInfo *procmsg_msginfo_get_full_info (MsgInfo *msginfo); 341 MsgInfo *procmsg_msginfo_get_full_info_from_file 342 (MsgInfo *msginfo, 343 const gchar *file); 344 void procmsg_msginfo_free (MsgInfo **msginfo); 345 guint procmsg_msginfo_memusage (MsgInfo *msginfo); 346 347 gint procmsg_send_message_queue_with_lock(const gchar *file, 348 gchar **errstr, 349 FolderItem *queue, 350 gint msgnum, 351 gboolean *queued_removed); 352 353 gint procmsg_send_message_queue (const gchar *file, 354 gchar **errstr, 355 FolderItem *queue, 356 gint msgnum, 357 gboolean *queued_removed); 358 359 void procmsg_msginfo_set_flags (MsgInfo *msginfo, 360 MsgPermFlags perm_flags, 361 MsgTmpFlags tmp_flags); 362 void procmsg_msginfo_unset_flags (MsgInfo *msginfo, 363 MsgPermFlags perm_flags, 364 MsgTmpFlags tmp_flags); 365 void procmsg_msginfo_change_flags (MsgInfo *msginfo, 366 MsgPermFlags add_perm_flags, 367 MsgTmpFlags add_tmp_flags, 368 MsgPermFlags rem_perm_flags, 369 MsgTmpFlags rem_tmp_flags); 370 gint procmsg_remove_special_headers (const gchar *in, 371 const gchar *out); 372 373 gint procmsg_save_to_outbox(FolderItem *outbox, const gchar *file, 374 gboolean is_queued); 375 gboolean procmsg_msg_has_flagged_parent (MsgInfo *info, 376 MsgPermFlags perm_flags); 377 gboolean procmsg_msg_has_marked_parent (MsgInfo *info); 378 void procmsg_msginfo_set_to_folder (MsgInfo *msginfo, 379 FolderItem *to_folder); 380 void procmsg_msglist_filter (GSList *list, 381 PrefsAccount *ac, 382 GSList **filtered, 383 GSList **unfiltered, 384 gboolean do_filter); 385 386 MsgInfo *procmsg_msginfo_new_from_mimeinfo 387 (MsgInfo *src_msginfo, 388 MimeInfo *mimeinfo); 389 390 void procmsg_register_spam_learner (int (*learn_func)(MsgInfo *info, GSList *list, gboolean spam)); 391 void procmsg_unregister_spam_learner (int (*learn_func)(MsgInfo *info, GSList *list, gboolean spam)); 392 gboolean procmsg_spam_can_learn (void); 393 void procmsg_spam_set_folder (const char *item_identifier, FolderItem *(*spam_get_folder_func)(MsgInfo *info)); 394 FolderItem *procmsg_spam_get_folder (MsgInfo *msginfo); 395 int procmsg_spam_learner_learn (MsgInfo *msginfo, GSList *msglist, gboolean spam); 396 gboolean procmsg_have_queued_mails_fast (void); 397 gboolean procmsg_have_trashed_mails_fast (void); 398 gboolean procmsg_is_sending(void); 399 gchar *procmsg_msginfo_get_tags_str(MsgInfo *msginfo); 400 void procmsg_msginfo_update_tags(MsgInfo *msginfo, gboolean set, gint id); 401 void procmsg_msginfo_clear_tags(MsgInfo *msginfo); 402 void procmsg_msginfo_commit_tags(GSList *msglist); 403 MsgInfo *procmsg_get_msginfo_from_identifier(const gchar *id); 404 gchar *procmsg_msginfo_get_identifier(MsgInfo *msginfo); 405 406 gchar *procmsg_msginfo_get_avatar(MsgInfo *msginfo, gint type); 407 void procmsg_msginfo_add_avatar(MsgInfo *msginfo, gint type, const gchar *data); 408 #endif /* __PROCMSG_H__ */ 409