NeoMutt  2025-12-11-694-ga89709
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
compress.c
Go to the documentation of this file.
1
25
38
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 "mutt.h"
51#include "lib.h"
52#include "expando/lib.h"
53#include "hooks/lib.h"
54#include "expando.h"
55#include "mx.h"
56
57struct Email;
58
62const struct Command CompCommands[] = {
63 // clang-format off
64 { "append-hook", CMD_APPEND_HOOK, parse_compress_hook,
65 N_("Define command to append to a compressed mailbox"),
66 N_("append-hook <regex> <shell-command>"),
67 "optionalfeatures.html#append-hook" },
68 { "close-hook", CMD_CLOSE_HOOK, parse_compress_hook,
69 N_("Define command to close a compressed mailbox"),
70 N_("close-hook <regex> <shell-command>"),
71 "optionalfeatures.html#close-hook" },
72 { "open-hook", CMD_OPEN_HOOK, parse_compress_hook,
73 N_("Define command to open a compressed mailbox"),
74 N_("open-hook <regex> <shell-command>"),
75 "optionalfeatures.html#open-hook" },
76
77 { NULL, CMD_NONE, NULL, NULL, NULL, NULL, CF_NO_FLAGS },
78 // clang-format on
79};
80
90 // clang-format off
91 { "f", "from", ED_COMPRESS, ED_CMP_FROM, NULL },
92 { "t", "to", ED_COMPRESS, ED_CMP_TO, NULL },
93 { NULL, NULL, 0, -1, NULL }
94 // clang-format on
95};
96
108static bool lock_realpath(struct Mailbox *m, bool excl)
109{
110 if (!m || !m->compress_info)
111 return false;
112
113 struct CompressInfo *ci = m->compress_info;
114
115 if (ci->locked)
116 return true;
117
118 if (excl)
119 ci->fp_lock = mutt_file_fopen(m->realpath, "a");
120 else
121 ci->fp_lock = mutt_file_fopen(m->realpath, "r");
122 if (!ci->fp_lock)
123 {
124 mutt_perror("%s", m->realpath);
125 return false;
126 }
127
128 int r = mutt_file_lock(fileno(ci->fp_lock), excl, true);
129 if (r == 0)
130 {
131 ci->locked = true;
132 }
133 else if (excl)
134 {
136 m->readonly = true;
137 return true;
138 }
139 else
140 {
142 }
143
144 return r == 0;
145}
146
153static void unlock_realpath(struct Mailbox *m)
154{
155 if (!m || !m->compress_info)
156 return;
157
158 struct CompressInfo *ci = m->compress_info;
159
160 if (!ci->locked)
161 return;
162
163 mutt_file_unlock(fileno(ci->fp_lock));
164
165 ci->locked = false;
167}
168
179static int setup_paths(struct Mailbox *m)
180{
181 if (!m)
182 return -1;
183
184 /* Setup the right paths */
186
187 /* We will uncompress to TMPDIR */
188 struct Buffer *buf = buf_pool_get();
189 buf_mktemp(buf);
190 buf_copy(&m->pathbuf, buf);
191 buf_pool_release(&buf);
192
193 return mutt_file_touch(mailbox_path(m)) ? 0 : -1;
194}
195
202static void store_size(const struct Mailbox *m)
203{
204 if (!m || !m->compress_info)
205 return;
206
207 struct CompressInfo *ci = m->compress_info;
208
210}
211
217static struct Expando *validate_compress_expando(const char *s)
218{
219 struct Buffer *err = buf_pool_get();
220
221 struct Expando *exp = expando_parse(s, CompressFormatDef, err);
222 if (!exp)
223 {
224 mutt_error(_("Expando parse error: %s"), buf_string(err));
225 }
226
227 buf_pool_release(&err);
228 return exp;
229}
230
239static struct CompressInfo *set_compress_info(struct Mailbox *m)
240{
241 if (!m)
242 return NULL;
243
244 if (m->compress_info)
245 return m->compress_info;
246
247 /* Open is compulsory */
248 const char *o = mutt_find_hook(CMD_OPEN_HOOK, mailbox_path(m));
249 if (!o)
250 return NULL;
251
252 const char *c = mutt_find_hook(CMD_CLOSE_HOOK, mailbox_path(m));
253 const char *a = mutt_find_hook(CMD_APPEND_HOOK, mailbox_path(m));
254
255 struct CompressInfo *ci = MUTT_MEM_CALLOC(1, struct CompressInfo);
256 m->compress_info = ci;
257
259 ci->cmd_close = c ? validate_compress_expando(c) : NULL;
260 ci->cmd_append = a ? validate_compress_expando(a) : NULL;
261
262 return ci;
263}
264
269static void compress_info_free(struct Mailbox *m)
270{
271 if (!m || !m->compress_info)
272 return;
273
274 struct CompressInfo *ci = m->compress_info;
278
280
281 FREE(&m->compress_info);
282}
283
295static bool execute_command(struct Mailbox *m, const struct Expando *exp, const char *progress)
296{
297 if (!m || !exp || !progress)
298 return false;
299
300 if (m->verbose)
301 mutt_message(progress, m->realpath);
302
303 bool rc = true;
304 struct Buffer *sys_cmd = buf_pool_get();
305 buf_alloc(sys_cmd, STR_COMMAND);
306
308 mutt_endwin();
309 fflush(stdout);
310
312 sys_cmd->dsize, sys_cmd);
313
314 if (mutt_system(buf_string(sys_cmd)) != 0)
315 {
316 rc = false;
318 mutt_error(_("Error running \"%s\""), buf_string(sys_cmd));
319 }
320
322
323 buf_pool_release(&sys_cmd);
324 return rc;
325}
326
339{
340 if (!m)
341 return false;
342
343 /* If this succeeds, we know there's an open-hook */
344 struct CompressInfo *ci = set_compress_info(m);
345 if (!ci)
346 return false;
347
348 /* We have an open-hook, so to append we need an append-hook,
349 * or a close-hook. */
350 if (ci->cmd_append || ci->cmd_close)
351 return true;
352
353 mutt_error(_("Can't append without an append-hook or close-hook : %s"), mailbox_path(m));
354 return false;
355}
356
367bool mutt_comp_can_read(const char *path)
368{
369 if (!path)
370 return false;
371
372 if (mutt_find_hook(CMD_OPEN_HOOK, path))
373 return true;
374
375 return false;
376}
377
387int mutt_comp_valid_command(const char *cmd)
388{
389 if (!cmd)
390 return 0;
391
392 return strstr(cmd, "%f") && strstr(cmd, "%t");
393}
394
398static bool comp_ac_owns_path(struct Account *a, const char *path)
399{
400 return false;
401}
402
406static bool comp_ac_add(struct Account *a, struct Mailbox *m)
407{
408 return true;
409}
410
420{
421 struct CompressInfo *ci = set_compress_info(m);
422 if (!ci)
423 return MX_OPEN_ERROR;
424
425 /* If there's no close-hook, or the file isn't writable */
426 if (!ci->cmd_close || (access(mailbox_path(m), W_OK) != 0))
427 m->readonly = true;
428
429 if (setup_paths(m) != 0)
430 goto cmo_fail;
431 store_size(m);
432
433 if (!lock_realpath(m, false))
434 {
435 mutt_error(_("Unable to lock mailbox"));
436 goto cmo_fail;
437 }
438
439 if (!execute_command(m, ci->cmd_open, _("Decompressing %s")))
440 goto cmo_fail;
441
443
445 if (m->type == MUTT_UNKNOWN)
446 {
447 mutt_error(_("Can't identify the contents of the compressed file"));
448 goto cmo_fail;
449 }
450
451 ci->child_ops = mx_get_ops(m->type);
452 if (!ci->child_ops)
453 {
454 mutt_error(_("Can't find mailbox ops for mailbox type %d"), m->type);
455 goto cmo_fail;
456 }
457
458 m->account->type = m->type;
459 return ci->child_ops->mbox_open(m);
460
461cmo_fail:
462 /* remove the partial uncompressed file */
463 (void) remove(mailbox_path(m));
465 return MX_OPEN_ERROR;
466}
467
474static bool comp_mbox_open_append(struct Mailbox *m, OpenMailboxFlags flags)
475{
476 /* If this succeeds, we know there's an open-hook */
477 struct CompressInfo *ci = set_compress_info(m);
478 if (!ci)
479 return false;
480
481 /* To append we need an append-hook or a close-hook */
482 if (!ci->cmd_append && !ci->cmd_close)
483 {
484 mutt_error(_("Can't append without an append-hook or close-hook : %s"),
485 mailbox_path(m));
486 goto cmoa_fail1;
487 }
488
489 if (setup_paths(m) != 0)
490 goto cmoa_fail2;
491
492 /* Lock the realpath for the duration of the append.
493 * It will be unlocked in the close */
494 if (!lock_realpath(m, true))
495 {
496 mutt_error(_("Unable to lock mailbox"));
497 goto cmoa_fail2;
498 }
499
500 /* Open the existing mailbox, unless we are appending */
501 if (!ci->cmd_append && (mutt_file_get_size(m->realpath) > 0))
502 {
503 if (!execute_command(m, ci->cmd_open, _("Decompressing %s")))
504 {
505 mutt_error(_("Compress command failed: %s"), ci->cmd_open->string);
506 goto cmoa_fail2;
507 }
509 }
510 else
511 {
512 m->type = cs_subset_enum(NeoMutt->sub, "mbox_type");
513 }
514
515 /* We can only deal with mbox and mmdf mailboxes */
516 if ((m->type != MUTT_MBOX) && (m->type != MUTT_MMDF))
517 {
518 mutt_error(_("Unsupported mailbox type for appending"));
519 goto cmoa_fail2;
520 }
521
522 ci->child_ops = mx_get_ops(m->type);
523 if (!ci->child_ops)
524 {
525 mutt_error(_("Can't find mailbox ops for mailbox type %d"), m->type);
526 goto cmoa_fail2;
527 }
528
529 if (!ci->child_ops->mbox_open_append(m, flags))
530 goto cmoa_fail2;
531
532 return true;
533
534cmoa_fail2:
535 /* remove the partial uncompressed file */
536 (void) remove(mailbox_path(m));
537cmoa_fail1:
538 /* Free the compress_info to prevent close from trying to recompress */
540
541 return false;
542}
543
554static enum MxStatus comp_mbox_check(struct Mailbox *m)
555{
556 if (!m->compress_info)
557 return MX_STATUS_ERROR;
558
559 struct CompressInfo *ci = m->compress_info;
560
561 const struct MxOps *ops = ci->child_ops;
562 if (!ops)
563 return MX_STATUS_ERROR;
564
565 long size = mutt_file_get_size(m->realpath);
566 if (size == ci->size)
567 return MX_STATUS_OK;
568
569 if (!lock_realpath(m, false))
570 {
571 mutt_error(_("Unable to lock mailbox"));
572 return MX_STATUS_ERROR;
573 }
574
575 bool rc = execute_command(m, ci->cmd_open, _("Decompressing %s"));
576 store_size(m);
578 if (!rc)
579 return MX_STATUS_ERROR;
580
581 return ops->mbox_check(m);
582}
583
590static enum MxStatus comp_mbox_sync(struct Mailbox *m)
591{
592 if (!m->compress_info)
593 return MX_STATUS_ERROR;
594
595 struct CompressInfo *ci = m->compress_info;
596
597 if (!ci->cmd_close)
598 {
599 mutt_error(_("Can't sync a compressed file without a close-hook"));
600 return MX_STATUS_ERROR;
601 }
602
603 const struct MxOps *ops = ci->child_ops;
604 if (!ops)
605 return MX_STATUS_ERROR;
606
607 if (!lock_realpath(m, true))
608 {
609 mutt_error(_("Unable to lock mailbox"));
610 return MX_STATUS_ERROR;
611 }
612
613 enum MxStatus check = comp_mbox_check(m);
614 if (check != MX_STATUS_OK)
615 goto sync_cleanup;
616
617 check = ops->mbox_sync(m);
618 if (check != MX_STATUS_OK)
619 goto sync_cleanup;
620
621 if (!execute_command(m, ci->cmd_close, _("Compressing %s")))
622 {
623 check = MX_STATUS_ERROR;
624 goto sync_cleanup;
625 }
626
627 check = MX_STATUS_OK;
628
629sync_cleanup:
630 store_size(m);
632 return check;
633}
634
641static enum MxStatus comp_mbox_close(struct Mailbox *m)
642{
643 if (!m->compress_info)
644 return MX_STATUS_ERROR;
645
646 struct CompressInfo *ci = m->compress_info;
647
648 const struct MxOps *ops = ci->child_ops;
649 if (!ops)
650 {
652 return MX_STATUS_ERROR;
653 }
654
655 ops->mbox_close(m);
656
657 /* sync has already been called, so we only need to delete some files */
658 if (m->append)
659 {
660 const struct Expando *append = NULL;
661 const char *msg = NULL;
662
663 /* The file exists and we can append */
664 if ((access(m->realpath, F_OK) == 0) && ci->cmd_append)
665 {
666 append = ci->cmd_append;
667 msg = _("Compressed-appending to %s...");
668 }
669 else
670 {
671 append = ci->cmd_close;
672 msg = _("Compressing %s");
673 }
674
675 if (!execute_command(m, append, msg))
676 {
678 mutt_error(_("Error. Preserving temporary file: %s"), mailbox_path(m));
679 }
680 else
681 {
682 if (remove(mailbox_path(m)) < 0)
683 {
684 mutt_debug(LL_DEBUG1, "remove failed: %s: %s (errno %d)\n",
685 mailbox_path(m), strerror(errno), errno);
686 }
687 }
688
690 }
691 else
692 {
693 /* If the file was removed, remove the compressed folder too */
694 if (access(mailbox_path(m), F_OK) != 0)
695 {
696 const bool c_save_empty = cs_subset_bool(NeoMutt->sub, "save_empty");
697 if (!c_save_empty)
698 {
699 if (remove(m->realpath) < 0)
700 {
701 mutt_debug(LL_DEBUG1, "remove failed: %s: %s (errno %d)\n",
702 m->realpath, strerror(errno), errno);
703 }
704 }
705 }
706 else
707 {
708 if (remove(mailbox_path(m)) < 0)
709 {
710 mutt_debug(LL_DEBUG1, "remove failed: %s: %s (errno %d)\n",
711 mailbox_path(m), strerror(errno), errno);
712 }
713 }
714 }
715
717
718 return MX_STATUS_OK;
719}
720
724static bool comp_msg_open(struct Mailbox *m, struct Message *msg, struct Email *e)
725{
726 if (!m->compress_info)
727 return false;
728
729 struct CompressInfo *ci = m->compress_info;
730
731 const struct MxOps *ops = ci->child_ops;
732 if (!ops)
733 return false;
734
735 /* Delegate */
736 return ops->msg_open(m, msg, e);
737}
738
742static bool comp_msg_open_new(struct Mailbox *m, struct Message *msg, const struct Email *e)
743{
744 if (!m->compress_info)
745 return false;
746
747 struct CompressInfo *ci = m->compress_info;
748
749 const struct MxOps *ops = ci->child_ops;
750 if (!ops)
751 return false;
752
753 /* Delegate */
754 return ops->msg_open_new(m, msg, e);
755}
756
760static int comp_msg_commit(struct Mailbox *m, struct Message *msg)
761{
762 if (!m->compress_info)
763 return -1;
764
765 struct CompressInfo *ci = m->compress_info;
766
767 const struct MxOps *ops = ci->child_ops;
768 if (!ops)
769 return -1;
770
771 /* Delegate */
772 return ops->msg_commit(m, msg);
773}
774
778static int comp_msg_close(struct Mailbox *m, struct Message *msg)
779{
780 if (!m->compress_info)
781 return -1;
782
783 struct CompressInfo *ci = m->compress_info;
784
785 const struct MxOps *ops = ci->child_ops;
786 if (!ops)
787 return -1;
788
789 /* Delegate */
790 return ops->msg_close(m, msg);
791}
792
796static int comp_msg_padding_size(struct Mailbox *m)
797{
798 if (!m->compress_info)
799 return 0;
800
801 struct CompressInfo *ci = m->compress_info;
802
803 const struct MxOps *ops = ci->child_ops;
804 if (!ops || !ops->msg_padding_size)
805 return 0;
806
807 return ops->msg_padding_size(m);
808}
809
813static int comp_msg_save_hcache(struct Mailbox *m, struct Email *e)
814{
815 if (!m->compress_info)
816 return 0;
817
818 struct CompressInfo *ci = m->compress_info;
819
820 const struct MxOps *ops = ci->child_ops;
821 if (!ops || !ops->msg_save_hcache)
822 return 0;
823
824 return ops->msg_save_hcache(m, e);
825}
826
830static int comp_tags_edit(struct Mailbox *m, const char *tags, struct Buffer *buf)
831{
832 if (!m->compress_info)
833 return 0;
834
835 struct CompressInfo *ci = m->compress_info;
836
837 const struct MxOps *ops = ci->child_ops;
838 if (!ops || !ops->tags_edit)
839 return 0;
840
841 return ops->tags_edit(m, tags, buf);
842}
843
847static int comp_tags_commit(struct Mailbox *m, struct Email *e, const char *buf)
848{
849 if (!m->compress_info)
850 return 0;
851
852 struct CompressInfo *ci = m->compress_info;
853
854 const struct MxOps *ops = ci->child_ops;
855 if (!ops || !ops->tags_commit)
856 return 0;
857
858 return ops->tags_commit(m, e, buf);
859}
860
864static enum MailboxType comp_path_probe(const char *path, const struct stat *st)
865{
866 if (!st || !S_ISREG(st->st_mode))
867 return MUTT_UNKNOWN;
868
869 if (mutt_comp_can_read(path))
870 return MUTT_COMPRESSED;
871
872 return MUTT_UNKNOWN;
873}
874
878static int comp_path_canon(struct Buffer *path)
879{
880 mutt_path_canon(path, NeoMutt->home_dir, false);
881 return 0;
882}
883
890const struct MxOps MxCompOps = {
891 // clang-format off
892 .type = MUTT_COMPRESSED,
893 .name = "compressed",
894 .is_local = true,
895 .ac_owns_path = comp_ac_owns_path,
896 .ac_add = comp_ac_add,
897 .mbox_open = comp_mbox_open,
898 .mbox_open_append = comp_mbox_open_append,
899 .mbox_check = comp_mbox_check,
900 .mbox_check_stats = NULL,
901 .mbox_sync = comp_mbox_sync,
902 .mbox_close = comp_mbox_close,
903 .msg_open = comp_msg_open,
904 .msg_open_new = comp_msg_open_new,
905 .msg_commit = comp_msg_commit,
906 .msg_close = comp_msg_close,
907 .msg_padding_size = comp_msg_padding_size,
908 .msg_save_hcache = comp_msg_save_hcache,
909 .tags_edit = comp_tags_edit,
910 .tags_commit = comp_tags_commit,
911 .path_probe = comp_path_probe,
912 .path_canon = comp_path_canon,
913 .path_is_empty = NULL,
914 // clang-format on
915};
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
#define CF_NO_FLAGS
No flags are set.
Definition command.h:48
@ CMD_CLOSE_HOOK
:close-hook
Definition command.h:70
@ CMD_NONE
No Command.
Definition command.h:59
@ CMD_OPEN_HOOK
:open-hook
Definition command.h:100
@ CMD_APPEND_HOOK
:append-hook
Definition command.h:64
static struct CompressInfo * set_compress_info(struct Mailbox *m)
Find the compress hooks for a mailbox.
Definition compress.c:239
static void compress_info_free(struct Mailbox *m)
Frees the compress info members and structure.
Definition compress.c:269
static int setup_paths(struct Mailbox *m)
Set the mailbox paths.
Definition compress.c:179
const struct ExpandoDefinition CompressFormatDef[]
Expando definitions.
Definition compress.c:89
static void store_size(const struct Mailbox *m)
Save the size of the compressed file.
Definition compress.c:202
static bool lock_realpath(struct Mailbox *m, bool excl)
Try to lock the Mailbox.realpath.
Definition compress.c:108
bool mutt_comp_can_append(struct Mailbox *m)
Can we append to this path?
Definition compress.c:338
static void unlock_realpath(struct Mailbox *m)
Unlock the mailbox->realpath.
Definition compress.c:153
const struct Command CompCommands[]
Compression Commands.
Definition compress.c:62
int mutt_comp_valid_command(const char *cmd)
Is this command string allowed?
Definition compress.c:387
static bool execute_command(struct Mailbox *m, const struct Expando *exp, const char *progress)
Run a system command.
Definition compress.c:295
static struct Expando * validate_compress_expando(const char *s)
Validate the Compress hooks.
Definition compress.c:217
bool mutt_comp_can_read(const char *path)
Can we read from this file?
Definition compress.c:367
const struct ExpandoRenderCallback CompressRenderCallbacks[]
Callbacks for Compression Hook Expandos.
Definition expando.c:64
Compress Expando definitions.
Compressed mbox local mailbox type.
@ ED_CMP_FROM
'from' path
Definition lib.h:51
@ ED_CMP_TO
'to' path
Definition lib.h:52
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.
Convenience wrapper for the core headers.
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition mailbox.h:213
MailboxType
Supported mailbox formats.
Definition mailbox.h:40
@ MUTT_MMDF
'mmdf' Mailbox type
Definition mailbox.h:45
@ MUTT_MBOX
'mbox' Mailbox type
Definition mailbox.h:44
@ MUTT_COMPRESSED
Compressed file Mailbox type.
Definition mailbox.h:52
@ MUTT_UNKNOWN
Mailbox wasn't recognised.
Definition mailbox.h:43
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.
bool mutt_file_touch(const char *path)
Make sure a file exists.
Definition file.c:974
int mutt_file_lock(int fd, bool excl, bool timeout)
(Try to) Lock a file using fcntl()
Definition file.c:1088
int mutt_file_unlock(int fd)
Unlock a file previously locked by mutt_file_lock()
Definition file.c:1135
long mutt_file_get_size(const char *path)
Get the size of a file.
Definition file.c:1414
#define mutt_file_fclose(FP)
Definition file.h:139
#define mutt_file_fopen(PATH, MODE)
Definition file.h:138
enum CommandResult parse_compress_hook(const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
Parse compress hook commands - Implements Command::parse() -.
Definition parse.c:914
#define mutt_error(...)
Definition logging2.h:94
#define mutt_message(...)
Definition logging2.h:93
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
#define mutt_perror(...)
Definition logging2.h:95
static bool comp_ac_add(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account - Implements MxOps::ac_add() -.
Definition compress.c:406
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:398
const struct MxOps MxCompOps
Compressed Mailbox - Implements MxOps -.
Definition compress.c:890
static enum MxStatus comp_mbox_check(struct Mailbox *m)
Check for new mail - Implements MxOps::mbox_check() -.
Definition compress.c:554
static enum MxStatus comp_mbox_close(struct Mailbox *m)
Close a Mailbox - Implements MxOps::mbox_close() -.
Definition compress.c:641
static bool comp_mbox_open_append(struct Mailbox *m, OpenMailboxFlags flags)
Open a Mailbox for appending - Implements MxOps::mbox_open_append() -.
Definition compress.c:474
static enum MxOpenReturns comp_mbox_open(struct Mailbox *m)
Open a Mailbox - Implements MxOps::mbox_open() -.
Definition compress.c:419
static enum MxStatus comp_mbox_sync(struct Mailbox *m)
Save changes to the Mailbox - Implements MxOps::mbox_sync() -.
Definition compress.c:590
static int comp_msg_close(struct Mailbox *m, struct Message *msg)
Close an email - Implements MxOps::msg_close() -.
Definition compress.c:778
static int comp_msg_commit(struct Mailbox *m, struct Message *msg)
Save changes to an email - Implements MxOps::msg_commit() -.
Definition compress.c:760
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:742
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:724
static int comp_msg_padding_size(struct Mailbox *m)
Bytes of padding between messages - Implements MxOps::msg_padding_size() -.
Definition compress.c:796
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:813
static int comp_path_canon(struct Buffer *path)
Canonicalise a Mailbox path - Implements MxOps::path_canon() -.
Definition compress.c:878
static enum MailboxType comp_path_probe(const char *path, const struct stat *st)
Is this a compressed Mailbox?
Definition compress.c:864
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:847
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:830
Convenience wrapper for the gui headers.
char * mutt_find_hook(enum CommandId id, const char *pat)
Find a matching hook.
Definition exec.c:114
Hook Commands.
@ LL_DEBUG1
Log at debug level 1.
Definition logging2.h:45
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
#define MUTT_MEM_CALLOC(n, type)
Definition memory.h:52
Convenience wrapper for the library headers.
#define N_(a)
Definition message.h:32
#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:284
Many unsorted constants and some structs.
int mutt_system(const char *cmd)
Run an external command.
Definition system.c:51
const struct MxOps * mx_get_ops(enum MailboxType type)
Get mailbox operations.
Definition mx.c:124
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition mx.c:1323
API for mailboxes.
uint8_t OpenMailboxFlags
Flags for mutt_open_mailbox(), e.g. MUTT_NOSORT.
Definition mxapi.h:38
MxOpenReturns
Return values for mbox_open()
Definition mxapi.h:72
@ MX_OPEN_ERROR
Open failed with an error.
Definition mxapi.h:74
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_sync(), and mbox_close()
Definition mxapi.h:59
@ MX_STATUS_ERROR
An error occurred.
Definition mxapi.h:60
@ MX_STATUS_OK
No changes.
Definition mxapi.h:61
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition render.h:33
void mutt_sig_block(void)
Block signals during critical operations.
Definition signal.c:227
void mutt_sig_unblock(void)
Restore previously blocked signals.
Definition signal.c:245
#define STR_COMMAND
Enough space for a long command line.
Definition string2.h:42
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:61
struct Expando * cmd_open
open-hook command
Definition lib.h:64
FILE * fp_lock
fp used for locking
Definition lib.h:68
struct Expando * cmd_append
append-hook command
Definition lib.h:62
const struct MxOps * child_ops
callbacks of de-compressed file
Definition lib.h:66
bool locked
if realpath is locked
Definition lib.h:67
long size
size of the compressed file
Definition lib.h:65
struct Expando * cmd_close
close-hook command
Definition lib.h:63
The envelope/body of an email.
Definition email.h:39
Definition of a format string.
Definition definition.h:43
Parsed Expando trees.
Definition expando.h:41
const char * string
Pointer to the parsed string.
Definition expando.h:42
A mailbox.
Definition mailbox.h:78
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition mailbox.h:80
bool append
Mailbox is opened in append mode.
Definition mailbox.h:108
enum MailboxType type
Mailbox type.
Definition mailbox.h:101
struct Buffer pathbuf
Path of the Mailbox.
Definition mailbox.h:79
struct Account * account
Account that owns this Mailbox.
Definition mailbox.h:126
void * compress_info
Compressed mbox module private data.
Definition mailbox.h:120
bool readonly
Don't allow changes to the mailbox.
Definition mailbox.h:115
bool verbose
Display status messages?
Definition mailbox.h:116
A local copy of an email.
Definition message.h:34
Definition mxapi.h:87
bool(* msg_open)(struct Mailbox *m, struct Message *msg, struct Email *e)
Definition mxapi.h:212
int(* tags_commit)(struct Mailbox *m, struct Email *e, const char *buf)
Definition mxapi.h:319
int(* msg_save_hcache)(struct Mailbox *m, struct Email *e)
Definition mxapi.h:285
int(* msg_padding_size)(struct Mailbox *m)
Definition mxapi.h:270
int(* tags_edit)(struct Mailbox *m, const char *tags, struct Buffer *buf)
Definition mxapi.h:302
int(* msg_commit)(struct Mailbox *m, struct Message *msg)
Definition mxapi.h:243
enum MxOpenReturns(* mbox_open)(struct Mailbox *m)
Definition mxapi.h:132
int(* msg_close)(struct Mailbox *m, struct Message *msg)
Definition mxapi.h:258
bool(* msg_open_new)(struct Mailbox *m, struct Message *msg, const struct Email *e)
Definition mxapi.h:228
enum MxStatus(* mbox_close)(struct Mailbox *m)
Definition mxapi.h:195
enum MxStatus(* mbox_sync)(struct Mailbox *m)
Definition mxapi.h:183
bool(* mbox_open_append)(struct Mailbox *m, OpenMailboxFlags flags)
Definition mxapi.h:146
enum MxStatus(* mbox_check)(struct Mailbox *m)
Definition mxapi.h:158
Container for Accounts, Notifications.
Definition neomutt.h:41
char * home_dir
User's home directory.
Definition neomutt.h:56
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
#define buf_mktemp(buf)
Definition tmp.h:33