2 * Copyright notice from original mutt:
3 * Copyright (C) 2000 Thomas Roessler <roessler@does-not-exist.org>
5 * This file is part of mutt-ng, see http://www.muttng.org/.
6 * It's licensed under the GNU General Public License,
7 * please see the file GPL in the top level source directory.
11 * A simple URL parser.
18 #include <lib-lib/mem.h>
19 #include <lib-lib/ascii.h>
20 #include <lib-lib/mapping.h>
22 #include <lib-mime/mime.h>
30 static struct mapping_t UrlMap[] = {
45 static void url_pct_decode (char *s)
52 for (d = s; *s; s++) {
53 if (*s == '%' && s[1] && s[2] &&
54 isxdigit ((unsigned char) s[1]) &&
55 isxdigit ((unsigned char) s[2]) &&
56 hexval (s[1]) >= 0 && hexval (s[2]) >= 0) {
57 *d++ = (hexval (s[1]) << 4) | (hexval (s[2]));
66 url_scheme_t url_check_scheme (const char *s)
72 if (!s || !(t = strchr (s, ':')))
74 if ((t - s) + 1 >= sizeof (sbuf))
77 m_strcpy(sbuf, t - s + 1, s);
78 for (t = sbuf; *t; t++)
79 *t = ascii_tolower (*t);
81 if ((i = mutt_getvaluebyname (sbuf, UrlMap)) == -1)
84 return (url_scheme_t) i;
87 int url_parse_file (char *d, const char *src, size_t dl)
89 if (ascii_strncasecmp (src, "file:", 5))
91 else if (!ascii_strncasecmp (src, "file://", 7)) /* we don't support remote files */
94 m_strcpy(d, dl, src + 5);
100 /* ciss_parse_userhost: fill in components of ciss with info from src. Note
101 * these are pointers into src, which is altered with '\0's. Port of 0
102 * means no port given. */
103 static char *ciss_parse_userhost (ciss_url_t * ciss, char *src)
114 if (strncmp (src, "//", 2))
119 if ((path = strchr (src, '/')))
122 if ((t = strrchr (src, '@'))) {
124 if ((p = strchr (src, ':'))) {
127 url_pct_decode (ciss->pass);
130 url_pct_decode (ciss->user);
136 if ((p = strchr (t, ':'))) {
138 ciss->port = atoi (p);
144 url_pct_decode (ciss->host);
148 /* url_parse_ciss: Fill in ciss_url_t. char* elements are pointers into src,
149 * which is modified by this call (duplicate it first if you need to). */
150 int url_parse_ciss (ciss_url_t * ciss, char *src)
154 if ((ciss->scheme = url_check_scheme (src)) == U_UNKNOWN)
157 tmp = strchr (src, ':') + 1;
159 ciss->path = ciss_parse_userhost (ciss, tmp);
160 url_pct_decode (ciss->path);
165 /* url_ciss_tostring: output the URL string for a given CISS object. */
167 int url_ciss_tostring (ciss_url_t * ciss, char *dest, size_t len, int flags)
171 if (ciss->scheme == U_UNKNOWN)
174 snprintf (dest, len, "%s:", mutt_getnamebyvalue (ciss->scheme, UrlMap));
177 m_strcat(dest, len, "//");
178 len -= (l = m_strlen(dest));
182 if (flags & U_DECODE_PASSWD && ciss->pass)
183 snprintf (dest, len, "%s:%s@", ciss->user, ciss->pass);
185 snprintf (dest, len, "%s@", ciss->user);
187 len -= (l = m_strlen(dest));
192 snprintf (dest, len, "%s:%hu/", ciss->host, ciss->port);
194 snprintf (dest, len, "%s/", ciss->host);
198 m_strcat(dest, len, ciss->path);
203 int url_parse_mailto (ENVELOPE * e, char **body, const char *src)
209 char scratch[HUGE_STRING];
215 if (!(t = strchr (src, ':')))
218 if ((tmp = m_strdup(t + 1)) == NULL)
221 if ((headers = strchr (tmp, '?')))
224 url_pct_decode (tmp);
225 e->to = rfc822_parse_adrlist (e->to, tmp);
227 tag = headers ? strtok (headers, "&") : NULL;
229 for (; tag; tag = strtok (NULL, "&")) {
230 if ((value = strchr (tag, '=')))
232 if (!value || !*value)
235 url_pct_decode (tag);
236 url_pct_decode (value);
238 if (!ascii_strcasecmp (tag, "body")) {
240 str_replace (body, value);
243 #define SAFEPFX (option (OPTSTRICTMAILTO) ? "" : "X-Mailto-")
244 taglen = m_strlen(tag) + m_strlen(SAFEPFX);
245 /* mutt_parse_rfc822_line makes some assumptions */
246 snprintf (scratch, sizeof (scratch), "%s%s: %s", SAFEPFX, tag, value);
248 scratch[taglen] = '\0';
249 value = vskipspaces(&scratch[taglen + 1]);
250 mutt_parse_rfc822_line (e, NULL, scratch, value, 1, 0, 0, &last);
251 /* if $strict_mailto is set, force editing headers to let
252 * users have a look at what we got */
253 if (!option (OPTSTRICTMAILTO)) {
254 set_option (OPTXMAILTO);
255 set_option (OPTEDITHDRS);