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

📄 muttlib.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org> * Copyright (C) 1999-2000 Thomas Roessler <roessler@does-not-exist.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 "mutt_curses.h"#include "mime.h"#include "mailbox.h"#include "mx.h"#include "url.h"#ifdef USE_IMAP#include "imap.h"#endif#include "mutt_crypt.h"#include <string.h>#include <ctype.h>#include <unistd.h>#include <stdlib.h>#include <sys/wait.h>#include <errno.h>#include <sys/stat.h>#include <fcntl.h>#include <time.h>#include <sys/types.h>#include <utime.h>BODY *mutt_new_body (void){  BODY *p = (BODY *) safe_calloc (1, sizeof (BODY));      p->disposition = DISPATTACH;  p->use_disp = 1;  return (p);}/* Modified by blong to accept a "suggestion" for file name.  If * that file exists, then construct one with unique name but  * keep any extension.  This might fail, I guess. * Renamed to mutt_adv_mktemp so I only have to change where it's * called, and not all possible cases. */void mutt_adv_mktemp (char *s, size_t l){  char buf[_POSIX_PATH_MAX];  char tmp[_POSIX_PATH_MAX];  char *period;  size_t sl;  struct stat sb;    strfcpy (buf, NONULL (Tempdir), sizeof (buf));  mutt_expand_path (buf, sizeof (buf));  if (s[0] == '\0')  {    snprintf (s, l, "%s/muttXXXXXX", buf);    mktemp (s);  }  else  {    strfcpy (tmp, s, sizeof (tmp));    mutt_sanitize_filename (tmp, 1);    snprintf (s, l, "%s/%s", buf, tmp);    if (lstat (s, &sb) == -1 && errno == ENOENT)      return;    if ((period = strrchr (tmp, '.')) != NULL)      *period = 0;    snprintf (s, l, "%s/%s.XXXXXX", buf, tmp);    mktemp (s);    if (period != NULL)    {      *period = '.';      sl = mutt_strlen(s);      strfcpy(s + sl, period, l - sl);    }  }}/* create a send-mode duplicate from a receive-mode body */int mutt_copy_body (FILE *fp, BODY **tgt, BODY *src){  char tmp[_POSIX_PATH_MAX];  BODY *b;  PARAMETER *par, **ppar;    short use_disp;  if (src->filename)  {    use_disp = 1;    strfcpy (tmp, src->filename, sizeof (tmp));  }  else  {    use_disp = 0;    tmp[0] = '\0';  }  mutt_adv_mktemp (tmp, sizeof (tmp));  if (mutt_save_attachment (fp, src, tmp, 0, NULL) == -1)    return -1;        *tgt = mutt_new_body ();  b = *tgt;  memcpy (b, src, sizeof (BODY));  b->parts = NULL;  b->next  = NULL;  b->filename = safe_strdup (tmp);  b->use_disp = use_disp;  b->unlink = 1;  if (mutt_is_text_part (b))    b->noconv = 1;  b->xtype = safe_strdup (b->xtype);  b->subtype = safe_strdup (b->subtype);  b->form_name = safe_strdup (b->form_name);  b->filename = safe_strdup (b->filename);  b->d_filename = safe_strdup (b->d_filename);  b->description = safe_strdup (b->description);  /*    * we don't seem to need the HEADER structure currently.   * XXX - this may change in the future   */  if (b->hdr) b->hdr = NULL;    /* copy parameters */  for (par = b->parameter, ppar = &b->parameter; par; ppar = &(*ppar)->next, par = par->next)  {    *ppar = mutt_new_parameter ();    (*ppar)->attribute = safe_strdup (par->attribute);    (*ppar)->value = safe_strdup (par->value);  }  mutt_stamp_attachment (b);    return 0;}void mutt_free_body (BODY **p){  BODY *a = *p, *b;  while (a)  {    b = a;    a = a->next;     if (b->parameter)      mutt_free_parameter (&b->parameter);    if (b->unlink && b->filename)    {      dprint (1, (debugfile, "mutt_free_body: Unlinking %s.\n", b->filename));      unlink (b->filename);    }    else if (b->filename)       dprint (1, (debugfile, "mutt_free_body: Not unlinking %s.\n", b->filename));    FREE (&b->filename);    FREE (&b->content);    FREE (&b->xtype);    FREE (&b->subtype);    FREE (&b->description);    FREE (&b->form_name);    if (b->hdr)    {      /* Don't free twice (b->hdr->content = b->parts) */      b->hdr->content = NULL;      mutt_free_header(&b->hdr);    }    if (b->parts)      mutt_free_body (&b->parts);    FREE (&b);  }  *p = 0;}void mutt_free_parameter (PARAMETER **p){  PARAMETER *t = *p;  PARAMETER *o;  while (t)  {    FREE (&t->attribute);    FREE (&t->value);    o = t;    t = t->next;    FREE (&o);  }  *p = 0;}LIST *mutt_add_list (LIST *head, const char *data){  size_t len = mutt_strlen (data);  return mutt_add_list_n (head, data, len ? len + 1 : 0);}LIST *mutt_add_list_n (LIST *head, const void *data, size_t len){  LIST *tmp;    for (tmp = head; tmp && tmp->next; tmp = tmp->next)    ;  if (tmp)  {    tmp->next = safe_malloc (sizeof (LIST));    tmp = tmp->next;  }  else    head = tmp = safe_malloc (sizeof (LIST));    tmp->data = safe_malloc (len);  if (len)    memcpy (tmp->data, data, len);  tmp->next = NULL;  return head;}void mutt_free_list (LIST **list){  LIST *p;    if (!list) return;  while (*list)  {    p = *list;    *list = (*list)->next;    FREE (&p->data);    FREE (&p);  }}HEADER *mutt_dup_header(HEADER *h){  HEADER *hnew;  hnew = mutt_new_header();  memcpy(hnew, h, sizeof (HEADER));  return hnew;}void mutt_free_header (HEADER **h){  if(!h || !*h) return;  mutt_free_envelope (&(*h)->env);  mutt_free_body (&(*h)->content);  FREE (&(*h)->maildir_flags);  FREE (&(*h)->tree);  FREE (&(*h)->path);#ifdef MIXMASTER  mutt_free_list (&(*h)->chain);#endif#if defined USE_POP || defined USE_IMAP  FREE (&(*h)->data);#endif  FREE (h);		/* __FREE_CHECKED__ */}/* returns true if the header contained in "s" is in list "t" */int mutt_matches_ignore (const char *s, LIST *t){  for (; t; t = t->next)  {    if (!ascii_strncasecmp (s, t->data, mutt_strlen (t->data)) || *t->data == '*')      return 1;  }  return 0;}/* prepend the path part of *path to *link */void mutt_expand_link (char *newpath, const char *path, const char *link){  const char *lb = NULL;  size_t len;  /* link is full path */  if (*link == '/')  {    strfcpy (newpath, link, _POSIX_PATH_MAX);    return;  }  if ((lb = strrchr (path, '/')) == NULL)  {    /* no path in link */    strfcpy (newpath, link, _POSIX_PATH_MAX);    return;  }  len = lb - path + 1;  memcpy (newpath, path, len);  strfcpy (newpath + len, link, _POSIX_PATH_MAX - len);}char *mutt_expand_path (char *s, size_t slen){  return _mutt_expand_path (s, slen, 0);}char *_mutt_expand_path (char *s, size_t slen, int rx){  char p[_POSIX_PATH_MAX] = "";  char q[_POSIX_PATH_MAX] = "";  char tmp[_POSIX_PATH_MAX];  char *t;  char *tail = "";   int recurse = 0;    do   {    recurse = 0;    switch (*s)    {      case '~':      {	if (*(s + 1) == '/' || *(s + 1) == 0)	{	  strfcpy (p, NONULL(Homedir), sizeof (p));	  tail = s + 1;	}	else	{	  struct passwd *pw;	  if ((t = strchr (s + 1, '/'))) 	    *t = 0;	  if ((pw = getpwnam (s + 1)))	  {	    strfcpy (p, pw->pw_dir, sizeof (p));	    if (t)	    {	      *t = '/';	      tail = t;	    }	    else	      tail = "";	  }	  else	  {	    /* user not found! */	    if (t)	      *t = '/';	    *p = '\0';	    tail = s;	  }	}      }      break;            case '=':      case '+':          {#ifdef USE_IMAP	/* if folder = {host} or imap[s]://host/: don't append slash */	if (mx_is_imap (NONULL (Maildir)) &&	    (Maildir[strlen (Maildir) - 1] == '}' ||	     Maildir[strlen (Maildir) - 1] == '/'))	  strfcpy (p, NONULL (Maildir), sizeof (p));	else#endif	  snprintf (p, sizeof (p), "%s/", NONULL (Maildir));		tail = s + 1;      }      break;            /* elm compatibility, @ expands alias to user name */          case '@':      {	HEADER *h;	ADDRESS *alias;		if ((alias = mutt_lookup_alias (s + 1)))	{	  h = mutt_new_header();	  h->env = mutt_new_envelope();	  h->env->from = h->env->to = alias;	  mutt_default_save (p, sizeof (p), h);	  h->env->from = h->env->to = NULL;	  mutt_free_header (&h);	  /* Avoid infinite recursion if the resulting folder starts with '@' */	  if (*p != '@')	    recurse = 1;	  	  tail = "";	}      }      break;            case '>':      {	strfcpy (p, NONULL(Inbox), sizeof (p));	tail = s + 1;      }      break;            case '<':      {	strfcpy (p, NONULL(Outbox), sizeof (p));	tail = s + 1;      }      break;            case '!':      {	if (*(s+1) == '!')	{	  strfcpy (p, NONULL(LastFolder), sizeof (p));	  tail = s + 2;	}	else 	{	  strfcpy (p, NONULL(Spoolfile), sizeof (p));	  tail = s + 1;	}      }      break;            case '-':      {	strfcpy (p, NONULL(LastFolder), sizeof (p));	tail = s + 1;      }      break;            case '^':              {	strfcpy (p, NONULL(CurrentFolder), sizeof (p));	tail = s + 1;      }      break;      default:      {	*p = '\0';	tail = s;      }    }    if (rx && *p && !recurse)    {      mutt_rx_sanitize_string (q, sizeof (q), p);      snprintf (tmp, sizeof (tmp), "%s%s", q, tail);    }    else      snprintf (tmp, sizeof (tmp), "%s%s", p, tail);        strfcpy (s, tmp, slen);  }  while (recurse);#ifdef USE_IMAP  /* Rewrite IMAP path in canonical form - aids in string comparisons of   * folders. May possibly fail, in which case s should be the same. */  if (mx_is_imap (s))    imap_expand_path (s, slen);#endif  return (s);}/* Extract the real name from /etc/passwd's GECOS field. * When set, honor the regular expression in GecosMask, * otherwise assume that the GECOS field is a  * comma-separated list. * Replace "&" by a capitalized version of the user's login * name. */char *mutt_gecos_name (char *dest, size_t destlen, struct passwd *pw){  regmatch_t pat_match[1];  size_t pwnl;  int idx;  char *p;    if (!pw || !pw->pw_gecos)     return NULL;  memset (dest, 0, destlen);    if (GecosMask.rx)  {    if (regexec (GecosMask.rx, pw->pw_gecos, 1, pat_match, 0) == 0)      strfcpy (dest, pw->pw_gecos + pat_match[0].rm_so, 	       MIN (pat_match[0].rm_eo - pat_match[0].rm_so + 1, destlen));  }  else if ((p = strchr (pw->pw_gecos, ',')))    strfcpy (dest, pw->pw_gecos, MIN (destlen, p - pw->pw_gecos + 1));  else    strfcpy (dest, pw->pw_gecos, destlen);  pwnl = strlen (pw->pw_name);  for (idx = 0; dest[idx]; idx++)  {    if (dest[idx] == '&')    {      memmove (&dest[idx + pwnl], &dest[idx + 1],	       MAX(destlen - idx - pwnl - 1, 0));      memcpy (&dest[idx], pw->pw_name, MIN(destlen - idx - 1, pwnl));      dest[idx] = toupper ((unsigned char) dest[idx]);    }  }        return dest;}  

⌨️ 快捷键说明

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