move url.[hc] into the lib-lib.
[apps/madmutt.git] / lib-lib / url.c
diff --git a/lib-lib/url.c b/lib-lib/url.c
new file mode 100644 (file)
index 0000000..afc444b
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ *  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.
+ *
+ *  Copyright © 2006 Pierre Habouzit
+ */
+/*
+ * Copyright notice from original mutt:
+ * Copyright (C) 2000 Thomas Roessler <roessler@does-not-exist.org>
+ *
+ * This file is part of mutt-ng, see http://www.muttng.org/.
+ * It's licensed under the GNU General Public License,
+ * please see the file GPL in the top level source directory.
+ */
+
+/*
+ * A simple URL parser.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <ctype.h>
+
+#include <lib-lib/mem.h>
+#include <lib-lib/ascii.h>
+#include <lib-lib/mapping.h>
+#include <lib-lib/url.h>
+
+#include <lib-mime/mime.h>
+
+#include "mutt.h"
+
+static struct mapping_t UrlMap[] = {
+    {"file",   U_FILE},
+    {"imap",   U_IMAP},
+    {"imaps",  U_IMAPS},
+    {"pop",    U_POP},
+    {"pops",   U_POPS},
+    {"nntp",   U_NNTP},
+    {"news",   U_NNTP},
+    {"nntps",  U_NNTPS},
+    {"snews",  U_NNTPS},
+    {"mailto", U_MAILTO},
+    {NULL,     U_UNKNOWN}
+};
+
+/* decode url escaping */
+char *url_decode(char *p)
+{
+    char *q = p;
+
+    if (!p)
+        return NULL;
+
+    while (*q) {
+        if (*q == '%' && hexval(q[1]) >= 0 && hexval(q[2]) >= 0) {
+            *p++ = (hexval(q[1]) << 4) | hexval(q[2]);
+            q += 3;
+        } else {
+            *p++ = *q++;
+        }
+    }
+
+    *p = '\0';
+    return p;
+}
+
+url_scheme_t url_check_scheme(const char *s)
+{
+    char sbuf[STRING];
+    char *t;
+    int i;
+
+    if (!s || !(t = strchr(s, ':')))
+        return U_UNKNOWN;
+
+    m_strncpy(sbuf, sizeof(sbuf), s, t - s);
+    i = mutt_getvaluebyname(sbuf, UrlMap);
+    return i == -1 ? U_UNKNOWN : i;
+}
+
+/* ciss_parse_userhost: fill in components of ciss with info from src. Note
+ *   these are pointers into src, which is altered with '\0's. Port of 0
+ *   means no port given.
+ * FIXME: THIS IS TASTELESS
+ */
+static char *ciss_parse_userhost(ciss_url_t *ciss, char *src)
+{
+    char *t;
+    char *p;
+    char *path;
+
+    ciss->user = NULL;
+    ciss->pass = NULL;
+    ciss->host = NULL;
+    ciss->port = 0;
+
+    if (strncmp(src, "//", 2))
+        return src;
+
+    src += 2;
+
+    if ((path = strchr(src, '/')))
+        *path++ = '\0';
+
+    if ((t = strrchr(src, '@'))) {
+        *t = '\0';
+        if ((p = strchr (src, ':'))) {
+            *p = '\0';
+            ciss->pass = p + 1;
+            url_decode (ciss->pass);
+        }
+        ciss->user = src;
+        url_decode (ciss->user);
+        t++;
+    }
+    else
+        t = src;
+
+    if ((p = strchr (t, ':'))) {
+        *p++ = '\0';
+        ciss->port = atoi (p);
+    }
+    else
+        ciss->port = 0;
+
+    ciss->host = t;
+    url_decode(ciss->host);
+    return path;
+}
+
+/* url_parse_ciss: Fill in ciss_url_t. char* elements are pointers into src,
+ *   which is modified by this call (duplicate it first if you need to).
+ * FIXME: THIS IS TASTELESS
+ */
+int url_parse_ciss(ciss_url_t *ciss, char *src)
+{
+    ciss->scheme = url_check_scheme(src);
+    if (ciss->scheme == U_UNKNOWN)
+        return -1;
+
+    ciss->path = ciss_parse_userhost(ciss, strchr(src, ':') + 1);
+    url_decode(ciss->path);
+
+    return 0;
+}
+
+/* url_ciss_tostring: output the URL string for a given CISS object. */
+int url_ciss_tostring(ciss_url_t *ciss, char *dst, ssize_t len, int flags)
+{
+    ssize_t l = 0;
+
+    if (ciss->scheme == U_UNKNOWN)
+        return -1;
+
+    snprintf(dst, len, "%s:", mutt_getnamebyvalue(ciss->scheme, UrlMap));
+
+    if (ciss->host) {
+        l = m_strcat(dst, len, "//");
+
+        if (ciss->user) {
+            if ((flags & U_DECODE_PASSWD) && ciss->pass) {
+                l += snprintf(dst + l, len - l, "%s:%s@", ciss->user, ciss->pass);
+            } else {
+                l += snprintf(dst + l, len - l, "%s@", ciss->user);
+            }
+        }
+
+        if (ciss->port) {
+            l += snprintf(dst + l, len - l, "%s:%hu/", ciss->host, ciss->port);
+        } else {
+            l += snprintf(dst + l, len - l, "%s/", ciss->host);
+        }
+    }
+
+    l += m_strcpy(dst + l, len - l, ciss->path);
+
+    return 0;
+}