From 8a4ba77068e5d7f6eab2cc1c1c10f31dcbccf7a6 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Mon, 12 Oct 2009 23:41:21 +0300 Subject: 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. --- src/url.c | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 src/url.c (limited to 'src/url.c') 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 . */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "pies.h" +#include +#include +#include + +/* 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; +} -- cgit v1.2.1