NeoMutt
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
compress.c
Go to the documentation of this file.
1
37#include "config.h"
38#include <errno.h>
39#include <stdbool.h>
40#include <stdint.h>
41#include <stdio.h>
42#include <string.h>
43#include <sys/stat.h>
44#include <unistd.h>
45#include "mutt/lib.h"
46#include "config/lib.h"
47#include "core/lib.h"
48#include "gui/lib.h"
49#include "lib.h"
50#include "format_flags.h"
51#include "globals.h"
52#include "hook.h"
53#include "muttlib.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", mutt_parse_hook, MUTT_APPEND_HOOK },
65 { "close-hook", mutt_parse_hook, MUTT_CLOSE_HOOK },
66 { "open-hook", mutt_parse_hook, MUTT_OPEN_HOOK },
67 // clang-format on
68};
69
74{
76}
77
89static bool lock_realpath(struct Mailbox *m, bool excl)
90{
91 if (!m || !m->compress_info)
92 return false;
93
94 struct CompressInfo *ci = m->compress_info;
95
96 if (ci->locked)
97 return true;
98
99 if (excl)
100 ci->fp_lock = fopen(m->realpath, "a");
101 else
102 ci->fp_lock = fopen(m->realpath, "r");
103 if (!ci->fp_lock)
104 {
105 mutt_perror("%s", m->realpath);
106 return false;
107 }
108
109 int r = mutt_file_lock(fileno(ci->fp_lock), excl, true);
110 if (r == 0)
111 {
112 ci->locked = true;
113 }
114 else if (excl)
115 {
117 m->readonly = true;
118 return true;
119 }
120
121 return r == 0;
122}
123
130static void unlock_realpath(struct Mailbox *m)
131{
132 if (!m || !m->compress_info)
133 return;
134
135 struct CompressInfo *ci = m->compress_info;
136
137 if (!ci->locked)
138 return;
139
140 mutt_file_unlock(fileno(ci->fp_lock));
141
142 ci->locked = false;
144}
145
156static int setup_paths(struct Mailbox *m)
157{
158 if (!m)
159 return -1;
160
161 /* Setup the right paths */
163
164 /* We will uncompress to TMPDIR */
165 struct Buffer *buf = buf_pool_get();
166 buf_mktemp(buf);
167 buf_copy(&m->pathbuf, buf);
168 buf_pool_release(&buf);
169
170 FILE *fp = mutt_file_fopen(mailbox_path(m), "w");
171 if (!fp)
172 return -1;
173
174 mutt_file_fclose(&fp);
175 return 0;
176}
177
184static void store_size(const struct Mailbox *m)
185{
186 if (!m || !m->compress_info)
187 return;
188
189 struct CompressInfo *ci = m->compress_info;
190
192}
193
202static struct CompressInfo *set_compress_info(struct Mailbox *m)
203{
204 if (!m)
205 return NULL;
206
207 if (m->compress_info)
208 return m->compress_info;
209
210 /* Open is compulsory */
211 const char *o = mutt_find_hook(MUTT_OPEN_HOOK, mailbox_path(m));
212 if (!o)
213 return NULL;
214
215 const char *c = mutt_find_hook(MUTT_CLOSE_HOOK, mailbox_path(m));
216 const char *a = mutt_find_hook(MUTT_APPEND_HOOK, mailbox_path(m));
217
218 struct CompressInfo *ci = mutt_mem_calloc(1, sizeof(struct CompressInfo));
219 m->compress_info = ci;
220
221 ci->cmd_open = mutt_str_dup(o);
222 ci->cmd_close = mutt_str_dup(c);
223 ci->cmd_append = mutt_str_dup(a);
224
225 return ci;
226}
227
232static void compress_info_free(struct Mailbox *m)
233{
234 if (!m || !m->compress_info)
235 return;
236
237 struct CompressInfo *ci = m->compress_info;
238 FREE(&ci->cmd_open);
239 FREE(&ci->cmd_close);
240 FREE(&ci->cmd_append);
241
243
244 FREE(&m->compress_info);
245}
246
255static const char *compress_format_str(char *buf, size_t buflen, size_t col, int cols,
256 char op, const char *src, const char *prec,
257 const char *if_str, const char *else_str,
258 intptr_t data, MuttFormatFlags flags)
259{
260 if (!buf || (data == 0))
261 return src;
262
263 struct Mailbox *m = (struct Mailbox *) data;
264
265 /* NOTE the compressed file config vars expect %f and %t to be
266 * surrounded by '' (unlike other NeoMutt config vars, which add the
267 * outer quotes for the user). This is why we use the
268 * buf_quote_filename() form with add_outer of false. */
269 struct Buffer *quoted = buf_pool_get();
270 switch (op)
271 {
272 case 'f':
273 /* Compressed file */
274 buf_quote_filename(quoted, m->realpath, false);
275 snprintf(buf, buflen, "%s", buf_string(quoted));
276 break;
277 case 't':
278 /* Plaintext, temporary file */
279 buf_quote_filename(quoted, mailbox_path(m), false);
280 snprintf(buf, buflen, "%s", buf_string(quoted));
281 break;
282 }
283
284 buf_pool_release(&quoted);
285 return src;
286}
287
307static void expand_command_str(const struct Mailbox *m, const char *cmd, char *buf, int buflen)
308{
309 if (!m || !cmd || !buf)
310 return;
311
312 mutt_expando_format(buf, buflen, 0, buflen, cmd, compress_format_str,
313 (intptr_t) m, MUTT_FORMAT_NO_FLAGS);
314}
315
327static bool execute_command(struct Mailbox *m, const char *command, const char *progress)
328{
329 if (!m || !command || !progress)
330 return false;
331
332 if (m->verbose)
333 mutt_message(progress, m->realpath);
334
335 bool rc = true;
336 char sys_cmd[STR_COMMAND] = { 0 };
337
339 endwin();
340 fflush(stdout);
341
342 expand_command_str(m, command, sys_cmd, sizeof(sys_cmd));
343
344 if (mutt_system(sys_cmd) != 0)
345 {
346 rc = false;
348 mutt_error(_("Error running \"%s\""), sys_cmd);
349 }
350
352
353 return rc;
354}
355
368{
369 if (!m)
370 return false;
371
372 /* If this succeeds, we know there's an open-hook */
373 struct CompressInfo *ci = set_compress_info(m);
374 if (!ci)
375 return false;
376
377 /* We have an open-hook, so to append we need an append-hook,
378 * or a close-hook. */
379 if (ci->cmd_append || ci->cmd_close)
380 return true;
381
382 mutt_error(_("Can't append without an append-hook or close-hook : %s"), mailbox_path(m));
383 return false;
384}
385
396bool mutt_comp_can_read(const char *path)
397{
398 if (!path)
399 return false;
400
402 return true;
403
404 return false;
405}
406
416int mutt_comp_valid_command(const char *cmd)
417{
418 if (!cmd)
419 return 0;
420
421 return strstr(cmd, "%f") && strstr(cmd, "%t");
422}
423
427static bool comp_ac_owns_path(struct Account *a, const char *path)
428{
429 return false;
430}
431
435static bool comp_ac_add(struct Account *a, struct Mailbox *m)
436{
437 return true;
438}
439
449{
450 struct CompressInfo *ci = set_compress_info(m);
451 if (!ci)
452 return MX_OPEN_ERROR;
453
454 /* If there's no close-hook, or the file isn't writable */
455 if (!ci->cmd_close || (access(mailbox_path(m), W_OK) != 0))
456 m->readonly = true;
457
458 if (setup_paths(m) != 0)
459 goto cmo_fail;
460 store_size(m);
461
462 if (!lock_realpath(m, false))
463 {
464 mutt_error(_("Unable to lock mailbox"));
465 goto cmo_fail;
466 }
467
468 if (!execute_command(m, ci->cmd_open, _("Decompressing %s")))
469 goto cmo_fail;
470
472
474 if (m->type == MUTT_UNKNOWN)
475 {
476 mutt_error(_("Can't identify the contents of the compressed file"));
477 goto cmo_fail;
478 }
479
480 ci->child_ops = mx_get_ops(m->type);
481 if (!ci->child_ops)
482 {
483 mutt_error(_("Can't find mailbox ops for mailbox type %d"), m->type);
484 goto cmo_fail;
485 }
486
487 m->account->type = m->type;
488 return ci->child_ops->mbox_open(m);
489
490cmo_fail:
491 /* remove the partial uncompressed file */
492 (void) remove(mailbox_path(m));
494 return MX_OPEN_ERROR;
495}
496
505static bool comp_mbox_open_append(struct Mailbox *m, OpenMailboxFlags flags)
506{
507 /* If this succeeds, we know there's an open-hook */
508 struct CompressInfo *ci = set_compress_info(m);
509 if (!ci)
510 return false;
511
512 /* To append we need an append-hook or a close-hook */
513 if (!ci->cmd_append && !ci->cmd_close)
514 {
515 mutt_error(_("Can't append without an append-hook or close-hook : %s"),
516 mailbox_path(m));
517 goto cmoa_fail1;
518 }
519
520 if (setup_paths(m) != 0)
521 goto cmoa_fail2;
522
523 /* Lock the realpath for the duration of the append.
524 * It will be unlocked in the close */
525 if (!lock_realpath(m, true))
526 {
527 mutt_error(_("Unable to lock mailbox"));
528 goto cmoa_fail2;
529 }
530
531 /* Open the existing mailbox, unless we are appending */
532 if (!ci->cmd_append && (mutt_file_get_size(m->realpath) > 0))
533 {
534 if (!execute_command(m, ci->cmd_open, _("Decompressing %s")))
535 {
536 mutt_error(_("Compress command failed: %s"), ci->cmd_open);
537 goto cmoa_fail2;
538 }
540 }
541 else
542 {
543 m->type = cs_subset_enum(NeoMutt->sub, "mbox_type");
544 }
545
546 /* We can only deal with mbox and mmdf mailboxes */
547 if ((m->type != MUTT_MBOX) && (m->type != MUTT_MMDF))
548 {
549 mutt_error(_("Unsupported mailbox type for appending"));
550 goto cmoa_fail2;
551 }
552
553 ci->child_ops = mx_get_ops(m->type);
554 if (!ci->child_ops)
555 {
556 mutt_error(_("Can't find mailbox ops for mailbox type %d"), m->type);
557 goto cmoa_fail2;
558 }
559
560 if (!ci->child_ops->mbox_open_append(m, flags))
561 goto cmoa_fail2;
562
563 return true;
564
565cmoa_fail2:
566 /* remove the partial uncompressed file */
567 (void) remove(mailbox_path(m));
568cmoa_fail1:
569 /* Free the compress_info to prevent close from trying to recompress */
571
572 return false;
573}
574
585static enum MxStatus comp_mbox_check(struct Mailbox *m)
586{
587 if (!m->compress_info)
588 return MX_STATUS_ERROR;
589
590 struct CompressInfo *ci = m->compress_info;
591
592 const struct MxOps *ops = ci->child_ops;
593 if (!ops)
594 return MX_STATUS_ERROR;
595
596 int size = mutt_file_get_size(m->realpath);
597 if (size == ci->size)
598 return MX_STATUS_OK;
599
600 if (!lock_realpath(m, false))
601 {
602 mutt_error(_("Unable to lock mailbox"));
603 return MX_STATUS_ERROR;
604 }
605
606 bool rc = execute_command(m, ci->cmd_open, _("Decompressing %s"));
607 store_size(m);
609 if (!rc)
610 return MX_STATUS_ERROR;
611
612 return ops->mbox_check(m);
613}
614
621static enum MxStatus comp_mbox_sync(struct Mailbox *m)
622{
623 if (!m->compress_info)
624 return MX_STATUS_ERROR;
625
626 struct CompressInfo *ci = m->compress_info;
627
628 if (!ci->cmd_close)
629 {
630 mutt_error(_("Can't sync a compressed file without a close-hook"));
631 return MX_STATUS_ERROR;
632 }
633
634 const struct MxOps *ops = ci->child_ops;
635 if (!ops)
636 return MX_STATUS_ERROR;
637
638 if (!lock_realpath(m, true))
639 {
640 mutt_error(_("Unable to lock mailbox"));
641 return MX_STATUS_ERROR;
642 }
643
644 enum MxStatus check = comp_mbox_check(m);
645 if (check != MX_STATUS_OK)
646 goto sync_cleanup;
647
648 check = ops->mbox_sync(m);
649 if (check != MX_STATUS_OK)
650 goto sync_cleanup;
651
652 if (!execute_command(m, ci->cmd_close, _("Compressing %s")))
653 {
654 check = MX_STATUS_ERROR;
655 goto sync_cleanup;
656 }
657
658 check = MX_STATUS_OK;
659
660sync_cleanup:
661 store_size(m);
663 return check;
664}
665
672static enum MxStatus comp_mbox_close(struct Mailbox *m)
673{
674 if (!m->compress_info)
675 return MX_STATUS_ERROR;
676
677 struct CompressInfo *ci = m->compress_info;
678
679 const struct MxOps *ops = ci->child_ops;
680 if (!ops)
681 {
683 return MX_STATUS_ERROR;
684 }
685
686 ops->mbox_close(m);
687
688 /* sync has already been called, so we only need to delete some files */
689 if (m->append)
690 {
691 const char *append = NULL;
692 const char *msg = NULL;
693
694 /* The file exists and we can append */
695 if ((access(m->realpath, F_OK) == 0) && ci->cmd_append)
696 {
697 append = ci->cmd_append;
698 msg = _("Compressed-appending to %s...");
699 }
700 else
701 {
702 append = ci->cmd_close;
703 msg = _("Compressing %s");
704 }
705
706 if (!execute_command(m, append, msg))
707 {
709 mutt_error(_("Error. Preserving temporary file: %s"), mailbox_path(m));
710 }
711 else
712 {
713 if (remove(mailbox_path(m)) < 0)
714 {
715 mutt_debug(LL_DEBUG1, "remove failed: %s: %s (errno %d)\n",
716 mailbox_path(m), strerror(errno), errno);
717 }
718 }
719
721 }
722 else
723 {
724 /* If the file was removed, remove the compressed folder too */
725 if (access(mailbox_path(m), F_OK) != 0)
726 {
727 const bool c_save_empty = cs_subset_bool(NeoMutt->sub, "save_empty");
728 if (!c_save_empty)
729 {
730 if (remove(m->realpath) < 0)
731 {
732 mutt_debug(LL_DEBUG1, "remove failed: %s: %s (errno %d)\n",
733 m->realpath, strerror(errno), errno);
734 }
735 }
736 }
737 else
738 {
739 if (remove(mailbox_path(m)) < 0)
740 {
741 mutt_debug(LL_DEBUG1, "remove failed: %s: %s (errno %d)\n",
742 mailbox_path(m), strerror(errno), errno);
743 }
744 }
745 }
746
748
749 return MX_STATUS_OK;
750}
751
755static bool comp_msg_open(struct Mailbox *m, struct Message *msg, struct Email *e)
756{
757 if (!m->compress_info)
758 return false;
759
760 struct CompressInfo *ci = m->compress_info;
761
762 const struct MxOps *ops = ci->child_ops;
763 if (!ops)
764 return false;
765
766 /* Delegate */
767 return ops->msg_open(m, msg, e);
768}
769
773static bool comp_msg_open_new(struct Mailbox *m, struct Message *msg, const struct Email *e)
774{
775 if (!m->compress_info)
776 return false;
777
778 struct CompressInfo *ci = m->compress_info;
779
780 const struct MxOps *ops = ci->child_ops;
781 if (!ops)
782 return false;
783
784 /* Delegate */
785 return ops->msg_open_new(m, msg, e);
786}
787
791static int comp_msg_commit(struct Mailbox *m, struct Message *msg)
792{
793 if (!m->compress_info)
794 return -1;
795
796 struct CompressInfo *ci = m->compress_info;
797
798 const struct MxOps *ops = ci->child_ops;
799 if (!ops)
800 return -1;
801
802 /* Delegate */
803 return ops->msg_commit(m, msg);
804}
805
809static int comp_msg_close(struct Mailbox *m, struct Message *msg)
810{
811 if (!m->compress_info)
812 return -1;
813
814 struct CompressInfo *ci = m->compress_info;
815
816 const struct MxOps *ops = ci->child_ops;
817 if (!ops)
818 return -1;
819
820 /* Delegate */
821 return ops->msg_close(m, msg);
822}
823
827static int comp_msg_padding_size(struct Mailbox *m)
828{
829 if (!m->compress_info)
830 return 0;
831
832 struct CompressInfo *ci = m->compress_info;
833
834 const struct MxOps *ops = ci->child_ops;
835 if (!ops || !ops->msg_padding_size)
836 return 0;
837
838 return ops->msg_padding_size(m);
839}
840
844static int comp_msg_save_hcache(struct Mailbox *m, struct Email *e)
845{
846 if (!m->compress_info)
847 return 0;
848
849 struct CompressInfo *ci = m->compress_info;
850
851 const struct MxOps *ops = ci->child_ops;
852 if (!ops || !ops->msg_save_hcache)
853 return 0;
854
855 return ops->msg_save_hcache(m, e);
856}
857
861static int comp_tags_edit(struct Mailbox *m, const char *tags, struct Buffer *buf)
862{
863 if (!m->compress_info)
864 return 0;
865
866 struct CompressInfo *ci = m->compress_info;
867
868 const struct MxOps *ops = ci->child_ops;
869 if (!ops || !ops->tags_edit)
870 return 0;
871
872 return ops->tags_edit(m, tags, buf);
873}
874
878static int comp_tags_commit(struct Mailbox *m, struct Email *e, const char *buf)
879{
880 if (!m->compress_info)
881 return 0;
882
883 struct CompressInfo *ci = m->compress_info;
884
885 const struct MxOps *ops = ci->child_ops;
886 if (!ops || !ops->tags_commit)
887 return 0;
888
889 return ops->tags_commit(m, e, buf);
890}
891
895static enum MailboxType comp_path_probe(const char *path, const struct stat *st)
896{
897 if (!st || !S_ISREG(st->st_mode))
898 return MUTT_UNKNOWN;
899
900 if (mutt_comp_can_read(path))
901 return MUTT_COMPRESSED;
902
903 return MUTT_UNKNOWN;
904}
905
909static int comp_path_canon(struct Buffer *path)
910{
911 mutt_path_canon(path, HomeDir, false);
912 return 0;
913}
914
918static int comp_path_pretty(struct Buffer *path, const char *folder)
919{
920 if (mutt_path_abbr_folder(path, folder))
921 return 0;
922
923 if (mutt_path_pretty(path, HomeDir, false))
924 return 0;
925
926 return -1;
927}
928
932static int comp_path_parent(struct Buffer *path)
933{
934 if (mutt_path_parent(path))
935 return 0;
936
937 if (buf_at(path, 0) == '~')
938 mutt_path_canon(path, HomeDir, false);
939
940 if (mutt_path_parent(path))
941 return 0;
942
943 return -1;
944}
945
952const struct MxOps MxCompOps = {
953 // clang-format off
955 .name = "compressed",
956 .is_local = true,
957 .ac_owns_path = comp_ac_owns_path,
958 .ac_add = comp_ac_add,
959 .mbox_open = comp_mbox_open,
960 .mbox_open_append = comp_mbox_open_append,
961 .mbox_check = comp_mbox_check,
962 .mbox_check_stats = NULL,
963 .mbox_sync = comp_mbox_sync,
964 .mbox_close = comp_mbox_close,
965 .msg_open = comp_msg_open,
966 .msg_open_new = comp_msg_open_new,
967 .msg_commit = comp_msg_commit,
968 .msg_close = comp_msg_close,
969 .msg_padding_size = comp_msg_padding_size,
970 .msg_save_hcache = comp_msg_save_hcache,
971 .tags_edit = comp_tags_edit,
972 .tags_commit = comp_tags_commit,
973 .path_probe = comp_path_probe,
974 .path_canon = comp_path_canon,
975 .path_pretty = comp_path_pretty,
976 .path_parent = comp_path_parent,
977 .path_is_empty = NULL,
978 // clang-format on
979};
char buf_at(const struct Buffer *buf, size_t offset)
Return the character at the given offset.
Definition: buffer.c:638
size_t buf_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition: buffer.c:572
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:93
static struct CompressInfo * set_compress_info(struct Mailbox *m)
Find the compress hooks for a mailbox.
Definition: compress.c:202
static void compress_info_free(struct Mailbox *m)
Frees the compress info members and structure.
Definition: compress.c:232
static int setup_paths(struct Mailbox *m)
Set the mailbox paths.
Definition: compress.c:156
void mutt_comp_init(void)
Setup feature commands.
Definition: compress.c:73
static void store_size(const struct Mailbox *m)
Save the size of the compressed file.
Definition: compress.c:184
static bool lock_realpath(struct Mailbox *m, bool excl)
Try to lock the Mailbox.realpath.
Definition: compress.c:89
bool mutt_comp_can_append(struct Mailbox *m)
Can we append to this path?
Definition: compress.c:367
static void unlock_realpath(struct Mailbox *m)
Unlock the mailbox->realpath.
Definition: compress.c:130
static const struct Command CompCommands[]
Compression Commands.
Definition: compress.c:62
static bool execute_command(struct Mailbox *m, const char *command, const char *progress)
Run a system command.
Definition: compress.c:327
int mutt_comp_valid_command(const char *cmd)
Is this command string allowed?
Definition: compress.c:416
static void expand_command_str(const struct Mailbox *m, const char *cmd, char *buf, int buflen)
Expand placeholders in command string.
Definition: compress.c:307
bool mutt_comp_can_read(const char *path)
Can we read from this file?
Definition: compress.c:396
unsigned char cs_subset_enum(const struct ConfigSubset *sub, const char *name)
Get a enumeration config item by name.
Definition: helpers.c:72
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:48
Convenience wrapper for the config headers.
char * HomeDir
User's home directory.
Definition: globals.c:39
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.
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition: curs_lib.c:188
void buf_quote_filename(struct Buffer *buf, const char *filename, bool add_outer)
Quote a filename to survive the shell's quoting rules.
Definition: file.c:936
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:636
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
int mutt_file_lock(int fd, bool excl, bool timeout)
(Try to) Lock a file using fcntl()
Definition: file.c:1243
int mutt_file_unlock(int fd)
Unlock a file previously locked by mutt_file_lock()
Definition: file.c:1290
long mutt_file_get_size(const char *path)
Get the size of a file.
Definition: file.c:1560
Flags to control mutt_expando_format()
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
uint8_t MuttFormatFlags
Flags for mutt_expando_format(), e.g. MUTT_FORMAT_FORCESUBJ.
Definition: format_flags.h:29
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:128
static const char * compress_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Expand the filenames in a command string - Implements format_t -.
Definition: compress.c:255
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t callback, intptr_t data, MuttFormatFlags flags)
Expand expandos (x) in a string -.
Definition: muttlib.c:745
#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:435
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:427
const struct MxOps MxCompOps
Compressed Mailbox - Implements MxOps -.
Definition: compress.c:952
static enum MxStatus comp_mbox_check(struct Mailbox *m)
Check for new mail - Implements MxOps::mbox_check() -.
Definition: compress.c:585
static enum MxStatus comp_mbox_close(struct Mailbox *m)
Close a Mailbox - Implements MxOps::mbox_close() -.
Definition: compress.c:672
static bool comp_mbox_open_append(struct Mailbox *m, OpenMailboxFlags flags)
Open a Mailbox for appending - Implements MxOps::mbox_open_append() -.
Definition: compress.c:505
static enum MxOpenReturns comp_mbox_open(struct Mailbox *m)
Open a Mailbox - Implements MxOps::mbox_open() -.
Definition: compress.c:448
static enum MxStatus comp_mbox_sync(struct Mailbox *m)
Save changes to the Mailbox - Implements MxOps::mbox_sync() -.
Definition: compress.c:621
static int comp_msg_close(struct Mailbox *m, struct Message *msg)
Close an email - Implements MxOps::msg_close() -.
Definition: compress.c:809
static int comp_msg_commit(struct Mailbox *m, struct Message *msg)
Save changes to an email - Implements MxOps::msg_commit() -.
Definition: compress.c:791
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:773
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:755
static int comp_msg_padding_size(struct Mailbox *m)
Bytes of padding between messages - Implements MxOps::msg_padding_size() -.
Definition: compress.c:827
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:844
static int comp_path_canon(struct Buffer *path)
Canonicalise a Mailbox path - Implements MxOps::path_canon() -.
Definition: compress.c:909
static int comp_path_parent(struct Buffer *path)
Find the parent of a Mailbox path - Implements MxOps::path_parent() -.
Definition: compress.c:932
static int comp_path_pretty(struct Buffer *path, const char *folder)
Abbreviate a Mailbox path - Implements MxOps::path_pretty() -.
Definition: compress.c:918
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:895
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:878
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:861
Convenience wrapper for the gui headers.
char * mutt_find_hook(HookFlags type, const char *pat)
Find a matching hook.
Definition: hook.c:636
Parse and execute user-defined hooks.
#define MUTT_OPEN_HOOK
open-hook: to read a compressed mailbox
Definition: hook.h:51
#define MUTT_CLOSE_HOOK
close-hook: write to a compressed mailbox
Definition: hook.h:53
#define MUTT_APPEND_HOOK
append-hook: append to a compressed mailbox
Definition: hook.h:52
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition: mailbox.h:210
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
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define FREE(x)
Definition: memory.h:45
#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:280
bool mutt_path_abbr_folder(struct Buffer *path, const char *folder)
Create a folder abbreviation.
Definition: path.c:494
bool mutt_path_parent(struct Buffer *path)
Find the parent of a path.
Definition: path.c:461
bool mutt_path_pretty(struct Buffer *path, const char *homedir, bool is_dir)
Tidy a filesystem path.
Definition: path.c:188
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:251
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:327
Some miscellaneous functions.
const struct MxOps * mx_get_ops(enum MailboxType type)
Get mailbox operations.
Definition: mx.c:139
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1343
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_snc(), 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:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
Prototypes for many functions.
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:52
void mutt_sig_block(void)
Block signals during critical operations.
Definition: signal.c:163
void mutt_sig_unblock(void)
Restore previously blocked signals.
Definition: signal.c:181
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:37
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
String manipulation buffer.
Definition: buffer.h:34
Private data for compress.
Definition: lib.h:47
const char * cmd_append
append-hook command
Definition: lib.h:48
FILE * fp_lock
fp used for locking
Definition: lib.h:54
const char * cmd_open
open-hook command
Definition: lib.h:50
const struct MxOps * child_ops
callbacks of de-compressed file
Definition: lib.h:52
bool locked
if realpath is locked
Definition: lib.h:53
const char * cmd_close
close-hook command
Definition: lib.h:49
long size
size of the compressed file
Definition: lib.h:51
The envelope/body of an email.
Definition: email.h:37
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:108
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:128
void * compress_info
Compressed mbox module private data.
Definition: mailbox.h:121
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: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:41
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:45
#define buf_mktemp(buf)
Definition: tmp.h:33