⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 edit.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
字号:
/* * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. */ /* Close approximation of the mailx(1) builtin editor for sending mail. */#if HAVE_CONFIG_H# include "config.h"#endif#include "mutt.h"#include "mutt_curses.h"#include "mutt_idna.h"#include <stdio.h>#include <string.h>#include <stdlib.h>#include <ctype.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>/* * SLcurses_waddnstr() can't take a "const char *", so this is only * declared "static" (sigh) */static char* EditorHelp1 = 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\~f messages	include messages\n\~F messages	same as ~f, except also include headers\n\~h		edit the message header\n\~m messages	include and quote messages\n\~M messages	same as ~m, except include headers\n\~p		print the message\n");static char* EditorHelp2 = N_("\~q		write file and quit editor\n\~r file		read a file into the editor\n\~t users	add users to the To: field\n\~u		recall the previous line\n\~v		edit message with the $visual editor\n\~w file		write message to file\n\~x		abort changes and quit editor\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, LOFF_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);    p = tmp + tmplen;    tmplen = sizeof (tmp) - tmplen;  }  fseeko (f, offset, 0);  while (bytes > 0)  {    if (fgets (p, tmplen - 1, f) == NULL) break;    bytes -= mutt_strlen (p);    if (*bufmax == *buflen)      safe_realloc (&buf, sizeof (char *) * (*bufmax += 25));    buf[(*buflen)++] = safe_strdup (tmp);  }  if (buf && *bufmax == *buflen) { /* Do not smash memory past buf */    safe_realloc (&buf, sizeof (char *) * (++*bufmax));  }  if (buf) buf[*buflen] = NULL;  return (buf);}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")))  {    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);    }    fclose (f);  }  else  {    snprintf(tmp, sizeof(tmp), "%s: %s\n", path, strerror(errno));    addstr(tmp);  }  return (buf);}static int be_barf_file (const char *path, char **buf, int buflen){  FILE *f;  int i;    if ((f = 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;  printw ("fclose: %s\n", strerror (errno));  return (-1);}static void be_free_memory (char **buf, int buflen){  while (buflen-- > 0)    FREE (&buf[buflen]);  if (buf)    FREE (&buf);}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)  {    n = atoi (msg);    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 (*bufmax == *buflen)	safe_realloc ( &buf, sizeof (char *) * (*bufmax += 25));      buf[(*buflen)++] = safe_strdup (tmp);      bytes = Context->hdrs[n]->content->length;      if (inc_hdrs)      {	offset = Context->hdrs[n]->offset;	bytes += Context->hdrs[n]->content->offset - offset;      }      else	offset = Context->hdrs[n]->content->offset;      buf = be_snarf_data (Context->fp, buf, bufmax, buflen, offset, bytes,			   pfx);      if (*bufmax == *buflen)	safe_realloc (&buf, sizeof (char *) * (*bufmax += 25));      buf[(*buflen)++] = safe_strdup ("\n");    }    else      printw (_("%d: invalid message number.\n"), n);    msg = NULL;  }  return (buf);}static void be_print_header (ENVELOPE *env){  char tmp[HUGE_STRING];  if (env->to)  {    addstr ("To: ");    tmp[0] = 0;    rfc822_write_address (tmp, sizeof (tmp), env->to, 1);    addstr (tmp);    addch ('\n');  }  if (env->cc)  {    addstr ("Cc: ");    tmp[0] = 0;    rfc822_write_address (tmp, sizeof (tmp), env->cc, 1);    addstr (tmp);    addch ('\n');  }  if (env->bcc)  {    addstr ("Bcc: ");    tmp[0] = 0;    rfc822_write_address (tmp, sizeof (tmp), env->bcc, 1);    addstr (tmp);    addch ('\n');  }  if (env->subject)  {    addstr ("Subject: ");    addstr (env->subject);    addch ('\n');  }  addch ('\n');}/* args: *	force	override the $ask* vars (used for the ~h command) */static void be_edit_header (ENVELOPE *e, int force){  char tmp[HUGE_STRING];  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)    {      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? */      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? */    addstr (tmp);  }  addch ('\n');  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);    addch ('\n');  }  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)    {      rfc822_free_address (&e->cc);      e->cc = mutt_parse_adrlist (e->cc, tmp);      e->cc = mutt_expand_aliases (e->cc);      tmp[0] = 0;      mutt_addrlist_to_idna (e->cc, NULL);      rfc822_write_address (tmp, sizeof (tmp), e->cc, 1);      mvaddstr (LINES - 1, 4, tmp);    }    else      mutt_addrlist_to_idna (e->cc, NULL);    addch ('\n');  }  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)    {      rfc822_free_address (&e->bcc);      e->bcc = mutt_parse_adrlist (e->bcc, tmp);      e->bcc = mutt_expand_aliases (e->bcc);      mutt_addrlist_to_idna (e->bcc, NULL);      tmp[0] = 0;      rfc822_write_address (tmp, sizeof (tmp), e->bcc, 1);      mvaddstr (LINES - 1, 5, tmp);    }    else      mutt_addrlist_to_idna (e->bcc, NULL);    addch ('\n');  }}int mutt_builtin_editor (const char *path, HEADER *msg, HEADER *cur){  char **buf = NULL;  int bufmax = 0, buflen = 0;  char tmp[LONG_STRING];  int abort = 0;  int done = 0;  int i;  char *p;    scrollok (stdscr, TRUE);  be_edit_header (msg->env, 0);  addstr (_("(End message with a . on a line by itself)\n"));  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)    {      tmp[0] = 0;      continue;    }    addch ('\n');    if (EscChar && tmp[0] == EscChar[0] && tmp[1] != EscChar[0])    {      /* remove trailing whitespace from the line */      p = tmp + mutt_strlen (tmp) - 1;      while (p >= tmp && ISSPACE (*p))	*p-- = 0;      p = tmp + 2;      SKIPWS (p);      switch (tmp[1])      {	case '?':	  addstr (_(EditorHelp1));          addstr (_(EditorHelp2));	  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);          }	  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 if (mutt_strcmp (".", tmp) == 0)      done = 1;    else    {      safe_strcat (tmp, sizeof (tmp), "\n");      if (buflen == bufmax)	safe_realloc (&buf, sizeof (char *) * (bufmax += 25));      buf[buflen++] = safe_strdup (tmp[1] == '~' ? tmp + 1 : tmp);    }        tmp[0] = 0;  }  if (!abort) be_barf_file (path, buf, buflen);  be_free_memory (buf, buflen);  return (abort ? -1 : 0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -