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

📄 init.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 5 页
字号:
    for (i = 0; Commands[i].name; i++)    {      if (!mutt_strcmp (token->data, Commands[i].name))      {	if (Commands[i].func (token, &expn, Commands[i].data, err) != 0)	  goto finish;        break;      }    }    if (!Commands[i].name)    {      snprintf (err->data, err->dsize, _("%s: unknown command"), NONULL (token->data));      goto finish;    }  }  r = 0;finish:  if (expn.destroy)    FREE (&expn.data);  return (r);}#define NUMVARS (sizeof (MuttVars)/sizeof (MuttVars[0]))#define NUMCOMMANDS (sizeof (Commands)/sizeof (Commands[0]))/* initial string that starts completion. No telling how much crap  * the user has typed so far. Allocate LONG_STRING just to be sure! */char User_typed [LONG_STRING] = {0}; int  Num_matched = 0; /* Number of matches for completion */char Completed [STRING] = {0}; /* completed string (command or variable) */const char **Matches;/* this is a lie until mutt_init runs: */int  Matches_listsize = MAX(NUMVARS,NUMCOMMANDS) + 10;static void matches_ensure_morespace(int current){  int base_space, extra_space, space;  if (current > Matches_listsize - 2)  {    base_space = MAX(NUMVARS,NUMCOMMANDS) + 1;     extra_space = Matches_listsize - base_space;    extra_space *= 2;    space = base_space + extra_space;    safe_realloc (&Matches, space * sizeof (char *));    memset (&Matches[current + 1], 0, space - current);    Matches_listsize = space;  }}/* helper function for completion.  Changes the dest buffer if   necessary/possible to aid completion.	dest == completion result gets here.	src == candidate for completion.	try == user entered data for completion.	len == length of dest buffer.*/static void candidate (char *dest, char *try, const char *src, int len){  int l;  if (strstr (src, try) == src)  {    matches_ensure_morespace (Num_matched);    Matches[Num_matched++] = src;    if (dest[0] == 0)      strfcpy (dest, src, len);    else    {      for (l = 0; src[l] && src[l] == dest[l]; l++);      dest[l] = 0;    }  }}int mutt_command_complete (char *buffer, size_t len, int pos, int numtabs){  char *pt = buffer;  int num;  int spaces; /* keep track of the number of leading spaces on the line */  myvar_t *myv;  SKIPWS (buffer);  spaces = buffer - pt;  pt = buffer + pos - spaces;  while ((pt > buffer) && !isspace ((unsigned char) *pt))    pt--;  if (pt == buffer) /* complete cmd */  {    /* first TAB. Collect all the matches */    if (numtabs == 1)    {      Num_matched = 0;      strfcpy (User_typed, pt, sizeof (User_typed));      memset (Matches, 0, Matches_listsize);      memset (Completed, 0, sizeof (Completed));      for (num = 0; Commands[num].name; num++)	candidate (Completed, User_typed, Commands[num].name, sizeof (Completed));      matches_ensure_morespace (Num_matched);      Matches[Num_matched++] = User_typed;      /* All matches are stored. Longest non-ambiguous string is ""       * i.e. dont change 'buffer'. Fake successful return this time */      if (User_typed[0] == 0)	return 1;    }    if (Completed[0] == 0 && User_typed[0])      return 0;     /* Num_matched will _always_ be atleast 1 since the initial      * user-typed string is always stored */    if (numtabs == 1 && Num_matched == 2)      snprintf(Completed, sizeof(Completed),"%s", Matches[0]);    else if (numtabs > 1 && Num_matched > 2)      /* cycle thru all the matches */      snprintf(Completed, sizeof(Completed), "%s", 	       Matches[(numtabs - 2) % Num_matched]);    /* return the completed command */    strncpy (buffer, Completed, len - spaces);  }  else if (!mutt_strncmp (buffer, "set", 3)	   || !mutt_strncmp (buffer, "unset", 5)	   || !mutt_strncmp (buffer, "reset", 5)	   || !mutt_strncmp (buffer, "toggle", 6))  { 		/* complete variables */    char *prefixes[] = { "no", "inv", "?", "&", 0 };        pt++;    /* loop through all the possible prefixes (no, inv, ...) */    if (!mutt_strncmp (buffer, "set", 3))    {      for (num = 0; prefixes[num]; num++)      {	if (!mutt_strncmp (pt, prefixes[num], mutt_strlen (prefixes[num])))	{	  pt += mutt_strlen (prefixes[num]);	  break;	}      }    }        /* first TAB. Collect all the matches */    if (numtabs == 1)    {      Num_matched = 0;      strfcpy (User_typed, pt, sizeof (User_typed));      memset (Matches, 0, Matches_listsize);      memset (Completed, 0, sizeof (Completed));      for (num = 0; MuttVars[num].option; num++)	candidate (Completed, User_typed, MuttVars[num].option, sizeof (Completed));      for (myv = MyVars; myv; myv = myv->next)	candidate (Completed, User_typed, myv->name, sizeof (Completed));      matches_ensure_morespace (Num_matched);      Matches[Num_matched++] = User_typed;      /* All matches are stored. Longest non-ambiguous string is ""       * i.e. dont change 'buffer'. Fake successful return this time */      if (User_typed[0] == 0)	return 1;    }    if (Completed[0] == 0 && User_typed[0])      return 0;    /* Num_matched will _always_ be atleast 1 since the initial     * user-typed string is always stored */    if (numtabs == 1 && Num_matched == 2)      snprintf(Completed, sizeof(Completed),"%s", Matches[0]);    else if (numtabs > 1 && Num_matched > 2)    /* cycle thru all the matches */      snprintf(Completed, sizeof(Completed), "%s", 	       Matches[(numtabs - 2) % Num_matched]);    strncpy (pt, Completed, buffer + len - pt - spaces);  }  else if (!mutt_strncmp (buffer, "exec", 4))  {    struct binding_t *menu = km_get_table (CurrentMenu);    if (!menu && CurrentMenu != MENU_PAGER)      menu = OpGeneric;        pt++;    /* first TAB. Collect all the matches */    if (numtabs == 1)    {      Num_matched = 0;      strfcpy (User_typed, pt, sizeof (User_typed));      memset (Matches, 0, Matches_listsize);      memset (Completed, 0, sizeof (Completed));      for (num = 0; menu[num].name; num++)	candidate (Completed, User_typed, menu[num].name, sizeof (Completed));      /* try the generic menu */      if (Completed[0] == 0 && CurrentMenu != MENU_PAGER)       {	menu = OpGeneric;	for (num = 0; menu[num].name; num++)	  candidate (Completed, User_typed, menu[num].name, sizeof (Completed));      }      matches_ensure_morespace (Num_matched);      Matches[Num_matched++] = User_typed;      /* All matches are stored. Longest non-ambiguous string is ""       * i.e. dont change 'buffer'. Fake successful return this time */      if (User_typed[0] == 0)	return 1;    }    if (Completed[0] == 0 && User_typed[0])      return 0;    /* Num_matched will _always_ be atleast 1 since the initial     * user-typed string is always stored */    if (numtabs == 1 && Num_matched == 2)      snprintf(Completed, sizeof(Completed),"%s", Matches[0]);    else if (numtabs > 1 && Num_matched > 2)    /* cycle thru all the matches */      snprintf(Completed, sizeof(Completed), "%s", 	       Matches[(numtabs - 2) % Num_matched]);    strncpy (pt, Completed, buffer + len - pt - spaces);  }  else    return 0;  return 1;}int mutt_var_value_complete (char *buffer, size_t len, int pos){  char var[STRING], *pt = buffer;  int spaces;    if (buffer[0] == 0)    return 0;  SKIPWS (buffer);  spaces = buffer - pt;  pt = buffer + pos - spaces;  while ((pt > buffer) && !isspace ((unsigned char) *pt))    pt--;  pt++; /* move past the space */  if (*pt == '=') /* abort if no var before the '=' */    return 0;  if (mutt_strncmp (buffer, "set", 3) == 0)  {    int idx;    char val[LONG_STRING];    const char *myvarval;    strfcpy (var, pt, sizeof (var));    /* ignore the trailing '=' when comparing */    var[mutt_strlen (var) - 1] = 0;    if ((idx = mutt_option_index (var)) == -1)    {      if ((myvarval = myvar_get(var)) != NULL)      {	snprintf (pt, len - (pt - buffer), "%s=\"%s\"", var, myvarval);	return 1;      }      return 0; /* no such variable. */    }    else if (var_to_string (idx, val, sizeof (val)))    {      snprintf (pt, len - (pt - buffer), "%s=\"%s\"", var, val);      return 1;    }  }  return 0;}static int var_to_string (int idx, char* val, size_t len){  char tmp[LONG_STRING];  char *s, *d;  char *vals[] = { "no", "yes", "ask-no", "ask-yes" };  tmp[0] = '\0';  if ((DTYPE(MuttVars[idx].type) == DT_STR) ||      (DTYPE(MuttVars[idx].type) == DT_PATH) ||      (DTYPE(MuttVars[idx].type) == DT_RX))  {    strfcpy (tmp, NONULL (*((char **) MuttVars[idx].data)), sizeof (tmp));    if (DTYPE (MuttVars[idx].type) == DT_PATH)      mutt_pretty_mailbox (tmp);  }  else if (DTYPE (MuttVars[idx].type) == DT_ADDR)  {    rfc822_write_address (tmp, sizeof (tmp), *((ADDRESS **) MuttVars[idx].data), 0);  }  else if (DTYPE (MuttVars[idx].type) == DT_QUAD)    strfcpy (tmp, vals[quadoption (MuttVars[idx].data)], sizeof (tmp));  else if (DTYPE (MuttVars[idx].type) == DT_NUM)    snprintf (tmp, sizeof (tmp), "%d", (*((short *) MuttVars[idx].data)));  else if (DTYPE (MuttVars[idx].type) == DT_SORT)  {    const struct mapping_t *map;    char *p;    switch (MuttVars[idx].type & DT_SUBTYPE_MASK)    {      case DT_SORT_ALIAS:        map = SortAliasMethods;        break;      case DT_SORT_BROWSER:        map = SortBrowserMethods;        break;      case DT_SORT_KEYS:        if ((WithCrypto & APPLICATION_PGP))          map = SortKeyMethods;        else          map = SortMethods;        break;      default:        map = SortMethods;        break;    }    p = mutt_getnamebyvalue (*((short *) MuttVars[idx].data) & SORT_MASK, map);    snprintf (tmp, sizeof (tmp), "%s%s%s",              (*((short *) MuttVars[idx].data) & SORT_REVERSE) ? "reverse-" : "",              (*((short *) MuttVars[idx].data) & SORT_LAST) ? "last-" : "",              p);  }  else if (DTYPE (MuttVars[idx].type) == DT_MAGIC)  {    char *p;    switch (DefaultMagic)    {      case M_MBOX:        p = "mbox";        break;      case M_MMDF:        p = "MMDF";        break;      case M_MH:        p = "MH";        break;      case M_MAILDIR:        p = "Maildir";        break;      default:        p = "unknown";    }    strfcpy (tmp, p, sizeof (tmp));  }  else if (DTYPE (MuttVars[idx].type) == DT_BOOL)    strfcpy (tmp, option (MuttVars[idx].data) ? "yes" : "no", sizeof (tmp));  else    return 0;  for (s = tmp, d = val; *s && len - (d - val) > 2; len--)  {    if (*s == '\\' || *s == '"')      *d++ = '\\';    *d++ = *s++;  }  *d = '\0';  return 1;}/* Implement the -Q command line flag */int mutt_query_variables (LIST *queries){  LIST *p;    char errbuff[STRING];  char command[STRING];    BUFFER err, token;    memset (&err, 0, sizeof (err));  memset (&token, 0, sizeof (token));    err.data = errbuff;  err.dsize = sizeof (errbuff);    for (p = queries; p; p = p->next)  {    snprintf (command, sizeof (command), "set ?%s\n", p->data);    if (mutt_parse_rc_line (command, &token, &err) == -1)    {      fprintf (stderr, "%s\n", err.data);      FREE (&token.data);      return 1;    }    printf ("%s\n", err.data);  }    FREE (&token.data);  return 0;}/* dump out the value of all the variables we have */int mutt_dump_variables (void){  int i;    char errbuff[STRING];  char command[STRING];    BUFFER err, token;    memset (&err, 0, sizeof (err));  memset (&token, 0, sizeof (token));    err.data = errbuff;  err.dsize = sizeof (errbuff);    for (i = 0; MuttVars[i].option; i++)  {    if (MuttVars[i].type == DT_SYN)      continue;    snprintf (command, sizeof (command), "set ?%s\n", MuttVars[i].option);    if (mutt_parse_rc_line (command, &token, &err) == -1)    {      fprintf (stderr, "%s\n", err.data);      FREE (&token.data);      return 1;    }    printf("%s\n", err.data);  }    FREE (&token.data);  return 0;}char *mutt_getnamebyvalue (int val, const struct mapping_t *map){  int i;  for (i=0; map[i].name; i++)    if (map[i].value == val)      return (map[i].name);  return NULL;}int mutt_getvaluebyname (const char *name, const struct mapping_t *map){  int i;  for (i = 0; map[i].name; i++)    if (ascii_strcasecmp (map[i].name, name) == 0)      return (map[i].value);  return (-1);}#ifdef DEBUGstatic void start_debug (void){  time_t t;  int i;  char buf[_POSIX_PATH_MAX];  char buf2[_POSIX_PATH_MAX];  /* rotate the old debug logs */  for (i=3; i>=0; i--)  {    snprintf (buf, sizeof(buf), "%s/.muttdebug%d", NONULL(Homedir), i);    snprintf (buf2, sizeof(buf2), "%s/.muttdebug%d", NONULL(Homedir), i+1);    rename (buf, buf2);  }  if ((debugfile = safe_fopen(buf, "w")) != NULL)  {    t = time (0);    setbuf (debugfile, NULL); /* don't buffer the debugging output! */    fprintf (debugfile, "Mutt %s started at %s.\nDebugging at level %d.\n\n",	     MUTT_VERSION, asctime (localtime (&t)), debuglevel);  }}#endifstatic int mutt_execute_commands (LIST *p){  BUFFER err, token;  char errstr[SHORT_STRING];  memset (&err, 0, sizeof (err));  err.data = errstr;  err.dsize = sizeof (errstr);  memset (&token, 0, sizeof (token));  for (; p; p = p->next)  {    if (mutt_parse_rc_line (p->data, &token, &err) != 0)    {      fprintf (stderr, _("Error in command line: %s\n"), err.data);      FREE (&token.data);      return (-1);    }  }  FREE (&token.data);  return 0;}void mutt_init (int skip_sys_rc, LIST *commands){  struct passwd *pw;  struct utsname utsname;  char *p, buffer[STRING], error[STRING];  int i, default_rc = 0, need_pause = 0;  BUFFER err;  memset (&err, 0, sizeof (err));  err.data = error;  err.dsize = sizeof (error);  Groups = hash_create (1031);    /*    * XXX - use something even more difficult to predict?   */  snprintf (AttachmentMarker, sizeof (AttachmentMarker),	    "\033]9;%ld\a", (long) time (NULL));    /* on one of the systems I use, getcwd() does not return the same prefix     as is listed in the passwd file */  if ((p = getenv ("HOME")))    Homedir = safe_strdup (p);  /* Get some information about the user */  if ((pw = getpwuid (getuid ())))  {    char rnbuf[STRING];    Username = safe_strdup (pw->pw_name);    if (!Homedir)      Homedir = safe_strdup (pw->pw_dir);    Realname = safe_strdup (mutt_gecos_name (rnbuf, sizeof (rnbuf), pw));    Shell = safe_strdup (pw->pw_shell);    endpwent ();  }  else   {    if (!Homedir)    {      mutt_endwin (NULL);      fputs (_("unable to determine home directory"), stderr);      exit (1);    }    if ((p = getenv ("USER")))      Username = safe_strdup (p);    else    {      mutt_endwin (NULL);      fputs (_("unable to determine username"), stderr);      exit (1);    }    Shell = safe_strdup ((p =

⌨️ 快捷键说明

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