]> granicus.if.org Git - neomutt/blobdiff - editmsg.c
merge: light refactoring
[neomutt] / editmsg.c
index 878ed91b629f00b5ecd3465d8c93ab88f80cada4..cdd7e1fa86a60efdee41497e15d016fa2cc633ef 100644 (file)
--- a/editmsg.c
+++ b/editmsg.c
 #include <time.h>
 #include <unistd.h>
 #include "mutt/mutt.h"
+#include "email/lib.h"
+#include "core/lib.h"
 #include "mutt.h"
 #include "context.h"
 #include "copy.h"
+#include "curs_lib.h"
 #include "globals.h"
-#include "header.h"
-#include "mailbox.h"
+#include "muttlib.h"
 #include "mx.h"
-#include "options.h"
 #include "protos.h"
 
 /**
- * edit_or_view_one_message - Edit an email or view it in an external editor
- * @param edit true if the message should be editable. If false, changes
- *            to the message (in the editor) will be ignored.
- * @param ctx Context
- * @param cur Header of email
- * @retval 1  Message not modified
- * @retval 0  Message edited successfully
+ * ev_message - Edit an email or view it in an external editor
+ * @param action Action to perform, e.g. #EVM_EDIT
+ * @param m      Mailbox
+ * @param e      Email
+ * @retval  1 Message not modified
+ * @retval  0 Message edited successfully
  * @retval -1 Error
  */
