2 * Copyright (C) 2000 Thomas Roessler <roessler@does-not-exist.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
20 * A simple URL parser.
31 static struct mapping_t UrlMap[] =
41 { "mailto", U_MAILTO },
46 static void url_pct_decode (char *s)
55 if (*s == '%' && s[1] && s[2] &&
56 isxdigit ((unsigned char) s[1]) &&
57 isxdigit ((unsigned char) s[2]) &&
58 hexval (s[1]) >= 0 && hexval (s[2]) >= 0)
60 *d++ = (hexval (s[1]) << 4) | (hexval (s[2]));
69 url_scheme_t url_check_scheme (const char *s)
75 if (!s || !(t = strchr (s, ':')))
77 if ((t - s) + 1 >= sizeof (sbuf))
80 strfcpy (sbuf, s, t - s + 1);
81 for (t = sbuf; *t; t++)
82 *t = ascii_tolower (*t);
84 if ((i = mutt_getvaluebyname (sbuf, UrlMap)) == -1)
87 return (url_scheme_t) i;
90 int url_parse_file (char *d, const char *src, size_t dl)
92 if (ascii_strncasecmp (src, "file:", 5))
94 else if (!ascii_strncasecmp (src, "file://", 7)) /* we don't support remote files */
97 strfcpy (d, src + 5, dl);
103 /* ciss_parse_userhost: fill in components of ciss with info from src. Note
104 * these are pointers into src, which is altered with '\0's. Port of 0
105 * means no port given. */
106 static char *ciss_parse_userhost (ciss_url_t *ciss, char *src)
117 if (strncmp (src, "//", 2))
122 if ((path = strchr (src, '/')))
125 if ((t = strrchr (src, '@')))
128 if ((p = strchr (src, ':')))
132 url_pct_decode (ciss->pass);
135 url_pct_decode (ciss->user);
141 if ((p = strchr (t, ':')))
144 ciss->port = atoi (p);
150 url_pct_decode (ciss->host);
154 /* url_parse_ciss: Fill in ciss_url_t. char* elements are pointers into src,
155 * which is modified by this call (duplicate it first if you need to). */
156 int url_parse_ciss (ciss_url_t *ciss, char *src)
160 if ((ciss->scheme = url_check_scheme (src)) == U_UNKNOWN)
163 tmp = strchr (src, ':') + 1;
165 ciss->path = ciss_parse_userhost (ciss, tmp);
166 url_pct_decode (ciss->path);
171 /* url_ciss_tostring: output the URL string for a given CISS object. */
172 int url_ciss_tostring (ciss_url_t* ciss, char* dest, size_t len, int flags)
174 if (ciss->scheme == U_UNKNOWN)
177 snprintf (dest, len, "%s:", mutt_getnamebyvalue (ciss->scheme, UrlMap));
181 strncat (dest, "//", len - strlen (dest));
183 if (flags & U_DECODE_PASSWD && ciss->pass)
184 snprintf (dest + strlen (dest), len - strlen (dest), "%s:%s@",
185 ciss->user, ciss->pass);
187 snprintf (dest + strlen (dest), len - strlen (dest), "%s@",
192 snprintf (dest + strlen (dest), len - strlen (dest), "%s:%hu/",
193 ciss->host, ciss->port);
195 snprintf (dest + strlen (dest), len - strlen (dest), "%s/", ciss->host);
199 strncat (dest, ciss->path, len - strlen (dest));
204 int url_parse_mailto (ENVELOPE *e, char **body, const char *src)
210 char scratch[HUGE_STRING];
216 if (!(t = strchr (src, ':')))
219 if ((tmp = safe_strdup (t + 1)) == NULL)
222 if ((headers = strchr (tmp, '?')))
225 url_pct_decode (tmp);
226 e->to = rfc822_parse_adrlist (e->to, tmp);
228 tag = headers ? strtok (headers, "&") : NULL;
230 for (; tag; tag = strtok (NULL, "&"))
232 if ((value = strchr (tag, '=')))
234 if (!value || !*value)
237 url_pct_decode (tag);
238 url_pct_decode (value);
240 if (!ascii_strcasecmp (tag, "body"))
241 mutt_str_replace (body, value);
244 taglen = strlen (tag);
245 /* mutt_parse_rfc822_line makes some assumptions */
246 snprintf (scratch, sizeof (scratch), "%s: %s", tag, value);
247 scratch[taglen] = '\0';
248 value = &scratch[taglen+1];
250 mutt_parse_rfc822_line (e, NULL, scratch, value, 1, 0, 0, &last);