NeoMutt  2024-12-12-19-ge4b57e
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
compress.c
Go to the documentation of this file.
1
39#include "config.h"
40#include <errno.h>
41#include <stdbool.h>
42#include <stdio.h>
43#include <string.h>
44#include <sys/stat.h>
45#include <unistd.h>
46#include "mutt/lib.h"
47#include "config/lib.h"
48#include "core/lib.h"
49#include "gui/lib.h"
50#include "lib.h"
51#include "expando/lib.h"
52#include "expando.h"
53#include "globals.h"
54#include "hook.h"
55#include "mx.h"
56#include "protos.h"
57
58struct Email;
59
63static const struct Command CompCommands[] = {
64 // clang-format off
65 { "append-hook", mutt_parse_hook, MUTT_APPEND_HOOK },
66 { "close-hook", mutt_parse_hook, MUTT_CLOSE_HOOK },
67 { "open-hook", mutt_parse_hook, MUTT_OPEN_HOOK },
68 // clang-format on
69};
70
80 // clang-format off
81 { "f", "from", ED_COMPRESS, ED_CMP_FROM, NULL },
82 { "t", "to", ED_COMPRESS, ED_CMP_TO, NULL },
83 { NULL, NULL, 0, -1, NULL }
84 // clang-format on
85};
86
91{
93}
94
106static bool lock_realpath(struct Mailbox *m, bool excl)
107{
108 if (!m || !m->compress_info)
109 return false;
110
111 struct CompressInfo *ci = m->compress_info;
112
113 if (ci->locked)
114 return true;
115
116 if (excl)
117 ci->fp_lock = mutt_file_fopen(m->realpath, "a");
118 else
119 ci->fp_lock = mutt_file_fopen(m->realpath, "r");
120 if (!ci->fp_lock)
121 {
122 mutt_perror("%s", m->realpath);
123 return false;
124 }
125
126 int r = mutt_file_lock(fileno(ci->fp_lock), excl, true);
127 if (r == 0)
128 {
129 ci->locked = true;
130 }
131 else if (excl)
132 {
134 m->readonly = true;
135 return true;
136 }
137
138 return r == 0;
139}
140
147static void unlock_realpath(struct Mailbox *m)
148{
149 if (!m || !m->compress_info)
150 return;
151
152 struct CompressInfo *ci = m->compress_info;
153
154 if (!ci->locked)
155 return;
156
157 mutt_file_unlock(fileno(ci->fp_lock));
158
159 ci->locked = false;
161}
162
173static int setup_paths(struct Mailbox *m)
174{
175 if (!m)
176 return -1;
177
178 /* Setup the right paths */
180
181 /* We will uncompress to TMPDIR */
182 struct Buffer *buf = buf_pool_get();
183 buf_mktemp(buf);
184 buf_copy(&m->pathbuf, buf);
185 buf_pool_release(&buf);
186
187 FILE *fp = mutt_file_fopen(mailbox_path(m), "w");
188 if (!fp)
189 return -1;
190
191 mutt_file_fclose(&fp);
192 return 0;
193}
194
201static void store_size(const struct Mailbox *m)
202{
203 if (!m || !m->compress_info)
204 return;
205
206 struct CompressInfo *ci = m->compress_info;
207
209}
210
216static struct Expando *validate_compress_expando(const char *s)
217{
218 struct Buffer *err = buf_pool_get();
219
220 struct Expando *exp = expando_parse(s, CompressFormatDef, err);
221 if (!exp)
222 {
223 mutt_error(_("Expando parse error: %s"), buf_string(err));
224 }
225
226 buf_pool_release(&err);
227 return exp;
228}
229
238static struct CompressInfo *set_compress_info(struct Mailbox *m)
239{
240 if (!m)
241 return NULL;
242
243 if (m->compress_info)
244 return m->compress_info;
245
246 /* Open is compulsory */
247 const char *o = mutt_find_hook(MUTT_OPEN_HOOK, mailbox_path(m));
248 if (!o)
249 return NULL;
250
251 const char *c = mutt_find_hook(MUTT_CLOSE_HOOK, mailbox_path(m));
252 const char *a = mutt_find_hook(MUTT_APPEND_HOOK, mailbox_path(m));
253
254 struct CompressInfo *ci = MUTT_MEM_CALLOC(1, struct CompressInfo);
255 m->compress_info = ci;
256
260
261 return ci;
262}
263
268static void compress_info_free(struct Mailbox *m)
269{
270 if (!m || !m->compress_info)
271 return;
272
273 struct CompressInfo *ci = m->compress_info;
277
279
280 FREE(&m->compress_info);
281}
282
294static bool execute_command(struct Mailbox *m, const struct Expando *exp, const char *progress)
295{
296 if (!m || !exp || !progress)
297 return false;
298
299 if (m->verbose)
300 mutt_message(progress, m->realpath);
301
302 bool rc = true;
303 struct Buffer *sys_cmd = buf_pool_get();
304 buf_alloc(sys_cmd, STR_COMMAND);
305
307 mutt_endwin();
308 fflush(stdout);
309
311 sys_cmd->dsize, sys_cmd);
312
313 if (mutt_system(buf_string(sys_cmd)) != 0)
314 {
315 rc = false;
317 mutt_error(_("Error running \"%s\""), buf_string(sys_cmd));
318 }
319
321
322 buf_pool_release(&sys_cmd);
323 return rc;
324}
325
338{
339 if (!m)
340 return false;
341
342 /* If this succeeds, we know there's an open-hook */
343 struct CompressInfo *ci = set_compress_info(m);
344 if (!ci)
345 return false;
346
347 /* We have an open-hook, so to append we need an append-hook,
348 * or a close-hook. */
349 if (ci->cmd_append || ci->cmd_close)
350 return true;
351
352 mutt_error(_("Can't append without an append-hook or close-hook : %s"), mailbox_path(m));
353 return false;
354}
355
366bool mutt_comp_can_read(const char *path)
367{
368 if (!path)
369 return false;
370
372 return true;
373
374 return false;
375}
376
386int mutt_comp_valid_command(const char *cmd)
387{
388 if (!cmd)
389 return 0;
390
391 return strstr(cmd, "%f") && strstr(cmd, "%t");
392}
393
397static bool comp_ac_owns_path(struct Account *a, const char *path)
398{
399 return false;
400}
401
405static bool comp_ac_add(struct Account *a, struct Mailbox *m)
406{
407 return true;
408}
409
419{
420 struct CompressInfo *ci = set_compress_info(m);
421 if (!ci)
422 return MX_OPEN_ERROR;
423
424 /* If there's no close-hook, or the file isn't writable */
425 if (!ci->cmd_close || (access(mailbox_path(m), W_OK) != 0))
426 m->readonly = true;
427
428 if (setup_paths(m) != 0)
429 goto cmo_fail;
430 store_size(m);
431
432 if (!lock_realpath(m, false))
433 {
434 mutt_error(_("Unable to lock mailbox"));
435 goto cmo_fail;
436 }
437
438 if (!execute_command(m, ci->cmd_open, _("Decompressing %s")))
439 goto cmo_fail;
440
442
444 if (m->type == MUTT_UNKNOWN)
445 {
446 mutt_error(_("Can't identify the contents of the compressed file"));
447 goto cmo_fail;
448 }
449
450 ci->child_ops = mx_get_ops(m->type);
451 if (!ci->child_ops)
452 {
453 mutt_error(_("Can't find mailbox ops for mailbox type %d"), m->type);
454 goto cmo_fail;
455 }
456
457 m->account->type = m->type;
458 return ci->child_ops->mbox_open(m);
459
460cmo_fail:
461 /* remove the partial uncompressed file */
462 (void) remove(mailbox_path(m));
464 return MX_OPEN_ERROR;
465}
466
475static bool comp_mbox_open_append(struct Mailbox *m, OpenMailboxFlags flags)
476{
477 /* If this succeeds, we know there's an open-hook */
478 struct CompressInfo *ci = set_compress_info(m);
479 if (!ci)
480 return false;
481
482 /* To append we need an append-hook or a close-hook */
483 if (!ci->cmd_append && !ci->cmd_close)
484 {
485 mutt_error(_("Can't append without an append-hook or close-hook : %s"),
486 mailbox_path(m));
487 goto cmoa_fail1;
488 }
489
490 if (setup_paths(m) != 0)
491 goto cmoa_fail2;
492
493 /* Lock the realpath for the duration of the append.
494 * It will be unlocked in the close */
495 if (!lock_realpath(m, true))
496 {
497 mutt_error(_("Unable to lock mailbox"));
498 goto cmoa_fail2;
499 }
500
501 /* Open the existing mailbox, unless we are appending */
502 if (!ci->cmd_append && (mutt_file_get_size(m->realpath) > 0))
503 {
504 if (!execute_command(m, ci->cmd_open, _("Decompressing %s")))
505 {
506 mutt_error(_("Compress command failed: %s"), ci->cmd_open->string);
507 goto cmoa_fail2;
508 }
510 }
511 else
512 {
513 m->type = cs_subset_enum(NeoMutt->sub, "mbox_type");
514 }
515
516 /* We can only deal with mbox and mmdf mailboxes */
517 if ((m->type != MUTT_MBOX) && (m->type != MUTT_MMDF))
518 {
519 mutt_error(_("Unsupported mailbox type for appending"));
520 goto cmoa_fail2;
521 }
522
523 ci->child_ops = mx_get_ops(m->type);
524 if (!ci->child_ops)
525 {
526 mutt_error(_("Can't find mailbox ops for mailbox type %d"), m->type);
527 goto cmoa_fail2;
528 }
529
530 if (!ci->child_ops->mbox_open_append(m, flags))
531 goto cmoa_fail2;
532
533 return true;
534
535cmoa_fail2:
536 /* remove the partial uncompressed file */
537 (void) remove(mailbox_path(m));
538cmoa_fail1:
539 /* Free the compress_info to prevent close from trying to recompress */
541
542 return false;
543}
544
555static enum MxStatus comp_mbox_check(struct Mailbox *m)
556{
557 if (!m->compress_info)
558 return MX_STATUS_ERROR;
559
560 struct CompressInfo *ci = m->compress_info;
561
562 const struct MxOps *ops = ci->child_ops;
563 if (!ops)
564 return MX_STATUS_ERROR;
565
566 int size = mutt_file_get_size(m->realpath);
567 if (size == ci->size)
568 return MX_STATUS_OK;
569
570 if (!lock_realpath(m, false))
571 {
572 mutt_error(_("Unable to lock mailbox"));
573 return MX_STATUS_ERROR;
574 }
575
576 bool rc = execute_command(m, ci->cmd_open, _("Decompressing %s"));
577 store_size(m);
579 if (!rc)
580 return MX_STATUS_ERROR;
581
582 return ops->mbox_check(m);
583}
584
591static enum MxStatus comp_mbox_sync(struct Mailbox *m)
592{
593 if (!m->compress_info)
594 return MX_STATUS_ERROR;
595
596 struct CompressInfo *ci = m->compress_info;
597
598 if (!ci->cmd_close)
599 {
600 mutt_error(_("Can't sync a compressed file without a close-hook"));
601 return MX_STATUS_ERROR;
602 }
603
604 const struct MxOps *ops = ci->child_ops;
605 if (!ops)
606 return MX_STATUS_ERROR;
607
608 if (!lock_realpath(m, true))
609 {
610 mutt_error(_("Unable to lock mailbox"));
611 return MX_STATUS_ERROR;
612 }
613
614 enum MxStatus check = comp_mbox_check(m);
615 if (check != MX_STATUS_OK)
616 goto sync_cleanup;
617
618 check = ops->mbox_sync(m);
619 if (check != MX_STATUS_OK)
620 goto sync_cleanup;
621
622 if (!execute_command(m, ci->cmd_close, _("Compressing %s")))
623 {
624 check = MX_STATUS_ERROR;
625 goto sync_cleanup;
626 }
627
628 check = MX_STATUS_OK;
629
630sync_cleanup:
631 store_size(m);
633 return check;
634}
635
642static enum MxStatus comp_mbox_close(struct Mailbox *m)
643{
644 if (!m->compress_info)
645 return MX_STATUS_ERROR;
646
647 struct CompressInfo *ci = m->compress_info;
648
649 const struct MxOps *ops = ci->child_ops;
650 if (!ops)
651 {
653 return MX_STATUS_ERROR;
654 }
655
656 ops->mbox_close(m);
657
658 /* sync has already been called, so we only need to delete some files */
659 if (m->append)
660 {
661 const struct Expando *append = NULL;
662 const char *msg = NULL;
663
664 /* The file exists and we can append */
665 if ((access(m->realpath, F_OK) == 0) && ci->cmd_append)
666 {
667 append = ci->cmd_append;
668 msg = _("Compressed-appending to %s...");
669 }
670 else
671 {
672 append = ci->cmd_close;
673 msg = _("Compressing %s");
674 }
675
676 if (!execute_command(m, append, msg))
677 {
679 mutt_error(_("Error. Preserving temporary file: %s"), mailbox_path(m));
680 }
681 else
682 {
683 if (remove(mailbox_path(m)) < 0)
684 {
685 mutt_debug(LL_DEBUG1, "remove failed: %s: %s (errno %d)\n",
686 mailbox_path(m), strerror(errno), errno);
687 }
688 }
689
691 }
692 else
693 {
694 /* If the file was removed, remove the compressed folder too */
695 if (access(mailbox_path(m), F_OK) != 0)
696 {
697 const bool c_save_empty = cs_subset_bool(NeoMutt->sub, "save_empty");
698 if (!c_save_empty)
699 {
700 if (remove(m->realpath) < 0)
701 {
702 mutt_debug(LL_DEBUG1, "remove failed: %s: %s (errno %d)\n",
703 m->realpath, strerror(errno), errno);
704 }
705 }
706 }
707 else
708 {
709 if (remove(mailbox_path(m)) < 0)
710 {
711 mutt_debug(LL_DEBUG1, "remove failed: %s: %s (errno %d)\n",
712 mailbox_path(m), strerror(errno), errno);
713 }
714 }
715 }
716
718
719 return MX_STATUS_OK;
720}
721
725static bool comp_msg_open(struct Mailbox *m, struct Message *msg, struct Email *e)
726{
727 if (!m->compress_info)
728 return false;
729
730 struct CompressInfo *ci = m->compress_info;
731
732 const struct MxOps *ops = ci->child_ops;
733 if (!ops)
734 return false;
735
736 /* Delegate */
737 return ops->msg_open(m, msg, e);
738}
739
743static bool comp_msg_open_new(struct Mailbox *m, struct Message *msg, const struct Email *e)
744{
745 if (!m->compress_info)
746 return false;
747
748 struct CompressInfo *ci = m->compress_info;
749
750 const struct MxOps *ops = ci->child_ops;
751 if (!ops)
752 return false;
753
754 /* Delegate */
755 return ops->msg_open_new(m, msg, e);
756}
757
761static int comp_msg_commit(struct Mailbox *m, struct Message *msg)
762{
763 if (!m->compress_info)
764 return -1;
765
766 struct CompressInfo *ci = m->compress_info;
767
768 const struct MxOps *ops = ci->child_ops;
769 if (!ops)
770 return -1;
771
772 /* Delegate */
773 return ops->msg_commit(m, msg);
774}
775
779static int comp_msg_close(struct Mailbox *m, struct Message *msg)
780{
781 if (!m->compress_info)
782 return -1;
783
784 struct CompressInfo *ci = m->compress_info;
785
786 const struct MxOps *ops = ci->child_ops;
787 if (!ops)
788 return -1;
789
790 /* Delegate */
791 return ops->msg_close(m, msg);
792}
793
797static int comp_msg_padding_size(struct Mailbox *m)
798{
799 if (!m->compress_info)
800 return 0;
801
802 struct CompressInfo *ci = m->compress_info;
803
804 const struct MxOps *ops = ci->child_ops;
805 if (!ops || !ops->msg_padding_size)
806 return 0;
807
808 return ops->msg_padding_size(m);
809}
810
814static int comp_msg_save_hcache(struct Mailbox *m, struct Email *e)
815{
816 if (!m->compress_info)
817 return 0;
818
819 struct CompressInfo *ci = m->compress_info;
820
821 const struct MxOps *ops = ci->child_ops;
822 if (!ops || !ops->msg_save_hcache)
823 return 0;
824
825 return ops->msg_save_hcache(m, e);
826}
827
831static int comp_tags_edit(struct Mailbox *m, const char *tags, struct Buffer *buf)
832{
833 if (!m->compress_info)
834 return 0;
835
836 struct CompressInfo *ci = m->compress_info;
837
838 const struct MxOps *ops = ci->child_ops;
839 if (!ops || !ops->tags_edit)
840 return 0;
841
842 return ops->tags_edit(m, tags, buf);
843}
844
848static int comp_tags_commit(struct Mailbox *m, struct Email *e, const char *buf)
849{
850 if (!m->compress_info)
851 return 0;
852
853 struct CompressInfo *ci = m->compress_info;
854
855 const struct MxOps *ops = ci->child_ops;
856 if (!ops || !ops->tags_commit)
857 return 0;
858
859 return ops->tags_commit(m, e, buf);
860}
861
865static enum MailboxType comp_path_probe(const char *path, const struct stat *st)
866{
867 if (!st || !S_ISREG(st->st_mode))
868 return MUTT_UNKNOWN;
869
870 if (mutt_comp_can_read(path))
871 return MUTT_COMPRESSED;
872
873 return MUTT_UNKNOWN;
874}
875
879static int comp_path_canon(struct Buffer *path)
880{
881 mutt_path_canon(path, HomeDir, false);
882 return 0;
883}
884
891const struct MxOps MxCompOps = {
892 // clang-format off
894 .name = "compressed",
895 .is_local = true,
896 .ac_owns_path = comp_ac_owns_path,
897 .ac_add = comp_ac_add,
898 .mbox_open = comp_mbox_open,
899 .mbox_open_append = comp_mbox_open_append,
900 .mbox_check = comp_mbox_check,
901 .mbox_check_stats = NULL,
902 .mbox_sync = comp_mbox_sync,
903 .mbox_close = comp_mbox_close,
904 .msg_open = comp_msg_open,
905 .msg_open_new = comp_msg_open_new,
906 .msg_commit = comp_msg_commit,
907 .msg_close = comp_msg_close,
908 .msg_padding_size = comp_msg_padding_size,
909 .msg_save_hcache = comp_msg_save_hcache,
910 .tags_edit = comp_tags_edit,
911 .tags_commit = comp_tags_commit,
912 .path_probe = comp_path_probe,
913 .path_canon = comp_path_canon,
914 .path_is_empty = NULL,
915 // clang-format on
916};
size_t buf_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition: buffer.c:601
void buf_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:337
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:96
static struct CompressInfo * set_compress_info(struct Mailbox *m)
Find the compress hooks for a mailbox.
Definition: compress.c:238
static void compress_info_free(struct Mailbox *m)
Frees the compress info members and structure.
Definition: compress.c:268
static int setup_paths(struct Mailbox *m)
Set the mailbox paths.
Definition: compress.c:173
const struct ExpandoDefinition CompressFormatDef[]
Expando definitions.
Definition: compress.c:79
void mutt_comp_init(void)
Setup feature commands.
Definition: compress.c:90
static void store_size(const struct Mailbox *m)
Save the size of the compressed file.
Definition: compress.c:201
static bool lock_realpath(struct Mailbox *m, bool excl)
Try to lock the Mailbox.realpath.
Definition: compress.c:106
bool mutt_comp_can_append(struct Mailbox *m)
Can we append to this path?
Definition: compress.c:337
static void unlock_realpath(struct Mailbox *m)
Unlock the mailbox->realpath.
Definition: compress.c:147
static const struct Command CompCommands[]
Compression Commands.
Definition: compress.c:63
int mutt_comp_valid_command(const char *cmd)
Is this command string allowed?
Definition: compress.c:386
static bool execute_command(struct Mailbox *m, const struct Expando *exp, const char *progress)
Run a system command.
Definition: compress.c:294
static struct Expando * validate_compress_expando(const char *s)
Validate the Compress hooks.
Definition: compress.c:216
bool mutt_comp_can_read(const char *path)
Can we read from this file?
Definition: compress.c:366
const struct ExpandoRenderCallback CompressRenderCallbacks[]
Callbacks for Compression Hook Expandos.
Definition: expando.c:70
@ ED_CMP_FROM
'from' path
Definition: lib.h:50
@ ED_CMP_TO
'to' path
Definition: lib.h:51
unsigned char cs_subset_enum(const struct ConfigSubset *sub, const char *name)
Get a enumeration config item by name.
Definition: helpers.c:71
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:47
Convenience wrapper for the config headers.
char * HomeDir
User's home directory.
Definition: globals.c:37
void commands_register(const struct Command *cmds, const size_t num_cmds)
Add commands to Commands array.
Definition: command.c:53
Convenience wrapper for the core headers.
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition: mailbox.h:223
MailboxType
Supported mailbox formats.
Definition: mailbox.h:41
@ MUTT_MMDF
'mmdf' Mailbox type
Definition: mailbox.h:46
@ MUTT_MBOX
'mbox' Mailbox type
Definition: mailbox.h:45
@ MUTT_COMPRESSED
Compressed file Mailbox type.
Definition: mailbox.h:53
@ MUTT_UNKNOWN
Mailbox wasn't recognised.
Definition: mailbox.h:44
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition: curs_lib.c:173
void mutt_endwin(void)
Shutdown curses.
Definition: curs_lib.c:151
@ ED_COMPRESS
Compress ED_CMP_ ExpandoDataCompress.
Definition: domain.h:40
struct Expando * expando_parse(const char *str, const struct ExpandoDefinition *defs, struct Buffer *err)
Parse an Expando string.
Definition: expando.c:81
void expando_free(struct Expando **ptr)
Free an Expando object.
Definition: expando.c:61
int expando_render(const struct Expando *exp, const struct ExpandoRenderCallback *erc, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf)
Render an Expando + data into a string.
Definition: expando.c:118
Parse Expando string.
int mutt_file_lock(int fd, bool excl, bool timeout)
(Try to) Lock a file using fcntl()
Definition: file.c:1202
int mutt_file_unlock(int fd)
Unlock a file previously locked by mutt_file_lock()
Definition: file.c:1249
long mutt_file_get_size(const char *path)
Get the size of a file.
Definition: file.c:1519
#define mutt_file_fclose(FP)
Definition: file.h:138
#define mutt_file_fopen(PATH, MODE)
Definition: file.h:137
enum CommandResult mutt_parse_hook(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'hook' family of commands - Implements Command::parse() -.
Definition: hook.c:166
#define mutt_error(...)
Definition: logging2.h:92
#define mutt_message(...)
Definition: logging2.h:91
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
#define mutt_perror(...)
Definition: logging2.h:93
static bool comp_ac_add(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account - Implements MxOps::ac_add() -.
Definition: compress.c:405
static bool comp_ac_owns_path(struct Account *a, const char *path)
Check whether an Account owns a Mailbox path - Implements MxOps::ac_owns_path() -.
Definition: compress.c:397
const struct MxOps MxCompOps
Compressed Mailbox - Implements MxOps -.
Definition: compress.c:891
static enum MxStatus comp_mbox_check(struct Mailbox *m)
Check for new mail - Implements MxOps::mbox_check() -.
Definition: compress.c:555
static enum MxStatus comp_mbox_close(struct Mailbox *m)
Close a Mailbox - Implements MxOps::mbox_close() -.
Definition: compress.c:642
static bool comp_mbox_open_append(struct Mailbox *m, OpenMailboxFlags flags)
Open a Mailbox for appending - Implements MxOps::mbox_open_append() -.
Definition: compress.c:475
static enum MxOpenReturns comp_mbox_open(struct Mailbox *m)
Open a Mailbox - Implements MxOps::mbox_open() -.
Definition: compress.c:418
static enum MxStatus comp_mbox_sync(struct Mailbox *m)
Save changes to the Mailbox - Implements MxOps::mbox_sync() -.
Definition: compress.c:591
static int comp_msg_close(struct Mailbox *m, struct Message *msg)
Close an email - Implements MxOps::msg_close() -.
Definition: compress.c:779
static int comp_msg_commit(struct Mailbox *m, struct Message *msg)
Save changes to an email - Implements MxOps::msg_commit() -.
Definition: compress.c:761
static bool comp_msg_open_new(struct Mailbox *m, struct Message *msg, const struct Email *e)
Open a new message in a Mailbox - Implements MxOps::msg_open_new() -.
Definition: compress.c:743
static bool comp_msg_open(struct Mailbox *m, struct Message *msg, struct Email *e)
Open an email message in a Mailbox - Implements MxOps::msg_open() -.
Definition: compress.c:725
static int comp_msg_padding_size(struct Mailbox *m)
Bytes of padding between messages - Implements MxOps::msg_padding_size() -.
Definition: compress.c:797
static int comp_msg_save_hcache(struct Mailbox *m, struct Email *e)
Save message to the header cache - Implements MxOps::msg_save_hcache() -.
Definition: compress.c:814
static int comp_path_canon(struct Buffer *path)
Canonicalise a Mailbox path - Implements MxOps::path_canon() -.
Definition: compress.c:879
static enum MailboxType comp_path_probe(const char *path, const struct stat *st)
Is this a compressed Mailbox? - Implements MxOps::path_probe() -.
Definition: compress.c:865
static int comp_tags_commit(struct Mailbox *m, struct Email *e, const char *buf)
Save the tags to a message - Implements MxOps::tags_commit() -.
Definition: compress.c:848
static int comp_tags_edit(struct Mailbox *m, const char *tags, struct Buffer *buf)
Prompt and validate new messages tags - Implements MxOps::tags_edit() -.
Definition: compress.c:831
Convenience wrapper for the gui headers.
char * mutt_find_hook(HookFlags type, const char *pat)
Find a matching hook.
Definition: hook.c:678
Parse and execute user-defined hooks.
#define MUTT_OPEN_HOOK
open-hook: to read a compressed mailbox
Definition: hook.h:49
#define MUTT_CLOSE_HOOK
close-hook: write to a compressed mailbox
Definition: hook.h:51
#define MUTT_APPEND_HOOK
append-hook: append to a compressed mailbox
Definition: hook.h:50
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
#define FREE(x)
Definition: memory.h:55
#define MUTT_MEM_CALLOC(n, type)
Definition: memory.h:40
#define mutt_array_size(x)
Definition: memory.h:38
Convenience wrapper for the library headers.
#define _(a)
Definition: message.h:28
bool mutt_path_canon(struct Buffer *path, const char *homedir, bool is_dir)
Create the canonical version of a path.
Definition: path.c:248
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:280
const struct MxOps * mx_get_ops(enum MailboxType type)
Get mailbox operations.
Definition: mx.c:127
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1321
API for mailboxes.
uint8_t OpenMailboxFlags
Flags for mutt_open_mailbox(), e.g. MUTT_NOSORT.
Definition: mxapi.h:39
MxOpenReturns
Return values for mbox_open()
Definition: mxapi.h:76
@ MX_OPEN_ERROR
Open failed with an error.
Definition: mxapi.h:78
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_sync(), and mbox_close()
Definition: mxapi.h:63
@ MX_STATUS_ERROR
An error occurred.
Definition: mxapi.h:64
@ MX_STATUS_OK
No changes.
Definition: mxapi.h:65
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:82
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:96
Prototypes for many functions.
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:52
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: render.h:33
Sidebar Expando definitions.
void mutt_sig_block(void)
Block signals during critical operations.
Definition: signal.c:212
void mutt_sig_unblock(void)
Restore previously blocked signals.
Definition: signal.c:230
Key value store.
#define STR_COMMAND
Enough space for a long command line.
Definition: string2.h:35
A group of associated Mailboxes.
Definition: account.h:36
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:37
String manipulation buffer.
Definition: buffer.h:36
size_t dsize
Length of data.
Definition: buffer.h:39
Private data for compress.
Definition: lib.h:60
struct Expando * cmd_open
open-hook command
Definition: lib.h:63
FILE * fp_lock
fp used for locking
Definition: lib.h:67
struct Expando * cmd_append
append-hook command
Definition: lib.h:61
const struct MxOps * child_ops
callbacks of de-compressed file
Definition: lib.h:65
bool locked
if realpath is locked
Definition: lib.h:66
long size
size of the compressed file
Definition: lib.h:64
struct Expando * cmd_close
close-hook command
Definition: lib.h:62
The envelope/body of an email.
Definition: email.h:39
Definition of a format string.
Definition: definition.h:44
Parsed Expando trees.
Definition: expando.h:41
const char * string
Pointer to the parsed string.
Definition: expando.h:42
A mailbox.
Definition: mailbox.h:79
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:81
bool append
Mailbox is opened in append mode.
Definition: mailbox.h:109
enum MailboxType type
Mailbox type.
Definition: mailbox.h:102
struct Buffer pathbuf
Path of the Mailbox.
Definition: mailbox.h:80
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:127
void * compress_info
Compressed mbox module private data.
Definition: mailbox.h:121
bool readonly
Don't allow changes to the mailbox.
Definition: mailbox.h:116
bool verbose
Display status messages?
Definition: mailbox.h:117
A local copy of an email.
Definition: message.h:34
Definition: mxapi.h:91
bool(* msg_open)(struct Mailbox *m, struct Message *msg, struct Email *e)
Definition: mxapi.h:216
int(* tags_commit)(struct Mailbox *m, struct Email *e, const char *buf)
Definition: mxapi.h:323
int(* msg_save_hcache)(struct Mailbox *m, struct Email *e)
Definition: mxapi.h:289
enum MailboxType type
Mailbox type, e.g. MUTT_IMAP.
Definition: mxapi.h:92
int(* msg_padding_size)(struct Mailbox *m)
Definition: mxapi.h:274
int(* tags_edit)(struct Mailbox *m, const char *tags, struct Buffer *buf)
Definition: mxapi.h:306
int(* msg_commit)(struct Mailbox *m, struct Message *msg)
Definition: mxapi.h:247
enum MxOpenReturns(* mbox_open)(struct Mailbox *m)
Definition: mxapi.h:136
int(* msg_close)(struct Mailbox *m, struct Message *msg)
Definition: mxapi.h:262
bool(* msg_open_new)(struct Mailbox *m, struct Message *msg, const struct Email *e)
Definition: mxapi.h:232
enum MxStatus(* mbox_close)(struct Mailbox *m)
Definition: mxapi.h:199
enum MxStatus(* mbox_sync)(struct Mailbox *m)
Definition: mxapi.h:187
bool(* mbox_open_append)(struct Mailbox *m, OpenMailboxFlags flags)
Definition: mxapi.h:150
enum MxStatus(* mbox_check)(struct Mailbox *m)
Definition: mxapi.h:162
Container for Accounts, Notifications.
Definition: neomutt.h:42
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:46
#define buf_mktemp(buf)
Definition: tmp.h:33