-static int edit_or_view_one_message(bool edit, struct Context *ctx, struct Header *cur)
+static int ev_message(enum EvMessage action, struct Mailbox *m, struct Email *e)
 {
-  char tmp[_POSIX_PATH_MAX];
-  char buf[STRING];
-  int omagic;
-  int oerrno;
+  char buf[256];
   int rc;
-
-  bool o_read;
-  bool o_old;
-
-  int of, cf;
-
-  struct Context tmpctx;
-  struct Message *msg = NULL;
-
   FILE *fp = NULL;
-
   struct stat sb;
-  time_t mtime = 0;
+  bool old_append = m->append;
 
-  mutt_mktemp(tmp, sizeof(tmp));
+  struct Buffer *fname = mutt_buffer_pool_get();
+  mutt_buffer_mktemp(fname);
 
-  omagic = MboxType;
-  MboxType = MUTT_MBOX;
+  enum MailboxType omagic = C_MboxType;
+  C_MboxType = MUTT_MBOX;
 
-  rc = (mx_open_mailbox(tmp, MUTT_NEWFOLDER, &tmpctx) == NULL) ? -1 : 0;
+  struct Mailbox *m_fname = mx_path_resolve(mutt_b2s(fname));
+  struct Context *ctx_tmp = mx_mbox_open(m_fname, MUTT_NEWFOLDER);
 
-  MboxType = omagic;
+  C_MboxType = omagic;
 
-  if (rc == -1)
+  if (!ctx_tmp)
   {
     mutt_error(_("could not create temporary folder: %s"), strerror(errno));
+    mutt_buffer_pool_release(&fname);
+    mailbox_free(&m_fname);
     return -1;
   }
 
-  rc = mutt_append_message(
-      &tmpctx, ctx, cur, 0,
-      CH_NOLEN | ((ctx->magic == MUTT_MBOX || ctx->magic == MUTT_MMDF) ? 0 : CH_NOSTATUS));
-  oerrno = errno;
+  const CopyHeaderFlags chflags =
+      CH_NOLEN |
+      (((m->magic == MUTT_MBOX) || (m->magic == MUTT_MMDF)) ? CH_NO_FLAGS : CH_NOSTATUS);
+  rc = mutt_append_message(ctx_tmp->mailbox, m, e, MUTT_CM_NO_FLAGS, chflags);
+  int oerrno = errno;
 
-  mx_close_mailbox(&tmpctx, NULL);
+  mx_mbox_close(&ctx_tmp);
 
   if (rc == -1)
   {
@@ -105,10 +97,10 @@ static int edit_or_view_one_message(bool edit, struct Context *ctx, struct Heade
     goto bail;
   }
 
-  rc = stat(tmp, &sb);
+  rc = stat(mutt_b2s(fname), &sb);
   if (rc == -1)
   {
-    mutt_error(_("Can't stat %s: %s"), tmp, strerror(errno));
+    mutt_error(_("Can't stat %s: %s"), mutt_b2s(fname), strerror(errno));
     goto bail;
   }
 
@@ -116,67 +108,67 @@ static int edit_or_view_one_message(bool edit, struct Context *ctx, struct Heade
    * truncate the last newline in the temp file, which is logically part of
    * the message separator, and not the body of the message.  If we fail to
    * remove it, the message will grow by one line each time the user edits
-   * the message.
-   */
-  if (sb.st_size != 0 && truncate(tmp, sb.st_size - 1) == -1)
+   * the message.  */
+  if ((sb.st_size != 0) && (truncate(mutt_b2s(fname), sb.st_size - 1) == -1))
   {
     mutt_error(_("could not truncate temporary mail folder: %s"), strerror(errno));
     goto bail;
   }
 
-  if (!edit)
+  if (action == EVM_VIEW)
   {
     /* remove write permissions */
-    rc = mutt_file_chmod_rm_stat(tmp, S_IWUSR | S_IWGRP | S_IWOTH, &sb);
+    rc = mutt_file_chmod_rm_stat(mutt_b2s(fname), S_IWUSR | S_IWGRP | S_IWOTH, &sb);
     if (rc == -1)
     {
-      mutt_debug(1, "Could not remove write permissions of %s: %s", tmp, strerror(errno));
+      mutt_debug(LL_DEBUG1, "Could not remove write permissions of %s: %s",
+                 mutt_b2s(fname), strerror(errno));
       /* Do not bail out here as we are checking afterwards if we should adopt
        * changes of the temporary file. */
     }
   }
 
   /* Do not reuse the stat sb here as it is outdated. */
-  mtime = mutt_file_decrease_mtime(tmp, NULL);
+  time_t mtime = mutt_file_decrease_mtime(mutt_b2s(fname), NULL);
 
-  mutt_edit_file(NONULL(Editor), tmp);
+  mutt_edit_file(NONULL(C_Editor), mutt_b2s(fname));
 
-  rc = stat(tmp, &sb);
+  rc = stat(mutt_b2s(fname), &sb);
   if (rc == -1)
   {
-    mutt_error(_("Can't stat %s: %s"), tmp, strerror(errno));
+    mutt_error(_("Can't stat %s: %s"), mutt_b2s(fname), strerror(errno));
     goto bail;
   }
 
   if (sb.st_size == 0)
   {
-    mutt_message(_("Message file is empty!"));
+    mutt_message(_("Message file is empty"));
     rc = 1;
     goto bail;
   }
 
-  if (edit && sb.st_mtime == mtime)
+  if ((action == EVM_EDIT) && (sb.st_mtime == mtime))
   {
-    mutt_message(_("Message not modified!"));
+    mutt_message(_("Message not modified"));
     rc = 1;
     goto bail;
   }
 
-  if (!edit && sb.st_mtime != mtime)
+  if ((action == EVM_VIEW) && (sb.st_mtime != mtime))
   {
     mutt_message(_("Message of read-only mailbox modified! Ignoring changes."));
     rc = 1;
     goto bail;
   }
 
-  if (!edit)
+  if (action == EVM_VIEW)
   {
     /* stop processing here and skip right to the end */
     rc = 1;
     goto bail;
   }
 
-  fp = fopen(tmp, "r");
+  fp = fopen(mutt_b2s(fname), "r");
   if (!fp)
   {
     rc = -1;
@@ -184,7 +176,8 @@ static int edit_or_view_one_message(bool edit, struct Context *ctx, struct Heade
     goto bail;
   }
 
-  if (mx_open_mailbox(ctx->path, MUTT_APPEND, &tmpctx) == NULL)
+  struct Context *ctx_app = mx_mbox_open(m, MUTT_APPEND | MUTT_QUIET);
+  if (!ctx_app)
   {
     rc = -1;
     /* L10N: %s is from strerror(errno) */
@@ -192,12 +185,15 @@ static int edit_or_view_one_message(bool edit, struct Context *ctx, struct Heade
     goto bail;
   }
 
-  of = 0;
-  cf = ((tmpctx.magic == MUTT_MBOX || tmpctx.magic == MUTT_MMDF) ? 0 : CH_NOSTATUS);
+  MsgOpenFlags of = MUTT_MSG_NO_FLAGS;
+  CopyHeaderFlags cf =
+      (((ctx_app->mailbox->magic == MUTT_MBOX) || (ctx_app->mailbox->magic == MUTT_MMDF)) ?
+           CH_NO_FLAGS :
+           CH_NOSTATUS);
 
   if (fgets(buf, sizeof(buf), fp) && is_from(buf, NULL, 0, NULL))
   {
-    if (tmpctx.magic == MUTT_MBOX || tmpctx.magic == MUTT_MMDF)
+    if ((ctx_app->mailbox->magic == MUTT_MBOX) || (ctx_app->mailbox->magic == MUTT_MMDF))
       cf = CH_FROM | CH_FORCE_FROM;
   }
   else
@@ -206,77 +202,74 @@ static int edit_or_view_one_message(bool edit, struct Context *ctx, struct Heade
   /* XXX - we have to play games with the message flags to avoid
    * problematic behavior with maildir folders.  */
 
-  o_read = cur->read;
-  o_old = cur->old;
-  cur->read = cur->old = false;
-  msg = mx_open_new_message(&tmpctx, cur, of);
-  cur->read = o_read;
-  cur->old = o_old;
+  bool o_read = e->read;
+  bool o_old = e->old;
+  e->read = false;
+  e->old = false;
+  struct Message *msg = mx_msg_open_new(ctx_app->mailbox, e, of);
+  e->read = o_read;
+  e->old = o_old;
 
   if (!msg)
   {
     mutt_error(_("Can't append to folder: %s"), strerror(errno));
-    mx_close_mailbox(&tmpctx, NULL);
+    mx_mbox_close(&ctx_app);
     goto bail;
   }
 
-  rc = mutt_copy_hdr(fp, msg->fp, 0, sb.st_size, CH_NOLEN | cf, NULL);
+  rc = mutt_copy_hdr(fp, msg->fp, 0, sb.st_size, CH_NOLEN | cf, NULL, 0);
   if (rc == 0)
   {
     fputc('\n', msg->fp);
     mutt_file_copy_stream(fp, msg->fp);
   }
 
-  rc = mx_commit_message(msg, &tmpctx);
-  mx_close_message(&tmpctx, &msg);
+  rc = mx_msg_commit(ctx_app->mailbox, msg);
+  mx_msg_close(ctx_app->mailbox, &msg);
 
-  mx_close_mailbox(&tmpctx, NULL);
+  mx_mbox_close(&ctx_app);
 
 bail:
-  if (fp)
-    mutt_file_fclose(&fp);
+  mutt_file_fclose(&fp);
 
   if (rc >= 0)
-    unlink(tmp);
+    unlink(mutt_b2s(fname));
 
   if (rc == 0)
   {
-    mutt_set_flag(Context, cur, MUTT_DELETE, 1);
-    mutt_set_flag(Context, cur, MUTT_PURGE, 1);
-    mutt_set_flag(Context, cur, MUTT_READ, 1);
+    mutt_set_flag(m, e, MUTT_DELETE, true);
+    mutt_set_flag(m, e, MUTT_PURGE, true);
+    mutt_set_flag(m, e, MUTT_READ, true);
 
-    if (DeleteUntag)
-      mutt_set_flag(Context, cur, MUTT_TAG, 0);
+    if (C_DeleteUntag)
+      mutt_set_flag(m, e, MUTT_TAG, false);
   }
   else if (rc == -1)
-    mutt_message(_("Error. Preserving temporary file: %s"), tmp);
+    mutt_message(_("Error. Preserving temporary file: %s"), mutt_b2s(fname));
+
+  m->append = old_append;
 
+  mutt_buffer_pool_release(&fname);
   return rc;
 }
 
-int edit_or_view_message(bool edit, struct Context *ctx, struct Header *hdr)
+/**
+ * mutt_ev_message - Edit or view a message
+ * @param m      Mailbox
+ * @param el     List of Emails
+ * @param action Action to perform, e.g. #EVM_EDIT
+ * @retval 1  Message not modified
+ * @retval 0  Message edited successfully
+ * @retval -1 Error
+ */
+int mutt_ev_message(struct Mailbox *m, struct EmailList *el, enum EvMessage action)
 {
-  if (hdr)
-    return edit_or_view_one_message(edit, ctx, hdr);
-
-  for (int i = 0; i < ctx->msgcount; i++)
+  struct EmailNode *en = NULL;
+  STAILQ_FOREACH(en, el, entries)
   {
-    if (!message_is_tagged(ctx, i))
-      continue;
-
-    if (edit_or_view_one_message(edit, ctx, ctx->hdrs[i]) == -1)
+    if (ev_message(action, m, en->email) == -1)
       return -1;
   }
 
   return 0;
 }
-
-int mutt_edit_message(struct Context *ctx, struct Header *hdr)
-{
-  return edit_or_view_message(true, ctx, hdr); /* true means edit */
-}
-
-int mutt_view_message(struct Context *ctx, struct Header *hdr)
-{
-  return edit_or_view_message(false, ctx, hdr); /* false means only view */
-}