]> granicus.if.org Git - neomutt/commitdiff
editmsg.c: Implement mutt_view_message() function
authorReis Radomil <reisradomil@fake-box.com>
Wed, 15 Nov 2017 20:53:03 +0000 (21:53 +0100)
committerReis Radomil <reisradomil@fake-box.com>
Wed, 15 Nov 2017 20:58:37 +0000 (21:58 +0100)
Add mutt_view_message() function, which opens the selected message or
the tagged messages as a read-only file in an external editor. This
function is similar to mutt_edit_message() but does not allow modifying
the message.

A usage scenario might be to view the message source code in an editor.

Note: This patch only adds C functions. It does not add any mutt-functions.

editmsg.c
protos.h

index 456536820c2595862aeecb4b342f6835235cc0b1..0d5b3ad5a7dee52cc239fe33680f5cec3d1844ef 100644 (file)
--- a/editmsg.c
+++ b/editmsg.c
 #include "protos.h"
 
 /**
- * edit_one_message - Edit an email
+ * 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 massage (in the editor) will be ignored.
  * @param ctx Context
  * @param cur Header of email
  * @retval 1  Message not modified
  * @retval 0  Message edited successfully
  * @retval -1 Error
  */
-static int edit_one_message(struct Context *ctx, struct Header *cur)
+static int edit_or_view_one_message(bool edit, struct Context *ctx,
+                                    struct Header *cur)
 {
   char tmp[_POSIX_PATH_MAX];
   char buff[STRING];
@@ -118,7 +121,20 @@ static int edit_one_message(struct Context *ctx, struct Header *cur)
     goto bail;
   }
 
-  mtime = mutt_decrease_mtime(tmp, &sb);
+  /* remove write permissions */
+  if (!edit)
+  {
+    rc = chmod(tmp, sb.st_mode & ~(S_IWUSR | S_IWGRP | S_IWOTH));
+    if (rc == -1)
+    {
+      mutt_debug(1, "Could not remove write permissions of %s: %s", tmp, 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_decrease_mtime(tmp, NULL);
 
   mutt_edit_file(NONULL(Editor), tmp);
 
@@ -136,13 +152,27 @@ static int edit_one_message(struct Context *ctx, struct Header *cur)
     goto bail;
   }
 
-  if (sb.st_mtime == mtime)
+  if (edit && sb.st_mtime == mtime)
   {
     mutt_message(_("Message not modified!"));
     rc = 1;
     goto bail;
   }
 
+  if (!edit && sb.st_mtime != mtime)
+  {
+    mutt_message(_("Message of read-only mailbox modified! Ignoring changes."));
+    rc = 1;
+    goto bail;
+  }
+
+  if (!edit)
+  {
+    /* stop processing here and skip right to the end */
+    rc = 1;
+    goto bail;
+  }
+
   fp = fopen(tmp, "r");
   if (!fp)
   {
@@ -221,19 +251,29 @@ bail:
   return rc;
 }
 
-int mutt_edit_message(struct Context *ctx, struct Header *hdr)
+int edit_or_view_message(bool edit, struct Context *ctx, struct Header *hdr)
 {
   if (hdr)
-    return edit_one_message(ctx, hdr);
+    return edit_or_view_one_message(edit, ctx, hdr);
 
   for (int i = 0; i < ctx->msgcount; i++)
   {
     if (!message_is_tagged(ctx, i))
       continue;
 
-    if (edit_one_message(ctx, ctx->hdrs[i]) == -1)
+    if (edit_or_view_one_message(edit, ctx, ctx->hdrs[i]) == -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 */
+}
index a4867749a7e44032c3870c4483b1e357d58da154..27384a3d5d6dcfea94398d1b54bac24f5d5d1801 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -272,6 +272,7 @@ int mutt_display_message(struct Header *cur);
 int mutt_dump_variables(int hide_sensitive);
 int mutt_edit_attachment(struct Body *a);
 int mutt_edit_message(struct Context *ctx, struct Header *hdr);
+int mutt_view_message(struct Context *ctx, struct Header *hdr);
 int mutt_fetch_recips(struct Envelope *out, struct Envelope *in, int flags);
 int mutt_chscmp(const char *s, const char *chs);
 #define mutt_is_utf8(a) mutt_chscmp(a, "utf-8")