we're grownups now. don't care about stupid OS'es that don't know what an
[apps/madmutt.git] / edit.c
diff --git a/edit.c b/edit.c
index 7e8f507..966d1be 100644 (file)
--- a/edit.c
+++ b/edit.c
@@ -1,27 +1,28 @@
 /*
+ * Copyright notice from original mutt:
  * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
- * 
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- * 
- *     This program is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- * 
- *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
- */ 
+ *
+ * This file is part of mutt-ng, see http://www.muttng.org/.
+ * It's licensed under the GNU General Public License,
+ * please see the file GPL in the top level source directory.
+ */
 
 /* Close approximation of the mailx(1) builtin editor for sending mail. */
 
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
 #include "mutt.h"
+#include "ascii.h"
+#include "enter.h"
 #include "mutt_curses.h"
 #include "mutt_idna.h"
 
+#include "lib/mem.h"
+#include "lib/intl.h"
+#include "lib/str.h"
+
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -34,7 +35,7 @@
  * SLcurses_waddnstr() can't take a "const char *", so this is only
  * declared "static" (sigh)
  */
-static charEditorHelp = N_("\
+static char *EditorHelp = N_("\
 ~~             insert a line begining with a single ~\n\
 ~b users       add users to the Bcc: field\n\
 ~c users       add users to the Cc: field\n\
@@ -54,61 +55,58 @@ static char* EditorHelp = N_("\
 ~?             this message\n\
 .              on a line by itself ends input\n");
 
-static char **
-be_snarf_data (FILE *f, char **buf, int *bufmax, int *buflen, int offset,
-              int bytes, int prefix)
+static char **be_snarf_data (FILE * f, char **buf, int *bufmax, int *buflen,
+                             off_t offset, int bytes, int prefix)
 {
   char tmp[HUGE_STRING];
   char *p = tmp;
   int tmplen = sizeof (tmp);
 
   tmp[sizeof (tmp) - 1] = 0;
-  if (prefix)
-  {
-    strfcpy (tmp, NONULL(Prefix), sizeof (tmp));
-    tmplen = mutt_strlen (tmp);
+  if (prefix) {
+    strfcpy (tmp, NONULL (Prefix), sizeof (tmp));
+    tmplen = str_len (tmp);
     p = tmp + tmplen;
     tmplen = sizeof (tmp) - tmplen;
   }
 
-  fseek (f, offset, 0);
-  while (bytes > 0)
-  {
-    if (fgets (p, tmplen - 1, f) == NULL) break;
-    bytes -= mutt_strlen (p);
+  fseeko (f, offset, 0);
+  while (bytes > 0) {
+    if (fgets (p, tmplen - 1, f) == NULL)
+      break;
+    bytes -= str_len (p);
     if (*bufmax == *buflen)
-      safe_realloc (&buf, sizeof (char *) * (*bufmax += 25));
-    buf[(*buflen)++] = safe_strdup (tmp);
+      mem_realloc (&buf, sizeof (char *) * (*bufmax += 25));
+    buf[(*buflen)++] = str_dup (tmp);
   }
-  if (buf && *bufmax == *buflen) { /* Do not smash memory past buf */
-    safe_realloc (&buf, sizeof (char *) * (++*bufmax));
+  if (buf && *bufmax == *buflen) {      /* Do not smash memory past buf */
+    mem_realloc (&buf, sizeof (char *) * (++*bufmax));
   }
-  if (buf) buf[*buflen] = NULL;
+  if (buf)
+    buf[*buflen] = NULL;
   return (buf);
 }
 
-static char **
-be_snarf_file (const char *path, char **buf, int *max, int *len, int verbose)
+static char **be_snarf_file (const char *path, char **buf, int *max, int *len,
+                             int verbose)
 {
   FILE *f;
   char tmp[LONG_STRING];
   struct stat sb;
-  
-  if ((f = fopen (path, "r")))
-  {
+
+  if ((f = fopen (path, "r"))) {
     fstat (fileno (f), &sb);
     buf = be_snarf_data (f, buf, max, len, 0, sb.st_size, 0);
-    if (verbose)
-    {
-      snprintf(tmp, sizeof(tmp), "\"%s\" %lu bytes\n", path, (unsigned long) sb.st_size);
-      addstr(tmp);
+    if (verbose) {
+      snprintf (tmp, sizeof (tmp), "\"%s\" %lu bytes\n", path,
+                (unsigned long) sb.st_size);
+      addstr (tmp);
     }
     fclose (f);
   }
-  else
-  {
-    snprintf(tmp, sizeof(tmp), "%s: %s\n", path, strerror(errno));
-    addstr(tmp);
+  else {
+    snprintf (tmp, sizeof (tmp), "%s: %s\n", path, strerror (errno));
+    addstr (tmp);
   }
   return (buf);
 }
@@ -117,15 +115,16 @@ static int be_barf_file (const char *path, char **buf, int buflen)
 {
   FILE *f;
   int i;
-  
-  if ((f = safe_fopen (path, "w")) == NULL)            /* __FOPEN_CHECKED__ */
-  {
+
+  if ((f = safe_fopen (path, "w")) == NULL) {   /* __FOPEN_CHECKED__ */
     addstr (strerror (errno));
     addch ('\n');
     return (-1);
   }
-  for (i = 0; i < buflen; i++) fputs (buf[i], f);
-  if (fclose (f) == 0) return 0;
+  for (i = 0; i < buflen; i++)
+    fputs (buf[i], f);
+  if (fclose (f) == 0)
+    return 0;
   printw ("fclose: %s\n", strerror (errno));
   return (-1);
 }
@@ -133,50 +132,46 @@ static int be_barf_file (const char *path, char **buf, int buflen)
 static void be_free_memory (char **buf, int buflen)
 {
   while (buflen-- > 0)
-    FREE (&buf[buflen]);
+    mem_free (&buf[buflen]);
   if (buf)
-    FREE (&buf);
+    mem_free (&buf);
 }
 
-static char **
-be_include_messages (char *msg, char **buf, int *bufmax, int *buflen,
-                    int pfx, int inc_hdrs)
+static char **be_include_messages (char *msg, char **buf, int *bufmax,
+                                   int *buflen, int pfx, int inc_hdrs)
 {
   int offset, bytes, n;
   char tmp[LONG_STRING];
 
-  while ((msg = strtok (msg, " ,")) != NULL)
-  {
+  while ((msg = strtok (msg, " ,")) != NULL) {
     n = atoi (msg);
-    if (n > 0 && n <= Context->msgcount)
-    {
+    if (n > 0 && n <= Context->msgcount) {
       n--;
 
       /* add the attribution */
-      if (Attribution)
-      {
-       mutt_make_string (tmp, sizeof (tmp) - 1, Attribution, Context, Context->hdrs[n]);
-       strcat (tmp, "\n");     /* __STRCAT_CHECKED__ */
+      if (Attribution) {
+        mutt_make_string (tmp, sizeof (tmp) - 1, Attribution, Context,
+                          Context->hdrs[n]);
+        strcat (tmp, "\n");     /* __STRCAT_CHECKED__ */
       }
 
       if (*bufmax == *buflen)
-       safe_realloc ( &buf, sizeof (char *) * (*bufmax += 25));
-      buf[(*buflen)++] = safe_strdup (tmp);
+        mem_realloc (&buf, sizeof (char *) * (*bufmax += 25));
+      buf[(*buflen)++] = str_dup (tmp);
 
       bytes = Context->hdrs[n]->content->length;
-      if (inc_hdrs)
-      {
-       offset = Context->hdrs[n]->offset;
-       bytes += Context->hdrs[n]->content->offset - offset;
+      if (inc_hdrs) {
+        offset = Context->hdrs[n]->offset;
+        bytes += Context->hdrs[n]->content->offset - offset;
       }
       else
-       offset = Context->hdrs[n]->content->offset;
+        offset = Context->hdrs[n]->content->offset;
       buf = be_snarf_data (Context->fp, buf, bufmax, buflen, offset, bytes,
-                          pfx);
+                           pfx);
 
       if (*bufmax == *buflen)
-       safe_realloc (&buf, sizeof (char *) * (*bufmax += 25));
-      buf[(*buflen)++] = safe_strdup ("\n");
+        mem_realloc (&buf, sizeof (char *) * (*bufmax += 25));
+      buf[(*buflen)++] = str_dup ("\n");
     }
     else
       printw (_("%d: invalid message number.\n"), n);
@@ -185,36 +180,32 @@ be_include_messages (char *msg, char **buf, int *bufmax, int *buflen,
   return (buf);
 }
 
-static void be_print_header (ENVELOPE *env)
+static void be_print_header (ENVELOPE * env)
 {
   char tmp[HUGE_STRING];
 
-  if (env->to)
-  {
+  if (env->to) {
     addstr ("To: ");
     tmp[0] = 0;
     rfc822_write_address (tmp, sizeof (tmp), env->to, 1);
     addstr (tmp);
     addch ('\n');
   }
-  if (env->cc)
-  {
+  if (env->cc) {
     addstr ("Cc: ");
     tmp[0] = 0;
     rfc822_write_address (tmp, sizeof (tmp), env->cc, 1);
     addstr (tmp);
     addch ('\n');
   }
-  if (env->bcc)
-  {
+  if (env->bcc) {
     addstr ("Bcc: ");
     tmp[0] = 0;
     rfc822_write_address (tmp, sizeof (tmp), env->bcc, 1);
     addstr (tmp);
     addch ('\n');
   }
-  if (env->subject)
-  {
+  if (env->subject) {
     addstr ("Subject: ");
     addstr (env->subject);
     addch ('\n');
@@ -225,53 +216,47 @@ static void be_print_header (ENVELOPE *env)
 /* args:
  *     force   override the $ask* vars (used for the ~h command)
  */
-static void be_edit_header (ENVELOPE *e, int force)
+static void be_edit_header (ENVELOPE * e, int force)
 {
   char tmp[HUGE_STRING];
 
-  move (LINES-1, 0);
+  move (LINES - 1, 0);
 
   addstr ("To: ");
   tmp[0] = 0;
   mutt_addrlist_to_local (e->to);
   rfc822_write_address (tmp, sizeof (tmp), e->to, 0);
-  if (!e->to || force)
-  {
-    if (mutt_enter_string (tmp, sizeof (tmp), LINES-1, 4, 0) == 0)
-    {
+  if (!e->to || force) {
+    if (mutt_enter_string (tmp, sizeof (tmp), LINES - 1, 4, 0) == 0) {
       rfc822_free_address (&e->to);
       e->to = mutt_parse_adrlist (e->to, tmp);
       e->to = mutt_expand_aliases (e->to);
-      mutt_addrlist_to_idna (e->to, NULL);     /* XXX - IDNA error reporting? */
+      mutt_addrlist_to_idna (e->to, NULL);      /* XXX - IDNA error reporting? */
       tmp[0] = 0;
       rfc822_write_address (tmp, sizeof (tmp), e->to, 1);
       mvaddstr (LINES - 1, 4, tmp);
     }
   }
-  else
-  {
-    mutt_addrlist_to_idna (e->to, NULL);       /* XXX - IDNA error reporting? */
+  else {
+    mutt_addrlist_to_idna (e->to, NULL);        /* XXX - IDNA error reporting? */
     addstr (tmp);
   }
   addch ('\n');
 
-  if (!e->subject || force)
-  {
+  if (!e->subject || force) {
     addstr ("Subject: ");
-    strfcpy (tmp, e->subject ? e->subject: "", sizeof (tmp));
-    if (mutt_enter_string (tmp, sizeof (tmp), LINES-1, 9, 0) == 0)
-      mutt_str_replace (&e->subject, tmp);
+    strfcpy (tmp, e->subject ? e->subject : "", sizeof (tmp));
+    if (mutt_enter_string (tmp, sizeof (tmp), LINES - 1, 9, 0) == 0)
+      str_replace (&e->subject, tmp);
     addch ('\n');
   }
 
-  if ((!e->cc && option (OPTASKCC)) || force)
-  {
+  if ((!e->cc && option (OPTASKCC)) || force) {
     addstr ("Cc: ");
     tmp[0] = 0;
     mutt_addrlist_to_local (e->cc);
     rfc822_write_address (tmp, sizeof (tmp), e->cc, 0);
-    if (mutt_enter_string (tmp, sizeof (tmp), LINES-1, 4, 0) == 0)
-    {
+    if (mutt_enter_string (tmp, sizeof (tmp), LINES - 1, 4, 0) == 0) {
       rfc822_free_address (&e->cc);
       e->cc = mutt_parse_adrlist (e->cc, tmp);
       e->cc = mutt_expand_aliases (e->cc);
@@ -285,14 +270,12 @@ static void be_edit_header (ENVELOPE *e, int force)
     addch ('\n');
   }
 
-  if (option (OPTASKBCC) || force)
-  {
+  if (option (OPTASKBCC) || force) {
     addstr ("Bcc: ");
     tmp[0] = 0;
     mutt_addrlist_to_local (e->bcc);
     rfc822_write_address (tmp, sizeof (tmp), e->bcc, 0);
-    if (mutt_enter_string (tmp, sizeof (tmp), LINES-1, 5, 0) == 0)
-    {
+    if (mutt_enter_string (tmp, sizeof (tmp), LINES - 1, 5, 0) == 0) {
       rfc822_free_address (&e->bcc);
       e->bcc = mutt_parse_adrlist (e->bcc, tmp);
       e->bcc = mutt_expand_aliases (e->bcc);
@@ -307,7 +290,7 @@ static void be_edit_header (ENVELOPE *e, int force)
   }
 }
 
-int mutt_builtin_editor (const char *path, HEADER *msg, HEADER *cur)
+int mutt_builtin_editor (const char *path, HEADER * msg, HEADER * cur)
 {
   char **buf = NULL;
   int bufmax = 0, buflen = 0;
@@ -316,7 +299,7 @@ int mutt_builtin_editor (const char *path, HEADER *msg, HEADER *cur)
   int done = 0;
   int i;
   char *p;
-  
+
   scrollok (stdscr, TRUE);
 
   be_edit_header (msg->env, 0);
@@ -326,153 +309,146 @@ int mutt_builtin_editor (const char *path, HEADER *msg, HEADER *cur)
   buf = be_snarf_file (path, buf, &bufmax, &buflen, 0);
 
   tmp[0] = 0;
-  while (!done)
-  {
-    if (mutt_enter_string (tmp, sizeof (tmp), LINES-1, 0, 0) == -1)
-    {
+  while (!done) {
+    if (mutt_enter_string (tmp, sizeof (tmp), LINES - 1, 0, 0) == -1) {
       tmp[0] = 0;
       continue;
     }
     addch ('\n');
 
-    if (EscChar && tmp[0] == EscChar[0] && tmp[1] != EscChar[0])
-    {
+    if (EscChar && tmp[0] == EscChar[0] && tmp[1] != EscChar[0]) {
       /* remove trailing whitespace from the line */
-      p = tmp + mutt_strlen (tmp) - 1;
+      p = tmp + str_len (tmp) - 1;
       while (p >= tmp && ISSPACE (*p))
-       *p-- = 0;
+        *p-- = 0;
 
       p = tmp + 2;
       SKIPWS (p);
 
-      switch (tmp[1])
-      {
-       case '?':
-         addstr (_(EditorHelp));
-         break;
-       case 'b':
-         msg->env->bcc = mutt_parse_adrlist (msg->env->bcc, p);
-         msg->env->bcc = mutt_expand_aliases (msg->env->bcc);
-         break;
-       case 'c':
-         msg->env->cc = mutt_parse_adrlist (msg->env->cc, p);
-         msg->env->cc = mutt_expand_aliases (msg->env->cc);
-         break;
-       case 'h':
-         be_edit_header (msg->env, 1);
-         break;
-       case 'F':
-       case 'f':
-       case 'm':
-       case 'M':
-         if (Context)
-         {
-           if (!*p && cur)
-           {
-             /* include the current message */
-             p = tmp + mutt_strlen (tmp) + 1;
-             snprintf (tmp + mutt_strlen (tmp), sizeof (tmp) - mutt_strlen (tmp), " %d",
-                                                               cur->msgno + 1);
-           }
-           buf = be_include_messages (p, buf, &bufmax, &buflen,
-                                      (ascii_tolower (tmp[1]) == 'm'),
-                                      (ascii_isupper ((unsigned char) tmp[1])));
-         }
-         else
-           addstr (_("No mailbox.\n"));
-         break;
-       case 'p':
-         addstr ("-----\n");
-         addstr (_("Message contains:\n"));
-         be_print_header (msg->env);
-         for (i = 0; i < buflen; i++)
-           addstr (buf[i]);
-         addstr (_("(continue)\n"));
-         break;
-       case 'q':
-         done = 1;
-         break;
-       case 'r':
-         if (*p)
-          {
-           strncpy(tmp, p, sizeof(tmp));
-           mutt_expand_path(tmp, sizeof(tmp));
-           buf = be_snarf_file (tmp, buf, &bufmax, &buflen, 1);
+      switch (tmp[1]) {
+      case '?':
+        addstr (_(EditorHelp));
+        break;
+      case 'b':
+        msg->env->bcc = mutt_parse_adrlist (msg->env->bcc, p);
+        msg->env->bcc = mutt_expand_aliases (msg->env->bcc);
+        break;
+      case 'c':
+        msg->env->cc = mutt_parse_adrlist (msg->env->cc, p);
+        msg->env->cc = mutt_expand_aliases (msg->env->cc);
+        break;
+      case 'h':
+        be_edit_header (msg->env, 1);
+        break;
+      case 'F':
+      case 'f':
+      case 'm':
+      case 'M':
+        if (Context) {
+          if (!*p && cur) {
+            /* include the current message */
+            p = tmp + str_len (tmp) + 1;
+            snprintf (tmp + str_len (tmp),
+                      sizeof (tmp) - str_len (tmp), " %d",
+                      cur->msgno + 1);
+          }
+          buf = be_include_messages (p, buf, &bufmax, &buflen,
+                                     (ascii_tolower (tmp[1]) == 'm'),
+                                     (ascii_isupper
+                                      ((unsigned char) tmp[1])));
+        }
+        else
+          addstr (_("No mailbox.\n"));
+        break;
+      case 'p':
+        addstr ("-----\n");
+        addstr (_("Message contains:\n"));
+        be_print_header (msg->env);
+        for (i = 0; i < buflen; i++)
+          addstr (buf[i]);
+        addstr (_("(continue)\n"));
+        break;
+      case 'q':
+        done = 1;
+        break;
+      case 'r':
+        if (*p) {
+          strncpy (tmp, p, sizeof (tmp));
+          mutt_expand_path (tmp, sizeof (tmp));
+          buf = be_snarf_file (tmp, buf, &bufmax, &buflen, 1);
+        }
+        else
+          addstr (_("missing filename.\n"));
+        break;
+      case 's':
+        str_replace (&msg->env->subject, p);
+        break;
+      case 't':
+        msg->env->to = rfc822_parse_adrlist (msg->env->to, p);
+        msg->env->to = mutt_expand_aliases (msg->env->to);
+        break;
+      case 'u':
+        if (buflen) {
+          buflen--;
+          strfcpy (tmp, buf[buflen], sizeof (tmp));
+          tmp[str_len (tmp) - 1] = 0;
+          mem_free (&buf[buflen]);
+          buf[buflen] = NULL;
+          continue;
+        }
+        else
+          addstr (_("No lines in message.\n"));
+        break;
+
+      case 'e':
+      case 'v':
+        if (be_barf_file (path, buf, buflen) == 0) {
+          char *tag, *err;
+
+          be_free_memory (buf, buflen);
+          buf = NULL;
+          bufmax = buflen = 0;
+
+          if (option (OPTEDITHDRS)) {
+            mutt_env_to_local (msg->env);
+            mutt_edit_headers (NONULL (Visual), path, msg, NULL, 0);
+            if (mutt_env_to_idna (msg->env, &tag, &err))
+              printw (_("Bad IDN in %s: '%s'\n"), tag, err);
           }
-         else
-           addstr (_("missing filename.\n"));
-         break;
-       case 's':
-         mutt_str_replace (&msg->env->subject, p);
-         break;
-       case 't':
-         msg->env->to = rfc822_parse_adrlist (msg->env->to, p);
-         msg->env->to = mutt_expand_aliases (msg->env->to);
-         break;
-       case 'u':
-         if (buflen)
-         {
-           buflen--;
-           strfcpy (tmp, buf[buflen], sizeof (tmp));
-           tmp[mutt_strlen (tmp)-1] = 0;
-           FREE (&buf[buflen]);
-           buf[buflen] = NULL;
-           continue;
-         }
-         else
-           addstr (_("No lines in message.\n"));
-         break;
-
-       case 'e':
-       case 'v':
-         if (be_barf_file (path, buf, buflen) == 0)
-         {
-           char *tag, *err;
-           be_free_memory (buf, buflen);
-           buf = NULL;
-           bufmax = buflen = 0;
-
-           if (option (OPTEDITHDRS))
-           {
-             mutt_env_to_local (msg->env);
-             mutt_edit_headers (NONULL(Visual), path, msg, NULL, 0);
-             if (mutt_env_to_idna (msg->env, &tag, &err))
-               printw (_("Bad IDN in %s: '%s'\n"), tag, err);
-           }
-           else
-             mutt_edit_file (NONULL(Visual), path);
-
-           buf = be_snarf_file (path, buf, &bufmax, &buflen, 0);
-
-           addstr (_("(continue)\n"));
-         }
-         break;
-       case 'w':
-         be_barf_file (*p ? p : path, buf, buflen);
-         break;
-       case 'x':
-         abort = 1;
-         done = 1;
-         break;
-       default:
-         printw (_("%s: unknown editor command (~? for help)\n"), tmp);
-         break;
+          else
+            mutt_edit_file (NONULL (Visual), path);
+
+          buf = be_snarf_file (path, buf, &bufmax, &buflen, 0);
+
+          addstr (_("(continue)\n"));
+        }
+        break;
+      case 'w':
+        be_barf_file (*p ? p : path, buf, buflen);
+        break;
+      case 'x':
+        abort = 1;
+        done = 1;
+        break;
+      default:
+        printw (_("%s: unknown editor command (~? for help)\n"), tmp);
+        break;
       }
     }
-    else if (mutt_strcmp (".", tmp) == 0)
+    else if (str_cmp (".", tmp) == 0)
       done = 1;
-    else
-    {
-      safe_strcat (tmp, sizeof (tmp), "\n");
+    else {
+      str_cat (tmp, sizeof (tmp), "\n");
       if (buflen == bufmax)
-       safe_realloc (&buf, sizeof (char *) * (bufmax += 25));
-      buf[buflen++] = safe_strdup (tmp[1] == '~' ? tmp + 1 : tmp);
+        mem_realloc (&buf, sizeof (char *) * (bufmax += 25));
+      buf[buflen++] = str_dup (tmp[1] == '~' ? tmp + 1 : tmp);
     }
-    
+
     tmp[0] = 0;
   }
 
-  if (!abort) be_barf_file (path, buf, buflen);
+  if (!abort)
+    be_barf_file (path, buf, buflen);
   be_free_memory (buf, buflen);
 
   return (abort ? -1 : 0);