/** * comp_mbox_open - Implements MxOps::mbox_open() * * Set up a compressed mailbox to be read. * Decompress the mailbox and set up the paths and hooks needed. * Then determine the type of the mailbox so we can delegate the handling of * messages. */ static int comp_mbox_open(struct Mailbox *m) { if (!m || (m->magic != MUTT_COMPRESSED)) return -1; struct CompressInfo *ci = set_compress_info(m); if (!ci) return -1; /* If there's no close-hook, or the file isn't writable */ if (!ci->cmd_close || (access(m->path, W_OK) != 0)) m->readonly = true; if (setup_paths(m) != 0) goto cmo_fail; store_size(m); if (!lock_realpath(m, false)) { mutt_error(_("Unable to lock mailbox")); goto cmo_fail; } int rc = execute_command(m, ci->cmd_open, _("Decompressing %s")); if (rc == 0) goto cmo_fail; unlock_realpath(m); m->magic = mx_path_probe(m->path, NULL); if (m->magic == MUTT_UNKNOWN) { mutt_error(_("Can't identify the contents of the compressed file")); goto cmo_fail; } ci->child_ops = mx_get_ops(m->magic); if (!ci->child_ops) { mutt_error(_("Can't find mailbox ops for mailbox type %d"), m->magic); goto cmo_fail; } m->account->magic = m->magic; return ci->child_ops->mbox_open(m); cmo_fail: /* remove the partial uncompressed file */ remove(m->path); free_compress_info(m); return -1; }
/** * mbox_test_new_folder - Test if an mbox or mmdf mailbox has new mail * @param path Path to the mailbox * @retval bool true if the folder contains new mail */ bool mbox_test_new_folder(const char *path) { bool rc = false; enum MailboxType magic = mx_path_probe(path, NULL); if ((magic != MUTT_MBOX) && (magic != MUTT_MMDF)) return false; FILE *fp = fopen(path, "rb"); if (fp) { rc = test_last_status_new(fp); mutt_file_fclose(&fp); } return rc; }
/** * comp_mbox_open_append - Implements MxOps::mbox_open_append() * * flags may also contain #MUTT_NEWFOLDER * * To append to a compressed mailbox we need an append-hook (or both open- and * close-hooks). */ static int comp_mbox_open_append(struct Mailbox *m, OpenMailboxFlags flags) { if (!m) return -1; /* If this succeeds, we know there's an open-hook */ struct CompressInfo *ci = set_compress_info(m); if (!ci) return -1; /* To append we need an append-hook or a close-hook */ if (!ci->cmd_append && !ci->cmd_close) { mutt_error(_("Cannot append without an append-hook or close-hook : %s"), m->path); goto cmoa_fail1; } if (setup_paths(m) != 0) goto cmoa_fail2; /* Lock the realpath for the duration of the append. * It will be unlocked in the close */ if (!lock_realpath(m, true)) { mutt_error(_("Unable to lock mailbox")); goto cmoa_fail2; } /* Open the existing mailbox, unless we are appending */ if (!ci->cmd_append && (mutt_file_get_size(m->realpath) > 0)) { int rc = execute_command(m, ci->cmd_open, _("Decompressing %s")); if (rc == 0) { mutt_error(_("Compress command failed: %s"), ci->cmd_open); goto cmoa_fail2; } m->magic = mx_path_probe(m->path, NULL); } else m->magic = C_MboxType; /* We can only deal with mbox and mmdf mailboxes */ if ((m->magic != MUTT_MBOX) && (m->magic != MUTT_MMDF)) { mutt_error(_("Unsupported mailbox type for appending")); goto cmoa_fail2; } ci->child_ops = mx_get_ops(m->magic); if (!ci->child_ops) { mutt_error(_("Can't find mailbox ops for mailbox type %d"), m->magic); goto cmoa_fail2; } if (ci->child_ops->mbox_open_append(m, flags) != 0) goto cmoa_fail2; return 0; cmoa_fail2: /* remove the partial uncompressed file */ remove(m->path); cmoa_fail1: /* Free the compress_info to prevent close from trying to recompress */ free_compress_info(m); return -1; }