summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoerg <joerg@pkgsrc.org>2008-04-24 10:21:33 +0000
committerjoerg <joerg@pkgsrc.org>2008-04-24 10:21:33 +0000
commitdb6317831526e37375c447744873d61bbfa0a1f0 (patch)
treed148702c4687b2a6a62b649eea4efdf3dd49366c
parent1bc6f93d6aa5b1b1110ff8964f5599526f469d98 (diff)
downloadpkgsrc-db6317831526e37375c447744873d61bbfa0a1f0.tar.gz
libfetch-2.11:
Implement full quoting support in FILE and FTP protocols.
-rw-r--r--net/libfetch/Makefile4
-rw-r--r--net/libfetch/files/common.c5
-rw-r--r--net/libfetch/files/fetch.c90
-rw-r--r--net/libfetch/files/fetch.h3
-rw-r--r--net/libfetch/files/file.c56
-rw-r--r--net/libfetch/files/ftp.c23
6 files changed, 124 insertions, 57 deletions
diff --git a/net/libfetch/Makefile b/net/libfetch/Makefile
index 563de9604b8..3a9a148056c 100644
--- a/net/libfetch/Makefile
+++ b/net/libfetch/Makefile
@@ -1,7 +1,7 @@
-# $NetBSD: Makefile,v 1.13 2008/04/24 07:55:00 joerg Exp $
+# $NetBSD: Makefile,v 1.14 2008/04/24 10:21:33 joerg Exp $
#
-DISTNAME= libfetch-2.10
+DISTNAME= libfetch-2.11
CATEGORIES= net
MASTER_SITES= # empty
DISTFILES= # empty
diff --git a/net/libfetch/files/common.c b/net/libfetch/files/common.c
index 1403d6ddff6..d7ecc96a4e3 100644
--- a/net/libfetch/files/common.c
+++ b/net/libfetch/files/common.c
@@ -1,4 +1,4 @@
-/* $NetBSD: common.c,v 1.10 2008/04/24 07:55:00 joerg Exp $ */
+/* $NetBSD: common.c,v 1.11 2008/04/24 10:21:33 joerg Exp $ */
/*-
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
* Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>
@@ -647,8 +647,7 @@ fetch_add_entry(struct url_list *ue, struct url *base, const char *name,
++name_len;
}
- name_len = strlen(name);
- tmp_name = malloc( base_doc_len + name_len + 2);
+ tmp_name = malloc( base_doc_len + name_len + 1);
if (tmp_name == NULL) {
errno = ENOMEM;
fetch_syserr();
diff --git a/net/libfetch/files/fetch.c b/net/libfetch/files/fetch.c
index a9e0fddea8e..8f9a7b022ad 100644
--- a/net/libfetch/files/fetch.c
+++ b/net/libfetch/files/fetch.c
@@ -1,4 +1,4 @@
-/* $NetBSD: fetch.c,v 1.7 2008/04/24 07:55:00 joerg Exp $ */
+/* $NetBSD: fetch.c,v 1.8 2008/04/24 10:21:33 joerg Exp $ */
/*-
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
* All rights reserved.
@@ -366,6 +366,7 @@ fetchParseURL(const char *URL)
const char *p, *q;
struct url *u;
size_t i, count;
+ int pre_quoted;
/* allocate struct url */
if ((u = calloc(1, sizeof(*u))) == NULL) {
@@ -374,11 +375,13 @@ fetchParseURL(const char *URL)
}
if (*URL == '/') {
+ pre_quoted = 0;
strcpy(u->scheme, SCHEME_FILE);
p = URL;
goto quote_doc;
}
if (strncmp(URL, "file:", 5) == 0) {
+ pre_quoted = 1;
strcpy(u->scheme, SCHEME_FILE);
URL += 5;
if (URL[0] != '/' || URL[1] != '/' || URL[2] != '/') {
@@ -390,6 +393,7 @@ fetchParseURL(const char *URL)
}
if (strncmp(URL, "http:", 5) == 0 ||
strncmp(URL, "https:", 6) == 0) {
+ pre_quoted = 1;
if (URL[4] == ':') {
strcpy(u->scheme, SCHEME_HTTP);
URL += 5;
@@ -407,6 +411,7 @@ fetchParseURL(const char *URL)
goto find_hostname;
}
if (strncmp(URL, "ftp:", 4) == 0) {
+ pre_quoted = 1;
strcpy(u->scheme, SCHEME_FTP);
URL += 4;
if (URL[0] != '/' || URL[1] != '/') {
@@ -476,16 +481,21 @@ find_hostname:
quote_doc:
count = 1;
- for (i = 0; p[i] != '\0'; ++i)
- count += fetch_urlpath_safe(p[i]) ? 1 : 3;
+ for (i = 0; p[i] != '\0'; ++i) {
+ if ((!pre_quoted && p[i] == '%') ||
+ !fetch_urlpath_safe(p[i]))
+ count += 3;
+ else
+ ++count;
+ }
+
if ((u->doc = malloc(count)) == NULL) {
fetch_syserr();
goto ouch;
}
for (i = 0; *p != '\0'; ++p) {
- if (fetch_urlpath_safe(*p))
- u->doc[i++] = *p;
- else {
+ if ((!pre_quoted && *p == '%') ||
+ !fetch_urlpath_safe(*p)) {
u->doc[i++] = '%';
if ((unsigned char)*p < 160)
u->doc[i++] = '0' + ((unsigned char)*p) / 16;
@@ -495,7 +505,8 @@ quote_doc:
u->doc[i++] = '0' + ((unsigned char)*p) % 16;
else
u->doc[i++] = 'a' - 10 + ((unsigned char)*p) % 16;
- }
+ } else
+ u->doc[i++] = *p;
}
u->doc[i] = '\0';
@@ -529,37 +540,52 @@ xdigit2digit(char digit)
}
/*
- * Extract the file name component of a URL.
- */
+ * Unquote whole URL.
+ * Skips optional parts like query or fragment identifier.
+ */
char *
-fetch_extract_filename(struct url *url)
+fetch_unquote_doc(struct url *url)
{
- char *name, *name_iter;
- const char *last_slash, *iter;
+ char *unquoted;
+ const char *iter;
+ size_t i;
+
+ if ((unquoted = malloc(strlen(url->doc) + 1)) == NULL)
+ return NULL;
- last_slash = url->doc;
- if (*last_slash == '\0')
- return strdup("");
- for (iter = last_slash + 1; *iter; ++iter) {
+ for (i = 0, iter = url->doc; *iter != '\0'; ++iter) {
if (*iter == '#' || *iter == '?')
break;
- if (*iter == '/')
- last_slash = iter;
- }
- if (last_slash + 1 == iter)
- return strdup("");
- name_iter = name = malloc(iter - last_slash);
- while (++last_slash < iter) {
- if (*last_slash != '%' ||
- !isxdigit((unsigned char)last_slash[1]) ||
- !isxdigit((unsigned char)last_slash[2])) {
- *name_iter++ = *last_slash;
+ if (iter[0] != '%' ||
+ !isxdigit((unsigned char)iter[1]) ||
+ !isxdigit((unsigned char)iter[2])) {
+ unquoted[i++] = *iter;
continue;
}
- *name_iter++ = xdigit2digit(last_slash[1]) * 16 +
- xdigit2digit(last_slash[2]);
- last_slash += 2;
+ unquoted[i++] = xdigit2digit(iter[1]) * 16 +
+ xdigit2digit(iter[2]);
+ iter += 2;
}
- *name_iter = '\0';
- return name;
+ unquoted[i] = '\0';
+ return unquoted;
+}
+
+
+/*
+ * Extract the file name component of a URL.
+ */
+char *
+fetch_extract_filename(struct url *url)
+{
+ char *unquoted, *filename;
+ const char *last_slash;
+
+ if ((unquoted = fetch_unquote_doc(url)) == NULL)
+ return NULL;
+
+ if ((last_slash = strrchr(unquoted, '/')) == NULL)
+ return unquoted;
+ filename = strdup(last_slash + 1);
+ free(unquoted);
+ return filename;
}
diff --git a/net/libfetch/files/fetch.h b/net/libfetch/files/fetch.h
index e03d4f71de2..7917746b932 100644
--- a/net/libfetch/files/fetch.h
+++ b/net/libfetch/files/fetch.h
@@ -1,4 +1,4 @@
-/* $NetBSD: fetch.h,v 1.8 2008/04/21 17:15:31 joerg Exp $ */
+/* $NetBSD: fetch.h,v 1.9 2008/04/24 10:21:33 joerg Exp $ */
/*-
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
* All rights reserved.
@@ -151,6 +151,7 @@ void fetchFreeURL(struct url *);
/* URL listening */
void fetch_init_url_list(struct url_list *);
void fetch_free_url_list(struct url_list *);
+char *fetch_unquote_doc(struct url *);
char *fetch_extract_filename(struct url *);
/* Authentication */
diff --git a/net/libfetch/files/file.c b/net/libfetch/files/file.c
index 2d0d6f6617d..f3444ecbced 100644
--- a/net/libfetch/files/file.c
+++ b/net/libfetch/files/file.c
@@ -1,4 +1,4 @@
-/* $NetBSD: file.c,v 1.8 2008/04/24 07:55:00 joerg Exp $ */
+/* $NetBSD: file.c,v 1.9 2008/04/24 10:21:33 joerg Exp $ */
/*-
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
* All rights reserved.
@@ -69,10 +69,17 @@ fetchFile_close(void *cookie)
fetchIO *
fetchXGetFile(struct url *u, struct url_stat *us, const char *flags)
{
+ char *path;
fetchIO *f;
int fd, *cookie;
- fd = open(u->doc, O_RDONLY);
+ if ((path = fetch_unquote_doc(u)) == NULL) {
+ fetch_syserr();
+ return NULL;
+ }
+
+ fd = open(path, O_RDONLY);
+ free(path);
if (fd == -1) {
fetch_syserr();
return NULL;
@@ -114,13 +121,21 @@ fetchGetFile(struct url *u, const char *flags)
fetchIO *
fetchPutFile(struct url *u, const char *flags)
{
+ char *path;
fetchIO *f;
int fd, *cookie;
+ if ((path = fetch_unquote_doc(u)) == NULL) {
+ fetch_syserr();
+ return NULL;
+ }
+
if (CHECK_FLAG('a'))
- fd = open(u->doc, O_WRONLY | O_APPEND);
+ fd = open(path, O_WRONLY | O_APPEND);
else
- fd = open(u->doc, O_WRONLY);
+ fd = open(path, O_WRONLY);
+
+ free(path);
if (fd == -1) {
fetch_syserr();
@@ -166,34 +181,47 @@ fetch_stat_file(int fd, struct url_stat *us)
return (0);
}
-static int
-fetch_stat_file2(const char *fn, struct url_stat *us)
+int
+fetchStatFile(struct url *u, struct url_stat *us, const char *flags)
{
+ char *path;
int fd, rv;
- fd = open(fn, O_RDONLY);
+ if ((path = fetch_unquote_doc(u)) == NULL) {
+ fetch_syserr();
+ return -1;
+ }
+
+ fd = open(path, O_RDONLY);
+ free(path);
+
if (fd == -1) {
fetch_syserr();
return -1;
}
+
rv = fetch_stat_file(fd, us);
close(fd);
- return rv;
-}
-int
-fetchStatFile(struct url *u, struct url_stat *us, const char *flags)
-{
- return (fetch_stat_file2(u->doc, us));
+ return rv;
}
int
fetchListFile(struct url_list *ue, struct url *u, const char *pattern, const char *flags)
{
+ char *path;
struct dirent *de;
DIR *dir;
- if ((dir = opendir(u->doc)) == NULL) {
+ if ((path = fetch_unquote_doc(u)) == NULL) {
+ fetch_syserr();
+ return -1;
+ }
+
+ dir = opendir(path);
+ free(path);
+
+ if (dir == NULL) {
fetch_syserr();
return -1;
}
diff --git a/net/libfetch/files/ftp.c b/net/libfetch/files/ftp.c
index 1d44107e8d6..fc731197a24 100644
--- a/net/libfetch/files/ftp.c
+++ b/net/libfetch/files/ftp.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ftp.c,v 1.20 2008/04/24 07:55:00 joerg Exp $ */
+/* $NetBSD: ftp.c,v 1.21 2008/04/24 10:21:33 joerg Exp $ */
/*-
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
* Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>
@@ -1102,6 +1102,8 @@ fetchIO *
ftp_request(struct url *url, const char *op, const char *op_arg,
struct url_stat *us, struct url *purl, const char *flags)
{
+ fetchIO *f;
+ char *path;
conn_t *conn;
int oflag;
@@ -1124,15 +1126,24 @@ ftp_request(struct url *url, const char *op, const char *op_arg,
if (conn == NULL)
return (NULL);
+ if ((path = fetch_unquote_doc(url)) == NULL) {
+ fetch_syserr();
+ return NULL;
+ }
+
/* change directory */
- if (ftp_cwd(conn, url->doc, op_arg != NULL) == -1)
+ if (ftp_cwd(conn, path, op_arg != NULL) == -1) {
+ free(path);
return (NULL);
+ }
/* stat file */
- if (us && ftp_stat(conn, url->doc, us) == -1
+ if (us && ftp_stat(conn, path, us) == -1
&& fetchLastErrCode != FETCH_PROTO
- && fetchLastErrCode != FETCH_UNAVAIL)
+ && fetchLastErrCode != FETCH_UNAVAIL) {
+ free(path);
return (NULL);
+ }
/* just a stat */
if (strcmp(op, "STAT") == 0)
@@ -1143,7 +1154,9 @@ ftp_request(struct url *url, const char *op, const char *op_arg,
oflag = O_RDONLY;
/* initiate the transfer */
- return (ftp_transfer(conn, op, url->doc, op_arg, oflag, url->offset, flags));
+ f = (ftp_transfer(conn, op, path, op_arg, oflag, url->offset, flags));
+ free(path);
+ return f;
}
/*