aboutsummaryrefslogtreecommitdiff
path: root/src/url.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-10-12 23:41:21 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2009-10-12 23:42:04 +0300
commit8a4ba77068e5d7f6eab2cc1c1c10f31dcbccf7a6 (patch)
treec70f38d943c778684bb9dbfc7db018e7efb21bf1 /src/url.c
parentaf04ed630f18e9003756317cc627a11084d0d59a (diff)
downloadpies-8a4ba77068e5d7f6eab2cc1c1c10f31dcbccf7a6.tar.gz
pies-8a4ba77068e5d7f6eab2cc1c1c10f31dcbccf7a6.tar.bz2
Fix make distcheck and check-docs.
* doc/Makefile.am: Fix `check-*' goals. * doc/pies.texi: Update and rearrange material. Document new configuration. * lib/Makefile.am (libpies_a_SOURCES): Remove nls.c * src/Makefile.am (EXTRA_DIST): Remove pies.rc, add pp-setup. (INCLUDES): Add $(top_builddir)/gnu * src/pies.c: Minor changes. * src/progman.c: Minor changes. * README-hacking: New file.
Diffstat (limited to 'src/url.c')
-rw-r--r--src/url.c212
1 files changed, 212 insertions, 0 deletions
diff --git a/src/url.c b/src/url.c
new file mode 100644
index 0000000..69abcfb
--- /dev/null
+++ b/src/url.c
@@ -0,0 +1,212 @@
+/* This file is part of Pies
+ Copyright (C) 2009 Sergey Poznyakoff
+
+ Pies 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 3, or (at your option)
+ any later version.
+
+ Pies 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 Pies. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include "pies.h"
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+
+/* proto://[user[:password]@][host[:port]/]path[;arg=str[;arg=str...]
+*/
+
+static int
+alloc_string_len (char **sptr, const char *start, size_t len)
+{
+ *sptr = malloc (len + 1);
+ if (!*sptr)
+ return 1;
+ memcpy (*sptr, start, len);
+ (*sptr)[len] = 0;
+ return 0;
+}
+
+static int
+alloc_string (char **sptr, const char *start, const char *end)
+{
+ size_t len = end ? end - start : strlen (start);
+ return alloc_string_len (sptr, start, len);
+}
+
+static int
+url_parse_args (struct pies_url *url, char **str)
+{
+ struct wordsplit ws;
+
+ ws.ws_delim = ";";
+ if (wordsplit (*str, &ws, WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_DELIM))
+ return 1;
+ url->argc = ws.ws_wordc;
+ url->argv = ws.ws_wordv;
+ return 0;
+}
+
+static int
+url_parse_path (struct pies_url *url, char **str)
+{
+ char *p;
+
+ p = strchr (*str, ';');
+ if (!p)
+ p = *str + strlen (*str);
+ if (alloc_string(&url->path, *str, p))
+ return 1;
+ *str = p;
+ if (*p)
+ ++ * str;
+ return url_parse_args (url, str);
+}
+
+/* On input str points at the beginning of host part */
+static int
+url_parse_host (struct pies_url *url, char **str)
+{
+ char *s = *str;
+ size_t len = strcspn (s, "/:");
+
+ if (s[len] == ':')
+ {
+ char *q;
+ unsigned long n = strtoul (s + len + 1, &q, 10);
+ if ((*q && !strchr("/;:", *q)) || n > USHRT_MAX)
+ return 1;
+ url->port = n;
+ *str = q + strcspn(q, "/");
+ }
+ else
+ *str = s + len;
+ if (alloc_string_len (&url->host, s, len))
+ return 1;
+ if (**str)
+ {
+ ++*str;
+ return url_parse_path (url, str);
+ }
+ return 0;
+}
+
+/* On input str points past the mech:// part */
+static int
+url_parse_user (struct pies_url *url, char **str)
+{
+ size_t len = strcspn (*str, ":;@/");
+ char *p = *str + len;
+
+ switch (*p)
+ {
+ case ';':
+ case ':':
+ len = strcspn (p + 1, "@/:");
+ if (p[len+1] == '@')
+ {
+ if (alloc_string_len(&url->passwd, p + 1, len))
+ return 1;
+ if (alloc_string (&url->user, *str, p))
+ return 1;
+ *str = p + len + 2;
+ }
+ break;
+
+ case '@':
+ if (alloc_string (&url->user, *str, p))
+ return 1;
+ url->passwd = NULL;
+ *str = p + 1;
+ }
+ return url_parse_host (url, str);
+}
+
+static int
+url_parse_proto (struct pies_url *url, const char *str)
+{
+ char *p;
+
+ if (!str)
+ {
+ errno = EINVAL;
+ return 1;
+ }
+
+ p = strchr (str, ':');
+ if (!p)
+ {
+ errno = EINVAL;
+ return 1;
+ }
+
+ alloc_string (&url->proto, str, p);
+
+ /* Skip slashes */
+ for (p++; *p == '/'; p++)
+ ;
+ return url_parse_user (url, &p);
+}
+
+void
+pies_url_destroy (struct pies_url **purl)
+{
+ int i;
+ struct pies_url *url = *purl;
+
+ free (url->string);
+ free (url->proto);
+ free (url->host);
+ free (url->path);
+ free (url->user);
+ free (url->passwd);
+ for (i = 0; i < url->argc; i++)
+ free (url->argv[i]);
+ free (url->argv);
+ free(url);
+ *purl = NULL;
+}
+
+int
+pies_url_create (struct pies_url **purl, const char *str)
+{
+ int rc;
+ struct pies_url *url;
+
+ url = malloc (sizeof (*url));
+ if (!url)
+ return 1;
+ memset (url, 0, sizeof(*url));
+ rc = url_parse_proto (url, str);
+ if (rc)
+ pies_url_destroy (&url);
+ else
+ {
+ url->string = strdup (str);
+ *purl = url;
+ }
+ return rc;
+}
+
+const char *
+pies_url_get_arg (struct pies_url *url, const char *argname)
+{
+ int i;
+ size_t arglen = strlen (argname);
+ for (i = 0; i < url->argc; i++)
+ {
+ size_t len = strcspn (url->argv[i], "=");
+ if (len == arglen && memcmp (url->argv[i], argname, arglen) == 0)
+ return url->argv[i] + len + 1;
+ }
+ return NULL;
+}

Return to:

Send suggestions and report system problems to the System administrator.