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

📄 parse.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 3 页
字号:
    mutt_str_replace (&b->subtype, "plain");  }}/* parse a MESSAGE/RFC822 body * * args: *	fp		stream to read from * *	parent		structure which contains info about the message/rfc822 *			body part * * NOTE: this assumes that `parent->length' has been set! */BODY *mutt_parse_messageRFC822 (FILE *fp, BODY *parent){  BODY *msg;  parent->hdr = mutt_new_header ();  parent->hdr->offset = ftello (fp);  parent->hdr->env = mutt_read_rfc822_header (fp, parent->hdr, 0, 0);  msg = parent->hdr->content;  /* ignore the length given in the content-length since it could be wrong     and we already have the info to calculate the correct length */  /* if (msg->length == -1) */  msg->length = parent->length - (msg->offset - parent->offset);  /* if body of this message is empty, we can end up with a negative length */  if (msg->length < 0)    msg->length = 0;  mutt_parse_part(fp, msg);  return (msg);}/* parse a multipart structure * * args: *	fp		stream to read from * *	boundary	body separator * *	end_off		length of the multipart body (used when the final *			boundary is missing to avoid reading too far) * *	digest		1 if reading a multipart/digest, 0 otherwise */BODY *mutt_parse_multipart (FILE *fp, const char *boundary, LOFF_T end_off, int digest){#ifdef SUN_ATTACHMENT  int lines;#endif  int blen, len, crlf = 0;  char buffer[LONG_STRING];  BODY *head = 0, *last = 0, *new = 0;  int i;  int final = 0; /* did we see the ending boundary? */  if (!boundary)  {    mutt_error _("multipart message has no boundary parameter!");    return (NULL);  }  blen = mutt_strlen (boundary);  while (ftello (fp) < end_off && fgets (buffer, LONG_STRING, fp) != NULL)  {    len = mutt_strlen (buffer);    crlf =  (len > 1 && buffer[len - 2] == '\r') ? 1 : 0;    if (buffer[0] == '-' && buffer[1] == '-' &&	mutt_strncmp (buffer + 2, boundary, blen) == 0)    {      if (last)      {	last->length = ftello (fp) - last->offset - len - 1 - crlf;	if (last->parts && last->parts->length == 0)	  last->parts->length = ftello (fp) - last->parts->offset - len - 1 - crlf;	/* if the body is empty, we can end up with a -1 length */	if (last->length < 0)	  last->length = 0;      }      /* Remove any trailing whitespace, up to the length of the boundary */      for (i = len - 1; ISSPACE (buffer[i]) && i >= blen + 2; i--)        buffer[i] = 0;      /* Check for the end boundary */      if (mutt_strcmp (buffer + blen + 2, "--") == 0)      {	final = 1;	break; /* done parsing */      }      else if (buffer[2 + blen] == 0)      {	new = mutt_read_mime_header (fp, digest);#ifdef SUN_ATTACHMENT        if (mutt_get_parameter ("content-lines", new->parameter)) {	  for (lines = atoi(mutt_get_parameter ("content-lines", new->parameter));	       lines; lines-- )	     if (ftello (fp) >= end_off || fgets (buffer, LONG_STRING, fp) == NULL)	       break;	}#endif		/*	 * Consistency checking - catch	 * bad attachment end boundaries	 */		if(new->offset > end_off)	{	  mutt_free_body(&new);	  break;	}	if (head)	{	  last->next = new;	  last = new;	}	else	  last = head = new;      }    }  }  /* in case of missing end boundary, set the length to something reasonable */  if (last && last->length == 0 && !final)    last->length = end_off - last->offset;  /* parse recursive MIME parts */  for(last = head; last; last = last->next)    mutt_parse_part(fp, last);    return (head);}static const char *uncomment_timezone (char *buf, size_t buflen, const char *tz){  char *p;  size_t len;  if (*tz != '(')    return tz; /* no need to do anything */  tz++;  SKIPWS (tz);  if ((p = strpbrk (tz, " )")) == NULL)    return tz;  len = p - tz;  if (len > buflen - 1)    len = buflen - 1;  memcpy (buf, tz, len);  buf[len] = 0;  return buf;}static struct tz_t{  char tzname[5];  unsigned char zhours;  unsigned char zminutes;  unsigned char zoccident; /* west of UTC? */}TimeZones[] ={  { "aat",   1,  0, 1 }, /* Atlantic Africa Time */  { "adt",   4,  0, 0 }, /* Arabia DST */  { "ast",   3,  0, 0 }, /* Arabia *//*{ "ast",   4,  0, 1 },*/ /* Atlantic */  { "bst",   1,  0, 0 }, /* British DST */  { "cat",   1,  0, 0 }, /* Central Africa */  { "cdt",   5,  0, 1 },  { "cest",  2,  0, 0 }, /* Central Europe DST */  { "cet",   1,  0, 0 }, /* Central Europe */  { "cst",   6,  0, 1 },/*{ "cst",   8,  0, 0 },*/ /* China *//*{ "cst",   9, 30, 0 },*/ /* Australian Central Standard Time */  { "eat",   3,  0, 0 }, /* East Africa */  { "edt",   4,  0, 1 },  { "eest",  3,  0, 0 }, /* Eastern Europe DST */  { "eet",   2,  0, 0 }, /* Eastern Europe */  { "egst",  0,  0, 0 }, /* Eastern Greenland DST */  { "egt",   1,  0, 1 }, /* Eastern Greenland */  { "est",   5,  0, 1 },  { "gmt",   0,  0, 0 },  { "gst",   4,  0, 0 }, /* Presian Gulf */  { "hkt",   8,  0, 0 }, /* Hong Kong */  { "ict",   7,  0, 0 }, /* Indochina */  { "idt",   3,  0, 0 }, /* Israel DST */  { "ist",   2,  0, 0 }, /* Israel *//*{ "ist",   5, 30, 0 },*/ /* India */  { "jst",   9,  0, 0 }, /* Japan */  { "kst",   9,  0, 0 }, /* Korea */  { "mdt",   6,  0, 1 },  { "met",   1,  0, 0 }, /* this is now officially CET */  { "msd",   4,  0, 0 }, /* Moscow DST */  { "msk",   3,  0, 0 }, /* Moscow */  { "mst",   7,  0, 1 },  { "nzdt", 13,  0, 0 }, /* New Zealand DST */  { "nzst", 12,  0, 0 }, /* New Zealand */  { "pdt",   7,  0, 1 },  { "pst",   8,  0, 1 },  { "sat",   2,  0, 0 }, /* South Africa */  { "smt",   4,  0, 0 }, /* Seychelles */  { "sst",  11,  0, 1 }, /* Samoa *//*{ "sst",   8,  0, 0 },*/ /* Singapore */  { "utc",   0,  0, 0 },  { "wat",   0,  0, 0 }, /* West Africa */  { "west",  1,  0, 0 }, /* Western Europe DST */  { "wet",   0,  0, 0 }, /* Western Europe */  { "wgst",  2,  0, 1 }, /* Western Greenland DST */  { "wgt",   3,  0, 1 }, /* Western Greenland */  { "wst",   8,  0, 0 }, /* Western Australia */};/* parses a date string in RFC822 format: * * Date: [ weekday , ] day-of-month month year hour:minute:second timezone * * This routine assumes that `h' has been initialized to 0.  the `timezone' * field is optional, defaulting to +0000 if missing. */time_t mutt_parse_date (const char *s, HEADER *h){  int count = 0;  char *t;  int hour, min, sec;  struct tm tm;  int i;  int tz_offset = 0;  int zhours = 0;  int zminutes = 0;  int zoccident = 0;  const char *ptz;  char tzstr[SHORT_STRING];  char scratch[SHORT_STRING];  /* Don't modify our argument. Fixed-size buffer is ok here since   * the date format imposes a natural limit.    */  strfcpy (scratch, s, sizeof (scratch));    /* kill the day of the week, if it exists. */  if ((t = strchr (scratch, ',')))    t++;  else    t = scratch;  SKIPWS (t);  memset (&tm, 0, sizeof (tm));  while ((t = strtok (t, " \t")) != NULL)  {    switch (count)    {      case 0: /* day of the month */	if (!isdigit ((unsigned char) *t))	  return (-1);	tm.tm_mday = atoi (t);	if (tm.tm_mday > 31)	  return (-1);	break;      case 1: /* month of the year */	if ((i = mutt_check_month (t)) < 0)	  return (-1);	tm.tm_mon = i;	break;      case 2: /* year */	tm.tm_year = atoi (t);        if (tm.tm_year < 50)	  tm.tm_year += 100;        else if (tm.tm_year >= 1900)	  tm.tm_year -= 1900;	break;      case 3: /* time of day */	if (sscanf (t, "%d:%d:%d", &hour, &min, &sec) == 3)	  ;	else if (sscanf (t, "%d:%d", &hour, &min) == 2)	  sec = 0;	else	{	  dprint(1, (debugfile, "parse_date: could not process time format: %s\n", t));	  return(-1);	}	tm.tm_hour = hour;	tm.tm_min = min;	tm.tm_sec = sec;	break;      case 4: /* timezone */	/* sometimes we see things like (MST) or (-0700) so attempt to	 * compensate by uncommenting the string if non-RFC822 compliant	 */	ptz = uncomment_timezone (tzstr, sizeof (tzstr), t);	if (*ptz == '+' || *ptz == '-')	{	  if (ptz[1] && ptz[2] && ptz[3] && ptz[4]	      && isdigit ((unsigned char) ptz[1]) && isdigit ((unsigned char) ptz[2])	      && isdigit ((unsigned char) ptz[3]) && isdigit ((unsigned char) ptz[4]))	  {	    zhours = (ptz[1] - '0') * 10 + (ptz[2] - '0');	    zminutes = (ptz[3] - '0') * 10 + (ptz[4] - '0');	    if (ptz[0] == '-')	      zoccident = 1;	  }	}	else	{	  struct tz_t *tz;	  tz = bsearch (ptz, TimeZones, sizeof TimeZones/sizeof (struct tz_t),			sizeof (struct tz_t),			(int (*)(const void *, const void *)) ascii_strcasecmp			/* This is safe to do: A pointer to a struct equals			 * a pointer to its first element*/);	  if (tz)	  {	    zhours = tz->zhours;	    zminutes = tz->zminutes;	    zoccident = tz->zoccident;	  }	  /* ad hoc support for the European MET (now officially CET) TZ */	  if (ascii_strcasecmp (t, "MET") == 0)	  {	    if ((t = strtok (NULL, " \t")) != NULL)	    {	      if (!ascii_strcasecmp (t, "DST"))		zhours++;	    }	  }	}	tz_offset = zhours * 3600 + zminutes * 60;	if (!zoccident)	  tz_offset = -tz_offset;	break;    }    count++;    t = 0;  }  if (count < 4) /* don't check for missing timezone */  {    dprint(1,(debugfile, "parse_date(): error parsing date format, using received time\n"));    return (-1);  }  if (h)  {    h->zhours = zhours;    h->zminutes = zminutes;    h->zoccident = zoccident;  }  return (mutt_mktime (&tm, 0) + tz_offset);}/* extract the first substring that looks like a message-id */static char *extract_message_id (const char *s){  const char *p;  char *r;  size_t l;  if ((s = strchr (s, '<')) == NULL || (p = strchr (s, '>')) == NULL)    return (NULL);  l = (size_t)(p - s) + 1;  r = safe_malloc (l + 1);  memcpy (r, s, l);  r[l] = 0;  return (r);}void mutt_parse_mime_message (CONTEXT *ctx, HEADER *cur){  MESSAGE *msg;  do {    if (cur->content->type != TYPEMESSAGE &&        cur->content->type != TYPEMULTIPART)      break; /* nothing to do */    if (cur->content->parts)      break; /* The message was parsed earlier. */    if ((msg = mx_open_message (ctx, cur->msgno)))    {      mutt_parse_part (msg->fp, cur->content);      if (WithCrypto)        cur->security = crypt_query (cur->content);      mx_close_message (&msg);    }  } while (0);  cur->attach_valid = 0;}int mutt_parse_rfc822_line (ENVELOPE *e, HEADER *hdr, char *line, char *p, short user_hdrs, short weed,			    short do_2047, LIST **lastp){  int matched = 0;  LIST *last = NULL;    if (lastp)    last = *lastp;    switch (ascii_tolower (line[0]))  {    case 'a':    if (ascii_strcasecmp (line+1, "pparently-to") == 0)    {      e->to = rfc822_parse_adrlist (e->to, p);      matched = 1;    }    else if (ascii_strcasecmp (line+1, "pparently-from") == 0)    {      e->from = rfc822_parse_adrlist (e->from, p);      matched = 1;    }    break;        case 'b':    if (ascii_strcasecmp (line+1, "cc") == 0)    {      e->bcc = rfc822_parse_adrlist (e->bcc, p);      matched = 1;    }    break;        case 'c':    if (ascii_strcasecmp (line+1, "c") == 0)    {      e->cc = rfc822_parse_adrlist (e->cc, p);      matched = 1;    }    else if (ascii_strncasecmp (line + 1, "ontent-", 7) == 0)    {      if (ascii_strcasecmp (line+8, "type") == 0)      {	if (hdr)	  mutt_parse_content_type (p, hdr->content);	matched = 1;      }      else if (ascii_strcasecmp (line+8, "transfer-encoding") == 0)      {	if (hdr)	  hdr->content->encoding = mutt_check_encoding (p);	matched = 1;      }      else if (ascii_strcasecmp (line+8, "length") == 0)      {	if (hdr)	{	  if ((hdr->content->length = atoi (p)) < 0)	    hdr->content->length = -1;	}	matched = 1;      }      else if (ascii_strcasecmp (line+8, "description") == 0)      {	if (hdr)	{	  mutt_str_replace (&hdr->content->description, p);	  rfc2047_decode (&hdr->content->description);	}	matched = 1;      }      else if (ascii_strcasecmp (line+8, "disposition") == 0)      {	if (hdr)	  parse_content_disposition (p, hdr->content);	matched = 1;      }    }    break;        case 'd':    if (!ascii_strcasecmp ("ate", line + 1))    {      mutt_str_replace (&e->date, p);      if (hdr)	hdr->date_sent = mutt_parse_date (p, hdr);      matched = 1;    }    break;        case 'e':    if (!ascii_strcasecmp ("xpires", line + 1) &&	hdr && mutt_parse_date (p, NULL) < time (NULL))      hdr->expired = 1;    break;        case 'f':    if (!ascii_strcasecmp ("rom", line + 1))    {      e->from = rfc822_parse_adrlist (e->from, p);      matched = 1;    }    break;        case 'i':    if (!ascii_strcasecmp (line+1, "n-reply-to"))    {      mutt_free_list (&e->in_reply_to);      e->in_reply_to = mutt_parse_references (p, 1);      matched = 1;    }    break;        case 'l':    if (!ascii_strcasecmp (line + 1, "ines"))    {      if (hdr)      {	hdr->lines = atoi (p);	/* 	 * HACK - mutt has, for a very short time, produced negative	 * Lines header values.  Ignore them. 	 */	if (hdr->lines < 0)	  hdr->lines = 0;      }      matched = 1;    }    else if (!ascii_strcasecmp (line + 1, "ist-Post"))    {

⌨️ 快捷键说明

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