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

📄 init.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (C) 1996-2002 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. */ #if HAVE_CONFIG_H# include "config.h"#endif#include "mutt.h"#include "mapping.h"#include "mutt_curses.h"#include "mutt_regex.h"#include "history.h"#include "keymap.h"#include "mbyte.h"#include "charset.h"#include "mutt_crypt.h"#include "mutt_idna.h"#if defined(USE_SSL)#include "mutt_ssl.h"#endif#include "mx.h"#include "init.h"#include "mailbox.h"#include <ctype.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <sys/utsname.h>#include <errno.h>#include <sys/wait.h>#define CHECK_PAGER \  if ((CurrentMenu == MENU_PAGER) && (idx >= 0) &&	\	    (MuttVars[idx].flags & R_RESORT)) \	{ \	  snprintf (err->data, err->dsize, \	    _("Not available in this menu.")); \	  return (-1); \	} elsetypedef struct myvar{  char *name;  char *value;  struct myvar* next;} myvar_t;static myvar_t* MyVars;static int var_to_string (int idx, char* val, size_t len);static void myvar_set (const char* var, const char* val);static const char* myvar_get (const char* var);static void myvar_del (const char* var);void toggle_quadoption (int opt){  int n = opt/4;  int b = (opt % 4) * 2;  QuadOptions[n] ^= (1 << b);}void set_quadoption (int opt, int flag){  int n = opt/4;  int b = (opt % 4) * 2;  QuadOptions[n] &= ~(0x3 << b);  QuadOptions[n] |= (flag & 0x3) << b;}int quadoption (int opt){  int n = opt/4;  int b = (opt % 4) * 2;  return (QuadOptions[n] >> b) & 0x3;}int query_quadoption (int opt, const char *prompt){  int v = quadoption (opt);  switch (v)  {    case M_YES:    case M_NO:      return (v);    default:      v = mutt_yesorno (prompt, (v == M_ASKYES));      CLEARLINE (LINES - 1);      return (v);  }  /* not reached */}/* given the variable ``s'', return the index into the rc_vars array which   matches, or -1 if the variable is not found.  */int mutt_option_index (char *s){  int i;  for (i = 0; MuttVars[i].option; i++)    if (mutt_strcmp (s, MuttVars[i].option) == 0)      return (MuttVars[i].type == DT_SYN ?  mutt_option_index ((char *) MuttVars[i].data) : i);  return (-1);}int mutt_extract_token (BUFFER *dest, BUFFER *tok, int flags){  char		ch;  char		qc = 0; /* quote char */  char		*pc;  /* reset the destination pointer to the beginning of the buffer */  dest->dptr = dest->data;  SKIPWS (tok->dptr);  while ((ch = *tok->dptr))  {    if (!qc)    {      if ((ISSPACE (ch) && !(flags & M_TOKEN_SPACE)) ||	  (ch == '#' && !(flags & M_TOKEN_COMMENT)) ||	  (ch == '=' && (flags & M_TOKEN_EQUAL)) ||	  (ch == ';' && !(flags & M_TOKEN_SEMICOLON)) ||	  ((flags & M_TOKEN_PATTERN) && strchr ("~%=!|", ch)))	break;    }    tok->dptr++;    if (ch == qc)      qc = 0; /* end of quote */    else if (!qc && (ch == '\'' || ch == '"') && !(flags & M_TOKEN_QUOTE))      qc = ch;    else if (ch == '\\' && qc != '\'')    {	if (!*tok->dptr)	    return -1; /* premature end of token */      switch (ch = *tok->dptr++)      {	case 'c':	case 'C':	    if (!*tok->dptr)		return -1; /* premature end of token */	  mutt_buffer_addch (dest, (toupper ((unsigned char) *tok->dptr)                                    - '@') & 0x7f);	  tok->dptr++;	  break;	case 'r':	  mutt_buffer_addch (dest, '\r');	  break;	case 'n':	  mutt_buffer_addch (dest, '\n');	  break;	case 't':	  mutt_buffer_addch (dest, '\t');	  break;	case 'f':	  mutt_buffer_addch (dest, '\f');	  break;	case 'e':	  mutt_buffer_addch (dest, '\033');	  break;	default:	  if (isdigit ((unsigned char) ch) &&	      isdigit ((unsigned char) *tok->dptr) &&	      isdigit ((unsigned char) *(tok->dptr + 1)))	  {	    mutt_buffer_addch (dest, (ch << 6) + (*tok->dptr << 3) + *(tok->dptr + 1) - 3504);	    tok->dptr += 2;	  }	  else	    mutt_buffer_addch (dest, ch);      }    }    else if (ch == '^' && (flags & M_TOKEN_CONDENSE))    {	if (!*tok->dptr)	    return -1; /* premature end of token */      ch = *tok->dptr++;      if (ch == '^')	mutt_buffer_addch (dest, ch);      else if (ch == '[')	mutt_buffer_addch (dest, '\033');      else if (isalpha ((unsigned char) ch))	mutt_buffer_addch (dest, toupper ((unsigned char) ch) - '@');      else      {	mutt_buffer_addch (dest, '^');	mutt_buffer_addch (dest, ch);      }    }    else if (ch == '`' && (!qc || qc == '"'))    {      FILE	*fp;      pid_t	pid;      char	*cmd, *ptr;      size_t	expnlen;      BUFFER	expn;      int	line = 0;      pc = tok->dptr;      do {	if ((pc = strpbrk (pc, "\\`")))	{	  /* skip any quoted chars */	  if (*pc == '\\')	    pc += 2;	}      } while (pc && *pc != '`');      if (!pc)      {	dprint (1, (debugfile, "mutt_get_token: mismatched backtics\n"));	return (-1);      }      cmd = mutt_substrdup (tok->dptr, pc);      if ((pid = mutt_create_filter (cmd, NULL, &fp, NULL)) < 0)      {	dprint (1, (debugfile, "mutt_get_token: unable to fork command: %s", cmd));	FREE (&cmd);	return (-1);      }      FREE (&cmd);      tok->dptr = pc + 1;      /* read line */      memset (&expn, 0, sizeof (expn));      expn.data = mutt_read_line (NULL, &expn.dsize, fp, &line);      fclose (fp);      mutt_wait_filter (pid);      /* if we got output, make a new string consiting of the shell ouptput	 plus whatever else was left on the original line */      /* BUT: If this is inside a quoted string, directly add output to        * the token */      if (expn.data && qc)      {	mutt_buffer_addstr (dest, expn.data);	FREE (&expn.data);      }      else if (expn.data)      {	expnlen = mutt_strlen (expn.data);	tok->dsize = expnlen + mutt_strlen (tok->dptr) + 1;	ptr = safe_malloc (tok->dsize);	memcpy (ptr, expn.data, expnlen);	strcpy (ptr + expnlen, tok->dptr);	/* __STRCPY_CHECKED__ */	if (tok->destroy)	  FREE (&tok->data);	tok->data = ptr;	tok->dptr = ptr;	tok->destroy = 1; /* mark that the caller should destroy this data */	ptr = NULL;	FREE (&expn.data);      }    }    else if (ch == '$' && (!qc || qc == '"') && (*tok->dptr == '{' || isalpha ((unsigned char) *tok->dptr)))    {      const char *env = NULL;      char *var = NULL;      int idx;      if (*tok->dptr == '{')      {	tok->dptr++;	if ((pc = strchr (tok->dptr, '}')))	{	  var = mutt_substrdup (tok->dptr, pc);	  tok->dptr = pc + 1;	}      }      else      {	for (pc = tok->dptr; isalnum ((unsigned char) *pc) || *pc == '_'; pc++)	  ;	var = mutt_substrdup (tok->dptr, pc);	tok->dptr = pc;      }      if (var)      {        if ((env = getenv (var)) || (env = myvar_get (var)))          mutt_buffer_addstr (dest, env);        else if ((idx = mutt_option_index (var)) != -1)        {          /* expand settable mutt variables */          char val[LONG_STRING];          if (var_to_string (idx, val, sizeof (val)))            mutt_buffer_addstr (dest, val);        }        FREE (&var);      }    }    else      mutt_buffer_addch (dest, ch);  }  mutt_buffer_addch (dest, 0); /* terminate the string */  SKIPWS (tok->dptr);  return 0;}static void mutt_free_opt (struct option_t* p){  REGEXP* pp;  switch (p->type & DT_MASK)  {  case DT_ADDR:    rfc822_free_address ((ADDRESS**)p->data);    break;  case DT_RX:    pp = (REGEXP*)p->data;    FREE (&pp->pattern);    if (pp->rx)    {      regfree (pp->rx);      FREE (&pp->rx);    }    break;  case DT_PATH:  case DT_STR:    FREE ((char**)p->data);		/* __FREE_CHECKED__ */    break;  }}/* clean up before quitting */void mutt_free_opts (void){  int i;  for (i = 0; MuttVars[i].option; i++)    mutt_free_opt (MuttVars + i);  mutt_free_rx_list (&Alternates);  mutt_free_rx_list (&UnAlternates);  mutt_free_rx_list (&MailLists);  mutt_free_rx_list (&UnMailLists);  mutt_free_rx_list (&SubscribedLists);  mutt_free_rx_list (&UnSubscribedLists);  mutt_free_rx_list (&NoSpamList);}static void add_to_list (LIST **list, const char *str){  LIST *t, *last = NULL;  /* don't add a NULL or empty string to the list */  if (!str || *str == '\0')    return;  /* check to make sure the item is not already on this list */  for (last = *list; last; last = last->next)  {    if (ascii_strcasecmp (str, last->data) == 0)    {      /* already on the list, so just ignore it */      last = NULL;      break;    }    if (!last->next)      break;  }  if (!*list || last)  {    t = (LIST *) safe_calloc (1, sizeof (LIST));    t->data = safe_strdup (str);    if (last)    {      last->next = t;      last = last->next;    }    else      *list = last = t;  }}int mutt_add_to_rx_list (RX_LIST **list, const char *s, int flags, BUFFER *err){  RX_LIST *t, *last = NULL;  REGEXP *rx;  if (!s || !*s)    return 0;  if (!(rx = mutt_compile_regexp (s, flags)))  {    snprintf (err->data, err->dsize, "Bad regexp: %s\n", s);    return -1;  }  /* check to make sure the item is not already on this list */  for (last = *list; last; last = last->next)  {    if (ascii_strcasecmp (rx->pattern, last->rx->pattern) == 0)    {      /* already on the list, so just ignore it */      last = NULL;      break;    }    if (!last->next)      break;  }  if (!*list || last)  {    t = mutt_new_rx_list();    t->rx = rx;    if (last)    {      last->next = t;      last = last->next;    }    else      *list = last = t;  }  else /* duplicate */    mutt_free_regexp (&rx);  return 0;}static int add_to_spam_list (SPAM_LIST **list, const char *pat, const char *templ, BUFFER *err){  SPAM_LIST *t = NULL, *last = NULL;  REGEXP *rx;  int n;  const char *p;  if (!pat || !*pat || !templ)    return 0;  if (!(rx = mutt_compile_regexp (pat, REG_ICASE)))  {    snprintf (err->data, err->dsize, _("Bad regexp: %s"), pat);    return -1;  }  /* check to make sure the item is not already on this list */  for (last = *list; last; last = last->next)  {    if (ascii_strcasecmp (rx->pattern, last->rx->pattern) == 0)    {      /* Already on the list. Formerly we just skipped this case, but       * now we're supporting removals, which means we're supporting       * re-adds conceptually. So we probably want this to imply a       * removal, then do an add. We can achieve the removal by freeing       * the template, and leaving t pointed at the current item.       */      t = last;      FREE(&t->template);      break;    }    if (!last->next)      break;  }  /* If t is set, it's pointing into an extant SPAM_LIST* that we want to   * update. Otherwise we want to make a new one to link at the list's end.   */  if (!t)  {    t = mutt_new_spam_list();    t->rx = rx;    if (last)      last->next = t;    else      *list = t;  }  /* Now t is the SPAM_LIST* that we want to modify. It is prepared. */  t->template = safe_strdup(templ);  /* Find highest match number in template string */  t->nmatch = 0;  for (p = templ; *p;)  {    if (*p == '%')    {        n = atoi(++p);        if (n > t->nmatch)          t->nmatch = n;        while (*p && isdigit((int)*p))          ++p;    }    else        ++p;  }  t->nmatch++;		/* match 0 is always the whole expr */  return 0;}static int remove_from_spam_list (SPAM_LIST **list, const char *pat){  SPAM_LIST *spam, *prev;  int nremoved = 0;  /* Being first is a special case. */  spam = *list;  if (!spam)    return 0;  if (spam->rx && !mutt_strcmp(spam->rx->pattern, pat))  {    *list = spam->next;    mutt_free_regexp(&spam->rx);    FREE(&spam->template);    FREE(&spam);    return 1;  }  prev = spam;  for (spam = prev->next; spam;)  {    if (!mutt_strcmp(spam->rx->pattern, pat))    {      prev->next = spam->next;      mutt_free_regexp(&spam->rx);      FREE(&spam->template);      FREE(&spam);      spam = prev->next;      ++nremoved;    }    else      spam = spam->next;  }  return nremoved;}static void remove_from_list (LIST **l, const char *str){

⌨️ 快捷键说明

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