diff options
author | joerg <joerg> | 2008-04-24 10:21:33 +0000 |
---|---|---|
committer | joerg <joerg> | 2008-04-24 10:21:33 +0000 |
commit | e334f8654bd677f18716cc27a11c61cb68bb6443 (patch) | |
tree | d148702c4687b2a6a62b649eea4efdf3dd49366c /net/libfetch | |
parent | 339d6f5ec90084d8ce948d01befe2e331179e7cc (diff) | |
download | pkgsrc-e334f8654bd677f18716cc27a11c61cb68bb6443.tar.gz |
libfetch-2.11:
Implement full quoting support in FILE and FTP protocols.
Diffstat (limited to 'net/libfetch')
-rw-r--r-- | net/libfetch/Makefile | 4 | ||||
-rw-r--r-- | net/libfetch/files/common.c | 5 | ||||
-rw-r--r-- | net/libfetch/files/fetch.c | 90 | ||||
-rw-r--r-- | net/libfetch/files/fetch.h | 3 | ||||
-rw-r--r-- | net/libfetch/files/file.c | 56 | ||||
-rw-r--r-- | net/libfetch/files/ftp.c | 23 |
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; } /* |