📄 muttlib.c
字号:
char *mutt_get_parameter (const char *s, PARAMETER *p){ for (; p; p = p->next) if (ascii_strcasecmp (s, p->attribute) == 0) return (p->value); return NULL;}void mutt_set_parameter (const char *attribute, const char *value, PARAMETER **p){ PARAMETER *q; if (!value) { mutt_delete_parameter (attribute, p); return; } for(q = *p; q; q = q->next) { if (ascii_strcasecmp (attribute, q->attribute) == 0) { mutt_str_replace (&q->value, value); return; } } q = mutt_new_parameter(); q->attribute = safe_strdup(attribute); q->value = safe_strdup(value); q->next = *p; *p = q;}void mutt_delete_parameter (const char *attribute, PARAMETER **p){ PARAMETER *q; for (q = *p; q; p = &q->next, q = q->next) { if (ascii_strcasecmp (attribute, q->attribute) == 0) { *p = q->next; q->next = NULL; mutt_free_parameter (&q); return; } }}/* returns 1 if Mutt can't display this type of data, 0 otherwise */int mutt_needs_mailcap (BODY *m){ switch (m->type) { case TYPETEXT: if (!ascii_strcasecmp ("plain", m->subtype) || !ascii_strcasecmp ("rfc822-headers", m->subtype) || !ascii_strcasecmp ("enriched", m->subtype)) return 0; break; case TYPEAPPLICATION: if((WithCrypto & APPLICATION_PGP) && mutt_is_application_pgp(m)) return 0; if((WithCrypto & APPLICATION_SMIME) && mutt_is_application_smime(m)) return 0; break; case TYPEMULTIPART: case TYPEMESSAGE: return 0; } return 1;}int mutt_is_text_part (BODY *b){ int t = b->type; char *s = b->subtype; if ((WithCrypto & APPLICATION_PGP) && mutt_is_application_pgp (b)) return 0; if (t == TYPETEXT) return 1; if (t == TYPEMESSAGE) { if (!ascii_strcasecmp ("delivery-status", s)) return 1; } if ((WithCrypto & APPLICATION_PGP) && t == TYPEAPPLICATION) { if (!ascii_strcasecmp ("pgp-keys", s)) return 1; } return 0;}void mutt_free_envelope (ENVELOPE **p){ if (!*p) return; rfc822_free_address (&(*p)->return_path); rfc822_free_address (&(*p)->from); rfc822_free_address (&(*p)->to); rfc822_free_address (&(*p)->cc); rfc822_free_address (&(*p)->bcc); rfc822_free_address (&(*p)->sender); rfc822_free_address (&(*p)->reply_to); rfc822_free_address (&(*p)->mail_followup_to); FREE (&(*p)->list_post); FREE (&(*p)->subject); /* real_subj is just an offset to subject and shouldn't be freed */ FREE (&(*p)->message_id); FREE (&(*p)->supersedes); FREE (&(*p)->date); FREE (&(*p)->x_label); mutt_buffer_free (&(*p)->spam); mutt_free_list (&(*p)->references); mutt_free_list (&(*p)->in_reply_to); mutt_free_list (&(*p)->userhdrs); FREE (p); /* __FREE_CHECKED__ */}/* move all the headers from extra not present in base into base */void mutt_merge_envelopes(ENVELOPE* base, ENVELOPE** extra){ /* copies each existing element if necessary, and sets the element * to NULL in the source so that mutt_free_envelope doesn't leave us * with dangling pointers. */#define MOVE_ELEM(h) if (!base->h) { base->h = (*extra)->h; (*extra)->h = NULL; } MOVE_ELEM(return_path); MOVE_ELEM(from); MOVE_ELEM(to); MOVE_ELEM(cc); MOVE_ELEM(bcc); MOVE_ELEM(sender); MOVE_ELEM(reply_to); MOVE_ELEM(mail_followup_to); MOVE_ELEM(list_post); MOVE_ELEM(message_id); MOVE_ELEM(supersedes); MOVE_ELEM(date); MOVE_ELEM(x_label); if (!base->refs_changed) { MOVE_ELEM(references); } if (!base->irt_changed) { MOVE_ELEM(in_reply_to); } /* real_subj is subordinate to subject */ if (!base->subject) { base->subject = (*extra)->subject; base->real_subj = (*extra)->real_subj; (*extra)->subject = NULL; (*extra)->real_subj = NULL; } /* spam and user headers should never be hashed, and the new envelope may * have better values. Use new versions regardless. */ mutt_buffer_free (&base->spam); mutt_free_list (&base->userhdrs); MOVE_ELEM(spam); MOVE_ELEM(userhdrs);#undef MOVE_ELEM mutt_free_envelope(extra);}void _mutt_mktemp (char *s, const char *src, int line){ snprintf (s, _POSIX_PATH_MAX, "%s/mutt-%s-%d-%d-%d", NONULL (Tempdir), NONULL(Hostname), (int) getuid(), (int) getpid (), Counter++); dprint (1, (debugfile, "%s:%d: mutt_mktemp returns \"%s\".\n", src, line, s)); unlink (s);}void mutt_free_alias (ALIAS **p){ ALIAS *t; while (*p) { t = *p; *p = (*p)->next; FREE (&t->name); rfc822_free_address (&t->addr); FREE (&t); }}/* collapse the pathname using ~ or = when possible */void mutt_pretty_mailbox (char *s){ char *p = s, *q = s; size_t len; url_scheme_t scheme; scheme = url_check_scheme (s);#ifdef USE_IMAP if (scheme == U_IMAP || scheme == U_IMAPS) { imap_pretty_mailbox (s); return; }#endif /* if s is an url, only collapse path component */ if (scheme != U_UNKNOWN) { p = strchr(s, ':')+1; if (!strncmp (p, "//", 2)) q = strchr (p+2, '/'); if (!q) q = strchr (p, '\0'); p = q; } /* first attempt to collapse the pathname */ while (*p) { if (*p == '/' && p[1] == '/') { *q++ = '/'; p += 2; } else if (p[0] == '/' && p[1] == '.' && p[2] == '/') { *q++ = '/'; p += 3; } else *q++ = *p++; } *q = 0; if (mutt_strncmp (s, Maildir, (len = mutt_strlen (Maildir))) == 0 && s[len] == '/') { *s++ = '='; memmove (s, s + len, mutt_strlen (s + len) + 1); } else if (mutt_strncmp (s, Homedir, (len = mutt_strlen (Homedir))) == 0 && s[len] == '/') { *s++ = '~'; memmove (s, s + len - 1, mutt_strlen (s + len - 1) + 1); }}void mutt_pretty_size (char *s, size_t len, long n){ if (n == 0) strfcpy (s, "0K", len); else if (n < 10189) /* 0.1K - 9.9K */ snprintf (s, len, "%3.1fK", (n < 103) ? 0.1 : n / 1024.0); else if (n < 1023949) /* 10K - 999K */ { /* 51 is magic which causes 10189/10240 to be rounded up to 10 */ snprintf (s, len, "%ldK", (n + 51) / 1024); } else if (n < 10433332) /* 1.0M - 9.9M */ snprintf (s, len, "%3.1fM", n / 1048576.0); else /* 10M+ */ { /* (10433332 + 52428) / 1048576 = 10 */ snprintf (s, len, "%ldM", (n + 52428) / 1048576); }}void mutt_expand_file_fmt (char *dest, size_t destlen, const char *fmt, const char *src){ char tmp[LONG_STRING]; mutt_quote_filename (tmp, sizeof (tmp), src); mutt_expand_fmt (dest, destlen, fmt, tmp);}void mutt_expand_fmt (char *dest, size_t destlen, const char *fmt, const char *src){ const char *p; char *d; size_t slen; int found = 0; slen = mutt_strlen (src); destlen--; for (p = fmt, d = dest; destlen && *p; p++) { if (*p == '%') { switch (p[1]) { case '%': *d++ = *p++; destlen--; break; case 's': found = 1; strfcpy (d, src, destlen + 1); d += destlen > slen ? slen : destlen; destlen -= destlen > slen ? slen : destlen; p++; break; default: *d++ = *p; destlen--; break; } } else { *d++ = *p; destlen--; } } *d = '\0'; if (!found && destlen > 0) { safe_strcat (dest, destlen, " "); safe_strcat (dest, destlen, src); } }/* return 0 on success, -1 on abort, 1 on error */int mutt_check_overwrite (const char *attname, const char *path, char *fname, size_t flen, int *append, char **directory) { int rc = 0; char tmp[_POSIX_PATH_MAX]; struct stat st; strfcpy (fname, path, flen); if (access (fname, F_OK) != 0) return 0; if (stat (fname, &st) != 0) return -1; if (S_ISDIR (st.st_mode)) { if (directory) { switch (mutt_multi_choice (_("File is a directory, save under it? [(y)es, (n)o, (a)ll]"), _("yna"))) { case 3: /* all */ mutt_str_replace (directory, fname); break; case 1: /* yes */ FREE (directory); /* __FREE_CHECKED__ */ break; case -1: /* abort */ FREE (directory); /* __FREE_CHECKED__ */ return -1; case 2: /* no */ FREE (directory); /* __FREE_CHECKED__ */ return 1; } } else if ((rc = mutt_yesorno (_("File is a directory, save under it?"), M_YES)) != M_YES) return (rc == M_NO) ? 1 : -1; if (!attname || !attname[0]) { tmp[0] = 0; if (mutt_get_field (_("File under directory: "), tmp, sizeof (tmp), M_FILE | M_CLEAR) != 0 || !tmp[0]) return (-1); mutt_concat_path (fname, path, tmp, flen); } else mutt_concat_path (fname, path, mutt_basename (attname), flen); } if (*append == 0 && access (fname, F_OK) == 0) { switch (mutt_multi_choice (_("File exists, (o)verwrite, (a)ppend, or (c)ancel?"), _("oac"))) { case -1: /* abort */ return -1; case 3: /* cancel */ return 1; case 2: /* append */ *append = M_SAVE_APPEND; break; case 1: /* overwrite */ *append = M_SAVE_OVERWRITE; break; } } return 0;}void mutt_save_path (char *d, size_t dsize, ADDRESS *a){ if (a && a->mailbox) { strfcpy (d, a->mailbox, dsize); if (!option (OPTSAVEADDRESS)) { char *p; if ((p = strpbrk (d, "%@"))) *p = 0; } mutt_strlower (d); } else *d = 0;}void mutt_safe_path (char *s, size_t l, ADDRESS *a){ char *p; mutt_save_path (s, l, a); for (p = s; *p; p++) if (*p == '/' || ISSPACE (*p) || !IsPrint ((unsigned char) *p)) *p = '_';}void mutt_FormatString (char *dest, /* output buffer */ size_t destlen, /* output buffer len */ const char *src, /* template string */ format_t *callback, /* callback for processing */ unsigned long data, /* callback data */ format_flag flags) /* callback flags */{ char prefix[SHORT_STRING], buf[LONG_STRING], *cp, *wptr = dest, ch; char ifstring[SHORT_STRING], elsestring[SHORT_STRING]; size_t wlen, count, len, col, wid; prefix[0] = '\0'; destlen--; /* save room for the terminal \0 */ wlen = (flags & M_FORMAT_ARROWCURSOR && option (OPTARROWCURSOR)) ? 3 : 0; col = wlen; while (*src && wlen < destlen) { if (*src == '%') { if (*++src == '%') { *wptr++ = '%'; wlen++; col++; src++; continue; } if (*src == '?') { flags |= M_FORMAT_OPTIONAL; src++; } else { flags &= ~M_FORMAT_OPTIONAL; /* eat the format string */ cp = prefix; count = 0; while (count < sizeof (prefix) && (isdigit ((unsigned char) *src) || *src == '.' || *src == '-')) { *cp++ = *src++; count++; } *cp = 0; } if (!*src) break; /* bad format */ ch = *src++; /* save the character to switch on */ if (flags & M_FORMAT_OPTIONAL) { if (*src != '?') break; /* bad format */ src++; /* eat the `if' part of the string */ cp = ifstring; count = 0; while (count < sizeof (ifstring) && *src && *src != '?' && *src != '&') { *cp++ = *src++; count++; } *cp = 0; /* eat the `else' part of the string (optional) */ if (*src == '&') src++; /* skip the & */ cp = elsestring; count = 0; while (count < sizeof (elsestring) && *src && *src != '?') { *cp++ = *src++; count++; } *cp = 0; if (!*src) break; /* bad format */ src++; /* move past the trailing `?' */ } /* handle generic cases first */ if (ch == '>') { /* right justify to EOL */ ch = *src++; /* pad char */ /* calculate space left on line. if we've already written more data than will fit on the line, ignore the rest of the line */ count = (COLS < destlen ? COLS : destlen); if (count > col) { count -= col; /* how many columns left on this line */ mutt_FormatString (buf, sizeof (buf), src, callback, data, flags); len = mutt_strlen (buf); wid = mutt_strwidth (buf); if (count > wid) { count -= wid; /* how many chars to pad */ memset (wptr, ch, count); wptr += count;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -