}
}
+int mutt_parse_rfc822_line (ENVELOPE *e, HEADER *hdr, char *line, char *p, short user_hdrs, short weed,
+ short do_2047, LIST **lastp, char **in_reply_to)
+{
+ int matched = 0;
+ LIST *last = NULL;
+
+ if (lastp)
+ last = *lastp;
+
+ switch (tolower (line[0]))
+ {
+ case 'a':
+ if (mutt_strcasecmp (line+1, "pparently-to") == 0)
+ {
+ e->to = rfc822_parse_adrlist (e->to, p);
+ matched = 1;
+ }
+ else if (mutt_strcasecmp (line+1, "pparently-from") == 0)
+ {
+ e->from = rfc822_parse_adrlist (e->from, p);
+ matched = 1;
+ }
+ break;
+
+ case 'b':
+ if (mutt_strcasecmp (line+1, "cc") == 0)
+ {
+ e->bcc = rfc822_parse_adrlist (e->bcc, p);
+ matched = 1;
+ }
+ break;
+
+ case 'c':
+ if (mutt_strcasecmp (line+1, "c") == 0)
+ {
+ e->cc = rfc822_parse_adrlist (e->cc, p);
+ matched = 1;
+ }
+ else if (mutt_strncasecmp (line + 1, "ontent-", 7) == 0)
+ {
+ if (mutt_strcasecmp (line+8, "type") == 0)
+ {
+ if (hdr)
+ mutt_parse_content_type (p, hdr->content);
+ matched = 1;
+ }
+ else if (mutt_strcasecmp (line+8, "transfer-encoding") == 0)
+ {
+ if (hdr)
+ hdr->content->encoding = mutt_check_encoding (p);
+ matched = 1;
+ }
+ else if (mutt_strcasecmp (line+8, "length") == 0)
+ {
+ if (hdr)
+ {
+ if ((hdr->content->length = atoi (p)) < 0)
+ hdr->content->length = -1;
+ }
+ matched = 1;
+ }
+ else if (mutt_strcasecmp (line+8, "description") == 0)
+ {
+ if (hdr)
+ {
+ mutt_str_replace (&hdr->content->description, p);
+ rfc2047_decode (&hdr->content->description);
+ }
+ matched = 1;
+ }
+ else if (mutt_strcasecmp (line+8, "disposition") == 0)
+ {
+ if (hdr)
+ parse_content_disposition (p, hdr->content);
+ matched = 1;
+ }
+ }
+ break;
+
+ case 'd':
+ if (!mutt_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 (!mutt_strcasecmp ("xpires", line + 1) &&
+ hdr && mutt_parse_date (p, NULL) < time (NULL))
+ hdr->expired = 1;
+ break;
+
+ case 'f':
+ if (!mutt_strcasecmp ("rom", line + 1))
+ {
+ e->from = rfc822_parse_adrlist (e->from, p);
+ matched = 1;
+ }
+ break;
+
+ case 'i':
+ if (!mutt_strcasecmp (line+1, "n-reply-to"))
+ {
+ if (hdr && in_reply_to)
+ {
+ *in_reply_to = strdup (p);
+ if (do_2047)
+ rfc2047_decode (in_reply_to);
+ }
+ }
+ break;
+
+ case 'l':
+ if (!mutt_strcasecmp (line + 1, "ines"))
+ {
+ if (hdr)
+ hdr->lines = atoi (p);
+ matched = 1;
+ }
+ break;
+
+ case 'm':
+ if (!mutt_strcasecmp (line + 1, "ime-version"))
+ {
+ if (hdr)
+ hdr->mime = 1;
+ matched = 1;
+ }
+ else if (!mutt_strcasecmp (line + 1, "essage-id"))
+ {
+ /* We add a new "Message-Id:" when building a message */
+ safe_free ((void **) &e->message_id);
+ e->message_id = extract_message_id (p);
+ matched = 1;
+ }
+ else if (!mutt_strncasecmp (line + 1, "ail-", 4))
+ {
+ if (!mutt_strcasecmp (line + 5, "reply-to"))
+ {
+ /* override the Reply-To: field */
+ rfc822_free_address (&e->reply_to);
+ e->reply_to = rfc822_parse_adrlist (e->reply_to, p);
+ matched = 1;
+ }
+ else if (!mutt_strcasecmp (line + 5, "followup-to"))
+ {
+ e->mail_followup_to = rfc822_parse_adrlist (e->mail_followup_to, p);
+ matched = 1;
+ }
+ }
+ break;
+
+ case 'r':
+ if (!mutt_strcasecmp (line + 1, "eferences"))
+ {
+ mutt_free_list (&e->references);
+ e->references = mutt_parse_references (p);
+ matched = 1;
+ }
+ else if (!mutt_strcasecmp (line + 1, "eply-to"))
+ {
+ e->reply_to = rfc822_parse_adrlist (e->reply_to, p);
+ matched = 1;
+ }
+ else if (!mutt_strcasecmp (line + 1, "eturn-path"))
+ {
+ e->return_path = rfc822_parse_adrlist (e->return_path, p);
+ matched = 1;
+ }
+ else if (!mutt_strcasecmp (line + 1, "eceived"))
+ {
+ if (hdr && !hdr->received)
+ {
+ char *d = strchr (p, ';');
+
+ if (d)
+ hdr->received = mutt_parse_date (d + 1, NULL);
+ }
+ }
+ break;
+
+ case 's':
+ if (!mutt_strcasecmp (line + 1, "ubject"))
+ {
+ if (!e->subject)
+ e->subject = safe_strdup (p);
+ matched = 1;
+ }
+ else if (!mutt_strcasecmp (line + 1, "ender"))
+ {
+ e->sender = rfc822_parse_adrlist (e->sender, p);
+ matched = 1;
+ }
+ else if (!mutt_strcasecmp (line + 1, "tatus"))
+ {
+ if (hdr)
+ {
+ while (*p)
+ {
+ switch(*p)
+ {
+ case 'r':
+ hdr->replied = 1;
+ break;
+ case 'O':
+ if (option (OPTMARKOLD))
+ hdr->old = 1;
+ break;
+ case 'R':
+ hdr->read = 1;
+ break;
+ }
+ p++;
+ }
+ }
+ matched = 1;
+ }
+ else if ((!mutt_strcasecmp ("upersedes", line + 1) ||
+ !mutt_strcasecmp ("upercedes", line + 1)) && hdr)
+ e->supersedes = safe_strdup (p);
+ break;
+
+ case 't':
+ if (mutt_strcasecmp (line+1, "o") == 0)
+ {
+ e->to = rfc822_parse_adrlist (e->to, p);
+ matched = 1;
+ }
+ break;
+
+ case 'x':
+ if (mutt_strcasecmp (line+1, "-status") == 0)
+ {
+ if (hdr)
+ {
+ while (*p)
+ {
+ switch (*p)
+ {
+ case 'A':
+ hdr->replied = 1;
+ break;
+ case 'D':
+ hdr->deleted = 1;
+ break;
+ case 'F':
+ hdr->flagged = 1;
+ break;
+ default:
+ break;
+ }
+ p++;
+ }
+ }
+ matched = 1;
+ }
+ else if (mutt_strcasecmp (line+1, "-label") == 0)
+ {
+ e->x_label = safe_strdup(p);
+ matched = 1;
+ }
+
+ default:
+ break;
+ }
+
+ /* Keep track of the user-defined headers */
+ if (!matched && user_hdrs)
+ {
+ /* restore the original line */
+ line[strlen (line)] = ':';
+
+ if (weed && option (OPTWEED) && mutt_matches_ignore (line, Ignore)
+ && !mutt_matches_ignore (line, UnIgnore))
+ goto done;
+
+ if (last)
+ {
+ last->next = mutt_new_list ();
+ last = last->next;
+ }
+ else
+ last = e->userhdrs = mutt_new_list ();
+ last->data = safe_strdup (line);
+ if (do_2047)
+ rfc2047_decode (&last->data);
+ }
+
+ done:
+
+ *lastp = last;
+ return matched;
+}
+
+
/* mutt_read_rfc822_header() -- parses a RFC822 header
*
* Args:
if (!*p)
continue; /* skip empty header fields */
- switch (tolower (line[0]))
- {
- case 'a':
- if (mutt_strcasecmp (line+1, "pparently-to") == 0)
- {
- e->to = rfc822_parse_adrlist (e->to, p);
- matched = 1;
- }
- else if (mutt_strcasecmp (line+1, "pparently-from") == 0)
- {
- e->from = rfc822_parse_adrlist (e->from, p);
- matched = 1;
- }
- break;
-
- case 'b':
- if (mutt_strcasecmp (line+1, "cc") == 0)
- {
- e->bcc = rfc822_parse_adrlist (e->bcc, p);
- matched = 1;
- }
- break;
-
- case 'c':
- if (mutt_strcasecmp (line+1, "c") == 0)
- {
- e->cc = rfc822_parse_adrlist (e->cc, p);
- matched = 1;
- }
- else if (mutt_strncasecmp (line + 1, "ontent-", 7) == 0)
- {
- if (mutt_strcasecmp (line+8, "type") == 0)
- {
- if (hdr)
- mutt_parse_content_type (p, hdr->content);
- matched = 1;
- }
- else if (mutt_strcasecmp (line+8, "transfer-encoding") == 0)
- {
- if (hdr)
- hdr->content->encoding = mutt_check_encoding (p);
- matched = 1;
- }
- else if (mutt_strcasecmp (line+8, "length") == 0)
- {
- if (hdr)
- {
- if ((hdr->content->length = atoi (p)) < 0)
- hdr->content->length = -1;
- }
- matched = 1;
- }
- else if (mutt_strcasecmp (line+8, "description") == 0)
- {
- if (hdr)
- {
- mutt_str_replace (&hdr->content->description, p);
- rfc2047_decode (&hdr->content->description);
- }
- matched = 1;
- }
- else if (mutt_strcasecmp (line+8, "disposition") == 0)
- {
- if (hdr)
- parse_content_disposition (p, hdr->content);
- matched = 1;
- }
- }
- break;
-
- case 'd':
- if (!mutt_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 (!mutt_strcasecmp ("xpires", line + 1) &&
- hdr && mutt_parse_date (p, NULL) < time (NULL))
- hdr->expired = 1;
- break;
-
- case 'f':
- if (!mutt_strcasecmp ("rom", line + 1))
- {
- e->from = rfc822_parse_adrlist (e->from, p);
- matched = 1;
- }
- break;
-
- case 'i':
- if (!mutt_strcasecmp (line+1, "n-reply-to"))
- {
- if (hdr)
- {
- in_reply_to = strdup (p);
- rfc2047_decode (&in_reply_to);
- }
- }
- break;
-
- case 'l':
- if (!mutt_strcasecmp (line + 1, "ines"))
- {
- if (hdr)
- hdr->lines = atoi (p);
- matched = 1;
- }
- break;
-
- case 'm':
- if (!mutt_strcasecmp (line + 1, "ime-version"))
- {
- if (hdr)
- hdr->mime = 1;
- matched = 1;
- }
- else if (!mutt_strcasecmp (line + 1, "essage-id"))
- {
- /* We add a new "Message-Id:" when building a message */
- safe_free ((void **) &e->message_id);
- e->message_id = extract_message_id (p);
- matched = 1;
- }
- else if (!mutt_strncasecmp (line + 1, "ail-", 4))
- {
- if (!mutt_strcasecmp (line + 5, "reply-to"))
- {
- /* override the Reply-To: field */
- rfc822_free_address (&e->reply_to);
- e->reply_to = rfc822_parse_adrlist (e->reply_to, p);
- matched = 1;
- }
- else if (!mutt_strcasecmp (line + 5, "followup-to"))
- {
- e->mail_followup_to = rfc822_parse_adrlist (e->mail_followup_to, p);
- matched = 1;
- }
- }
- break;
-
- case 'r':
- if (!mutt_strcasecmp (line + 1, "eferences"))
- {
- mutt_free_list (&e->references);
- e->references = mutt_parse_references (p);
- matched = 1;
- }
- else if (!mutt_strcasecmp (line + 1, "eply-to"))
- {
- e->reply_to = rfc822_parse_adrlist (e->reply_to, p);
- matched = 1;
- }
- else if (!mutt_strcasecmp (line + 1, "eturn-path"))
- {
- e->return_path = rfc822_parse_adrlist (e->return_path, p);
- matched = 1;
- }
- else if (!mutt_strcasecmp (line + 1, "eceived"))
- {
- if (hdr && !hdr->received)
- {
- char *d = strchr (p, ';');
-
- if (d)
- hdr->received = mutt_parse_date (d + 1, NULL);
- }
- }
- break;
-
- case 's':
- if (!mutt_strcasecmp (line + 1, "ubject"))
- {
- if (!e->subject)
- e->subject = safe_strdup (p);
- matched = 1;
- }
- else if (!mutt_strcasecmp (line + 1, "ender"))
- {
- e->sender = rfc822_parse_adrlist (e->sender, p);
- matched = 1;
- }
- else if (!mutt_strcasecmp (line + 1, "tatus"))
- {
- if (hdr)
- {
- while (*p)
- {
- switch(*p)
- {
- case 'r':
- hdr->replied = 1;
- break;
- case 'O':
- if (option (OPTMARKOLD))
- hdr->old = 1;
- break;
- case 'R':
- hdr->read = 1;
- break;
- }
- p++;
- }
- }
- matched = 1;
- }
- else if ((!mutt_strcasecmp ("upersedes", line + 1) ||
- !mutt_strcasecmp ("upercedes", line + 1)) && hdr)
- e->supersedes = safe_strdup (p);
- break;
-
- case 't':
- if (mutt_strcasecmp (line+1, "o") == 0)
- {
- e->to = rfc822_parse_adrlist (e->to, p);
- matched = 1;
- }
- break;
-
- case 'x':
- if (mutt_strcasecmp (line+1, "-status") == 0)
- {
- if (hdr)
- {
- while (*p)
- {
- switch (*p)
- {
- case 'A':
- hdr->replied = 1;
- break;
- case 'D':
- hdr->deleted = 1;
- break;
- case 'F':
- hdr->flagged = 1;
- break;
- default:
- break;
- }
- p++;
- }
- }
- matched = 1;
- }
- else if (mutt_strcasecmp (line+1, "-label") == 0)
- {
- e->x_label = safe_strdup(p);
- matched = 1;
- }
-
- default:
- break;
- }
-
- /* Keep track of the user-defined headers */
- if (!matched && user_hdrs)
- {
- /* restore the original line */
- line[strlen (line)] = ':';
-
- if (weed && option (OPTWEED) && mutt_matches_ignore (line, Ignore)
- && !mutt_matches_ignore (line, UnIgnore))
- continue;
-
- if (last)
- {
- last->next = mutt_new_list ();
- last = last->next;
- }
- else
- last = e->userhdrs = mutt_new_list ();
- last->data = safe_strdup (line);
- rfc2047_decode (&last->data);
- }
+ matched = mutt_parse_rfc822_line (e, hdr, line, p, user_hdrs, weed, 1, &last, &in_reply_to);
+
}
FREE (&line);
--- /dev/null
+/*
+ * Copyright (C) 2000 Thomas Roessler <roessler@guug.de>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ */
+
+/*
+ * A simple URL parser.
+ */
+
+#include "mutt.h"
+#include "mapping.h"
+#include "url.h"
+
+#include "mime.h"
+
+#include <ctype.h>
+
+static struct mapping_t UrlMap[] =
+{
+ { "file", U_FILE },
+#ifdef USE_IMAP
+ { "imap", U_IMAP },
+#endif
+#ifdef USE_POP
+ { "pop", U_POP },
+#endif
+#ifdef USE_SSL
+# ifdef USE_IMAP
+ { "imaps", U_IMAPS },
+# endif
+# ifdef USE_POP
+ { "pops", U_POPS },
+# endif
+#endif
+ { "mailto", U_MAILTO },
+ { NULL, U_UNKNOWN}
+};
+
+
+static void url_pct_decode (char *s)
+{
+ char *d;
+ for (d = s; *s; s++)
+ {
+ if (*s == '%' && s[1] && s[2] &&
+ hexval (s[1]) >= 0 && hexval(s[2]) >= 0)
+ {
+ *d++ = (hexval (s[1]) << 4) | (hexval (s[2]));
+ s += 2;
+ }
+ else
+ *d++ = *s;
+ }
+ *d ='\0';
+}
+
+url_scheme_t url_check_scheme (const char *s)
+{
+ char sbuf[STRING];
+ char *t;
+ int i;
+
+ if (!(t = strchr (s, ':')))
+ return U_UNKNOWN;
+ if ((t - s) + 1 >= sizeof (sbuf))
+ return U_UNKNOWN;
+
+ strfcpy (sbuf, s, t - s + 1);
+ for (t = sbuf; *t; t++)
+ *t = tolower (*t);
+
+ if ((i = mutt_getvaluebyname (sbuf, UrlMap)) == -1)
+ return U_UNKNOWN;
+ else
+ return (url_scheme_t) i;
+}
+
+int url_parse_file (char *d, const char *src, size_t dl)
+{
+ if (strncasecmp (src, "file:", 5))
+ return -1;
+ else if (!strncasecmp (src, "file://", 7)) /* we don't support remote files */
+ return -1;
+ else
+ strfcpy (d, src + 5, dl);
+
+ url_pct_decode (d);
+ return 0;
+}
+
+static char *ciss_parse_userhost (ciss_url_t *ciss, char *src)
+{
+ char *t;
+ char *p;
+ char *path;
+
+ if (strncmp (src, "//", 2))
+ return src;
+
+ src += 2;
+
+ if ((path = strchr (src, '/')))
+ *path++ = '\0';
+
+ if ((t = strchr (src, '@')))
+ {
+ *t = '\0';
+ if ((p = strchr (src, ':')))
+ {
+ *p = '\0';
+ ciss->pass = safe_strdup (p + 1);
+ }
+ ciss->user = safe_strdup (src);
+ t++;
+ }
+ else
+ t = src;
+
+ if ((p = strchr (t, ':')))
+ {
+ *p++ = '\0';
+ ciss->port = atoi (p);
+ }
+ else
+ ciss->port = 0;
+
+ ciss->host = safe_strdup (t);
+ return path;
+}
+
+static void ciss_parse_path (ciss_url_t *ciss, char *src)
+{
+ ciss->path = src;
+ url_pct_decode (ciss->path);
+}
+
+int url_parse_ciss (ciss_url_t *ciss, const char *src)
+{
+ char *t, *tmp;
+
+ if (!(t = strchr (src, ':')))
+ return -1;
+
+ tmp = safe_strdup (t + 1);
+
+ t = ciss_parse_userhost (ciss, tmp);
+ ciss_parse_path (ciss, t);
+
+ safe_free ((void **) &tmp);
+
+ return 0;
+}
+
+int url_parse_mailto (ENVELOPE *e, char **body, const char *src)
+{
+ char *t;
+ char *tmp;
+ char *headers;
+ char *tag, *value;
+ char scratch[HUGE_STRING];
+
+ int taglen;
+
+ LIST *last = NULL;
+
+ if (!(t = strchr (src, ':')))
+ return -1;
+
+ tmp = safe_strdup (t + 1);
+ if ((headers = strchr (tmp, '?')))
+ *headers++ = '\0';
+
+ url_pct_decode (tmp);
+ e->to = rfc822_parse_adrlist (e->to, tmp);
+
+ tag = headers ? strtok (headers, "&") : NULL;
+
+ for (; tag; tag = strtok (NULL, "&"))
+ {
+ if ((value = strchr (tag, '=')))
+ *value++ = '\0';
+ if (!value || !*value)
+ continue;
+
+ url_pct_decode (tag);
+ url_pct_decode (value);
+
+ if (!strcasecmp (tag, "body"))
+ mutt_str_replace (body, value);
+ else
+ {
+ taglen = strlen (tag);
+ /* mutt_parse_rfc822_line makes some assumptions */
+ snprintf (scratch, sizeof (scratch), "%s: %s", tag, value);
+ scratch[taglen] = '\0';
+ value = &scratch[taglen+1];
+ SKIPWS (value);
+ mutt_parse_rfc822_line (e, NULL, scratch, value, 1, 0, 0, &last, NULL);
+ }
+ }
+
+ safe_free ((void **) &tmp);
+ return 0;
+}
+