NeoMutt  2025-12-11-58-g09398d
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 "lib.h"
51#include "expando/lib.h"
52#include "expando.h"
53#include "hook.h"
54#include "mx.h"
55#include "protos.h"
56
57struct Email;
58
62static const struct Command CompCommands[] = {
63 // clang-format off
64 { "append-hook", parse_hook_compress, MUTT_APPEND_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", parse_hook_compress, MUTT_CLOSE_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", parse_hook_compress, MUTT_OPEN_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, NULL, 0, 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
104
116static bool lock_realpath(struct Mailbox *m, bool excl)
117{
118 if (!m || !m->compress_info)
119 return false;
120
121 struct CompressInfo *ci = m->compress_info;
122
123 if (ci->locked)
124 return true;
125
126 if (excl)
127 ci->fp_lock = mutt_file_fopen(m->realpath, "a");
128 else
129 ci->fp_lock = mutt_file_fopen(m->realpath, "r");
130 if (!ci->fp_lock)
131 {
132 mutt_perror("%s", m->realpath);
133 return false;
134 }
135
136 int r = mutt_file_lock(fileno(ci->fp_lock), excl, true);
137 if (r == 0)
138 {
139 ci->locked = true;
140 }
141 else if (excl)
142 {
144 m->readonly = true;
145 return true;
146 }
147
148 return r == 0;
149}
150
157static void unlock_realpath(struct Mailbox *m)
158{
159 if (!m || !m->compress_info)
160 return;
161
162 struct CompressInfo *ci = m->compress_info;
163
164 if (!ci->locked)
165 return;
166
167 mutt_file_unlock(fileno(ci->fp_lock));
168
169 ci->locked = false;
171}
172
183static int setup_paths(struct Mailbox *m)
184{
185 if (!m)
186 return -1;
187
188 /* Setup the right paths */
190
191 /* We will uncompress to TMPDIR */
192 struct Buffer *buf = buf_pool_get();
193 buf_mktemp(buf);
194 buf_copy(&m->pathbuf, buf);
195 buf_pool_release(&buf);
196
197 return mutt_file_touch(mailbox_path(m)) ? 0 : -1;
198}
199
206static void store_size(const struct Mailbox *m)
207{
208 if (!m || !m->compress_info)
209 return;
210
211 struct CompressInfo *ci = m->compress_info;
212
214}
215
221static struct Expando *validate_compress_expando(const char *s)
222{
223 struct Buffer *err = buf_pool_get();
224
225 struct Expando *exp = expando_parse(s, CompressFormatDef, err);
226 if (!exp)
227 {
228 mutt_error(_("Expando parse error: %s"), buf_string(err));
229 }
230
231 buf_pool_release(&err);
232 return exp;
233}
234
243static struct CompressInfo *set_compress_info(struct Mailbox *m)
244{
245 if (!m)
246 return NULL;
247
248 if (m->compress_info)
249 return m->compress_info;
250
251 /* Open is compulsory */
252 const char *o = mutt_find_hook(MUTT_OPEN_HOOK, mailbox_path(m));
253 if (!o)
254 return NULL;
255
256 const char *c = mutt_find_hook(MUTT_CLOSE_HOOK, mailbox_path(m));
257 const char *a = mutt_find_hook(MUTT_APPEND_HOOK, mailbox_path(m));
258
259 struct CompressInfo *ci = MUTT_MEM_CALLOC(1, struct CompressInfo);
260 m->compress_info = ci;
261
265
266 return ci;
267}
268
273static void compress_info_free(struct Mailbox *m)
274{
275 if (!m || !m->compress_info)
276 return;
277
278 struct CompressInfo *ci = m->compress_info;
282
284
285 FREE(&m->compress_info);
286}
287
299static bool execute_command(struct Mailbox *m, const struct Expando *exp, const char *progress)
300{
301 if (!m || !exp || !progress)
302 return false;
303
304 if (m->verbose)
305 mutt_message(progress, m->realpath);
306
307 bool rc = true;
308 struct Buffer *sys_cmd = buf_pool_get();
309 buf_alloc(sys_cmd, STR_COMMAND);
310
312 mutt_endwin();
313 fflush(stdout);
314
316 sys_cmd->dsize, sys_cmd);
317
318 if (mutt_system(buf_string(sys_cmd)) != 0)
319 {
320 rc = false;
322 mutt_error(_("Error running \"%s\""), buf_string(sys_cmd));
323 }
324
326
327 buf_pool_release(&sys_cmd);
328 return rc;
329}
330
343{
344 if (!m)
345 return false;
346
347 /* If this succeeds, we know there's an open-hook */
348 struct CompressInfo *ci = set_compress_info(m);
349 if (!ci)
350 return false;
351
352 /* We have an open-hook, so to append we need an append-hook,
353 * or a close-hook. */
354 if (ci->cmd_append || ci->cmd_close)
355 return true;
356
357 mutt_error(_("Can't append without an append-hook or close-hook : %s"), mailbox_path(m));
358 return false;
359}
360
371bool mutt_comp_can_read(const char *path)
372{
373 if (!path)
374 return false;
375
377 return true;
378
379 return false;
380}
381
391int mutt_comp_valid_command(const char *cmd)
392{
393 if (!cmd)
394 return 0;
395
396 return strstr(cmd, "%f") && strstr(cmd, "%t");
397}
398
402static bool comp_ac_owns_path(struct Account *a, const char *path)
403{
404 return false;
405}
406
410static bool comp_ac_add(struct Account *a, struct Mailbox *m)
411{
412 return true;
413}
414
424{
425 struct CompressInfo *ci = set_compress_info(m);
426 if (!ci)
427 return MX_OPEN_ERROR;
428
429 /* If there's no close-hook, or the file isn't writable */
430 if (!ci->cmd_close || (access(mailbox_path(m), W_OK) != 0))
431 m->readonly = true;
432
433 if (setup_paths(m) != 0)
434 goto cmo_fail;
435 store_size(m);
436
437 if (!lock_realpath(m, false))
438 {
439 mutt_error(_("Unable to lock mailbox"));
440 goto cmo_fail;
441 }
442
443 if (!execute_command(m, ci->cmd_open, _("Decompressing %s")))
444 goto cmo_fail;
445
447
449 if (m->type == MUTT_UNKNOWN)
450 {
451 mutt_error(_("Can't identify the contents of the compressed file"));
452 goto cmo_fail;
453 }
454
455 ci->child_ops = mx_get_ops(m->type);
456 if (!ci->child_ops)
457 {
458 mutt_error(_("Can't find mailbox ops for mailbox type %d"), m->type);
459 goto cmo_fail;
460 }
461
462 m->account->type = m->type;
463 return ci->child_ops->mbox_open(m);
464
465cmo_fail:
466 /* remove the partial uncompressed file */
467 (void) remove(mailbox_path(m));
469 return MX_OPEN_ERROR;
470}
471
478static bool comp_mbox_open_append(struct Mailbox *m, OpenMailboxFlags flags)
479{
480 /* If this succeeds, we know there's an open-hook */
481 struct CompressInfo *ci = set_compress_info(m);
482 if (!ci)
483 return false;
484
485 /* To append we need an append-hook or a close-hook */
486 if (!ci->cmd_append && !ci->cmd_close)
487 {
488 mutt_error(_("Can't append without an append-hook or close-hook : %s"),
489 mailbox_path(m));
490 goto cmoa_fail1;
491 }
492
493 if (setup_paths(m) != 0)
494 goto cmoa_fail2;
495
496 /* Lock the realpath for the duration of the append.
497 * It will be unlocked in the close */
498 if (!lock_realpath(m, true))
499 {
500 mutt_error(_("Unable to lock mailbox"));
501 goto cmoa_fail2;
502 }
503
504 /* Open the existing mailbox, unless we are appending */
505 if (!ci->cmd_append && (mutt_file_get_size(m->realpath) > 0))
506 {
507 if (!execute_command(m, ci->cmd_open, _("Decompressing %s")))
508 {
509 mutt_error(_("Compress command failed: %s"), ci->cmd_open->string);
510 goto cmoa_fail2;
511 }
513 }
514 else
515 {
516 m->type = cs_subset_enum(NeoMutt->sub, "mbox_type");
517 }
518
519 /* We can only deal with mbox and mmdf mailboxes */
520 if ((m->type != MUTT_MBOX) && (m->type != MUTT_MMDF))
521 {
522 mutt_error(_("Unsupported mailbox type for appending"));
523 goto cmoa_fail2;
524 }
525
526 ci->child_ops = mx_get_ops(m->type);
527 if (!ci->child_ops)
528 {
529 mutt_error(_("Can't find mailbox ops for mailbox type %d"), m->type);
530 goto cmoa_fail2;
531 }
532
533 if (!ci->child_ops->mbox_open_append(m, flags))
534 goto cmoa_fail2;
535
536 return true;
537
538cmoa_fail2:
539 /* remove the partial uncompressed file */
540 (void) remove(mailbox_path(m));
541cmoa_fail1:
542 /* Free the compress_info to prevent close from trying to recompress */
544
545 return false;
546}
547
558static enum MxStatus comp_mbox_check(struct Mailbox *m)
559{
560 if (!m->compress_info)
561 return MX_STATUS_ERROR;
562
563 struct CompressInfo *ci = m->compress_info;
564
565 const struct MxOps *ops = ci->child_ops;
566 if (!ops)
567 return MX_STATUS_ERROR;
568
569 int size = mutt_file_get_size(m->realpath);
570 if (size == ci->size)
571 return MX_STATUS_OK;
572
573 if (!lock_realpath(m, false))
574 {
575 mutt_error(_("Unable to lock mailbox"));
576 return MX_STATUS_ERROR;
577 }
578
579 bool rc = execute_command(m, ci->cmd_open, _("Decompressing %s"));
580 store_size(m);
582 if (!rc)
583 return MX_STATUS_ERROR;
584
585 return ops->mbox_check(m);
586}
587
594static enum MxStatus comp_mbox_sync(struct Mailbox *m)
595{
596 if (!m->compress_info)
597 return MX_STATUS_ERROR;
598
599 struct CompressInfo *ci = m->compress_info;
600
601 if (!ci->cmd_close)
602 {
603 mutt_error(_("Can't sync a compressed file without a close-hook"));
604 return MX_STATUS_ERROR;
605 }
606
607 const struct MxOps *ops = ci->child_ops;
608 if (!ops)
609 return MX_STATUS_ERROR;
610
611 if (!lock_realpath(m, true))
612 {
613 mutt_error(_("Unable to lock mailbox"));
614 return MX_STATUS_ERROR;
615 }
616
617 enum MxStatus check = comp_mbox_check(m);
618 if (check != MX_STATUS_OK)
619 goto sync_cleanup;
620
621 check = ops->mbox_sync(m);
622 if (check != MX_STATUS_OK)
623 goto sync_cleanup;
624
625 if (!execute_command(m, ci->cmd_close, _("Compressing %s")))
626 {
627 check = MX_STATUS_ERROR;
628 goto sync_cleanup;
629 }
630
631 check = MX_STATUS_OK;
632
633sync_cleanup:
634 store_size(m);
636 return check;
637}
638
645static enum MxStatus comp_mbox_close(struct Mailbox *m)
646{
647 if (!m->compress_info)
648 return MX_STATUS_ERROR;
649
650 struct CompressInfo *ci = m->compress_info;
651
652 const struct MxOps *ops = ci->child_ops;
653 if (!ops)
654 {
656 return MX_STATUS_ERROR;
657 }
658
659 ops->mbox_close(m);
660
661 /* sync has already been called, so we only need to delete some files */
662 if (m->append)
663 {
664 const struct Expando *append = NULL;
665 const char *msg = NULL;
666
667 /* The file exists and we can append */
668 if ((access(m->realpath, F_OK) == 0) && ci->cmd_append)
669 {
670 append = ci->cmd_append;
671 msg = _("Compressed-appending to %s...");
672 }
673 else
674 {
675 append = ci->cmd_close;
676 msg = _("Compressing %s");
677 }
678
679 if (!execute_command(m, append, msg))
680 {
682 mutt_error(_("Error. Preserving temporary file: %s"), mailbox_path(m));
683 }
684 else
685 {
686 if (remove(mailbox_path(m)) < 0)
687 {
688 mutt_debug(LL_DEBUG1, "remove failed: %s: %s (errno %d)\n",
689 mailbox_path(m), strerror(errno), errno);
690 }
691 }
692
694 }
695 else
696 {
697 /* If the file was removed, remove the compressed folder too */
698 if (access(mailbox_path(m), F_OK) != 0)
699 {
700 const bool c_save_empty = cs_subset_bool(NeoMutt->sub, "save_empty");
701 if (!c_save_empty)
702 {
703 if (remove(m->realpath) < 0)
704 {
705 mutt_debug(LL_DEBUG1, "remove failed: %s: %s (errno %d)\n",
706 m->realpath, strerror(errno), errno);
707 }
708 }
709 }
710 else
711 {
712 if (remove(mailbox_path(m)) < 0)
713 {
714 mutt_debug(LL_DEBUG1, "remove failed: %s: %s (errno %d)\n",
715 mailbox_path(m), strerror(errno), errno);
716 }
717 }
718 }
719
721
722 return MX_STATUS_OK;
723}
724
728static bool comp_msg_open(struct Mailbox *m, struct Message *msg, struct Email *e)
729{
730 if (!m->compress_info)
731 return false;
732
733 struct CompressInfo *ci = m->compress_info;
734
735 const struct MxOps *ops = ci->child_ops;
736 if (!ops)
737 return false;
738
739 /* Delegate */
740 return ops->msg_open(m, msg, e);
741}
742
746static bool comp_msg_open_new(struct Mailbox *m, struct Message *msg, const struct Email *e)
747{
748 if (!m->compress_info)
749 return false;
750
751 struct CompressInfo *ci = m->compress_info;
752
753 const struct MxOps *ops = ci->child_ops;
754 if (!ops)
755 return false;
756
757 /* Delegate */
758 return ops->msg_open_new(m, msg, e);
759}
760
764static int comp_msg_commit(struct Mailbox *m, struct Message *msg)
765{
766 if (!m->compress_info)
767 return -1;
768
769 struct CompressInfo *ci = m->compress_info;
770
771 const struct MxOps *ops = ci->child_ops;
772 if (!ops)
773 return -1;
774
775 /* Delegate */
776 return ops->msg_commit(m, msg);
777}
778
782static int comp_msg_close(struct Mailbox *m, struct Message *msg)
783{
784 if (!m->compress_info)
785 return -1;
786
787 struct CompressInfo *ci = m->compress_info;
788
789 const struct MxOps *ops = ci->child_ops;
790 if (!ops)
791 return -1;
792
793 /* Delegate */
794 return ops->msg_close(m, msg);
795}
796
800static int comp_msg_padding_size(struct Mailbox *m)
801{
802 if (!m->compress_info)
803 return 0;
804
805 struct CompressInfo *ci = m->compress_info;
806
807 const struct MxOps *ops = ci->child_ops;
808 if (!ops || !ops->msg_padding_size)
809 return 0;
810
811 return ops->msg_padding_size(m);
812}
813
817static int comp_msg_save_hcache(struct Mailbox *m, struct Email *e)
818{
819 if (!m->compress_info)
820 return 0;
821
822 struct CompressInfo *ci = m->compress_info;
823
824 const struct MxOps *ops = ci->child_ops;
825 if (!ops || !ops->msg_save_hcache)
826 return 0;
827
828 return ops->msg_save_hcache(m, e);
829}
830
834static int comp_tags_edit(struct Mailbox *m, const char *tags, struct Buffer *buf)
835{
836 if (!m->compress_info)
837 return 0;
838
839 struct CompressInfo *ci = m->compress_info;
840
841 const struct MxOps *ops = ci->child_ops;
842 if (!ops || !ops->tags_edit)
843 return 0;
844
845 return ops->tags_edit(m, tags, buf);
846}
847
851static int comp_tags_commit(struct Mailbox *m, struct Email *e, const char *buf)
852{
853 if (!m->compress_info)
854 return 0;
855
856 struct CompressInfo *ci = m->compress_info;
857
858 const struct MxOps *ops = ci->child_ops;
859 if (!ops || !ops->tags_commit)
860 return 0;
861
862 return ops->tags_commit(m, e, buf);
863}
864
868static enum MailboxType comp_path_probe(const char *path, const struct stat *st)
869{
870 if (!st || !S_ISREG(st->st_mode))
871 return MUTT_UNKNOWN;
872
873 if (mutt_comp_can_read(path))
874 return MUTT_COMPRESSED;
875
876 return MUTT_UNKNOWN;
877}
878
882static int comp_path_canon(struct Buffer *path)
883{
884 mutt_path_canon(path, NeoMutt->home_dir, false);
885 return 0;
886}
887
894const struct MxOps MxCompOps = {
895 // clang-format off
896 .type = MUTT_COMPRESSED,
897 .name = "compressed",
898 .is_local = true,
899 .ac_owns_path = comp_ac_owns_path,
900 .ac_add = comp_ac_add,
901 .mbox_open = comp_mbox_open,
902 .mbox_open_append = comp_mbox_open_append,
903 .mbox_check = comp_mbox_check,
904 .mbox_check_stats = NULL,
905 .mbox_sync = comp_mbox_sync,
906 .mbox_close = comp_mbox_close,
907 .msg_open = comp_msg_open,
908 .msg_open_new = comp_msg_open_new,
909 .msg_commit = comp_msg_commit,
910 .msg_close = comp_msg_close,
911 .msg_padding_size = comp_msg_padding_size,
912 .msg_save_hcache = comp_msg_save_hcache,
913 .tags_edit = comp_tags_edit,
914 .tags_commit = comp_tags_commit,
915 .path_probe = comp_path_probe,
916 .path_canon = comp_path_canon,
917 .path_is_empty = NULL,
918 // clang-format on
919};
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:46
static struct CompressInfo * set_compress_info(struct Mailbox *m)
Find the compress hooks for a mailbox.
Definition compress.c:243
static void compress_info_free(struct Mailbox *m)
Frees the compress info members and structure.
Definition compress.c:273
static int setup_paths(struct Mailbox *m)
Set the mailbox paths.
Definition compress.c:183
const struct ExpandoDefinition CompressFormatDef[]
Expando definitions.
Definition compress.c:89
void mutt_comp_init(void)
Setup Compressed Mailbox commands.
Definition compress.c:100
static void store_size(const struct Mailbox *m)
Save the size of the compressed file.
Definition compress.c:206
static bool lock_realpath(struct Mailbox *m, bool excl)
Try to lock the Mailbox.realpath.
Definition compress.c:116
bool mutt_comp_can_append(struct Mailbox *m)
Can we append to this path?
Definition compress.c:342
static void unlock_realpath(struct Mailbox *m)
Unlock the mailbox->realpath.
Definition compress.c:157
static 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:391
static bool execute_command(struct Mailbox *m, const struct Expando *exp, const char *progress)
Run a system command.
Definition compress.c:299
static struct Expando * validate_compress_expando(const char *s)
Validate the Compress hooks.
Definition compress.c:221
bool mutt_comp_can_read(const char *path)
Can we read from this file?
Definition compress.c:371
const struct ExpandoRenderCallback CompressRenderCallbacks[]
Callbacks for Compression Hook Expandos.
Definition expando.c:70
Compress Expando definitions.
Compressed mbox local mailbox type.
@ 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.
bool commands_register(struct CommandArray *ca, const struct Command *cmds)
Add commands to Commands array.
Definition command.c:51
Convenience wrapper for the core headers.
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition mailbox.h:214
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:174
void mutt_endwin(void)
Shutdown curses.
Definition curs_lib.c:152
@ 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:981
int mutt_file_lock(int fd, bool excl, bool timeout)
(Try to) Lock a file using fcntl()
Definition file.c:1095
int mutt_file_unlock(int fd)
Unlock a file previously locked by mutt_file_lock()
Definition file.c:1142
long mutt_file_get_size(const char *path)
Get the size of a file.
Definition file.c:1412
#define mutt_file_fclose(FP)
Definition file.h:139
#define mutt_file_fopen(PATH, MODE)
Definition file.h:138
enum CommandResult parse_hook_compress(const struct Command *cmd, struct Buffer *line, struct Buffer *err)
Parse compress hook commands - Implements Command::parse() -.
Definition hook.c:927
#define mutt_error(...)
Definition logging2.h:93
#define mutt_message(...)
Definition logging2.h:92
#define mutt_debug(LEVEL,...)
Definition logging2.h:90
#define mutt_perror(...)
Definition logging2.h:94
static bool comp_ac_add(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account - Implements MxOps::ac_add() -.
Definition compress.c:410
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:402
const struct MxOps MxCompOps
Compressed Mailbox - Implements MxOps -.
Definition compress.c:894
static enum MxStatus comp_mbox_check(struct Mailbox *m)
Check for new mail - Implements MxOps::mbox_check() -.
Definition compress.c:558
static enum MxStatus comp_mbox_close(struct Mailbox *m)
Close a Mailbox - Implements MxOps::mbox_close() -.
Definition compress.c:645
static bool comp_mbox_open_append(struct Mailbox *m, OpenMailboxFlags flags)
Open a Mailbox for appending - Implements MxOps::mbox_open_append() -.
Definition compress.c:478
static enum MxOpenReturns comp_mbox_open(struct Mailbox *m)
Open a Mailbox - Implements MxOps::mbox_open() -.
Definition compress.c:423
static enum MxStatus comp_mbox_sync(struct Mailbox *m)
Save changes to the Mailbox - Implements MxOps::mbox_sync() -.
Definition compress.c:594
static int comp_msg_close(struct Mailbox *m, struct Message *msg)
Close an email - Implements MxOps::msg_close() -.
Definition compress.c:782
static int comp_msg_commit(struct Mailbox *m, struct Message *msg)
Save changes to an email - Implements MxOps::msg_commit() -.
Definition compress.c:764
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:746
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:728
static int comp_msg_padding_size(struct Mailbox *m)
Bytes of padding between messages - Implements MxOps::msg_padding_size() -.
Definition compress.c:800
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:817
static int comp_path_canon(struct Buffer *path)
Canonicalise a Mailbox path - Implements MxOps::path_canon() -.
Definition compress.c:882
static enum MailboxType comp_path_probe(const char *path, const struct stat *st)
Is this a compressed Mailbox?
Definition compress.c:868
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:851
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:834
Convenience wrapper for the gui headers.
char * mutt_find_hook(HookFlags type, const char *pat)
Find a matching hook.
Definition hook.c:1339
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:44
#define FREE(x)
Definition memory.h:62
#define MUTT_MEM_CALLOC(n, type)
Definition memory.h:47
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:282
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:1326
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:73
@ MX_OPEN_ERROR
Open failed with an error.
Definition mxapi.h:75
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_sync(), and mbox_close()
Definition mxapi.h:60
@ MX_STATUS_ERROR
An error occurred.
Definition mxapi.h:61
@ MX_STATUS_OK
No changes.
Definition mxapi.h:62
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
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:41
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: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: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:88
bool(* msg_open)(struct Mailbox *m, struct Message *msg, struct Email *e)
Definition mxapi.h:213
int(* tags_commit)(struct Mailbox *m, struct Email *e, const char *buf)
Definition mxapi.h:320
int(* msg_save_hcache)(struct Mailbox *m, struct Email *e)
Definition mxapi.h:286
int(* msg_padding_size)(struct Mailbox *m)
Definition mxapi.h:271
int(* tags_edit)(struct Mailbox *m, const char *tags, struct Buffer *buf)
Definition mxapi.h:303
int(* msg_commit)(struct Mailbox *m, struct Message *msg)
Definition mxapi.h:244
enum MxOpenReturns(* mbox_open)(struct Mailbox *m)
Definition mxapi.h:133
int(* msg_close)(struct Mailbox *m, struct Message *msg)
Definition mxapi.h:259
bool(* msg_open_new)(struct Mailbox *m, struct Message *msg, const struct Email *e)
Definition mxapi.h:229
enum MxStatus(* mbox_close)(struct Mailbox *m)
Definition mxapi.h:196
enum MxStatus(* mbox_sync)(struct Mailbox *m)
Definition mxapi.h:184
bool(* mbox_open_append)(struct Mailbox *m, OpenMailboxFlags flags)
Definition mxapi.h:147
enum MxStatus(* mbox_check)(struct Mailbox *m)
Definition mxapi.h:159
Container for Accounts, Notifications.
Definition neomutt.h:43
struct CommandArray commands
NeoMutt commands.
Definition neomutt.h:51
char * home_dir
User's home directory.
Definition neomutt.h:54
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:47
#define buf_mktemp(buf)
Definition tmp.h:33