📄 init.c
字号:
if (!mutt_strcmp ("all", tmp->data)) { if (CurrentMenu == MENU_PAGER) { snprintf (err->data, err->dsize, _("Not available in this menu.")); return (-1); } for (idx = 0; MuttVars[idx].option; idx++) mutt_restore_default (&MuttVars[idx]); set_option (OPTFORCEREDRAWINDEX); set_option (OPTFORCEREDRAWPAGER); set_option (OPTSORTSUBTHREADS); set_option (OPTNEEDRESORT); set_option (OPTRESORTINIT); set_option (OPTREDRAWTREE); return 0; } else { CHECK_PAGER; if (myvar) myvar_del (myvar); else mutt_restore_default (&MuttVars[idx]); } } else if (!myvar && DTYPE (MuttVars[idx].type) == DT_BOOL) { if (s && *s->dptr == '=') { if (unset || inv || query) { snprintf (err->data, err->dsize, "Usage: set variable=yes|no"); return (-1); } s->dptr++; mutt_extract_token (tmp, s, 0); if (ascii_strcasecmp ("yes", tmp->data) == 0) unset = inv = 0; else if (ascii_strcasecmp ("no", tmp->data) == 0) unset = 1; else { snprintf (err->data, err->dsize, "Usage: set variable=yes|no"); return (-1); } } if (query) { snprintf (err->data, err->dsize, option (MuttVars[idx].data) ? _("%s is set") : _("%s is unset"), tmp->data); return 0; } CHECK_PAGER; if (unset) unset_option (MuttVars[idx].data); else if (inv) toggle_option (MuttVars[idx].data); else set_option (MuttVars[idx].data); } else if (myvar || DTYPE (MuttVars[idx].type) == DT_STR || DTYPE (MuttVars[idx].type) == DT_PATH || DTYPE (MuttVars[idx].type) == DT_ADDR) { if (unset) { CHECK_PAGER; if (myvar) myvar_del (myvar); else if (DTYPE (MuttVars[idx].type) == DT_ADDR) rfc822_free_address ((ADDRESS **) MuttVars[idx].data); else /* MuttVars[idx].data is already 'char**' (or some 'void**') or... * so cast to 'void*' is okay */ FREE ((void *) MuttVars[idx].data); /* __FREE_CHECKED__ */ } else if (query || *s->dptr != '=') { char _tmp[STRING]; const char *val = NULL; if (myvar) { if ((val = myvar_get (myvar))) { snprintf (err->data, err->dsize, "%s=\"%s\"", myvar, val); break; } else { snprintf (err->data, err->dsize, _("%s: unknown variable"), myvar); return (-1); } } else if (DTYPE (MuttVars[idx].type) == DT_ADDR) { _tmp[0] = '\0'; rfc822_write_address (_tmp, sizeof (_tmp), *((ADDRESS **) MuttVars[idx].data), 0); val = _tmp; } else val = *((char **) MuttVars[idx].data); /* user requested the value of this variable */ snprintf (err->data, err->dsize, "%s=\"%s\"", MuttVars[idx].option, NONULL (val)); break; } else { CHECK_PAGER; s->dptr++; if (myvar) { /* myvar is a pointer to tmp and will be lost on extract_token */ myvar = safe_strdup (myvar); myvar_del (myvar); } else if (DTYPE (MuttVars[idx].type) == DT_ADDR) rfc822_free_address ((ADDRESS **) MuttVars[idx].data); else /* MuttVars[idx].data is already 'char**' (or some 'void**') or... * so cast to 'void*' is okay */ FREE ((void *) MuttVars[idx].data); /* __FREE_CHECKED__ */ mutt_extract_token (tmp, s, 0); if (myvar) { myvar_set (myvar, tmp->data); FREE (&myvar); myvar="don't resort"; } else if (DTYPE (MuttVars[idx].type) == DT_PATH) { strfcpy (scratch, tmp->data, sizeof (scratch)); mutt_expand_path (scratch, sizeof (scratch)); *((char **) MuttVars[idx].data) = safe_strdup (scratch); } else if (DTYPE (MuttVars[idx].type) == DT_STR) { *((char **) MuttVars[idx].data) = safe_strdup (tmp->data); if (mutt_strcmp (MuttVars[idx].option, "charset") == 0) mutt_set_charset (Charset); } else { *((ADDRESS **) MuttVars[idx].data) = rfc822_parse_adrlist (NULL, tmp->data); } } } else if (DTYPE(MuttVars[idx].type) == DT_RX) { REGEXP *ptr = (REGEXP *) MuttVars[idx].data; regex_t *rx; int e, flags = 0; if (query || *s->dptr != '=') { /* user requested the value of this variable */ snprintf (err->data, err->dsize, "%s=\"%s\"", MuttVars[idx].option, NONULL (ptr->pattern)); break; } if (option(OPTATTACHMSG) && !mutt_strcmp(MuttVars[idx].option, "reply_regexp")) { snprintf (err->data, err->dsize, "Operation not permitted when in attach-message mode."); r = -1; break; } CHECK_PAGER; s->dptr++; /* copy the value of the string */ mutt_extract_token (tmp, s, 0); if (!ptr->pattern || mutt_strcmp (ptr->pattern, tmp->data) != 0) { int not = 0; /* $mask is case-sensitive */ if (mutt_strcmp (MuttVars[idx].option, "mask") != 0) flags |= mutt_which_case (tmp->data); p = tmp->data; if (mutt_strcmp (MuttVars[idx].option, "mask") == 0) { if (*p == '!') { not = 1; p++; } } rx = (regex_t *) safe_malloc (sizeof (regex_t)); if ((e = REGCOMP (rx, p, flags)) != 0) { regerror (e, rx, err->data, err->dsize); regfree (rx); FREE (&rx); break; } /* get here only if everything went smootly */ if (ptr->pattern) { FREE (&ptr->pattern); regfree ((regex_t *) ptr->rx); FREE (&ptr->rx); } ptr->pattern = safe_strdup (tmp->data); ptr->rx = rx; ptr->not = not; /* $reply_regexp and $alterantes require special treatment */ if (Context && Context->msgcount && mutt_strcmp (MuttVars[idx].option, "reply_regexp") == 0) { regmatch_t pmatch[1]; int i; #define CUR_ENV Context->hdrs[i]->env for (i = 0; i < Context->msgcount; i++) { if (CUR_ENV && CUR_ENV->subject) { CUR_ENV->real_subj = (regexec (ReplyRegexp.rx, CUR_ENV->subject, 1, pmatch, 0)) ? CUR_ENV->subject : CUR_ENV->subject + pmatch[0].rm_eo; } }#undef CUR_ENV } } } else if (DTYPE(MuttVars[idx].type) == DT_MAGIC) { if (query || *s->dptr != '=') { 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"; break; } snprintf (err->data, err->dsize, "%s=%s", MuttVars[idx].option, p); break; } CHECK_PAGER; s->dptr++; /* copy the value of the string */ mutt_extract_token (tmp, s, 0); if (mx_set_magic (tmp->data)) { snprintf (err->data, err->dsize, _("%s: invalid mailbox type"), tmp->data); r = -1; break; } } else if (DTYPE(MuttVars[idx].type) == DT_NUM) { short *ptr = (short *) MuttVars[idx].data; int val; char *t; if (query || *s->dptr != '=') { /* user requested the value of this variable */ snprintf (err->data, err->dsize, "%s=%d", MuttVars[idx].option, *ptr); break; } CHECK_PAGER; s->dptr++; mutt_extract_token (tmp, s, 0); val = strtol (tmp->data, &t, 0); if (!*tmp->data || *t || (short) val != val) { snprintf (err->data, err->dsize, _("%s: invalid value"), tmp->data); r = -1; break; } else *ptr = (short) val; /* these ones need a sanity check */ if (mutt_strcmp (MuttVars[idx].option, "history") == 0) { if (*ptr < 0) *ptr = 0; mutt_init_history (); } else if (mutt_strcmp (MuttVars[idx].option, "pager_index_lines") == 0) { if (*ptr < 0) *ptr = 0; } } else if (DTYPE (MuttVars[idx].type) == DT_QUAD) { if (query) { char *vals[] = { "no", "yes", "ask-no", "ask-yes" }; snprintf (err->data, err->dsize, "%s=%s", MuttVars[idx].option, vals [ quadoption (MuttVars[idx].data) ]); break; } CHECK_PAGER; if (*s->dptr == '=') { s->dptr++; mutt_extract_token (tmp, s, 0); if (ascii_strcasecmp ("yes", tmp->data) == 0) set_quadoption (MuttVars[idx].data, M_YES); else if (ascii_strcasecmp ("no", tmp->data) == 0) set_quadoption (MuttVars[idx].data, M_NO); else if (ascii_strcasecmp ("ask-yes", tmp->data) == 0) set_quadoption (MuttVars[idx].data, M_ASKYES); else if (ascii_strcasecmp ("ask-no", tmp->data) == 0) set_quadoption (MuttVars[idx].data, M_ASKNO); else { snprintf (err->data, err->dsize, _("%s: invalid value"), tmp->data); r = -1; break; } } else { if (inv) toggle_quadoption (MuttVars[idx].data); else if (unset) set_quadoption (MuttVars[idx].data, M_NO); else set_quadoption (MuttVars[idx].data, M_YES); } } else if (DTYPE (MuttVars[idx].type) == DT_SORT) { const struct mapping_t *map = NULL; 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; break; case DT_SORT_AUX: map = SortAuxMethods; break; default: map = SortMethods; break; } if (!map) { snprintf (err->data, err->dsize, _("%s: Unknown type."), MuttVars[idx].option); r = -1; break; } if (query || *s->dptr != '=') { p = mutt_getnamebyvalue (*((short *) MuttVars[idx].data) & SORT_MASK, map); snprintf (err->data, err->dsize, "%s=%s%s%s", MuttVars[idx].option, (*((short *) MuttVars[idx].data) & SORT_REVERSE) ? "reverse-" : "", (*((short *) MuttVars[idx].data) & SORT_LAST) ? "last-" : "", p); return 0; } CHECK_PAGER; s->dptr++; mutt_extract_token (tmp, s , 0); if (parse_sort ((short *) MuttVars[idx].data, tmp->data, map, err) == -1) { r = -1; break; } } else { snprintf (err->data, err->dsize, _("%s: unknown type"), MuttVars[idx].option); r = -1; break; } if (!myvar) { if (MuttVars[idx].flags & R_INDEX) set_option (OPTFORCEREDRAWINDEX); if (MuttVars[idx].flags & R_PAGER) set_option (OPTFORCEREDRAWPAGER); if (MuttVars[idx].flags & R_RESORT_SUB) set_option (OPTSORTSUBTHREADS); if (MuttVars[idx].flags & R_RESORT) set_option (OPTNEEDRESORT); if (MuttVars[idx].flags & R_RESORT_INIT) set_option (OPTRESORTINIT); if (MuttVars[idx].flags & R_TREE) set_option (OPTREDRAWTREE); } } return (r);}#define MAXERRS 128/* reads the specified initialization file. returns -1 if errors were found so that we can pause to let the user know... */static int source_rc (const char *rcfile, BUFFER *err){ FILE *f; int line = 0, rc = 0, conv = 0; BUFFER token; char *linebuf = NULL; char *currentline = NULL; size_t buflen; pid_t pid; dprint (2, (debugfile, "Reading configuration file '%s'.\n", rcfile)); if ((f = mutt_open_read (rcfile, &pid)) == NULL) { snprintf (err->data, err->dsize, "%s: %s", rcfile, strerror (errno)); return (-1); } memset (&token, 0, sizeof (token)); while ((linebuf = mutt_read_line (linebuf, &buflen, f, &line)) != NULL) { conv=ConfigCharset && (*ConfigCharset) && Charset; if (conv) { currentline=safe_strdup(linebuf); if (!currentline) continue; mutt_convert_string(¤tline, ConfigCharset, Charset, 0); } else currentline=linebuf; if (mutt_parse_rc_line (currentline, &token, err) == -1) { mutt_error (_("Error in %s, line %d: %s"), rcfile, line, err->data); if (--rc < -MAXERRS) { if (conv) FREE(¤tline); break; } } else { if (rc < 0) rc = -1; } if (conv) FREE(¤tline); } FREE (&token.data); FREE (&linebuf); fclose (f); if (pid != -1) mutt_wait_filter (pid); if (rc) { /* the muttrc source keyword */ snprintf (err->data, err->dsize, rc >= -MAXERRS ? _("source: errors in %s") : _("source: reading aborted due too many errors in %s"), rcfile); rc = -1; } return (rc);}#undef MAXERRSstatic int parse_source (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err){ char path[_POSIX_PATH_MAX]; if (mutt_extract_token (tmp, s, 0) != 0) { snprintf (err->data, err->dsize, _("source: error at %s"), s->dptr); return (-1); } if (MoreArgs (s)) { strfcpy (err->data, _("source: too many arguments"), err->dsize); return (-1); } strfcpy (path, tmp->data, sizeof (path)); mutt_expand_path (path, sizeof (path)); return (source_rc (path, err));}/* line command to execute token scratch buffer to be used by parser. caller should free token->data when finished. the reason for this variable is to avoid having to allocate and deallocate a lot of memory if we are parsing many lines. the caller can pass in the memory to use, which avoids having to create new space for every call to this function. err where to write error messages */int mutt_parse_rc_line (/* const */ char *line, BUFFER *token, BUFFER *err){ int i, r = -1; BUFFER expn; memset (&expn, 0, sizeof (expn)); expn.data = expn.dptr = line; expn.dsize = mutt_strlen (line); *err->data = 0; SKIPWS (expn.dptr); while (*expn.dptr) { if (*expn.dptr == '#') break; /* rest of line is a comment */ if (*expn.dptr == ';') { expn.dptr++; continue; } mutt_extract_token (token, &expn, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -