NeoMutt  2020-06-26-30-g76c339
Teaching an old dog new tricks
DOXYGEN
compress.c
Go to the documentation of this file.
1 
35 #include "config.h"
36 #include <stdbool.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <sys/stat.h>
40 #include <unistd.h>
41 #include "mutt/lib.h"
42 #include "core/lib.h"
43 #include "gui/lib.h"
44 #include "lib.h"
45 #include "format_flags.h"
46 #include "globals.h"
47 #include "hook.h"
48 #include "muttlib.h"
49 #include "mx.h"
50 #include "protos.h"
51 
52 struct Email;
53 
65 static bool lock_realpath(struct Mailbox *m, bool excl)
66 {
67  if (!m || !m->compress_info)
68  return false;
69 
70  struct CompressInfo *ci = m->compress_info;
71 
72  if (ci->locked)
73  return true;
74 
75  if (excl)
76  ci->fp_lock = fopen(m->realpath, "a");
77  else
78  ci->fp_lock = fopen(m->realpath, "r");
79  if (!ci->fp_lock)
80  {
82  return false;
83  }
84 
85  int r = mutt_file_lock(fileno(ci->fp_lock), excl, true);
86  if (r == 0)
87  ci->locked = true;
88  else if (excl)
89  {
91  m->readonly = true;
92  return true;
93  }
94 
95  return r == 0;
96 }
97 
104 static void unlock_realpath(struct Mailbox *m)
105 {
106  if (!m || !m->compress_info)
107  return;
108 
109  struct CompressInfo *ci = m->compress_info;
110 
111  if (!ci->locked)
112  return;
113 
114  mutt_file_unlock(fileno(ci->fp_lock));
115 
116  ci->locked = false;
118 }
119 
130 static int setup_paths(struct Mailbox *m)
131 {
132  if (!m)
133  return -1;
134 
135  /* Setup the right paths */
137 
138  /* We will uncompress to /tmp */
139  struct Buffer *buf = mutt_buffer_pool_get();
140  mutt_buffer_mktemp(buf);
141  mutt_buffer_copy(&m->pathbuf, buf);
143 
144  FILE *fp = mutt_file_fopen(mailbox_path(m), "w");
145  if (!fp)
146  return -1;
147 
148  mutt_file_fclose(&fp);
149  return 0;
150 }
151 
158 static void store_size(const struct Mailbox *m)
159 {
160  if (!m || !m->compress_info)
161  return;
162 
163  struct CompressInfo *ci = m->compress_info;
164 
165  ci->size = mutt_file_get_size(m->realpath);
166 }
167 
176 static struct CompressInfo *set_compress_info(struct Mailbox *m)
177 {
178  if (!m)
179  return NULL;
180 
181  if (m->compress_info)
182  return m->compress_info;
183 
184  /* Open is compulsory */
185  const char *o = mutt_find_hook(MUTT_OPEN_HOOK, mailbox_path(m));
186  if (!o)
187  return NULL;
188 
189  const char *c = mutt_find_hook(MUTT_CLOSE_HOOK, mailbox_path(m));
190  const char *a = mutt_find_hook(MUTT_APPEND_HOOK, mailbox_path(m));
191 
192  struct CompressInfo *ci = mutt_mem_calloc(1, sizeof(struct CompressInfo));
193  m->compress_info = ci;
194 
195  ci->cmd_open = mutt_str_dup(o);
196  ci->cmd_close = mutt_str_dup(c);
197  ci->cmd_append = mutt_str_dup(a);
198 
199  return ci;
200 }
201 
206 static void compress_info_free(struct Mailbox *m)
207 {
208  if (!m || !m->compress_info)
209  return;
210 
211  struct CompressInfo *ci = m->compress_info;
212  FREE(&ci->cmd_open);
213  FREE(&ci->cmd_close);
214  FREE(&ci->cmd_append);
215 
216  unlock_realpath(m);
217 
218  FREE(&m->compress_info);
219 }
220 
229 static const char *compress_format_str(char *buf, size_t buflen, size_t col, int cols,
230  char op, const char *src, const char *prec,
231  const char *if_str, const char *else_str,
232  intptr_t data, MuttFormatFlags flags)
233 {
234  if (!buf || (data == 0))
235  return src;
236 
237  struct Mailbox *m = (struct Mailbox *) data;
238 
239  /* NOTE the compressed file config vars expect %f and %t to be
240  * surrounded by '' (unlike other NeoMutt config vars, which add the
241  * outer quotes for the user). This is why we use the
242  * mutt_buffer_quote_filename() form with add_outer of false. */
243  struct Buffer *quoted = mutt_buffer_pool_get();
244  switch (op)
245  {
246  case 'f':
247  /* Compressed file */
248  mutt_buffer_quote_filename(quoted, m->realpath, false);
249  snprintf(buf, buflen, "%s", mutt_b2s(quoted));
250  break;
251  case 't':
252  /* Plaintext, temporary file */
253  mutt_buffer_quote_filename(quoted, mailbox_path(m), false);
254  snprintf(buf, buflen, "%s", mutt_b2s(quoted));
255  break;
256  }
257 
258  mutt_buffer_pool_release(&quoted);
259  return src;
260 }
261 
279 static void expand_command_str(const struct Mailbox *m, const char *cmd, char *buf, int buflen)
280 {
281  if (!m || !cmd || !buf)
282  return;
283 
284  mutt_expando_format(buf, buflen, 0, buflen, cmd, compress_format_str,
285  (intptr_t) m, MUTT_FORMAT_NO_FLAGS);
286 }
287 
299 static int execute_command(struct Mailbox *m, const char *command, const char *progress)
300 {
301  if (!m || !command || !progress)
302  return 0;
303 
304  if (m->verbose)
305  mutt_message(progress, m->realpath);
306 
307  int rc = 1;
308  char sys_cmd[STR_COMMAND];
309 
310  mutt_sig_block();
311  endwin();
312  fflush(stdout);
313 
314  expand_command_str(m, command, sys_cmd, sizeof(sys_cmd));
315 
316  if (mutt_system(sys_cmd) != 0)
317  {
318  rc = 0;
320  mutt_error(_("Error running \"%s\""), sys_cmd);
321  }
322 
324 
325  return rc;
326 }
327 
340 {
341  if (!m)
342  return false;
343 
344  /* If this succeeds, we know there's an open-hook */
345  struct CompressInfo *ci = set_compress_info(m);
346  if (!ci)
347  return false;
348 
349  /* We have an open-hook, so to append we need an append-hook,
350  * or a close-hook. */
351  if (ci->cmd_append || ci->cmd_close)
352  return true;
353 
354  mutt_error(_("Can't append without an append-hook or close-hook : %s"), mailbox_path(m));
355  return false;
356 }
357 
368 bool mutt_comp_can_read(const char *path)
369 {
370  if (!path)
371  return false;
372 
373  if (mutt_find_hook(MUTT_OPEN_HOOK, path))
374  return true;
375 
376  return false;
377 }
378 
388 int mutt_comp_valid_command(const char *cmd)
389 {
390  if (!cmd)
391  return 0;
392 
393  return strstr(cmd, "%f") && strstr(cmd, "%t");
394 }
395 
399 static struct Account *comp_ac_find(struct Account *a, const char *path)
400 {
401  return NULL;
402 }
403 
407 static int comp_ac_add(struct Account *a, struct Mailbox *m)
408 {
409  if (!a || !m || (m->type != MUTT_COMPRESSED))
410  return -1;
411  return 0;
412 }
413 
422 static int comp_mbox_open(struct Mailbox *m)
423 {
424  if (!m || (m->type != MUTT_COMPRESSED))
425  return -1;
426 
427  struct CompressInfo *ci = set_compress_info(m);
428  if (!ci)
429  return -1;
430 
431  int rc;
432 
433  /* If there's no close-hook, or the file isn't writable */
434  if (!ci->cmd_close || (access(mailbox_path(m), W_OK) != 0))
435  m->readonly = true;
436 
437  if (setup_paths(m) != 0)
438  goto cmo_fail;
439  store_size(m);
440 
441  if (!lock_realpath(m, false))
442  {
443  mutt_error(_("Unable to lock mailbox"));
444  goto cmo_fail;
445  }
446 
447  rc = execute_command(m, ci->cmd_open, _("Decompressing %s"));
448  if (rc == 0)
449  goto cmo_fail;
450 
451  unlock_realpath(m);
452 
454  if (m->type == MUTT_UNKNOWN)
455  {
456  mutt_error(_("Can't identify the contents of the compressed file"));
457  goto cmo_fail;
458  }
459 
460  ci->child_ops = mx_get_ops(m->type);
461  if (!ci->child_ops)
462  {
463  mutt_error(_("Can't find mailbox ops for mailbox type %d"), m->type);
464  goto cmo_fail;
465  }
466 
467  m->account->type = m->type;
468  return ci->child_ops->mbox_open(m);
469 
470 cmo_fail:
471  /* remove the partial uncompressed file */
472  remove(mailbox_path(m));
474  return -1;
475 }
476 
485 static int comp_mbox_open_append(struct Mailbox *m, OpenMailboxFlags flags)
486 {
487  if (!m)
488  return -1;
489 
490  /* If this succeeds, we know there's an open-hook */
491  struct CompressInfo *ci = set_compress_info(m);
492  if (!ci)
493  return -1;
494 
495  /* To append we need an append-hook or a close-hook */
496  if (!ci->cmd_append && !ci->cmd_close)
497  {
498  mutt_error(_("Can't append without an append-hook or close-hook : %s"),
499  mailbox_path(m));
500  goto cmoa_fail1;
501  }
502 
503  if (setup_paths(m) != 0)
504  goto cmoa_fail2;
505 
506  /* Lock the realpath for the duration of the append.
507  * It will be unlocked in the close */
508  if (!lock_realpath(m, true))
509  {
510  mutt_error(_("Unable to lock mailbox"));
511  goto cmoa_fail2;
512  }
513 
514  /* Open the existing mailbox, unless we are appending */
515  if (!ci->cmd_append && (mutt_file_get_size(m->realpath) > 0))
516  {
517  int rc = execute_command(m, ci->cmd_open, _("Decompressing %s"));
518  if (rc == 0)
519  {
520  mutt_error(_("Compress command failed: %s"), ci->cmd_open);
521  goto cmoa_fail2;
522  }
524  }
525  else
526  m->type = C_MboxType;
527 
528  /* We can only deal with mbox and mmdf mailboxes */
529  if ((m->type != MUTT_MBOX) && (m->type != MUTT_MMDF))
530  {
531  mutt_error(_("Unsupported mailbox type for appending"));
532  goto cmoa_fail2;
533  }
534 
535  ci->child_ops = mx_get_ops(m->type);
536  if (!ci->child_ops)
537  {
538  mutt_error(_("Can't find mailbox ops for mailbox type %d"), m->type);
539  goto cmoa_fail2;
540  }
541 
542  if (ci->child_ops->mbox_open_append(m, flags) != 0)
543  goto cmoa_fail2;
544 
545  return 0;
546 
547 cmoa_fail2:
548  /* remove the partial uncompressed file */
549  remove(mailbox_path(m));
550 cmoa_fail1:
551  /* Free the compress_info to prevent close from trying to recompress */
553 
554  return -1;
555 }
556 
572 static int comp_mbox_check(struct Mailbox *m, int *index_hint)
573 {
574  if (!m || !m->compress_info)
575  return -1;
576 
577  struct CompressInfo *ci = m->compress_info;
578 
579  const struct MxOps *ops = ci->child_ops;
580  if (!ops)
581  return -1;
582 
583  int size = mutt_file_get_size(m->realpath);
584  if (size == ci->size)
585  return 0;
586 
587  if (!lock_realpath(m, false))
588  {
589  mutt_error(_("Unable to lock mailbox"));
590  return -1;
591  }
592 
593  int rc = execute_command(m, ci->cmd_open, _("Decompressing %s"));
594  store_size(m);
595  unlock_realpath(m);
596  if (rc == 0)
597  return -1;
598 
599  return ops->mbox_check(m, index_hint);
600 }
601 
608 static int comp_mbox_sync(struct Mailbox *m, int *index_hint)
609 {
610  if (!m || !m->compress_info)
611  return -1;
612 
613  struct CompressInfo *ci = m->compress_info;
614 
615  if (!ci->cmd_close)
616  {
617  mutt_error(_("Can't sync a compressed file without a close-hook"));
618  return -1;
619  }
620 
621  const struct MxOps *ops = ci->child_ops;
622  if (!ops)
623  return -1;
624 
625  if (!lock_realpath(m, true))
626  {
627  mutt_error(_("Unable to lock mailbox"));
628  return -1;
629  }
630 
631  int rc = comp_mbox_check(m, index_hint);
632  if (rc != 0)
633  goto sync_cleanup;
634 
635  rc = ops->mbox_sync(m, index_hint);
636  if (rc != 0)
637  goto sync_cleanup;
638 
639  rc = execute_command(m, ci->cmd_close, _("Compressing %s"));
640  if (rc == 0)
641  {
642  rc = -1;
643  goto sync_cleanup;
644  }
645 
646  rc = 0;
647 
648 sync_cleanup:
649  store_size(m);
650  unlock_realpath(m);
651  return rc;
652 }
653 
660 static int comp_mbox_close(struct Mailbox *m)
661 {
662  if (!m || !m->compress_info)
663  return -1;
664 
665  struct CompressInfo *ci = m->compress_info;
666 
667  const struct MxOps *ops = ci->child_ops;
668  if (!ops)
669  {
671  return -1;
672  }
673 
674  ops->mbox_close(m);
675 
676  /* sync has already been called, so we only need to delete some files */
677  if (m->append)
678  {
679  const char *append = NULL;
680  const char *msg = NULL;
681 
682  /* The file exists and we can append */
683  if ((access(m->realpath, F_OK) == 0) && ci->cmd_append)
684  {
685  append = ci->cmd_append;
686  msg = _("Compressed-appending to %s...");
687  }
688  else
689  {
690  append = ci->cmd_close;
691  msg = _("Compressing %s");
692  }
693 
694  int rc = execute_command(m, append, msg);
695  if (rc == 0)
696  {
698  mutt_error(_("Error. Preserving temporary file: %s"), mailbox_path(m));
699  }
700  else
701  remove(mailbox_path(m));
702 
703  unlock_realpath(m);
704  }
705  else
706  {
707  /* If the file was removed, remove the compressed folder too */
708  if ((access(mailbox_path(m), F_OK) != 0) && !C_SaveEmpty)
709  {
710  remove(m->realpath);
711  }
712  else
713  {
714  remove(mailbox_path(m));
715  }
716  }
717 
719 
720  return 0;
721 }
722 
726 static int comp_msg_open(struct Mailbox *m, struct Message *msg, int msgno)
727 {
728  if (!m || !m->compress_info)
729  return -1;
730 
731  struct CompressInfo *ci = m->compress_info;
732 
733  const struct MxOps *ops = ci->child_ops;
734  if (!ops)
735  return -1;
736 
737  /* Delegate */
738  return ops->msg_open(m, msg, msgno);
739 }
740 
744 static int comp_msg_open_new(struct Mailbox *m, struct Message *msg, struct Email *e)
745 {
746  if (!m || !m->compress_info)
747  return -1;
748 
749  struct CompressInfo *ci = m->compress_info;
750 
751  const struct MxOps *ops = ci->child_ops;
752  if (!ops)
753  return -1;
754 
755  /* Delegate */
756  return ops->msg_open_new(m, msg, e);
757 }
758 
762 static int comp_msg_commit(struct Mailbox *m, struct Message *msg)
763 {
764  if (!m || !m->compress_info)
765  return -1;
766 
767  struct CompressInfo *ci = m->compress_info;
768 
769  const struct MxOps *ops = ci->child_ops;
770  if (!ops)
771  return -1;
772 
773  /* Delegate */
774  return ops->msg_commit(m, msg);
775 }
776 
780 static int comp_msg_close(struct Mailbox *m, struct Message *msg)
781 {
782  if (!m || !m->compress_info)
783  return -1;
784 
785  struct CompressInfo *ci = m->compress_info;
786 
787  const struct MxOps *ops = ci->child_ops;
788  if (!ops)
789  return -1;
790 
791  /* Delegate */
792  return ops->msg_close(m, msg);
793 }
794 
798 static int comp_msg_padding_size(struct Mailbox *m)
799 {
800  if (!m || !m->compress_info)
801  return 0;
802 
803  struct CompressInfo *ci = m->compress_info;
804 
805  const struct MxOps *ops = ci->child_ops;
806  if (!ops || !ops->msg_padding_size)
807  return 0;
808 
809  return ops->msg_padding_size(m);
810 }
811 
815 static int comp_msg_save_hcache(struct Mailbox *m, struct Email *e)
816 {
817  if (!m || !m->compress_info)
818  return 0;
819 
820  struct CompressInfo *ci = m->compress_info;
821 
822  const struct MxOps *ops = ci->child_ops;
823  if (!ops || !ops->msg_save_hcache)
824  return 0;
825 
826  return ops->msg_save_hcache(m, e);
827 }
828 
832 static int comp_tags_edit(struct Mailbox *m, const char *tags, char *buf, size_t buflen)
833 {
834  if (!m || !m->compress_info)
835  return 0;
836 
837  struct CompressInfo *ci = m->compress_info;
838 
839  const struct MxOps *ops = ci->child_ops;
840  if (!ops || !ops->tags_edit)
841  return 0;
842 
843  return ops->tags_edit(m, tags, buf, buflen);
844 }
845 
849 static int comp_tags_commit(struct Mailbox *m, struct Email *e, char *buf)
850 {
851  if (!m || !m->compress_info)
852  return 0;
853 
854  struct CompressInfo *ci = m->compress_info;
855 
856  const struct MxOps *ops = ci->child_ops;
857  if (!ops || !ops->tags_commit)
858  return 0;
859 
860  return ops->tags_commit(m, e, buf);
861 }
862 
866 static enum MailboxType comp_path_probe(const char *path, const struct stat *st)
867 {
868  if (!path)
869  return MUTT_UNKNOWN;
870 
871  if (!st || !S_ISREG(st->st_mode))
872  return MUTT_UNKNOWN;
873 
874  if (mutt_comp_can_read(path))
875  return MUTT_COMPRESSED;
876 
877  return MUTT_UNKNOWN;
878 }
879 
883 static int comp_path_canon(char *buf, size_t buflen)
884 {
885  if (!buf)
886  return -1;
887 
888  mutt_path_canon(buf, buflen, HomeDir, false);
889  return 0;
890 }
891 
895 static int comp_path_pretty(char *buf, size_t buflen, const char *folder)
896 {
897  if (!buf)
898  return -1;
899 
900  if (mutt_path_abbr_folder(buf, buflen, folder))
901  return 0;
902 
903  if (mutt_path_pretty(buf, buflen, HomeDir, false))
904  return 0;
905 
906  return -1;
907 }
908 
912 static int comp_path_parent(char *buf, size_t buflen)
913 {
914  if (!buf)
915  return -1;
916 
917  if (mutt_path_parent(buf, buflen))
918  return 0;
919 
920  if (buf[0] == '~')
921  mutt_path_canon(buf, buflen, HomeDir, false);
922 
923  if (mutt_path_parent(buf, buflen))
924  return 0;
925 
926  return -1;
927 }
928 
929 // clang-format off
936 struct MxOps MxCompOps = {
938  .name = "compressed",
939  .is_local = true,
940  .ac_find = comp_ac_find,
941  .ac_add = comp_ac_add,
942  .mbox_open = comp_mbox_open,
943  .mbox_open_append = comp_mbox_open_append,
944  .mbox_check = comp_mbox_check,
945  .mbox_check_stats = NULL,
946  .mbox_sync = comp_mbox_sync,
947  .mbox_close = comp_mbox_close,
948  .msg_open = comp_msg_open,
949  .msg_open_new = comp_msg_open_new,
950  .msg_commit = comp_msg_commit,
951  .msg_close = comp_msg_close,
952  .msg_padding_size = comp_msg_padding_size,
953  .msg_save_hcache = comp_msg_save_hcache,
954  .tags_edit = comp_tags_edit,
955  .tags_commit = comp_tags_commit,
956  .path_probe = comp_path_probe,
957  .path_canon = comp_path_canon,
958  .path_pretty = comp_path_pretty,
959  .path_parent = comp_path_parent,
960 };
961 // clang-format on
Convenience wrapper for the gui headers.
void mutt_buffer_quote_filename(struct Buffer *buf, const char *filename, bool add_outer)
Quote a filename to survive the shell&#39;s quoting rules.
Definition: file.c:836
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:194
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:81
int(* msg_commit)(struct Mailbox *m, struct Message *msg)
Save changes to an email.
Definition: mx.h:210
static int comp_mbox_check(struct Mailbox *m, int *index_hint)
Check for new mail - Implements MxOps::mbox_check()
Definition: compress.c:572
void mutt_sig_unblock(void)
Restore previously blocked signals.
Definition: signal.c:168
const struct MxOps * mx_get_ops(enum MailboxType type)
Get mailbox operations.
Definition: mx.c:142
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
uint8_t MuttFormatFlags
Flags for mutt_expando_format(), e.g. MUTT_FORMAT_FORCESUBJ.
Definition: format_flags.h:29
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
const char * cmd_append
append-hook command
Definition: lib.h:50
The envelope/body of an email.
Definition: email.h:37
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
static void compress_info_free(struct Mailbox *m)
Frees the compress info members and structure.
Definition: compress.c:206
#define mutt_perror(...)
Definition: logging.h:85
long mutt_file_get_size(const char *path)
Get the size of a file.
Definition: file.c:1488
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer&#39;s contents to another Buffer.
Definition: buffer.c:445
static int comp_mbox_open(struct Mailbox *m)
Open a Mailbox - Implements MxOps::mbox_open()
Definition: compress.c:422
int(* mbox_sync)(struct Mailbox *m, int *index_hint)
Save changes to the Mailbox.
Definition: mx.h:173
bool mutt_path_parent(char *buf, size_t buflen)
Find the parent of a path.
Definition: path.c:459
#define mutt_message(...)
Definition: logging.h:83
FILE * fp_lock
fp used for locking
Definition: lib.h:56
static int comp_ac_add(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account - Implements MxOps::ac_add()
Definition: compress.c:407
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
A group of associated Mailboxes.
Definition: account.h:36
String manipulation buffer.
Definition: buffer.h:33
WHERE bool C_SaveEmpty
Config: (mbox,mmdf) Preserve empty mailboxes.
Definition: globals.h:241
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:815
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
#define _(a)
Definition: message.h:28
Mailbox wasn&#39;t recognised.
Definition: mailbox.h:47
static int comp_path_parent(char *buf, size_t buflen)
Find the parent of a Mailbox path - Implements MxOps::path_parent()
Definition: compress.c:912
static int comp_path_pretty(char *buf, size_t buflen, const char *folder)
Abbreviate a Mailbox path - Implements MxOps::path_pretty()
Definition: compress.c:895
uint8_t OpenMailboxFlags
Flags for mutt_open_mailbox(), e.g. MUTT_NOSORT.
Definition: mx.h:51
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
long size
size of the compressed file
Definition: lib.h:53
bool locked
if realpath is locked
Definition: lib.h:55
static struct Account * comp_ac_find(struct Account *a, const char *path)
Find an Account that matches a Mailbox path - Implements MxOps::ac_find()
Definition: compress.c:399
Flags to control mutt_expando_format()
int mutt_file_unlock(int fd)
Unlock a file previously locked by mutt_file_lock()
Definition: file.c:1216
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
static int comp_mbox_open_append(struct Mailbox *m, OpenMailboxFlags flags)
Open a Mailbox for appending - Implements MxOps::mbox_open_append()
Definition: compress.c:485
Hundreds of global variables to back the user variables.
bool mutt_path_pretty(char *buf, size_t buflen, const char *homedir, bool is_dir)
Tidy a filesystem path.
Definition: path.c:186
char * HomeDir
User&#39;s home directory.
Definition: globals.h:50
int(* msg_open_new)(struct Mailbox *m, struct Message *msg, struct Email *e)
Open a new message in a Mailbox.
Definition: mx.h:201
int(* mbox_open)(struct Mailbox *m)
Open a Mailbox.
Definition: mx.h:136
int(* mbox_open_append)(struct Mailbox *m, OpenMailboxFlags flags)
Open a Mailbox for appending.
Definition: mx.h:145
Some miscellaneous functions.
const char * cmd_close
close-hook command
Definition: lib.h:51
static int comp_tags_edit(struct Mailbox *m, const char *tags, char *buf, size_t buflen)
Prompt and validate new messages tags - Implements MxOps::tags_edit()
Definition: compress.c:832
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:862
Parse and execute user-defined hooks.
static void store_size(const struct Mailbox *m)
Save the size of the compressed file.
Definition: compress.c:158
int mutt_file_lock(int fd, bool excl, bool timeout)
(try to) lock a file using fcntl()
Definition: file.c:1168
API for mailboxes.
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:119
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
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:866
static struct CompressInfo * set_compress_info(struct Mailbox *m)
Find the compress hooks for a mailbox.
Definition: compress.c:176
Convenience wrapper for the core headers.
Compressed mbox local mailbox type.
static int comp_msg_padding_size(struct Mailbox *m)
Bytes of padding between messages - Implements MxOps::msg_padding_size()
Definition: compress.c:798
int(* msg_padding_size)(struct Mailbox *m)
Bytes of padding between messages.
Definition: mx.h:226
static int comp_path_canon(char *buf, size_t buflen)
Canonicalise a Mailbox path - Implements MxOps::path_canon()
Definition: compress.c:883
#define MUTT_APPEND_HOOK
append-hook: append to a compressed mailbox
Definition: hook.h:59
enum MailboxType type
Mailbox type, e.g. MUTT_IMAP.
Definition: mx.h:107
#define mutt_b2s(buf)
Definition: buffer.h:41
Prototypes for many functions.
int(* tags_edit)(struct Mailbox *m, const char *tags, char *buf, size_t buflen)
Prompt and validate new messages tags.
Definition: mx.h:247
A local copy of an email.
Definition: mx.h:83
A mailbox.
Definition: mailbox.h:81
char * mutt_find_hook(HookFlags type, const char *pat)
Find a matching hook.
Definition: hook.c:552
static int comp_tags_commit(struct Mailbox *m, struct Email *e, char *buf)
Save the tags to a message - Implements MxOps::tags_commit()
Definition: compress.c:849
#define MUTT_CLOSE_HOOK
close-hook: write to a compressed mailbox
Definition: hook.h:60
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:229
int(* msg_save_hcache)(struct Mailbox *m, struct Email *e)
Save message to the header cache.
Definition: mx.h:235
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
int(* msg_open)(struct Mailbox *m, struct Message *msg, int msgno)
Open an email message in a Mailbox.
Definition: mx.h:191
int mutt_comp_valid_command(const char *cmd)
Is this command string allowed?
Definition: compress.c:388
int(* mbox_check)(struct Mailbox *m, int *index_hint)
Check for new mail.
Definition: mx.h:154
Compressed file Mailbox type.
Definition: mailbox.h:56
bool append
Mailbox is opened in append mode.
Definition: mailbox.h:113
bool verbose
Display status messages?
Definition: mailbox.h:118
unsigned char C_MboxType
Config: Default type for creating new mailboxes.
Definition: mx.c:85
static int comp_mbox_sync(struct Mailbox *m, int *index_hint)
Save changes to the Mailbox - Implements MxOps::mbox_sync()
Definition: compress.c:608
static void unlock_realpath(struct Mailbox *m)
Unlock the mailbox->realpath.
Definition: compress.c:104
#define MUTT_OPEN_HOOK
open-hook: to read a compressed mailbox
Definition: hook.h:58
bool mutt_path_abbr_folder(char *buf, size_t buflen, const char *folder)
Create a folder abbreviation.
Definition: path.c:492
Private data for compress.
Definition: lib.h:48
static int execute_command(struct Mailbox *m, const char *command, const char *progress)
Run a system command.
Definition: compress.c:299
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:450
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:48
#define STR_COMMAND
Enough space for a long command line.
Definition: string2.h:35
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:579
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1328
bool mutt_path_canon(char *buf, size_t buflen, const char *homedir, bool is_dir)
Create the canonical version of a path.
Definition: path.c:285
MailboxType
Supported mailbox formats.
Definition: mailbox.h:43
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
static int comp_msg_open(struct Mailbox *m, struct Message *msg, int msgno)
Open an email message in a Mailbox - Implements MxOps::msg_open()
Definition: compress.c:726
int(* mbox_close)(struct Mailbox *m)
Close a Mailbox.
Definition: mx.h:181
#define mutt_error(...)
Definition: logging.h:84
bool mutt_comp_can_read(const char *path)
Can we read from this file?
Definition: compress.c:368
void * compress_info
Compressed mbox module private data.
Definition: mailbox.h:124
static int comp_msg_commit(struct Mailbox *m, struct Message *msg)
Save changes to an email - Implements MxOps::msg_commit()
Definition: compress.c:762
#define FREE(x)
Definition: memory.h:40
int(* msg_close)(struct Mailbox *m, struct Message *msg)
Close an email.
Definition: mx.h:219
static bool lock_realpath(struct Mailbox *m, bool excl)
Try to lock the ctx->realpath.
Definition: compress.c:65
const struct MxOps * child_ops
callbacks of de-compressed file
Definition: lib.h:54
static int comp_msg_close(struct Mailbox *m, struct Message *msg)
Close an email - Implements MxOps::msg_close()
Definition: compress.c:780
struct Buffer pathbuf
Definition: mailbox.h:83
Convenience wrapper for the library headers.
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
static int comp_mbox_close(struct Mailbox *m)
Close a Mailbox - Implements MxOps::mbox_close()
Definition: compress.c:660
void mutt_sig_block(void)
Block signals during critical operations.
Definition: signal.c:150
const char * cmd_open
open-hook command
Definition: lib.h:52
static void expand_command_str(const struct Mailbox *m, const char *cmd, char *buf, int buflen)
Expand placeholders in command string.
Definition: compress.c:279
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
bool mutt_comp_can_append(struct Mailbox *m)
Can we append to this path?
Definition: compress.c:339
The Mailbox API.
Definition: mx.h:105
static int comp_msg_open_new(struct Mailbox *m, struct Message *msg, struct Email *e)
Open a new message in a Mailbox - Implements MxOps::msg_open_new()
Definition: compress.c:744
int(* tags_commit)(struct Mailbox *m, struct Email *e, char *buf)
Save the tags to a message.
Definition: mx.h:257
static int setup_paths(struct Mailbox *m)
Set the mailbox paths.
Definition: compress.c:130